xref: /aosp_15_r20/hardware/interfaces/threadnetwork/aidl/default/socket_interface.hpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1  /*
2   * Copyright (C) 2024 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /**
18   * @file
19   *   This file includes definitions for the Socket interface interface to radio
20   * (RCP).
21   */
22  
23  #include "lib/spinel/spinel_interface.hpp"
24  #include "lib/url/url.hpp"
25  #include "logger.hpp"
26  
27  namespace aidl {
28  namespace android {
29  namespace hardware {
30  namespace threadnetwork {
31  
32  /**
33   * Defines a Socket interface to the Radio Co-processor (RCP)
34   *
35   */
36  class SocketInterface : public ot::Spinel::SpinelInterface,
37                          public ot::Posix::Logger<SocketInterface> {
38    public:
39      static const char kLogModuleName[];  ///< Module name used for logging.
40  
41      /**
42       * Initializes the object.
43       *
44       * @param[in] aRadioUrl  RadioUrl parsed from radio url.
45       *
46       */
47      explicit SocketInterface(const ot::Url::Url& aRadioUrl);
48  
49      /**
50       * This destructor deinitializes the object.
51       *
52       */
53      ~SocketInterface();
54  
55      /**
56       * Initializes the interface to the Radio Co-processor (RCP)
57       *
58       * @note This method should be called before reading and sending Spinel
59       * frames to the interface.
60       *
61       * @param[in] aCallback         Callback on frame received
62       * @param[in] aCallbackContext  Callback context
63       * @param[in] aFrameBuffer      A reference to a `RxFrameBuffer` object.
64       *
65       * @retval OT_ERROR_NONE       The interface is initialized successfully
66       * @retval OT_ERROR_ALREADY    The interface is already initialized.
67       * @retval OT_ERROR_FAILED     Failed to initialize the interface.
68       *
69       */
70      otError Init(ReceiveFrameCallback aCallback, void* aCallbackContext,
71                   RxFrameBuffer& aFrameBuffer);
72  
73      /**
74       * Deinitializes the interface to the RCP.
75       *
76       */
77      void Deinit(void);
78  
79      /**
80       * Sends a Spinel frame to Radio Co-processor (RCP) over the
81       * socket.
82       *
83       * @param[in] aFrame     A pointer to buffer containing the Spinel frame to
84       * send.
85       * @param[in] aLength    The length (number of bytes) in the frame.
86       *
87       * @retval OT_ERROR_NONE     Successfully sent the Spinel frame.
88       * @retval OT_ERROR_FAILED   Failed to send a frame.
89       *
90       */
91      otError SendFrame(const uint8_t* aFrame, uint16_t aLength);
92  
93      /**
94       * Waits for receiving part or all of Spinel frame within specified
95       * interval.
96       *
97       * @param[in]  aTimeout  The timeout value in microseconds.
98       *
99       * @retval OT_ERROR_NONE             Part or all of Spinel frame is
100       * received.
101       * @retval OT_ERROR_RESPONSE_TIMEOUT No Spinel frame is received within @p
102       * aTimeout.
103       * @retval OT_EXIT_FAILURE           RCP error
104       *
105       */
106      otError WaitForFrame(uint64_t aTimeoutUs);
107  
108      /**
109       * Updates the file descriptor sets with file descriptors used by the radio
110       * driver.
111       *
112       * @param[in,out]   aMainloopContext  A pointer to the mainloop context
113       * containing fd_sets.
114       *
115       */
116      void UpdateFdSet(void* aMainloopContext);
117  
118      /**
119       * Performs radio driver processing.
120       *
121       * @param[in]   aMainloopContext  A pointer to the mainloop context
122       * containing fd_sets.
123       *
124       */
125      void Process(const void* aMainloopContext);
126  
127      /**
128       * Returns the bus speed between the host and the radio.
129       *
130       * @return   Bus speed in bits/second.
131       *
132       */
GetBusSpeed(void) const133      uint32_t GetBusSpeed(void) const { return 1000000; }
134  
135      /**
136       * Hardware resets the RCP.
137       *
138       * @retval OT_ERROR_NONE            Successfully reset the RCP.
139       * @retval OT_ERROR_FAILED          Hardware reset is failed.
140       *
141       */
142      otError HardwareReset(void);
143  
144      /**
145       * Returns the RCP interface metrics.
146       *
147       * @return The RCP interface metrics.
148       *
149       */
GetRcpInterfaceMetrics(void) const150      const otRcpInterfaceMetrics* GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; }
151  
152      /**
153       * Indicates whether or not the given interface matches this interface name.
154       *
155       * @param[in] aInterfaceName A pointer to the interface name.
156       *
157       * @retval TRUE   The given interface name matches this interface name.
158       * @retval FALSE  The given interface name doesn't match this interface
159       * name.
160       */
IsInterfaceNameMatch(const char * aInterfaceName)161      static bool IsInterfaceNameMatch(const char* aInterfaceName) {
162          static const char kInterfaceName[] = "spinel+socket";
163          return (strncmp(aInterfaceName, kInterfaceName, strlen(kInterfaceName)) == 0);
164      }
165  
166    private:
167      /**
168       * Instructs `SocketInterface` to read data from radio over the
169       * socket.
170       *
171       * If a full Spinel frame is received, this method invokes the
172       * `HandleSocketFrame()` (on the `aCallback` object from constructor) to
173       * pass the received frame to be processed.
174       *
175       */
176      void Read(void);
177  
178      /**
179       * Writes a given frame to the socket.
180       *
181       * @param[in] aFrame  A pointer to buffer containing the frame to write.
182       * @param[in] aLength The length (number of bytes) in the frame.
183       *
184       */
185      void Write(const uint8_t* aFrame, uint16_t aLength);
186  
187      /**
188       * Process received data.
189       *
190       * If a full frame is finished processing and we obtain the raw Spinel
191       * frame, this method invokes the `HandleSocketFrame()` (on the `aCallback`
192       * object from constructor) to pass the received frame to be processed.
193       *
194       * @param[in] aBuffer  A pointer to buffer containing data.
195       * @param[in] aLength  The length (number of bytes) in the buffer.
196       *
197       */
198      void ProcessReceivedData(const uint8_t* aBuffer, uint16_t aLength);
199  
200      static void HandleSocketFrame(void* aContext, otError aError);
201      void HandleSocketFrame(otError aError);
202  
203      /**
204       * Opens file specified by aRadioUrl.
205       *
206       * @param[in] aRadioUrl  A reference to object containing path to file and
207       * data for configuring the connection with tty type file.
208       *
209       * @retval The file descriptor of newly opened file.
210       * @retval -1 Fail to open file.
211       *
212       */
213      int OpenFile(const ot::Url::Url& aRadioUrl);
214  
215      /**
216       * Closes file associated with the file descriptor.
217       *
218       */
219      void CloseFile(void);
220  
221      /**
222       * Check if socket file is created.
223       *
224       * @param[in] aPath  Socket file path name.
225       *
226       * @retval TRUE The required socket file is created.
227       * @retval FALSE The required socket file is not created.
228       *
229       */
230      bool IsSocketFileExisted(const char* aPath);
231  
232      /**
233       * Wait until the socket file is created.
234       *
235       * @param[in] aPath  Socket file path name.
236       *
237       */
238      void WaitForSocketFileCreated(const char* aPath);
239  
240      /**
241       * Wait for the hardware reset completion signal.
242       *
243       * @retval OT_ERROR_NONE       Hardware reset is successfully.
244       * @retval OT_ERROR_FAILED     Hardware reset is failed.
245       *
246       */
247      otError WaitForHardwareResetCompletion(uint32_t aTimeoutMs);
248  
249      /**
250       * Initialize socket
251       *
252       * @retval TRUE  Socket initialization is successful.
253       * @retval FALSE Socket initialization is failed.
254       *
255       */
256      otError InitSocket();
257  
258      /**
259       * Reset socket interface to intitial state.
260       *
261       */
262      void ResetStates(void);
263  
264      enum {
265          kMaxSelectTimeMs = 2000,             ///< Maximum wait time in Milliseconds for file
266                                               ///< descriptor to become available.
267          kMaxRetriesForSocketCloseCheck = 3,  ///< Maximum retry times for checking
268                                               ///< if socket is closed.
269          kMaxRetriesForSocketInit = 3,        ///< Maximum retry times for socket initialization.
270      };
271  
272      ReceiveFrameCallback mReceiveFrameCallback;
273      void* mReceiveFrameContext;
274      RxFrameBuffer* mReceiveFrameBuffer;
275  
276      int mSockFd;
277      const ot::Url::Url& mRadioUrl;
278  
279      bool mIsHardwareResetting;
280  
281      otRcpInterfaceMetrics mInterfaceMetrics;
282  
283      // Non-copyable, intentionally not implemented.
284      SocketInterface(const SocketInterface&);
285      SocketInterface& operator=(const SocketInterface&);
286  };
287  
288  }  // namespace threadnetwork
289  }  // namespace hardware
290  }  // namespace android
291  }  // namespace aidl
292