3 * Copyright (c) 2020 Project CHIP Authors
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 #include <core/CHIPError.h>
21 #include <inet/IPAddress.h>
22 #include <inet/InetInterface.h>
23 #include <inet/InetLayer.h>
24 #include <inet/UDPEndPoint.h>
26 #include <mdns/minimal/core/BytesRange.h>
31 namespace BroadcastIpAddresses {
33 // Get standard mDNS Broadcast addresses
35 void GetIpv6Into(chip::Inet::IPAddress & dest);
36 void GetIpv4Into(chip::Inet::IPAddress & dest);
38 } // namespace BroadcastIpAddresses
40 /// Provides a list of intefaces to listen on.
42 /// When listening on IP, both IP address type (IPv4 or IPv6) and interface id
43 /// are important. In particular, when using link-local IP addresses, the actual
44 /// interface matters (e.g. FF02::FB will care over which IPv6 interface it is sent)
46 /// For MDNS in particular, you may want:
47 /// - IPv4 listen on INET_NULL_INTERFACEID
48 /// - IPv6 listen on every specific interface id available (except local loopback and other
49 /// not usable interfaces like docker)
53 virtual ~ListenIterator() {}
55 // Get the next interface/address type to listen on
56 virtual bool Next(chip::Inet::InterfaceId * id, chip::Inet::IPAddressType * type) = 0;
59 /// Handles mDNS Server Callbacks
63 virtual ~ServerDelegate() {}
65 // Callback of when a query is received
66 virtual void OnQuery(const BytesRange & data, const chip::Inet::IPPacketInfo * info) = 0;
68 // Callback of when a response is received
69 virtual void OnResponse(const BytesRange & data, const chip::Inet::IPPacketInfo * info) = 0;
72 // Defines an mDNS server that listens on one or more interfaces.
74 // I can send and receive mDNS packets (requests/replies)
80 chip::Inet::InterfaceId interfaceId = INET_NULL_INTERFACEID;
81 chip::Inet::IPAddressType addressType;
82 chip::Inet::UDPEndPoint * udp = nullptr;
85 ServerBase(EndpointInfo * endpointStorage, size_t kStorageSize) : mEndpoints(endpointStorage), mEndpointCount(kStorageSize)
87 for (size_t i = 0; i < mEndpointCount; i++)
89 mEndpoints[i].udp = nullptr;
92 BroadcastIpAddresses::GetIpv6Into(mIpv6BroadcastAddress);
94 #if INET_CONFIG_ENABLE_IPV4
95 BroadcastIpAddresses::GetIpv4Into(mIpv4BroadcastAddress);
100 /// Closes all currently open endpoints
103 /// Listen on the given interfaces/address types.
105 /// Since mDNS uses link-local addresses, one generally wants to listen on all
106 /// non-loopback interfaces.
107 CHIP_ERROR Listen(chip::Inet::InetLayer * inetLayer, ListenIterator * it, uint16_t port);
109 /// Send the specified packet to a destination IP address over the specified address
110 CHIP_ERROR DirectSend(chip::System::PacketBufferHandle && data, const chip::Inet::IPAddress & addr, uint16_t port,
111 chip::Inet::InterfaceId interface);
113 /// Send a specific packet broadcast to all interfaces
114 CHIP_ERROR BroadcastSend(chip::System::PacketBufferHandle data, uint16_t port);
116 /// Send a specific packet broadcast to a specific interface
117 CHIP_ERROR BroadcastSend(chip::System::PacketBufferHandle data, uint16_t port, chip::Inet::InterfaceId interface);
119 ServerBase & SetDelegate(ServerDelegate * d)
125 /// How many endpoints are availabe to be used by the server.
126 size_t GetEndpointCount() const { return mEndpointCount; }
128 /// Get the endpoints that are used by this server
130 /// Entries with non-null UDP are considered usable.
131 const EndpointInfo * GetEndpoints() const { return mEndpoints; }
134 static void OnUdpPacketReceived(chip::Inet::IPEndPointBasis * endPoint, chip::System::PacketBufferHandle buffer,
135 const chip::Inet::IPPacketInfo * info);
137 EndpointInfo * mEndpoints; // possible endpoints, to listen on multiple interfaces
138 const size_t mEndpointCount; // how many endpoints are allocated
139 ServerDelegate * mDelegate = nullptr;
141 // Broadcast IP addresses are cached to not require a string parse every time
142 // Ideally we should be able to constexpr these
143 chip::Inet::IPAddress mIpv6BroadcastAddress;
144 #if INET_CONFIG_ENABLE_IPV4
145 chip::Inet::IPAddress mIpv4BroadcastAddress;
149 template <size_t kCount>
150 class Server : public ServerBase
153 Server() : ServerBase(mAllocatedStorage, kCount) {}
157 EndpointInfo mAllocatedStorage[kCount];
160 } // namespace Minimal