xref: /aosp_15_r20/external/openthread/src/android/thread_network_hal/hal_interface.hpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2022, 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 includes definitions for the IPC binder interface to radio (RCP).
32  */
33 
34 #ifndef ANDROID_THREAD_NETWORK_HAL_INTERFACE_HPP_
35 #define ANDROID_THREAD_NETWORK_HAL_INTERFACE_HPP_
36 
37 #include "openthread-posix-config.h"
38 
39 #include "platform-posix.h"
40 #include "lib/spinel/spinel_interface.hpp"
41 
42 #include <openthread/openthread-system.h>
43 
44 #if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_VENDOR
45 
46 #include <aidl/android/hardware/threadnetwork/BnThreadChipCallback.h>
47 #include <aidl/android/hardware/threadnetwork/IThreadChip.h>
48 #include <aidl/android/hardware/threadnetwork/IThreadChipCallback.h>
49 
50 namespace ot {
51 namespace Posix {
52 
53 /**
54  * This class defines an IPC Binder interface to the Radio Co-processor (RCP).
55  *
56  */
57 class HalInterface : public ot::Spinel::SpinelInterface
58 {
59 public:
60     /**
61      * This constructor initializes the object.
62      *
63      * @param[in]  aRadioUrl   Arguments parsed from radio url.
64      *
65      */
66     HalInterface(const Url::Url &aRadioUrl);
67 
68     /**
69      * This destructor deinitializes the object.
70      *
71      */
72     ~HalInterface(void);
73 
74     /**
75      * This method initializes the interface to the Radio Co-processor (RCP).
76      *
77      * @note This method should be called before reading and sending spinel frames to the interface.
78      *
79      * @param[in] aCallback         A reference to a `Callback` object.
80      * @param[in] aCallbackContext  The context pointer passed to the callback.
81      * @param[in] aFrameBuffer      A reference to a `RxFrameBuffer` object.
82      *
83      * @retval OT_ERROR_NONE          The interface is initialized successfully.
84      * @retval OT_ERROR_ALREADY       The interface is already initialized.
85      * @retval OT_ERROR_INVALID_ARGS  The UART device or executable cannot be found or failed to open/run.
86      *
87      */
88     otError Init(Spinel::SpinelInterface::ReceiveFrameCallback aCallback,
89                  void                                         *aCallbackContext,
90                  Spinel::SpinelInterface::RxFrameBuffer       &aFrameBuffer) override;
91 
92     /**
93      * This method deinitializes the interface to the RCP.
94      *
95      */
96     void Deinit(void) override;
97 
98     /**
99      * This method encodes and sends a spinel frame to Radio Co-processor (RCP) over the socket.
100      *
101      * @param[in] aFrame     A pointer to buffer containing the spinel frame to send.
102      * @param[in] aLength    The length (number of bytes) in the frame.
103      *
104      * @retval OT_ERROR_NONE     Successfully encoded and sent the spinel frame.
105      * @retval OT_ERROR_BUSY     Failed due to another operation is on going.
106      * @retval OT_ERROR_NO_BUFS  Insufficient buffer space available to encode the frame.
107      * @retval OT_ERROR_FAILED   Failed to call the HAL to send the frame.
108      *
109      */
110     otError SendFrame(const uint8_t *aFrame, uint16_t aLength) override;
111 
112     /**
113      * This method waits for receiving part or all of spinel frame within specified interval.
114      *
115      * @param[in]  aTimeout  The timeout value in microseconds.
116      *
117      * @retval OT_ERROR_NONE             Part or all of spinel frame is received.
118      * @retval OT_ERROR_RESPONSE_TIMEOUT No spinel frame is received within @p aTimeout.
119      *
120      */
121     otError WaitForFrame(uint64_t aTimeoutUs) override;
122 
123     /**
124      * This method updates the file descriptor sets with file descriptors used by the radio driver.
125      *
126      * @param[in]   aMainloopContext  The context containing fd_sets.
127      *
128      */
129     void UpdateFdSet(void *aMainloopContext) override;
130 
131     /**
132      * This method performs radio driver processing.
133      *
134      * @param[in]   aMainloopContext  The context containing fd_sets.
135      *
136      */
137     void Process(const void *aMainloopContext) override;
138 
139     /**
140      * This method returns the bus speed between the host and the radio.
141      *
142      * @returns   Bus speed in bits/second.
143      *
144      */
145     uint32_t GetBusSpeed(void) const override;
146 
147     /**
148      * This method hardware resets the RCP. It will be called after a software reset fails.
149      *
150      * @retval OT_ERROR_NONE            Successfully reset the RCP.
151      * @retval OT_ERROR_NOT_IMPLEMENT   The hardware reset is not implemented.
152      *
153      */
154     otError HardwareReset(void) override;
155 
156     /**
157      * Returns the RCP interface metrics.
158      *
159      * @returns The RCP interface metrics.
160      *
161      */
GetRcpInterfaceMetrics(void) const162     const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const override { return &mInterfaceMetrics; }
163 
164 private:
165     void        ReceiveFrameCallback(const std::vector<uint8_t> &aFrame);
166     static void BinderDeathCallback(void *aContext);
167     otError     StatusToError(const ::ndk::ScopedAStatus &aStatus) const;
168 
169     class ThreadChipCallback : public ::aidl::android::hardware::threadnetwork::BnThreadChipCallback
170     {
171     public:
ThreadChipCallback(HalInterface * aInterface)172         ThreadChipCallback(HalInterface *aInterface)
173             : mInterface(aInterface)
174         {
175         }
176 
onReceiveSpinelFrame(const std::vector<uint8_t> & in_aFrame)177         ::ndk::ScopedAStatus onReceiveSpinelFrame(const std::vector<uint8_t> &in_aFrame)
178         {
179             mInterface->ReceiveFrameCallback(in_aFrame);
180             return ndk::ScopedAStatus::ok();
181         }
182 
183     private:
184         HalInterface *mInterface;
185     };
186 
187     enum
188     {
189         kMaxFrameSize = Spinel::SpinelInterface::kMaxFrameSize,
190     };
191 
192     Spinel::SpinelInterface::ReceiveFrameCallback mRxFrameCallback;
193     void                                         *mRxFrameContext;
194     Spinel::SpinelInterface::RxFrameBuffer       *mRxFrameBuffer;
195 
196     otRcpInterfaceMetrics mInterfaceMetrics;
197 
198     std::shared_ptr<::aidl::android::hardware::threadnetwork::IThreadChip>         mThreadChip;
199     std::shared_ptr<::aidl::android::hardware::threadnetwork::IThreadChipCallback> mThreadChipCallback;
200 
201     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
202     int                                  mBinderFd;
203     uint8_t                              mHalInterfaceId;
204 
205     // Non-copyable, intentionally not implemented.
206     HalInterface(const HalInterface &);
207     HalInterface &operator=(const HalInterface &);
208 };
209 
210 } // namespace Posix
211 } // namespace ot
212 
213 #endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_VENDOR
214 #endif // ANDROID_THREAD_NETWORK_HAL_INTERFACE_HPP_
215