Skip to content

Commit 24ac32a

Browse files
committed
WIP - Add Zephyr port for socket APIs
JerryScript-DCO-1.0-Signed-off-by: Jimmy Huang [email protected]
1 parent 85cab9d commit 24ac32a

File tree

1 file changed

+232
-1
lines changed

1 file changed

+232
-1
lines changed

targets/zephyr/src/jerry-port.c

Lines changed: 232 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616
#include <stdarg.h>
1717

1818
#include <zephyr.h>
19+
#ifdef JERRY_DEBUGGER
20+
#include <sys/fcntl.h>
21+
#include <net/socket.h>
22+
#endif
1923

2024
#include "jerryscript-port.h"
2125

22-
2326
/**
2427
* Provide log message implementation for the engine.
2528
*/
@@ -82,3 +85,231 @@ jerryx_port_handler_print_char (char c) /**< the character to print */
8285
{
8386
printf ("%c", c);
8487
} /* jerryx_port_handler_print_char */
88+
89+
#ifdef JERRY_DEBUGGER
90+
91+
struct jerry_debugger_config_t
92+
{
93+
uint16_t debugger_port; /**< debugger socket communication port */
94+
};
95+
96+
struct jerry_debugger_conn_t
97+
{
98+
int fd; /**< holds the file descriptor of the socket communication */
99+
};
100+
101+
static jerry_debugger_config_t socket_config =
102+
{
103+
.debugger_port = 0,
104+
};
105+
106+
static jerry_debugger_conn_t socket_connection; /**< client connection */
107+
108+
/**
109+
* Provide the implementation of debugger accept api.
110+
*
111+
* @return the accepted incoming debugger connection
112+
*
113+
* Note:
114+
* This function is only available if the port implementation library is
115+
* compiled with the JERRY_DEBUGGER macro.
116+
*/
117+
static jerry_debugger_conn_t *
118+
jerry_debugger_socket_accept (jerry_debugger_transport_t *transport_p) /**< transport object */
119+
{
120+
int server_socket;
121+
struct sockaddr_in addr;
122+
socklen_t sin_size = sizeof (struct sockaddr_in);
123+
124+
addr.sin_family = AF_INET;
125+
addr.sin_port = htons (transport_p->config_p->debugger_port);
126+
addr.sin_addr.s_addr = INADDR_ANY;
127+
128+
if ((server_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
129+
{
130+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
131+
return NULL;
132+
}
133+
134+
if (bind (server_socket, (struct sockaddr *)&addr, sizeof (struct sockaddr)) == -1)
135+
{
136+
close (server_socket);
137+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
138+
return NULL;
139+
}
140+
141+
if (listen (server_socket, 1) == -1)
142+
{
143+
close (server_socket);
144+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
145+
return NULL;
146+
}
147+
148+
int client_socket = accept (server_socket, (struct sockaddr *)&addr, &sin_size);
149+
close (server_socket);
150+
151+
if (client_socket == -1)
152+
{
153+
return NULL;
154+
}
155+
156+
/* Set non-blocking mode. */
157+
int socket_flags = fcntl (client_socket, F_GETFL, 0);
158+
159+
if (socket_flags < 0)
160+
{
161+
close (client_socket);
162+
return NULL;
163+
}
164+
165+
if (fcntl (client_socket, F_SETFL, socket_flags | O_NONBLOCK) == -1)
166+
{
167+
close (client_socket);
168+
return NULL;
169+
}
170+
171+
char str[NET_IPV4_ADDR_LEN];
172+
net_addr_ntop(AF_INET, &addr.sin_addr, str, sizeof(str));
173+
jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Connected from: %s\n", str);
174+
175+
socket_connection.fd = client_socket;
176+
177+
return &socket_connection;
178+
} /* jerry_debugger_socket_accept */
179+
180+
/**
181+
* Provide the implementation of debugger send api.
182+
* Send message to the client side.
183+
*
184+
* @return JERRY_CONN_ERROR_NONE - if the data was sent successfully to the client side
185+
* JERRY_CONN_ERROR_INVALID - if the connection is invalid
186+
* JERRY_CONN_ERROR_AGAIN - if the transfer didn't go through immediately, but can try again later
187+
* JERRY_CONN_ERROR_IO - if the data failed to send
188+
* Note:
189+
* This function is only available if the port implementation library is
190+
* compiled with the JERRY_DEBUGGER macro.
191+
*/
192+
static jerry_debugger_conn_errors_t
193+
jerry_debugger_socket_send (jerry_debugger_conn_t *connection_p, /**< connection pointer */
194+
const void *data_p, /**< data pointer */
195+
size_t data_len, /**< data size */
196+
size_t *bytes_sent) /**< bytes sent */
197+
{
198+
if (!connection_p)
199+
{
200+
*bytes_sent = 0;
201+
return JERRY_CONN_ERROR_INVALID;
202+
}
203+
204+
ssize_t sent = send (connection_p->fd, data_p, data_len, 0);
205+
206+
if (sent < 0)
207+
{
208+
*bytes_sent = 0;
209+
if (errno == EWOULDBLOCK)
210+
{
211+
return JERRY_CONN_ERROR_AGAIN;
212+
}
213+
else
214+
{
215+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
216+
return JERRY_CONN_ERROR_IO;
217+
}
218+
}
219+
220+
*bytes_sent = (size_t) sent;
221+
return JERRY_CONN_ERROR_NONE;
222+
} /* jerry_debugger_socket_send */
223+
224+
/**
225+
* Provide the implementation of debugger receive api.
226+
* Receive message from the client side.
227+
*
228+
* @return JERRY_CONN_ERROR_NONE - if the data was received successfully from the client side
229+
* JERRY_CONN_ERROR_INVALID - if the connection is invalid
230+
* JERRY_CONN_ERROR_AGAIN - if there's no incoming data, you should try again later
231+
* JERRY_CONN_ERROR_IO - if the data failed to receive
232+
* Note:
233+
* This function is only available if the port implementation library is
234+
* compiled with the JERRY_DEBUGGER macro.
235+
*/
236+
static jerry_debugger_conn_errors_t
237+
jerry_debugger_socket_receive (jerry_debugger_conn_t *connection_p, /**< connection pointer */
238+
void *data_p, /**< data pointer */
239+
size_t max_len, /**< max data size */
240+
size_t *bytes_received) /**< bytes received */
241+
{
242+
if (!connection_p)
243+
{
244+
*bytes_received = 0;
245+
return JERRY_CONN_ERROR_INVALID;
246+
}
247+
248+
ssize_t received = recv (connection_p->fd, data_p, max_len, 0);
249+
250+
if (received < 0)
251+
{
252+
*bytes_received = 0;
253+
if (errno == EWOULDBLOCK)
254+
{
255+
return JERRY_CONN_ERROR_AGAIN;
256+
}
257+
else
258+
{
259+
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
260+
return JERRY_CONN_ERROR_IO;
261+
}
262+
}
263+
264+
*bytes_received = (size_t) received;
265+
return JERRY_CONN_ERROR_NONE;
266+
} /* jerry_debugger_socket_receive */
267+
268+
/**
269+
* Provide the implementation of debugger close api.
270+
* Closes the debugger connection.
271+
*
272+
* @return JERRY_CONN_ERROR_NONE - if successful
273+
* JERRY_CONN_ERROR_INVALID - if the connection is invalid
274+
* Note:
275+
* This function is only available if the port implementation library is
276+
* compiled with the JERRY_DEBUGGER macro.
277+
*/
278+
static jerry_debugger_conn_errors_t
279+
jerry_debugger_socket_close (jerry_debugger_conn_t *connection_p) /**< connection pointer */
280+
{
281+
if (!connection_p)
282+
{
283+
return JERRY_CONN_ERROR_INVALID;
284+
}
285+
286+
close (connection_p->fd);
287+
return JERRY_CONN_ERROR_NONE;
288+
} /* jerry_debugger_socket_close */
289+
290+
static jerry_debugger_transport_t socket_transport =
291+
{
292+
.config_p = &socket_config,
293+
.accept = jerry_debugger_socket_accept,
294+
.send = jerry_debugger_socket_send,
295+
.receive = jerry_debugger_socket_receive,
296+
.close = jerry_debugger_socket_close,
297+
};
298+
299+
#endif /* JERRY_DEBUGGER */
300+
301+
/**
302+
* Create and return the socket transport on the provided port for the debugger
303+
*
304+
* @return the transport created
305+
*/
306+
jerry_debugger_transport_t *
307+
jerry_debugger_init_socket_transport (uint16_t tcp_port) /**< server port number */
308+
{
309+
#ifdef JERRY_DEBUGGER
310+
socket_transport.config_p->debugger_port = tcp_port;
311+
return &socket_transport;
312+
#else /* !JERRY_DEBUGGER */
313+
return NULL;
314+
#endif /* JERRY_DEBUGGER */
315+
} /* jerry_debugger_init_socket_transport */

0 commit comments

Comments
 (0)