1 /*
2  *  Copyright (c) 2016, 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 /**
30  * @file
31  *   This file implements the OpenThread Instance API.
32  */
33 
34 #include "openthread-core-config.h"
35 
36 #include <openthread/instance.h>
37 #include <openthread/platform/misc.h>
38 
39 #include "common/as_core_type.hpp"
40 #include "common/locator_getters.hpp"
41 #include "common/new.hpp"
42 #include "radio/radio.hpp"
43 
44 #if !defined(OPENTHREAD_BUILD_DATETIME)
45 #ifdef __ANDROID__
46 #ifdef OPENTHREAD_CONFIG_ANDROID_NDK_ENABLE
47 #include <sys/system_properties.h>
48 #else
49 #include <cutils/properties.h>
50 #endif
51 #else // __ANDROID__
52 #if defined(__DATE__)
53 #define OPENTHREAD_BUILD_DATETIME __DATE__ " " __TIME__
54 #endif
55 #endif // __ANDROID__
56 #endif // !defined(OPENTHREAD_BUILD_DATETIME)
57 
58 using namespace ot;
59 
60 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
61 #if OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE
otInstanceInitMultiple(uint8_t aIdx)62 otInstance *otInstanceInitMultiple(uint8_t aIdx)
63 {
64     Instance *instance;
65 
66     instance = Instance::InitMultiple(aIdx);
67 
68     return instance;
69 }
70 #endif // OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE
otInstanceInit(void * aInstanceBuffer,size_t * aInstanceBufferSize)71 otInstance *otInstanceInit(void *aInstanceBuffer, size_t *aInstanceBufferSize)
72 {
73     Instance *instance;
74 
75     instance = Instance::Init(aInstanceBuffer, aInstanceBufferSize);
76 
77     return instance;
78 }
79 #else
otInstanceInitSingle(void)80 otInstance *otInstanceInitSingle(void) { return &Instance::InitSingle(); }
81 #endif // #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
82 
otInstanceGetId(otInstance * aInstance)83 uint32_t otInstanceGetId(otInstance *aInstance) { return AsCoreType(aInstance).GetId(); }
84 
otInstanceIsInitialized(otInstance * aInstance)85 bool otInstanceIsInitialized(otInstance *aInstance)
86 {
87 #if OPENTHREAD_MTD || OPENTHREAD_FTD
88     return AsCoreType(aInstance).IsInitialized();
89 #else
90     OT_UNUSED_VARIABLE(aInstance);
91     return true;
92 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
93 }
94 
otInstanceFinalize(otInstance * aInstance)95 void otInstanceFinalize(otInstance *aInstance) { AsCoreType(aInstance).Finalize(); }
96 
otInstanceReset(otInstance * aInstance)97 void otInstanceReset(otInstance *aInstance) { AsCoreType(aInstance).Reset(); }
98 
99 #if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE
otInstanceResetToBootloader(otInstance * aInstance)100 otError otInstanceResetToBootloader(otInstance *aInstance) { return AsCoreType(aInstance).ResetToBootloader(); }
101 #endif
102 
103 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
otInstanceGetUptime(otInstance * aInstance)104 uint64_t otInstanceGetUptime(otInstance *aInstance) { return AsCoreType(aInstance).Get<Uptime>().GetUptime(); }
105 
otInstanceGetUptimeAsString(otInstance * aInstance,char * aBuffer,uint16_t aSize)106 void otInstanceGetUptimeAsString(otInstance *aInstance, char *aBuffer, uint16_t aSize)
107 {
108     AssertPointerIsNotNull(aBuffer);
109 
110     AsCoreType(aInstance).Get<Uptime>().GetUptime(aBuffer, aSize);
111 }
112 #endif
113 
114 #if OPENTHREAD_MTD || OPENTHREAD_FTD
otSetStateChangedCallback(otInstance * aInstance,otStateChangedCallback aCallback,void * aContext)115 otError otSetStateChangedCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aContext)
116 {
117     return AsCoreType(aInstance).Get<Notifier>().RegisterCallback(aCallback, aContext);
118 }
119 
otRemoveStateChangeCallback(otInstance * aInstance,otStateChangedCallback aCallback,void * aContext)120 void otRemoveStateChangeCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aContext)
121 {
122     AsCoreType(aInstance).Get<Notifier>().RemoveCallback(aCallback, aContext);
123 }
124 
otInstanceFactoryReset(otInstance * aInstance)125 void otInstanceFactoryReset(otInstance *aInstance) { AsCoreType(aInstance).FactoryReset(); }
126 
otInstanceErasePersistentInfo(otInstance * aInstance)127 otError otInstanceErasePersistentInfo(otInstance *aInstance) { return AsCoreType(aInstance).ErasePersistentInfo(); }
128 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
129 
130 #if OPENTHREAD_RADIO
otInstanceResetRadioStack(otInstance * aInstance)131 void otInstanceResetRadioStack(otInstance *aInstance) { AsCoreType(aInstance).ResetRadioStack(); }
132 #endif
133 
otGetVersionString(void)134 const char *otGetVersionString(void)
135 {
136     /**
137      * PLATFORM_VERSION_ATTR_PREFIX and PLATFORM_VERSION_ATTR_SUFFIX are
138      * intended to be used to specify compiler directives to indicate
139      * what linker section the platform version string should be stored.
140      *
141      * This is useful for specifying an exact location of where the version
142      * string will be located so that it can be easily retrieved from the
143      * raw firmware image.
144      *
145      * If PLATFORM_VERSION_ATTR_PREFIX is unspecified, the keyword `static`
146      * is used instead.
147      *
148      * If both are unspecified, the location of the string in the firmware
149      * image will be undefined and may change.
150      */
151 
152 #if !defined(OPENTHREAD_BUILD_DATETIME) && defined(__ANDROID__)
153 
154 #ifdef OPENTHREAD_CONFIG_ANDROID_NDK_ENABLE
155     static char sVersion[100 + PROP_VALUE_MAX];
156     char        dateTime[PROP_VALUE_MAX];
157 
158     __system_property_get("ro.build.date", dateTime);
159 #else
160     static char sVersion[100 + PROPERTY_VALUE_MAX];
161     char        dateTime[PROPERTY_VALUE_MAX];
162 
163     property_get("ro.build.date", dateTime, "Thu Jan 1 1970 UTC 00:00:00");
164 #endif
165 
166     snprintf(sVersion, sizeof(sVersion), "%s/%s ;%s ; %s", PACKAGE_NAME, PACKAGE_VERSION,
167              OPENTHREAD_CONFIG_PLATFORM_INFO, dateTime);
168 #else
169 
170 #ifdef PLATFORM_VERSION_ATTR_PREFIX
171     PLATFORM_VERSION_ATTR_PREFIX
172 #else
173     static
174 #endif
175     const char sVersion[] = PACKAGE_NAME "/" PACKAGE_VERSION "; " OPENTHREAD_CONFIG_PLATFORM_INFO
176 #ifdef OPENTHREAD_BUILD_DATETIME
177                                          "; " OPENTHREAD_BUILD_DATETIME
178 #endif
179 #ifdef PLATFORM_VERSION_ATTR_SUFFIX
180                                              PLATFORM_VERSION_ATTR_SUFFIX
181 #endif
182         ; // Trailing semicolon to end statement.
183 
184 #endif
185 
186     return sVersion;
187 }
188 
otGetRadioVersionString(otInstance * aInstance)189 const char *otGetRadioVersionString(otInstance *aInstance)
190 {
191     return AsCoreType(aInstance).Get<Radio>().GetVersionString();
192 }
193