1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker * Copyright (c) 2016, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker * All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker *
5*cfb92d14SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker *
16*cfb92d14SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker */
28*cfb92d14SAndroid Build Coastguard Worker
29*cfb92d14SAndroid Build Coastguard Worker #include "platform-simulation.h"
30*cfb92d14SAndroid Build Coastguard Worker
31*cfb92d14SAndroid Build Coastguard Worker #include <assert.h>
32*cfb92d14SAndroid Build Coastguard Worker #include <errno.h>
33*cfb92d14SAndroid Build Coastguard Worker #include <fcntl.h>
34*cfb92d14SAndroid Build Coastguard Worker #include <poll.h>
35*cfb92d14SAndroid Build Coastguard Worker #include <signal.h>
36*cfb92d14SAndroid Build Coastguard Worker #include <stdio.h>
37*cfb92d14SAndroid Build Coastguard Worker #include <stdlib.h>
38*cfb92d14SAndroid Build Coastguard Worker #include <termios.h>
39*cfb92d14SAndroid Build Coastguard Worker #include <unistd.h>
40*cfb92d14SAndroid Build Coastguard Worker
41*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/debug_uart.h>
42*cfb92d14SAndroid Build Coastguard Worker
43*cfb92d14SAndroid Build Coastguard Worker #include "simul_utils.h"
44*cfb92d14SAndroid Build Coastguard Worker #include "utils/code_utils.h"
45*cfb92d14SAndroid Build Coastguard Worker #include "utils/uart.h"
46*cfb92d14SAndroid Build Coastguard Worker
47*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART == 0
48*cfb92d14SAndroid Build Coastguard Worker
49*cfb92d14SAndroid Build Coastguard Worker static uint8_t s_receive_buffer[128];
50*cfb92d14SAndroid Build Coastguard Worker static const uint8_t *s_write_buffer;
51*cfb92d14SAndroid Build Coastguard Worker static uint16_t s_write_length;
52*cfb92d14SAndroid Build Coastguard Worker static int s_in_fd;
53*cfb92d14SAndroid Build Coastguard Worker static int s_out_fd;
54*cfb92d14SAndroid Build Coastguard Worker
55*cfb92d14SAndroid Build Coastguard Worker static struct termios original_stdin_termios;
56*cfb92d14SAndroid Build Coastguard Worker static struct termios original_stdout_termios;
57*cfb92d14SAndroid Build Coastguard Worker
restore_stdin_termios(void)58*cfb92d14SAndroid Build Coastguard Worker static void restore_stdin_termios(void) { tcsetattr(s_in_fd, TCSAFLUSH, &original_stdin_termios); }
59*cfb92d14SAndroid Build Coastguard Worker
restore_stdout_termios(void)60*cfb92d14SAndroid Build Coastguard Worker static void restore_stdout_termios(void) { tcsetattr(s_out_fd, TCSAFLUSH, &original_stdout_termios); }
61*cfb92d14SAndroid Build Coastguard Worker
platformUartRestore(void)62*cfb92d14SAndroid Build Coastguard Worker void platformUartRestore(void)
63*cfb92d14SAndroid Build Coastguard Worker {
64*cfb92d14SAndroid Build Coastguard Worker restore_stdin_termios();
65*cfb92d14SAndroid Build Coastguard Worker restore_stdout_termios();
66*cfb92d14SAndroid Build Coastguard Worker dup2(s_out_fd, STDOUT_FILENO);
67*cfb92d14SAndroid Build Coastguard Worker }
68*cfb92d14SAndroid Build Coastguard Worker
otPlatUartEnable(void)69*cfb92d14SAndroid Build Coastguard Worker otError otPlatUartEnable(void)
70*cfb92d14SAndroid Build Coastguard Worker {
71*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
72*cfb92d14SAndroid Build Coastguard Worker struct termios termios;
73*cfb92d14SAndroid Build Coastguard Worker
74*cfb92d14SAndroid Build Coastguard Worker s_in_fd = dup(STDIN_FILENO);
75*cfb92d14SAndroid Build Coastguard Worker s_out_fd = dup(STDOUT_FILENO);
76*cfb92d14SAndroid Build Coastguard Worker dup2(STDERR_FILENO, STDOUT_FILENO);
77*cfb92d14SAndroid Build Coastguard Worker
78*cfb92d14SAndroid Build Coastguard Worker // We need this signal to make sure that this
79*cfb92d14SAndroid Build Coastguard Worker // process terminates properly.
80*cfb92d14SAndroid Build Coastguard Worker signal(SIGPIPE, SIG_DFL);
81*cfb92d14SAndroid Build Coastguard Worker
82*cfb92d14SAndroid Build Coastguard Worker if (isatty(s_in_fd))
83*cfb92d14SAndroid Build Coastguard Worker {
84*cfb92d14SAndroid Build Coastguard Worker tcgetattr(s_in_fd, &original_stdin_termios);
85*cfb92d14SAndroid Build Coastguard Worker atexit(&restore_stdin_termios);
86*cfb92d14SAndroid Build Coastguard Worker }
87*cfb92d14SAndroid Build Coastguard Worker
88*cfb92d14SAndroid Build Coastguard Worker if (isatty(s_out_fd))
89*cfb92d14SAndroid Build Coastguard Worker {
90*cfb92d14SAndroid Build Coastguard Worker tcgetattr(s_out_fd, &original_stdout_termios);
91*cfb92d14SAndroid Build Coastguard Worker atexit(&restore_stdout_termios);
92*cfb92d14SAndroid Build Coastguard Worker }
93*cfb92d14SAndroid Build Coastguard Worker
94*cfb92d14SAndroid Build Coastguard Worker if (isatty(s_in_fd))
95*cfb92d14SAndroid Build Coastguard Worker {
96*cfb92d14SAndroid Build Coastguard Worker // get current configuration
97*cfb92d14SAndroid Build Coastguard Worker otEXPECT_ACTION(tcgetattr(s_in_fd, &termios) == 0, perror("tcgetattr"); error = OT_ERROR_GENERIC);
98*cfb92d14SAndroid Build Coastguard Worker
99*cfb92d14SAndroid Build Coastguard Worker // Set up the termios settings for raw mode. This turns
100*cfb92d14SAndroid Build Coastguard Worker // off input/output processing, line processing, and character processing.
101*cfb92d14SAndroid Build Coastguard Worker cfmakeraw(&termios);
102*cfb92d14SAndroid Build Coastguard Worker
103*cfb92d14SAndroid Build Coastguard Worker // Set up our cflags for local use. Turn on hangup-on-close.
104*cfb92d14SAndroid Build Coastguard Worker termios.c_cflag |= HUPCL | CREAD | CLOCAL;
105*cfb92d14SAndroid Build Coastguard Worker
106*cfb92d14SAndroid Build Coastguard Worker // "Minimum number of characters for noncanonical read"
107*cfb92d14SAndroid Build Coastguard Worker termios.c_cc[VMIN] = 1;
108*cfb92d14SAndroid Build Coastguard Worker
109*cfb92d14SAndroid Build Coastguard Worker // "Timeout in deciseconds for noncanonical read"
110*cfb92d14SAndroid Build Coastguard Worker termios.c_cc[VTIME] = 0;
111*cfb92d14SAndroid Build Coastguard Worker
112*cfb92d14SAndroid Build Coastguard Worker // configure baud rate
113*cfb92d14SAndroid Build Coastguard Worker otEXPECT_ACTION(cfsetispeed(&termios, OPENTHREAD_SIMULATION_UART_BAUDRATE) == 0, perror("cfsetispeed");
114*cfb92d14SAndroid Build Coastguard Worker error = OT_ERROR_GENERIC);
115*cfb92d14SAndroid Build Coastguard Worker
116*cfb92d14SAndroid Build Coastguard Worker // set configuration
117*cfb92d14SAndroid Build Coastguard Worker otEXPECT_ACTION(tcsetattr(s_in_fd, TCSANOW, &termios) == 0, perror("tcsetattr"); error = OT_ERROR_GENERIC);
118*cfb92d14SAndroid Build Coastguard Worker }
119*cfb92d14SAndroid Build Coastguard Worker
120*cfb92d14SAndroid Build Coastguard Worker if (isatty(s_out_fd))
121*cfb92d14SAndroid Build Coastguard Worker {
122*cfb92d14SAndroid Build Coastguard Worker // get current configuration
123*cfb92d14SAndroid Build Coastguard Worker otEXPECT_ACTION(tcgetattr(s_out_fd, &termios) == 0, perror("tcgetattr"); error = OT_ERROR_GENERIC);
124*cfb92d14SAndroid Build Coastguard Worker
125*cfb92d14SAndroid Build Coastguard Worker // Set up the termios settings for raw mode. This turns
126*cfb92d14SAndroid Build Coastguard Worker // off input/output processing, line processing, and character processing.
127*cfb92d14SAndroid Build Coastguard Worker cfmakeraw(&termios);
128*cfb92d14SAndroid Build Coastguard Worker
129*cfb92d14SAndroid Build Coastguard Worker // Absolutely obliterate all output processing.
130*cfb92d14SAndroid Build Coastguard Worker termios.c_oflag = 0;
131*cfb92d14SAndroid Build Coastguard Worker
132*cfb92d14SAndroid Build Coastguard Worker // Set up our cflags for local use. Turn on hangup-on-close.
133*cfb92d14SAndroid Build Coastguard Worker termios.c_cflag |= HUPCL | CREAD | CLOCAL;
134*cfb92d14SAndroid Build Coastguard Worker
135*cfb92d14SAndroid Build Coastguard Worker // configure baud rate
136*cfb92d14SAndroid Build Coastguard Worker otEXPECT_ACTION(cfsetospeed(&termios, OPENTHREAD_SIMULATION_UART_BAUDRATE) == 0, perror("cfsetospeed");
137*cfb92d14SAndroid Build Coastguard Worker error = OT_ERROR_GENERIC);
138*cfb92d14SAndroid Build Coastguard Worker
139*cfb92d14SAndroid Build Coastguard Worker // set configuration
140*cfb92d14SAndroid Build Coastguard Worker otEXPECT_ACTION(tcsetattr(s_out_fd, TCSANOW, &termios) == 0, perror("tcsetattr"); error = OT_ERROR_GENERIC);
141*cfb92d14SAndroid Build Coastguard Worker }
142*cfb92d14SAndroid Build Coastguard Worker
143*cfb92d14SAndroid Build Coastguard Worker return error;
144*cfb92d14SAndroid Build Coastguard Worker
145*cfb92d14SAndroid Build Coastguard Worker exit:
146*cfb92d14SAndroid Build Coastguard Worker close(s_in_fd);
147*cfb92d14SAndroid Build Coastguard Worker close(s_out_fd);
148*cfb92d14SAndroid Build Coastguard Worker return error;
149*cfb92d14SAndroid Build Coastguard Worker }
150*cfb92d14SAndroid Build Coastguard Worker
otPlatUartDisable(void)151*cfb92d14SAndroid Build Coastguard Worker otError otPlatUartDisable(void)
152*cfb92d14SAndroid Build Coastguard Worker {
153*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
154*cfb92d14SAndroid Build Coastguard Worker
155*cfb92d14SAndroid Build Coastguard Worker close(s_in_fd);
156*cfb92d14SAndroid Build Coastguard Worker close(s_out_fd);
157*cfb92d14SAndroid Build Coastguard Worker
158*cfb92d14SAndroid Build Coastguard Worker return error;
159*cfb92d14SAndroid Build Coastguard Worker }
160*cfb92d14SAndroid Build Coastguard Worker
otPlatUartSend(const uint8_t * aBuf,uint16_t aBufLength)161*cfb92d14SAndroid Build Coastguard Worker otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
162*cfb92d14SAndroid Build Coastguard Worker {
163*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
164*cfb92d14SAndroid Build Coastguard Worker
165*cfb92d14SAndroid Build Coastguard Worker otEXPECT_ACTION(s_write_length == 0, error = OT_ERROR_BUSY);
166*cfb92d14SAndroid Build Coastguard Worker
167*cfb92d14SAndroid Build Coastguard Worker s_write_buffer = aBuf;
168*cfb92d14SAndroid Build Coastguard Worker s_write_length = aBufLength;
169*cfb92d14SAndroid Build Coastguard Worker
170*cfb92d14SAndroid Build Coastguard Worker exit:
171*cfb92d14SAndroid Build Coastguard Worker return error;
172*cfb92d14SAndroid Build Coastguard Worker }
173*cfb92d14SAndroid Build Coastguard Worker
platformUartUpdateFdSet(fd_set * aReadFdSet,fd_set * aWriteFdSet,fd_set * aErrorFdSet,int * aMaxFd)174*cfb92d14SAndroid Build Coastguard Worker void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
175*cfb92d14SAndroid Build Coastguard Worker {
176*cfb92d14SAndroid Build Coastguard Worker utilsAddFdToFdSet(s_in_fd, aReadFdSet, aMaxFd);
177*cfb92d14SAndroid Build Coastguard Worker utilsAddFdToFdSet(s_in_fd, aErrorFdSet, aMaxFd);
178*cfb92d14SAndroid Build Coastguard Worker
179*cfb92d14SAndroid Build Coastguard Worker if ((s_write_length > 0))
180*cfb92d14SAndroid Build Coastguard Worker {
181*cfb92d14SAndroid Build Coastguard Worker utilsAddFdToFdSet(s_out_fd, aWriteFdSet, aMaxFd);
182*cfb92d14SAndroid Build Coastguard Worker utilsAddFdToFdSet(s_out_fd, aErrorFdSet, aMaxFd);
183*cfb92d14SAndroid Build Coastguard Worker }
184*cfb92d14SAndroid Build Coastguard Worker }
185*cfb92d14SAndroid Build Coastguard Worker
otPlatUartFlush(void)186*cfb92d14SAndroid Build Coastguard Worker otError otPlatUartFlush(void)
187*cfb92d14SAndroid Build Coastguard Worker {
188*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
189*cfb92d14SAndroid Build Coastguard Worker ssize_t count;
190*cfb92d14SAndroid Build Coastguard Worker
191*cfb92d14SAndroid Build Coastguard Worker otEXPECT_ACTION(s_write_buffer != NULL && s_write_length > 0, error = OT_ERROR_INVALID_STATE);
192*cfb92d14SAndroid Build Coastguard Worker
193*cfb92d14SAndroid Build Coastguard Worker while ((count = write(s_out_fd, s_write_buffer, s_write_length)) > 0 && (s_write_length -= count) > 0)
194*cfb92d14SAndroid Build Coastguard Worker {
195*cfb92d14SAndroid Build Coastguard Worker s_write_buffer += count;
196*cfb92d14SAndroid Build Coastguard Worker }
197*cfb92d14SAndroid Build Coastguard Worker
198*cfb92d14SAndroid Build Coastguard Worker if (count != -1)
199*cfb92d14SAndroid Build Coastguard Worker {
200*cfb92d14SAndroid Build Coastguard Worker assert(s_write_length == 0);
201*cfb92d14SAndroid Build Coastguard Worker s_write_buffer = NULL;
202*cfb92d14SAndroid Build Coastguard Worker }
203*cfb92d14SAndroid Build Coastguard Worker else
204*cfb92d14SAndroid Build Coastguard Worker {
205*cfb92d14SAndroid Build Coastguard Worker perror("write(UART)");
206*cfb92d14SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
207*cfb92d14SAndroid Build Coastguard Worker }
208*cfb92d14SAndroid Build Coastguard Worker
209*cfb92d14SAndroid Build Coastguard Worker exit:
210*cfb92d14SAndroid Build Coastguard Worker return error;
211*cfb92d14SAndroid Build Coastguard Worker }
212*cfb92d14SAndroid Build Coastguard Worker
platformUartProcess(void)213*cfb92d14SAndroid Build Coastguard Worker void platformUartProcess(void)
214*cfb92d14SAndroid Build Coastguard Worker {
215*cfb92d14SAndroid Build Coastguard Worker ssize_t rval;
216*cfb92d14SAndroid Build Coastguard Worker const int error_flags = POLLERR | POLLNVAL | POLLHUP;
217*cfb92d14SAndroid Build Coastguard Worker struct pollfd pollfd[] = {
218*cfb92d14SAndroid Build Coastguard Worker {s_in_fd, POLLIN | error_flags, 0},
219*cfb92d14SAndroid Build Coastguard Worker {s_out_fd, POLLOUT | error_flags, 0},
220*cfb92d14SAndroid Build Coastguard Worker };
221*cfb92d14SAndroid Build Coastguard Worker
222*cfb92d14SAndroid Build Coastguard Worker errno = 0;
223*cfb92d14SAndroid Build Coastguard Worker
224*cfb92d14SAndroid Build Coastguard Worker rval = poll(pollfd, sizeof(pollfd) / sizeof(*pollfd), 0);
225*cfb92d14SAndroid Build Coastguard Worker
226*cfb92d14SAndroid Build Coastguard Worker if (rval < 0)
227*cfb92d14SAndroid Build Coastguard Worker {
228*cfb92d14SAndroid Build Coastguard Worker perror("poll");
229*cfb92d14SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
230*cfb92d14SAndroid Build Coastguard Worker }
231*cfb92d14SAndroid Build Coastguard Worker
232*cfb92d14SAndroid Build Coastguard Worker if (rval > 0)
233*cfb92d14SAndroid Build Coastguard Worker {
234*cfb92d14SAndroid Build Coastguard Worker if ((pollfd[0].revents & error_flags) != 0)
235*cfb92d14SAndroid Build Coastguard Worker {
236*cfb92d14SAndroid Build Coastguard Worker perror("s_in_fd");
237*cfb92d14SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
238*cfb92d14SAndroid Build Coastguard Worker }
239*cfb92d14SAndroid Build Coastguard Worker
240*cfb92d14SAndroid Build Coastguard Worker if ((pollfd[1].revents & error_flags) != 0)
241*cfb92d14SAndroid Build Coastguard Worker {
242*cfb92d14SAndroid Build Coastguard Worker perror("s_out_fd");
243*cfb92d14SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
244*cfb92d14SAndroid Build Coastguard Worker }
245*cfb92d14SAndroid Build Coastguard Worker
246*cfb92d14SAndroid Build Coastguard Worker if (pollfd[0].revents & POLLIN)
247*cfb92d14SAndroid Build Coastguard Worker {
248*cfb92d14SAndroid Build Coastguard Worker rval = read(s_in_fd, s_receive_buffer, sizeof(s_receive_buffer));
249*cfb92d14SAndroid Build Coastguard Worker
250*cfb92d14SAndroid Build Coastguard Worker if (rval <= 0)
251*cfb92d14SAndroid Build Coastguard Worker {
252*cfb92d14SAndroid Build Coastguard Worker perror("read");
253*cfb92d14SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
254*cfb92d14SAndroid Build Coastguard Worker }
255*cfb92d14SAndroid Build Coastguard Worker
256*cfb92d14SAndroid Build Coastguard Worker otPlatUartReceived(s_receive_buffer, (uint16_t)rval);
257*cfb92d14SAndroid Build Coastguard Worker }
258*cfb92d14SAndroid Build Coastguard Worker
259*cfb92d14SAndroid Build Coastguard Worker if ((s_write_length > 0) && (pollfd[1].revents & POLLOUT))
260*cfb92d14SAndroid Build Coastguard Worker {
261*cfb92d14SAndroid Build Coastguard Worker rval = write(s_out_fd, s_write_buffer, s_write_length);
262*cfb92d14SAndroid Build Coastguard Worker
263*cfb92d14SAndroid Build Coastguard Worker if (rval >= 0)
264*cfb92d14SAndroid Build Coastguard Worker {
265*cfb92d14SAndroid Build Coastguard Worker s_write_buffer += (uint16_t)rval;
266*cfb92d14SAndroid Build Coastguard Worker s_write_length -= (uint16_t)rval;
267*cfb92d14SAndroid Build Coastguard Worker
268*cfb92d14SAndroid Build Coastguard Worker if (s_write_length == 0)
269*cfb92d14SAndroid Build Coastguard Worker {
270*cfb92d14SAndroid Build Coastguard Worker otPlatUartSendDone();
271*cfb92d14SAndroid Build Coastguard Worker }
272*cfb92d14SAndroid Build Coastguard Worker }
273*cfb92d14SAndroid Build Coastguard Worker else if (errno != EINTR)
274*cfb92d14SAndroid Build Coastguard Worker {
275*cfb92d14SAndroid Build Coastguard Worker perror("write");
276*cfb92d14SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
277*cfb92d14SAndroid Build Coastguard Worker }
278*cfb92d14SAndroid Build Coastguard Worker }
279*cfb92d14SAndroid Build Coastguard Worker }
280*cfb92d14SAndroid Build Coastguard Worker }
281*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME_UART == 0
282*cfb92d14SAndroid Build Coastguard Worker
283*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART && (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART)
284*cfb92d14SAndroid Build Coastguard Worker
285*cfb92d14SAndroid Build Coastguard Worker static FILE *posix_logfile;
286*cfb92d14SAndroid Build Coastguard Worker
otPlatDebugUart_logfile(const char * filename)287*cfb92d14SAndroid Build Coastguard Worker otError otPlatDebugUart_logfile(const char *filename)
288*cfb92d14SAndroid Build Coastguard Worker {
289*cfb92d14SAndroid Build Coastguard Worker posix_logfile = fopen(filename, "wt");
290*cfb92d14SAndroid Build Coastguard Worker
291*cfb92d14SAndroid Build Coastguard Worker return posix_logfile ? OT_ERROR_NONE : OT_ERROR_FAILED;
292*cfb92d14SAndroid Build Coastguard Worker }
293*cfb92d14SAndroid Build Coastguard Worker
otPlatDebugUart_putchar_raw(int c)294*cfb92d14SAndroid Build Coastguard Worker void otPlatDebugUart_putchar_raw(int c)
295*cfb92d14SAndroid Build Coastguard Worker {
296*cfb92d14SAndroid Build Coastguard Worker FILE *fp;
297*cfb92d14SAndroid Build Coastguard Worker
298*cfb92d14SAndroid Build Coastguard Worker /* note: log file will have a mix of cr/lf and
299*cfb92d14SAndroid Build Coastguard Worker * in some/many cases duplicate cr because in
300*cfb92d14SAndroid Build Coastguard Worker * some cases the log function {ie: Mbed} already
301*cfb92d14SAndroid Build Coastguard Worker * includes the CR or LF... but other log functions
302*cfb92d14SAndroid Build Coastguard Worker * do not include cr/lf and expect it appended
303*cfb92d14SAndroid Build Coastguard Worker */
304*cfb92d14SAndroid Build Coastguard Worker fp = posix_logfile;
305*cfb92d14SAndroid Build Coastguard Worker
306*cfb92d14SAndroid Build Coastguard Worker if (fp != NULL)
307*cfb92d14SAndroid Build Coastguard Worker {
308*cfb92d14SAndroid Build Coastguard Worker /* log is lost ... until a file is setup */
309*cfb92d14SAndroid Build Coastguard Worker fputc(c, fp);
310*cfb92d14SAndroid Build Coastguard Worker /* we could "fflush" but will not */
311*cfb92d14SAndroid Build Coastguard Worker }
312*cfb92d14SAndroid Build Coastguard Worker }
313*cfb92d14SAndroid Build Coastguard Worker
otPlatDebugUart_kbhit(void)314*cfb92d14SAndroid Build Coastguard Worker int otPlatDebugUart_kbhit(void)
315*cfb92d14SAndroid Build Coastguard Worker {
316*cfb92d14SAndroid Build Coastguard Worker /* not supported */
317*cfb92d14SAndroid Build Coastguard Worker return 0;
318*cfb92d14SAndroid Build Coastguard Worker }
319*cfb92d14SAndroid Build Coastguard Worker
otPlatDebugUart_getc(void)320*cfb92d14SAndroid Build Coastguard Worker int otPlatDebugUart_getc(void)
321*cfb92d14SAndroid Build Coastguard Worker {
322*cfb92d14SAndroid Build Coastguard Worker /* not supported */
323*cfb92d14SAndroid Build Coastguard Worker return -1;
324*cfb92d14SAndroid Build Coastguard Worker }
325*cfb92d14SAndroid Build Coastguard Worker
326*cfb92d14SAndroid Build Coastguard Worker #endif
327