1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include "jerryscript-debugger-transport.h"
17425bb815Sopenharmony_ci#include "jerryscript-ext/debugger.h"
18425bb815Sopenharmony_ci#include "jext-common.h"
19425bb815Sopenharmony_ci
20425bb815Sopenharmony_ci#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
21425bb815Sopenharmony_ci
22425bb815Sopenharmony_ci#include <errno.h>
23425bb815Sopenharmony_ci
24425bb815Sopenharmony_ci#ifdef _WIN32
25425bb815Sopenharmony_ci#include <basetsd.h>
26425bb815Sopenharmony_citypedef SSIZE_T ssize_t;
27425bb815Sopenharmony_ci#include <ws2tcpip.h>
28425bb815Sopenharmony_ci#include <winsock2.h>
29425bb815Sopenharmony_ci
30425bb815Sopenharmony_ci/* On Windows the WSAEWOULDBLOCK value can be returned for non-blocking operations */
31425bb815Sopenharmony_ci#define JERRYX_EWOULDBLOCK WSAEWOULDBLOCK
32425bb815Sopenharmony_ci
33425bb815Sopenharmony_ci/* On Windows the invalid socket's value of INVALID_SOCKET */
34425bb815Sopenharmony_ci#define JERRYX_SOCKET_INVALID INVALID_SOCKET
35425bb815Sopenharmony_ci
36425bb815Sopenharmony_ci/* On Windows sockets have a SOCKET typedef */
37425bb815Sopenharmony_citypedef SOCKET jerryx_socket;
38425bb815Sopenharmony_ci
39425bb815Sopenharmony_ci#else /* !_WIN32 */
40425bb815Sopenharmony_ci
41425bb815Sopenharmony_ci#include <arpa/inet.h>
42425bb815Sopenharmony_ci#include <fcntl.h>
43425bb815Sopenharmony_ci#include <sys/socket.h>
44425bb815Sopenharmony_ci#include <unistd.h>
45425bb815Sopenharmony_ci
46425bb815Sopenharmony_ci/* On *nix the EWOULDBLOCK errno value can be returned for non-blocking operations */
47425bb815Sopenharmony_ci#define JERRYX_EWOULDBLOCK EWOULDBLOCK
48425bb815Sopenharmony_ci
49425bb815Sopenharmony_ci/* On *nix the invalid socket has a value of -1 */
50425bb815Sopenharmony_ci#define JERRYX_SOCKET_INVALID (-1)
51425bb815Sopenharmony_ci
52425bb815Sopenharmony_ci/* On *nix the sockets are integer identifiers */
53425bb815Sopenharmony_citypedef int jerryx_socket;
54425bb815Sopenharmony_ci#endif /* _WIN32 */
55425bb815Sopenharmony_ci
56425bb815Sopenharmony_ci/**
57425bb815Sopenharmony_ci * Implementation of transport over tcp/ip.
58425bb815Sopenharmony_ci */
59425bb815Sopenharmony_citypedef struct
60425bb815Sopenharmony_ci{
61425bb815Sopenharmony_ci  jerry_debugger_transport_header_t header; /**< transport header */
62425bb815Sopenharmony_ci  jerryx_socket tcp_socket; /**< tcp socket */
63425bb815Sopenharmony_ci} jerryx_debugger_transport_tcp_t;
64425bb815Sopenharmony_ci
65425bb815Sopenharmony_ci/**
66425bb815Sopenharmony_ci * Get the network error value.
67425bb815Sopenharmony_ci *
68425bb815Sopenharmony_ci * On Windows this returns the result of the `WSAGetLastError ()` call and
69425bb815Sopenharmony_ci * on any other system the `errno` value.
70425bb815Sopenharmony_ci *
71425bb815Sopenharmony_ci *
72425bb815Sopenharmony_ci * @return last error value.
73425bb815Sopenharmony_ci */
74425bb815Sopenharmony_cistatic inline int
75425bb815Sopenharmony_cijerryx_debugger_tcp_get_errno (void)
76425bb815Sopenharmony_ci{
77425bb815Sopenharmony_ci#ifdef _WIN32
78425bb815Sopenharmony_ci  return WSAGetLastError ();
79425bb815Sopenharmony_ci#else /* !_WIN32 */
80425bb815Sopenharmony_ci  return errno;
81425bb815Sopenharmony_ci#endif /* _WIN32 */
82425bb815Sopenharmony_ci} /* jerryx_debugger_tcp_get_errno */
83425bb815Sopenharmony_ci
84425bb815Sopenharmony_ci/**
85425bb815Sopenharmony_ci * Correctly close a single socket.
86425bb815Sopenharmony_ci */
87425bb815Sopenharmony_cistatic inline void
88425bb815Sopenharmony_cijerryx_debugger_tcp_close_socket (jerryx_socket socket_id) /**< socket to close */
89425bb815Sopenharmony_ci{
90425bb815Sopenharmony_ci#ifdef _WIN32
91425bb815Sopenharmony_ci  closesocket (socket_id);
92425bb815Sopenharmony_ci#else /* !_WIN32 */
93425bb815Sopenharmony_ci  close (socket_id);
94425bb815Sopenharmony_ci#endif /* _WIN32 */
95425bb815Sopenharmony_ci} /* jerryx_debugger_tcp_close_socket */
96425bb815Sopenharmony_ci
97425bb815Sopenharmony_ci/**
98425bb815Sopenharmony_ci * Log tcp error message.
99425bb815Sopenharmony_ci */
100425bb815Sopenharmony_cistatic void
101425bb815Sopenharmony_cijerryx_debugger_tcp_log_error (int errno_value) /**< error value to log */
102425bb815Sopenharmony_ci{
103425bb815Sopenharmony_ci  if (errno_value == 0)
104425bb815Sopenharmony_ci  {
105425bb815Sopenharmony_ci    return;
106425bb815Sopenharmony_ci  }
107425bb815Sopenharmony_ci
108425bb815Sopenharmony_ci#ifdef _WIN32
109425bb815Sopenharmony_ci  char *error_message = NULL;
110425bb815Sopenharmony_ci  FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
111425bb815Sopenharmony_ci                 NULL,
112425bb815Sopenharmony_ci                 (DWORD)errno_value,
113425bb815Sopenharmony_ci                 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
114425bb815Sopenharmony_ci                 (LPTSTR) &error_message,
115425bb815Sopenharmony_ci                 0,
116425bb815Sopenharmony_ci                 NULL);
117425bb815Sopenharmony_ci  jerry_port_log (JERRY_LOG_LEVEL_ERROR, "TCP Error: %s\n", error_message);
118425bb815Sopenharmony_ci  LocalFree (error_message);
119425bb815Sopenharmony_ci#else /* !_WIN32 */
120425bb815Sopenharmony_ci  jerry_port_log (JERRY_LOG_LEVEL_ERROR, "TCP Error: %s\n", strerror (errno_value));
121425bb815Sopenharmony_ci#endif /* _WIN32 */
122425bb815Sopenharmony_ci} /* jerryx_debugger_tcp_log_error */
123425bb815Sopenharmony_ci
124425bb815Sopenharmony_ci/**
125425bb815Sopenharmony_ci * Close a tcp connection.
126425bb815Sopenharmony_ci */
127425bb815Sopenharmony_cistatic void
128425bb815Sopenharmony_cijerryx_debugger_tcp_close (jerry_debugger_transport_header_t *header_p) /**< tcp implementation */
129425bb815Sopenharmony_ci{
130425bb815Sopenharmony_ci  JERRYX_ASSERT (!jerry_debugger_transport_is_connected ());
131425bb815Sopenharmony_ci
132425bb815Sopenharmony_ci  jerryx_debugger_transport_tcp_t *tcp_p = (jerryx_debugger_transport_tcp_t *) header_p;
133425bb815Sopenharmony_ci
134425bb815Sopenharmony_ci  JERRYX_DEBUG_MSG ("TCP connection closed.\n");
135425bb815Sopenharmony_ci
136425bb815Sopenharmony_ci  jerryx_debugger_tcp_close_socket (tcp_p->tcp_socket);
137425bb815Sopenharmony_ci
138425bb815Sopenharmony_ci  jerry_heap_free ((void *) header_p, sizeof (jerryx_debugger_transport_tcp_t));
139425bb815Sopenharmony_ci} /* jerryx_debugger_tcp_close */
140425bb815Sopenharmony_ci
141425bb815Sopenharmony_ci/**
142425bb815Sopenharmony_ci * Send data over a tcp connection.
143425bb815Sopenharmony_ci *
144425bb815Sopenharmony_ci * @return true - if the data has been sent successfully
145425bb815Sopenharmony_ci *         false - otherwise
146425bb815Sopenharmony_ci */
147425bb815Sopenharmony_cistatic bool
148425bb815Sopenharmony_cijerryx_debugger_tcp_send (jerry_debugger_transport_header_t *header_p, /**< tcp implementation */
149425bb815Sopenharmony_ci                          uint8_t *message_p, /**< message to be sent */
150425bb815Sopenharmony_ci                          size_t message_length) /**< message length in bytes */
151425bb815Sopenharmony_ci{
152425bb815Sopenharmony_ci  JERRYX_ASSERT (jerry_debugger_transport_is_connected ());
153425bb815Sopenharmony_ci
154425bb815Sopenharmony_ci  jerryx_debugger_transport_tcp_t *tcp_p = (jerryx_debugger_transport_tcp_t *) header_p;
155425bb815Sopenharmony_ci
156425bb815Sopenharmony_ci  do
157425bb815Sopenharmony_ci  {
158425bb815Sopenharmony_ci#ifdef __linux__
159425bb815Sopenharmony_ci    ssize_t is_err = recv (tcp_p->tcp_socket, NULL, 0, MSG_PEEK);
160425bb815Sopenharmony_ci
161425bb815Sopenharmony_ci    if (is_err == 0 && errno != JERRYX_EWOULDBLOCK)
162425bb815Sopenharmony_ci    {
163425bb815Sopenharmony_ci      int err_val = errno;
164425bb815Sopenharmony_ci      jerry_debugger_transport_close ();
165425bb815Sopenharmony_ci      jerryx_debugger_tcp_log_error (err_val);
166425bb815Sopenharmony_ci      return false;
167425bb815Sopenharmony_ci    }
168425bb815Sopenharmony_ci#endif /* __linux__ */
169425bb815Sopenharmony_ci#ifdef _WIN32
170425bb815Sopenharmony_ci    ssize_t sent_bytes = send (tcp_p->tcp_socket, (char *)message_p, (int)message_length, 0);
171425bb815Sopenharmony_ci#else
172425bb815Sopenharmony_ci    ssize_t sent_bytes = send (tcp_p->tcp_socket, message_p, message_length, 0);
173425bb815Sopenharmony_ci#endif
174425bb815Sopenharmony_ci
175425bb815Sopenharmony_ci    if (sent_bytes < 0)
176425bb815Sopenharmony_ci    {
177425bb815Sopenharmony_ci      int err_val = jerryx_debugger_tcp_get_errno ();
178425bb815Sopenharmony_ci
179425bb815Sopenharmony_ci      if (err_val == JERRYX_EWOULDBLOCK)
180425bb815Sopenharmony_ci      {
181425bb815Sopenharmony_ci        continue;
182425bb815Sopenharmony_ci      }
183425bb815Sopenharmony_ci
184425bb815Sopenharmony_ci      jerry_debugger_transport_close ();
185425bb815Sopenharmony_ci      jerryx_debugger_tcp_log_error (err_val);
186425bb815Sopenharmony_ci      return false;
187425bb815Sopenharmony_ci    }
188425bb815Sopenharmony_ci
189425bb815Sopenharmony_ci    message_p += sent_bytes;
190425bb815Sopenharmony_ci    message_length -= (size_t) sent_bytes;
191425bb815Sopenharmony_ci  }
192425bb815Sopenharmony_ci  while (message_length > 0);
193425bb815Sopenharmony_ci
194425bb815Sopenharmony_ci  return true;
195425bb815Sopenharmony_ci} /* jerryx_debugger_tcp_send */
196425bb815Sopenharmony_ci
197425bb815Sopenharmony_ci/**
198425bb815Sopenharmony_ci * Receive data from a tcp connection.
199425bb815Sopenharmony_ci */
200425bb815Sopenharmony_cistatic bool
201425bb815Sopenharmony_cijerryx_debugger_tcp_receive (jerry_debugger_transport_header_t *header_p, /**< tcp implementation */
202425bb815Sopenharmony_ci                             jerry_debugger_transport_receive_context_t *receive_context_p) /**< receive context */
203425bb815Sopenharmony_ci{
204425bb815Sopenharmony_ci  jerryx_debugger_transport_tcp_t *tcp_p = (jerryx_debugger_transport_tcp_t *) header_p;
205425bb815Sopenharmony_ci
206425bb815Sopenharmony_ci  uint8_t *buffer_p = receive_context_p->buffer_p + receive_context_p->received_length;
207425bb815Sopenharmony_ci  size_t buffer_size = JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE - receive_context_p->received_length;
208425bb815Sopenharmony_ci#ifdef _WIN32
209425bb815Sopenharmony_ci  ssize_t length = recv (tcp_p->tcp_socket, (char *)buffer_p, (int)buffer_size, 0);
210425bb815Sopenharmony_ci#else
211425bb815Sopenharmony_ci  ssize_t length = recv (tcp_p->tcp_socket, buffer_p, buffer_size, 0);
212425bb815Sopenharmony_ci#endif
213425bb815Sopenharmony_ci
214425bb815Sopenharmony_ci  if (length <= 0)
215425bb815Sopenharmony_ci  {
216425bb815Sopenharmony_ci    int err_val = jerryx_debugger_tcp_get_errno ();
217425bb815Sopenharmony_ci
218425bb815Sopenharmony_ci    if (err_val != JERRYX_EWOULDBLOCK || length == 0)
219425bb815Sopenharmony_ci    {
220425bb815Sopenharmony_ci      jerry_debugger_transport_close ();
221425bb815Sopenharmony_ci      jerryx_debugger_tcp_log_error (err_val);
222425bb815Sopenharmony_ci      return false;
223425bb815Sopenharmony_ci    }
224425bb815Sopenharmony_ci    length = 0;
225425bb815Sopenharmony_ci  }
226425bb815Sopenharmony_ci
227425bb815Sopenharmony_ci  receive_context_p->received_length += (size_t) length;
228425bb815Sopenharmony_ci
229425bb815Sopenharmony_ci  if (receive_context_p->received_length > 0)
230425bb815Sopenharmony_ci  {
231425bb815Sopenharmony_ci    receive_context_p->message_p = receive_context_p->buffer_p;
232425bb815Sopenharmony_ci    receive_context_p->message_length = receive_context_p->received_length;
233425bb815Sopenharmony_ci  }
234425bb815Sopenharmony_ci
235425bb815Sopenharmony_ci  return true;
236425bb815Sopenharmony_ci} /* jerryx_debugger_tcp_receive */
237425bb815Sopenharmony_ci
238425bb815Sopenharmony_ci/**
239425bb815Sopenharmony_ci * Utility method to prepare the server socket to accept connections.
240425bb815Sopenharmony_ci *
241425bb815Sopenharmony_ci * The following steps are performed:
242425bb815Sopenharmony_ci *  * Configure address re-use.
243425bb815Sopenharmony_ci *  * Bind the socket to the given port
244425bb815Sopenharmony_ci *  * Start listening on the socket.
245425bb815Sopenharmony_ci *
246425bb815Sopenharmony_ci * @return true if everything is ok
247425bb815Sopenharmony_ci *         false if there was an error
248425bb815Sopenharmony_ci */
249425bb815Sopenharmony_cistatic bool
250425bb815Sopenharmony_cijerryx_debugger_tcp_configure_socket (jerryx_socket server_socket, /** < socket to configure */
251425bb815Sopenharmony_ci                                      uint16_t port) /** < port number to be used for the socket */
252425bb815Sopenharmony_ci{
253425bb815Sopenharmony_ci  struct sockaddr_in addr;
254425bb815Sopenharmony_ci
255425bb815Sopenharmony_ci  addr.sin_family = AF_INET;
256425bb815Sopenharmony_ci  addr.sin_port = htons (port);
257425bb815Sopenharmony_ci  addr.sin_addr.s_addr = INADDR_ANY;
258425bb815Sopenharmony_ci
259425bb815Sopenharmony_ci#ifdef _WIN32
260425bb815Sopenharmony_ci  char opt_value = 1;
261425bb815Sopenharmony_ci#else
262425bb815Sopenharmony_ci  int opt_value = 1;
263425bb815Sopenharmony_ci#endif
264425bb815Sopenharmony_ci
265425bb815Sopenharmony_ci  if (setsockopt (server_socket, SOL_SOCKET, SO_REUSEADDR, &opt_value, sizeof (int)) != 0)
266425bb815Sopenharmony_ci  {
267425bb815Sopenharmony_ci    return false;
268425bb815Sopenharmony_ci  }
269425bb815Sopenharmony_ci
270425bb815Sopenharmony_ci  if (bind (server_socket, (struct sockaddr *) &addr, sizeof (struct sockaddr_in)) != 0)
271425bb815Sopenharmony_ci  {
272425bb815Sopenharmony_ci    return false;
273425bb815Sopenharmony_ci  }
274425bb815Sopenharmony_ci
275425bb815Sopenharmony_ci  if (listen (server_socket, 1) != 0)
276425bb815Sopenharmony_ci  {
277425bb815Sopenharmony_ci    return false;
278425bb815Sopenharmony_ci  }
279425bb815Sopenharmony_ci
280425bb815Sopenharmony_ci  return true;
281425bb815Sopenharmony_ci} /* jerryx_debugger_tcp_configure_socket */
282425bb815Sopenharmony_ci
283425bb815Sopenharmony_ci/**
284425bb815Sopenharmony_ci * Create a tcp connection.
285425bb815Sopenharmony_ci *
286425bb815Sopenharmony_ci * @return true if successful,
287425bb815Sopenharmony_ci *         false otherwise
288425bb815Sopenharmony_ci */
289425bb815Sopenharmony_cibool
290425bb815Sopenharmony_cijerryx_debugger_tcp_create (uint16_t port) /**< listening port */
291425bb815Sopenharmony_ci{
292425bb815Sopenharmony_ci#ifdef _WIN32
293425bb815Sopenharmony_ci  WSADATA wsaData;
294425bb815Sopenharmony_ci  int wsa_init_status = WSAStartup (MAKEWORD (2, 2), &wsaData);
295425bb815Sopenharmony_ci  if (wsa_init_status != NO_ERROR)
296425bb815Sopenharmony_ci  {
297425bb815Sopenharmony_ci    JERRYX_ERROR_MSG ("WSA Error: %d\n", wsa_init_status);
298425bb815Sopenharmony_ci    return false;
299425bb815Sopenharmony_ci  }
300425bb815Sopenharmony_ci#endif /* _WIN32 */
301425bb815Sopenharmony_ci
302425bb815Sopenharmony_ci  jerryx_socket server_socket = socket (AF_INET, SOCK_STREAM, 0);
303425bb815Sopenharmony_ci  if (server_socket == JERRYX_SOCKET_INVALID)
304425bb815Sopenharmony_ci  {
305425bb815Sopenharmony_ci    jerryx_debugger_tcp_log_error (jerryx_debugger_tcp_get_errno ());
306425bb815Sopenharmony_ci    return false;
307425bb815Sopenharmony_ci  }
308425bb815Sopenharmony_ci
309425bb815Sopenharmony_ci  if (!jerryx_debugger_tcp_configure_socket (server_socket, port))
310425bb815Sopenharmony_ci  {
311425bb815Sopenharmony_ci    int error = jerryx_debugger_tcp_get_errno ();
312425bb815Sopenharmony_ci    jerryx_debugger_tcp_close_socket (server_socket);
313425bb815Sopenharmony_ci    jerryx_debugger_tcp_log_error (error);
314425bb815Sopenharmony_ci    return false;
315425bb815Sopenharmony_ci  }
316425bb815Sopenharmony_ci
317425bb815Sopenharmony_ci  JERRYX_DEBUG_MSG ("Waiting for client connection\n");
318425bb815Sopenharmony_ci
319425bb815Sopenharmony_ci  struct sockaddr_in addr;
320425bb815Sopenharmony_ci  socklen_t sin_size = sizeof (struct sockaddr_in);
321425bb815Sopenharmony_ci
322425bb815Sopenharmony_ci  jerryx_socket tcp_socket = accept (server_socket, (struct sockaddr *) &addr, &sin_size);
323425bb815Sopenharmony_ci
324425bb815Sopenharmony_ci  jerryx_debugger_tcp_close_socket (server_socket);
325425bb815Sopenharmony_ci
326425bb815Sopenharmony_ci  if (tcp_socket == JERRYX_SOCKET_INVALID)
327425bb815Sopenharmony_ci  {
328425bb815Sopenharmony_ci    jerryx_debugger_tcp_log_error (jerryx_debugger_tcp_get_errno ());
329425bb815Sopenharmony_ci    return false;
330425bb815Sopenharmony_ci  }
331425bb815Sopenharmony_ci
332425bb815Sopenharmony_ci  /* Set non-blocking mode. */
333425bb815Sopenharmony_ci#ifdef _WIN32
334425bb815Sopenharmony_ci  u_long nonblocking_enabled = 1;
335425bb815Sopenharmony_ci  if (ioctlsocket (tcp_socket, (long)FIONBIO, &nonblocking_enabled) != NO_ERROR)
336425bb815Sopenharmony_ci  {
337425bb815Sopenharmony_ci    jerryx_debugger_tcp_close_socket (tcp_socket);
338425bb815Sopenharmony_ci    return false;
339425bb815Sopenharmony_ci  }
340425bb815Sopenharmony_ci#else /* !_WIN32 */
341425bb815Sopenharmony_ci  int socket_flags = fcntl (tcp_socket, F_GETFL, 0);
342425bb815Sopenharmony_ci
343425bb815Sopenharmony_ci  if (socket_flags < 0)
344425bb815Sopenharmony_ci  {
345425bb815Sopenharmony_ci    close (tcp_socket);
346425bb815Sopenharmony_ci    return false;
347425bb815Sopenharmony_ci  }
348425bb815Sopenharmony_ci
349425bb815Sopenharmony_ci  if (fcntl (tcp_socket, F_SETFL, socket_flags | O_NONBLOCK) == -1)
350425bb815Sopenharmony_ci  {
351425bb815Sopenharmony_ci    close (tcp_socket);
352425bb815Sopenharmony_ci    return false;
353425bb815Sopenharmony_ci  }
354425bb815Sopenharmony_ci#endif /* _WIN32 */
355425bb815Sopenharmony_ci
356425bb815Sopenharmony_ci  JERRYX_DEBUG_MSG ("Connected from: %s\n", inet_ntoa (addr.sin_addr));
357425bb815Sopenharmony_ci
358425bb815Sopenharmony_ci  size_t size = sizeof (jerryx_debugger_transport_tcp_t);
359425bb815Sopenharmony_ci
360425bb815Sopenharmony_ci  jerry_debugger_transport_header_t *header_p;
361425bb815Sopenharmony_ci  header_p = (jerry_debugger_transport_header_t *) jerry_heap_alloc (size);
362425bb815Sopenharmony_ci
363425bb815Sopenharmony_ci  if (!header_p)
364425bb815Sopenharmony_ci  {
365425bb815Sopenharmony_ci    jerryx_debugger_tcp_close_socket (tcp_socket);
366425bb815Sopenharmony_ci    return false;
367425bb815Sopenharmony_ci  }
368425bb815Sopenharmony_ci
369425bb815Sopenharmony_ci  header_p->close = jerryx_debugger_tcp_close;
370425bb815Sopenharmony_ci  header_p->send = jerryx_debugger_tcp_send;
371425bb815Sopenharmony_ci  header_p->receive = jerryx_debugger_tcp_receive;
372425bb815Sopenharmony_ci
373425bb815Sopenharmony_ci  ((jerryx_debugger_transport_tcp_t *) header_p)->tcp_socket = tcp_socket;
374425bb815Sopenharmony_ci
375425bb815Sopenharmony_ci  jerry_debugger_transport_add (header_p,
376425bb815Sopenharmony_ci                                0,
377425bb815Sopenharmony_ci                                JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE,
378425bb815Sopenharmony_ci                                0,
379425bb815Sopenharmony_ci                                JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE);
380425bb815Sopenharmony_ci
381425bb815Sopenharmony_ci  return true;
382425bb815Sopenharmony_ci} /* jerryx_debugger_tcp_create */
383425bb815Sopenharmony_ci
384425bb815Sopenharmony_ci#else /* !(defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)) */
385425bb815Sopenharmony_ci
386425bb815Sopenharmony_ci/**
387425bb815Sopenharmony_ci * Dummy function when debugger is disabled.
388425bb815Sopenharmony_ci *
389425bb815Sopenharmony_ci * @return false
390425bb815Sopenharmony_ci */
391425bb815Sopenharmony_cibool
392425bb815Sopenharmony_cijerryx_debugger_tcp_create (uint16_t port)
393425bb815Sopenharmony_ci{
394425bb815Sopenharmony_ci  JERRYX_UNUSED (port);
395425bb815Sopenharmony_ci  return false;
396425bb815Sopenharmony_ci} /* jerryx_debugger_tcp_create */
397425bb815Sopenharmony_ci
398425bb815Sopenharmony_ci#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
399