1 /*
2  *  Copyright (c) 2024, 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 PLATFORM_SIMULATION_SOCKET_UTILS_H_
30 #define PLATFORM_SIMULATION_SOCKET_UTILS_H_
31 
32 #include "platform-simulation.h"
33 
34 /**
35  * Represents a socket for communication with other simulation node.
36  *
37  * This is used for emulation of 15.4 radio or other interfaces.
38  *
39  */
40 typedef struct utilsSocket
41 {
42     bool     mInitialized; ///< Whether or not initialized.
43     bool     mUseIp6;      ///< Whether IPv6 or IPv4.
44     int      mTxFd;        ///< RX file descriptor.
45     int      mRxFd;        ///< TX file descriptor.
46     uint16_t mPortBase;    ///< Base port number value.
47     uint16_t mPort;        ///< The port number used by this node
48     union
49     {
50         struct sockaddr_in  mSockAddr4; ///< The IPv4 group sock address.
51         struct sockaddr_in6 mSockAddr6; ///< The IPv4 group sock address.
52     } mGroupAddr;                       ///< The group sock address for simulating radio.
53 } utilsSocket;
54 
55 extern const char *gLocalInterface; ///< Local interface name or address to use for sockets
56 
57 /**
58  * Adds a file descriptor (FD) to a given FD set.
59  *
60  * @param[in] aFd      The FD to add.
61  * @param[in] aFdSet   The FD set to add to.
62  * @param[in] aMaxFd   A pointer to track maximum FD in @p aFdSet (can be NULL).
63  *
64  */
65 void utilsAddFdToFdSet(int aFd, fd_set *aFdSet, int *aMaxFd);
66 
67 /**
68  * Initializes the socket.
69  *
70  * @param[in] aSocket     The socket to initialize.
71  * @param[in] aPortBase   The base port number value. Nodes will determine their port as `aPortBased + gNodeId`.
72  *
73  */
74 void utilsInitSocket(utilsSocket *aSocket, uint16_t aPortBase);
75 
76 /**
77  * De-initializes the socket.
78  *
79  * @param[in] aSocket   The socket to de-initialize.
80  *
81  */
82 void utilsDeinitSocket(utilsSocket *aSocket);
83 
84 /**
85  * Adds sockets RX FD to a given FD set.
86  *
87  * @param[in] aSocket   The socket.
88  * @param[in] aFdSet    The (read) FD set to add to.
89  * @param[in] aMaxFd    A pointer to track maximum FD in @p aFdSet (can be NULL).
90  *
91  */
92 void utilsAddSocketRxFd(const utilsSocket *aSocket, fd_set *aFdSet, int *aMaxFd);
93 
94 /**
95  * Adds sockets TX FD to a given FD set.
96  *
97  * @param[in] aSocket   The socket.
98  * @param[in] aFdSet    The (write) FD set to add to.
99  * @param[in] aMaxFd    A pointer to track maximum FD in @p aFdSet (can be NULL).
100  *
101  */
102 void utilsAddSocketTxFd(const utilsSocket *aSocket, fd_set *aFdSet, int *aMaxFd);
103 
104 /**
105  * Indicates whether the socket can receive.
106  *
107  * @param[in] aSocket       The socket.
108  * @param[in] aReadFdSet    The read FD set.
109  *
110  * @retval TRUE   The socket RX FD is in @p aReadFdSet, and socket can receive.
111  * @retval FALSE  The socket RX FD is not in @p aReadFdSet. Socket is not ready to receive.
112  *
113  */
114 bool utilsCanSocketReceive(const utilsSocket *aSocket, const fd_set *aReadFdSet);
115 
116 /**
117  * Indicates whether the socket can send.
118  *
119  * @param[in] aSocket   The socket.
120  * @param[in] aFdSet    The write FD set.
121  *
122  * @retval TRUE   The socket TX FD is in @p aWriteFdSet, and socket can send.
123  * @retval FALSE  The socket TX FD is not in @p aWriteFdSet. Socket is not ready to send.
124  *
125  */
126 bool utilsCanSocketSend(const utilsSocket *aSocket, const fd_set *aWriteFdSet);
127 
128 /**
129  * Receives data from socket.
130  *
131  * MUST be used when `utilsCanSocketReceive()` returns `TRUE.
132  *
133  * @param[in] aSocket          The socket.
134  * @param[out] aBuffer         The buffer to output the read content.
135  * @param[in]  aBufferSize     Maximum size of buffer in bytes.
136  * @param[out] aSenderNodeId   A pointer to return the Node ID of the sender (derived from the port number).
137  *                             Can be NULL if not needed.
138  *
139  * @returns The number of received bytes written into @p aBuffer.
140  *
141  */
142 uint16_t utilsReceiveFromSocket(const utilsSocket *aSocket,
143                                 void              *aBuffer,
144                                 uint16_t           aBufferSize,
145                                 uint16_t          *aSenderNodeId);
146 
147 /**
148  * Sends data over the socket.
149  *
150  * @param[in] aSocket         The socket.
151  * @param[in] aBuffer         The buffer containing the bytes to sent.
152  * @param[in]  aBufferSize    Size of data in @p buffer in bytes.
153  *
154  */
155 void utilsSendOverSocket(const utilsSocket *aSocket, const void *aBuffer, uint16_t aBufferLength);
156 
157 #endif // PLATFORM_SIMULATION_SOCKET_UTILS_H_
158