1 // Copyright (C) 2014 Michael McMaster <michael@codesrc.com>
3 // This file is part of SCSI2SD.
5 // SCSI2SD is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // SCSI2SD is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
18 #include "hidpacket.h"
21 enum STATE { IDLE, PARTIAL, COMPLETE };
24 uint8_t buffer[HIDPACKET_MAX_LEN];
28 size_t offset; // Current offset into buffer.
30 static HIDPacketState rx __attribute__((aligned(USBHID_LEN))) = {{}, IDLE, 0, 0};
31 static HIDPacketState tx __attribute__((aligned(USBHID_LEN))) = {{}, IDLE, 0, 0};
49 void hidPacket_recv(const uint8_t* bytes, size_t len)
53 // Invalid. We need at least a chunk number and payload length.
58 uint8_t chunk = bytes[0] & 0x7F;
59 int final = bytes[0] & 0x80;
60 uint8_t payloadLen = bytes[1];
61 if ((payloadLen > (len - 2)) || // short packet
62 (payloadLen + rx.offset > sizeof(rx.buffer))) // buffer overflow
72 memcpy(rx.buffer, bytes + 2, payloadLen);
73 rx.offset = payloadLen;
76 else if ((rx.state == PARTIAL) && (chunk == rx.chunk + 1))
78 memcpy(rx.buffer + rx.offset, bytes + 2, payloadLen);
79 rx.offset += payloadLen;
82 else if (chunk == rx.chunk)
84 // duplicated packet. ignore.
88 // invalid. Maybe we missed some data.
92 if ((rx.state == PARTIAL) && final)
99 hidPacket_getPacket(size_t* len)
101 if (rx.state == COMPLETE)
114 void hidPacket_send(const uint8_t* bytes, size_t len)
116 if (len <= sizeof(tx.buffer))
121 memcpy(tx.buffer, bytes, len);
130 hidPacket_getHIDBytes(uint8_t* hidBuffer)
132 if ((tx.state != PARTIAL) || (tx.offset <= 0))
137 hidBuffer[0] = tx.chunk;
140 if (tx.offset <= USBHID_LEN - 2)
142 hidBuffer[0] = hidBuffer[0] | 0x80;
145 memset(hidBuffer + 2, 0, USBHID_LEN - 2);
149 payload = USBHID_LEN - 2;
152 tx.offset -= payload;
153 hidBuffer[1] = payload;
154 memcpy(hidBuffer + 2, tx.buffer, payload);
155 memmove(tx.buffer, tx.buffer + payload, sizeof(tx.buffer) - payload);