Some checks failed
dev release / build (push) Failing after 12s
Builds out the full v1 scope: a vendored+patched openscreen subset for low-latency Cast Streaming (Mirroring receiver 0F5096E8) alongside the existing Cast V2/HLS and new DLNA/AVTransport casting paths, breadcastd's Idle/Casting state machine with a private IPC socket, the breadcast GTK4 popup as a thin IPC client, and bread.cast.*/bread.command.cast.* breadd integration (device discovery, start/stop, mirroring lifecycle events). Also adds bakery/systemd/Forgejo CI packaging. Validated end-to-end against a real Chromecast/Google TV: negotiated Cast Streaming session, live pipeline playback, and daemon+GUI click-to-cast/ stop through the actual popup.
140 lines
4.8 KiB
C++
140 lines
4.8 KiB
C++
// Copyright 2018 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef PLATFORM_API_UDP_SOCKET_H_
|
|
#define PLATFORM_API_UDP_SOCKET_H_
|
|
|
|
#include <stddef.h> // size_t
|
|
#include <stdint.h> // uint8_t
|
|
|
|
#include <memory>
|
|
|
|
#include "platform/api/network_interface.h"
|
|
#include "platform/base/error.h"
|
|
#include "platform/base/ip_address.h"
|
|
#include "platform/base/span.h"
|
|
#include "platform/base/udp_packet.h"
|
|
|
|
namespace openscreen {
|
|
|
|
class TaskRunner;
|
|
|
|
// An open UDP socket for sending/receiving datagrams to/from either specific
|
|
// endpoints or over IP multicast.
|
|
//
|
|
// Usage: The socket is created and opened by calling the Create() method. This
|
|
// returns a unique pointer that auto-closes/destroys the socket when it goes
|
|
// out-of-scope.
|
|
class UdpSocket {
|
|
public:
|
|
// Client for the UdpSocket class.
|
|
class Client {
|
|
public:
|
|
// Method called when the UDP socket is bound. Default implementation
|
|
// does nothing, as clients may not care about the socket bind state.
|
|
virtual void OnBound(UdpSocket* socket) {}
|
|
|
|
// Method called on socket configuration operations when an error occurs.
|
|
// These specific APIs are:
|
|
// UdpSocket::Bind()
|
|
// UdpSocket::SetMulticastOutboundInterface(...)
|
|
// UdpSocket::JoinMulticastGroup(...)
|
|
// UdpSocket::SetDscp(...)
|
|
virtual void OnError(UdpSocket* socket, const Error& error) = 0;
|
|
|
|
// Method called when an error occurs during a SendMessage call.
|
|
virtual void OnSendError(UdpSocket* socket, const Error& error) = 0;
|
|
|
|
// Method called when a packet is read.
|
|
virtual void OnRead(UdpSocket* socket, ErrorOr<UdpPacket> packet) = 0;
|
|
|
|
protected:
|
|
virtual ~Client();
|
|
};
|
|
|
|
// Common, modern code points for use with DSCP. This list is non-inclusive,
|
|
// callers are encouraged to check validity of an integer code point by
|
|
// ensuring it is in the bounds of [kBestEffort, kMaxValue] inclusive.
|
|
// https://www.rfc-editor.org/rfc/rfc2474.html
|
|
enum class DscpMode : uint8_t {
|
|
// Best-effort, no differentiated treatment.
|
|
kBestEffort = 0,
|
|
|
|
// Assured Forwarding code points.
|
|
// https://datatracker.ietf.org/doc/html/rfc2597#section-6
|
|
kAF11 = 10,
|
|
kAF12 = 12,
|
|
kAF13 = 14,
|
|
kAF21 = 18,
|
|
kAF22 = 20,
|
|
kAF23 = 22,
|
|
kAF31 = 26,
|
|
kAF32 = 28,
|
|
kAF33 = 30,
|
|
kAF41 = 34,
|
|
kAF42 = 36,
|
|
kAF43 = 38,
|
|
|
|
// Expedited Forwarding (EF) code point.
|
|
// https://www.rfc-editor.org/rfc/rfc3246.html
|
|
kEF = 46,
|
|
|
|
// As a 6-bit value, DSCP ranges from [0, 63] inclusive.
|
|
kMaxValue = 63,
|
|
};
|
|
|
|
using Version = IPAddress::Version;
|
|
|
|
// Creates a new, scoped UdpSocket within the IPv4 or IPv6 family.
|
|
// `local_endpoint` may be zero (see comments for Bind()). This method must be
|
|
// defined in the platform-level implementation. All `client` methods called
|
|
// will be queued on the provided `task_runner`. For this reason, the provided
|
|
// TaskRunner and Client must exist for the duration of the created socket's
|
|
// lifetime.
|
|
static ErrorOr<std::unique_ptr<UdpSocket>> Create(
|
|
TaskRunner& task_runner,
|
|
Client* client,
|
|
const IPEndpoint& local_endpoint);
|
|
|
|
virtual ~UdpSocket();
|
|
|
|
// Returns true if `socket` belongs to the IPv4/IPv6 address family.
|
|
virtual bool IsIPv4() const = 0;
|
|
virtual bool IsIPv6() const = 0;
|
|
|
|
// Returns the current local endpoint's address and port. Initially, this will
|
|
// be the same as the value that was passed into Create(). However, it can
|
|
// later change after certain operations, such as Bind(), are executed.
|
|
virtual IPEndpoint GetLocalEndpoint() const = 0;
|
|
|
|
// Binds to the address specified in the constructor. If the local endpoint's
|
|
// address is zero, the operating system will bind to all interfaces. If the
|
|
// local endpoint's port is zero, the operating system will automatically find
|
|
// a free local port and bind to it. Future calls to GetLocalEndpoint() will
|
|
// reflect the resolved port.
|
|
virtual void Bind() = 0;
|
|
|
|
// Sets the device to use for outgoing multicast packets on the socket.
|
|
virtual void SetMulticastOutboundInterface(NetworkInterfaceIndex ifindex) = 0;
|
|
|
|
// Joins to the multicast group at the given address, using the specified
|
|
// interface.
|
|
virtual void JoinMulticastGroup(const IPAddress& address,
|
|
NetworkInterfaceIndex ifindex) = 0;
|
|
|
|
// Sends a message. If the message is not sent, Client::OnSendError() will be
|
|
// called to indicate this. Error::Code::kAgain indicates the operation would
|
|
// block, which can be expected during normal operation.
|
|
virtual void SendMessage(ByteView data, const IPEndpoint& dest) = 0;
|
|
|
|
// Sets the DSCP value to use for all messages sent from this socket.
|
|
virtual void SetDscp(DscpMode mode) = 0;
|
|
|
|
protected:
|
|
UdpSocket();
|
|
};
|
|
|
|
} // namespace openscreen
|
|
|
|
#endif // PLATFORM_API_UDP_SOCKET_H_
|