OpenOCD
jsp_server.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2014 by Franck Jullien *
5  * franck.jullien@gmail.com *
6  * *
7  * Based on ./src/server/telnet_server.c *
8  ***************************************************************************/
9 
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13 
14 #include <server/telnet_server.h>
15 
16 #include "or1k_tap.h"
17 #include "or1k_du.h"
18 #include "jsp_server.h"
19 
20 static char *jsp_port;
21 
27 static const char * const negotiate =
28  "\xFF\xFB\x03" /* IAC WILL Suppress Go Ahead */
29  "\xFF\xFB\x01" /* IAC WILL Echo */
30  "\xFF\xFD\x03" /* IAC DO Suppress Go Ahead */
31  "\xFF\xFE\x01"; /* IAC DON'T Echo */
32 
33 /* The only way we can detect that the socket is closed is the first time
34  * we write to it, we will fail. Subsequent write operations will
35  * succeed. Shudder!
36  */
37 static int telnet_write(struct connection *connection, const void *data, int len)
38 {
39  struct telnet_connection *t_con = connection->priv;
40  if (t_con->closed)
42 
43  if (connection_write(connection, data, len) == len)
44  return ERROR_OK;
45  t_con->closed = 1;
47 }
48 
49 static int jsp_poll_read(void *priv)
50 {
51  struct jsp_service *jsp_service = (struct jsp_service *)priv;
52  unsigned char out_buffer[10];
53  unsigned char in_buffer[10];
54  int out_len = 0;
55  int in_len;
56 
57  if (!jsp_service->connection)
58  return ERROR_FAIL;
59 
60  memset(out_buffer, 0, 10);
61 
62  or1k_adv_jtag_jsp_xfer(jsp_service->jtag_info, &out_len, out_buffer, &in_len, in_buffer);
63  if (in_len)
64  telnet_write(jsp_service->connection, in_buffer, in_len);
65 
66  return ERROR_OK;
67 }
68 
70 {
71  struct telnet_connection *telnet_connection = malloc(sizeof(struct telnet_connection));
73 
75 
76  /* initialize telnet connection information */
81 
82  /* negotiate telnet options */
84 
85  /* print connection banner */
86  if (jsp_service->banner) {
88  telnet_write(connection, "\r\n", 2);
89  }
90 
92 
95  if (retval != ERROR_OK)
96  return retval;
97 
98  return ERROR_OK;
99 }
100 
101 static int jsp_input(struct connection *connection)
102 {
103  int bytes_read;
104  unsigned char buffer[TELNET_BUFFER_SIZE];
105  unsigned char *buf_p;
106  struct telnet_connection *t_con = connection->priv;
108 
110 
111  if (bytes_read == 0)
113  else if (bytes_read == -1) {
114  LOG_ERROR("error during read: %s", strerror(errno));
116  }
117 
118  buf_p = buffer;
119  while (bytes_read) {
120  switch (t_con->state) {
121  case TELNET_STATE_DATA:
122  if (*buf_p == 0xff)
123  t_con->state = TELNET_STATE_IAC;
124  else {
125  int out_len = 1;
126  int in_len;
127  unsigned char in_buffer[10];
129  &out_len, buf_p, &in_len,
130  in_buffer);
131  if (in_len)
133  in_buffer, in_len);
134  }
135  break;
136  case TELNET_STATE_IAC:
137  switch (*buf_p) {
138  case 0xfe:
139  t_con->state = TELNET_STATE_DONT;
140  break;
141  case 0xfd:
142  t_con->state = TELNET_STATE_DO;
143  break;
144  case 0xfc:
145  t_con->state = TELNET_STATE_WONT;
146  break;
147  case 0xfb:
148  t_con->state = TELNET_STATE_WILL;
149  break;
150  }
151  break;
152  case TELNET_STATE_SB:
153  break;
154  case TELNET_STATE_SE:
155  break;
156  case TELNET_STATE_WILL:
157  case TELNET_STATE_WONT:
158  case TELNET_STATE_DO:
159  case TELNET_STATE_DONT:
160  t_con->state = TELNET_STATE_DATA;
161  break;
162  default:
163  LOG_ERROR("unknown telnet state");
164  exit(-1);
165  }
166 
167  bytes_read--;
168  buf_p++;
169  }
170 
171  return ERROR_OK;
172 }
173 
175 {
177 
179  if (retval != ERROR_OK)
180  return retval;
181 
182  free(connection->priv);
183  connection->priv = NULL;
184  return ERROR_OK;
185 }
186 
187 static const struct service_driver jsp_service_driver = {
188  .name = "jsp",
189  .new_connection_during_keep_alive_handler = NULL,
190  .new_connection_handler = jsp_new_connection,
191  .input_handler = jsp_input,
192  .connection_closed_handler = jsp_connection_closed,
193  .keep_client_alive_handler = NULL,
194 };
195 
196 int jsp_init(struct or1k_jtag *jtag_info, char *banner)
197 {
198  struct jsp_service *jsp_service = malloc(sizeof(struct jsp_service));
201 
203 }
204 
205 COMMAND_HANDLER(handle_jsp_port_command)
206 {
207  return CALL_COMMAND_HANDLER(server_pipe_command, &jsp_port);
208 }
209 
210 static const struct command_registration jsp_command_handlers[] = {
211  {
212  .name = "jsp_port",
213  .handler = handle_jsp_port_command,
214  .mode = COMMAND_ANY,
215  .help = "Specify port on which to listen "
216  "for incoming JSP telnet connections.",
217  .usage = "[port_num]",
218  },
220 };
221 
223 {
224  jsp_port = strdup("7777");
225  return register_commands(cmd_ctx, NULL, jsp_command_handlers);
226 }
227 
229 {
230  free(jsp_port);
231 }
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:118
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
Definition: command.h:274
@ COMMAND_ANY
Definition: command.h:42
static struct esp_usb_jtag * priv
Definition: esp_usb_jtag.c:219
int jsp_init(struct or1k_jtag *jtag_info, char *banner)
Definition: jsp_server.c:196
COMMAND_HANDLER(handle_jsp_port_command)
Definition: jsp_server.c:205
static int jsp_poll_read(void *priv)
Definition: jsp_server.c:49
void jsp_service_free(void)
Definition: jsp_server.c:228
static int jsp_connection_closed(struct connection *connection)
Definition: jsp_server.c:174
static const struct command_registration jsp_command_handlers[]
Definition: jsp_server.c:210
static const struct service_driver jsp_service_driver
Definition: jsp_server.c:187
static int jsp_new_connection(struct connection *connection)
Definition: jsp_server.c:69
static char * jsp_port
Definition: jsp_server.c:20
static int telnet_write(struct connection *connection, const void *data, int len)
Definition: jsp_server.c:37
static const char *const negotiate
A skim of the relevant RFCs suggests that if my application simply sent the characters IAC DONT LINEM...
Definition: jsp_server.c:27
static int jsp_input(struct connection *connection)
Definition: jsp_server.c:101
int jsp_register_commands(struct command_context *cmd_ctx)
Definition: jsp_server.c:222
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define ERROR_OK
Definition: log.h:164
int or1k_adv_jtag_jsp_xfer(struct or1k_jtag *jtag_info, int *out_len, unsigned char *out_buffer, int *in_len, unsigned char *in_buffer)
Definition: or1k_du_adv.c:961
int connection_write(struct connection *connection, const void *data, int len)
Definition: server.c:732
int connection_read(struct connection *connection, void *data, int len)
Definition: server.c:744
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
Definition: server.c:198
#define ERROR_SERVER_REMOTE_CLOSED
Definition: server.h:119
const char * name
Definition: command.h:235
void * priv
Definition: server.h:43
struct service * service
Definition: server.h:41
struct connection * connection
Definition: jsp_server.h:13
char * banner
Definition: jsp_server.h:11
struct or1k_jtag * jtag_info
Definition: jsp_server.h:12
Definition: or1k.h:77
const char * name
the name of the server
Definition: server.h:49
void * priv
Definition: server.h:81
enum telnet_states state
Definition: telnet_server.h:39
int target_unregister_timer_callback(int(*callback)(void *priv), void *priv)
Definition: target.c:1748
int target_register_timer_callback(int(*callback)(void *priv), unsigned int time_ms, enum target_timer_type type, void *priv)
The period is very approximate, the callback can happen much more often or much more rarely than spec...
Definition: target.c:1658
@ TARGET_TIMER_TYPE_PERIODIC
Definition: target.h:327
#define TELNET_BUFFER_SIZE
Definition: telnet_server.h:19
@ TELNET_STATE_DO
Definition: telnet_server.h:31
@ TELNET_STATE_SB
Definition: telnet_server.h:27
@ TELNET_STATE_DONT
Definition: telnet_server.h:32
@ TELNET_STATE_WILL
Definition: telnet_server.h:29
@ TELNET_STATE_IAC
Definition: telnet_server.h:26
@ TELNET_STATE_WONT
Definition: telnet_server.h:30
@ TELNET_STATE_DATA
Definition: telnet_server.h:25
@ TELNET_STATE_SE
Definition: telnet_server.h:28
#define NULL
Definition: usb.h:16