Skip to content

Commit 84bb335

Browse files
committed
WIP - Add Zephyr port for socket APIs
Signed-off-by: Jimmy Huang <[email protected]>
1 parent 4f9e42b commit 84bb335

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed

targets/zephyr/src/jerry-port.c

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
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

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

0 commit comments

Comments
 (0)