Call poll at a fixed interval.
[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, see <http://www.gnu.org/licenses/>. *
23  ***************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "server.h"
30 #include <target/target.h>
31 #include <target/target_request.h>
32 #include <target/openrisc/jsp_server.h>
33 #include "openocd.h"
34 #include "tcl_server.h"
35 #include "telnet_server.h"
36 #include "time_support.h"
37
38 #include <signal.h>
39
40 #ifdef HAVE_NETDB_H
41 #include <netdb.h>
42 #endif
43
44 #ifndef _WIN32
45 #include <netinet/tcp.h>
46 #endif
47
48 static struct service *services;
49
50 enum shutdown_reason {
51         CONTINUE_MAIN_LOOP,                     /* stay in main event loop */
52         SHUTDOWN_REQUESTED,                     /* set by shutdown command; exit the event loop and quit the debugger */
53         SHUTDOWN_WITH_ERROR_CODE,       /* set by shutdown command; quit with non-zero return code */
54         SHUTDOWN_WITH_SIGNAL_CODE       /* set by sig_handler; exec shutdown then exit with signal as return code */
55 };
56 static enum shutdown_reason shutdown_openocd = CONTINUE_MAIN_LOOP;
57
58 /* store received signal to exit application by killing ourselves */
59 static int last_signal;
60
61 /* set the polling period to 100ms */
62 static int polling_period = 100;
63
64 /* address by name on which to listen for incoming TCP/IP connections */
65 static char *bindto_name;
66
67 static int add_connection(struct service *service, struct command_context *cmd_ctx)
68 {
69         socklen_t address_size;
70         struct connection *c, **p;
71         int retval;
72         int flag = 1;
73
74         c = malloc(sizeof(struct connection));
75         c->fd = -1;
76         c->fd_out = -1;
77         memset(&c->sin, 0, sizeof(c->sin));
78         c->cmd_ctx = copy_command_context(cmd_ctx);
79         c->service = service;
80         c->input_pending = false;
81         c->priv = NULL;
82         c->next = NULL;
83
84         if (service->type == CONNECTION_TCP) {
85                 address_size = sizeof(c->sin);
86
87                 c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
88                 c->fd_out = c->fd;
89
90                 /* This increases performance dramatically for e.g. GDB load which
91                  * does not have a sliding window protocol.
92                  *
93                  * Ignore errors from this fn as it probably just means less performance
94                  */
95                 setsockopt(c->fd,       /* socket affected */
96                         IPPROTO_TCP,                    /* set option at TCP level */
97                         TCP_NODELAY,                    /* name of option */
98                         (char *)&flag,                  /* the cast is historical cruft */
99                         sizeof(int));                   /* length of option value */
100
101                 LOG_INFO("accepting '%s' connection on tcp/%s", service->name, service->port);
102                 retval = service->new_connection(c);
103                 if (retval != ERROR_OK) {
104                         close_socket(c->fd);
105                         LOG_ERROR("attempted '%s' connection rejected", service->name);
106                         command_done(c->cmd_ctx);
107                         free(c);
108                         return retval;
109                 }
110         } else if (service->type == CONNECTION_STDINOUT) {
111                 c->fd = service->fd;
112                 c->fd_out = fileno(stdout);
113
114 #ifdef _WIN32
115                 /* we are using stdin/out so ignore ctrl-c under windoze */
116                 SetConsoleCtrlHandler(NULL, TRUE);
117 #endif
118
119                 /* do not check for new connections again on stdin */
120                 service->fd = -1;
121
122                 LOG_INFO("accepting '%s' connection from pipe", service->name);
123                 retval = service->new_connection(c);
124                 if (retval != ERROR_OK) {
125                         LOG_ERROR("attempted '%s' connection rejected", service->name);
126                         command_done(c->cmd_ctx);
127                         free(c);
128                         return retval;
129                 }
130         } else if (service->type == CONNECTION_PIPE) {
131                 c->fd = service->fd;
132                 /* do not check for new connections again on stdin */
133                 service->fd = -1;
134
135                 char *out_file = alloc_printf("%so", service->port);
136                 c->fd_out = open(out_file, O_WRONLY);
137                 free(out_file);
138                 if (c->fd_out == -1) {
139                         LOG_ERROR("could not open %s", service->port);
140                         command_done(c->cmd_ctx);
141                         free(c);
142                         return ERROR_FAIL;
143                 }
144
145                 LOG_INFO("accepting '%s' connection from pipe %s", service->name, service->port);
146                 retval = service->new_connection(c);
147                 if (retval != ERROR_OK) {
148                         LOG_ERROR("attempted '%s' connection rejected", service->name);
149                         command_done(c->cmd_ctx);
150                         free(c);
151                         return retval;
152                 }
153         }
154
155         /* add to the end of linked list */
156         for (p = &service->connections; *p; p = &(*p)->next)
157                 ;
158         *p = c;
159
160         if (service->max_connections != CONNECTION_LIMIT_UNLIMITED)
161                 service->max_connections--;
162
163         return ERROR_OK;
164 }
165
166 static int remove_connection(struct service *service, struct connection *connection)
167 {
168         struct connection **p = &service->connections;
169         struct connection *c;
170
171         /* find connection */
172         while ((c = *p)) {
173                 if (c->fd == connection->fd) {
174                         service->connection_closed(c);
175                         if (service->type == CONNECTION_TCP)
176                                 close_socket(c->fd);
177                         else if (service->type == CONNECTION_PIPE) {
178                                 /* The service will listen to the pipe again */
179                                 c->service->fd = c->fd;
180                         }
181
182                         command_done(c->cmd_ctx);
183
184                         /* delete connection */
185                         *p = c->next;
186                         free(c);
187
188                         if (service->max_connections != CONNECTION_LIMIT_UNLIMITED)
189                                 service->max_connections++;
190
191                         break;
192                 }
193
194                 /* redirect p to next list pointer */
195                 p = &(*p)->next;
196         }
197
198         return ERROR_OK;
199 }
200
201 static void free_service(struct service *c)
202 {
203         free(c->name);
204         free(c->port);
205         free(c);
206 }
207
208 int add_service(char *name,
209         const char *port,
210         int max_connections,
211         new_connection_handler_t new_connection_handler,
212         input_handler_t input_handler,
213         connection_closed_handler_t connection_closed_handler,
214         void *priv)
215 {
216         struct service *c, **p;
217         struct hostent *hp;
218         int so_reuseaddr_option = 1;
219
220         c = malloc(sizeof(struct service));
221
222         c->name = strdup(name);
223         c->port = strdup(port);
224         c->max_connections = 1; /* Only TCP/IP ports can support more than one connection */
225         c->fd = -1;
226         c->connections = NULL;
227         c->new_connection = new_connection_handler;
228         c->input = input_handler;
229         c->connection_closed = connection_closed_handler;
230         c->priv = priv;
231         c->next = NULL;
232         long portnumber;
233         if (strcmp(c->port, "pipe") == 0)
234                 c->type = CONNECTION_STDINOUT;
235         else {
236                 char *end;
237                 portnumber = strtol(c->port, &end, 0);
238                 if (!*end && (parse_long(c->port, &portnumber) == ERROR_OK)) {
239                         c->portnumber = portnumber;
240                         c->type = CONNECTION_TCP;
241                 } else
242                         c->type = CONNECTION_PIPE;
243         }
244
245         if (c->type == CONNECTION_TCP) {
246                 c->max_connections = max_connections;
247
248                 c->fd = socket(AF_INET, SOCK_STREAM, 0);
249                 if (c->fd == -1) {
250                         LOG_ERROR("error creating socket: %s", strerror(errno));
251                         free_service(c);
252                         return ERROR_FAIL;
253                 }
254
255                 setsockopt(c->fd,
256                         SOL_SOCKET,
257                         SO_REUSEADDR,
258                         (void *)&so_reuseaddr_option,
259                         sizeof(int));
260
261                 socket_nonblock(c->fd);
262
263                 memset(&c->sin, 0, sizeof(c->sin));
264                 c->sin.sin_family = AF_INET;
265
266                 if (!bindto_name)
267                         c->sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
268                 else {
269                         hp = gethostbyname(bindto_name);
270                         if (!hp) {
271                                 LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
272                                 close_socket(c->fd);
273                                 free_service(c);
274                                 return ERROR_FAIL;
275                         }
276                         memcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);
277                 }
278                 c->sin.sin_port = htons(c->portnumber);
279
280                 if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
281                         LOG_ERROR("couldn't bind %s to socket on port %d: %s", name, c->portnumber, strerror(errno));
282                         close_socket(c->fd);
283                         free_service(c);
284                         return ERROR_FAIL;
285                 }
286
287 #ifndef _WIN32
288                 int segsize = 65536;
289                 setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG,  &segsize, sizeof(int));
290 #endif
291                 int window_size = 128 * 1024;
292
293                 /* These setsockopt()s must happen before the listen() */
294
295                 setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
296                         (char *)&window_size, sizeof(window_size));
297                 setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
298                         (char *)&window_size, sizeof(window_size));
299
300                 if (listen(c->fd, 1) == -1) {
301                         LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
302                         close_socket(c->fd);
303                         free_service(c);
304                         return ERROR_FAIL;
305                 }
306
307                 struct sockaddr_in addr_in;
308                 addr_in.sin_port = 0;
309                 socklen_t addr_in_size = sizeof(addr_in);
310                 if (getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0)
311                         LOG_INFO("Listening on port %hu for %s connections",
312                                  ntohs(addr_in.sin_port), name);
313         } else if (c->type == CONNECTION_STDINOUT) {
314                 c->fd = fileno(stdin);
315
316 #ifdef _WIN32
317                 /* for win32 set stdin/stdout to binary mode */
318                 if (_setmode(_fileno(stdout), _O_BINARY) < 0)
319                         LOG_WARNING("cannot change stdout mode to binary");
320                 if (_setmode(_fileno(stdin), _O_BINARY) < 0)
321                         LOG_WARNING("cannot change stdin mode to binary");
322                 if (_setmode(_fileno(stderr), _O_BINARY) < 0)
323                         LOG_WARNING("cannot change stderr mode to binary");
324 #else
325                 socket_nonblock(c->fd);
326 #endif
327         } else if (c->type == CONNECTION_PIPE) {
328 #ifdef _WIN32
329                 /* we currently do not support named pipes under win32
330                  * so exit openocd for now */
331                 LOG_ERROR("Named pipes currently not supported under this os");
332                 free_service(c);
333                 return ERROR_FAIL;
334 #else
335                 /* Pipe we're reading from */
336                 c->fd = open(c->port, O_RDONLY | O_NONBLOCK);
337                 if (c->fd == -1) {
338                         LOG_ERROR("could not open %s", c->port);
339                         free_service(c);
340                         return ERROR_FAIL;
341                 }
342 #endif
343         }
344
345         /* add to the end of linked list */
346         for (p = &services; *p; p = &(*p)->next)
347                 ;
348         *p = c;
349
350         return ERROR_OK;
351 }
352
353 static void remove_connections(struct service *service)
354 {
355         struct connection *connection;
356
357         connection = service->connections;
358
359         while (connection) {
360                 struct connection *tmp;
361
362                 tmp = connection->next;
363                 remove_connection(service, connection);
364                 connection = tmp;
365         }
366 }
367
368 int remove_service(const char *name, const char *port)
369 {
370         struct service *tmp;
371         struct service *prev;
372
373         prev = services;
374
375         for (tmp = services; tmp; prev = tmp, tmp = tmp->next) {
376                 if (!strcmp(tmp->name, name) && !strcmp(tmp->port, port)) {
377                         remove_connections(tmp);
378
379                         if (tmp == services)
380                                 services = tmp->next;
381                         else
382                                 prev->next = tmp->next;
383
384                         if (tmp->type != CONNECTION_STDINOUT)
385                                 close_socket(tmp->fd);
386
387                         free(tmp->priv);
388                         free_service(tmp);
389
390                         return ERROR_OK;
391                 }
392         }
393
394         return ERROR_OK;
395 }
396
397 static int remove_services(void)
398 {
399         struct service *c = services;
400
401         /* loop service */
402         while (c) {
403                 struct service *next = c->next;
404
405                 remove_connections(c);
406
407                 free(c->name);
408
409                 if (c->type == CONNECTION_PIPE) {
410                         if (c->fd != -1)
411                                 close(c->fd);
412                 }
413                 free(c->port);
414                 free(c->priv);
415                 /* delete service */
416                 free(c);
417
418                 /* remember the last service for unlinking */
419                 c = next;
420         }
421
422         services = NULL;
423
424         return ERROR_OK;
425 }
426
427 int server_loop(struct command_context *command_context)
428 {
429         struct service *service;
430
431         bool poll_ok = true;
432
433         /* used in select() */
434         fd_set read_fds;
435         int fd_max;
436
437         /* used in accept() */
438         int retval;
439
440         int64_t next_event = timeval_ms() + polling_period;
441
442 #ifndef _WIN32
443         if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
444                 LOG_ERROR("couldn't set SIGPIPE to SIG_IGN");
445 #endif
446
447         while (shutdown_openocd == CONTINUE_MAIN_LOOP) {
448                 /* monitor sockets for activity */
449                 fd_max = 0;
450                 FD_ZERO(&read_fds);
451
452                 /* add service and connection fds to read_fds */
453                 for (service = services; service; service = service->next) {
454                         if (service->fd != -1) {
455                                 /* listen for new connections */
456                                 FD_SET(service->fd, &read_fds);
457
458                                 if (service->fd > fd_max)
459                                         fd_max = service->fd;
460                         }
461
462                         if (service->connections) {
463                                 struct connection *c;
464
465                                 for (c = service->connections; c; c = c->next) {
466                                         /* check for activity on the connection */
467                                         FD_SET(c->fd, &read_fds);
468                                         if (c->fd > fd_max)
469                                                 fd_max = c->fd;
470                                 }
471                         }
472                 }
473
474                 struct timeval tv;
475                 tv.tv_sec = 0;
476                 if (poll_ok) {
477                         /* we're just polling this iteration, this is faster on embedded
478                          * hosts */
479                         tv.tv_usec = 0;
480                         retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
481                 } else {
482                         /* Every 100ms, can be changed with "poll_period" command */
483                         int timeout_ms = next_event - timeval_ms();
484                         if (timeout_ms < 0)
485                                 timeout_ms = 0;
486                         else if (timeout_ms > polling_period)
487                                 timeout_ms = polling_period;
488                         tv.tv_usec = timeout_ms * 1000;
489                         /* Only while we're sleeping we'll let others run */
490                         openocd_sleep_prelude();
491                         kept_alive();
492                         retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
493                         openocd_sleep_postlude();
494                 }
495
496                 if (retval == -1) {
497 #ifdef _WIN32
498
499                         errno = WSAGetLastError();
500
501                         if (errno == WSAEINTR)
502                                 FD_ZERO(&read_fds);
503                         else {
504                                 LOG_ERROR("error during select: %s", strerror(errno));
505                                 return ERROR_FAIL;
506                         }
507 #else
508
509                         if (errno == EINTR)
510                                 FD_ZERO(&read_fds);
511                         else {
512                                 LOG_ERROR("error during select: %s", strerror(errno));
513                                 return ERROR_FAIL;
514                         }
515 #endif
516                 }
517
518                 if (retval == 0) {
519                         /* We only execute these callbacks when there was nothing to do or we timed
520                          *out */
521                         target_call_timer_callbacks_now();
522                         next_event = target_timer_next_event();
523                         process_jim_events(command_context);
524
525                         FD_ZERO(&read_fds);     /* eCos leaves read_fds unchanged in this case!  */
526
527                         /* We timed out/there was nothing to do, timeout rather than poll next time
528                          **/
529                         poll_ok = false;
530                 } else {
531                         /* There was something to do, next time we'll just poll */
532                         poll_ok = true;
533                 }
534
535                 /* This is a simple back-off algorithm where we immediately
536                  * re-poll if we did something this time around.
537                  *
538                  * This greatly improves performance of DCC.
539                  */
540                 poll_ok = poll_ok || target_got_message();
541
542                 for (service = services; service; service = service->next) {
543                         /* handle new connections on listeners */
544                         if ((service->fd != -1)
545                                 && (FD_ISSET(service->fd, &read_fds))) {
546                                 if (service->max_connections != 0)
547                                         add_connection(service, command_context);
548                                 else {
549                                         if (service->type == CONNECTION_TCP) {
550                                                 struct sockaddr_in sin;
551                                                 socklen_t address_size = sizeof(sin);
552                                                 int tmp_fd;
553                                                 tmp_fd = accept(service->fd,
554                                                                 (struct sockaddr *)&service->sin,
555                                                                 &address_size);
556                                                 close_socket(tmp_fd);
557                                         }
558                                         LOG_INFO(
559                                                 "rejected '%s' connection, no more connections allowed",
560                                                 service->name);
561                                 }
562                         }
563
564                         /* handle activity on connections */
565                         if (service->connections) {
566                                 struct connection *c;
567
568                                 for (c = service->connections; c; ) {
569                                         if ((c->fd >= 0 && FD_ISSET(c->fd, &read_fds)) || c->input_pending) {
570                                                 retval = service->input(c);
571                                                 if (retval != ERROR_OK) {
572                                                         struct connection *next = c->next;
573                                                         if (service->type == CONNECTION_PIPE ||
574                                                                         service->type == CONNECTION_STDINOUT) {
575                                                                 /* if connection uses a pipe then
576                                                                  * shutdown openocd on error */
577                                                                 shutdown_openocd = SHUTDOWN_REQUESTED;
578                                                         }
579                                                         remove_connection(service, c);
580                                                         LOG_INFO("dropped '%s' connection",
581                                                                 service->name);
582                                                         c = next;
583                                                         continue;
584                                                 }
585                                         }
586                                         c = c->next;
587                                 }
588                         }
589                 }
590
591 #ifdef _WIN32
592                 MSG msg;
593                 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
594                         if (msg.message == WM_QUIT)
595                                 shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;
596                 }
597 #endif
598         }
599
600         /* when quit for signal or CTRL-C, run (eventually user implemented) "shutdown" */
601         if (shutdown_openocd == SHUTDOWN_WITH_SIGNAL_CODE)
602                 command_run_line(command_context, "shutdown");
603
604         return shutdown_openocd == SHUTDOWN_WITH_ERROR_CODE ? ERROR_FAIL : ERROR_OK;
605 }
606
607 static void sig_handler(int sig)
608 {
609         /* store only first signal that hits us */
610         if (shutdown_openocd == CONTINUE_MAIN_LOOP) {
611                 shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;
612                 last_signal = sig;
613                 LOG_DEBUG("Terminating on Signal %d", sig);
614         } else
615                 LOG_DEBUG("Ignored extra Signal %d", sig);
616 }
617
618
619 #ifdef _WIN32
620 BOOL WINAPI control_handler(DWORD ctrl_type)
621 {
622         shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;
623         return TRUE;
624 }
625 #else
626 static void sigkey_handler(int sig)
627 {
628         /* ignore keystroke generated signals if not in foreground process group */
629
630         if (tcgetpgrp(STDIN_FILENO) > 0)
631                 sig_handler(sig);
632         else
633                 LOG_DEBUG("Ignored Signal %d", sig);
634 }
635 #endif
636
637
638 int server_host_os_entry(void)
639 {
640         /* this currently only calls WSAStartup on native win32 systems
641          * before any socket operations are performed.
642          * This is an issue if you call init in your config script */
643
644 #ifdef _WIN32
645         WORD version_requested;
646         WSADATA wsadata;
647
648         version_requested = MAKEWORD(2, 2);
649
650         if (WSAStartup(version_requested, &wsadata) != 0) {
651                 LOG_ERROR("Failed to Open Winsock");
652                 return ERROR_FAIL;
653         }
654 #endif
655         return ERROR_OK;
656 }
657
658 int server_host_os_close(void)
659 {
660 #ifdef _WIN32
661         WSACleanup();
662 #endif
663         return ERROR_OK;
664 }
665
666 int server_preinit(void)
667 {
668 #ifdef _WIN32
669         /* register ctrl-c handler */
670         SetConsoleCtrlHandler(control_handler, TRUE);
671
672         signal(SIGBREAK, sig_handler);
673         signal(SIGINT, sig_handler);
674 #else
675         signal(SIGHUP, sig_handler);
676         signal(SIGPIPE, sig_handler);
677         signal(SIGQUIT, sigkey_handler);
678         signal(SIGINT, sigkey_handler);
679 #endif
680         signal(SIGTERM, sig_handler);
681         signal(SIGABRT, sig_handler);
682
683         return ERROR_OK;
684 }
685
686 int server_init(struct command_context *cmd_ctx)
687 {
688         int ret = tcl_init();
689
690         if (ret != ERROR_OK)
691                 return ret;
692
693         ret = telnet_init("Open On-Chip Debugger");
694
695         if (ret != ERROR_OK) {
696                 remove_services();
697                 return ret;
698         }
699
700         return ERROR_OK;
701 }
702
703 int server_quit(void)
704 {
705         remove_services();
706         target_quit();
707
708 #ifdef _WIN32
709         SetConsoleCtrlHandler(control_handler, FALSE);
710
711         return ERROR_OK;
712 #endif
713
714         /* return signal number so we can kill ourselves */
715         return last_signal;
716 }
717
718 void server_free(void)
719 {
720         tcl_service_free();
721         telnet_service_free();
722         jsp_service_free();
723
724         free(bindto_name);
725 }
726
727 void exit_on_signal(int sig)
728 {
729 #ifndef _WIN32
730         /* bring back default system handler and kill yourself */
731         signal(sig, SIG_DFL);
732         kill(getpid(), sig);
733 #endif
734 }
735
736 int connection_write(struct connection *connection, const void *data, int len)
737 {
738         if (len == 0) {
739                 /* successful no-op. Sockets and pipes behave differently here... */
740                 return 0;
741         }
742         if (connection->service->type == CONNECTION_TCP)
743                 return write_socket(connection->fd_out, data, len);
744         else
745                 return write(connection->fd_out, data, len);
746 }
747
748 int connection_read(struct connection *connection, void *data, int len)
749 {
750         if (connection->service->type == CONNECTION_TCP)
751                 return read_socket(connection->fd, data, len);
752         else
753                 return read(connection->fd, data, len);
754 }
755
756 /* tell the server we want to shut down */
757 COMMAND_HANDLER(handle_shutdown_command)
758 {
759         LOG_USER("shutdown command invoked");
760
761         shutdown_openocd = SHUTDOWN_REQUESTED;
762
763         if (CMD_ARGC == 1) {
764                 if (!strcmp(CMD_ARGV[0], "error")) {
765                         shutdown_openocd = SHUTDOWN_WITH_ERROR_CODE;
766                         return ERROR_FAIL;
767                 }
768         }
769
770         return ERROR_COMMAND_CLOSE_CONNECTION;
771 }
772
773 COMMAND_HANDLER(handle_poll_period_command)
774 {
775         if (CMD_ARGC == 0)
776                 LOG_WARNING("You need to set a period value");
777         else
778                 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], polling_period);
779
780         LOG_INFO("set servers polling period to %ums", polling_period);
781
782         return ERROR_OK;
783 }
784
785 COMMAND_HANDLER(handle_bindto_command)
786 {
787         switch (CMD_ARGC) {
788                 case 0:
789                         command_print(CMD, "bindto name: %s", bindto_name);
790                         break;
791                 case 1:
792                         free(bindto_name);
793                         bindto_name = strdup(CMD_ARGV[0]);
794                         break;
795                 default:
796                         return ERROR_COMMAND_SYNTAX_ERROR;
797         }
798         return ERROR_OK;
799 }
800
801 static const struct command_registration server_command_handlers[] = {
802         {
803                 .name = "shutdown",
804                 .handler = &handle_shutdown_command,
805                 .mode = COMMAND_ANY,
806                 .usage = "",
807                 .help = "shut the server down",
808         },
809         {
810                 .name = "poll_period",
811                 .handler = &handle_poll_period_command,
812                 .mode = COMMAND_ANY,
813                 .usage = "",
814                 .help = "set the servers polling period",
815         },
816         {
817                 .name = "bindto",
818                 .handler = &handle_bindto_command,
819                 .mode = COMMAND_CONFIG,
820                 .usage = "[name]",
821                 .help = "Specify address by name on which to listen for "
822                         "incoming TCP/IP connections",
823         },
824         COMMAND_REGISTRATION_DONE
825 };
826
827 int server_register_commands(struct command_context *cmd_ctx)
828 {
829         int retval = telnet_register_commands(cmd_ctx);
830         if (retval != ERROR_OK)
831                 return retval;
832
833         retval = tcl_register_commands(cmd_ctx);
834         if (retval != ERROR_OK)
835                 return retval;
836
837         retval = jsp_register_commands(cmd_ctx);
838         if (retval != ERROR_OK)
839                 return retval;
840
841         return register_commands(cmd_ctx, NULL, server_command_handlers);
842 }
843
844 COMMAND_HELPER(server_port_command, unsigned short *out)
845 {
846         switch (CMD_ARGC) {
847                 case 0:
848                         command_print(CMD, "%d", *out);
849                         break;
850                 case 1:
851                 {
852                         uint16_t port;
853                         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
854                         *out = port;
855                         break;
856                 }
857                 default:
858                         return ERROR_COMMAND_SYNTAX_ERROR;
859         }
860         return ERROR_OK;
861 }
862
863 COMMAND_HELPER(server_pipe_command, char **out)
864 {
865         switch (CMD_ARGC) {
866                 case 0:
867                         command_print(CMD, "%s", *out);
868                         break;
869                 case 1:
870                 {
871                         if (CMD_CTX->mode == COMMAND_EXEC) {
872                                 LOG_WARNING("unable to change server port after init");
873                                 return ERROR_COMMAND_ARGUMENT_INVALID;
874                         }
875                         free(*out);
876                         *out = strdup(CMD_ARGV[0]);
877                         break;
878                 }
879                 default:
880                         return ERROR_COMMAND_SYNTAX_ERROR;
881         }
882         return ERROR_OK;
883 }