tcl: introduce using_(jtag|swd|hla) helpers and use them in reset handler
[fw/openocd] / src / server / server.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2007-2010 Ã˜yvind Harboe                                 *
6  *   oyvind.harboe@zylin.com                                               *
7  *                                                                         *
8  *   Copyright (C) 2008 by Spencer Oliver                                  *
9  *   spen@spen-soft.co.uk                                                  *
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  *   This program is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19  *   GNU General Public License for more details.                          *
20  *                                                                         *
21  *   You should have received a copy of the GNU General Public License     *
22  *   along with this program; if not, write to the                         *
23  *   Free Software Foundation, Inc.,                                       *
24  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
25  ***************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "server.h"
32 #include <target/target.h>
33 #include <target/target_request.h>
34 #include <target/openrisc/jsp_server.h>
35 #include "openocd.h"
36 #include "tcl_server.h"
37 #include "telnet_server.h"
38
39 #include <signal.h>
40
41 #ifndef _WIN32
42 #include <netinet/tcp.h>
43 #endif
44
45 static struct service *services;
46
47 /* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
48 static int shutdown_openocd;
49
50 /* set the polling period to 100ms */
51 static int polling_period = 100;
52
53 static int add_connection(struct service *service, struct command_context *cmd_ctx)
54 {
55         socklen_t address_size;
56         struct connection *c, **p;
57         int retval;
58         int flag = 1;
59
60         c = malloc(sizeof(struct connection));
61         c->fd = -1;
62         c->fd_out = -1;
63         memset(&c->sin, 0, sizeof(c->sin));
64         c->cmd_ctx = copy_command_context(cmd_ctx);
65         c->service = service;
66         c->input_pending = 0;
67         c->priv = NULL;
68         c->next = NULL;
69
70         if (service->type == CONNECTION_TCP) {
71                 address_size = sizeof(c->sin);
72
73                 c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
74                 c->fd_out = c->fd;
75
76                 /* This increases performance dramatically for e.g. GDB load which
77                  * does not have a sliding window protocol.
78                  *
79                  * Ignore errors from this fn as it probably just means less performance
80                  */
81                 setsockopt(c->fd,       /* socket affected */
82                         IPPROTO_TCP,                    /* set option at TCP level */
83                         TCP_NODELAY,                    /* name of option */
84                         (char *)&flag,                  /* the cast is historical cruft */
85                         sizeof(int));                   /* length of option value */
86
87                 LOG_INFO("accepting '%s' connection on tcp/%s", service->name, service->port);
88                 retval = service->new_connection(c);
89                 if (retval != ERROR_OK) {
90                         close_socket(c->fd);
91                         LOG_ERROR("attempted '%s' connection rejected", service->name);
92                         command_done(c->cmd_ctx);
93                         free(c);
94                         return retval;
95                 }
96         } else if (service->type == CONNECTION_STDINOUT) {
97                 c->fd = service->fd;
98                 c->fd_out = fileno(stdout);
99
100 #ifdef _WIN32
101                 /* we are using stdin/out so ignore ctrl-c under windoze */
102                 SetConsoleCtrlHandler(NULL, TRUE);
103 #endif
104
105                 /* do not check for new connections again on stdin */
106                 service->fd = -1;
107
108                 LOG_INFO("accepting '%s' connection from pipe", service->name);
109                 retval = service->new_connection(c);
110                 if (retval != ERROR_OK) {
111                         LOG_ERROR("attempted '%s' connection rejected", service->name);
112                         command_done(c->cmd_ctx);
113                         free(c);
114                         return retval;
115                 }
116         } else if (service->type == CONNECTION_PIPE) {
117                 c->fd = service->fd;
118                 /* do not check for new connections again on stdin */
119                 service->fd = -1;
120
121                 char *out_file = alloc_printf("%so", service->port);
122                 c->fd_out = open(out_file, O_WRONLY);
123                 free(out_file);
124                 if (c->fd_out == -1) {
125                         LOG_ERROR("could not open %s", service->port);
126                         exit(1);
127                 }
128
129                 LOG_INFO("accepting '%s' connection from pipe %s", service->name, service->port);
130                 retval = service->new_connection(c);
131                 if (retval != ERROR_OK) {
132                         LOG_ERROR("attempted '%s' connection rejected", service->name);
133                         command_done(c->cmd_ctx);
134                         free(c);
135                         return retval;
136                 }
137         }
138
139         /* add to the end of linked list */
140         for (p = &service->connections; *p; p = &(*p)->next)
141                 ;
142         *p = c;
143
144         service->max_connections--;
145
146         return ERROR_OK;
147 }
148
149 static int remove_connection(struct service *service, struct connection *connection)
150 {
151         struct connection **p = &service->connections;
152         struct connection *c;
153
154         /* find connection */
155         while ((c = *p)) {
156                 if (c->fd == connection->fd) {
157                         service->connection_closed(c);
158                         if (service->type == CONNECTION_TCP)
159                                 close_socket(c->fd);
160                         else if (service->type == CONNECTION_PIPE) {
161                                 /* The service will listen to the pipe again */
162                                 c->service->fd = c->fd;
163                         }
164
165                         command_done(c->cmd_ctx);
166
167                         /* delete connection */
168                         *p = c->next;
169                         free(c);
170
171                         service->max_connections++;
172                         break;
173                 }
174
175                 /* redirect p to next list pointer */
176                 p = &(*p)->next;
177         }
178
179         return ERROR_OK;
180 }
181
182 /* FIX! make service return error instead of invoking exit() */
183 int add_service(char *name,
184         const char *port,
185         int max_connections,
186         new_connection_handler_t new_connection_handler,
187         input_handler_t input_handler,
188         connection_closed_handler_t connection_closed_handler,
189         void *priv)
190 {
191         struct service *c, **p;
192         int so_reuseaddr_option = 1;
193
194         c = malloc(sizeof(struct service));
195
196         c->name = strdup(name);
197         c->port = strdup(port);
198         c->max_connections = 1; /* Only TCP/IP ports can support more than one connection */
199         c->fd = -1;
200         c->connections = NULL;
201         c->new_connection = new_connection_handler;
202         c->input = input_handler;
203         c->connection_closed = connection_closed_handler;
204         c->priv = priv;
205         c->next = NULL;
206         long portnumber;
207         if (strcmp(c->port, "pipe") == 0)
208                 c->type = CONNECTION_STDINOUT;
209         else {
210                 char *end;
211                 portnumber = strtol(c->port, &end, 0);
212                 if (!*end && (parse_long(c->port, &portnumber) == ERROR_OK)) {
213                         c->portnumber = portnumber;
214                         c->type = CONNECTION_TCP;
215                 } else
216                         c->type = CONNECTION_PIPE;
217         }
218
219         if (c->type == CONNECTION_TCP) {
220                 c->max_connections = max_connections;
221
222                 c->fd = socket(AF_INET, SOCK_STREAM, 0);
223                 if (c->fd == -1) {
224                         LOG_ERROR("error creating socket: %s", strerror(errno));
225                         exit(-1);
226                 }
227
228                 setsockopt(c->fd,
229                         SOL_SOCKET,
230                         SO_REUSEADDR,
231                         (void *)&so_reuseaddr_option,
232                         sizeof(int));
233
234                 socket_nonblock(c->fd);
235
236                 memset(&c->sin, 0, sizeof(c->sin));
237                 c->sin.sin_family = AF_INET;
238                 c->sin.sin_addr.s_addr = INADDR_ANY;
239                 c->sin.sin_port = htons(c->portnumber);
240
241                 if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
242                         LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
243                         exit(-1);
244                 }
245
246 #ifndef _WIN32
247                 int segsize = 65536;
248                 setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG,  &segsize, sizeof(int));
249 #endif
250                 int window_size = 128 * 1024;
251
252                 /* These setsockopt()s must happen before the listen() */
253
254                 setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
255                         (char *)&window_size, sizeof(window_size));
256                 setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
257                         (char *)&window_size, sizeof(window_size));
258
259                 if (listen(c->fd, 1) == -1) {
260                         LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
261                         exit(-1);
262                 }
263         } else if (c->type == CONNECTION_STDINOUT) {
264                 c->fd = fileno(stdin);
265
266 #ifdef _WIN32
267                 /* for win32 set stdin/stdout to binary mode */
268                 if (_setmode(_fileno(stdout), _O_BINARY) < 0)
269                         LOG_WARNING("cannot change stdout mode to binary");
270                 if (_setmode(_fileno(stdin), _O_BINARY) < 0)
271                         LOG_WARNING("cannot change stdin mode to binary");
272                 if (_setmode(_fileno(stderr), _O_BINARY) < 0)
273                         LOG_WARNING("cannot change stderr mode to binary");
274 #else
275                 socket_nonblock(c->fd);
276 #endif
277         } else if (c->type == CONNECTION_PIPE) {
278 #ifdef _WIN32
279                 /* we currenty do not support named pipes under win32
280                  * so exit openocd for now */
281                 LOG_ERROR("Named pipes currently not supported under this os");
282                 exit(1);
283 #else
284                 /* Pipe we're reading from */
285                 c->fd = open(c->port, O_RDONLY | O_NONBLOCK);
286                 if (c->fd == -1) {
287                         LOG_ERROR("could not open %s", c->port);
288                         exit(1);
289                 }
290 #endif
291         }
292
293         /* add to the end of linked list */
294         for (p = &services; *p; p = &(*p)->next)
295                 ;
296         *p = c;
297
298         return ERROR_OK;
299 }
300
301 static int remove_services(void)
302 {
303         struct service *c = services;
304
305         /* loop service */
306         while (c) {
307                 struct service *next = c->next;
308
309                 if (c->name)
310                         free(c->name);
311
312                 if (c->type == CONNECTION_PIPE) {
313                         if (c->fd != -1)
314                                 close(c->fd);
315                 }
316                 if (c->port)
317                         free(c->port);
318
319                 if (c->priv)
320                         free(c->priv);
321
322                 /* delete service */
323                 free(c);
324
325                 /* remember the last service for unlinking */
326                 c = next;
327         }
328
329         services = NULL;
330
331         return ERROR_OK;
332 }
333
334 int server_loop(struct command_context *command_context)
335 {
336         struct service *service;
337
338         bool poll_ok = true;
339
340         /* used in select() */
341         fd_set read_fds;
342         int fd_max;
343
344         /* used in accept() */
345         int retval;
346
347 #ifndef _WIN32
348         if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
349                 LOG_ERROR("couldn't set SIGPIPE to SIG_IGN");
350 #endif
351
352         while (!shutdown_openocd) {
353                 /* monitor sockets for activity */
354                 fd_max = 0;
355                 FD_ZERO(&read_fds);
356
357                 /* add service and connection fds to read_fds */
358                 for (service = services; service; service = service->next) {
359                         if (service->fd != -1) {
360                                 /* listen for new connections */
361                                 FD_SET(service->fd, &read_fds);
362
363                                 if (service->fd > fd_max)
364                                         fd_max = service->fd;
365                         }
366
367                         if (service->connections) {
368                                 struct connection *c;
369
370                                 for (c = service->connections; c; c = c->next) {
371                                         /* check for activity on the connection */
372                                         FD_SET(c->fd, &read_fds);
373                                         if (c->fd > fd_max)
374                                                 fd_max = c->fd;
375                                 }
376                         }
377                 }
378
379                 struct timeval tv;
380                 tv.tv_sec = 0;
381                 if (poll_ok) {
382                         /* we're just polling this iteration, this is faster on embedded
383                          * hosts */
384                         tv.tv_usec = 0;
385                         retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
386                 } else {
387                         /* Every 100ms, can be changed with "poll_period" command */
388                         tv.tv_usec = polling_period * 1000;
389                         /* Only while we're sleeping we'll let others run */
390                         openocd_sleep_prelude();
391                         kept_alive();
392                         retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
393                         openocd_sleep_postlude();
394                 }
395
396                 if (retval == -1) {
397 #ifdef _WIN32
398
399                         errno = WSAGetLastError();
400
401                         if (errno == WSAEINTR)
402                                 FD_ZERO(&read_fds);
403                         else {
404                                 LOG_ERROR("error during select: %s", strerror(errno));
405                                 exit(-1);
406                         }
407 #else
408
409                         if (errno == EINTR)
410                                 FD_ZERO(&read_fds);
411                         else {
412                                 LOG_ERROR("error during select: %s", strerror(errno));
413                                 exit(-1);
414                         }
415 #endif
416                 }
417
418                 if (retval == 0) {
419                         /* We only execute these callbacks when there was nothing to do or we timed
420                          *out */
421                         target_call_timer_callbacks();
422                         process_jim_events(command_context);
423
424                         FD_ZERO(&read_fds);     /* eCos leaves read_fds unchanged in this case!  */
425
426                         /* We timed out/there was nothing to do, timeout rather than poll next time
427                          **/
428                         poll_ok = false;
429                 } else {
430                         /* There was something to do, next time we'll just poll */
431                         poll_ok = true;
432                 }
433
434                 /* This is a simple back-off algorithm where we immediately
435                  * re-poll if we did something this time around.
436                  *
437                  * This greatly improves performance of DCC.
438                  */
439                 poll_ok = poll_ok || target_got_message();
440
441                 for (service = services; service; service = service->next) {
442                         /* handle new connections on listeners */
443                         if ((service->fd != -1)
444                             && (FD_ISSET(service->fd, &read_fds))) {
445                                 if (service->max_connections > 0)
446                                         add_connection(service, command_context);
447                                 else {
448                                         if (service->type == CONNECTION_TCP) {
449                                                 struct sockaddr_in sin;
450                                                 socklen_t address_size = sizeof(sin);
451                                                 int tmp_fd;
452                                                 tmp_fd = accept(service->fd,
453                                                                 (struct sockaddr *)&service->sin,
454                                                                 &address_size);
455                                                 close_socket(tmp_fd);
456                                         }
457                                         LOG_INFO(
458                                                 "rejected '%s' connection, no more connections allowed",
459                                                 service->name);
460                                 }
461                         }
462
463                         /* handle activity on connections */
464                         if (service->connections) {
465                                 struct connection *c;
466
467                                 for (c = service->connections; c; ) {
468                                         if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending) {
469                                                 retval = service->input(c);
470                                                 if (retval != ERROR_OK) {
471                                                         struct connection *next = c->next;
472                                                         if (service->type == CONNECTION_PIPE ||
473                                                                         service->type == CONNECTION_STDINOUT) {
474                                                                 /* if connection uses a pipe then
475                                                                  * shutdown openocd on error */
476                                                                 shutdown_openocd = 1;
477                                                         }
478                                                         remove_connection(service, c);
479                                                         LOG_INFO("dropped '%s' connection",
480                                                                 service->name);
481                                                         c = next;
482                                                         continue;
483                                                 }
484                                         }
485                                         c = c->next;
486                                 }
487                         }
488                 }
489
490 #ifdef _WIN32
491                 MSG msg;
492                 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
493                         if (msg.message == WM_QUIT)
494                                 shutdown_openocd = 1;
495                 }
496 #endif
497         }
498
499         return ERROR_OK;
500 }
501
502 #ifdef _WIN32
503 BOOL WINAPI ControlHandler(DWORD dwCtrlType)
504 {
505         shutdown_openocd = 1;
506         return TRUE;
507 }
508
509 void sig_handler(int sig)
510 {
511         shutdown_openocd = 1;
512 }
513 #endif
514
515 int server_preinit(void)
516 {
517         /* this currently only calls WSAStartup on native win32 systems
518          * before any socket operations are performed.
519          * This is an issue if you call init in your config script */
520
521 #ifdef _WIN32
522         WORD wVersionRequested;
523         WSADATA wsaData;
524
525         wVersionRequested = MAKEWORD(2, 2);
526
527         if (WSAStartup(wVersionRequested, &wsaData) != 0) {
528                 LOG_ERROR("Failed to Open Winsock");
529                 exit(-1);
530         }
531
532         /* register ctrl-c handler */
533         SetConsoleCtrlHandler(ControlHandler, TRUE);
534
535         signal(SIGINT, sig_handler);
536         signal(SIGTERM, sig_handler);
537         signal(SIGBREAK, sig_handler);
538         signal(SIGABRT, sig_handler);
539 #endif
540
541         return ERROR_OK;
542 }
543
544 int server_init(struct command_context *cmd_ctx)
545 {
546         int ret = tcl_init();
547         if (ERROR_OK != ret)
548                 return ret;
549
550         return telnet_init("Open On-Chip Debugger");
551 }
552
553 int server_quit(void)
554 {
555         remove_services();
556
557 #ifdef _WIN32
558         WSACleanup();
559         SetConsoleCtrlHandler(ControlHandler, FALSE);
560 #endif
561
562         return ERROR_OK;
563 }
564
565 int connection_write(struct connection *connection, const void *data, int len)
566 {
567         if (len == 0) {
568                 /* successful no-op. Sockets and pipes behave differently here... */
569                 return 0;
570         }
571         if (connection->service->type == CONNECTION_TCP)
572                 return write_socket(connection->fd_out, data, len);
573         else
574                 return write(connection->fd_out, data, len);
575 }
576
577 int connection_read(struct connection *connection, void *data, int len)
578 {
579         if (connection->service->type == CONNECTION_TCP)
580                 return read_socket(connection->fd, data, len);
581         else
582                 return read(connection->fd, data, len);
583 }
584
585 /* tell the server we want to shut down */
586 COMMAND_HANDLER(handle_shutdown_command)
587 {
588         LOG_USER("shutdown command invoked");
589
590         shutdown_openocd = 1;
591
592         return ERROR_OK;
593 }
594
595 COMMAND_HANDLER(handle_poll_period_command)
596 {
597         if (CMD_ARGC == 0)
598                 LOG_WARNING("You need to set a period value");
599         else
600                 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], polling_period);
601
602         LOG_INFO("set servers polling period to %ums", polling_period);
603
604         return ERROR_OK;
605 }
606
607 static const struct command_registration server_command_handlers[] = {
608         {
609                 .name = "shutdown",
610                 .handler = &handle_shutdown_command,
611                 .mode = COMMAND_ANY,
612                 .usage = "",
613                 .help = "shut the server down",
614         },
615         {
616                 .name = "poll_period",
617                 .handler = &handle_poll_period_command,
618                 .mode = COMMAND_ANY,
619                 .usage = "",
620                 .help = "set the servers polling period",
621         },
622         COMMAND_REGISTRATION_DONE
623 };
624
625 int server_register_commands(struct command_context *cmd_ctx)
626 {
627         int retval = telnet_register_commands(cmd_ctx);
628         if (ERROR_OK != retval)
629                 return retval;
630
631         retval = tcl_register_commands(cmd_ctx);
632         if (ERROR_OK != retval)
633                 return retval;
634
635         retval = jsp_register_commands(cmd_ctx);
636         if (ERROR_OK != retval)
637                 return retval;
638
639         return register_commands(cmd_ctx, NULL, server_command_handlers);
640 }
641
642 COMMAND_HELPER(server_port_command, unsigned short *out)
643 {
644         switch (CMD_ARGC) {
645                 case 0:
646                         command_print(CMD_CTX, "%d", *out);
647                         break;
648                 case 1:
649                 {
650                         uint16_t port;
651                         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
652                         *out = port;
653                         break;
654                 }
655                 default:
656                         return ERROR_COMMAND_SYNTAX_ERROR;
657         }
658         return ERROR_OK;
659 }
660
661 COMMAND_HELPER(server_pipe_command, char **out)
662 {
663         switch (CMD_ARGC) {
664                 case 0:
665                         command_print(CMD_CTX, "%s", *out);
666                         break;
667                 case 1:
668                 {
669                         if (CMD_CTX->mode == COMMAND_EXEC) {
670                                 LOG_WARNING("unable to change server port after init");
671                                 return ERROR_COMMAND_ARGUMENT_INVALID;
672                         }
673                         free(*out);
674                         *out = strdup(CMD_ARGV[0]);
675                         break;
676                 }
677                 default:
678                         return ERROR_COMMAND_SYNTAX_ERROR;
679         }
680         return ERROR_OK;
681 }