blob: c39932c126ef193ac1f83d7dea09db99ea0787e4 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "usbip.h"
#include <cinttypes>
#include <utility>
#include "device_descriptors.h"
#include "server.h"
#include "smart_buffer.h"
#include "usb_printer.h"
#include "usbip_constants.h"
void PackUsbip(int* data, size_t msg_size) {
int size = msg_size / 4;
for (int i = 0; i < size; i++) {
data[i] = htonl(data[i]);
}
// Put |setup| into network byte order. Since |setup| is a 64-bit integer we
// have to swap the final 2 int entries since they are both a part of |setup|.
std::swap(data[size - 1], data[size - 2]);
}
void UnpackUsbip(int* data, size_t msg_size) {
int size = msg_size / 4;
for (int i = 0; i < size; i++) {
data[i] = ntohl(data[i]);
}
// Put |setup| into host byte order. Since |setup| is a 64-bit integer we
// have to swap the final 2 int entries since they are both a part of |setup|.
std::swap(data[size - 1], data[size - 2]);
}
void PrintUsbipHeaderBasic(const UsbipHeaderBasic& header) {
printf("usbip cmd %u\n", header.command);
printf("usbip seqnum %u\n", header.seqnum);
printf("usbip devid %u\n", header.devid);
printf("usbip direction %u\n", header.direction);
printf("usbip ep %u\n", header.ep);
}
void PrintUsbipCmdSubmit(const UsbipCmdSubmit& command) {
PrintUsbipHeaderBasic(command.header);
printf("usbip flags %u\n", command.transfer_flags);
printf("usbip number of packets %u\n", command.number_of_packets);
printf("usbip interval %u\n", command.interval);
printf("usbip setup %" PRIu64 "\n", command.setup);
printf("usbip buffer length %u\n", command.transfer_buffer_length);
}
void PrintUsbipRetSubmit(const UsbipRetSubmit& response) {
PrintUsbipHeaderBasic(response.header);
printf("usbip status %u\n", response.status);
printf("usbip actual_length %u\n", response.actual_length);
printf("usbip start_frame %u\n", response.start_frame);
printf("usbip number_of_packets %u\n", response.number_of_packets);
printf("usbip error_count %u\n", response.error_count);
}
void PrintUsbControlRequest(const UsbControlRequest& request) {
printf(" UC Request Type %u\n", request.bmRequestType);
printf(" UC Request %u\n", request.bRequest);
printf(" UC Value %u[%u]\n", request.wValue1, request.wValue0);
printf(" UC Index %u-%u\n", request.wIndex1, request.wIndex0);
printf(" UC Length %u\n", request.wLength);
}
UsbipRetSubmit CreateUsbipRetSubmit(const UsbipCmdSubmit& request) {
UsbipRetSubmit response;
memset(&response, 0, sizeof(response));
response.header.command = COMMAND_USBIP_RET_SUBMIT;
response.header.seqnum = request.header.seqnum;
response.header.devid = request.header.devid;
response.header.direction = request.header.direction;
response.header.ep = request.header.ep;
return response;
}
void SendUsbDataResponse(int sockfd, const UsbipCmdSubmit& usb_request,
size_t received) {
UsbipRetSubmit response = CreateUsbipRetSubmit(usb_request);
response.actual_length = received;
PrintUsbipRetSubmit(response);
size_t response_size = sizeof(response);
PackUsbip(reinterpret_cast<int*>(&response), response_size);
SmartBuffer smart_buffer(response_size);
smart_buffer.Add(&response, response_size);
SendBuffer(sockfd, smart_buffer);
}
void SendUsbControlResponse(int sockfd, const UsbipCmdSubmit& usb_request,
const uint8_t* data, size_t data_size) {
UsbipRetSubmit response = CreateUsbipRetSubmit(usb_request);
response.actual_length = data_size;
PrintUsbipRetSubmit(response);
size_t response_size = sizeof(response);
PackUsbip(reinterpret_cast<int*>(&response), response_size);
SmartBuffer smart_buffer(response_size);
smart_buffer.Add(&response, response_size);
if (data_size > 0) {
smart_buffer.Add(data, data_size);
}
SendBuffer(sockfd, smart_buffer);
}