1 /*
2 * Copyright (c) 2017, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28 #include <openthread-core-config.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <openthread/config.h>
32
33 #include <openthread/platform/alarm-milli.h>
34 #include <openthread/platform/debug_uart.h>
35 #include <openthread/platform/toolchain.h>
36
37 /*
38 * Implementation note:
39 * These are all "weak" so that a platform may if it chooses override the instance.
40 */
41
42 OT_TOOL_WEAK
otPlatDebugUart_printf(const char * fmt,...)43 void otPlatDebugUart_printf(const char *fmt, ...)
44 {
45 va_list ap;
46 va_start(ap, fmt);
47 otPlatDebugUart_vprintf(fmt, ap);
48 va_end(ap);
49 }
50
51 OT_TOOL_WEAK
otPlatDebugUart_vprintf(const char * fmt,va_list ap)52 void otPlatDebugUart_vprintf(const char *fmt, va_list ap)
53 {
54 char buf[128];
55 /* by standard ...
56 * vsnprintf() always null terminates
57 */
58 vsnprintf(buf, sizeof(buf), fmt, ap);
59 /* however ... some platforms have bugs */
60 buf[sizeof(buf) - 1] = 0;
61 otPlatDebugUart_puts_no_nl(buf);
62 }
63
64 OT_TOOL_WEAK
otPlatDebugUart_write_bytes(const uint8_t * pBytes,int nBytes)65 void otPlatDebugUart_write_bytes(const uint8_t *pBytes, int nBytes)
66 {
67 while (nBytes > 0)
68 {
69 otPlatDebugUart_putchar((int)(*pBytes));
70 pBytes++;
71 nBytes--;
72 }
73 }
74
75 OT_TOOL_WEAK
otPlatDebugUart_puts_no_nl(const char * s)76 void otPlatDebugUart_puts_no_nl(const char *s)
77 {
78 while (*s)
79 {
80 otPlatDebugUart_putchar(*s);
81 s++;
82 }
83 }
84
85 OT_TOOL_WEAK
otPlatDebugUart_puts(const char * s)86 void otPlatDebugUart_puts(const char *s)
87 {
88 otPlatDebugUart_puts_no_nl(s);
89 otPlatDebugUart_putchar('\n');
90 }
91
92 OT_TOOL_WEAK
otPlatDebugUart_putchar(int c)93 void otPlatDebugUart_putchar(int c)
94 {
95 /* map lf to crlf as needed */
96 if (c == '\n')
97 {
98 otPlatDebugUart_putchar_raw('\r');
99 }
100
101 otPlatDebugUart_putchar_raw(c);
102 }
103
104 /* provide WEAK stubs for platforms that do not implement all functions */
105 OT_TOOL_WEAK
otPlatDebugUart_putchar_raw(int c)106 void otPlatDebugUart_putchar_raw(int c)
107 {
108 OT_UNUSED_VARIABLE(c);
109 }
110
111 OT_TOOL_WEAK
otPlatDebugUart_kbhit(void)112 int otPlatDebugUart_kbhit(void)
113 {
114 return 0; /* nothing */
115 }
116
117 OT_TOOL_WEAK
otPlatDebugUart_getc(void)118 int otPlatDebugUart_getc(void)
119 {
120 return -1; /* nothing */
121 }
122
123 OT_TOOL_WEAK
otPlatDebugUart_logfile(const char * filename)124 otError otPlatDebugUart_logfile(const char *filename)
125 {
126 OT_UNUSED_VARIABLE(filename);
127
128 return OT_ERROR_FAILED;
129 }
130
131 #if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART)
132 /* this should not be a WEAK function */
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)133 void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
134 {
135 OT_UNUSED_VARIABLE(aLogLevel);
136 OT_UNUSED_VARIABLE(aLogRegion);
137
138 va_list ap;
139 uint32_t now;
140
141 now = otPlatAlarmMilliGetNow();
142 otPlatDebugUart_printf("%3d.%03d | ", (int)(now / 1000), (int)(now % 1000));
143 va_start(ap, aFormat);
144 otPlatDebugUart_vprintf(aFormat, ap);
145 va_end(ap);
146
147 otPlatDebugUart_putchar('\n');
148 }
149 #endif
150