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)) && !defined _WIN32
21425bb815Sopenharmony_ci
22425bb815Sopenharmony_ci#include <errno.h>
23425bb815Sopenharmony_ci#include <fcntl.h>
24425bb815Sopenharmony_ci#include <unistd.h>
25425bb815Sopenharmony_ci#include <termios.h>
26425bb815Sopenharmony_ci#include <stdlib.h>
27425bb815Sopenharmony_ci
28425bb815Sopenharmony_ci/* Max size of configuration string */
29425bb815Sopenharmony_ci#define CONFIG_SIZE (255)
30425bb815Sopenharmony_ci
31425bb815Sopenharmony_ci/**
32425bb815Sopenharmony_ci * Implementation of transport over serial connection.
33425bb815Sopenharmony_ci */
34425bb815Sopenharmony_citypedef struct
35425bb815Sopenharmony_ci{
36425bb815Sopenharmony_ci  jerry_debugger_transport_header_t header; /**< transport header */
37425bb815Sopenharmony_ci  int fd; /**< file descriptor */
38425bb815Sopenharmony_ci} jerryx_debugger_transport_serial_t;
39425bb815Sopenharmony_ci
40425bb815Sopenharmony_ci/**
41425bb815Sopenharmony_ci * Configure parameters for a serial port.
42425bb815Sopenharmony_ci */
43425bb815Sopenharmony_citypedef struct
44425bb815Sopenharmony_ci{
45425bb815Sopenharmony_ci  char *device_id;
46425bb815Sopenharmony_ci  uint32_t baud_rate; /**< specify the rate at which bits are transmitted for the serial interface */
47425bb815Sopenharmony_ci  uint32_t data_bits; /**< specify the number of data bits to transmit over the serial interface */
48425bb815Sopenharmony_ci  char parity; /**< specify how you want to check parity bits in the data bits transmitted via the serial port */
49425bb815Sopenharmony_ci  uint32_t stop_bits; /**< specify the number of bits used to indicate the end of a byte. */
50425bb815Sopenharmony_ci} jerryx_debugger_transport_serial_config_t;
51425bb815Sopenharmony_ci
52425bb815Sopenharmony_ci/**
53425bb815Sopenharmony_ci * Correctly close a file descriptor.
54425bb815Sopenharmony_ci */
55425bb815Sopenharmony_cistatic inline void
56425bb815Sopenharmony_cijerryx_debugger_serial_close_fd (int fd) /**< file descriptor to close */
57425bb815Sopenharmony_ci{
58425bb815Sopenharmony_ci  if (close (fd) != 0)
59425bb815Sopenharmony_ci  {
60425bb815Sopenharmony_ci    JERRYX_ERROR_MSG ("Error while closing the file descriptor: %d\n", errno);
61425bb815Sopenharmony_ci  }
62425bb815Sopenharmony_ci} /* jerryx_debugger_serial_close_fd */
63425bb815Sopenharmony_ci
64425bb815Sopenharmony_ci/**
65425bb815Sopenharmony_ci * Set a file descriptor to blocking or non-blocking mode.
66425bb815Sopenharmony_ci *
67425bb815Sopenharmony_ci * @return true if everything is ok
68425bb815Sopenharmony_ci *         false if there was an error
69425bb815Sopenharmony_ci **/
70425bb815Sopenharmony_cistatic bool
71425bb815Sopenharmony_cijerryx_debugger_serial_set_blocking (int fd, bool blocking)
72425bb815Sopenharmony_ci{
73425bb815Sopenharmony_ci  /* Save the current flags */
74425bb815Sopenharmony_ci  int flags = fcntl (fd, F_GETFL, 0);
75425bb815Sopenharmony_ci  if (flags == -1)
76425bb815Sopenharmony_ci  {
77425bb815Sopenharmony_ci    JERRYX_ERROR_MSG ("Error %d during get flags from file descriptor\n", errno);
78425bb815Sopenharmony_ci    return false;
79425bb815Sopenharmony_ci  }
80425bb815Sopenharmony_ci
81425bb815Sopenharmony_ci  if (blocking)
82425bb815Sopenharmony_ci  {
83425bb815Sopenharmony_ci    flags &= ~O_NONBLOCK;
84425bb815Sopenharmony_ci  }
85425bb815Sopenharmony_ci  else
86425bb815Sopenharmony_ci  {
87425bb815Sopenharmony_ci    flags |= O_NONBLOCK;
88425bb815Sopenharmony_ci  }
89425bb815Sopenharmony_ci
90425bb815Sopenharmony_ci  if (fcntl (fd, F_SETFL, flags) == -1)
91425bb815Sopenharmony_ci  {
92425bb815Sopenharmony_ci    JERRYX_ERROR_MSG ("Error %d during set flags from file descriptor\n", errno);
93425bb815Sopenharmony_ci    return false;
94425bb815Sopenharmony_ci  }
95425bb815Sopenharmony_ci
96425bb815Sopenharmony_ci  return true;
97425bb815Sopenharmony_ci} /* jerryx_debugger_serial_set_blocking */
98425bb815Sopenharmony_ci
99425bb815Sopenharmony_ci/**
100425bb815Sopenharmony_ci * Configure the file descriptor used by the serial communcation.
101425bb815Sopenharmony_ci *
102425bb815Sopenharmony_ci * @return true if everything is ok
103425bb815Sopenharmony_ci *         false if there was an error
104425bb815Sopenharmony_ci */
105425bb815Sopenharmony_cistatic inline bool
106425bb815Sopenharmony_cijerryx_debugger_serial_configure_attributes (int fd, jerryx_debugger_transport_serial_config_t serial_config)
107425bb815Sopenharmony_ci{
108425bb815Sopenharmony_ci  struct termios options;
109425bb815Sopenharmony_ci  memset (&options, 0, sizeof (options));
110425bb815Sopenharmony_ci
111425bb815Sopenharmony_ci  /* Get the parameters associated with the file descriptor */
112425bb815Sopenharmony_ci  if (tcgetattr (fd, &options) != 0)
113425bb815Sopenharmony_ci  {
114425bb815Sopenharmony_ci    JERRYX_ERROR_MSG ("Error %d from tggetattr\n", errno);
115425bb815Sopenharmony_ci    return false;
116425bb815Sopenharmony_ci  }
117425bb815Sopenharmony_ci
118425bb815Sopenharmony_ci  /* Set the input and output baud rates */
119425bb815Sopenharmony_ci  cfsetispeed (&options, serial_config.baud_rate);
120425bb815Sopenharmony_ci  cfsetospeed (&options, serial_config.baud_rate);
121425bb815Sopenharmony_ci
122425bb815Sopenharmony_ci  /* Set the control modes */
123425bb815Sopenharmony_ci  options.c_cflag &= (uint32_t) ~CSIZE; // character size mask
124425bb815Sopenharmony_ci  options.c_cflag |= (CLOCAL | CREAD); // ignore modem control lines and enable the receiver
125425bb815Sopenharmony_ci
126425bb815Sopenharmony_ci  switch (serial_config.data_bits)
127425bb815Sopenharmony_ci  {
128425bb815Sopenharmony_ci    case 5:
129425bb815Sopenharmony_ci    {
130425bb815Sopenharmony_ci      options.c_cflag |= CS5; // set character size mask to 5-bit chars
131425bb815Sopenharmony_ci      break;
132425bb815Sopenharmony_ci    }
133425bb815Sopenharmony_ci    case 6:
134425bb815Sopenharmony_ci    {
135425bb815Sopenharmony_ci      options.c_cflag |= CS6; // set character size mask to 6-bit chars
136425bb815Sopenharmony_ci      break;
137425bb815Sopenharmony_ci    }
138425bb815Sopenharmony_ci    case 7:
139425bb815Sopenharmony_ci    {
140425bb815Sopenharmony_ci      options.c_cflag |= CS7; // set character size mask to 7-bit chars
141425bb815Sopenharmony_ci      break;
142425bb815Sopenharmony_ci    }
143425bb815Sopenharmony_ci    case 8:
144425bb815Sopenharmony_ci    {
145425bb815Sopenharmony_ci      options.c_cflag |= CS8; // set character size mask to 8-bit chars
146425bb815Sopenharmony_ci      break;
147425bb815Sopenharmony_ci    }
148425bb815Sopenharmony_ci    default:
149425bb815Sopenharmony_ci    {
150425bb815Sopenharmony_ci      JERRYX_ERROR_MSG ("Unsupported data bits: %d\n", serial_config.data_bits);
151425bb815Sopenharmony_ci      return false;
152425bb815Sopenharmony_ci    }
153425bb815Sopenharmony_ci  }
154425bb815Sopenharmony_ci
155425bb815Sopenharmony_ci  switch (serial_config.parity)
156425bb815Sopenharmony_ci  {
157425bb815Sopenharmony_ci    case 'N':
158425bb815Sopenharmony_ci    {
159425bb815Sopenharmony_ci      options.c_cflag &= (unsigned int) ~(PARENB | PARODD);
160425bb815Sopenharmony_ci      break;
161425bb815Sopenharmony_ci    }
162425bb815Sopenharmony_ci    case 'O':
163425bb815Sopenharmony_ci    {
164425bb815Sopenharmony_ci      options.c_cflag |= PARENB;
165425bb815Sopenharmony_ci      options.c_cflag |= PARODD;
166425bb815Sopenharmony_ci      break;
167425bb815Sopenharmony_ci    }
168425bb815Sopenharmony_ci    case 'E':
169425bb815Sopenharmony_ci    {
170425bb815Sopenharmony_ci      options.c_cflag |= PARENB;
171425bb815Sopenharmony_ci      options.c_cflag |= PARODD;
172425bb815Sopenharmony_ci      break;
173425bb815Sopenharmony_ci    }
174425bb815Sopenharmony_ci    default:
175425bb815Sopenharmony_ci    {
176425bb815Sopenharmony_ci      JERRYX_ERROR_MSG ("Unsupported parity: %c\n", serial_config.parity);
177425bb815Sopenharmony_ci      return false;
178425bb815Sopenharmony_ci    }
179425bb815Sopenharmony_ci  }
180425bb815Sopenharmony_ci
181425bb815Sopenharmony_ci  switch (serial_config.stop_bits)
182425bb815Sopenharmony_ci  {
183425bb815Sopenharmony_ci    case 1:
184425bb815Sopenharmony_ci    {
185425bb815Sopenharmony_ci      options.c_cflag &= (uint32_t) ~CSTOPB; // set 1 stop bits
186425bb815Sopenharmony_ci      break;
187425bb815Sopenharmony_ci    }
188425bb815Sopenharmony_ci    case 2:
189425bb815Sopenharmony_ci    {
190425bb815Sopenharmony_ci      options.c_cflag |= CSTOPB; // set 2 stop bits
191425bb815Sopenharmony_ci      break;
192425bb815Sopenharmony_ci    }
193425bb815Sopenharmony_ci    default:
194425bb815Sopenharmony_ci    {
195425bb815Sopenharmony_ci      JERRYX_ERROR_MSG ("Unsupported stop bits: %d\n", serial_config.stop_bits);
196425bb815Sopenharmony_ci      return false;
197425bb815Sopenharmony_ci    }
198425bb815Sopenharmony_ci  }
199425bb815Sopenharmony_ci
200425bb815Sopenharmony_ci  /* Set the input modes */
201425bb815Sopenharmony_ci  options.c_iflag &= (uint32_t) ~IGNBRK; // disable break processing
202425bb815Sopenharmony_ci  options.c_iflag &= (uint32_t) ~(IXON | IXOFF | IXANY); // disable xon/xoff ctrl
203425bb815Sopenharmony_ci
204425bb815Sopenharmony_ci  /* Set the output modes: no remapping, no delays */
205425bb815Sopenharmony_ci  options.c_oflag = 0;
206425bb815Sopenharmony_ci
207425bb815Sopenharmony_ci  /* Set the local modes: no signaling chars, no echo, no canoncial processing */
208425bb815Sopenharmony_ci  options.c_lflag = 0;
209425bb815Sopenharmony_ci
210425bb815Sopenharmony_ci  /* Read returns when at least one byte of data is available. */
211425bb815Sopenharmony_ci  options.c_cc[VMIN]  = 1; // read block
212425bb815Sopenharmony_ci  options.c_cc[VTIME] = 5; // 0.5 seconds read timeout
213425bb815Sopenharmony_ci
214425bb815Sopenharmony_ci  /* Set the parameters associated with the file descriptor */
215425bb815Sopenharmony_ci  if (tcsetattr (fd, TCSANOW, &options) != 0)
216425bb815Sopenharmony_ci  {
217425bb815Sopenharmony_ci    JERRYX_ERROR_MSG ("Error %d from tcsetattr", errno);
218425bb815Sopenharmony_ci    return false;
219425bb815Sopenharmony_ci  }
220425bb815Sopenharmony_ci
221425bb815Sopenharmony_ci  /* Flushes both data received but not read, and data written but not transmitted */
222425bb815Sopenharmony_ci  if (tcflush (fd, TCIOFLUSH) != 0)
223425bb815Sopenharmony_ci  {
224425bb815Sopenharmony_ci    JERRYX_ERROR_MSG ("Error %d in tcflush() :%s\n", errno, strerror (errno));
225425bb815Sopenharmony_ci    jerryx_debugger_serial_close_fd (fd);
226425bb815Sopenharmony_ci    return false;
227425bb815Sopenharmony_ci  }
228425bb815Sopenharmony_ci
229425bb815Sopenharmony_ci  return true;
230425bb815Sopenharmony_ci} /* jerryx_debugger_serial_configure_attributes */
231425bb815Sopenharmony_ci
232425bb815Sopenharmony_ci/**
233425bb815Sopenharmony_ci * Close a serial connection.
234425bb815Sopenharmony_ci */
235425bb815Sopenharmony_cistatic void
236425bb815Sopenharmony_cijerryx_debugger_serial_close (jerry_debugger_transport_header_t *header_p) /**< serial implementation */
237425bb815Sopenharmony_ci{
238425bb815Sopenharmony_ci  JERRYX_ASSERT (!jerry_debugger_transport_is_connected ());
239425bb815Sopenharmony_ci
240425bb815Sopenharmony_ci  jerryx_debugger_transport_serial_t *serial_p = (jerryx_debugger_transport_serial_t *) header_p;
241425bb815Sopenharmony_ci
242425bb815Sopenharmony_ci  JERRYX_DEBUG_MSG ("Serial connection closed.\n");
243425bb815Sopenharmony_ci
244425bb815Sopenharmony_ci  jerryx_debugger_serial_close_fd (serial_p->fd);
245425bb815Sopenharmony_ci
246425bb815Sopenharmony_ci  jerry_heap_free ((void *) header_p, sizeof (jerryx_debugger_transport_serial_t));
247425bb815Sopenharmony_ci} /* jerryx_debugger_serial_close */
248425bb815Sopenharmony_ci
249425bb815Sopenharmony_ci/**
250425bb815Sopenharmony_ci * Send data over a serial connection.
251425bb815Sopenharmony_ci *
252425bb815Sopenharmony_ci * @return true - if the data has been sent successfully
253425bb815Sopenharmony_ci *         false - otherwise
254425bb815Sopenharmony_ci */
255425bb815Sopenharmony_cistatic bool
256425bb815Sopenharmony_cijerryx_debugger_serial_send (jerry_debugger_transport_header_t *header_p, /**< serial implementation */
257425bb815Sopenharmony_ci                             uint8_t *message_p, /**< message to be sent */
258425bb815Sopenharmony_ci                             size_t message_length) /**< message length in bytes */
259425bb815Sopenharmony_ci{
260425bb815Sopenharmony_ci  JERRYX_ASSERT (jerry_debugger_transport_is_connected ());
261425bb815Sopenharmony_ci
262425bb815Sopenharmony_ci  jerryx_debugger_transport_serial_t *serial_p = (jerryx_debugger_transport_serial_t *) header_p;
263425bb815Sopenharmony_ci
264425bb815Sopenharmony_ci  do
265425bb815Sopenharmony_ci  {
266425bb815Sopenharmony_ci    ssize_t sent_bytes = write (serial_p->fd, message_p, message_length);
267425bb815Sopenharmony_ci
268425bb815Sopenharmony_ci    if (sent_bytes < 0)
269425bb815Sopenharmony_ci    {
270425bb815Sopenharmony_ci      if (errno == EWOULDBLOCK)
271425bb815Sopenharmony_ci      {
272425bb815Sopenharmony_ci        continue;
273425bb815Sopenharmony_ci      }
274425bb815Sopenharmony_ci
275425bb815Sopenharmony_ci      JERRYX_ERROR_MSG ("Error: write to file descriptor: %d\n", errno);
276425bb815Sopenharmony_ci      jerry_debugger_transport_close ();
277425bb815Sopenharmony_ci      return false;
278425bb815Sopenharmony_ci    }
279425bb815Sopenharmony_ci
280425bb815Sopenharmony_ci    message_p += sent_bytes;
281425bb815Sopenharmony_ci    message_length -= (size_t) sent_bytes;
282425bb815Sopenharmony_ci  }
283425bb815Sopenharmony_ci  while (message_length > 0);
284425bb815Sopenharmony_ci
285425bb815Sopenharmony_ci  return true;
286425bb815Sopenharmony_ci} /* jerryx_debugger_serial_send */
287425bb815Sopenharmony_ci
288425bb815Sopenharmony_ci/**
289425bb815Sopenharmony_ci * Receive data from a serial connection.
290425bb815Sopenharmony_ci */
291425bb815Sopenharmony_cistatic bool
292425bb815Sopenharmony_cijerryx_debugger_serial_receive (jerry_debugger_transport_header_t *header_p, /**< serial implementation */
293425bb815Sopenharmony_ci                                jerry_debugger_transport_receive_context_t *receive_context_p) /**< receive context */
294425bb815Sopenharmony_ci{
295425bb815Sopenharmony_ci  jerryx_debugger_transport_serial_t *serial_p = (jerryx_debugger_transport_serial_t *) header_p;
296425bb815Sopenharmony_ci
297425bb815Sopenharmony_ci  uint8_t *buffer_p = receive_context_p->buffer_p + receive_context_p->received_length;
298425bb815Sopenharmony_ci  size_t buffer_size = JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE - receive_context_p->received_length;
299425bb815Sopenharmony_ci
300425bb815Sopenharmony_ci  ssize_t length = read (serial_p->fd, buffer_p, buffer_size);
301425bb815Sopenharmony_ci
302425bb815Sopenharmony_ci  if (length <= 0)
303425bb815Sopenharmony_ci  {
304425bb815Sopenharmony_ci    if (errno != EWOULDBLOCK || length == 0)
305425bb815Sopenharmony_ci    {
306425bb815Sopenharmony_ci      jerry_debugger_transport_close ();
307425bb815Sopenharmony_ci      return false;
308425bb815Sopenharmony_ci    }
309425bb815Sopenharmony_ci    length = 0;
310425bb815Sopenharmony_ci  }
311425bb815Sopenharmony_ci
312425bb815Sopenharmony_ci  receive_context_p->received_length += (size_t) length;
313425bb815Sopenharmony_ci
314425bb815Sopenharmony_ci  if (receive_context_p->received_length > 0)
315425bb815Sopenharmony_ci  {
316425bb815Sopenharmony_ci    receive_context_p->message_p = receive_context_p->buffer_p;
317425bb815Sopenharmony_ci    receive_context_p->message_length = receive_context_p->received_length;
318425bb815Sopenharmony_ci  }
319425bb815Sopenharmony_ci
320425bb815Sopenharmony_ci  return true;
321425bb815Sopenharmony_ci} /* jerryx_debugger_serial_receive */
322425bb815Sopenharmony_ci
323425bb815Sopenharmony_ci/**
324425bb815Sopenharmony_ci * Create a serial connection.
325425bb815Sopenharmony_ci *
326425bb815Sopenharmony_ci * @return true if successful,
327425bb815Sopenharmony_ci *         false otherwise
328425bb815Sopenharmony_ci */
329425bb815Sopenharmony_cibool
330425bb815Sopenharmony_cijerryx_debugger_serial_create (const char *config) /**< specify the configuration */
331425bb815Sopenharmony_ci{
332425bb815Sopenharmony_ci  /* Parse the configuration string */
333425bb815Sopenharmony_ci  char tmp_config[CONFIG_SIZE];
334425bb815Sopenharmony_ci  strncpy (tmp_config, config, CONFIG_SIZE);
335425bb815Sopenharmony_ci  jerryx_debugger_transport_serial_config_t serial_config;
336425bb815Sopenharmony_ci
337425bb815Sopenharmony_ci  char *token = strtok (tmp_config, ",");
338425bb815Sopenharmony_ci  serial_config.device_id = token ? token : "/dev/ttyS0";
339425bb815Sopenharmony_ci  serial_config.baud_rate = (token = strtok (NULL, ",")) ? (uint32_t) strtoul (token, NULL, 10) : 115200;
340425bb815Sopenharmony_ci  serial_config.data_bits = (token = strtok (NULL, ",")) ? (uint32_t) strtoul (token, NULL, 10) : 8;
341425bb815Sopenharmony_ci  serial_config.parity = (token = strtok (NULL, ",")) ? token[0] : 'N';
342425bb815Sopenharmony_ci  serial_config.stop_bits = (token = strtok (NULL, ",")) ? (uint32_t) strtoul (token, NULL, 10) : 1;
343425bb815Sopenharmony_ci
344425bb815Sopenharmony_ci  int fd = open (serial_config.device_id, O_RDWR);
345425bb815Sopenharmony_ci
346425bb815Sopenharmony_ci  if (fd < 0)
347425bb815Sopenharmony_ci  {
348425bb815Sopenharmony_ci    JERRYX_ERROR_MSG ("Error %d opening %s: %s", errno, serial_config.device_id, strerror (errno));
349425bb815Sopenharmony_ci    return false;
350425bb815Sopenharmony_ci  }
351425bb815Sopenharmony_ci
352425bb815Sopenharmony_ci  if (!jerryx_debugger_serial_configure_attributes (fd, serial_config))
353425bb815Sopenharmony_ci  {
354425bb815Sopenharmony_ci    jerryx_debugger_serial_close_fd (fd);
355425bb815Sopenharmony_ci    return false;
356425bb815Sopenharmony_ci  }
357425bb815Sopenharmony_ci
358425bb815Sopenharmony_ci  JERRYX_DEBUG_MSG ("Waiting for client connection\n");
359425bb815Sopenharmony_ci
360425bb815Sopenharmony_ci  /* Client will sent a 'c' char to initiate the connection. */
361425bb815Sopenharmony_ci  uint8_t conn_char;
362425bb815Sopenharmony_ci  ssize_t t = read (fd, &conn_char, 1);
363425bb815Sopenharmony_ci  if (t != 1 || conn_char != 'c' || !jerryx_debugger_serial_set_blocking (fd, false))
364425bb815Sopenharmony_ci  {
365425bb815Sopenharmony_ci    return false;
366425bb815Sopenharmony_ci  }
367425bb815Sopenharmony_ci
368425bb815Sopenharmony_ci  JERRYX_DEBUG_MSG ("Client connected\n");
369425bb815Sopenharmony_ci
370425bb815Sopenharmony_ci  size_t size = sizeof (jerryx_debugger_transport_serial_t);
371425bb815Sopenharmony_ci
372425bb815Sopenharmony_ci  jerry_debugger_transport_header_t *header_p;
373425bb815Sopenharmony_ci  header_p = (jerry_debugger_transport_header_t *) jerry_heap_alloc (size);
374425bb815Sopenharmony_ci
375425bb815Sopenharmony_ci  if (!header_p)
376425bb815Sopenharmony_ci  {
377425bb815Sopenharmony_ci    jerryx_debugger_serial_close_fd (fd);
378425bb815Sopenharmony_ci    return false;
379425bb815Sopenharmony_ci  }
380425bb815Sopenharmony_ci
381425bb815Sopenharmony_ci  header_p->close = jerryx_debugger_serial_close;
382425bb815Sopenharmony_ci  header_p->send = jerryx_debugger_serial_send;
383425bb815Sopenharmony_ci  header_p->receive = jerryx_debugger_serial_receive;
384425bb815Sopenharmony_ci
385425bb815Sopenharmony_ci  ((jerryx_debugger_transport_serial_t *) header_p)->fd = fd;
386425bb815Sopenharmony_ci
387425bb815Sopenharmony_ci  jerry_debugger_transport_add (header_p,
388425bb815Sopenharmony_ci                                0,
389425bb815Sopenharmony_ci                                JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE,
390425bb815Sopenharmony_ci                                0,
391425bb815Sopenharmony_ci                                JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE);
392425bb815Sopenharmony_ci
393425bb815Sopenharmony_ci  return true;
394425bb815Sopenharmony_ci} /* jerryx_debugger_serial_create */
395425bb815Sopenharmony_ci
396425bb815Sopenharmony_ci#else /* !(defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)) || _WIN32 */
397425bb815Sopenharmony_ci/**
398425bb815Sopenharmony_ci * Dummy function when debugger is disabled.
399425bb815Sopenharmony_ci *
400425bb815Sopenharmony_ci * @return false
401425bb815Sopenharmony_ci */
402425bb815Sopenharmony_cibool
403425bb815Sopenharmony_cijerryx_debugger_serial_create (const char *config)
404425bb815Sopenharmony_ci{
405425bb815Sopenharmony_ci  JERRYX_UNUSED (config);
406425bb815Sopenharmony_ci  return false;
407425bb815Sopenharmony_ci} /* jerryx_debugger_serial_create */
408425bb815Sopenharmony_ci
409425bb815Sopenharmony_ci#endif /* (defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)) && !defined _WIN32 */
410