xref: /aosp_15_r20/external/openscreen/platform/api/udp_socket.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2018 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #ifndef PLATFORM_API_UDP_SOCKET_H_
6*3f982cf4SFabien Sanglard #define PLATFORM_API_UDP_SOCKET_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <stddef.h>  // size_t
9*3f982cf4SFabien Sanglard #include <stdint.h>  // uint8_t
10*3f982cf4SFabien Sanglard 
11*3f982cf4SFabien Sanglard #include <memory>
12*3f982cf4SFabien Sanglard 
13*3f982cf4SFabien Sanglard #include "platform/api/network_interface.h"
14*3f982cf4SFabien Sanglard #include "platform/base/error.h"
15*3f982cf4SFabien Sanglard #include "platform/base/ip_address.h"
16*3f982cf4SFabien Sanglard #include "platform/base/udp_packet.h"
17*3f982cf4SFabien Sanglard 
18*3f982cf4SFabien Sanglard namespace openscreen {
19*3f982cf4SFabien Sanglard 
20*3f982cf4SFabien Sanglard class TaskRunner;
21*3f982cf4SFabien Sanglard 
22*3f982cf4SFabien Sanglard // An open UDP socket for sending/receiving datagrams to/from either specific
23*3f982cf4SFabien Sanglard // endpoints or over IP multicast.
24*3f982cf4SFabien Sanglard //
25*3f982cf4SFabien Sanglard // Usage: The socket is created and opened by calling the Create() method. This
26*3f982cf4SFabien Sanglard // returns a unique pointer that auto-closes/destroys the socket when it goes
27*3f982cf4SFabien Sanglard // out-of-scope.
28*3f982cf4SFabien Sanglard class UdpSocket {
29*3f982cf4SFabien Sanglard  public:
30*3f982cf4SFabien Sanglard   // Client for the UdpSocket class.
31*3f982cf4SFabien Sanglard   class Client {
32*3f982cf4SFabien Sanglard    public:
33*3f982cf4SFabien Sanglard 
34*3f982cf4SFabien Sanglard     // Method called when the UDP socket is bound. Default implementation
35*3f982cf4SFabien Sanglard     // does nothing, as clients may not care about the socket bind state.
OnBound(UdpSocket * socket)36*3f982cf4SFabien Sanglard     virtual void OnBound(UdpSocket* socket) {}
37*3f982cf4SFabien Sanglard 
38*3f982cf4SFabien Sanglard     // Method called on socket configuration operations when an error occurs.
39*3f982cf4SFabien Sanglard     // These specific APIs are:
40*3f982cf4SFabien Sanglard     //   UdpSocket::Bind()
41*3f982cf4SFabien Sanglard     //   UdpSocket::SetMulticastOutboundInterface(...)
42*3f982cf4SFabien Sanglard     //   UdpSocket::JoinMulticastGroup(...)
43*3f982cf4SFabien Sanglard     //   UdpSocket::SetDscp(...)
44*3f982cf4SFabien Sanglard     virtual void OnError(UdpSocket* socket, Error error) = 0;
45*3f982cf4SFabien Sanglard 
46*3f982cf4SFabien Sanglard     // Method called when an error occurs during a SendMessage call.
47*3f982cf4SFabien Sanglard     virtual void OnSendError(UdpSocket* socket, Error error) = 0;
48*3f982cf4SFabien Sanglard 
49*3f982cf4SFabien Sanglard     // Method called when a packet is read.
50*3f982cf4SFabien Sanglard     virtual void OnRead(UdpSocket* socket, ErrorOr<UdpPacket> packet) = 0;
51*3f982cf4SFabien Sanglard 
52*3f982cf4SFabien Sanglard    protected:
53*3f982cf4SFabien Sanglard     virtual ~Client();
54*3f982cf4SFabien Sanglard   };
55*3f982cf4SFabien Sanglard 
56*3f982cf4SFabien Sanglard   // Constants used to specify how we want packets sent from this socket.
57*3f982cf4SFabien Sanglard   enum class DscpMode : uint8_t {
58*3f982cf4SFabien Sanglard     // Default value set by the system on creation of a new socket.
59*3f982cf4SFabien Sanglard     kUnspecified = 0x0,
60*3f982cf4SFabien Sanglard 
61*3f982cf4SFabien Sanglard     // Mode for Audio only.
62*3f982cf4SFabien Sanglard     kAudioOnly = 0xb8,
63*3f982cf4SFabien Sanglard 
64*3f982cf4SFabien Sanglard     // Mode for Audio + Video.
65*3f982cf4SFabien Sanglard     kAudioVideo = 0x88,
66*3f982cf4SFabien Sanglard 
67*3f982cf4SFabien Sanglard     // Mode for low priority operations such as trace log data.
68*3f982cf4SFabien Sanglard     kLowPriority = 0x20
69*3f982cf4SFabien Sanglard   };
70*3f982cf4SFabien Sanglard 
71*3f982cf4SFabien Sanglard   using Version = IPAddress::Version;
72*3f982cf4SFabien Sanglard 
73*3f982cf4SFabien Sanglard   // Creates a new, scoped UdpSocket within the IPv4 or IPv6 family.
74*3f982cf4SFabien Sanglard   // |local_endpoint| may be zero (see comments for Bind()). This method must be
75*3f982cf4SFabien Sanglard   // defined in the platform-level implementation. All |client| methods called
76*3f982cf4SFabien Sanglard   // will be queued on the provided |task_runner|. For this reason, the provided
77*3f982cf4SFabien Sanglard   // TaskRunner and Client must exist for the duration of the created socket's
78*3f982cf4SFabien Sanglard   // lifetime.
79*3f982cf4SFabien Sanglard   static ErrorOr<std::unique_ptr<UdpSocket>> Create(
80*3f982cf4SFabien Sanglard       TaskRunner* task_runner,
81*3f982cf4SFabien Sanglard       Client* client,
82*3f982cf4SFabien Sanglard       const IPEndpoint& local_endpoint);
83*3f982cf4SFabien Sanglard 
84*3f982cf4SFabien Sanglard   virtual ~UdpSocket();
85*3f982cf4SFabien Sanglard 
86*3f982cf4SFabien Sanglard   // Returns true if |socket| belongs to the IPv4/IPv6 address family.
87*3f982cf4SFabien Sanglard   virtual bool IsIPv4() const = 0;
88*3f982cf4SFabien Sanglard   virtual bool IsIPv6() const = 0;
89*3f982cf4SFabien Sanglard 
90*3f982cf4SFabien Sanglard   // Returns the current local endpoint's address and port. Initially, this will
91*3f982cf4SFabien Sanglard   // be the same as the value that was passed into Create(). However, it can
92*3f982cf4SFabien Sanglard   // later change after certain operations, such as Bind(), are executed.
93*3f982cf4SFabien Sanglard   virtual IPEndpoint GetLocalEndpoint() const = 0;
94*3f982cf4SFabien Sanglard 
95*3f982cf4SFabien Sanglard   // Binds to the address specified in the constructor. If the local endpoint's
96*3f982cf4SFabien Sanglard   // address is zero, the operating system will bind to all interfaces. If the
97*3f982cf4SFabien Sanglard   // local endpoint's port is zero, the operating system will automatically find
98*3f982cf4SFabien Sanglard   // a free local port and bind to it. Future calls to GetLocalEndpoint() will
99*3f982cf4SFabien Sanglard   // reflect the resolved port.
100*3f982cf4SFabien Sanglard   virtual void Bind() = 0;
101*3f982cf4SFabien Sanglard 
102*3f982cf4SFabien Sanglard   // Sets the device to use for outgoing multicast packets on the socket.
103*3f982cf4SFabien Sanglard   virtual void SetMulticastOutboundInterface(NetworkInterfaceIndex ifindex) = 0;
104*3f982cf4SFabien Sanglard 
105*3f982cf4SFabien Sanglard   // Joins to the multicast group at the given address, using the specified
106*3f982cf4SFabien Sanglard   // interface.
107*3f982cf4SFabien Sanglard   virtual void JoinMulticastGroup(const IPAddress& address,
108*3f982cf4SFabien Sanglard                                   NetworkInterfaceIndex ifindex) = 0;
109*3f982cf4SFabien Sanglard 
110*3f982cf4SFabien Sanglard   // Sends a message. If the message is not sent, Client::OnSendError() will be
111*3f982cf4SFabien Sanglard   // called to indicate this. Error::Code::kAgain indicates the operation would
112*3f982cf4SFabien Sanglard   // block, which can be expected during normal operation.
113*3f982cf4SFabien Sanglard   virtual void SendMessage(const void* data,
114*3f982cf4SFabien Sanglard                            size_t length,
115*3f982cf4SFabien Sanglard                            const IPEndpoint& dest) = 0;
116*3f982cf4SFabien Sanglard 
117*3f982cf4SFabien Sanglard   // Sets the DSCP value to use for all messages sent from this socket.
118*3f982cf4SFabien Sanglard   virtual void SetDscp(DscpMode state) = 0;
119*3f982cf4SFabien Sanglard 
120*3f982cf4SFabien Sanglard  protected:
121*3f982cf4SFabien Sanglard   UdpSocket();
122*3f982cf4SFabien Sanglard };
123*3f982cf4SFabien Sanglard 
124*3f982cf4SFabien Sanglard }  // namespace openscreen
125*3f982cf4SFabien Sanglard 
126*3f982cf4SFabien Sanglard #endif  // PLATFORM_API_UDP_SOCKET_H_
127