server: change prototype of add_service()
To easily add new methods to a service, pass all the methods through a struct. While there, drop the typedef for the methods and add currently unused new methods to support keep-alive and connections during keep-alive. No change in functionality. Change-Id: I2b5e7140db95021f6e7201e9d631ee340c60b453 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: https://review.openocd.org/c/openocd/+/6838 Reviewed-by: Tomas Vanek <vanekt@fbl.cz> Tested-by: jenkins
This commit is contained in:
parent
36e29f49e1
commit
99c77806fe
|
@ -3657,6 +3657,15 @@ static int gdb_input(struct connection *connection)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct service_driver gdb_service_driver = {
|
||||||
|
.name = "gdb",
|
||||||
|
.new_connection_during_keep_alive_handler = NULL,
|
||||||
|
.new_connection_handler = gdb_new_connection,
|
||||||
|
.input_handler = gdb_input,
|
||||||
|
.connection_closed_handler = gdb_connection_closed,
|
||||||
|
.keep_client_alive_handler = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
static int gdb_target_start(struct target *target, const char *port)
|
static int gdb_target_start(struct target *target, const char *port)
|
||||||
{
|
{
|
||||||
struct gdb_service *gdb_service;
|
struct gdb_service *gdb_service;
|
||||||
|
@ -3673,9 +3682,7 @@ static int gdb_target_start(struct target *target, const char *port)
|
||||||
gdb_service->core[1] = -1;
|
gdb_service->core[1] = -1;
|
||||||
target->gdb_service = gdb_service;
|
target->gdb_service = gdb_service;
|
||||||
|
|
||||||
ret = add_service("gdb",
|
ret = add_service(&gdb_service_driver, port, target->gdb_max_connections, gdb_service);
|
||||||
port, target->gdb_max_connections, &gdb_new_connection, &gdb_input,
|
|
||||||
&gdb_connection_closed, gdb_service);
|
|
||||||
/* initialize all targets gdb service with the same pointer */
|
/* initialize all targets gdb service with the same pointer */
|
||||||
{
|
{
|
||||||
struct target_list *head;
|
struct target_list *head;
|
||||||
|
|
|
@ -587,6 +587,15 @@ static int ipdbg_on_connection_closed(struct connection *connection)
|
||||||
return ipdbg_stop_polling(connection->service->priv);
|
return ipdbg_stop_polling(connection->service->priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct service_driver ipdbg_service_driver = {
|
||||||
|
.name = "ipdbg",
|
||||||
|
.new_connection_during_keep_alive_handler = NULL,
|
||||||
|
.new_connection_handler = ipdbg_on_new_connection,
|
||||||
|
.input_handler = ipdbg_on_connection_input,
|
||||||
|
.connection_closed_handler = ipdbg_on_connection_closed,
|
||||||
|
.keep_client_alive_handler = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
static int ipdbg_start(uint16_t port, struct jtag_tap *tap, uint32_t user_instruction,
|
static int ipdbg_start(uint16_t port, struct jtag_tap *tap, uint32_t user_instruction,
|
||||||
uint8_t data_register_length, struct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool)
|
uint8_t data_register_length, struct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool)
|
||||||
{
|
{
|
||||||
|
@ -618,8 +627,7 @@ static int ipdbg_start(uint16_t port, struct jtag_tap *tap, uint32_t user_instru
|
||||||
|
|
||||||
char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
|
char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
|
||||||
snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", port);
|
snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", port);
|
||||||
retval = add_service("ipdbg", port_str_buffer, 1, &ipdbg_on_new_connection,
|
retval = add_service(&ipdbg_service_driver, port_str_buffer, 1, service);
|
||||||
&ipdbg_on_connection_input, &ipdbg_on_connection_closed, service);
|
|
||||||
if (retval == ERROR_OK) {
|
if (retval == ERROR_OK) {
|
||||||
ipdbg_add_service(service);
|
ipdbg_add_service(service);
|
||||||
if (hub->active_services == 0 && hub->active_connections == 0)
|
if (hub->active_services == 0 && hub->active_connections == 0)
|
||||||
|
|
|
@ -110,6 +110,15 @@ static int rtt_input(struct connection *connection)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct service_driver rtt_service_driver = {
|
||||||
|
.name = "rtt",
|
||||||
|
.new_connection_during_keep_alive_handler = NULL,
|
||||||
|
.new_connection_handler = rtt_new_connection,
|
||||||
|
.input_handler = rtt_input,
|
||||||
|
.connection_closed_handler = rtt_connection_closed,
|
||||||
|
.keep_client_alive_handler = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
COMMAND_HANDLER(handle_rtt_start_command)
|
COMMAND_HANDLER(handle_rtt_start_command)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -125,8 +134,7 @@ COMMAND_HANDLER(handle_rtt_start_command)
|
||||||
|
|
||||||
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], service->channel);
|
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], service->channel);
|
||||||
|
|
||||||
ret = add_service("rtt", CMD_ARGV[0], CONNECTION_LIMIT_UNLIMITED,
|
ret = add_service(&rtt_service_driver, CMD_ARGV[0], CONNECTION_LIMIT_UNLIMITED, service);
|
||||||
rtt_new_connection, rtt_input, rtt_connection_closed, service);
|
|
||||||
|
|
||||||
if (ret != ERROR_OK) {
|
if (ret != ERROR_OK) {
|
||||||
free(service);
|
free(service);
|
||||||
|
|
|
@ -205,13 +205,8 @@ static void free_service(struct service *c)
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_service(char *name,
|
int add_service(const struct service_driver *driver, const char *port,
|
||||||
const char *port,
|
int max_connections, void *priv)
|
||||||
int max_connections,
|
|
||||||
new_connection_handler_t new_connection_handler,
|
|
||||||
input_handler_t input_handler,
|
|
||||||
connection_closed_handler_t connection_closed_handler,
|
|
||||||
void *priv)
|
|
||||||
{
|
{
|
||||||
struct service *c, **p;
|
struct service *c, **p;
|
||||||
struct hostent *hp;
|
struct hostent *hp;
|
||||||
|
@ -219,14 +214,16 @@ int add_service(char *name,
|
||||||
|
|
||||||
c = malloc(sizeof(struct service));
|
c = malloc(sizeof(struct service));
|
||||||
|
|
||||||
c->name = strdup(name);
|
c->name = strdup(driver->name);
|
||||||
c->port = strdup(port);
|
c->port = strdup(port);
|
||||||
c->max_connections = 1; /* Only TCP/IP ports can support more than one connection */
|
c->max_connections = 1; /* Only TCP/IP ports can support more than one connection */
|
||||||
c->fd = -1;
|
c->fd = -1;
|
||||||
c->connections = NULL;
|
c->connections = NULL;
|
||||||
c->new_connection = new_connection_handler;
|
c->new_connection_during_keep_alive = driver->new_connection_during_keep_alive_handler;
|
||||||
c->input = input_handler;
|
c->new_connection = driver->new_connection_handler;
|
||||||
c->connection_closed = connection_closed_handler;
|
c->input = driver->input_handler;
|
||||||
|
c->connection_closed = driver->connection_closed_handler;
|
||||||
|
c->keep_client_alive = driver->keep_client_alive_handler;
|
||||||
c->priv = priv;
|
c->priv = priv;
|
||||||
c->next = NULL;
|
c->next = NULL;
|
||||||
long portnumber;
|
long portnumber;
|
||||||
|
@ -278,7 +275,7 @@ int add_service(char *name,
|
||||||
c->sin.sin_port = htons(c->portnumber);
|
c->sin.sin_port = htons(c->portnumber);
|
||||||
|
|
||||||
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
|
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
|
||||||
LOG_ERROR("couldn't bind %s to socket on port %d: %s", name, c->portnumber, strerror(errno));
|
LOG_ERROR("couldn't bind %s to socket on port %d: %s", c->name, c->portnumber, strerror(errno));
|
||||||
close_socket(c->fd);
|
close_socket(c->fd);
|
||||||
free_service(c);
|
free_service(c);
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
@ -309,7 +306,7 @@ int add_service(char *name,
|
||||||
socklen_t addr_in_size = sizeof(addr_in);
|
socklen_t addr_in_size = sizeof(addr_in);
|
||||||
if (getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0)
|
if (getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0)
|
||||||
LOG_INFO("Listening on port %hu for %s connections",
|
LOG_INFO("Listening on port %hu for %s connections",
|
||||||
ntohs(addr_in.sin_port), name);
|
ntohs(addr_in.sin_port), c->name);
|
||||||
} else if (c->type == CONNECTION_STDINOUT) {
|
} else if (c->type == CONNECTION_STDINOUT) {
|
||||||
c->fd = fileno(stdin);
|
c->fd = fileno(stdin);
|
||||||
|
|
||||||
|
|
|
@ -55,9 +55,25 @@ struct connection {
|
||||||
struct connection *next;
|
struct connection *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*new_connection_handler_t)(struct connection *connection);
|
struct service_driver {
|
||||||
typedef int (*input_handler_t)(struct connection *connection);
|
/** the name of the server */
|
||||||
typedef int (*connection_closed_handler_t)(struct connection *connection);
|
const char *name;
|
||||||
|
/** optional minimal setup to accept a connection during keep-alive */
|
||||||
|
int (*new_connection_during_keep_alive_handler)(struct connection *connection);
|
||||||
|
/**
|
||||||
|
* complete code to accept a new connection.
|
||||||
|
* If 'new_connection_during_keep_alive_handler' above is present, this can be
|
||||||
|
* either called alone during the server_loop, or after the function above.
|
||||||
|
* Check the implementation in gdb_server.
|
||||||
|
* */
|
||||||
|
int (*new_connection_handler)(struct connection *connection);
|
||||||
|
/** callback to handle incoming data */
|
||||||
|
int (*input_handler)(struct connection *connection);
|
||||||
|
/** callback to tear down the connection */
|
||||||
|
int (*connection_closed_handler)(struct connection *connection);
|
||||||
|
/** called periodically to send keep-alive messages on the connection */
|
||||||
|
void (*keep_client_alive_handler)(struct connection *connection);
|
||||||
|
};
|
||||||
|
|
||||||
struct service {
|
struct service {
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -68,17 +84,17 @@ struct service {
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
int max_connections;
|
int max_connections;
|
||||||
struct connection *connections;
|
struct connection *connections;
|
||||||
new_connection_handler_t new_connection;
|
int (*new_connection_during_keep_alive)(struct connection *connection);
|
||||||
input_handler_t input;
|
int (*new_connection)(struct connection *connection);
|
||||||
connection_closed_handler_t connection_closed;
|
int (*input)(struct connection *connection);
|
||||||
|
int (*connection_closed)(struct connection *connection);
|
||||||
|
void (*keep_client_alive)(struct connection *connection);
|
||||||
void *priv;
|
void *priv;
|
||||||
struct service *next;
|
struct service *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
int add_service(char *name, const char *port,
|
int add_service(const struct service_driver *driver, const char *port,
|
||||||
int max_connections, new_connection_handler_t new_connection_handler,
|
int max_connections, void *priv);
|
||||||
input_handler_t in_handler, connection_closed_handler_t close_handler,
|
|
||||||
void *priv);
|
|
||||||
int remove_service(const char *name, const char *port);
|
int remove_service(const char *name, const char *port);
|
||||||
|
|
||||||
int server_host_os_entry(void);
|
int server_host_os_entry(void);
|
||||||
|
|
|
@ -276,6 +276,15 @@ static int tcl_closed(struct connection *connection)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct service_driver tcl_service_driver = {
|
||||||
|
.name = "tcl",
|
||||||
|
.new_connection_during_keep_alive_handler = NULL,
|
||||||
|
.new_connection_handler = tcl_new_connection,
|
||||||
|
.input_handler = tcl_input,
|
||||||
|
.connection_closed_handler = tcl_closed,
|
||||||
|
.keep_client_alive_handler = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
int tcl_init(void)
|
int tcl_init(void)
|
||||||
{
|
{
|
||||||
if (strcmp(tcl_port, "disabled") == 0) {
|
if (strcmp(tcl_port, "disabled") == 0) {
|
||||||
|
@ -283,9 +292,7 @@ int tcl_init(void)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return add_service("tcl", tcl_port, CONNECTION_LIMIT_UNLIMITED,
|
return add_service(&tcl_service_driver, tcl_port, CONNECTION_LIMIT_UNLIMITED, NULL);
|
||||||
&tcl_new_connection, &tcl_input,
|
|
||||||
&tcl_closed, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_HANDLER(handle_tcl_port_command)
|
COMMAND_HANDLER(handle_tcl_port_command)
|
||||||
|
|
|
@ -946,6 +946,15 @@ static int telnet_connection_closed(struct connection *connection)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct service_driver telnet_service_driver = {
|
||||||
|
.name = "telnet",
|
||||||
|
.new_connection_during_keep_alive_handler = NULL,
|
||||||
|
.new_connection_handler = telnet_new_connection,
|
||||||
|
.input_handler = telnet_input,
|
||||||
|
.connection_closed_handler = telnet_connection_closed,
|
||||||
|
.keep_client_alive_handler = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
int telnet_init(char *banner)
|
int telnet_init(char *banner)
|
||||||
{
|
{
|
||||||
if (strcmp(telnet_port, "disabled") == 0) {
|
if (strcmp(telnet_port, "disabled") == 0) {
|
||||||
|
@ -963,8 +972,7 @@ int telnet_init(char *banner)
|
||||||
|
|
||||||
telnet_service->banner = banner;
|
telnet_service->banner = banner;
|
||||||
|
|
||||||
int ret = add_service("telnet", telnet_port, CONNECTION_LIMIT_UNLIMITED,
|
int ret = add_service(&telnet_service_driver, telnet_port, CONNECTION_LIMIT_UNLIMITED,
|
||||||
telnet_new_connection, telnet_input, telnet_connection_closed,
|
|
||||||
telnet_service);
|
telnet_service);
|
||||||
|
|
||||||
if (ret != ERROR_OK) {
|
if (ret != ERROR_OK) {
|
||||||
|
|
|
@ -582,6 +582,15 @@ static int wrap_read_u32(struct target *target, struct adiv5_ap *tpiu_ap,
|
||||||
return mem_ap_read_atomic_u32(tpiu_ap, address, value);
|
return mem_ap_read_atomic_u32(tpiu_ap, address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct service_driver arm_tpiu_swo_service_driver = {
|
||||||
|
.name = "tpiu_swo_trace",
|
||||||
|
.new_connection_during_keep_alive_handler = NULL,
|
||||||
|
.new_connection_handler = arm_tpiu_swo_service_new_connection,
|
||||||
|
.input_handler = arm_tpiu_swo_service_input,
|
||||||
|
.connection_closed_handler = arm_tpiu_swo_service_connection_closed,
|
||||||
|
.keep_client_alive_handler = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||||
{
|
{
|
||||||
struct command *c = jim_to_command(interp);
|
struct command *c = jim_to_command(interp);
|
||||||
|
@ -700,10 +709,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
|
||||||
}
|
}
|
||||||
priv->obj = obj;
|
priv->obj = obj;
|
||||||
LOG_INFO("starting trace server for %s on %s", obj->name, &obj->out_filename[1]);
|
LOG_INFO("starting trace server for %s on %s", obj->name, &obj->out_filename[1]);
|
||||||
retval = add_service("tpiu_swo_trace", &obj->out_filename[1],
|
retval = add_service(&arm_tpiu_swo_service_driver, &obj->out_filename[1],
|
||||||
CONNECTION_LIMIT_UNLIMITED, arm_tpiu_swo_service_new_connection,
|
CONNECTION_LIMIT_UNLIMITED, priv);
|
||||||
arm_tpiu_swo_service_input, arm_tpiu_swo_service_connection_closed,
|
|
||||||
priv);
|
|
||||||
if (retval != ERROR_OK) {
|
if (retval != ERROR_OK) {
|
||||||
LOG_ERROR("Can't configure trace TCP port %s", &obj->out_filename[1]);
|
LOG_ERROR("Can't configure trace TCP port %s", &obj->out_filename[1]);
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
|
|
|
@ -195,19 +195,22 @@ static int jsp_connection_closed(struct connection *connection)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct service_driver jsp_service_driver = {
|
||||||
|
.name = "jsp",
|
||||||
|
.new_connection_during_keep_alive_handler = NULL,
|
||||||
|
.new_connection_handler = jsp_new_connection,
|
||||||
|
.input_handler = jsp_input,
|
||||||
|
.connection_closed_handler = jsp_connection_closed,
|
||||||
|
.keep_client_alive_handler = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
int jsp_init(struct or1k_jtag *jtag_info, char *banner)
|
int jsp_init(struct or1k_jtag *jtag_info, char *banner)
|
||||||
{
|
{
|
||||||
struct jsp_service *jsp_service = malloc(sizeof(struct jsp_service));
|
struct jsp_service *jsp_service = malloc(sizeof(struct jsp_service));
|
||||||
jsp_service->banner = banner;
|
jsp_service->banner = banner;
|
||||||
jsp_service->jtag_info = jtag_info;
|
jsp_service->jtag_info = jtag_info;
|
||||||
|
|
||||||
return add_service("jsp",
|
return add_service(&jsp_service_driver, jsp_port, 1, jsp_service);
|
||||||
jsp_port,
|
|
||||||
1,
|
|
||||||
jsp_new_connection,
|
|
||||||
jsp_input,
|
|
||||||
jsp_connection_closed,
|
|
||||||
jsp_service);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMAND_HANDLER(handle_jsp_port_command)
|
COMMAND_HANDLER(handle_jsp_port_command)
|
||||||
|
|
Loading…
Reference in New Issue