3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2018 Google LLC.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * This header file defines the <tt>Inet::IPEndPointBasis</tt>
22 * class, an intermediate, non-instantiable basis class
23 * supporting other IP-based end points.
29 #include <inet/EndPointBasis.h>
31 #include <system/SystemPacketBuffer.h>
33 #if CHIP_SYSTEM_CONFIG_USE_LWIP
34 #include <lwip/init.h>
35 #include <lwip/netif.h>
36 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
45 * @class IPEndPointBasis
47 * @brief Objects of this class represent non-instantiable IP protocol
51 class DLL_EXPORT IPEndPointBasis : public EndPointBasis
53 friend class InetLayer;
57 * @brief Basic dynamic state of the underlying endpoint.
60 * Objects are initialized in the "ready" state, proceed to the "bound"
61 * state after binding to a local interface address, then proceed to the
62 * "listening" state when they have continuations registered for handling
63 * events for reception of ICMP messages.
66 * The \c kBasisState_Closed state enumeration is mapped to \c
67 * kState_Ready for historical binary-compatibility reasons. The
68 * existing \c kState_Closed exists to identify separately the
69 * distinction between "not opened yet" and "previously opened
70 * now closed" that existed previously in the \c kState_Ready and
71 * \c kState_Closed states.
75 kState_Ready = kBasisState_Closed, /**< Endpoint initialized, but not open. */
76 kState_Bound = 1, /**< Endpoint bound, but not listening. */
77 kState_Listening = 2, /**< Endpoint receiving datagrams. */
78 kState_Closed = 3 /**< Endpoint closed, ready for release. */
82 * @brief Type of message text reception event handling function.
84 * @param[in] endPoint The endpoint associated with the event.
85 * @param[in] msg The message text received.
86 * @param[in] pktInfo The packet's IP information.
89 * Provide a function of this type to the \c OnMessageReceived delegate
90 * member to process message text reception events on \c endPoint where
91 * \c msg is the message text received from the sender at \c senderAddr.
93 typedef void (*OnMessageReceivedFunct)(IPEndPointBasis * endPoint, chip::System::PacketBufferHandle msg,
94 const IPPacketInfo * pktInfo);
96 /** The endpoint's message reception event handling function delegate. */
97 OnMessageReceivedFunct OnMessageReceived;
100 * @brief Type of reception error event handling function.
102 * @param[in] endPoint The endpoint associated with the event.
103 * @param[in] err The reason for the error.
106 * Provide a function of this type to the \c OnReceiveError delegate
107 * member to process reception error events on \c endPoint. The \c err
108 * argument provides specific detail about the type of the error.
110 typedef void (*OnReceiveErrorFunct)(IPEndPointBasis * endPoint, INET_ERROR err, const IPPacketInfo * pktInfo);
112 /** The endpoint's receive error event handling function delegate. */
113 OnReceiveErrorFunct OnReceiveError;
115 INET_ERROR SetMulticastLoopback(IPVersion aIPVersion, bool aLoopback);
116 INET_ERROR JoinMulticastGroup(InterfaceId aInterfaceId, const IPAddress & aAddress);
117 INET_ERROR LeaveMulticastGroup(InterfaceId aInterfaceId, const IPAddress & aAddress);
120 void Init(InetLayer * aInetLayer);
122 #if CHIP_SYSTEM_CONFIG_USE_LWIP
124 static struct netif * FindNetifFromInterfaceId(InterfaceId aInterfaceId);
125 static System::Error PostPacketBufferEvent(chip::System::Layer & aLayer, System::Object & aTarget, System::EventType aEventType,
126 System::PacketBufferHandle aBuffer);
129 void HandleDataReceived(chip::System::PacketBufferHandle aBuffer);
131 static IPPacketInfo * GetPacketInfo(const chip::System::PacketBufferHandle & aBuffer);
132 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP
134 #if CHIP_SYSTEM_CONFIG_USE_SOCKETS
135 InterfaceId mBoundIntfId;
137 INET_ERROR Bind(IPAddressType aAddressType, const IPAddress & aAddress, uint16_t aPort, InterfaceId aInterfaceId);
138 INET_ERROR BindInterface(IPAddressType aAddressType, InterfaceId aInterfaceId);
139 INET_ERROR SendMsg(const IPPacketInfo * aPktInfo, chip::System::PacketBufferHandle aBuffer, uint16_t aSendFlags);
140 INET_ERROR GetSocket(IPAddressType aAddressType, int aType, int aProtocol);
141 SocketEvents PrepareIO();
142 void HandlePendingIO(uint16_t aPort);
143 #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
145 #if CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
147 nw_listener_t mListener;
148 dispatch_semaphore_t mListenerSemaphore;
149 dispatch_queue_t mListenerQueue;
150 nw_connection_t mConnection;
151 dispatch_semaphore_t mConnectionSemaphore;
152 dispatch_queue_t mDispatchQueue;
153 dispatch_semaphore_t mSendSemaphore;
155 INET_ERROR Bind(IPAddressType aAddressType, const IPAddress & aAddress, uint16_t aPort, const nw_parameters_t & aParameters);
156 INET_ERROR ConfigureProtocol(IPAddressType aAddressType, const nw_parameters_t & aParameters);
157 INET_ERROR SendMsg(const IPPacketInfo * aPktInfo, chip::System::PacketBufferHandle aBuffer, uint16_t aSendFlags);
158 INET_ERROR StartListener();
159 INET_ERROR GetConnection(const IPPacketInfo * aPktInfo);
160 INET_ERROR GetEndPoint(nw_endpoint_t & aEndpoint, const IPAddressType aAddressType, const IPAddress & aAddress, uint16_t aPort);
161 INET_ERROR StartConnection(nw_connection_t & aConnection);
162 void GetPacketInfo(const nw_connection_t & aConnection, IPPacketInfo & aPacketInfo);
163 void HandleDataReceived(const nw_connection_t & aConnection);
164 INET_ERROR ReleaseListener();
165 INET_ERROR ReleaseConnection();
167 #endif // CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK
170 IPEndPointBasis() = delete;
171 IPEndPointBasis(const IPEndPointBasis &) = delete;
172 ~IPEndPointBasis() = delete;
175 #if CHIP_SYSTEM_CONFIG_USE_LWIP
177 inline struct netif * IPEndPointBasis::FindNetifFromInterfaceId(InterfaceId aInterfaceId)
179 struct netif * lRetval = NULL;
181 #if LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 0 && defined(NETIF_FOREACH)
182 NETIF_FOREACH(lRetval)
184 if (lRetval == aInterfaceId)
187 #else // LWIP_VERSION_MAJOR < 2 || !defined(NETIF_FOREACH)
188 for (lRetval = netif_list; lRetval != NULL && lRetval != aInterfaceId; lRetval = lRetval->next)
190 #endif // LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 0 && defined(NETIF_FOREACH)
195 #endif // CHIP_SYSTEM_CONFIG_USE_LWIP