chromium/chrome/browser/media/router/discovery/dial/dial_service_impl.cc

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/media/router/discovery/dial/dial_service_impl.h"

#include <stdint.h>

#include <algorithm>
#include <set>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/network_service_instance.h"
#include "net/base/address_family.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/network_interfaces.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/log/net_log.h"
#include "net/log/net_log_source.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "url/gurl.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chromeos/ash/components/network/network_state.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#endif

Time;
BrowserThread;
HttpResponseHeaders;
HttpUtil;
IOBufferWithSize;
IPAddress;
NetworkInterface;
NetworkInterfaceList;
StringIOBuffer;
UDPSocket;

namespace media_router {

#if !BUILDFLAG(IS_CHROMEOS_ASH)
void PostSendNetworkList(
    base::WeakPtr<DialServiceImpl> impl,
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    const std::optional<net::NetworkInterfaceList>& networks) {}
#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)

namespace {

// The total number of requests to make per discovery cycle.
const int kDialMaxRequests =;

// The interval to wait between successive requests.
const int kDialRequestIntervalMillis =;

// The maximum delay a device may wait before responding (MX).
const int kDialMaxResponseDelaySecs =;

// The maximum time a response is expected after a M-SEARCH request.
const int kDialResponseTimeoutSecs =;

// The multicast IP address for discovery.
const char kDialRequestAddress[] =;

// The UDP port number for discovery.
const uint16_t kDialRequestPort =;

// The DIAL service type as part of the search request.
const char kDialSearchType[] =;

// SSDP headers parsed from the response.
const char kSsdpLocationHeader[] =;
const char kSsdpCacheControlHeader[] =;
const char kSsdpConfigIdHeader[] =;
const char kSsdpUsnHeader[] =;
constexpr char kSsdpMaxAgeDirective[] =;
constexpr int kSsdpMaxMaxAge =;
constexpr int kSsdpMaxConfigId =;

// The receive buffer size, in bytes.
const int kDialRecvBufferSize =;

// Gets a specific header from |headers| and puts it in |value|.
bool GetHeader(HttpResponseHeaders* headers,
               const char* name,
               std::string* value) {}

// Returns the request string.
std::string BuildRequest() {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
// Finds the IP address of the preferred interface of network type |type|
// to bind the socket and inserts the address into |bind_address_list|. This
// ChromeOS version can prioritize wifi and ethernet interfaces.
void InsertBestBindAddressChromeOS(const ash::NetworkTypePattern& type,
                                   net::IPAddressList* bind_address_list) {
  const ash::NetworkState* state = ash::NetworkHandler::Get()
                                       ->network_state_handler()
                                       ->ConnectedNetworkByType(type);
  if (!state)
    return;
  std::string state_ip_address = state->GetIpAddress();
  IPAddress bind_ip_address;
  if (bind_ip_address.AssignFromIPLiteral(state_ip_address) &&
      bind_ip_address.IsIPv4()) {
    bind_address_list->push_back(bind_ip_address);
  }
}

net::IPAddressList GetBestBindAddressOnUIThread() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  net::IPAddressList bind_address_list;
  if (ash::NetworkHandler::IsInitialized()) {
    InsertBestBindAddressChromeOS(ash::NetworkTypePattern::Ethernet(),
                                  &bind_address_list);
    InsertBestBindAddressChromeOS(ash::NetworkTypePattern::WiFi(),
                                  &bind_address_list);
  }
  return bind_address_list;
}
#else
// This function and PostSendNetworkList together handle DialServiceImpl's use
// of the network service, while keeping all of DialServiceImpl running on the
// sequence associated with task_runner_ (currently the IO thread).
// DialServiceImpl has a legacy threading model, where it was designed to be
// called from the UI thread and run on a different thread.  Although a WeakPtr
// is desired for safety when posting tasks, they are not thread/sequence-safe.
// DialServiceImpl's simple use of the network service, however, doesn't
// actually require that any of its state be accessed on the UI thread.
// Therefore, the UI thread functions can be free functions which just
// pass-through an thread WeakPtr which will be used when passing the network
// service result back to the calling thread.  This model will change when the
// network service is fully launched and this code is updated.
void GetNetworkListOnUIThread(
    base::WeakPtr<DialServiceImpl> impl,
    scoped_refptr<base::SequencedTaskRunner> task_runner) {}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

}  // namespace

DialServiceImpl::DialSocket::DialSocket(DialServiceImpl* dial_service)
    :{}

DialServiceImpl::DialSocket::~DialSocket() {}

bool DialServiceImpl::DialSocket::CreateAndBindSocket(
    const IPAddress& bind_ip_address,
    net::NetLog* net_log) {}

void DialServiceImpl::DialSocket::SendOneRequest(
    const net::IPEndPoint& send_address,
    const scoped_refptr<net::StringIOBuffer>& send_buffer) {}

bool DialServiceImpl::DialSocket::IsClosed() {}

bool DialServiceImpl::DialSocket::CheckResult(const char* operation,
                                              int result) {}

void DialServiceImpl::DialSocket::Close() {}

void DialServiceImpl::DialSocket::OnSocketWrite(int send_buffer_size,
                                                int result) {}

bool DialServiceImpl::DialSocket::ReadSocket() {}

void DialServiceImpl::DialSocket::OnSocketRead(int result) {}

void DialServiceImpl::DialSocket::HandleResponse(int bytes_read) {}

bool DialServiceImpl::DialSocket::ParseResponse(const std::string& response,
                                                const base::Time& response_time,
                                                DialDeviceData* device) {}

DialServiceImpl::DialServiceImpl(
    DialService::Client& client,
    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
    net::NetLog* net_log)
    :{}

DialServiceImpl::~DialServiceImpl() {}

bool DialServiceImpl::Discover() {}

void DialServiceImpl::StartDiscovery() {}

void DialServiceImpl::SendNetworkList(
    const std::optional<NetworkInterfaceList>& networks) {}

void DialServiceImpl::DiscoverOnAddresses(
    const net::IPAddressList& ip_addresses) {}

void DialServiceImpl::BindAndAddSocket(const IPAddress& bind_ip_address) {}

std::unique_ptr<DialServiceImpl::DialSocket>
DialServiceImpl::CreateDialSocket() {}

void DialServiceImpl::SendOneRequest() {}

void DialServiceImpl::NotifyOnDiscoveryRequest() {}

void DialServiceImpl::NotifyOnDeviceDiscovered(
    const DialDeviceData& device_data) {}

void DialServiceImpl::NotifyOnError() {}

void DialServiceImpl::FinishDiscovery() {}

bool DialServiceImpl::HasOpenSockets() {}

}  // namespace media_router