summaryrefslogtreecommitdiff
path: root/src/input_common/helpers/udp_protocol.cpp
diff options
context:
space:
mode:
authorGravatar german772021-09-20 16:57:55 -0500
committerGravatar Narr the Reg2021-11-24 20:30:22 -0600
commit4c6f2c2547e1d97f12ebe708fac693a6183bbc45 (patch)
tree0abcd35f56088bbf732a92838995a465bae0f0ee /src/input_common/helpers/udp_protocol.cpp
parentinput_common: Create input poller and mapping (diff)
downloadyuzu-4c6f2c2547e1d97f12ebe708fac693a6183bbc45.tar.gz
yuzu-4c6f2c2547e1d97f12ebe708fac693a6183bbc45.tar.xz
yuzu-4c6f2c2547e1d97f12ebe708fac693a6183bbc45.zip
input_common: Move touch and analog from button. Move udp protocol
Diffstat (limited to 'src/input_common/helpers/udp_protocol.cpp')
-rw-r--r--src/input_common/helpers/udp_protocol.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/input_common/helpers/udp_protocol.cpp b/src/input_common/helpers/udp_protocol.cpp
new file mode 100644
index 000000000..cdeab7e11
--- /dev/null
+++ b/src/input_common/helpers/udp_protocol.cpp
@@ -0,0 +1,78 @@
1// Copyright 2018 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <cstddef>
6#include <cstring>
7#include "common/logging/log.h"
8#include "input_common/helpers/udp_protocol.h"
9
10namespace InputCommon::CemuhookUDP {
11
12static constexpr std::size_t GetSizeOfResponseType(Type t) {
13 switch (t) {
14 case Type::Version:
15 return sizeof(Response::Version);
16 case Type::PortInfo:
17 return sizeof(Response::PortInfo);
18 case Type::PadData:
19 return sizeof(Response::PadData);
20 }
21 return 0;
22}
23
24namespace Response {
25
26/**
27 * Returns Type if the packet is valid, else none
28 *
29 * Note: Modifies the buffer to zero out the crc (since thats the easiest way to check without
30 * copying the buffer)
31 */
32std::optional<Type> Validate(u8* data, std::size_t size) {
33 if (size < sizeof(Header)) {
34 return std::nullopt;
35 }
36 Header header{};
37 std::memcpy(&header, data, sizeof(Header));
38 if (header.magic != SERVER_MAGIC) {
39 LOG_ERROR(Input, "UDP Packet has an unexpected magic value");
40 return std::nullopt;
41 }
42 if (header.protocol_version != PROTOCOL_VERSION) {
43 LOG_ERROR(Input, "UDP Packet protocol mismatch");
44 return std::nullopt;
45 }
46 if (header.type < Type::Version || header.type > Type::PadData) {
47 LOG_ERROR(Input, "UDP Packet is an unknown type");
48 return std::nullopt;
49 }
50
51 // Packet size must equal sizeof(Header) + sizeof(Data)
52 // and also verify that the packet info mentions the correct size. Since the spec includes the
53 // type of the packet as part of the data, we need to include it in size calculations here
54 // ie: payload_length == sizeof(T) + sizeof(Type)
55 const std::size_t data_len = GetSizeOfResponseType(header.type);
56 if (header.payload_length != data_len + sizeof(Type) || size < data_len + sizeof(Header)) {
57 LOG_ERROR(
58 Input,
59 "UDP Packet payload length doesn't match. Received: {} PayloadLength: {} Expected: {}",
60 size, header.payload_length, data_len + sizeof(Type));
61 return std::nullopt;
62 }
63
64 const u32 crc32 = header.crc;
65 boost::crc_32_type result;
66 // zero out the crc in the buffer and then run the crc against it
67 std::memset(&data[offsetof(Header, crc)], 0, sizeof(u32_le));
68
69 result.process_bytes(data, data_len + sizeof(Header));
70 if (crc32 != result.checksum()) {
71 LOG_ERROR(Input, "UDP Packet CRC check failed. Offset: {}", offsetof(Header, crc));
72 return std::nullopt;
73 }
74 return header.type;
75}
76} // namespace Response
77
78} // namespace InputCommon::CemuhookUDP