X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fserver%2Fserver.c;h=f762704dd3412f6c6761aeca0c14518311093626;hp=05018694bc375ecf433cc33a4b94c415681ab3c8;hb=74ce435d97ca4f6f81645d755d04123f075aa42b;hpb=23d88e57748bece953ddf1063017152243abc93a diff --git a/src/server/server.c b/src/server/server.c index 05018694bc..f762704dd3 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -28,7 +28,10 @@ #endif #include "server.h" -#include "target.h" +#include +#include "openocd.h" +#include "tcl_server.h" +#include "telnet_server.h" #include @@ -37,7 +40,7 @@ #endif -service_t *services = NULL; +struct service *services = NULL; /* shutdown_openocd == 1: exit the main event loop, and quit the debugger */ static int shutdown_openocd = 0; @@ -45,14 +48,14 @@ static int shutdown_openocd = 0; /* set when using pipes rather than tcp */ int server_use_pipes = 0; -int add_connection(service_t *service, command_context_t *cmd_ctx) +int add_connection(struct service *service, struct command_context *cmd_ctx) { socklen_t address_size; - connection_t *c, **p; + struct connection *c, **p; int retval; int flag = 1; - c = malloc(sizeof(connection_t)); + c = malloc(sizeof(struct connection)); c->fd = -1; memset(&c->sin, 0, sizeof(c->sin)); c->cmd_ctx = copy_command_context(cmd_ctx); @@ -109,10 +112,10 @@ int add_connection(service_t *service, command_context_t *cmd_ctx) return ERROR_OK; } -int remove_connection(service_t *service, connection_t *connection) +int remove_connection(struct service *service, struct connection *connection) { - connection_t **p = &service->connections; - connection_t *c; + struct connection **p = &service->connections; + struct connection *c; /* find connection */ while ((c = *p)) @@ -141,10 +144,10 @@ int remove_connection(service_t *service, connection_t *connection) int add_service(char *name, enum connection_type type, unsigned short port, int max_connections, new_connection_handler_t new_connection_handler, input_handler_t input_handler, connection_closed_handler_t connection_closed_handler, void *priv) { - service_t *c, **p; + struct service *c, **p; int so_reuseaddr_option = 1; - c = malloc(sizeof(service_t)); + c = malloc(sizeof(struct service)); c->name = strdup(name); c->type = type; @@ -232,8 +235,8 @@ int add_service(char *name, enum connection_type type, unsigned short port, int int remove_service(unsigned short port) { - service_t **p = &services; - service_t *c; + struct service **p = &services; + struct service *c; /* find service */ while ((c = *p)) @@ -260,12 +263,12 @@ int remove_service(unsigned short port) int remove_services(void) { - service_t *c = services; + struct service *c = services; /* loop service */ while (c) { - service_t *next = c->next; + struct service *next = c->next; if (c->name) free(c->name); @@ -285,16 +288,14 @@ int remove_services(void) return ERROR_OK; } -extern void openocd_sleep_prelude(void); -extern void openocd_sleep_postlude(void); - -int server_loop(command_context_t *command_context) +int server_loop(struct command_context *command_context) { - service_t *service; + struct service *service; + + bool poll = true; /* used in select() */ fd_set read_fds; - struct timeval tv; int fd_max; /* used in accept() */ @@ -305,13 +306,9 @@ int server_loop(command_context_t *command_context) LOG_ERROR("couldn't set SIGPIPE to SIG_IGN"); #endif - /* do regular tasks after at most 10ms */ - tv.tv_sec = 0; - tv.tv_usec = 10000; - while (!shutdown_openocd) { - /* monitor sockets for acitvity */ + /* monitor sockets for activity */ fd_max = 0; FD_ZERO(&read_fds); @@ -329,7 +326,7 @@ int server_loop(command_context_t *command_context) if (service->connections) { - connection_t *c; + struct connection *c; for (c = service->connections; c; c = c->next) { @@ -351,12 +348,24 @@ int server_loop(command_context_t *command_context) #endif #endif - openocd_sleep_prelude(); - kept_alive(); - - /* Only while we're sleeping we'll let others run */ - retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); - openocd_sleep_postlude(); + struct timeval tv; + tv.tv_sec = 0; + if (poll) + { + /* we're just polling this iteration, this is faster on embedded + * hosts */ + tv.tv_usec = 0; + retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); + } else + { + /* Every 100ms */ + tv.tv_usec = 100000; + /* Only while we're sleeping we'll let others run */ + openocd_sleep_prelude(); + kept_alive(); + retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); + openocd_sleep_postlude(); + } if (retval == -1) { @@ -385,15 +394,20 @@ int server_loop(command_context_t *command_context) #endif } - target_call_timer_callbacks(); - process_jim_events (); - if (retval == 0) { - /* do regular tasks after at most 100ms */ - tv.tv_sec = 0; - tv.tv_usec = 10000; + /* We only execute these callbacks when there was nothing to do or we timed out */ + target_call_timer_callbacks(); + process_jim_events(command_context); + FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */ + + /* We timed out/there was nothing to do, timeout rather than poll next time */ + poll = false; + } else + { + /* There was something to do, next time we'll just poll */ + poll = true; } for (service = services; service; service = service->next) @@ -423,7 +437,7 @@ int server_loop(command_context_t *command_context) /* handle activity on connections */ if (service->connections) { - connection_t *c; + struct connection *c; for (c = service->connections; c;) { @@ -431,7 +445,7 @@ int server_loop(command_context_t *command_context) { if ((retval = service->input(c)) != ERROR_OK) { - connection_t *next = c->next; + struct connection *next = c->next; if (service->type == CONNECTION_PIPE) { /* if connection uses a pipe then shutdown openocd on error */ @@ -487,8 +501,12 @@ void sig_handler(int sig) { } #endif -int server_init(void) +int server_preinit(void) { + /* this currently only calls WSAStartup on native win32 systems + * before any socket operations are performed. + * This is an issue if you call init in your config script */ + #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; @@ -521,6 +539,15 @@ int server_init(void) return ERROR_OK; } +int server_init(struct command_context *cmd_ctx) +{ + int ret = tcl_init(cmd_ctx); + if (ERROR_OK != ret) + return ret; + + return telnet_init("Open On-Chip Debugger"); +} + int server_quit(void) { remove_services(); @@ -534,35 +561,46 @@ int server_quit(void) } /* tell the server we want to shut down */ -static int handle_shutdown_command(struct command_context_s *cmd_ctx, - char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_shutdown_command) { shutdown_openocd = 1; return ERROR_COMMAND_CLOSE_CONNECTION; } -int server_register_commands(command_context_t *context) +static const struct command_registration server_command_handlers[] = { + { + .name = "shutdown", + .handler = &handle_shutdown_command, + .mode = COMMAND_ANY, + .help = "shut the server down", + }, + COMMAND_REGISTRATION_DONE +}; + +int server_register_commands(struct command_context *cmd_ctx) { - register_command(context, NULL, "shutdown", - handle_shutdown_command, COMMAND_ANY, - "shut the server down"); + int retval = telnet_register_commands(cmd_ctx); + if (ERROR_OK != retval) + return retval; - return ERROR_OK; -} + retval = tcl_register_commands(cmd_ctx); + if (ERROR_OK != retval) + return retval; + return register_commands(cmd_ctx, NULL, server_command_handlers); +} -int server_port_command(struct command_context_s *cmd_ctx, - char *cmd, char **args, int argc, unsigned short *out) +SERVER_PORT_COMMAND() { - switch (argc) { + switch (CMD_ARGC) { case 0: - command_print(cmd_ctx, "%d", *out); + command_print(CMD_CTX, "%d", *out); break; case 1: { uint16_t port; - COMMAND_PARSE_NUMBER(u16, args[0], port); + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port); *out = port; break; }