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  * @brief
32  *   This file defines the platform-specific functions needed by OpenThread's example applications.
33  */
34 
35 #ifndef OPENTHREAD_SYSTEM_H_
36 #define OPENTHREAD_SYSTEM_H_
37 
38 #include <setjmp.h>
39 #include <stdbool.h>
40 #include <stdint.h>
41 #include <stdio.h>
42 #include <sys/select.h>
43 
44 #include <openthread/error.h>
45 #include <openthread/instance.h>
46 #include <openthread/ip6.h>
47 #include <openthread/platform/misc.h>
48 
49 #include "lib/spinel/coprocessor_type.h"
50 #include "lib/spinel/radio_spinel_metrics.h"
51 
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55 
56 /**
57  * Represents default parameters for the SPI interface.
58  *
59  */
60 enum
61 {
62     OT_PLATFORM_CONFIG_SPI_DEFAULT_MODE           = 0,       ///< Default SPI Mode: CPOL=0, CPHA=0.
63     OT_PLATFORM_CONFIG_SPI_DEFAULT_SPEED_HZ       = 1000000, ///< Default SPI speed in hertz.
64     OT_PLATFORM_CONFIG_SPI_DEFAULT_CS_DELAY_US    = 20,      ///< Default delay after SPI C̅S̅ assertion, in µsec.
65     OT_PLATFORM_CONFIG_SPI_DEFAULT_RESET_DELAY_MS = 0, ///< Default delay after R̅E̅S̅E̅T̅ assertion, in milliseconds.
66     OT_PLATFORM_CONFIG_SPI_DEFAULT_ALIGN_ALLOWANCE =
67         16, ///< Default maximum number of 0xFF bytes to clip from start of MISO frame.
68     OT_PLATFORM_CONFIG_SPI_DEFAULT_SMALL_PACKET_SIZE =
69         32,                                ///< Default smallest SPI packet size we can receive in a single transaction.
70     OT_PLATFORM_CONFIG_MAX_RADIO_URLS = 2, ///< Max number of Radio URLs.
71 };
72 
73 /**
74  * Represents the Co-processor URLs.
75  *
76  */
77 typedef struct otPlatformCoprocessorUrls
78 {
79     const char *mUrls[OT_PLATFORM_CONFIG_MAX_RADIO_URLS]; ///< Co-processor URLs.
80     uint8_t     mNum;                                     ///< Number of Co-processor URLs.
81 } otPlatformCoprocessorUrls;
82 
83 /**
84  * Represents platform specific configurations.
85  *
86  */
87 typedef struct otPlatformConfig
88 {
89     const char               *mBackboneInterfaceName; ///< Backbone network interface name.
90     const char               *mInterfaceName;         ///< Thread network interface name.
91     otPlatformCoprocessorUrls mCoprocessorUrls;       ///< Coprocessor URLs.
92     int                       mRealTimeSignal;        ///< The real-time signal for microsecond timer.
93     uint32_t                  mSpeedUpFactor;         ///< Speed up factor.
94     bool                      mPersistentInterface;   ///< Whether persistent the interface
95     bool                      mDryRun;                ///< If 'DryRun' is set, the posix daemon will exit
96                                                       ///< directly after initialization.
97     CoprocessorType mCoprocessorType;                 ///< The co-processor type. This field is used to pass
98                                                       ///< the type to the app layer.
99 } otPlatformConfig;
100 
101 /**
102  * Represents the platform spinel driver structure.
103  *
104  */
105 typedef struct otSpinelDriver otSpinelDriver;
106 
107 /**
108  * Gets the instance of the spinel driver;
109  *
110  * @note This API is used for external projects to get the instance of `SpinelDriver` to customize
111  *       different spinel handlings.
112  *
113  * @returns A pointer to the spinel driver instance.
114  *
115  */
116 otSpinelDriver *otSysGetSpinelDriver(void);
117 
118 /**
119  * Initializes the co-processor and the spinel driver.
120  *
121  * @note This API will initialize the co-processor by resetting it and return the co-processor type.
122  *       If this API is called, the upcoming call of `otSysInit` won't initialize the co-processor
123  *       and the spinel driver again, unless `otSysDeinit` is called. This API is used to get the
124  *       co-processor type without calling `otSysInit`.
125  *
126  * @param[in]  aUrls  The URLs to initialize the co-processor.
127  *
128  * @returns The co-processor type.
129  *
130  */
131 CoprocessorType otSysInitCoprocessor(otPlatformCoprocessorUrls *aUrls);
132 
133 /**
134  * Performs all platform-specific initialization of OpenThread's drivers and initializes the OpenThread
135  * instance.
136  *
137  * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
138  *       when initialization of OpenThread's drivers is most appropriate.
139  *
140  * @param[in]  aPlatformConfig  Platform configuration structure.
141  *
142  * @returns A pointer to the OpenThread instance.
143  *
144  */
145 otInstance *otSysInit(otPlatformConfig *aPlatformConfig);
146 
147 /**
148  * Finalizes the OpenThread instance and performs all platform-specific deinitialization for OpenThread's
149  * drivers.
150  *
151  * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
152  *       when deinitialization of OpenThread's drivers is most appropriate.
153  *
154  */
155 void otSysDeinit(void);
156 
157 /**
158  * Represents a context for a select() based mainloop.
159  *
160  */
161 typedef struct otSysMainloopContext
162 {
163     fd_set         mReadFdSet;  ///< The read file descriptors.
164     fd_set         mWriteFdSet; ///< The write file descriptors.
165     fd_set         mErrorFdSet; ///< The error file descriptors.
166     int            mMaxFd;      ///< The max file descriptor.
167     struct timeval mTimeout;    ///< The timeout.
168 } otSysMainloopContext;
169 
170 /**
171  * Updates the file descriptor sets with file descriptors used by OpenThread drivers.
172  *
173  * @param[in]       aInstance   The OpenThread instance structure.
174  * @param[in,out]   aMainloop   A pointer to the mainloop context.
175  *
176  */
177 void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop);
178 
179 /**
180  * Polls OpenThread's mainloop.
181  *
182  * @param[in,out]   aMainloop   A pointer to the mainloop context.
183  *
184  * @returns value returned from select().
185  *
186  */
187 int otSysMainloopPoll(otSysMainloopContext *aMainloop);
188 
189 /**
190  * Performs all platform-specific processing for OpenThread's example applications.
191  *
192  * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function
193  *       in the main loop when processing OpenThread's drivers is most appropriate.
194  *
195  * @param[in]   aInstance   The OpenThread instance structure.
196  * @param[in]   aMainloop   A pointer to the mainloop context.
197  *
198  */
199 void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop);
200 
201 /**
202  * Returns the radio url help string.
203  *
204  * @returns the radio url help string.
205  *
206  */
207 const char *otSysGetRadioUrlHelpString(void);
208 
209 extern otPlatResetReason gPlatResetReason;
210 
211 /**
212  * Returns the Thread network interface name.
213  *
214  * @returns The Thread network interface name.
215  *
216  */
217 const char *otSysGetThreadNetifName(void);
218 
219 /**
220  * Returns the Thread network interface index.
221  *
222  * @returns The Thread network interface index.
223  *
224  */
225 unsigned int otSysGetThreadNetifIndex(void);
226 
227 /**
228  * Returns the infrastructure network interface name.
229  *
230  * @returns The infrastructure network interface name, or `nullptr` if not specified.
231  *
232  */
233 const char *otSysGetInfraNetifName(void);
234 
235 /**
236  * Returns the infrastructure network interface index.
237  *
238  * @returns The infrastructure network interface index.
239  *
240  */
241 uint32_t otSysGetInfraNetifIndex(void);
242 
243 /**
244  * Returns the radio spinel metrics.
245  *
246  * @returns The radio spinel metrics.
247  *
248  */
249 const otRadioSpinelMetrics *otSysGetRadioSpinelMetrics(void);
250 
251 /**
252  * Returns the RCP interface metrics.
253  *
254  * @returns The RCP interface metrics.
255  *
256  */
257 const otRcpInterfaceMetrics *otSysGetRcpInterfaceMetrics(void);
258 
259 /**
260  * Returns the ifr_flags of the infrastructure network interface.
261  *
262  * @returns The ifr_flags of infrastructure network interface.
263  *
264  */
265 uint32_t otSysGetInfraNetifFlags(void);
266 
267 typedef struct otSysInfraNetIfAddressCounters
268 {
269     uint32_t mLinkLocalAddresses;
270     uint32_t mUniqueLocalAddresses;
271     uint32_t mGlobalUnicastAddresses;
272 } otSysInfraNetIfAddressCounters;
273 
274 /**
275  * This functions counts the number of addresses on the infrastructure network interface.
276  *
277  * @param[out] aAddressCounters  The counters of addresses on infrastructure network interface.
278  *
279  */
280 void otSysCountInfraNetifAddresses(otSysInfraNetIfAddressCounters *aAddressCounters);
281 
282 /**
283  * Sets the infrastructure network interface and the ICMPv6 socket.
284  *
285  * This function specifies the network interface name and the ICMPv6 socket on that interface. After calling this
286  * function, the caller can call otBorderRoutingInit() to let Border Routing work on that interface.
287  *
288  * @param[in] aInfraNetifName  The name of the infrastructure network interface.
289  * @param[in] aIcmp6Socket     A SOCK_RAW socket running on the infrastructure network interface.
290  *
291  */
292 void otSysSetInfraNetif(const char *aInfraNetifName, int aIcmp6Socket);
293 
294 /**
295  * Returns TRUE if the infrastructure interface is running.
296  *
297  * @returns TRUE if the infrastructure interface is running, FALSE if not.
298  *
299  */
300 bool otSysInfraIfIsRunning(void);
301 
302 /**
303  * Initializes the CLI module using the daemon.
304  *
305  * This function initializes the CLI module, and assigns the daemon to handle
306  * the CLI output. This function can be invoked multiple times. The typical use case
307  * is that, after OTBR/vendor_server's CLI output redirection, it uses this API to
308  * restore the original daemon's CLI output.
309  *
310  * @param[in] aInstance  The OpenThread instance structure.
311  *
312  */
313 void otSysCliInitUsingDaemon(otInstance *aInstance);
314 
315 /**
316  * Sets whether to retrieve upstream DNS servers from "resolv.conf".
317  *
318  * @param[in] aEnabled  TRUE if enable retrieving upstream DNS servers from "resolv.conf", FALSE otherwise.
319  *
320  */
321 void otSysUpstreamDnsServerSetResolvConfEnabled(bool aEnabled);
322 
323 /**
324  * Sets the upstream DNS server list.
325  *
326  * @param[in] aUpstreamDnsServers  A pointer to the list of upstream DNS server addresses. Each address could be an IPv6
327  *                                 address or an IPv4-mapped IPv6 address.
328  * @param[in] aNumServers          The number of upstream DNS servers.
329  *
330  */
331 void otSysUpstreamDnsSetServerList(const otIp6Address *aUpstreamDnsServers, int aNumServers);
332 
333 #ifdef __cplusplus
334 } // end of extern "C"
335 #endif
336 
337 #endif // OPENTHREAD_SYSTEM_H_
338