USBForward: heartbeat mechanism
Change-Id: I0ff1dd380e4086d3f380f6f337f08a44371c87d2
diff --git a/guest/usbforward/protocol.h b/guest/usbforward/protocol.h
index 45dc05e..c55c3b6 100644
--- a/guest/usbforward/protocol.h
+++ b/guest/usbforward/protocol.h
@@ -67,6 +67,15 @@
// - int32_t(actual length)
// - int32_t[actual length] bytes
CmdDataTransfer,
+
+ // Heartbeat is used to detect whether device is alive.
+ // This is a trivial request/response mechanism.
+ // Response status indicates whether server is ready.
+ // Request format:
+ // - RequestHeader{}
+ // Response format:
+ // - ResponseHeader{}
+ CmdHeartbeat,
};
// Status represents command execution result, using USB/IP compatible values.
@@ -141,4 +150,4 @@
uint32_t timeout;
} __attribute__((packed));
-} // namespace usb_forward
\ No newline at end of file
+} // namespace usb_forward
diff --git a/guest/usbforward/usb_server.cpp b/guest/usbforward/usb_server.cpp
index 3bc05b4..5720571 100644
--- a/guest/usbforward/usb_server.cpp
+++ b/guest/usbforward/usb_server.cpp
@@ -153,6 +153,14 @@
fd_->Write(&rsp, sizeof(rsp));
}
+void USBServer::HandleHeartbeat(uint32_t tag) {
+ auto handle = GetDevice();
+
+ avd::LockGuard<avd::Mutex> lock(write_mutex_);
+ ResponseHeader rsp{handle ? StatusSuccess : StatusFailure, tag};
+ fd_->Write(&rsp, sizeof(rsp));
+}
+
void USBServer::HandleControlTransfer(uint32_t tag) {
ControlTransfer req;
// If disconnected prematurely, don't send response.
@@ -334,6 +342,11 @@
HandleDataTransfer(req.tag);
break;
+ case CmdHeartbeat:
+ ALOGV("Processing Heartbeat command, tag=%d", req.tag);
+ HandleHeartbeat(req.tag);
+ break;
+
default:
ALOGE("Discarding unknown command %08x, tag=%d", req.command,
req.tag);
@@ -342,4 +355,4 @@
}
}
-} // namespace usb_forward
\ No newline at end of file
+} // namespace usb_forward
diff --git a/guest/usbforward/usb_server.h b/guest/usbforward/usb_server.h
index 397ad1a..843436c 100644
--- a/guest/usbforward/usb_server.h
+++ b/guest/usbforward/usb_server.h
@@ -59,6 +59,9 @@
// Handle CmdDataTransfer request.
void HandleDataTransfer(uint32_t tag);
+ // Handle CmdHeartbeat request.
+ void HandleHeartbeat(uint32_t tag);
+
// OnAsyncDataTransferComplete handles end of asynchronous data transfer cycle
// and sends response back to caller.
void OnTransferComplete(uint32_t tag, bool is_data_in, bool is_success,
@@ -77,4 +80,4 @@
USBServer& operator=(const USBServer& other) = delete;
};
-} // namespace usb_forward
\ No newline at end of file
+} // namespace usb_forward