Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2020 Project CHIP Authors 4 : * All rights reserved. 5 : * 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 9 : * 10 : * http://www.apache.org/licenses/LICENSE-2.0 11 : * 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. 17 : */ 18 : 19 : /** 20 : * @file 21 : * This file defines the CHIP Connection object that maintains a UDP connection. 22 : * It binds to any available local addr and port and begins listening. 23 : * 24 : */ 25 : 26 : #pragma once 27 : 28 : #include <utility> 29 : 30 : #include <inet/IPAddress.h> 31 : #include <inet/IPPacketInfo.h> 32 : #include <inet/InetInterface.h> 33 : #include <inet/UDPEndPoint.h> 34 : #include <lib/core/CHIPCore.h> 35 : #include <transport/raw/Base.h> 36 : 37 : #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT 38 : struct otInstance; 39 : #endif // CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT 40 : 41 : namespace chip { 42 : namespace Transport { 43 : 44 : /** Defines listening parameters for setting up a UDP transport */ 45 : class UdpListenParameters 46 : { 47 : public: 48 2 : explicit UdpListenParameters(Inet::EndPointManager<Inet::UDPEndPoint> * endPointManager) : mEndPointManager(endPointManager) {} 49 : UdpListenParameters(const UdpListenParameters &) = default; 50 : UdpListenParameters(UdpListenParameters &&) = default; 51 : 52 7 : Inet::EndPointManager<Inet::UDPEndPoint> * GetEndPointManager() { return mEndPointManager; } 53 : 54 14 : Inet::IPAddressType GetAddressType() const { return mAddressType; } 55 2 : UdpListenParameters & SetAddressType(Inet::IPAddressType type) 56 : { 57 2 : mAddressType = type; 58 : 59 2 : return *this; 60 : } 61 : 62 14 : uint16_t GetListenPort() const { return mListenPort; } 63 2 : UdpListenParameters & SetListenPort(uint16_t port) 64 : { 65 2 : mListenPort = port; 66 : 67 2 : return *this; 68 : } 69 : 70 7 : Inet::InterfaceId GetInterfaceId() const { return mInterfaceId; } 71 : UdpListenParameters & SetInterfaceId(Inet::InterfaceId id) 72 : { 73 : mInterfaceId = id; 74 : 75 : return *this; 76 : } 77 : 78 : /** 79 : * Networking Stack Native parameter (optional) 80 : */ 81 7 : void * GetNativeParams() const { return mNativeParams; } 82 1 : UdpListenParameters & SetNativeParams(void * params) 83 : { 84 1 : mNativeParams = params; 85 : 86 1 : return *this; 87 : } 88 : 89 : private: 90 : Inet::EndPointManager<Inet::UDPEndPoint> * mEndPointManager; ///< Associated endpoint factory 91 : Inet::IPAddressType mAddressType = Inet::IPAddressType::kIPv6; ///< type of listening socket 92 : uint16_t mListenPort = CHIP_PORT; ///< UDP listen port 93 : Inet::InterfaceId mInterfaceId = Inet::InterfaceId::Null(); ///< Interface to listen on 94 : void * mNativeParams = nullptr; 95 : }; 96 : 97 : /** Implements a transport using UDP. */ 98 : class DLL_EXPORT UDP : public Base 99 : { 100 : /** 101 : * The State of the UDP connection 102 : * 103 : */ 104 : enum class State 105 : { 106 : kNotReady = 0, /**< State before initialization. */ 107 : kInitialized = 1, /**< State after class is listening and ready. */ 108 : }; 109 : 110 : public: 111 : ~UDP() override; 112 : 113 : /** 114 : * Initialize a UDP transport on a given port. 115 : * 116 : * @param params UDP configuration parameters for this transport 117 : * 118 : * @details 119 : * Generally send and receive ports should be the same and equal to CHIP_PORT. 120 : * The class allows separate definitions to allow local execution of several 121 : * Nodes. 122 : */ 123 : CHIP_ERROR Init(UdpListenParameters & params); 124 : 125 : uint16_t GetBoundPort(); 126 : 127 : /** 128 : * Close the open endpoint without destroying the object 129 : */ 130 : void Close() override; 131 : 132 : CHIP_ERROR SendMessage(const Transport::PeerAddress & address, System::PacketBufferHandle && msgBuf) override; 133 : 134 : CHIP_ERROR MulticastGroupJoinLeave(const Transport::PeerAddress & address, bool join) override; 135 : 136 0 : bool CanListenMulticast() override 137 : { 138 0 : return (mState == State::kInitialized) && (mUDPEndpointType == Inet::IPAddressType::kIPv6); 139 : } 140 : 141 2 : bool CanSendToPeer(const Transport::PeerAddress & address) override 142 : { 143 4 : return (mState == State::kInitialized) && (address.GetTransportType() == Type::kUdp) && 144 4 : (address.GetIPAddress().Type() == mUDPEndpointType); 145 : } 146 : 147 : private: 148 : // UDP message receive handler. 149 : static void OnUdpReceive(Inet::UDPEndPoint * endPoint, System::PacketBufferHandle && buffer, 150 : const Inet::IPPacketInfo * pktInfo); 151 : 152 : static void OnUdpError(Inet::UDPEndPoint * endPoint, CHIP_ERROR err, const Inet::IPPacketInfo * pktInfo); 153 : 154 : Inet::UDPEndPoint * mUDPEndPoint = nullptr; ///< UDP socket used by the transport 155 : Inet::IPAddressType mUDPEndpointType = Inet::IPAddressType::kUnknown; ///< Socket listening type 156 : State mState = State::kNotReady; ///< State of the UDP transport 157 : }; 158 : 159 : } // namespace Transport 160 : } // namespace chip