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 #include <lib/fit/defer.h>
6 #include <xdc-host-utils/conn.h>
7 #include <xdc-server-utils/msg.h>
8 #include <xdc-server-utils/packet.h>
9 #include <xdc-server-utils/stream.h>
10 
11 #include <cassert>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <poll.h>
15 #include <signal.h>
16 #include <stdio.h>
17 #include <sys/file.h>
18 #include <sys/socket.h>
19 #include <sys/types.h>
20 #include <sys/un.h>
21 #include <unistd.h>
22 
23 #include "usb-handler.h"
24 #include "xdc-server.h"
25 
26 namespace xdc {
27 
28 static constexpr uint32_t MAX_PENDING_CONN_BACKLOG = 128;
29 static const char* XDC_LOCK_PATH = "/tmp/xdc.lock";
30 
SetStreamId(uint32_t stream_id)31 void Client::SetStreamId(uint32_t stream_id) {
32     registered_ = true;
33     stream_id_ = stream_id;
34 }
35 
SetConnected(bool connected)36 void Client::SetConnected(bool connected) {
37     if (connected == connected_) {
38         fprintf(stderr, "tried to set client with stream id %u as %s again.\n",
39                 stream_id(), connected ? "connected" : "disconnected");
40         return;
41     }
42     printf("client with stream id %u is now %s to the xdc device stream.\n",
43            stream_id(), connected ? "connected" : "disconnected");
44     connected_ = connected;
45 }
46 
UpdatePollState(bool usb_writable)47 bool Client::UpdatePollState(bool usb_writable) {
48     short updated_events = events_;
49     // We want to poll for the client readable signal if:
50     //  - The client has not yet registered a stream id, or,
51     //  - The xdc stream of the client's id is ready to be written to.
52     if (!stream_id() || (usb_writable && connected())) {
53         updated_events |= POLLIN;
54     } else {
55         updated_events &= ~(POLLIN);
56     }
57     // We need to poll for the client writable signal if we have data to send to the client.
58     if (completed_reads_.size() > 0) {
59         updated_events |= POLLOUT;
60     } else {
61         updated_events &= ~POLLOUT;
62     }
63     if (updated_events != events_) {
64         events_ = updated_events;
65         return true;
66     }
67     return false;
68 }
69 
AddCompletedRead(std::unique_ptr<UsbHandler::Transfer> transfer)70 void Client::AddCompletedRead(std::unique_ptr<UsbHandler::Transfer> transfer) {
71     completed_reads_.push_back(std::move(transfer));
72 }
73 
ProcessCompletedReads(const std::unique_ptr<UsbHandler> & usb_handler)74 void Client::ProcessCompletedReads(const std::unique_ptr<UsbHandler>& usb_handler) {
75     for (auto iter = completed_reads_.begin(); iter != completed_reads_.end();) {
76         std::unique_ptr<UsbHandler::Transfer>& transfer = *iter;
77 
78         unsigned char* data = transfer->data() + transfer->offset();
79         size_t len_to_write = transfer->actual_length() - transfer->offset();
80 
81         ssize_t total_written = 0;
82         while (total_written < len_to_write) {
83             ssize_t res = send(fd(), data + total_written, len_to_write - total_written, 0);
84             if (res < 0) {
85                 if (errno == EAGAIN) {
86                     fprintf(stderr, "can't send completed read to client currently\n");
87                     // Need to wait for client to be writable again.
88                     return;
89                 } else {
90                     fprintf(stderr, "can't write to client, err: %s\n", strerror(errno));
91                     return;
92                 }
93             }
94             total_written += res;
95             int offset = transfer->offset() + res;
96             assert(transfer->SetOffset(offset));
97         }
98         usb_handler->RequeueRead(std::move(transfer));
99         iter = completed_reads_.erase(iter);
100     }
101 }
102 
ProcessWrites(const std::unique_ptr<UsbHandler> & usb_handler)103 zx_status_t Client::ProcessWrites(const std::unique_ptr<UsbHandler>& usb_handler) {
104     if (!connected()) {
105         return ZX_ERR_SHOULD_WAIT;
106     }
107     while (true) {
108         if (!pending_write_) {
109             pending_write_ = usb_handler->GetWriteTransfer();
110             if (!pending_write_) {
111                 return ZX_ERR_SHOULD_WAIT; // No transfers currently available.
112             }
113         }
114         // If there is no pending data to transfer, read more from the client.
115         if (!has_write_data()) {
116             // Read from the client into the usb transfer buffer. Leave space for the header.
117             unsigned char* buf = pending_write_->write_data_buffer();
118 
119             int n = recv(fd(), buf, UsbHandler::Transfer::MAX_WRITE_DATA_SIZE, 0);
120             if (n == 0) {
121                 return ZX_ERR_PEER_CLOSED;
122             } else if (n == EAGAIN) {
123                 return ZX_ERR_SHOULD_WAIT;
124             } else if (n < 0) {
125                 fprintf(stderr, "recv got unhandled err: %s\n", strerror(errno));
126                 return ZX_ERR_IO;
127             }
128             pending_write_->FillHeader(stream_id(), n);
129         }
130         if (usb_handler->writable()) {
131             pending_write_ = usb_handler->QueueWriteTransfer(std::move(pending_write_));
132             if (pending_write_) {
133                 // Usb handler was busy and returned the write.
134                 return ZX_ERR_SHOULD_WAIT;
135             }
136         } else {
137             break; // Usb handler is busy, need to wait for some writes to complete.
138         }
139     }
140     return ZX_ERR_SHOULD_WAIT;
141 }
142 
ReturnTransfers(const std::unique_ptr<UsbHandler> & usb_handler)143 void Client::ReturnTransfers(const std::unique_ptr<UsbHandler>& usb_handler) {
144     for (auto& transfer : completed_reads_) {
145         usb_handler->RequeueRead(std::move(transfer));
146     }
147     completed_reads_.clear();
148 
149     if (pending_write_) {
150         usb_handler->ReturnWriteTransfer(std::move(pending_write_));
151     }
152 }
153 
154 // static
Create()155 std::unique_ptr<XdcServer> XdcServer::Create() {
156     auto conn = std::make_unique<XdcServer>(ConstructorTag{});
157     if (!conn->Init()) {
158         return nullptr;
159     }
160     return conn;
161 }
162 
Init()163 bool XdcServer::Init() {
164     usb_handler_ = UsbHandler::Create();
165     if (!usb_handler_) {
166         return false;
167     }
168 
169     socket_fd_.reset(socket(AF_UNIX, SOCK_STREAM, 0));
170     if (!socket_fd_) {
171         fprintf(stderr, "failed to create socket, err: %s\n", strerror(errno));
172         return false;
173     }
174     sockaddr_un addr = {};
175     addr.sun_family = AF_UNIX;
176     strncpy(addr.sun_path, XDC_SOCKET_PATH, sizeof(addr.sun_path));
177 
178     // Check if another instance of the xdc server is running.
179     socket_lock_fd_.reset(open(XDC_LOCK_PATH, O_CREAT | O_RDONLY, 0666));
180     if (!socket_lock_fd_) {
181         return false;
182     }
183     int res = flock(socket_lock_fd_.get(), LOCK_EX | LOCK_NB);
184     if (res != 0) {
185         fprintf(stderr, "Failed to acquire socket lock, err: %s.\n", strerror(errno));
186         return false;
187     }
188     // Remove the socket file if it exists.
189     unlink(XDC_SOCKET_PATH);
190     if (bind(socket_fd_.get(), (sockaddr*)&addr, sizeof(addr)) != 0) {
191         fprintf(stderr, "Could not bind socket with pathname: %s, err: %s\n",
192                 XDC_SOCKET_PATH, strerror(errno));
193         return false;
194     }
195     if (listen(socket_fd_.get(), MAX_PENDING_CONN_BACKLOG) < 0) {
196         fprintf(stderr, "Could not listen on socket fd: %d, err: %s\n",
197                 socket_fd_.get(), strerror(errno));
198         return false;
199     }
200     return true;
201 }
202 
UpdateClientPollEvents()203 void XdcServer::UpdateClientPollEvents() {
204     for (auto iter : clients_) {
205         std::shared_ptr<Client> client = iter.second;
206         bool changed = client->UpdatePollState(usb_handler_->writable());
207         if (changed) {
208             // We need to update the corresponding file descriptor in the poll_fds_ array
209             // passed to poll.
210             int fd = client->fd();
211             auto is_fd = [fd](auto& elem) { return elem.fd == fd; };
212             auto fd_iter = std::find_if(poll_fds_.begin(), poll_fds_.end(), is_fd);
213             if (fd_iter == poll_fds_.end()) {
214                 fprintf(stderr, "could not find pollfd for client with fd %d\n", fd);
215                 continue;
216             }
217             fd_iter->events = client->events();
218         }
219     }
220 }
221 
UpdateUsbHandlerFds()222 void XdcServer::UpdateUsbHandlerFds() {
223     std::map<int, short> added_fds;
224     std::set<int> removed_fds;
225     usb_handler_->GetFdUpdates(added_fds, removed_fds);
226 
227     for (auto iter : added_fds) {
228         int fd = iter.first;
229         short events = iter.second;
230 
231         auto match = std::find_if(poll_fds_.begin(), poll_fds_.end(),
232                                   [&fd](auto& pollfd) { return pollfd.fd == fd; });
233         if (match != poll_fds_.end()) {
234             fprintf(stderr, "already have usb handler fd: %d\n", fd);
235             continue;
236         }
237         poll_fds_.push_back(pollfd{fd, events, 0});
238         printf("usb handler added fd: %d\n", fd);
239     }
240     for (auto fd : removed_fds) {
241         auto match = std::remove_if(poll_fds_.begin(), poll_fds_.end(),
242                                     [&fd](auto& pollfd) { return pollfd.fd == fd; });
243         if (match == poll_fds_.end()) {
244             fprintf(stderr, "could not find usb handler fd: %d to delete\n", fd);
245             continue;
246         }
247         poll_fds_.erase(match, poll_fds_.end());
248         printf("usb handler removed fd: %d\n", fd);
249     }
250 }
251 
Run()252 void XdcServer::Run() {
253     signal(SIGPIPE, SIG_IGN); // Prevent clients from causing SIGPIPE.
254 
255     printf("Waiting for connections on: %s\n", XDC_SOCKET_PATH);
256 
257     // Listen for new client connections.
258     poll_fds_.push_back(pollfd{socket_fd_.get(), POLLIN, 0});
259 
260     // Initialize to true as we want to get the initial usb handler fds.
261     bool update_usb_handler_fds = true;
262 
263     for (;;) {
264         if (update_usb_handler_fds) {
265             UpdateUsbHandlerFds();
266             update_usb_handler_fds = false;
267         }
268 
269         // poll expects an array of pollfds.
270         int num = poll(&poll_fds_[0], poll_fds_.size(), -1 /* timeout */);
271         if (num < 0) {
272             fprintf(stderr, "poll failed, err: %s\n", strerror(errno));
273             break;
274         }
275         // Not using an iterator for poll_fds_ as we might add/remove elements.
276         int num_sockets = poll_fds_.size();
277         int i = 0;
278         while (i < num_sockets) {
279             if (poll_fds_[i].fd == socket_fd_.get()) {
280                 // A new client is trying to connect.
281                 if (poll_fds_[i].revents & POLLIN) {
282                     ClientConnect();
283                     // Don't need to increment num_sockets as there aren't poll events for it yet.
284                 }
285             } else if (usb_handler_->IsValidFd(poll_fds_[i].fd)) {
286                 if (poll_fds_[i].revents) {
287                     std::vector<std::unique_ptr<UsbHandler::Transfer>> completed_reads;
288                     update_usb_handler_fds = usb_handler_->HandleEvents(completed_reads);
289 
290                     SendQueuedCtrlMsgs();
291 
292                     for (auto& usb_transfer : completed_reads) {
293                         UsbReadComplete(std::move(usb_transfer));
294                     }
295                 }
296             } else {
297                 auto iter = clients_.find(poll_fds_[i].fd);
298                 if (iter == clients_.end()) {
299                     fprintf(stderr, "poll returned an unknown fd: %d\n", poll_fds_[i].fd);
300                     poll_fds_.erase(poll_fds_.begin() + i);
301                     --num_sockets;
302                     continue;
303                 }
304 
305                 std::shared_ptr<Client> client = iter->second;
306 
307                 // Received client disconnect signal.
308                 // Only remove the client if the corresponding xdc device stream is offline.
309                 // Otherwise the client may still have data buffered to send to the usb handler,
310                 // and we will wait until reading from the client returns zero (disconnect).
311                 bool delete_client =
312                     (poll_fds_[i].revents & POLLHUP) && !client->connected();
313 
314                 // Check if the client had pending data to write, or signalled new data available.
315                 bool do_write = client->has_write_data() && usb_handler_->writable() &&
316                                 client->connected();
317                 bool new_data_available = poll_fds_[i].revents & POLLIN;
318                 if (!delete_client && (do_write || new_data_available)) {
319                     if (!client->registered()) {
320                         // Delete the client if registering the stream failed.
321                         delete_client = !RegisterStream(client);
322                     }
323                     if (!delete_client) {
324                         zx_status_t status = client->ProcessWrites(usb_handler_);
325                         if (status == ZX_ERR_PEER_CLOSED) {
326                             delete_client = true;
327                         }
328                     }
329                 }
330 
331                 if (delete_client) {
332                     client->ReturnTransfers(usb_handler_);
333                     // Notify the host server that the stream is now offline.
334                     if (client->stream_id()) {
335                         NotifyStreamState(client->stream_id(), false /* online */);
336                     }
337                     poll_fds_.erase(poll_fds_.begin() + i);
338                     --num_sockets;
339                     printf("fd %d stream %u disconnected\n", client->fd(), client->stream_id());
340                     clients_.erase(iter);
341                     continue;
342                 }
343                 client->ProcessCompletedReads(usb_handler_);
344             }
345             ++i;
346         }
347         UpdateClientPollEvents();
348     }
349 }
350 
ClientConnect()351 void XdcServer::ClientConnect() {
352     struct sockaddr_un addr;
353     socklen_t len = sizeof(addr);
354     // Most of the time we want non-blocking transfers, so we can handle other clients / libusb.
355     int client_fd = accept(socket_fd_.get(), (struct sockaddr*)&addr, &len);
356     if (client_fd < 0) {
357         fprintf(stderr, "Socket accept failed, err: %s\n", strerror(errno));
358         return;
359     }
360     if (clients_.count(client_fd) > 0) {
361         fprintf(stderr, "Client already connected, socket fd: %d\n", client_fd);
362         return;
363     }
364     int flags = fcntl(client_fd, F_GETFL, 0);
365     if (flags < 0) {
366         fprintf(stderr, "Could not get socket flags, err: %s\n", strerror(errno));
367         close(client_fd);
368         return;
369     }
370     int res = fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
371     if (res != 0) {
372         fprintf(stderr, "Could not set socket as nonblocking, err: %s\n", strerror(errno));
373         close(client_fd);
374         return;
375     }
376     printf("Client connected, socket fd: %d\n", client_fd);
377     clients_[client_fd] = std::make_shared<Client>(client_fd);
378     poll_fds_.push_back(pollfd{client_fd, POLLIN, 0});
379 }
380 
RegisterStream(std::shared_ptr<Client> client)381 bool XdcServer::RegisterStream(std::shared_ptr<Client> client) {
382     RegisterStreamRequest stream_id;
383     ssize_t n = recv(client->fd(), &stream_id, sizeof(stream_id), MSG_WAITALL);
384     if (n != sizeof(stream_id)) {
385         fprintf(stderr, "failed to read stream id from client fd: %d, got len: %ld, got err: %s\n",
386                 client->fd(), n, strerror(errno));
387         return false;
388     }
389     // Client has disconnected. This will be handled in the main poll thread.
390     if (n == 0) {
391         return false;
392     }
393     RegisterStreamResponse resp = false;
394     if (stream_id == DEBUG_STREAM_ID_RESERVED) {
395         fprintf(stderr, "cannot register stream id %u\n", DEBUG_STREAM_ID_RESERVED);
396     } else if (GetClient(stream_id)) {
397         fprintf(stderr, "stream id %u was already registered\n", stream_id);
398     } else {
399         client->SetStreamId(stream_id);
400         printf("registered stream id %u\n", stream_id);
401         NotifyStreamState(stream_id, true /* online */);
402         if (dev_stream_ids_.count(stream_id)) {
403             client->SetConnected(true);
404         }
405         resp = true;
406     }
407 
408     ssize_t res = send(client->fd(), &resp, sizeof(resp), MSG_WAITALL);
409     if (res != sizeof(resp)) {
410         // Failed to send reply, disconnect the client.
411         return false;
412     }
413     return resp;
414 }
415 
GetClient(uint32_t stream_id)416 std::shared_ptr<Client> XdcServer::GetClient(uint32_t stream_id) {
417     auto is_client = [stream_id](auto& pair) -> bool {
418         return pair.second->stream_id() == stream_id;
419     };
420     auto iter = std::find_if(clients_.begin(), clients_.end(), is_client);
421     return iter == clients_.end() ? nullptr : iter->second;
422 }
423 
UsbReadComplete(std::unique_ptr<UsbHandler::Transfer> transfer)424 void XdcServer::UsbReadComplete(std::unique_ptr<UsbHandler::Transfer> transfer) {
425     auto requeue = fit::defer([&]() { usb_handler_->RequeueRead(std::move(transfer)); });
426 
427     bool is_new_packet;
428     uint32_t stream_id;
429 
430     zx_status_t status = xdc_update_packet_state(&read_packet_state_, transfer->data(),
431                                                  transfer->actual_length(), &is_new_packet);
432     if (status != ZX_OK) {
433         fprintf(stderr, "error processing transfer: %d, dropping read of size %d\n",
434                 status, transfer->actual_length());
435     }
436     stream_id = read_packet_state_.header.stream_id;
437     if (is_new_packet && stream_id == XDC_MSG_STREAM) {
438         HandleCtrlMsg(transfer->data(), transfer->actual_length());
439         return;
440     }
441     // Pass the completed transfer to the registered client, if any.
442     auto client = GetClient(stream_id);
443     if (!client) {
444         fprintf(stderr, "No client registered for stream %u, dropping read of size %d\n",
445                 stream_id, transfer->actual_length());
446         return;
447     }
448     // If it is the start of a new packet, the client should begin reading after the header.
449     int offset = is_new_packet ? sizeof(xdc_packet_header_t) : 0;
450     assert(transfer->SetOffset(offset));
451     client->AddCompletedRead(std::move(transfer));
452     requeue.cancel();
453 }
454 
HandleCtrlMsg(unsigned char * transfer_buf,int transfer_len)455 void XdcServer::HandleCtrlMsg(unsigned char* transfer_buf, int transfer_len) {
456     int data_len = transfer_len - (int)sizeof(xdc_packet_header_t);
457     if (data_len < (int)sizeof(xdc_msg_t)) {
458         fprintf(stderr, "malformed msg, got %d bytes, need %lu\n", data_len, sizeof(xdc_msg_t));
459         return;
460     }
461     xdc_msg_t* msg = reinterpret_cast<xdc_msg_t*>(transfer_buf + sizeof(xdc_packet_header_t));
462     switch (msg->opcode) {
463     case XDC_NOTIFY_STREAM_STATE: {
464         uint32_t stream_id = msg->notify_stream_state.stream_id;
465         bool online = msg->notify_stream_state.online;
466 
467         auto dev_stream = dev_stream_ids_.find(stream_id);
468         bool saved_online_state = dev_stream != dev_stream_ids_.end();
469         if (online == saved_online_state) {
470             fprintf(stderr, "tried to set stream %u to %s again\n",
471                     stream_id, online ? "online" : "offline");
472             return;
473         }
474         if (online) {
475             dev_stream_ids_.insert(stream_id);
476         } else {
477             dev_stream_ids_.erase(dev_stream);
478         }
479         printf("xdc device stream id %u is now %s\n", stream_id, online ? "online" : "offline");
480 
481         // Update the host client's connected status.
482         auto client = GetClient(stream_id);
483         if (!client) {
484             break;
485         }
486         client->SetConnected(online);
487         break;
488     }
489     default:
490         fprintf(stderr, "unknown msg opcode: %u\n", msg->opcode);
491     }
492 }
493 
NotifyStreamState(uint32_t stream_id,bool online)494 void XdcServer::NotifyStreamState(uint32_t stream_id, bool online) {
495     xdc_msg_t msg = {
496         .opcode = XDC_NOTIFY_STREAM_STATE,
497         .notify_stream_state.stream_id = stream_id,
498         .notify_stream_state.online = online};
499     queued_ctrl_msgs_.push_back(msg);
500     SendQueuedCtrlMsgs();
501 }
502 
SendCtrlMsg(xdc_msg_t & msg)503 bool XdcServer::SendCtrlMsg(xdc_msg_t& msg) {
504     std::unique_ptr<UsbHandler::Transfer> transfer = usb_handler_->GetWriteTransfer();
505     if (!transfer) {
506         return false;
507     }
508     zx_status_t res = transfer->FillData(DEBUG_STREAM_ID_RESERVED,
509                                          reinterpret_cast<unsigned char*>(&msg), sizeof(msg));
510     assert(res == ZX_OK); // Should not fail.
511     transfer = usb_handler_->QueueWriteTransfer(std::move(transfer));
512     bool queued = !transfer;
513     if (!queued) {
514         usb_handler_->ReturnWriteTransfer(std::move(transfer));
515     }
516     return queued;
517 }
518 
SendQueuedCtrlMsgs()519 void XdcServer::SendQueuedCtrlMsgs() {
520     auto msgs_iter = queued_ctrl_msgs_.begin();
521     while (msgs_iter != queued_ctrl_msgs_.end()) {
522         bool sent = SendCtrlMsg(*msgs_iter);
523         if (sent) {
524             msgs_iter = queued_ctrl_msgs_.erase(msgs_iter);
525         } else {
526             // Need to wait.
527             return;
528         }
529     }
530 }
531 
532 } // namespace xdc
533 
main(int argc,char ** argv)534 int main(int argc, char** argv) {
535     printf("Starting XHCI Debug Capability server...\n");
536     std::unique_ptr<xdc::XdcServer> xdc_server = xdc::XdcServer::Create();
537     if (!xdc_server) {
538         return -1;
539     }
540     xdc_server->Run();
541     return 0;
542 }
543