1 /*
2  *  Copyright (c) 2021, 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 #ifndef OT_POSIX_PLATFORM_RADIO_HPP_
30 #define OT_POSIX_PLATFORM_RADIO_HPP_
31 
32 #include "hdlc_interface.hpp"
33 #include "logger.hpp"
34 #include "radio_url.hpp"
35 #include "rcp_caps_diag.hpp"
36 #include "spi_interface.hpp"
37 #include "spinel_manager.hpp"
38 #include "vendor_interface.hpp"
39 #include "common/code_utils.hpp"
40 #include "lib/spinel/radio_spinel.hpp"
41 #include "lib/spinel/spinel_driver.hpp"
42 #if OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
43 #ifdef OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
44 #include OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
45 #endif
46 #endif
47 
48 namespace ot {
49 namespace Posix {
50 
51 /**
52  * Manages Thread radio.
53  */
54 class Radio : public Logger<Radio>
55 {
56 public:
57     static const char kLogModuleName[]; ///< Module name used for logging.
58 
59     /**
60      * Creates the radio manager.
61      */
62     Radio(void);
63 
64     /**
65      * Initialize the Thread radio.
66      *
67      * @param[in]   aUrl    A pointer to the null-terminated URL.
68      */
69     void Init(const char *aUrl);
70 
71     /**
72      * Acts as an accessor to the spinel interface instance used by the radio.
73      *
74      * @returns A reference to the radio's spinel interface instance.
75      */
GetSpinelInterface(void)76     Spinel::SpinelInterface &GetSpinelInterface(void) { return SpinelManager::GetSpinelManager().GetSpinelInterface(); }
77 
78     /**
79      * Acts as an accessor to the radio spinel instance used by the radio.
80      *
81      * @returns A reference to the radio spinel instance.
82      */
GetRadioSpinel(void)83     Spinel::RadioSpinel &GetRadioSpinel(void) { return mRadioSpinel; }
84 
85     /**
86      * Acts as an accessor to the RCP capability diagnostic instance used by the radio.
87      *
88      * @returns A reference to the RCP capability diagnostic instance.
89      */
90 #if OPENTHREAD_POSIX_CONFIG_RCP_CAPS_DIAG_ENABLE
GetRcpCapsDiag(void)91     RcpCapsDiag &GetRcpCapsDiag(void) { return mRcpCapsDiag; }
92 #endif
93 
94 private:
95     void ProcessRadioUrl(const RadioUrl &aRadioUrl);
96     void ProcessMaxPowerTable(const RadioUrl &aRadioUrl);
97 
98 #if OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE && OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
99     static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::SpiInterface) > sizeof(ot::Posix::HdlcInterface)
100                                                           ? sizeof(ot::Posix::SpiInterface)
101                                                           : sizeof(ot::Posix::HdlcInterface);
102 #elif OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE
103     static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::HdlcInterface);
104 #elif OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
105     static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::SpiInterface);
106 #elif OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE
107     static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::VendorInterface);
108 #else
109 #error "No Spinel interface is specified!"
110 #endif
111 
112     static constexpr otRadioCaps kRequiredRadioCaps =
113 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
114         OT_RADIO_CAPS_TRANSMIT_SEC | OT_RADIO_CAPS_TRANSMIT_TIMING |
115 #endif
116         OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_TRANSMIT_RETRIES | OT_RADIO_CAPS_CSMA_BACKOFF;
117 
118     RadioUrl mRadioUrl;
119 #if OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
120     Spinel::VendorRadioSpinel mRadioSpinel;
121 #else
122     Spinel::RadioSpinel     mRadioSpinel;
123 #endif
124 
125 #if OPENTHREAD_POSIX_CONFIG_RCP_CAPS_DIAG_ENABLE
126     RcpCapsDiag mRcpCapsDiag;
127 #endif
128 };
129 
130 } // namespace Posix
131 } // namespace ot
132 
133 #endif // OT_POSIX_PLATFORM_RADIO_HPP_
134