1 /*
2 * Copyright (c) 2024, 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
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include <openthread/platform/entropy.h>
33 #include <openthread/platform/logging.h>
34 #include <openthread/platform/misc.h>
35
36 #include "nexus_core.hpp"
37 #include "nexus_node.hpp"
38
39 namespace ot {
40 namespace Nexus {
41
42 static void LogVarArgs(Node *aActiveNode, const char *aFormat, va_list aArgs);
43
44 extern "C" {
45
46 //---------------------------------------------------------------------------------------------------------------------
47 // otTasklets
48
otTaskletsSignalPending(otInstance * aInstance)49 void otTaskletsSignalPending(otInstance *aInstance)
50 {
51 OT_UNUSED_VARIABLE(aInstance);
52
53 Core::Get().MarkPendingAction();
54 }
55
56 //---------------------------------------------------------------------------------------------------------------------
57 // otPlatLog
58
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)59 void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
60 {
61 OT_UNUSED_VARIABLE(aLogLevel);
62 OT_UNUSED_VARIABLE(aLogRegion);
63
64 va_list args;
65
66 va_start(args, aFormat);
67 LogVarArgs(Core::Get().GetActiveNode(), aFormat, args);
68 va_end(args);
69 }
70
71 //---------------------------------------------------------------------------------------------------------------------
72 // Heap allocation APIs
73
otPlatCAlloc(size_t aNum,size_t aSize)74 void *otPlatCAlloc(size_t aNum, size_t aSize)
75 {
76 void *ptr = calloc(aNum, aSize);
77 return ptr;
78 }
79
otPlatFree(void * aPtr)80 void otPlatFree(void *aPtr) { free(aPtr); }
81
82 //---------------------------------------------------------------------------------------------------------------------
83 // Entropy
84
otPlatEntropyGet(uint8_t * aOutput,uint16_t aOutputLength)85 otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
86 {
87 Error error = OT_ERROR_NONE;
88 FILE *file = nullptr;
89 size_t readLength;
90
91 file = fopen("/dev/urandom", "rb");
92 VerifyOrExit(file != nullptr, error = kErrorFailed);
93
94 readLength = fread(aOutput, 1, aOutputLength, file);
95
96 if (readLength != aOutputLength)
97 {
98 error = kErrorFailed;
99 }
100
101 fclose(file);
102
103 exit:
104 return error;
105 }
106
107 //---------------------------------------------------------------------------------------------------------------------
108 // Misc
109
otPlatDiagProcess(otInstance *,uint8_t,char * [])110 otError otPlatDiagProcess(otInstance *, uint8_t, char *[]) { return kErrorNotImplemented; }
otPlatDiagModeSet(bool)111 void otPlatDiagModeSet(bool) {}
otPlatDiagModeGet()112 bool otPlatDiagModeGet() { return false; }
otPlatDiagChannelSet(uint8_t)113 void otPlatDiagChannelSet(uint8_t) {}
otPlatDiagTxPowerSet(int8_t)114 void otPlatDiagTxPowerSet(int8_t) {}
otPlatDiagRadioReceived(otInstance *,otRadioFrame *,otError)115 void otPlatDiagRadioReceived(otInstance *, otRadioFrame *, otError) {}
otPlatDiagAlarmCallback(otInstance *)116 void otPlatDiagAlarmCallback(otInstance *) {}
otPlatUartSendDone(void)117 void otPlatUartSendDone(void) {}
otPlatUartReceived(const uint8_t *,uint16_t)118 void otPlatUartReceived(const uint8_t *, uint16_t) {}
otPlatReset(otInstance *)119 void otPlatReset(otInstance *) {}
otPlatResetToBootloader(otInstance *)120 otError otPlatResetToBootloader(otInstance *) { return kErrorNotImplemented; }
otPlatGetResetReason(otInstance *)121 otPlatResetReason otPlatGetResetReason(otInstance *) { return OT_PLAT_RESET_REASON_POWER_ON; }
otPlatWakeHost(void)122 void otPlatWakeHost(void) {}
123
124 } // extern "C"
125
126 //---------------------------------------------------------------------------------------------------------------------
127 // Log related function
128
Log(const char * aFormat,...)129 void Log(const char *aFormat, ...)
130 {
131 va_list args;
132
133 va_start(args, aFormat);
134 LogVarArgs(nullptr, aFormat, args);
135 va_end(args);
136 }
137
LogVarArgs(Node * aActiveNode,const char * aFormat,va_list aArgs)138 static void LogVarArgs(Node *aActiveNode, const char *aFormat, va_list aArgs)
139 {
140 uint32_t now = Core::Get().GetNow().GetValue();
141
142 printf("%02u:%02u:%02u.%03u ", now / 3600000, (now / 60000) % 60, (now / 1000) % 60, now % 1000);
143
144 if (aActiveNode != nullptr)
145 {
146 printf("%03u ", aActiveNode->GetInstance().GetId());
147 }
148
149 vprintf(aFormat, aArgs);
150 printf("\n");
151 }
152
153 } // namespace Nexus
154 } // namespace ot
155