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  */
55 class Radio : public Logger<Radio>
56 {
57 public:
58     static const char kLogModuleName[]; ///< Module name used for logging.
59 
60     /**
61      * Creates the radio manager.
62      *
63      */
64     Radio(void);
65 
66     /**
67      * Initialize the Thread radio.
68      *
69      * @param[in]   aUrl    A pointer to the null-terminated URL.
70      *
71      */
72     void Init(const char *aUrl);
73 
74     /**
75      * Acts as an accessor to the spinel interface instance used by the radio.
76      *
77      * @returns A reference to the radio's spinel interface instance.
78      *
79      */
GetSpinelInterface(void)80     Spinel::SpinelInterface &GetSpinelInterface(void) { return SpinelManager::GetSpinelManager().GetSpinelInterface(); }
81 
82     /**
83      * Acts as an accessor to the radio spinel instance used by the radio.
84      *
85      * @returns A reference to the radio spinel instance.
86      *
87      */
GetRadioSpinel(void)88     Spinel::RadioSpinel &GetRadioSpinel(void) { return mRadioSpinel; }
89 
90     /**
91      * Acts as an accessor to the RCP capability diagnostic instance used by the radio.
92      *
93      * @returns A reference to the RCP capability diagnostic instance.
94      *
95      */
96 #if OPENTHREAD_POSIX_CONFIG_RCP_CAPS_DIAG_ENABLE
GetRcpCapsDiag(void)97     RcpCapsDiag &GetRcpCapsDiag(void) { return mRcpCapsDiag; }
98 #endif
99 
100 private:
101     void ProcessRadioUrl(const RadioUrl &aRadioUrl);
102     void ProcessMaxPowerTable(const RadioUrl &aRadioUrl);
103 
104 #if OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE && OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
105     static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::SpiInterface) > sizeof(ot::Posix::HdlcInterface)
106                                                           ? sizeof(ot::Posix::SpiInterface)
107                                                           : sizeof(ot::Posix::HdlcInterface);
108 #elif OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE
109     static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::HdlcInterface);
110 #elif OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
111     static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::SpiInterface);
112 #elif OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE
113     static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::VendorInterface);
114 #else
115 #error "No Spinel interface is specified!"
116 #endif
117 
118     static constexpr otRadioCaps kRequiredRadioCaps =
119 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
120         OT_RADIO_CAPS_TRANSMIT_SEC | OT_RADIO_CAPS_TRANSMIT_TIMING |
121 #endif
122         OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_TRANSMIT_RETRIES | OT_RADIO_CAPS_CSMA_BACKOFF;
123 
124     RadioUrl mRadioUrl;
125 #if OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
126     Spinel::VendorRadioSpinel mRadioSpinel;
127 #else
128     Spinel::RadioSpinel     mRadioSpinel;
129 #endif
130 
131 #if OPENTHREAD_POSIX_CONFIG_RCP_CAPS_DIAG_ENABLE
132     RcpCapsDiag mRcpCapsDiag;
133 #endif
134 };
135 
136 } // namespace Posix
137 } // namespace ot
138 
139 #endif // OT_POSIX_PLATFORM_RADIO_HPP_
140