1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#pragma once 6 7#include <fbl/unique_fd.h> 8#include <map> 9#include <poll.h> 10#include <set> 11#include <vector> 12 13#include "usb-handler.h" 14 15namespace xdc { 16 17class Client { 18public: 19 explicit Client(int fd) : fd_(fd) {} 20 21 void SetStreamId(uint32_t stream_id); 22 void SetConnected(bool connected); 23 // Returns whether the set of client events we are polling for has changed. 24 bool UpdatePollState(bool usb_writable); 25 26 // Queues a completed read transfer to be written to the client. 27 void AddCompletedRead(std::unique_ptr<UsbHandler::Transfer> transfer); 28 // Writes data from completed read transfers to the client until there are 29 // no transfers left, or the client is currently unavailable to accept data. 30 void ProcessCompletedReads(const std::unique_ptr<UsbHandler>& usb_handler); 31 // Writes data read from the client to the usb handler. 32 zx_status_t ProcessWrites(const std::unique_ptr<UsbHandler>& usb_handler); 33 // Returns any unused transfers to the usb handler. 34 void ReturnTransfers(const std::unique_ptr<UsbHandler>& usb_handler); 35 36 int fd() const { return fd_.get(); } 37 // Returns the set of client events we should poll for. 38 short events() const { return events_; } 39 bool registered() const { return registered_; } 40 uint32_t stream_id() const { return stream_id_; } 41 bool connected() const { return connected_; } 42 // Returns true if we have read data from the client not yet sent to the usb handler. 43 bool has_write_data() const { return pending_write_ && pending_write_->request_length() > 0; } 44 45private: 46 fbl::unique_fd fd_; 47 48 short events_ = 0; 49 50 // Whether the client has registered a stream id. 51 bool registered_ = false; 52 uint32_t stream_id_ = 0; 53 // True if the client has registered a stream id, 54 // and that stream id is also registered on the xdc device side. 55 bool connected_ = false; 56 57 std::vector<std::unique_ptr<UsbHandler::Transfer>> completed_reads_; 58 // Data read from the client, to be sent to the usb handler. 59 std::unique_ptr<UsbHandler::Transfer> pending_write_; 60}; 61 62class XdcServer { 63 // This is required by the XdcServer constructor, to stop clients calling it directly. 64 struct ConstructorTag { explicit ConstructorTag() = default; }; 65 66public: 67 // Create should be called instead. This is public for make_unique. 68 XdcServer(ConstructorTag tag) {} 69 70 static std::unique_ptr<XdcServer> Create(); 71 void Run(); 72 73private: 74 bool Init(); 75 76 void UpdateClientPollEvents(); 77 78 // Updates poll_fds_ with any newly added or removed usb handler fds. 79 void UpdateUsbHandlerFds(); 80 81 // Processes new client connections on the server socket. 82 void ClientConnect(); 83 84 // Returns whether registration succeeded. 85 bool RegisterStream(std::shared_ptr<Client> client); 86 87 // Returns the client registered to the given stream id, or nullptr if none was foumd. 88 std::shared_ptr<Client> GetClient(uint32_t stream_id); 89 90 void UsbReadComplete(std::unique_ptr<UsbHandler::Transfer> transfer); 91 // Parses the control message from the given transfer buffer. 92 void HandleCtrlMsg(unsigned char* transfer_buf, int transfer_len); 93 94 // Sends a control message the to the xdc device with whether a stream has gone on / offline. 95 // If the message cannot currently be sent, it is queued to be retried later. 96 void NotifyStreamState(uint32_t stream_id, bool online); 97 bool SendCtrlMsg(xdc_msg_t& msg); 98 void SendQueuedCtrlMsgs(); 99 100 std::unique_ptr<UsbHandler> usb_handler_; 101 102 // Server socket we receive client connections on. 103 fbl::unique_fd socket_fd_; 104 // File lock acquired to ensure we don't unlink the socket of a running xdc server instance. 105 fbl::unique_fd socket_lock_fd_; 106 107 // Maps from client socket file descriptor to client. 108 std::map<int, std::shared_ptr<Client>> clients_; 109 110 // File descriptors we are currently polling on. 111 std::vector<pollfd> poll_fds_; 112 113 // Stream ids registered on the xdc device side. 114 std::set<uint32_t> dev_stream_ids_; 115 116 std::vector<xdc_msg_t> queued_ctrl_msgs_; 117 118 xdc_packet_state_t read_packet_state_; 119}; 120 121} // namespace xdc 122