aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/gdb_server.c129
-rw-r--r--src/server/gdb_server.h2
-rw-r--r--src/server/rtt_server.c69
-rw-r--r--src/server/startup.tcl78
-rw-r--r--src/server/tcl_server.c21
-rw-r--r--src/server/telnet_server.c30
6 files changed, 234 insertions, 95 deletions
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index f4ce5df..d9825c5 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -116,7 +116,7 @@ static int gdb_error(struct connection *connection, int retval);
static char *gdb_port;
static char *gdb_port_next;
-static void gdb_log_callback(void *priv, const char *file, unsigned line,
+static void gdb_log_callback(void *priv, const char *file, unsigned int line,
const char *function, const char *string);
static void gdb_sig_halted(struct connection *connection);
@@ -376,7 +376,7 @@ static int gdb_putback_char(struct connection *connection, int last_char)
/* The only way we can detect that the socket is closed is the first time
* we write to it, we will fail. Subsequent write operations will
* succeed. Shudder! */
-static int gdb_write(struct connection *connection, void *data, int len)
+static int gdb_write(struct connection *connection, const void *data, int len)
{
struct gdb_connection *gdb_con = connection->priv;
if (gdb_con->closed) {
@@ -392,7 +392,7 @@ static int gdb_write(struct connection *connection, void *data, int len)
return ERROR_SERVER_REMOTE_CLOSED;
}
-static void gdb_log_incoming_packet(struct connection *connection, char *packet)
+static void gdb_log_incoming_packet(struct connection *connection, const char *packet)
{
if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
return;
@@ -401,7 +401,7 @@ static void gdb_log_incoming_packet(struct connection *connection, char *packet)
struct gdb_connection *gdb_connection = connection->priv;
/* Avoid dumping non-printable characters to the terminal */
- const unsigned packet_len = strlen(packet);
+ const unsigned int packet_len = strlen(packet);
const char *nonprint = find_nonprint_char(packet, packet_len);
if (nonprint) {
/* Does packet at least have a prefix that is printable?
@@ -425,7 +425,7 @@ static void gdb_log_incoming_packet(struct connection *connection, char *packet)
}
}
-static void gdb_log_outgoing_packet(struct connection *connection, char *packet_buf,
+static void gdb_log_outgoing_packet(struct connection *connection, const char *packet_buf,
unsigned int packet_len, unsigned char checksum)
{
if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
@@ -443,7 +443,7 @@ static void gdb_log_outgoing_packet(struct connection *connection, char *packet_
}
static int gdb_put_packet_inner(struct connection *connection,
- char *buffer, int len)
+ const char *buffer, int len)
{
int i;
unsigned char my_checksum = 0;
@@ -565,7 +565,7 @@ static int gdb_put_packet_inner(struct connection *connection,
return ERROR_OK;
}
-int gdb_put_packet(struct connection *connection, char *buffer, int len)
+int gdb_put_packet(struct connection *connection, const char *buffer, int len)
{
struct gdb_connection *gdb_con = connection->priv;
gdb_con->busy = true;
@@ -955,7 +955,7 @@ static void gdb_fileio_reply(struct target *target, struct connection *connectio
/* encounter unknown syscall, continue */
gdb_connection->frontend_state = TARGET_RUNNING;
- target_resume(target, 1, 0x0, 0, 0);
+ target_resume(target, true, 0x0, false, false);
return;
}
@@ -965,7 +965,7 @@ static void gdb_fileio_reply(struct target *target, struct connection *connectio
if (program_exited) {
/* Use target_resume() to let target run its own exit syscall handler. */
gdb_connection->frontend_state = TARGET_RUNNING;
- target_resume(target, 1, 0x0, 0, 0);
+ target_resume(target, true, 0x0, false, false);
} else {
gdb_connection->frontend_state = TARGET_HALTED;
rtos_update_threads(target);
@@ -1249,7 +1249,7 @@ static void gdb_target_to_reg(struct target *target,
int i;
for (i = 0; i < str_len; i += 2) {
- unsigned t;
+ unsigned int t;
if (sscanf(tstr + i, "%02x", &t) != 1) {
LOG_ERROR("BUG: unable to convert register value");
exit(-1);
@@ -1308,7 +1308,7 @@ static int gdb_get_registers_packet(struct connection *connection,
return gdb_error(connection, retval);
for (i = 0; i < reg_list_size; i++) {
- if (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden)
+ if (!reg_list[i] || !reg_list[i]->exist || reg_list[i]->hidden)
continue;
reg_packet_size += DIV_ROUND_UP(reg_list[i]->size, 8) * 2;
}
@@ -1322,7 +1322,7 @@ static int gdb_get_registers_packet(struct connection *connection,
reg_packet_p = reg_packet;
for (i = 0; i < reg_list_size; i++) {
- if (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden)
+ if (!reg_list[i] || !reg_list[i]->exist || reg_list[i]->hidden)
continue;
retval = gdb_get_reg_value_as_str(target, reg_packet_p, reg_list[i]);
if (retval != ERROR_OK && gdb_report_register_access_error) {
@@ -1599,7 +1599,7 @@ static int gdb_read_memory_packet(struct connection *connection,
* cmd = view%20audit-trail&database = gdb&pr = 2395
*
* For now, the default is to fix up things to make current GDB versions work.
- * This can be overwritten using the gdb_report_data_abort <'enable'|'disable'> command.
+ * This can be overwritten using the "gdb report_data_abort <'enable'|'disable'>" command.
*/
memset(buffer, 0, len);
retval = ERROR_OK;
@@ -1755,7 +1755,7 @@ static int gdb_step_continue_packet(struct connection *connection,
char const *packet, int packet_size)
{
struct target *target = get_available_target_from_connection(connection);
- int current = 0;
+ bool current = false;
uint64_t address = 0x0;
int retval = ERROR_OK;
@@ -1764,17 +1764,17 @@ static int gdb_step_continue_packet(struct connection *connection,
if (packet_size > 1)
address = strtoull(packet + 1, NULL, 16);
else
- current = 1;
+ current = true;
gdb_running_type = packet[0];
if (packet[0] == 'c') {
LOG_DEBUG("continue");
/* resume at current address, don't handle breakpoints, not debugging */
- retval = target_resume(target, current, address, 0, 0);
+ retval = target_resume(target, current, address, false, false);
} else if (packet[0] == 's') {
LOG_DEBUG("step");
/* step at current or address, don't handle breakpoints */
- retval = target_step(target, current, address, 0);
+ retval = target_step(target, current, address, false);
}
return retval;
}
@@ -1838,18 +1838,9 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
return ERROR_FAIL;
}
retval = breakpoint_add(target, address, size, bp_type);
- if (retval == ERROR_NOT_IMPLEMENTED) {
- /* Send empty reply to report that breakpoints of this type are not supported */
- gdb_put_packet(connection, "", 0);
- } else if (retval != ERROR_OK) {
- retval = gdb_error(connection, retval);
- if (retval != ERROR_OK)
- return retval;
- } else
- gdb_put_packet(connection, "OK", 2);
} else {
- breakpoint_remove(target, address);
- gdb_put_packet(connection, "OK", 2);
+ assert(packet[0] == 'z');
+ retval = breakpoint_remove(target, address);
}
break;
case 2:
@@ -1858,26 +1849,26 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection,
{
if (packet[0] == 'Z') {
retval = watchpoint_add(target, address, size, wp_type, 0, WATCHPOINT_IGNORE_DATA_VALUE_MASK);
- if (retval == ERROR_NOT_IMPLEMENTED) {
- /* Send empty reply to report that watchpoints of this type are not supported */
- gdb_put_packet(connection, "", 0);
- } else if (retval != ERROR_OK) {
- retval = gdb_error(connection, retval);
- if (retval != ERROR_OK)
- return retval;
- } else
- gdb_put_packet(connection, "OK", 2);
} else {
- watchpoint_remove(target, address);
- gdb_put_packet(connection, "OK", 2);
+ assert(packet[0] == 'z');
+ retval = watchpoint_remove(target, address);
}
break;
}
default:
+ {
+ retval = ERROR_NOT_IMPLEMENTED;
break;
+ }
}
- return ERROR_OK;
+ if (retval == ERROR_NOT_IMPLEMENTED) {
+ /* Send empty reply to report that watchpoints of this type are not supported */
+ return gdb_put_packet(connection, "", 0);
+ }
+ if (retval != ERROR_OK)
+ return gdb_error(connection, retval);
+ return gdb_put_packet(connection, "OK", 2);
}
/* print out a string and allocate more space as needed,
@@ -2014,8 +2005,8 @@ static int gdb_memory_map(struct connection *connection,
compare_bank);
for (unsigned int i = 0; i < target_flash_banks; i++) {
- unsigned sector_size = 0;
- unsigned group_len = 0;
+ unsigned int sector_size = 0;
+ unsigned int group_len = 0;
p = banks[i];
@@ -2320,7 +2311,7 @@ static int get_reg_features_list(struct target *target, char const **feature_lis
*feature_list = calloc(1, sizeof(char *));
for (int i = 0; i < reg_list_size; i++) {
- if (reg_list[i]->exist == false || reg_list[i]->hidden)
+ if (!reg_list[i]->exist || reg_list[i]->hidden)
continue;
if (reg_list[i]->feature
@@ -2530,7 +2521,7 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o
int i;
for (i = 0; i < reg_list_size; i++) {
- if (reg_list[i]->exist == false || reg_list[i]->hidden)
+ if (!reg_list[i]->exist || reg_list[i]->hidden)
continue;
if (strcmp(reg_list[i]->feature->name, features[current_feature]))
@@ -3089,7 +3080,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
LOG_TARGET_DEBUG(target, "target continue");
gdb_connection->output_flag = GDB_OUTPUT_ALL;
- retval = target_resume(target, 1, 0, 0, 0);
+ retval = target_resume(target, true, 0, false, false);
if (retval == ERROR_TARGET_NOT_HALTED)
LOG_TARGET_INFO(target, "target was not halted when resume was requested");
@@ -3117,7 +3108,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
bool fake_step = false;
struct target *ct = target;
- int current_pc = 1;
+ bool current_pc = true;
int64_t thread_id;
parse++;
if (parse[0] == ':') {
@@ -3231,7 +3222,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
"Pretending to gdb that it is running until it's available again.");
retval = ERROR_FAIL;
} else {
- retval = target_step(ct, current_pc, 0, 0);
+ retval = target_step(ct, current_pc, 0, false);
if (retval == ERROR_TARGET_NOT_HALTED)
LOG_TARGET_INFO(ct, "target was not halted when step was requested");
}
@@ -3560,9 +3551,9 @@ static int gdb_fileio_response_packet(struct connection *connection,
/* After File-I/O ends, keep continue or step */
if (gdb_running_type == 'c')
- retval = target_resume(target, 1, 0x0, 0, 0);
+ retval = target_resume(target, true, 0x0, false, false);
else if (gdb_running_type == 's')
- retval = target_step(target, 1, 0x0, 0);
+ retval = target_step(target, true, 0x0, false);
else
retval = ERROR_FAIL;
@@ -3572,7 +3563,7 @@ static int gdb_fileio_response_packet(struct connection *connection,
return ERROR_OK;
}
-static void gdb_log_callback(void *priv, const char *file, unsigned line,
+static void gdb_log_callback(void *priv, const char *file, unsigned int line,
const char *function, const char *string)
{
struct connection *connection = priv;
@@ -4003,7 +3994,8 @@ static int gdb_target_add_one(struct target *target)
}
}
} else if (strcmp(gdb_port_next, "pipe") == 0) {
- gdb_port_next = "disabled";
+ free(gdb_port_next);
+ gdb_port_next = strdup("disabled");
}
}
return retval;
@@ -4034,7 +4026,7 @@ COMMAND_HANDLER(handle_gdb_sync_command)
if (!current_gdb_connection) {
command_print(CMD,
- "gdb_sync command can only be run from within gdb using \"monitor gdb_sync\"");
+ "gdb sync command can only be run from within gdb using \"monitor gdb sync\"");
return ERROR_FAIL;
}
@@ -4043,7 +4035,6 @@ COMMAND_HANDLER(handle_gdb_sync_command)
return ERROR_OK;
}
-/* daemon configuration command gdb_port */
COMMAND_HANDLER(handle_gdb_port_command)
{
int retval = CALL_COMMAND_HANDLER(server_pipe_command, &gdb_port);
@@ -4090,7 +4081,6 @@ COMMAND_HANDLER(handle_gdb_report_register_access_error)
return ERROR_OK;
}
-/* gdb_breakpoint_override */
COMMAND_HANDLER(handle_gdb_breakpoint_override_command)
{
if (CMD_ARGC == 0) {
@@ -4167,9 +4157,9 @@ out:
return retval;
}
-static const struct command_registration gdb_command_handlers[] = {
+static const struct command_registration gdb_subcommand_handlers[] = {
{
- .name = "gdb_sync",
+ .name = "sync",
.handler = handle_gdb_sync_command,
.mode = COMMAND_ANY,
.help = "next stepi will return immediately allowing "
@@ -4178,7 +4168,7 @@ static const struct command_registration gdb_command_handlers[] = {
.usage = ""
},
{
- .name = "gdb_port",
+ .name = "port",
.handler = handle_gdb_port_command,
.mode = COMMAND_CONFIG,
.help = "Normally gdb listens to a TCP/IP port. Each subsequent GDB "
@@ -4191,35 +4181,35 @@ static const struct command_registration gdb_command_handlers[] = {
.usage = "[port_num]",
},
{
- .name = "gdb_memory_map",
+ .name = "memory_map",
.handler = handle_gdb_memory_map_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable memory map",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_flash_program",
+ .name = "flash_program",
.handler = handle_gdb_flash_program_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable flash program",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_report_data_abort",
+ .name = "report_data_abort",
.handler = handle_gdb_report_data_abort_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable reporting data aborts",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_report_register_access_error",
+ .name = "report_register_access_error",
.handler = handle_gdb_report_register_access_error,
.mode = COMMAND_CONFIG,
.help = "enable or disable reporting register access errors",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_breakpoint_override",
+ .name = "breakpoint_override",
.handler = handle_gdb_breakpoint_override_command,
.mode = COMMAND_ANY,
.help = "Display or specify type of breakpoint "
@@ -4227,14 +4217,14 @@ static const struct command_registration gdb_command_handlers[] = {
.usage = "('hard'|'soft'|'disable')"
},
{
- .name = "gdb_target_description",
+ .name = "target_description",
.handler = handle_gdb_target_description_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable target description",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_save_tdesc",
+ .name = "save_tdesc",
.handler = handle_gdb_save_tdesc_command,
.mode = COMMAND_EXEC,
.help = "Save the target description file",
@@ -4243,6 +4233,17 @@ static const struct command_registration gdb_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration gdb_command_handlers[] = {
+ {
+ .name = "gdb",
+ .mode = COMMAND_ANY,
+ .help = "GDB commands",
+ .chain = gdb_subcommand_handlers,
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
int gdb_register_commands(struct command_context *cmd_ctx)
{
gdb_port = strdup("3333");
diff --git a/src/server/gdb_server.h b/src/server/gdb_server.h
index 4288ceb..1a626eb 100644
--- a/src/server/gdb_server.h
+++ b/src/server/gdb_server.h
@@ -28,7 +28,7 @@ int gdb_target_add_all(struct target *target);
int gdb_register_commands(struct command_context *command_context);
void gdb_service_free(void);
-int gdb_put_packet(struct connection *connection, char *buffer, int len);
+int gdb_put_packet(struct connection *connection, const char *buffer, int len);
int gdb_get_actual_connections(void);
diff --git a/src/server/rtt_server.c b/src/server/rtt_server.c
index 9769153..b44101c 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 buffer[64];
+ unsigned int length;
+ unsigned int offset;
+};
+
static int read_callback(unsigned int channel, const uint8_t *buffer,
size_t length, void *user_data)
{
@@ -56,7 +62,16 @@ 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) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+
+ connection->priv = data;
service = connection->service->priv;
LOG_DEBUG("rtt: New connection for channel %u", service->channel);
@@ -79,31 +94,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];
struct rtt_service *service;
- size_t length;
+ struct rtt_connection_data *data;
- service = (struct rtt_service *)connection->service->priv;
- bytes_read = connection_read(connection, buffer, sizeof(buffer));
+ data = connection->priv;
+ service = connection->service->priv;
- 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) {
+ int bytes_read;
- length = bytes_read;
- rtt_write_channel(service->channel, buffer, &length);
+ bytes_read = connection_read(connection, data->buffer, sizeof(data->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;
+ }
+ data->length = bytes_read;
+ data->offset = 0;
+ }
+ if (data->length > 0) {
+ unsigned char *ptr;
+ size_t length, to_write;
+
+ ptr = data->buffer + data->offset;
+ length = data->length - data->offset;
+ to_write = length;
+ rtt_write_channel(service->channel, ptr, &length);
+
+ if (length < to_write) {
+ data->offset += length;
+ connection->input_pending = true;
+ } else {
+ data->offset = 0;
+ data->length = 0;
+ connection->input_pending = false;
+ }
+ }
return ERROR_OK;
}
@@ -126,8 +163,10 @@ COMMAND_HANDLER(handle_rtt_start_command)
service = calloc(1, sizeof(struct rtt_service));
- if (!service)
+ if (!service) {
+ LOG_ERROR("Out of memory");
return ERROR_FAIL;
+ }
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], service->channel);
diff --git a/src/server/startup.tcl b/src/server/startup.tcl
index 1d30b1d..cf3eca3 100644
--- a/src/server/startup.tcl
+++ b/src/server/startup.tcl
@@ -41,3 +41,81 @@ proc _telnet_autocomplete_helper pattern {
return [lsort $cmds]
}
+
+lappend _telnet_autocomplete_skip "gdb_sync"
+proc "gdb_sync" {} {
+ echo "DEPRECATED! use 'gdb sync', not 'gdb_sync'"
+ eval gdb sync
+}
+
+lappend _telnet_autocomplete_skip "gdb_port"
+proc "gdb_port" {args} {
+ echo "DEPRECATED! use 'gdb port', not 'gdb_port'"
+ eval gdb port $args
+}
+
+lappend _telnet_autocomplete_skip "gdb_memory_map"
+proc "gdb_memory_map" {state} {
+ echo "DEPRECATED! use 'gdb memory_map', not 'gdb_memory_map'"
+ eval gdb memory_map $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_flash_program"
+proc "gdb_flash_program" {state} {
+ echo "DEPRECATED! use 'gdb flash_program', not 'gdb_flash_program'"
+ eval gdb flash_program $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_report_data_abort"
+proc "gdb_report_data_abort" {state} {
+ echo "DEPRECATED! use 'gdb report_data_abort', not 'gdb_report_data_abort'"
+ eval gdb report_data_abort $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_report_register_access_error"
+proc "gdb_report_register_access_error" {state} {
+ echo "DEPRECATED! use 'gdb report_register_access_error', not 'gdb_report_register_access_error'"
+ eval gdb report_register_access_error $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_breakpoint_override"
+proc "gdb_breakpoint_override" {override} {
+ echo "DEPRECATED! use 'gdb breakpoint_override', not 'gdb_breakpoint_override'"
+ eval gdb breakpoint_override $override
+}
+
+lappend _telnet_autocomplete_skip "gdb_target_description"
+proc "gdb_target_description" {state} {
+ echo "DEPRECATED! use 'gdb target_description', not 'gdb_target_description'"
+ eval gdb target_description $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_save_tdesc"
+proc "gdb_save_tdesc" {} {
+ echo "DEPRECATED! use 'gdb save_tdesc', not 'gdb_save_tdesc'"
+ eval gdb save_tdesc
+}
+
+lappend _telnet_autocomplete_skip "tcl_port"
+proc "tcl_port" {args} {
+ echo "DEPRECATED! use 'tcl port' not 'tcl_port'"
+ eval tcl port $args
+}
+
+lappend _telnet_autocomplete_skip "tcl_notifications"
+proc "tcl_notifications" {state} {
+ echo "DEPRECATED! use 'tcl notifications' not 'tcl_notifications'"
+ eval tcl notifications $state
+}
+
+lappend _telnet_autocomplete_skip "tcl_trace"
+proc "tcl_trace" {state} {
+ echo "DEPRECATED! use 'tcl trace' not 'tcl_trace'"
+ eval tcl trace $state
+}
+
+lappend _telnet_autocomplete_skip "telnet_port"
+proc "telnet_port" {args} {
+ echo "DEPRECATED! use 'telnet port', not 'telnet_port'"
+ eval telnet port $args
+}
diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c
index 16cbedc..16cc55e 100644
--- a/src/server/tcl_server.c
+++ b/src/server/tcl_server.c
@@ -323,25 +323,25 @@ COMMAND_HANDLER(handle_tcl_trace_command)
}
}
-static const struct command_registration tcl_command_handlers[] = {
+static const struct command_registration tcl_subcommand_handlers[] = {
{
- .name = "tcl_port",
+ .name = "port",
.handler = handle_tcl_port_command,
.mode = COMMAND_CONFIG,
.help = "Specify port on which to listen "
"for incoming Tcl syntax. "
- "Read help on 'gdb_port'.",
+ "Read help on 'gdb port'.",
.usage = "[port_num]",
},
{
- .name = "tcl_notifications",
+ .name = "notifications",
.handler = handle_tcl_notifications_command,
.mode = COMMAND_EXEC,
.help = "Target Notification output",
.usage = "[on|off]",
},
{
- .name = "tcl_trace",
+ .name = "trace",
.handler = handle_tcl_trace_command,
.mode = COMMAND_EXEC,
.help = "Target trace output",
@@ -350,6 +350,17 @@ static const struct command_registration tcl_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration tcl_command_handlers[] = {
+ {
+ .name = "tcl",
+ .mode = COMMAND_ANY,
+ .help = "tcl command group",
+ .usage = "",
+ .chain = tcl_subcommand_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
int tcl_register_commands(struct command_context *cmd_ctx)
{
tcl_port = strdup("6666");
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index 938bc5b..2c3f769 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -93,7 +93,7 @@ static int telnet_output(struct command_context *cmd_ctx, const char *line)
return telnet_outputline(connection, line);
}
-static void telnet_log_callback(void *priv, const char *file, unsigned line,
+static void telnet_log_callback(void *priv, const char *file, unsigned int line,
const char *function, const char *string)
{
struct connection *connection = priv;
@@ -570,7 +570,7 @@ static void telnet_auto_complete(struct connection *connection)
struct list_head lh;
};
- LIST_HEAD(matches);
+ OOCD_LIST_HEAD(matches);
/* - user command sequence, either at line beginning
* or we start over after these characters ';', '[', '{'
@@ -967,7 +967,6 @@ int telnet_init(char *banner)
return ERROR_OK;
}
-/* daemon configuration command telnet_port */
COMMAND_HANDLER(handle_telnet_port_command)
{
return CALL_COMMAND_HANDLER(server_pipe_command, &telnet_port);
@@ -978,22 +977,33 @@ COMMAND_HANDLER(handle_exit_command)
return ERROR_COMMAND_CLOSE_CONNECTION;
}
+static const struct command_registration telnet_subcommand_handlers[] = {
+ {
+ .name = "port",
+ .handler = handle_telnet_port_command,
+ .mode = COMMAND_CONFIG,
+ .help = "Specify port on which to listen "
+ "for incoming telnet connections. "
+ "Read help on 'gdb port'.",
+ .usage = "[port_num]",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
static const struct command_registration telnet_command_handlers[] = {
{
.name = "exit",
.handler = handle_exit_command,
- .mode = COMMAND_EXEC,
+ .mode = COMMAND_ANY,
.usage = "",
.help = "exit telnet session",
},
{
- .name = "telnet_port",
- .handler = handle_telnet_port_command,
+ .name = "telnet",
+ .chain = telnet_subcommand_handlers,
.mode = COMMAND_CONFIG,
- .help = "Specify port on which to listen "
- "for incoming telnet connections. "
- "Read help on 'gdb_port'.",
- .usage = "[port_num]",
+ .help = "telnet commands",
+ .usage = "",
},
COMMAND_REGISTRATION_DONE
};