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