mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-11-12 14:57:20 +00:00
[common] network: use LGProtocol codecs
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "interface/transport.h"
|
||||
|
||||
#include "common/network/protocol.h"
|
||||
#include <LGProtocol/NetworkProtocol.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "common/debug.h"
|
||||
#include "common/event.h"
|
||||
#include "common/locking.h"
|
||||
#include "common/network/protocol.h"
|
||||
#include <LGProtocol/NetworkProtocol.h>
|
||||
#include "common/option.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -45,16 +45,13 @@ set(COMMON_SOURCES
|
||||
src/cpuinfo.c
|
||||
src/debug.c
|
||||
src/ll.c
|
||||
src/network/protocol.c
|
||||
src/network/services.c
|
||||
src/network/wire.c
|
||||
)
|
||||
|
||||
add_library(lg_common STATIC ${COMMON_SOURCES})
|
||||
target_link_libraries(lg_common
|
||||
PUBLIC
|
||||
lg_common_platform
|
||||
LGProtocol::LGProtocol
|
||||
LGProtocol::Network
|
||||
)
|
||||
|
||||
if(ENABLE_BACKTRACE)
|
||||
|
||||
@@ -1,488 +0,0 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _H_LG_COMMON_NETWORK_PROTOCOL_
|
||||
#define _H_LG_COMMON_NETWORK_PROTOCOL_
|
||||
|
||||
#include "common/network/wire.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Encoded as the byte sequence "LGNW" by the little-endian wire writer. */
|
||||
#define LG_NET_WIRE_MAGIC UINT32_C(0x574E474C)
|
||||
#define LG_NET_WIRE_VERSION_MAJOR 1U
|
||||
#define LG_NET_WIRE_VERSION_MINOR 0U
|
||||
#define LG_NET_ENVELOPE_WIRE_SIZE 64U
|
||||
#define LG_NET_MAX_PAYLOAD_LENGTH (64U * 1024U * 1024U)
|
||||
#define LG_NET_MESSAGE_VERSION_CURRENT 1U
|
||||
#define LG_NET_MESSAGE_VERSION_INITIAL 1U
|
||||
#define LG_NET_PROTOCOL_VERSION_CURRENT 1U
|
||||
#define LG_NET_PROTOCOL_VERSION_MIN 1U
|
||||
#define LG_NET_PROTOCOL_VERSION_MAX LG_NET_PROTOCOL_VERSION_CURRENT
|
||||
#define LG_NET_MAX_CAPABILITY_RECORDS 64U
|
||||
#define LG_NET_HELLO_NONCE_LENGTH 32U
|
||||
#define LG_NET_PASSWORD_SALT_MAX_LENGTH 64U
|
||||
#define LG_NET_PASSWORD_CHALLENGE_MAX_LENGTH 64U
|
||||
#define LG_NET_PASSWORD_NONCE_MAX_LENGTH 64U
|
||||
#define LG_NET_PASSWORD_PROOF_MAX_LENGTH 64U
|
||||
/* 19527 is 0x4c47 (ASCII "LG") and is currently IANA-unassigned. */
|
||||
#define LG_NET_DEFAULT_PORT 19527U
|
||||
#define LG_NET_ALPN "looking-glass/1"
|
||||
#define LG_NET_ALPN_LENGTH (sizeof(LG_NET_ALPN) - 1U)
|
||||
|
||||
#define LG_NET_CORE_VERSION_CURRENT 1U
|
||||
#define LG_NET_CORE_VERSION_MIN 1U
|
||||
#define LG_NET_CORE_VERSION_MAX LG_NET_CORE_VERSION_CURRENT
|
||||
#define LG_NET_RECOVERY_VERSION_CURRENT 1U
|
||||
#define LG_NET_RECOVERY_VERSION_MIN 1U
|
||||
#define LG_NET_RECOVERY_VERSION_MAX LG_NET_RECOVERY_VERSION_CURRENT
|
||||
#define LG_NET_VIDEO_VERSION_CURRENT 1U
|
||||
#define LG_NET_VIDEO_VERSION_MIN 1U
|
||||
#define LG_NET_VIDEO_VERSION_MAX LG_NET_VIDEO_VERSION_CURRENT
|
||||
#define LG_NET_CURSOR_VERSION_CURRENT 1U
|
||||
#define LG_NET_CURSOR_VERSION_MIN 1U
|
||||
#define LG_NET_CURSOR_VERSION_MAX LG_NET_CURSOR_VERSION_CURRENT
|
||||
#define LG_NET_INPUT_VERSION_CURRENT 1U
|
||||
#define LG_NET_INPUT_VERSION_MIN 1U
|
||||
#define LG_NET_INPUT_VERSION_MAX LG_NET_INPUT_VERSION_CURRENT
|
||||
#define LG_NET_AUDIO_VERSION_CURRENT 1U
|
||||
#define LG_NET_AUDIO_VERSION_MIN 1U
|
||||
#define LG_NET_AUDIO_VERSION_MAX LG_NET_AUDIO_VERSION_CURRENT
|
||||
#define LG_NET_CLIPBOARD_VERSION_CURRENT 1U
|
||||
#define LG_NET_CLIPBOARD_VERSION_MIN 1U
|
||||
#define LG_NET_CLIPBOARD_VERSION_MAX LG_NET_CLIPBOARD_VERSION_CURRENT
|
||||
#define LG_NET_FILE_VERSION_CURRENT 1U
|
||||
#define LG_NET_FILE_VERSION_MIN 1U
|
||||
#define LG_NET_FILE_VERSION_MAX LG_NET_FILE_VERSION_CURRENT
|
||||
/* Reserved now so a future USB implementation cannot collide with a service. */
|
||||
#define LG_NET_USB_VERSION_RESERVED 1U
|
||||
|
||||
typedef uint16_t LGNetService;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_SERVICE_CORE = 1,
|
||||
LG_NET_SERVICE_RECOVERY = 2,
|
||||
LG_NET_SERVICE_VIDEO = 3,
|
||||
LG_NET_SERVICE_CURSOR = 4,
|
||||
LG_NET_SERVICE_INPUT = 5,
|
||||
LG_NET_SERVICE_AUDIO = 6,
|
||||
LG_NET_SERVICE_CLIPBOARD = 7,
|
||||
LG_NET_SERVICE_FILE = 8,
|
||||
LG_NET_SERVICE_USB = 9,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetCoreMessage;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CORE_MESSAGE_HELLO = 1,
|
||||
LG_NET_CORE_MESSAGE_HELLO_ACK = 2,
|
||||
LG_NET_CORE_MESSAGE_AUTH_CHALLENGE = 3,
|
||||
LG_NET_CORE_MESSAGE_AUTH_RESPONSE = 4,
|
||||
LG_NET_CORE_MESSAGE_AUTH_RESULT = 5,
|
||||
LG_NET_CORE_MESSAGE_CAPABILITY = 6,
|
||||
LG_NET_CORE_MESSAGE_CAPABILITIES_DONE = 7,
|
||||
LG_NET_CORE_MESSAGE_SESSION_INFO = 8,
|
||||
LG_NET_CORE_MESSAGE_STATUS = 9,
|
||||
LG_NET_CORE_MESSAGE_PING = 10,
|
||||
LG_NET_CORE_MESSAGE_PONG = 11,
|
||||
LG_NET_CORE_MESSAGE_GOODBYE = 12,
|
||||
LG_NET_CORE_MESSAGE_ERROR = 13,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetRecoveryMessage;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_RECOVERY_MESSAGE_GET_INFO = 1,
|
||||
LG_NET_RECOVERY_MESSAGE_INFO = 2,
|
||||
LG_NET_RECOVERY_MESSAGE_REQUEST = 3,
|
||||
LG_NET_RECOVERY_MESSAGE_STATUS = 4,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetVideoMessage;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_VIDEO_MESSAGE_SUBSCRIBE = 1,
|
||||
LG_NET_VIDEO_MESSAGE_UNSUBSCRIBE = 2,
|
||||
LG_NET_VIDEO_MESSAGE_STREAM_CONFIG = 3,
|
||||
LG_NET_VIDEO_MESSAGE_FRAME = 4,
|
||||
LG_NET_VIDEO_MESSAGE_FRAME_FRAGMENT = 5,
|
||||
LG_NET_VIDEO_MESSAGE_KEYFRAME_REQUEST = 6,
|
||||
LG_NET_VIDEO_MESSAGE_SCHEDULE = 7,
|
||||
LG_NET_VIDEO_MESSAGE_FEEDBACK = 8,
|
||||
LG_NET_VIDEO_MESSAGE_STATUS = 9,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetCursorMessage;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CURSOR_MESSAGE_STATE = 1,
|
||||
LG_NET_CURSOR_MESSAGE_POSITION = 2,
|
||||
LG_NET_CURSOR_MESSAGE_SHAPE = 3,
|
||||
LG_NET_CURSOR_MESSAGE_TRANSFORM = 4,
|
||||
LG_NET_CURSOR_MESSAGE_STATUS = 5,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetInputMessage;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_INPUT_MESSAGE_CLAIM = 1,
|
||||
LG_NET_INPUT_MESSAGE_CLAIM_RESULT = 2,
|
||||
LG_NET_INPUT_MESSAGE_KEEPALIVE = 3,
|
||||
LG_NET_INPUT_MESSAGE_RELEASE = 4,
|
||||
LG_NET_INPUT_MESSAGE_RESET = 5,
|
||||
LG_NET_INPUT_MESSAGE_MOUSE_RELATIVE = 6,
|
||||
LG_NET_INPUT_MESSAGE_MOUSE_ABSOLUTE = 7,
|
||||
LG_NET_INPUT_MESSAGE_KEYBOARD = 8,
|
||||
LG_NET_INPUT_MESSAGE_STATUS = 9,
|
||||
LG_NET_INPUT_MESSAGE_KEYBOARD_LEDS = 10,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetAudioMessage;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_AUDIO_MESSAGE_SUBSCRIBE = 1,
|
||||
LG_NET_AUDIO_MESSAGE_STATUS = 2,
|
||||
LG_NET_AUDIO_MESSAGE_PLAYBACK_START = 3,
|
||||
LG_NET_AUDIO_MESSAGE_PLAYBACK_STOP = 4,
|
||||
LG_NET_AUDIO_MESSAGE_PLAYBACK_DATA = 5,
|
||||
LG_NET_AUDIO_MESSAGE_PLAYBACK_VOLUME = 6,
|
||||
LG_NET_AUDIO_MESSAGE_PLAYBACK_MUTE = 7,
|
||||
LG_NET_AUDIO_MESSAGE_CAPTURE_START = 8,
|
||||
LG_NET_AUDIO_MESSAGE_CAPTURE_STOP = 9,
|
||||
LG_NET_AUDIO_MESSAGE_CAPTURE_DATA = 10,
|
||||
LG_NET_AUDIO_MESSAGE_CAPTURE_VOLUME = 11,
|
||||
LG_NET_AUDIO_MESSAGE_CAPTURE_MUTE = 12,
|
||||
LG_NET_AUDIO_MESSAGE_CLOCK_FEEDBACK = 13,
|
||||
LG_NET_AUDIO_MESSAGE_KEEPALIVE = 14,
|
||||
LG_NET_AUDIO_MESSAGE_RELEASE = 15,
|
||||
LG_NET_AUDIO_MESSAGE_STATE_BARRIER = 16,
|
||||
LG_NET_AUDIO_MESSAGE_STATE_ACK = 17,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetClipboardMessage;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CLIPBOARD_MESSAGE_CLAIM = 1,
|
||||
LG_NET_CLIPBOARD_MESSAGE_CLAIM_RESULT = 2,
|
||||
LG_NET_CLIPBOARD_MESSAGE_KEEPALIVE = 3,
|
||||
LG_NET_CLIPBOARD_MESSAGE_RELEASE = 4,
|
||||
LG_NET_CLIPBOARD_MESSAGE_OFFER = 5,
|
||||
LG_NET_CLIPBOARD_MESSAGE_CLEAR = 6,
|
||||
LG_NET_CLIPBOARD_MESSAGE_REQUEST = 7,
|
||||
LG_NET_CLIPBOARD_MESSAGE_DATA_BEGIN = 8,
|
||||
LG_NET_CLIPBOARD_MESSAGE_DATA_CHUNK = 9,
|
||||
LG_NET_CLIPBOARD_MESSAGE_DATA_END = 10,
|
||||
LG_NET_CLIPBOARD_MESSAGE_DATA_READY = 11,
|
||||
LG_NET_CLIPBOARD_MESSAGE_CANCEL = 12,
|
||||
LG_NET_CLIPBOARD_MESSAGE_STATUS = 13,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetFileMessage;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_FILE_MESSAGE_OFFER = 1,
|
||||
LG_NET_FILE_MESSAGE_ACQUIRE = 2,
|
||||
LG_NET_FILE_MESSAGE_ACQUIRED = 3,
|
||||
LG_NET_FILE_MESSAGE_RELEASE = 4,
|
||||
LG_NET_FILE_MESSAGE_REQUEST = 5,
|
||||
LG_NET_FILE_MESSAGE_ENTRY = 6,
|
||||
LG_NET_FILE_MESSAGE_DATA_BEGIN = 7,
|
||||
LG_NET_FILE_MESSAGE_DATA_CHUNK = 8,
|
||||
LG_NET_FILE_MESSAGE_DATA_END = 9,
|
||||
LG_NET_FILE_MESSAGE_DATA_READY = 10,
|
||||
LG_NET_FILE_MESSAGE_CANCEL = 11,
|
||||
LG_NET_FILE_MESSAGE_STATUS = 12,
|
||||
};
|
||||
|
||||
/* Message IDs are reserved for the future USB service; their payloads are not
|
||||
* defined by this protocol version. */
|
||||
typedef uint16_t LGNetUSBMessage;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_USB_MESSAGE_CAPABILITIES = 1,
|
||||
LG_NET_USB_MESSAGE_DEVICE = 2,
|
||||
LG_NET_USB_MESSAGE_CLAIM = 3,
|
||||
LG_NET_USB_MESSAGE_CONTROL = 4,
|
||||
LG_NET_USB_MESSAGE_ENDPOINT = 5,
|
||||
LG_NET_USB_MESSAGE_CANCEL = 6,
|
||||
LG_NET_USB_MESSAGE_RESET = 7,
|
||||
LG_NET_USB_MESSAGE_STATUS = 8,
|
||||
};
|
||||
|
||||
typedef uint32_t LGNetEnvelopeFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_ENVELOPE_RESPONSE = 1U << 0,
|
||||
LG_NET_ENVELOPE_FINAL = 1U << 1,
|
||||
LG_NET_ENVELOPE_RELIABLE = 1U << 2,
|
||||
LG_NET_ENVELOPE_DATAGRAM = 1U << 3,
|
||||
LG_NET_ENVELOPE_ACK_REQUIRED = 1U << 4,
|
||||
LG_NET_ENVELOPE_ERROR = 1U << 5,
|
||||
LG_NET_ENVELOPE_EARLY_DATA = 1U << 6,
|
||||
};
|
||||
|
||||
typedef struct LGNetEnvelope
|
||||
{
|
||||
uint16_t wireMajor;
|
||||
uint16_t wireMinor;
|
||||
uint16_t headerSize;
|
||||
LGNetService service;
|
||||
uint16_t messageType;
|
||||
uint16_t serviceVersion;
|
||||
uint16_t messageVersion;
|
||||
LGNetEnvelopeFlags flags;
|
||||
uint32_t payloadLength;
|
||||
uint64_t sessionEpoch;
|
||||
uint64_t componentEpoch;
|
||||
uint64_t sequence;
|
||||
uint64_t requestID;
|
||||
}
|
||||
LGNetEnvelope;
|
||||
|
||||
typedef struct LGNetPacketView
|
||||
{
|
||||
LGNetEnvelope envelope;
|
||||
const uint8_t * payload;
|
||||
size_t payloadLength;
|
||||
size_t wireSize;
|
||||
}
|
||||
LGNetPacketView;
|
||||
|
||||
typedef uint16_t LGNetRole;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_ROLE_CLIENT = 1,
|
||||
LG_NET_ROLE_SERVER = 2,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetAuthMode;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_AUTH_NONE = 0,
|
||||
LG_NET_AUTH_PASSWORD = 1,
|
||||
};
|
||||
|
||||
#define LG_NET_AUTH_MODE_FLAG(mode) (UINT32_C(1) << (mode))
|
||||
#define LG_NET_AUTH_MODE_DEFAULT LG_NET_AUTH_NONE
|
||||
#define LG_NET_AUTH_MODES_DEFAULT LG_NET_AUTH_MODE_FLAG(LG_NET_AUTH_NONE)
|
||||
#define LG_NET_AUTH_MODES_KNOWN \
|
||||
(LG_NET_AUTH_MODE_FLAG(LG_NET_AUTH_NONE) | \
|
||||
LG_NET_AUTH_MODE_FLAG(LG_NET_AUTH_PASSWORD))
|
||||
|
||||
typedef struct LGNetHello
|
||||
{
|
||||
LGNetRole role;
|
||||
uint16_t protocolMin;
|
||||
uint16_t protocolMax;
|
||||
uint32_t authModes;
|
||||
uint32_t maxPayloadLength;
|
||||
uint32_t maxDatagramPayload;
|
||||
uint32_t capabilityCount;
|
||||
uint8_t nonce[LG_NET_HELLO_NONCE_LENGTH];
|
||||
}
|
||||
LGNetHello;
|
||||
|
||||
typedef uint32_t LGNetHelloAckFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_HELLO_ACK_RESUMED = 1U << 0,
|
||||
};
|
||||
|
||||
typedef struct LGNetHelloAck
|
||||
{
|
||||
uint16_t protocolVersion;
|
||||
LGNetAuthMode authMode;
|
||||
LGNetHelloAckFlags flags;
|
||||
uint32_t maxPayloadLength;
|
||||
uint32_t maxDatagramPayload;
|
||||
uint32_t capabilityCount;
|
||||
uint64_t sessionEpoch;
|
||||
uint8_t nonce[LG_NET_HELLO_NONCE_LENGTH];
|
||||
}
|
||||
LGNetHelloAck;
|
||||
|
||||
#define LG_NET_HELLO_WIRE_SIZE 56U
|
||||
#define LG_NET_HELLO_ACK_WIRE_SIZE 64U
|
||||
|
||||
typedef uint16_t LGNetCapabilityFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CAPABILITY_REQUIRED = 1U << 0,
|
||||
LG_NET_CAPABILITY_SELECTED = 1U << 1,
|
||||
LG_NET_CAPABILITY_RELIABLE = 1U << 2,
|
||||
LG_NET_CAPABILITY_DATAGRAM = 1U << 3,
|
||||
LG_NET_CAPABILITY_BULK = 1U << 4,
|
||||
LG_NET_CAPABILITY_MULTI_CLIENT = 1U << 5,
|
||||
};
|
||||
|
||||
typedef struct LGNetCapability
|
||||
{
|
||||
LGNetService service;
|
||||
uint16_t versionMin;
|
||||
uint16_t versionMax;
|
||||
LGNetCapabilityFlags flags;
|
||||
uint64_t features;
|
||||
uint32_t maxPayloadLength;
|
||||
uint32_t maxDatagramPayload;
|
||||
uint16_t maxBidirectionalStreams;
|
||||
uint16_t maxUnidirectionalStreams;
|
||||
}
|
||||
LGNetCapability;
|
||||
|
||||
#define LG_NET_CAPABILITY_WIRE_SIZE 32U
|
||||
|
||||
/* Password proofs are carried by this library but derived by the application.
|
||||
* A password must never be sent on the wire. The negotiated algorithm defines
|
||||
* the proof and transcript binding; cryptography is outside this wire codec. */
|
||||
typedef uint16_t LGNetPasswordAlgorithm;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_PASSWORD_PBKDF2_HMAC_SHA256 = 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetPasswordChallenge
|
||||
{
|
||||
LGNetPasswordAlgorithm algorithm;
|
||||
uint32_t rounds;
|
||||
uint16_t saltLength;
|
||||
uint16_t challengeLength;
|
||||
uint8_t salt [LG_NET_PASSWORD_SALT_MAX_LENGTH];
|
||||
uint8_t challenge[LG_NET_PASSWORD_CHALLENGE_MAX_LENGTH];
|
||||
}
|
||||
LGNetPasswordChallenge;
|
||||
|
||||
typedef struct LGNetPasswordResponse
|
||||
{
|
||||
LGNetPasswordAlgorithm algorithm;
|
||||
uint16_t nonceLength;
|
||||
uint16_t proofLength;
|
||||
uint8_t nonce[LG_NET_PASSWORD_NONCE_MAX_LENGTH];
|
||||
uint8_t proof[LG_NET_PASSWORD_PROOF_MAX_LENGTH];
|
||||
}
|
||||
LGNetPasswordResponse;
|
||||
|
||||
typedef uint16_t LGNetAuthResultCode;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_AUTH_RESULT_ACCEPTED = 1,
|
||||
LG_NET_AUTH_RESULT_REJECTED = 2,
|
||||
LG_NET_AUTH_RESULT_UNSUPPORTED = 3,
|
||||
LG_NET_AUTH_RESULT_ERROR = 4,
|
||||
};
|
||||
|
||||
typedef struct LGNetAuthResult
|
||||
{
|
||||
LGNetAuthResultCode result;
|
||||
uint16_t proofLength;
|
||||
uint32_t retryAfterMs;
|
||||
uint8_t proof[LG_NET_PASSWORD_PROOF_MAX_LENGTH];
|
||||
}
|
||||
LGNetAuthResult;
|
||||
|
||||
#define LG_NET_PASSWORD_CHALLENGE_HEADER_SIZE 16U
|
||||
#define LG_NET_PASSWORD_RESPONSE_HEADER_SIZE 12U
|
||||
#define LG_NET_AUTH_RESULT_HEADER_SIZE 12U
|
||||
|
||||
void lgNetEnvelopeInit(LGNetEnvelope * envelope, LGNetService service,
|
||||
uint16_t messageType, uint16_t serviceVersion,
|
||||
uint16_t messageVersion);
|
||||
bool lgNetEnvelopeEncode(void * data, size_t size,
|
||||
const LGNetEnvelope * envelope);
|
||||
LGNetParseResult lgNetEnvelopeDecode(LGNetEnvelope * envelope,
|
||||
const void * data, size_t size);
|
||||
bool lgNetPacketSize(const LGNetEnvelope * envelope, size_t * size);
|
||||
bool lgNetPacketEncode(void * data, size_t size,
|
||||
const LGNetEnvelope * envelope, const void * payload);
|
||||
LGNetParseResult lgNetPacketDecode(LGNetPacketView * packet,
|
||||
const void * data, size_t size);
|
||||
|
||||
bool lgNetServiceKnown(LGNetService service);
|
||||
bool lgNetMessageKnown(LGNetService service, uint16_t messageType);
|
||||
|
||||
void lgNetHelloInit(LGNetHello * hello, LGNetRole role);
|
||||
bool lgNetHelloValid(const LGNetHello * hello);
|
||||
bool lgNetHelloEncode(void * data, size_t size, const LGNetHello * hello);
|
||||
LGNetParseResult lgNetHelloDecode(LGNetHello * hello,
|
||||
const void * data, size_t size);
|
||||
|
||||
void lgNetHelloAckInit(LGNetHelloAck * hello, uint64_t sessionEpoch);
|
||||
bool lgNetHelloAckValid(const LGNetHelloAck * hello);
|
||||
bool lgNetHelloAckEncode(
|
||||
void * data, size_t size, const LGNetHelloAck * hello);
|
||||
LGNetParseResult lgNetHelloAckDecode(LGNetHelloAck * hello,
|
||||
const void * data, size_t size);
|
||||
|
||||
bool lgNetCapabilityValid(const LGNetCapability * capability);
|
||||
bool lgNetCapabilityEncode(void * data, size_t size,
|
||||
const LGNetCapability * capability);
|
||||
LGNetParseResult lgNetCapabilityDecode(LGNetCapability * capability,
|
||||
const void * data, size_t size);
|
||||
|
||||
size_t lgNetPasswordChallengeSize(
|
||||
const LGNetPasswordChallenge * challenge);
|
||||
bool lgNetPasswordChallengeValid(
|
||||
const LGNetPasswordChallenge * challenge);
|
||||
bool lgNetPasswordChallengeEncode(void * data, size_t size,
|
||||
const LGNetPasswordChallenge * challenge);
|
||||
LGNetParseResult lgNetPasswordChallengeDecode(
|
||||
LGNetPasswordChallenge * challenge, const void * data, size_t size);
|
||||
|
||||
size_t lgNetPasswordResponseSize(const LGNetPasswordResponse * response);
|
||||
bool lgNetPasswordResponseValid(const LGNetPasswordResponse * response);
|
||||
bool lgNetPasswordResponseEncode(void * data, size_t size,
|
||||
const LGNetPasswordResponse * response);
|
||||
LGNetParseResult lgNetPasswordResponseDecode(
|
||||
LGNetPasswordResponse * response, const void * data, size_t size);
|
||||
|
||||
size_t lgNetAuthResultSize(const LGNetAuthResult * result);
|
||||
bool lgNetAuthResultValid(const LGNetAuthResult * result);
|
||||
bool lgNetAuthResultEncode(
|
||||
void * data, size_t size, const LGNetAuthResult * result);
|
||||
LGNetParseResult lgNetAuthResultDecode(LGNetAuthResult * result,
|
||||
const void * data, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,994 +0,0 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _H_LG_COMMON_NETWORK_SERVICES_
|
||||
#define _H_LG_COMMON_NETWORK_SERVICES_
|
||||
|
||||
#include "common/network/protocol.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Variable-length decoders return borrowed views into their input buffer. The
|
||||
* caller must keep that buffer alive while using the decoded payload. */
|
||||
|
||||
/* Fixed boundaries must not move when a service's current version changes. */
|
||||
#define LG_NET_VIDEO_PYROWAVE_INTRODUCED_SERVICE_VERSION 1U
|
||||
#define LG_NET_CURSOR_SHAPE_INTRODUCED_SERVICE_VERSION 1U
|
||||
#define LG_NET_INPUT_LEDS_INTRODUCED_SERVICE_VERSION 1U
|
||||
#define LG_NET_AUDIO_PCM_INTRODUCED_SERVICE_VERSION 1U
|
||||
#define LG_NET_CLIPBOARD_CHUNK_INTRODUCED_SERVICE_VERSION 1U
|
||||
#define LG_NET_FILE_CHUNK_INTRODUCED_SERVICE_VERSION 1U
|
||||
#define LG_NET_USB_RESERVED_INTRODUCED_SERVICE_VERSION 1U
|
||||
|
||||
#define LG_NET_VIDEO_MAX_WIDTH 32768U
|
||||
#define LG_NET_VIDEO_MAX_HEIGHT 32768U
|
||||
#define LG_NET_VIDEO_MAX_PLANES 4U
|
||||
#define LG_NET_VIDEO_STREAM_CONFIG_WIRE_SIZE 60U
|
||||
#define LG_NET_VIDEO_FRAME_HEADER_WIRE_SIZE 56U
|
||||
#define LG_NET_VIDEO_FRAGMENT_HEADER_WIRE_SIZE 40U
|
||||
#define LG_NET_VIDEO_FEEDBACK_WIRE_SIZE 56U
|
||||
#define LG_NET_VIDEO_MAX_FRAME_LENGTH \
|
||||
(LG_NET_MAX_PAYLOAD_LENGTH - LG_NET_VIDEO_FRAME_HEADER_WIRE_SIZE)
|
||||
#define LG_NET_VIDEO_MAX_FRAGMENT_LENGTH 65535U
|
||||
#define LG_NET_VIDEO_MAX_FRAGMENTS 65535U
|
||||
#define LG_NET_VIDEO_MAX_BLOCKS 65535U
|
||||
|
||||
#define LG_NET_CURSOR_MAX_WIDTH 4096U
|
||||
#define LG_NET_CURSOR_MAX_HEIGHT 4096U
|
||||
#define LG_NET_CURSOR_MAX_SHAPE_LENGTH (16U * 1024U * 1024U)
|
||||
#define LG_NET_CURSOR_POSITION_WIRE_SIZE 40U
|
||||
#define LG_NET_CURSOR_SHAPE_HEADER_WIRE_SIZE 40U
|
||||
|
||||
#define LG_NET_INPUT_CLAIM_WIRE_SIZE 24U
|
||||
#define LG_NET_INPUT_STATUS_WIRE_SIZE 32U
|
||||
#define LG_NET_INPUT_RELATIVE_WIRE_SIZE 40U
|
||||
#define LG_NET_INPUT_ABSOLUTE_WIRE_SIZE 48U
|
||||
#define LG_NET_INPUT_KEYBOARD_WIRE_SIZE 32U
|
||||
#define LG_NET_INPUT_LEDS_WIRE_SIZE 16U
|
||||
#define LG_NET_INPUT_ABSOLUTE_MAX_WIDTH 32768U
|
||||
#define LG_NET_INPUT_ABSOLUTE_MAX_HEIGHT 32768U
|
||||
#define LG_NET_INPUT_KEYBOARD_MODIFIER_MASK UINT32_C(0x000000FF)
|
||||
|
||||
#define LG_NET_AUDIO_MAX_CHANNELS 32U
|
||||
#define LG_NET_AUDIO_MAX_SAMPLE_RATE 768000U
|
||||
#define LG_NET_AUDIO_MAX_PACKET_FRAMES 16384U
|
||||
#define LG_NET_AUDIO_MAX_DATA_LENGTH (4U * 1024U * 1024U)
|
||||
#define LG_NET_AUDIO_FORMAT_WIRE_SIZE 40U
|
||||
#define LG_NET_AUDIO_DATA_HEADER_WIRE_SIZE 48U
|
||||
#define LG_NET_AUDIO_STATE_WIRE_SIZE 32U
|
||||
#define LG_NET_AUDIO_CLOCK_FEEDBACK_WIRE_SIZE 48U
|
||||
|
||||
#define LG_NET_CLIPBOARD_MAX_MIME_LENGTH 255U
|
||||
#define LG_NET_CLIPBOARD_MAX_FORMATS 256U
|
||||
#define LG_NET_CLIPBOARD_MAX_CHUNK_LENGTH (4U * 1024U * 1024U)
|
||||
#define LG_NET_CLIPBOARD_CLAIM_WIRE_SIZE 24U
|
||||
#define LG_NET_CLIPBOARD_OFFER_HEADER_WIRE_SIZE 40U
|
||||
#define LG_NET_CLIPBOARD_REQUEST_WIRE_SIZE 32U
|
||||
#define LG_NET_CLIPBOARD_CHUNK_HEADER_WIRE_SIZE 40U
|
||||
#define LG_NET_CLIPBOARD_STATUS_WIRE_SIZE 32U
|
||||
|
||||
#define LG_NET_FILE_MAX_LABEL_LENGTH 1024U
|
||||
#define LG_NET_FILE_MAX_PATH_LENGTH 4096U
|
||||
#define LG_NET_FILE_MAX_LINK_TARGET_LENGTH 4096U
|
||||
#define LG_NET_FILE_MAX_ENTRIES 1048576U
|
||||
#define LG_NET_FILE_MAX_CHUNK_LENGTH (4U * 1024U * 1024U)
|
||||
#define LG_NET_FILE_OFFER_HEADER_WIRE_SIZE 32U
|
||||
#define LG_NET_FILE_ENTRY_HEADER_WIRE_SIZE 56U
|
||||
#define LG_NET_FILE_REQUEST_WIRE_SIZE 40U
|
||||
#define LG_NET_FILE_CHUNK_HEADER_WIRE_SIZE 48U
|
||||
#define LG_NET_FILE_STATUS_WIRE_SIZE 40U
|
||||
|
||||
#define LG_NET_USB_RESERVED_HEADER_WIRE_SIZE 32U
|
||||
#define LG_NET_USB_MAX_RESERVED_PAYLOAD_LENGTH \
|
||||
(LG_NET_MAX_PAYLOAD_LENGTH - LG_NET_USB_RESERVED_HEADER_WIRE_SIZE)
|
||||
|
||||
typedef uint16_t LGNetVideoCodec;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_VIDEO_CODEC_PYROWAVE = 1,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetVideoPixelFormat;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_VIDEO_PIXEL_FORMAT_NV12 = 1,
|
||||
LG_NET_VIDEO_PIXEL_FORMAT_P010 = 2,
|
||||
LG_NET_VIDEO_PIXEL_FORMAT_YUV420P8 = 3,
|
||||
LG_NET_VIDEO_PIXEL_FORMAT_YUV420P10 = 4,
|
||||
LG_NET_VIDEO_PIXEL_FORMAT_YUV422P8 = 5,
|
||||
LG_NET_VIDEO_PIXEL_FORMAT_YUV422P10 = 6,
|
||||
LG_NET_VIDEO_PIXEL_FORMAT_YUV444P8 = 7,
|
||||
LG_NET_VIDEO_PIXEL_FORMAT_YUV444P10 = 8,
|
||||
LG_NET_VIDEO_PIXEL_FORMAT_YUV444P16F = 9,
|
||||
};
|
||||
|
||||
typedef uint8_t LGNetVideoChromaSubsampling;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_VIDEO_CHROMA_420 = 1,
|
||||
LG_NET_VIDEO_CHROMA_422 = 2,
|
||||
LG_NET_VIDEO_CHROMA_444 = 3,
|
||||
};
|
||||
|
||||
typedef uint8_t LGNetColorPrimaries;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_COLOR_PRIMARIES_BT601 = 1,
|
||||
LG_NET_COLOR_PRIMARIES_BT709 = 2,
|
||||
LG_NET_COLOR_PRIMARIES_BT2020 = 3,
|
||||
};
|
||||
|
||||
typedef uint8_t LGNetColorTransfer;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_COLOR_TRANSFER_LINEAR = 1,
|
||||
LG_NET_COLOR_TRANSFER_SRGB = 2,
|
||||
LG_NET_COLOR_TRANSFER_BT709 = 3,
|
||||
LG_NET_COLOR_TRANSFER_PQ = 4,
|
||||
LG_NET_COLOR_TRANSFER_HLG = 5,
|
||||
};
|
||||
|
||||
typedef uint8_t LGNetColorMatrix;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_COLOR_MATRIX_BT601 = 1,
|
||||
LG_NET_COLOR_MATRIX_BT709 = 2,
|
||||
LG_NET_COLOR_MATRIX_BT2020 = 3,
|
||||
LG_NET_COLOR_MATRIX_RGB = 4,
|
||||
};
|
||||
|
||||
typedef uint8_t LGNetColorRange;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_COLOR_RANGE_LIMITED = 1,
|
||||
LG_NET_COLOR_RANGE_FULL = 2,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetVideoStreamFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_VIDEO_STREAM_HDR = 1U << 0,
|
||||
LG_NET_VIDEO_STREAM_ALPHA = 1U << 1,
|
||||
LG_NET_VIDEO_STREAM_GPU_PLANES_ONLY = 1U << 2,
|
||||
LG_NET_VIDEO_STREAM_DATAGRAMS = 1U << 3,
|
||||
};
|
||||
|
||||
typedef struct LGNetVideoStreamConfig
|
||||
{
|
||||
uint32_t streamID;
|
||||
LGNetVideoCodec codec;
|
||||
uint16_t codecVersion;
|
||||
uint64_t configEpoch;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t refreshNumerator;
|
||||
uint32_t refreshDenominator;
|
||||
LGNetVideoPixelFormat pixelFormat;
|
||||
LGNetVideoChromaSubsampling chromaSubsampling;
|
||||
LGNetColorPrimaries colorPrimaries;
|
||||
LGNetColorTransfer colorTransfer;
|
||||
LGNetColorMatrix colorMatrix;
|
||||
LGNetColorRange colorRange;
|
||||
uint8_t planeCount;
|
||||
uint8_t bitDepth;
|
||||
LGNetVideoStreamFlags flags;
|
||||
uint32_t maxFrameLength;
|
||||
uint32_t maxFragmentLength;
|
||||
uint32_t maxFrameLatencyMs;
|
||||
}
|
||||
LGNetVideoStreamConfig;
|
||||
|
||||
typedef uint16_t LGNetVideoFrameFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_VIDEO_FRAME_KEYFRAME = 1U << 0,
|
||||
LG_NET_VIDEO_FRAME_DISCONTINUITY = 1U << 1,
|
||||
LG_NET_VIDEO_FRAME_END_OF_STREAM = 1U << 2,
|
||||
LG_NET_VIDEO_FRAME_HAS_CHECKSUM = 1U << 3,
|
||||
};
|
||||
|
||||
/* checksum is CRC-32C (Castagnoli), reflected polynomial 0x82f63b78, with
|
||||
* initial and final XOR 0xffffffff, over exactly encodedLength bytes of data.
|
||||
* It is zero when LG_NET_VIDEO_FRAME_HAS_CHECKSUM is clear. */
|
||||
typedef struct LGNetVideoFrame
|
||||
{
|
||||
uint32_t streamID;
|
||||
LGNetVideoCodec codec;
|
||||
LGNetVideoFrameFlags flags;
|
||||
uint64_t configEpoch;
|
||||
uint64_t frameID;
|
||||
uint64_t captureTimestampNs;
|
||||
uint64_t presentationTimestampNs;
|
||||
uint32_t encodedLength;
|
||||
uint16_t blockCount;
|
||||
uint16_t fragmentCount;
|
||||
uint32_t deadlineMs;
|
||||
uint32_t checksum;
|
||||
const uint8_t * data;
|
||||
}
|
||||
LGNetVideoFrame;
|
||||
|
||||
typedef uint16_t LGNetVideoFragmentFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_VIDEO_FRAGMENT_BLOCK_START = 1U << 0,
|
||||
LG_NET_VIDEO_FRAGMENT_BLOCK_END = 1U << 1,
|
||||
LG_NET_VIDEO_FRAGMENT_FRAME_END = 1U << 2,
|
||||
LG_NET_VIDEO_FRAGMENT_RECOVERY = 1U << 3,
|
||||
};
|
||||
|
||||
typedef struct LGNetVideoFragment
|
||||
{
|
||||
uint32_t streamID;
|
||||
uint64_t configEpoch;
|
||||
uint64_t frameID;
|
||||
uint32_t frameLength;
|
||||
uint32_t offset;
|
||||
uint16_t fragmentIndex;
|
||||
uint16_t fragmentCount;
|
||||
uint16_t blockIndex;
|
||||
uint16_t blockCount;
|
||||
uint16_t payloadLength;
|
||||
LGNetVideoFragmentFlags flags;
|
||||
const uint8_t * payload;
|
||||
}
|
||||
LGNetVideoFragment;
|
||||
|
||||
typedef uint32_t LGNetVideoFeedbackFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_VIDEO_FEEDBACK_REQUEST_KEYFRAME = 1U << 0,
|
||||
LG_NET_VIDEO_FEEDBACK_CONGESTED = 1U << 1,
|
||||
LG_NET_VIDEO_FEEDBACK_DECODER_STALLED = 1U << 2,
|
||||
};
|
||||
|
||||
typedef struct LGNetVideoFeedback
|
||||
{
|
||||
uint32_t streamID;
|
||||
LGNetVideoFeedbackFlags flags;
|
||||
uint64_t lastCompleteFrameID;
|
||||
uint64_t highestSeenFrameID;
|
||||
uint64_t lastDecodedFrameID;
|
||||
uint32_t lostFrames;
|
||||
uint32_t lostFragments;
|
||||
uint32_t receiveQueueUs;
|
||||
uint32_t decodeQueueUs;
|
||||
uint32_t roundTripUs;
|
||||
}
|
||||
LGNetVideoFeedback;
|
||||
|
||||
typedef uint32_t LGNetCursorPositionFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CURSOR_POSITION_VISIBLE = 1U << 0,
|
||||
LG_NET_CURSOR_POSITION_RELATIVE = 1U << 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetCursorPosition
|
||||
{
|
||||
uint64_t updateID;
|
||||
uint64_t timestampNs;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
uint32_t desktopWidth;
|
||||
uint32_t desktopHeight;
|
||||
LGNetCursorPositionFlags flags;
|
||||
uint32_t displayID;
|
||||
}
|
||||
LGNetCursorPosition;
|
||||
|
||||
typedef uint16_t LGNetCursorFormat;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CURSOR_FORMAT_BGRA8_PREMULTIPLIED = 1,
|
||||
LG_NET_CURSOR_FORMAT_RGBA8_PREMULTIPLIED = 2,
|
||||
LG_NET_CURSOR_FORMAT_MASKED_COLOR = 3,
|
||||
LG_NET_CURSOR_FORMAT_MONOCHROME = 4,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetCursorShapeFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CURSOR_SHAPE_HIDDEN = 1U << 0,
|
||||
LG_NET_CURSOR_SHAPE_ANIMATED = 1U << 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetCursorShape
|
||||
{
|
||||
uint64_t shapeID;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t pitch;
|
||||
uint32_t dataLength;
|
||||
LGNetCursorFormat format;
|
||||
LGNetCursorShapeFlags flags;
|
||||
uint32_t hotspotX;
|
||||
uint32_t hotspotY;
|
||||
uint32_t frameDurationMs;
|
||||
const uint8_t * data;
|
||||
}
|
||||
LGNetCursorShape;
|
||||
|
||||
typedef uint32_t LGNetInputClaimFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_INPUT_CLAIM_KEYBOARD = 1U << 0,
|
||||
LG_NET_INPUT_CLAIM_POINTER = 1U << 1,
|
||||
LG_NET_INPUT_CLAIM_EXCLUSIVE = 1U << 2,
|
||||
};
|
||||
|
||||
typedef struct LGNetInputClaim
|
||||
{
|
||||
uint64_t claimantID;
|
||||
uint64_t claimEpoch;
|
||||
uint32_t leaseMs;
|
||||
LGNetInputClaimFlags flags;
|
||||
}
|
||||
LGNetInputClaim;
|
||||
|
||||
typedef uint32_t LGNetInputStatusCode;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_INPUT_STATUS_ACCEPTED = 1,
|
||||
LG_NET_INPUT_STATUS_REJECTED = 2,
|
||||
LG_NET_INPUT_STATUS_RELEASED = 3,
|
||||
LG_NET_INPUT_STATUS_EXPIRED = 4,
|
||||
LG_NET_INPUT_STATUS_UNSUPPORTED = 5,
|
||||
LG_NET_INPUT_STATUS_ERROR = 6,
|
||||
};
|
||||
|
||||
typedef struct LGNetInputStatus
|
||||
{
|
||||
uint64_t claimEpoch;
|
||||
uint64_t lastSequence;
|
||||
LGNetInputStatusCode status;
|
||||
LGNetInputClaimFlags flags;
|
||||
uint32_t leaseRemainingMs;
|
||||
uint32_t detail;
|
||||
}
|
||||
LGNetInputStatus;
|
||||
|
||||
typedef uint32_t LGNetPointerButtons;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_POINTER_BUTTON_LEFT = 1U << 0,
|
||||
LG_NET_POINTER_BUTTON_RIGHT = 1U << 1,
|
||||
LG_NET_POINTER_BUTTON_MIDDLE = 1U << 2,
|
||||
LG_NET_POINTER_BUTTON_BACK = 1U << 3,
|
||||
LG_NET_POINTER_BUTTON_FORWARD = 1U << 4,
|
||||
};
|
||||
|
||||
typedef struct LGNetInputRelative
|
||||
{
|
||||
uint64_t sequence;
|
||||
uint64_t timestampNs;
|
||||
int32_t deltaX;
|
||||
int32_t deltaY;
|
||||
int32_t wheelX;
|
||||
int32_t wheelY;
|
||||
LGNetPointerButtons buttons;
|
||||
LGNetPointerButtons changedButtons;
|
||||
}
|
||||
LGNetInputRelative;
|
||||
|
||||
typedef struct LGNetInputAbsolute
|
||||
{
|
||||
uint64_t sequence;
|
||||
uint64_t timestampNs;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
int32_t wheelX;
|
||||
int32_t wheelY;
|
||||
LGNetPointerButtons buttons;
|
||||
LGNetPointerButtons changedButtons;
|
||||
}
|
||||
LGNetInputAbsolute;
|
||||
|
||||
typedef uint16_t LGNetKeyboardFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_KEYBOARD_DOWN = 1U << 0,
|
||||
LG_NET_KEYBOARD_REPEAT = 1U << 1,
|
||||
LG_NET_KEYBOARD_EXTENDED = 1U << 2,
|
||||
LG_NET_KEYBOARD_E1 = 1U << 3,
|
||||
};
|
||||
|
||||
/* modifiers uses the USB HID keyboard modifier byte in its low eight bits;
|
||||
* all other bits are reserved and must be zero. */
|
||||
typedef struct LGNetInputKeyboard
|
||||
{
|
||||
uint64_t sequence;
|
||||
uint64_t timestampNs;
|
||||
uint16_t usagePage;
|
||||
uint16_t usage;
|
||||
uint16_t scanCode;
|
||||
LGNetKeyboardFlags flags;
|
||||
uint32_t modifiers;
|
||||
}
|
||||
LGNetInputKeyboard;
|
||||
|
||||
typedef uint32_t LGNetKeyboardLEDs;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_KEYBOARD_LED_NUM_LOCK = 1U << 0,
|
||||
LG_NET_KEYBOARD_LED_CAPS_LOCK = 1U << 1,
|
||||
LG_NET_KEYBOARD_LED_SCROLL_LOCK = 1U << 2,
|
||||
LG_NET_KEYBOARD_LED_COMPOSE = 1U << 3,
|
||||
LG_NET_KEYBOARD_LED_KANA = 1U << 4,
|
||||
};
|
||||
|
||||
typedef struct LGNetInputLEDs
|
||||
{
|
||||
uint64_t sequence;
|
||||
LGNetKeyboardLEDs state;
|
||||
LGNetKeyboardLEDs validMask;
|
||||
}
|
||||
LGNetInputLEDs;
|
||||
|
||||
typedef uint16_t LGNetAudioDirection;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_AUDIO_DIRECTION_PLAYBACK = 1,
|
||||
LG_NET_AUDIO_DIRECTION_CAPTURE = 2,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetAudioSampleFormat;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_AUDIO_SAMPLE_S16_LE = 1,
|
||||
LG_NET_AUDIO_SAMPLE_S24_LE = 2,
|
||||
LG_NET_AUDIO_SAMPLE_S32_LE = 3,
|
||||
LG_NET_AUDIO_SAMPLE_F32_LE = 4,
|
||||
};
|
||||
|
||||
typedef uint32_t LGNetAudioFormatFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_AUDIO_FORMAT_INTERLEAVED = 1U << 0,
|
||||
};
|
||||
|
||||
typedef struct LGNetAudioFormat
|
||||
{
|
||||
uint32_t streamID;
|
||||
LGNetAudioDirection direction;
|
||||
LGNetAudioSampleFormat sampleFormat;
|
||||
uint64_t formatEpoch;
|
||||
uint32_t sampleRate;
|
||||
uint16_t channels;
|
||||
uint16_t framesPerPacket;
|
||||
uint32_t channelMask;
|
||||
LGNetAudioFormatFlags flags;
|
||||
uint32_t maxPacketFrames;
|
||||
}
|
||||
LGNetAudioFormat;
|
||||
|
||||
typedef uint16_t LGNetAudioDataFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_AUDIO_DATA_DISCONTINUITY = 1U << 0,
|
||||
LG_NET_AUDIO_DATA_SILENT = 1U << 1,
|
||||
LG_NET_AUDIO_DATA_END_OF_STREAM = 1U << 2,
|
||||
};
|
||||
|
||||
typedef struct LGNetAudioData
|
||||
{
|
||||
uint32_t streamID;
|
||||
LGNetAudioDirection direction;
|
||||
LGNetAudioDataFlags flags;
|
||||
uint64_t formatEpoch;
|
||||
uint64_t packetID;
|
||||
uint64_t timestampNs;
|
||||
uint64_t startFrame;
|
||||
uint32_t frameCount;
|
||||
uint32_t dataLength;
|
||||
const uint8_t * data;
|
||||
}
|
||||
LGNetAudioData;
|
||||
|
||||
typedef uint16_t LGNetAudioStateCode;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_AUDIO_STATE_STOPPED = 1,
|
||||
LG_NET_AUDIO_STATE_RUNNING = 2,
|
||||
LG_NET_AUDIO_STATE_PAUSED = 3,
|
||||
LG_NET_AUDIO_STATE_ERROR = 4,
|
||||
};
|
||||
|
||||
typedef uint32_t LGNetAudioStateFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_AUDIO_STATE_MUTED = 1U << 0,
|
||||
LG_NET_AUDIO_STATE_FORMAT_ACTIVE = 1U << 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetAudioState
|
||||
{
|
||||
uint32_t streamID;
|
||||
LGNetAudioDirection direction;
|
||||
LGNetAudioStateCode state;
|
||||
uint64_t stateSequence;
|
||||
uint64_t formatEpoch;
|
||||
int32_t volumeMillibels;
|
||||
LGNetAudioStateFlags flags;
|
||||
}
|
||||
LGNetAudioState;
|
||||
|
||||
typedef struct LGNetAudioClockFeedback
|
||||
{
|
||||
uint32_t streamID;
|
||||
LGNetAudioDirection direction;
|
||||
uint64_t formatEpoch;
|
||||
uint64_t packetID;
|
||||
uint64_t framePosition;
|
||||
uint64_t timestampNs;
|
||||
int32_t queuedFrames;
|
||||
int32_t driftPpm;
|
||||
}
|
||||
LGNetAudioClockFeedback;
|
||||
|
||||
typedef uint32_t LGNetClipboardClaimFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CLIPBOARD_CLAIM_READ = 1U << 0,
|
||||
LG_NET_CLIPBOARD_CLAIM_WRITE = 1U << 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetClipboardClaim
|
||||
{
|
||||
uint64_t ownerID;
|
||||
uint64_t claimEpoch;
|
||||
uint32_t leaseMs;
|
||||
LGNetClipboardClaimFlags flags;
|
||||
}
|
||||
LGNetClipboardClaim;
|
||||
|
||||
typedef uint16_t LGNetClipboardOfferFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CLIPBOARD_OFFER_LAZY = 1U << 0,
|
||||
LG_NET_CLIPBOARD_OFFER_SENSITIVE = 1U << 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetClipboardOffer
|
||||
{
|
||||
uint64_t offerID;
|
||||
uint64_t serial;
|
||||
uint64_t estimatedSize;
|
||||
uint32_t formatIndex;
|
||||
uint32_t formatCount;
|
||||
uint16_t mimeLength;
|
||||
LGNetClipboardOfferFlags flags;
|
||||
const uint8_t * mime;
|
||||
}
|
||||
LGNetClipboardOffer;
|
||||
|
||||
typedef struct LGNetClipboardRequest
|
||||
{
|
||||
uint64_t offerID;
|
||||
uint64_t requestID;
|
||||
uint32_t formatIndex;
|
||||
uint32_t maxChunkLength;
|
||||
uint64_t offset;
|
||||
}
|
||||
LGNetClipboardRequest;
|
||||
|
||||
typedef uint16_t LGNetClipboardChunkFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CLIPBOARD_CHUNK_FIRST = 1U << 0,
|
||||
LG_NET_CLIPBOARD_CHUNK_FINAL = 1U << 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetClipboardChunk
|
||||
{
|
||||
uint64_t requestID;
|
||||
uint64_t offerID;
|
||||
uint64_t offset;
|
||||
uint64_t totalLength;
|
||||
uint32_t dataLength;
|
||||
LGNetClipboardChunkFlags flags;
|
||||
const uint8_t * data;
|
||||
}
|
||||
LGNetClipboardChunk;
|
||||
|
||||
typedef uint32_t LGNetClipboardStatusCode;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_CLIPBOARD_STATUS_OK = 1,
|
||||
LG_NET_CLIPBOARD_STATUS_NOT_FOUND = 2,
|
||||
LG_NET_CLIPBOARD_STATUS_UNSUPPORTED = 3,
|
||||
LG_NET_CLIPBOARD_STATUS_CANCELLED = 4,
|
||||
LG_NET_CLIPBOARD_STATUS_BUSY = 5,
|
||||
LG_NET_CLIPBOARD_STATUS_ERROR = 6,
|
||||
};
|
||||
|
||||
typedef struct LGNetClipboardStatus
|
||||
{
|
||||
uint64_t requestID;
|
||||
uint64_t offerID;
|
||||
LGNetClipboardStatusCode status;
|
||||
uint32_t detail;
|
||||
uint64_t processedLength;
|
||||
}
|
||||
LGNetClipboardStatus;
|
||||
|
||||
typedef uint32_t LGNetFileOfferFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_FILE_OFFER_COPY = 1U << 0,
|
||||
LG_NET_FILE_OFFER_MOVE = 1U << 1,
|
||||
LG_NET_FILE_OFFER_RECURSIVE = 1U << 2,
|
||||
};
|
||||
|
||||
typedef struct LGNetFileOffer
|
||||
{
|
||||
uint64_t offerID;
|
||||
uint64_t totalBytes;
|
||||
uint32_t entryCount;
|
||||
LGNetFileOfferFlags flags;
|
||||
uint16_t labelLength;
|
||||
const uint8_t * label;
|
||||
}
|
||||
LGNetFileOffer;
|
||||
|
||||
typedef uint16_t LGNetFileEntryType;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_FILE_ENTRY_REGULAR = 1,
|
||||
LG_NET_FILE_ENTRY_DIRECTORY = 2,
|
||||
LG_NET_FILE_ENTRY_SYMLINK = 3,
|
||||
};
|
||||
|
||||
typedef uint16_t LGNetFileEntryFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_FILE_ENTRY_EXECUTABLE = 1U << 0,
|
||||
LG_NET_FILE_ENTRY_HIDDEN = 1U << 1,
|
||||
};
|
||||
|
||||
/* File path fields are strict UTF-8 without a trailing NUL. They are relative
|
||||
* to a receiver-selected transfer root and use '/' as their only separator.
|
||||
* Receivers must reject absolute paths, empty, '.' or '..' components, and
|
||||
* platform-native alternate separators before accessing the filesystem. The
|
||||
* same traversal rules apply to symbolic-link targets. */
|
||||
typedef struct LGNetFileEntry
|
||||
{
|
||||
uint64_t offerID;
|
||||
uint64_t entryID;
|
||||
uint64_t parentID;
|
||||
uint64_t size;
|
||||
uint64_t modifiedNs;
|
||||
uint32_t mode;
|
||||
LGNetFileEntryType type;
|
||||
LGNetFileEntryFlags flags;
|
||||
uint16_t pathLength;
|
||||
uint16_t linkTargetLength;
|
||||
const uint8_t * path;
|
||||
const uint8_t * linkTarget;
|
||||
}
|
||||
LGNetFileEntry;
|
||||
|
||||
typedef uint32_t LGNetFileRequestFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_FILE_REQUEST_METADATA = 1U << 0,
|
||||
LG_NET_FILE_REQUEST_DATA = 1U << 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetFileRequest
|
||||
{
|
||||
uint64_t requestID;
|
||||
uint64_t offerID;
|
||||
uint64_t entryID;
|
||||
uint64_t offset;
|
||||
uint32_t length;
|
||||
LGNetFileRequestFlags flags;
|
||||
}
|
||||
LGNetFileRequest;
|
||||
|
||||
typedef uint16_t LGNetFileChunkFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_FILE_CHUNK_FIRST = 1U << 0,
|
||||
LG_NET_FILE_CHUNK_FINAL = 1U << 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetFileChunk
|
||||
{
|
||||
uint64_t requestID;
|
||||
uint64_t offerID;
|
||||
uint64_t entryID;
|
||||
uint64_t offset;
|
||||
uint64_t totalLength;
|
||||
uint32_t dataLength;
|
||||
LGNetFileChunkFlags flags;
|
||||
const uint8_t * data;
|
||||
}
|
||||
LGNetFileChunk;
|
||||
|
||||
typedef uint32_t LGNetFileStatusCode;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_FILE_STATUS_OK = 1,
|
||||
LG_NET_FILE_STATUS_NOT_FOUND = 2,
|
||||
LG_NET_FILE_STATUS_DENIED = 3,
|
||||
LG_NET_FILE_STATUS_CANCELLED = 4,
|
||||
LG_NET_FILE_STATUS_INVALID = 5,
|
||||
LG_NET_FILE_STATUS_UNSUPPORTED = 6,
|
||||
LG_NET_FILE_STATUS_ERROR = 7,
|
||||
};
|
||||
|
||||
typedef struct LGNetFileStatus
|
||||
{
|
||||
uint64_t requestID;
|
||||
uint64_t offerID;
|
||||
uint64_t entryID;
|
||||
LGNetFileStatusCode status;
|
||||
uint32_t detail;
|
||||
uint64_t transferredLength;
|
||||
}
|
||||
LGNetFileStatus;
|
||||
|
||||
/* This header reserves framing only. It deliberately defines no USB
|
||||
* redirection operations or device semantics. */
|
||||
typedef uint16_t LGNetUSBReservedFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
LG_NET_USB_RESERVED_RESPONSE = 1U << 0,
|
||||
LG_NET_USB_RESERVED_FINAL = 1U << 1,
|
||||
};
|
||||
|
||||
typedef struct LGNetUSBReserved
|
||||
{
|
||||
uint16_t version;
|
||||
uint16_t headerSize;
|
||||
uint16_t messageType;
|
||||
LGNetUSBReservedFlags flags;
|
||||
uint64_t requestID;
|
||||
uint64_t sequence;
|
||||
uint32_t payloadLength;
|
||||
const uint8_t * payload;
|
||||
}
|
||||
LGNetUSBReserved;
|
||||
|
||||
bool lgNetVideoStreamConfigValid(const LGNetVideoStreamConfig * config);
|
||||
bool lgNetVideoStreamConfigEncode(void * data, size_t size,
|
||||
const LGNetVideoStreamConfig * config);
|
||||
LGNetParseResult lgNetVideoStreamConfigDecode(
|
||||
LGNetVideoStreamConfig * config, const void * data, size_t size);
|
||||
|
||||
size_t lgNetVideoFrameSize(const LGNetVideoFrame * frame);
|
||||
bool lgNetVideoFrameValid(const LGNetVideoFrame * frame);
|
||||
bool lgNetVideoFrameEncode(
|
||||
void * data, size_t size, const LGNetVideoFrame * frame);
|
||||
LGNetParseResult lgNetVideoFrameDecode(
|
||||
LGNetVideoFrame * frame, const void * data, size_t size);
|
||||
|
||||
size_t lgNetVideoFragmentSize(const LGNetVideoFragment * fragment);
|
||||
bool lgNetVideoFragmentValid(const LGNetVideoFragment * fragment);
|
||||
bool lgNetVideoFragmentEncode(
|
||||
void * data, size_t size, const LGNetVideoFragment * fragment);
|
||||
LGNetParseResult lgNetVideoFragmentDecode(
|
||||
LGNetVideoFragment * fragment, const void * data, size_t size);
|
||||
|
||||
bool lgNetVideoFeedbackValid(const LGNetVideoFeedback * feedback);
|
||||
bool lgNetVideoFeedbackEncode(
|
||||
void * data, size_t size, const LGNetVideoFeedback * feedback);
|
||||
LGNetParseResult lgNetVideoFeedbackDecode(
|
||||
LGNetVideoFeedback * feedback, const void * data, size_t size);
|
||||
|
||||
bool lgNetCursorPositionValid(const LGNetCursorPosition * position);
|
||||
bool lgNetCursorPositionEncode(
|
||||
void * data, size_t size, const LGNetCursorPosition * position);
|
||||
LGNetParseResult lgNetCursorPositionDecode(
|
||||
LGNetCursorPosition * position, const void * data, size_t size);
|
||||
|
||||
size_t lgNetCursorShapeSize(const LGNetCursorShape * shape);
|
||||
bool lgNetCursorShapeValid(const LGNetCursorShape * shape);
|
||||
bool lgNetCursorShapeEncode(
|
||||
void * data, size_t size, const LGNetCursorShape * shape);
|
||||
LGNetParseResult lgNetCursorShapeDecode(
|
||||
LGNetCursorShape * shape, const void * data, size_t size);
|
||||
|
||||
bool lgNetInputClaimValid(const LGNetInputClaim * claim);
|
||||
bool lgNetInputClaimEncode(
|
||||
void * data, size_t size, const LGNetInputClaim * claim);
|
||||
LGNetParseResult lgNetInputClaimDecode(
|
||||
LGNetInputClaim * claim, const void * data, size_t size);
|
||||
|
||||
bool lgNetInputStatusValid(const LGNetInputStatus * status);
|
||||
bool lgNetInputStatusEncode(
|
||||
void * data, size_t size, const LGNetInputStatus * status);
|
||||
LGNetParseResult lgNetInputStatusDecode(
|
||||
LGNetInputStatus * status, const void * data, size_t size);
|
||||
|
||||
bool lgNetInputRelativeValid(const LGNetInputRelative * relative);
|
||||
bool lgNetInputRelativeEncode(
|
||||
void * data, size_t size, const LGNetInputRelative * relative);
|
||||
LGNetParseResult lgNetInputRelativeDecode(
|
||||
LGNetInputRelative * relative, const void * data, size_t size);
|
||||
|
||||
bool lgNetInputAbsoluteValid(const LGNetInputAbsolute * absolute);
|
||||
bool lgNetInputAbsoluteEncode(
|
||||
void * data, size_t size, const LGNetInputAbsolute * absolute);
|
||||
LGNetParseResult lgNetInputAbsoluteDecode(
|
||||
LGNetInputAbsolute * absolute, const void * data, size_t size);
|
||||
|
||||
bool lgNetInputKeyboardValid(const LGNetInputKeyboard * keyboard);
|
||||
bool lgNetInputKeyboardEncode(
|
||||
void * data, size_t size, const LGNetInputKeyboard * keyboard);
|
||||
LGNetParseResult lgNetInputKeyboardDecode(
|
||||
LGNetInputKeyboard * keyboard, const void * data, size_t size);
|
||||
|
||||
bool lgNetInputLEDsValid(const LGNetInputLEDs * leds);
|
||||
bool lgNetInputLEDsEncode(
|
||||
void * data, size_t size, const LGNetInputLEDs * leds);
|
||||
LGNetParseResult lgNetInputLEDsDecode(
|
||||
LGNetInputLEDs * leds, const void * data, size_t size);
|
||||
|
||||
bool lgNetAudioFormatValid(const LGNetAudioFormat * format);
|
||||
bool lgNetAudioFormatEncode(
|
||||
void * data, size_t size, const LGNetAudioFormat * format);
|
||||
LGNetParseResult lgNetAudioFormatDecode(
|
||||
LGNetAudioFormat * format, const void * data, size_t size);
|
||||
|
||||
size_t lgNetAudioDataSize(const LGNetAudioData * audio);
|
||||
bool lgNetAudioDataValid(const LGNetAudioData * audio);
|
||||
bool lgNetAudioDataMatchesFormat(
|
||||
const LGNetAudioData * audio, const LGNetAudioFormat * format);
|
||||
bool lgNetAudioDataEncode(
|
||||
void * data, size_t size, const LGNetAudioData * audio);
|
||||
LGNetParseResult lgNetAudioDataDecode(
|
||||
LGNetAudioData * audio, const void * data, size_t size);
|
||||
|
||||
bool lgNetAudioStateValid(const LGNetAudioState * state);
|
||||
bool lgNetAudioStateEncode(
|
||||
void * data, size_t size, const LGNetAudioState * state);
|
||||
LGNetParseResult lgNetAudioStateDecode(
|
||||
LGNetAudioState * state, const void * data, size_t size);
|
||||
|
||||
bool lgNetAudioClockFeedbackValid(
|
||||
const LGNetAudioClockFeedback * feedback);
|
||||
bool lgNetAudioClockFeedbackEncode(void * data, size_t size,
|
||||
const LGNetAudioClockFeedback * feedback);
|
||||
LGNetParseResult lgNetAudioClockFeedbackDecode(
|
||||
LGNetAudioClockFeedback * feedback, const void * data, size_t size);
|
||||
|
||||
bool lgNetClipboardClaimValid(const LGNetClipboardClaim * claim);
|
||||
bool lgNetClipboardClaimEncode(
|
||||
void * data, size_t size, const LGNetClipboardClaim * claim);
|
||||
LGNetParseResult lgNetClipboardClaimDecode(
|
||||
LGNetClipboardClaim * claim, const void * data, size_t size);
|
||||
|
||||
size_t lgNetClipboardOfferSize(const LGNetClipboardOffer * offer);
|
||||
bool lgNetClipboardOfferValid(const LGNetClipboardOffer * offer);
|
||||
bool lgNetClipboardOfferEncode(
|
||||
void * data, size_t size, const LGNetClipboardOffer * offer);
|
||||
LGNetParseResult lgNetClipboardOfferDecode(
|
||||
LGNetClipboardOffer * offer, const void * data, size_t size);
|
||||
|
||||
bool lgNetClipboardRequestValid(const LGNetClipboardRequest * request);
|
||||
bool lgNetClipboardRequestEncode(
|
||||
void * data, size_t size, const LGNetClipboardRequest * request);
|
||||
LGNetParseResult lgNetClipboardRequestDecode(
|
||||
LGNetClipboardRequest * request, const void * data, size_t size);
|
||||
|
||||
size_t lgNetClipboardChunkSize(const LGNetClipboardChunk * chunk);
|
||||
bool lgNetClipboardChunkValid(const LGNetClipboardChunk * chunk);
|
||||
bool lgNetClipboardChunkEncode(
|
||||
void * data, size_t size, const LGNetClipboardChunk * chunk);
|
||||
LGNetParseResult lgNetClipboardChunkDecode(
|
||||
LGNetClipboardChunk * chunk, const void * data, size_t size);
|
||||
|
||||
bool lgNetClipboardStatusValid(const LGNetClipboardStatus * status);
|
||||
bool lgNetClipboardStatusEncode(
|
||||
void * data, size_t size, const LGNetClipboardStatus * status);
|
||||
LGNetParseResult lgNetClipboardStatusDecode(
|
||||
LGNetClipboardStatus * status, const void * data, size_t size);
|
||||
|
||||
size_t lgNetFileOfferSize(const LGNetFileOffer * offer);
|
||||
bool lgNetFileOfferValid(const LGNetFileOffer * offer);
|
||||
bool lgNetFileOfferEncode(
|
||||
void * data, size_t size, const LGNetFileOffer * offer);
|
||||
LGNetParseResult lgNetFileOfferDecode(
|
||||
LGNetFileOffer * offer, const void * data, size_t size);
|
||||
|
||||
size_t lgNetFileEntrySize(const LGNetFileEntry * entry);
|
||||
bool lgNetFileEntryValid(const LGNetFileEntry * entry);
|
||||
bool lgNetFileEntryEncode(
|
||||
void * data, size_t size, const LGNetFileEntry * entry);
|
||||
LGNetParseResult lgNetFileEntryDecode(
|
||||
LGNetFileEntry * entry, const void * data, size_t size);
|
||||
|
||||
bool lgNetFileRequestValid(const LGNetFileRequest * request);
|
||||
bool lgNetFileRequestEncode(
|
||||
void * data, size_t size, const LGNetFileRequest * request);
|
||||
LGNetParseResult lgNetFileRequestDecode(
|
||||
LGNetFileRequest * request, const void * data, size_t size);
|
||||
|
||||
size_t lgNetFileChunkSize(const LGNetFileChunk * chunk);
|
||||
bool lgNetFileChunkValid(const LGNetFileChunk * chunk);
|
||||
bool lgNetFileChunkEncode(
|
||||
void * data, size_t size, const LGNetFileChunk * chunk);
|
||||
LGNetParseResult lgNetFileChunkDecode(
|
||||
LGNetFileChunk * chunk, const void * data, size_t size);
|
||||
|
||||
bool lgNetFileStatusValid(const LGNetFileStatus * status);
|
||||
bool lgNetFileStatusEncode(
|
||||
void * data, size_t size, const LGNetFileStatus * status);
|
||||
LGNetParseResult lgNetFileStatusDecode(
|
||||
LGNetFileStatus * status, const void * data, size_t size);
|
||||
|
||||
size_t lgNetUSBReservedSize(const LGNetUSBReserved * reserved);
|
||||
bool lgNetUSBReservedValid(const LGNetUSBReserved * reserved);
|
||||
bool lgNetUSBReservedEncode(
|
||||
void * data, size_t size, const LGNetUSBReserved * reserved);
|
||||
LGNetParseResult lgNetUSBReservedDecode(
|
||||
LGNetUSBReserved * reserved, const void * data, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _H_LG_COMMON_NETWORK_WIRE_
|
||||
#define _H_LG_COMMON_NETWORK_WIRE_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum LGNetParseResult
|
||||
{
|
||||
LG_NET_PARSE_OK,
|
||||
LG_NET_PARSE_TRUNCATED,
|
||||
LG_NET_PARSE_INVALID_MAGIC,
|
||||
LG_NET_PARSE_INVALID_VERSION,
|
||||
LG_NET_PARSE_INVALID_HEADER,
|
||||
LG_NET_PARSE_INVALID_LENGTH,
|
||||
LG_NET_PARSE_INVALID_VALUE,
|
||||
}
|
||||
LGNetParseResult;
|
||||
|
||||
typedef struct LGNetWriter
|
||||
{
|
||||
uint8_t * data;
|
||||
size_t capacity;
|
||||
size_t offset;
|
||||
bool failed;
|
||||
}
|
||||
LGNetWriter;
|
||||
|
||||
typedef struct LGNetReader
|
||||
{
|
||||
const uint8_t * data;
|
||||
size_t size;
|
||||
size_t offset;
|
||||
bool failed;
|
||||
}
|
||||
LGNetReader;
|
||||
|
||||
void lgNetWriterInit(LGNetWriter * writer, void * data, size_t capacity);
|
||||
size_t lgNetWriterSize(const LGNetWriter * writer);
|
||||
size_t lgNetWriterRemaining(const LGNetWriter * writer);
|
||||
bool lgNetWriterValid(const LGNetWriter * writer);
|
||||
bool lgNetWriterU8(LGNetWriter * writer, uint8_t value);
|
||||
bool lgNetWriterU16(LGNetWriter * writer, uint16_t value);
|
||||
bool lgNetWriterU32(LGNetWriter * writer, uint32_t value);
|
||||
bool lgNetWriterU64(LGNetWriter * writer, uint64_t value);
|
||||
bool lgNetWriterI32(LGNetWriter * writer, int32_t value);
|
||||
bool lgNetWriterI64(LGNetWriter * writer, int64_t value);
|
||||
bool lgNetWriterBytes(
|
||||
LGNetWriter * writer, const void * data, size_t size);
|
||||
bool lgNetWriterZero(LGNetWriter * writer, size_t size);
|
||||
|
||||
void lgNetReaderInit(
|
||||
LGNetReader * reader, const void * data, size_t size);
|
||||
size_t lgNetReaderConsumed(const LGNetReader * reader);
|
||||
size_t lgNetReaderRemaining(const LGNetReader * reader);
|
||||
bool lgNetReaderValid(const LGNetReader * reader);
|
||||
bool lgNetReaderU8(LGNetReader * reader, uint8_t * value);
|
||||
bool lgNetReaderU16(LGNetReader * reader, uint16_t * value);
|
||||
bool lgNetReaderU32(LGNetReader * reader, uint32_t * value);
|
||||
bool lgNetReaderU64(LGNetReader * reader, uint64_t * value);
|
||||
bool lgNetReaderI32(LGNetReader * reader, int32_t * value);
|
||||
bool lgNetReaderI64(LGNetReader * reader, int64_t * value);
|
||||
bool lgNetReaderBytes(LGNetReader * reader, void * data, size_t size);
|
||||
bool lgNetReaderView(
|
||||
LGNetReader * reader, const uint8_t ** data, size_t size);
|
||||
bool lgNetReaderSkip(LGNetReader * reader, size_t size);
|
||||
bool lgNetReaderZero(LGNetReader * reader, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,730 +0,0 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common/network/protocol.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
static const LGNetEnvelopeFlags ENVELOPE_FLAGS =
|
||||
LG_NET_ENVELOPE_RESPONSE |
|
||||
LG_NET_ENVELOPE_FINAL |
|
||||
LG_NET_ENVELOPE_RELIABLE |
|
||||
LG_NET_ENVELOPE_DATAGRAM |
|
||||
LG_NET_ENVELOPE_ACK_REQUIRED |
|
||||
LG_NET_ENVELOPE_ERROR |
|
||||
LG_NET_ENVELOPE_EARLY_DATA;
|
||||
|
||||
static const LGNetCapabilityFlags CAPABILITY_FLAGS =
|
||||
LG_NET_CAPABILITY_REQUIRED |
|
||||
LG_NET_CAPABILITY_SELECTED |
|
||||
LG_NET_CAPABILITY_RELIABLE |
|
||||
LG_NET_CAPABILITY_DATAGRAM |
|
||||
LG_NET_CAPABILITY_BULK |
|
||||
LG_NET_CAPABILITY_MULTI_CLIENT;
|
||||
|
||||
static bool envelopeValid(const LGNetEnvelope * envelope, bool encode)
|
||||
{
|
||||
if (!envelope || envelope->wireMajor != LG_NET_WIRE_VERSION_MAJOR ||
|
||||
envelope->headerSize < LG_NET_ENVELOPE_WIRE_SIZE ||
|
||||
(encode && envelope->wireMinor != LG_NET_WIRE_VERSION_MINOR) ||
|
||||
(encode && envelope->headerSize != LG_NET_ENVELOPE_WIRE_SIZE) ||
|
||||
!envelope->service || !envelope->messageType ||
|
||||
!envelope->serviceVersion || !envelope->messageVersion ||
|
||||
envelope->payloadLength > LG_NET_MAX_PAYLOAD_LENGTH)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool authModeKnown(LGNetAuthMode mode)
|
||||
{
|
||||
return mode == LG_NET_AUTH_NONE || mode == LG_NET_AUTH_PASSWORD;
|
||||
}
|
||||
|
||||
static bool passwordAlgorithmKnown(LGNetPasswordAlgorithm algorithm)
|
||||
{
|
||||
return algorithm == LG_NET_PASSWORD_PBKDF2_HMAC_SHA256;
|
||||
}
|
||||
|
||||
static LGNetParseResult fixedDecodeResult(
|
||||
const LGNetReader * reader, size_t expected, size_t actual)
|
||||
{
|
||||
if (!reader || !lgNetReaderValid(reader))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
if (actual != expected || lgNetReaderConsumed(reader) != expected)
|
||||
return LG_NET_PARSE_INVALID_LENGTH;
|
||||
return LG_NET_PARSE_OK;
|
||||
}
|
||||
|
||||
void lgNetEnvelopeInit(LGNetEnvelope * envelope, LGNetService service,
|
||||
uint16_t messageType, uint16_t serviceVersion,
|
||||
uint16_t messageVersion)
|
||||
{
|
||||
if (!envelope)
|
||||
return;
|
||||
|
||||
memset(envelope, 0, sizeof(*envelope));
|
||||
envelope->wireMajor = LG_NET_WIRE_VERSION_MAJOR;
|
||||
envelope->wireMinor = LG_NET_WIRE_VERSION_MINOR;
|
||||
envelope->headerSize = LG_NET_ENVELOPE_WIRE_SIZE;
|
||||
envelope->service = service;
|
||||
envelope->messageType = messageType;
|
||||
envelope->serviceVersion = serviceVersion;
|
||||
envelope->messageVersion = messageVersion;
|
||||
}
|
||||
|
||||
bool lgNetEnvelopeEncode(void * data, size_t size,
|
||||
const LGNetEnvelope * envelope)
|
||||
{
|
||||
if (!data || size < LG_NET_ENVELOPE_WIRE_SIZE ||
|
||||
!envelopeValid(envelope, true) ||
|
||||
envelope->flags & ~ENVELOPE_FLAGS)
|
||||
return false;
|
||||
|
||||
LGNetWriter writer;
|
||||
lgNetWriterInit(&writer, data, size);
|
||||
return
|
||||
lgNetWriterU32(&writer, LG_NET_WIRE_MAGIC) &&
|
||||
lgNetWriterU16(&writer, envelope->wireMajor) &&
|
||||
lgNetWriterU16(&writer, envelope->wireMinor) &&
|
||||
lgNetWriterU16(&writer, envelope->headerSize) &&
|
||||
lgNetWriterU16(&writer, envelope->service) &&
|
||||
lgNetWriterU16(&writer, envelope->messageType) &&
|
||||
lgNetWriterU16(&writer, envelope->serviceVersion) &&
|
||||
lgNetWriterU16(&writer, envelope->messageVersion) &&
|
||||
lgNetWriterU16(&writer, 0) &&
|
||||
lgNetWriterU32(&writer, envelope->flags) &&
|
||||
lgNetWriterU32(&writer, envelope->payloadLength) &&
|
||||
lgNetWriterU32(&writer, 0) &&
|
||||
lgNetWriterU64(&writer, envelope->sessionEpoch) &&
|
||||
lgNetWriterU64(&writer, envelope->componentEpoch) &&
|
||||
lgNetWriterU64(&writer, envelope->sequence) &&
|
||||
lgNetWriterU64(&writer, envelope->requestID) &&
|
||||
lgNetWriterSize(&writer) == LG_NET_ENVELOPE_WIRE_SIZE;
|
||||
}
|
||||
|
||||
LGNetParseResult lgNetEnvelopeDecode(LGNetEnvelope * envelope,
|
||||
const void * data, size_t size)
|
||||
{
|
||||
if (!envelope || !data)
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
if (size < LG_NET_ENVELOPE_WIRE_SIZE)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
|
||||
LGNetEnvelope decoded;
|
||||
uint32_t magic;
|
||||
LGNetReader reader;
|
||||
memset(&decoded, 0, sizeof(decoded));
|
||||
lgNetReaderInit(&reader, data, LG_NET_ENVELOPE_WIRE_SIZE);
|
||||
if (!lgNetReaderU32(&reader, &magic) ||
|
||||
!lgNetReaderU16(&reader, &decoded.wireMajor) ||
|
||||
!lgNetReaderU16(&reader, &decoded.wireMinor) ||
|
||||
!lgNetReaderU16(&reader, &decoded.headerSize) ||
|
||||
!lgNetReaderU16(&reader, &decoded.service) ||
|
||||
!lgNetReaderU16(&reader, &decoded.messageType) ||
|
||||
!lgNetReaderU16(&reader, &decoded.serviceVersion) ||
|
||||
!lgNetReaderU16(&reader, &decoded.messageVersion) ||
|
||||
!lgNetReaderZero(&reader, 2) ||
|
||||
!lgNetReaderU32(&reader, &decoded.flags) ||
|
||||
!lgNetReaderU32(&reader, &decoded.payloadLength) ||
|
||||
!lgNetReaderZero(&reader, 4) ||
|
||||
!lgNetReaderU64(&reader, &decoded.sessionEpoch) ||
|
||||
!lgNetReaderU64(&reader, &decoded.componentEpoch) ||
|
||||
!lgNetReaderU64(&reader, &decoded.sequence) ||
|
||||
!lgNetReaderU64(&reader, &decoded.requestID))
|
||||
return LG_NET_PARSE_INVALID_HEADER;
|
||||
|
||||
if (magic != LG_NET_WIRE_MAGIC)
|
||||
return LG_NET_PARSE_INVALID_MAGIC;
|
||||
if (decoded.wireMajor != LG_NET_WIRE_VERSION_MAJOR)
|
||||
return LG_NET_PARSE_INVALID_VERSION;
|
||||
if (decoded.headerSize < LG_NET_ENVELOPE_WIRE_SIZE)
|
||||
return LG_NET_PARSE_INVALID_HEADER;
|
||||
if (decoded.headerSize > size)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
if (!envelopeValid(&decoded, false) || decoded.flags & ~ENVELOPE_FLAGS)
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
*envelope = decoded;
|
||||
return LG_NET_PARSE_OK;
|
||||
}
|
||||
|
||||
bool lgNetPacketSize(const LGNetEnvelope * envelope, size_t * size)
|
||||
{
|
||||
if (!size || !envelopeValid(envelope, false) ||
|
||||
envelope->headerSize > SIZE_MAX - envelope->payloadLength)
|
||||
return false;
|
||||
|
||||
*size = (size_t)envelope->headerSize + envelope->payloadLength;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetPacketEncode(void * data, size_t size,
|
||||
const LGNetEnvelope * envelope, const void * payload)
|
||||
{
|
||||
uint8_t header[LG_NET_ENVELOPE_WIRE_SIZE];
|
||||
size_t wireSize;
|
||||
if (!data || !envelope || (envelope->payloadLength && !payload) ||
|
||||
!lgNetPacketSize(envelope, &wireSize) || wireSize > size ||
|
||||
!lgNetEnvelopeEncode(header, sizeof(header), envelope))
|
||||
return false;
|
||||
|
||||
if (envelope->payloadLength)
|
||||
memmove((uint8_t *)data + envelope->headerSize, payload,
|
||||
envelope->payloadLength);
|
||||
memcpy(data, header, sizeof(header));
|
||||
return true;
|
||||
}
|
||||
|
||||
LGNetParseResult lgNetPacketDecode(LGNetPacketView * packet,
|
||||
const void * data, size_t size)
|
||||
{
|
||||
if (!packet)
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
LGNetPacketView decoded;
|
||||
memset(&decoded, 0, sizeof(decoded));
|
||||
const LGNetParseResult result = lgNetEnvelopeDecode(
|
||||
&decoded.envelope, data, size);
|
||||
if (result != LG_NET_PARSE_OK)
|
||||
return result;
|
||||
if (!lgNetPacketSize(&decoded.envelope, &decoded.wireSize))
|
||||
return LG_NET_PARSE_INVALID_LENGTH;
|
||||
if (decoded.wireSize > size)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
|
||||
decoded.payload = (const uint8_t *)data + decoded.envelope.headerSize;
|
||||
decoded.payloadLength = decoded.envelope.payloadLength;
|
||||
*packet = decoded;
|
||||
return LG_NET_PARSE_OK;
|
||||
}
|
||||
|
||||
bool lgNetServiceKnown(LGNetService service)
|
||||
{
|
||||
return service >= LG_NET_SERVICE_CORE && service <= LG_NET_SERVICE_USB;
|
||||
}
|
||||
|
||||
bool lgNetMessageKnown(LGNetService service, uint16_t messageType)
|
||||
{
|
||||
if (!messageType)
|
||||
return false;
|
||||
|
||||
switch (service)
|
||||
{
|
||||
case LG_NET_SERVICE_CORE:
|
||||
return messageType <= LG_NET_CORE_MESSAGE_ERROR;
|
||||
|
||||
case LG_NET_SERVICE_RECOVERY:
|
||||
return messageType <= LG_NET_RECOVERY_MESSAGE_STATUS;
|
||||
|
||||
case LG_NET_SERVICE_VIDEO:
|
||||
return messageType <= LG_NET_VIDEO_MESSAGE_STATUS;
|
||||
|
||||
case LG_NET_SERVICE_CURSOR:
|
||||
return messageType <= LG_NET_CURSOR_MESSAGE_STATUS;
|
||||
|
||||
case LG_NET_SERVICE_INPUT:
|
||||
return messageType <= LG_NET_INPUT_MESSAGE_KEYBOARD_LEDS;
|
||||
|
||||
case LG_NET_SERVICE_AUDIO:
|
||||
return messageType <= LG_NET_AUDIO_MESSAGE_STATE_ACK;
|
||||
|
||||
case LG_NET_SERVICE_CLIPBOARD:
|
||||
return messageType <= LG_NET_CLIPBOARD_MESSAGE_STATUS;
|
||||
|
||||
case LG_NET_SERVICE_FILE:
|
||||
return messageType <= LG_NET_FILE_MESSAGE_STATUS;
|
||||
|
||||
case LG_NET_SERVICE_USB:
|
||||
return messageType <= LG_NET_USB_MESSAGE_STATUS;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void lgNetHelloInit(LGNetHello * hello, LGNetRole role)
|
||||
{
|
||||
if (!hello)
|
||||
return;
|
||||
|
||||
memset(hello, 0, sizeof(*hello));
|
||||
hello->role = role;
|
||||
hello->protocolMin = LG_NET_PROTOCOL_VERSION_MIN;
|
||||
hello->protocolMax = LG_NET_PROTOCOL_VERSION_CURRENT;
|
||||
hello->authModes = LG_NET_AUTH_MODES_DEFAULT;
|
||||
hello->maxPayloadLength = LG_NET_MAX_PAYLOAD_LENGTH;
|
||||
}
|
||||
|
||||
bool lgNetHelloValid(const LGNetHello * hello)
|
||||
{
|
||||
return hello &&
|
||||
(hello->role == LG_NET_ROLE_CLIENT || hello->role == LG_NET_ROLE_SERVER) &&
|
||||
hello->protocolMin && hello->protocolMin <= hello->protocolMax &&
|
||||
hello->authModes &&
|
||||
hello->maxPayloadLength &&
|
||||
hello->maxPayloadLength <= LG_NET_MAX_PAYLOAD_LENGTH &&
|
||||
hello->maxDatagramPayload <= hello->maxPayloadLength &&
|
||||
hello->capabilityCount <= LG_NET_MAX_CAPABILITY_RECORDS;
|
||||
}
|
||||
|
||||
bool lgNetHelloEncode(void * data, size_t size, const LGNetHello * hello)
|
||||
{
|
||||
if (!data || size < LG_NET_HELLO_WIRE_SIZE || !lgNetHelloValid(hello))
|
||||
return false;
|
||||
|
||||
LGNetWriter writer;
|
||||
lgNetWriterInit(&writer, data, size);
|
||||
return
|
||||
lgNetWriterU16(&writer, hello->role) &&
|
||||
lgNetWriterU16(&writer, hello->protocolMin) &&
|
||||
lgNetWriterU16(&writer, hello->protocolMax) &&
|
||||
lgNetWriterU16(&writer, 0) &&
|
||||
lgNetWriterU32(&writer, hello->authModes) &&
|
||||
lgNetWriterU32(&writer, hello->maxPayloadLength) &&
|
||||
lgNetWriterU32(&writer, hello->maxDatagramPayload) &&
|
||||
lgNetWriterU32(&writer, hello->capabilityCount) &&
|
||||
lgNetWriterBytes(&writer, hello->nonce, sizeof(hello->nonce)) &&
|
||||
lgNetWriterSize(&writer) == LG_NET_HELLO_WIRE_SIZE;
|
||||
}
|
||||
|
||||
LGNetParseResult lgNetHelloDecode(LGNetHello * hello,
|
||||
const void * data, size_t size)
|
||||
{
|
||||
if (!hello || !data)
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
if (size < LG_NET_HELLO_WIRE_SIZE)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
|
||||
LGNetHello decoded;
|
||||
LGNetReader reader;
|
||||
memset(&decoded, 0, sizeof(decoded));
|
||||
lgNetReaderInit(&reader, data, size);
|
||||
if (!lgNetReaderU16(&reader, &decoded.role) ||
|
||||
!lgNetReaderU16(&reader, &decoded.protocolMin) ||
|
||||
!lgNetReaderU16(&reader, &decoded.protocolMax) ||
|
||||
!lgNetReaderZero(&reader, 2) ||
|
||||
!lgNetReaderU32(&reader, &decoded.authModes) ||
|
||||
!lgNetReaderU32(&reader, &decoded.maxPayloadLength) ||
|
||||
!lgNetReaderU32(&reader, &decoded.maxDatagramPayload) ||
|
||||
!lgNetReaderU32(&reader, &decoded.capabilityCount) ||
|
||||
!lgNetReaderBytes(&reader, decoded.nonce,
|
||||
sizeof(decoded.nonce)))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
const LGNetParseResult result = fixedDecodeResult(
|
||||
&reader, LG_NET_HELLO_WIRE_SIZE, size);
|
||||
if (result != LG_NET_PARSE_OK)
|
||||
return result;
|
||||
if (!lgNetHelloValid(&decoded))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
*hello = decoded;
|
||||
return LG_NET_PARSE_OK;
|
||||
}
|
||||
|
||||
void lgNetHelloAckInit(LGNetHelloAck * hello, uint64_t sessionEpoch)
|
||||
{
|
||||
if (!hello)
|
||||
return;
|
||||
|
||||
memset(hello, 0, sizeof(*hello));
|
||||
hello->protocolVersion = LG_NET_PROTOCOL_VERSION_CURRENT;
|
||||
hello->authMode = LG_NET_AUTH_MODE_DEFAULT;
|
||||
hello->maxPayloadLength = LG_NET_MAX_PAYLOAD_LENGTH;
|
||||
hello->sessionEpoch = sessionEpoch;
|
||||
}
|
||||
|
||||
bool lgNetHelloAckValid(const LGNetHelloAck * hello)
|
||||
{
|
||||
return hello &&
|
||||
hello->protocolVersion >= LG_NET_PROTOCOL_VERSION_MIN &&
|
||||
hello->protocolVersion <= LG_NET_PROTOCOL_VERSION_MAX &&
|
||||
authModeKnown(hello->authMode) &&
|
||||
!(hello->flags & ~LG_NET_HELLO_ACK_RESUMED) &&
|
||||
hello->maxPayloadLength &&
|
||||
hello->maxPayloadLength <= LG_NET_MAX_PAYLOAD_LENGTH &&
|
||||
hello->maxDatagramPayload <= hello->maxPayloadLength &&
|
||||
hello->capabilityCount <= LG_NET_MAX_CAPABILITY_RECORDS &&
|
||||
hello->sessionEpoch;
|
||||
}
|
||||
|
||||
bool lgNetHelloAckEncode(
|
||||
void * data, size_t size, const LGNetHelloAck * hello)
|
||||
{
|
||||
if (!data || size < LG_NET_HELLO_ACK_WIRE_SIZE ||
|
||||
!lgNetHelloAckValid(hello))
|
||||
return false;
|
||||
|
||||
LGNetWriter writer;
|
||||
lgNetWriterInit(&writer, data, size);
|
||||
return
|
||||
lgNetWriterU16(&writer, hello->protocolVersion) &&
|
||||
lgNetWriterU16(&writer, hello->authMode) &&
|
||||
lgNetWriterU32(&writer, hello->flags) &&
|
||||
lgNetWriterU32(&writer, hello->maxPayloadLength) &&
|
||||
lgNetWriterU32(&writer, hello->maxDatagramPayload) &&
|
||||
lgNetWriterU32(&writer, hello->capabilityCount) &&
|
||||
lgNetWriterU32(&writer, 0) &&
|
||||
lgNetWriterU64(&writer, hello->sessionEpoch) &&
|
||||
lgNetWriterBytes(&writer, hello->nonce, sizeof(hello->nonce)) &&
|
||||
lgNetWriterSize(&writer) == LG_NET_HELLO_ACK_WIRE_SIZE;
|
||||
}
|
||||
|
||||
LGNetParseResult lgNetHelloAckDecode(LGNetHelloAck * hello,
|
||||
const void * data, size_t size)
|
||||
{
|
||||
if (!hello || !data)
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
if (size < LG_NET_HELLO_ACK_WIRE_SIZE)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
|
||||
LGNetHelloAck decoded;
|
||||
LGNetReader reader;
|
||||
memset(&decoded, 0, sizeof(decoded));
|
||||
lgNetReaderInit(&reader, data, size);
|
||||
if (!lgNetReaderU16(&reader, &decoded.protocolVersion) ||
|
||||
!lgNetReaderU16(&reader, &decoded.authMode) ||
|
||||
!lgNetReaderU32(&reader, &decoded.flags) ||
|
||||
!lgNetReaderU32(&reader, &decoded.maxPayloadLength) ||
|
||||
!lgNetReaderU32(&reader, &decoded.maxDatagramPayload) ||
|
||||
!lgNetReaderU32(&reader, &decoded.capabilityCount) ||
|
||||
!lgNetReaderZero(&reader, 4) ||
|
||||
!lgNetReaderU64(&reader, &decoded.sessionEpoch) ||
|
||||
!lgNetReaderBytes(&reader, decoded.nonce,
|
||||
sizeof(decoded.nonce)))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
const LGNetParseResult result = fixedDecodeResult(
|
||||
&reader, LG_NET_HELLO_ACK_WIRE_SIZE, size);
|
||||
if (result != LG_NET_PARSE_OK)
|
||||
return result;
|
||||
if (!lgNetHelloAckValid(&decoded))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
*hello = decoded;
|
||||
return LG_NET_PARSE_OK;
|
||||
}
|
||||
|
||||
bool lgNetCapabilityValid(const LGNetCapability * capability)
|
||||
{
|
||||
if (!capability || !capability->service ||
|
||||
!capability->versionMin ||
|
||||
capability->versionMin > capability->versionMax ||
|
||||
capability->flags & ~CAPABILITY_FLAGS ||
|
||||
!capability->maxPayloadLength ||
|
||||
capability->maxPayloadLength > LG_NET_MAX_PAYLOAD_LENGTH ||
|
||||
capability->maxDatagramPayload > capability->maxPayloadLength)
|
||||
return false;
|
||||
|
||||
if ((capability->flags & LG_NET_CAPABILITY_SELECTED) &&
|
||||
capability->versionMin != capability->versionMax)
|
||||
return false;
|
||||
if (!!(capability->flags & LG_NET_CAPABILITY_DATAGRAM) !=
|
||||
!!capability->maxDatagramPayload)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetCapabilityEncode(void * data, size_t size,
|
||||
const LGNetCapability * capability)
|
||||
{
|
||||
if (!data || size < LG_NET_CAPABILITY_WIRE_SIZE ||
|
||||
!lgNetCapabilityValid(capability))
|
||||
return false;
|
||||
|
||||
LGNetWriter writer;
|
||||
lgNetWriterInit(&writer, data, size);
|
||||
return
|
||||
lgNetWriterU16(&writer, capability->service) &&
|
||||
lgNetWriterU16(&writer, capability->versionMin) &&
|
||||
lgNetWriterU16(&writer, capability->versionMax) &&
|
||||
lgNetWriterU16(&writer, capability->flags) &&
|
||||
lgNetWriterU64(&writer, capability->features) &&
|
||||
lgNetWriterU32(&writer, capability->maxPayloadLength) &&
|
||||
lgNetWriterU32(&writer, capability->maxDatagramPayload) &&
|
||||
lgNetWriterU16(&writer, capability->maxBidirectionalStreams) &&
|
||||
lgNetWriterU16(&writer, capability->maxUnidirectionalStreams) &&
|
||||
lgNetWriterU32(&writer, 0) &&
|
||||
lgNetWriterSize(&writer) == LG_NET_CAPABILITY_WIRE_SIZE;
|
||||
}
|
||||
|
||||
LGNetParseResult lgNetCapabilityDecode(LGNetCapability * capability,
|
||||
const void * data, size_t size)
|
||||
{
|
||||
if (!capability || !data)
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
if (size < LG_NET_CAPABILITY_WIRE_SIZE)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
|
||||
LGNetCapability decoded;
|
||||
LGNetReader reader;
|
||||
memset(&decoded, 0, sizeof(decoded));
|
||||
lgNetReaderInit(&reader, data, size);
|
||||
if (!lgNetReaderU16(&reader, &decoded.service) ||
|
||||
!lgNetReaderU16(&reader, &decoded.versionMin) ||
|
||||
!lgNetReaderU16(&reader, &decoded.versionMax) ||
|
||||
!lgNetReaderU16(&reader, &decoded.flags) ||
|
||||
!lgNetReaderU64(&reader, &decoded.features) ||
|
||||
!lgNetReaderU32(&reader, &decoded.maxPayloadLength) ||
|
||||
!lgNetReaderU32(&reader, &decoded.maxDatagramPayload) ||
|
||||
!lgNetReaderU16(&reader, &decoded.maxBidirectionalStreams) ||
|
||||
!lgNetReaderU16(&reader, &decoded.maxUnidirectionalStreams) ||
|
||||
!lgNetReaderZero(&reader, 4))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
const LGNetParseResult result = fixedDecodeResult(
|
||||
&reader, LG_NET_CAPABILITY_WIRE_SIZE, size);
|
||||
if (result != LG_NET_PARSE_OK)
|
||||
return result;
|
||||
if (!lgNetCapabilityValid(&decoded))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
*capability = decoded;
|
||||
return LG_NET_PARSE_OK;
|
||||
}
|
||||
|
||||
size_t lgNetPasswordChallengeSize(
|
||||
const LGNetPasswordChallenge * challenge)
|
||||
{
|
||||
if (!lgNetPasswordChallengeValid(challenge))
|
||||
return 0;
|
||||
return LG_NET_PASSWORD_CHALLENGE_HEADER_SIZE +
|
||||
challenge->saltLength + challenge->challengeLength;
|
||||
}
|
||||
|
||||
bool lgNetPasswordChallengeValid(
|
||||
const LGNetPasswordChallenge * challenge)
|
||||
{
|
||||
return challenge && passwordAlgorithmKnown(challenge->algorithm) &&
|
||||
challenge->rounds && challenge->saltLength &&
|
||||
challenge->saltLength <= LG_NET_PASSWORD_SALT_MAX_LENGTH &&
|
||||
challenge->challengeLength &&
|
||||
challenge->challengeLength <= LG_NET_PASSWORD_CHALLENGE_MAX_LENGTH;
|
||||
}
|
||||
|
||||
bool lgNetPasswordChallengeEncode(void * data, size_t size,
|
||||
const LGNetPasswordChallenge * challenge)
|
||||
{
|
||||
const size_t required = lgNetPasswordChallengeSize(challenge);
|
||||
if (!data || !required || size < required)
|
||||
return false;
|
||||
|
||||
LGNetWriter writer;
|
||||
lgNetWriterInit(&writer, data, size);
|
||||
return
|
||||
lgNetWriterU16(&writer, challenge->algorithm) &&
|
||||
lgNetWriterU16(&writer, 0) &&
|
||||
lgNetWriterU32(&writer, challenge->rounds) &&
|
||||
lgNetWriterU16(&writer, challenge->saltLength) &&
|
||||
lgNetWriterU16(&writer, challenge->challengeLength) &&
|
||||
lgNetWriterU32(&writer, 0) &&
|
||||
lgNetWriterBytes(&writer, challenge->salt,
|
||||
challenge->saltLength) &&
|
||||
lgNetWriterBytes(&writer, challenge->challenge,
|
||||
challenge->challengeLength) &&
|
||||
lgNetWriterSize(&writer) == required;
|
||||
}
|
||||
|
||||
LGNetParseResult lgNetPasswordChallengeDecode(
|
||||
LGNetPasswordChallenge * challenge, const void * data, size_t size)
|
||||
{
|
||||
if (!challenge || !data)
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
if (size < LG_NET_PASSWORD_CHALLENGE_HEADER_SIZE)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
|
||||
LGNetPasswordChallenge decoded;
|
||||
LGNetReader reader;
|
||||
memset(&decoded, 0, sizeof(decoded));
|
||||
lgNetReaderInit(&reader, data, size);
|
||||
if (!lgNetReaderU16(&reader, &decoded.algorithm) ||
|
||||
!lgNetReaderZero(&reader, 2) ||
|
||||
!lgNetReaderU32(&reader, &decoded.rounds) ||
|
||||
!lgNetReaderU16(&reader, &decoded.saltLength) ||
|
||||
!lgNetReaderU16(&reader, &decoded.challengeLength) ||
|
||||
!lgNetReaderZero(&reader, 4))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
if (decoded.saltLength > LG_NET_PASSWORD_SALT_MAX_LENGTH ||
|
||||
decoded.challengeLength > LG_NET_PASSWORD_CHALLENGE_MAX_LENGTH)
|
||||
return LG_NET_PARSE_INVALID_LENGTH;
|
||||
|
||||
const size_t expected = LG_NET_PASSWORD_CHALLENGE_HEADER_SIZE +
|
||||
decoded.saltLength + decoded.challengeLength;
|
||||
if (size < expected)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
if (size != expected ||
|
||||
!lgNetReaderBytes(&reader, decoded.salt, decoded.saltLength) ||
|
||||
!lgNetReaderBytes(&reader, decoded.challenge,
|
||||
decoded.challengeLength))
|
||||
return LG_NET_PARSE_INVALID_LENGTH;
|
||||
if (!lgNetPasswordChallengeValid(&decoded))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
*challenge = decoded;
|
||||
return LG_NET_PARSE_OK;
|
||||
}
|
||||
|
||||
size_t lgNetPasswordResponseSize(const LGNetPasswordResponse * response)
|
||||
{
|
||||
if (!lgNetPasswordResponseValid(response))
|
||||
return 0;
|
||||
return LG_NET_PASSWORD_RESPONSE_HEADER_SIZE +
|
||||
response->nonceLength + response->proofLength;
|
||||
}
|
||||
|
||||
bool lgNetPasswordResponseValid(const LGNetPasswordResponse * response)
|
||||
{
|
||||
return response && passwordAlgorithmKnown(response->algorithm) &&
|
||||
response->nonceLength &&
|
||||
response->nonceLength <= LG_NET_PASSWORD_NONCE_MAX_LENGTH &&
|
||||
response->proofLength &&
|
||||
response->proofLength <= LG_NET_PASSWORD_PROOF_MAX_LENGTH;
|
||||
}
|
||||
|
||||
bool lgNetPasswordResponseEncode(void * data, size_t size,
|
||||
const LGNetPasswordResponse * response)
|
||||
{
|
||||
const size_t required = lgNetPasswordResponseSize(response);
|
||||
if (!data || !required || size < required)
|
||||
return false;
|
||||
|
||||
LGNetWriter writer;
|
||||
lgNetWriterInit(&writer, data, size);
|
||||
return
|
||||
lgNetWriterU16(&writer, response->algorithm) &&
|
||||
lgNetWriterU16(&writer, response->nonceLength) &&
|
||||
lgNetWriterU16(&writer, response->proofLength) &&
|
||||
lgNetWriterU16(&writer, 0) &&
|
||||
lgNetWriterU32(&writer, 0) &&
|
||||
lgNetWriterBytes(&writer, response->nonce,
|
||||
response->nonceLength) &&
|
||||
lgNetWriterBytes(&writer, response->proof,
|
||||
response->proofLength) &&
|
||||
lgNetWriterSize(&writer) == required;
|
||||
}
|
||||
|
||||
LGNetParseResult lgNetPasswordResponseDecode(
|
||||
LGNetPasswordResponse * response, const void * data, size_t size)
|
||||
{
|
||||
if (!response || !data)
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
if (size < LG_NET_PASSWORD_RESPONSE_HEADER_SIZE)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
|
||||
LGNetPasswordResponse decoded;
|
||||
LGNetReader reader;
|
||||
memset(&decoded, 0, sizeof(decoded));
|
||||
lgNetReaderInit(&reader, data, size);
|
||||
if (!lgNetReaderU16(&reader, &decoded.algorithm) ||
|
||||
!lgNetReaderU16(&reader, &decoded.nonceLength) ||
|
||||
!lgNetReaderU16(&reader, &decoded.proofLength) ||
|
||||
!lgNetReaderZero(&reader, 2) ||
|
||||
!lgNetReaderZero(&reader, 4))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
if (decoded.nonceLength > LG_NET_PASSWORD_NONCE_MAX_LENGTH ||
|
||||
decoded.proofLength > LG_NET_PASSWORD_PROOF_MAX_LENGTH)
|
||||
return LG_NET_PARSE_INVALID_LENGTH;
|
||||
|
||||
const size_t expected = LG_NET_PASSWORD_RESPONSE_HEADER_SIZE +
|
||||
decoded.nonceLength + decoded.proofLength;
|
||||
if (size < expected)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
if (size != expected ||
|
||||
!lgNetReaderBytes(&reader, decoded.nonce, decoded.nonceLength) ||
|
||||
!lgNetReaderBytes(&reader, decoded.proof, decoded.proofLength))
|
||||
return LG_NET_PARSE_INVALID_LENGTH;
|
||||
if (!lgNetPasswordResponseValid(&decoded))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
*response = decoded;
|
||||
return LG_NET_PARSE_OK;
|
||||
}
|
||||
|
||||
size_t lgNetAuthResultSize(const LGNetAuthResult * result)
|
||||
{
|
||||
if (!lgNetAuthResultValid(result))
|
||||
return 0;
|
||||
return LG_NET_AUTH_RESULT_HEADER_SIZE + result->proofLength;
|
||||
}
|
||||
|
||||
bool lgNetAuthResultValid(const LGNetAuthResult * result)
|
||||
{
|
||||
return result &&
|
||||
result->result >= LG_NET_AUTH_RESULT_ACCEPTED &&
|
||||
result->result <= LG_NET_AUTH_RESULT_ERROR &&
|
||||
result->proofLength <= LG_NET_PASSWORD_PROOF_MAX_LENGTH;
|
||||
}
|
||||
|
||||
bool lgNetAuthResultEncode(
|
||||
void * data, size_t size, const LGNetAuthResult * result)
|
||||
{
|
||||
const size_t required = lgNetAuthResultSize(result);
|
||||
if (!data || !required || size < required)
|
||||
return false;
|
||||
|
||||
LGNetWriter writer;
|
||||
lgNetWriterInit(&writer, data, size);
|
||||
return
|
||||
lgNetWriterU16(&writer, result->result) &&
|
||||
lgNetWriterU16(&writer, result->proofLength) &&
|
||||
lgNetWriterU32(&writer, result->retryAfterMs) &&
|
||||
lgNetWriterU32(&writer, 0) &&
|
||||
lgNetWriterBytes(&writer, result->proof,
|
||||
result->proofLength) &&
|
||||
lgNetWriterSize(&writer) == required;
|
||||
}
|
||||
|
||||
LGNetParseResult lgNetAuthResultDecode(LGNetAuthResult * result,
|
||||
const void * data, size_t size)
|
||||
{
|
||||
if (!result || !data)
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
if (size < LG_NET_AUTH_RESULT_HEADER_SIZE)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
|
||||
LGNetAuthResult decoded;
|
||||
LGNetReader reader;
|
||||
memset(&decoded, 0, sizeof(decoded));
|
||||
lgNetReaderInit(&reader, data, size);
|
||||
if (!lgNetReaderU16(&reader, &decoded.result) ||
|
||||
!lgNetReaderU16(&reader, &decoded.proofLength) ||
|
||||
!lgNetReaderU32(&reader, &decoded.retryAfterMs) ||
|
||||
!lgNetReaderZero(&reader, 4))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
if (decoded.proofLength > LG_NET_PASSWORD_PROOF_MAX_LENGTH)
|
||||
return LG_NET_PARSE_INVALID_LENGTH;
|
||||
|
||||
const size_t expected = LG_NET_AUTH_RESULT_HEADER_SIZE +
|
||||
decoded.proofLength;
|
||||
if (size < expected)
|
||||
return LG_NET_PARSE_TRUNCATED;
|
||||
if (size != expected ||
|
||||
!lgNetReaderBytes(&reader, decoded.proof, decoded.proofLength))
|
||||
return LG_NET_PARSE_INVALID_LENGTH;
|
||||
if (!lgNetAuthResultValid(&decoded))
|
||||
return LG_NET_PARSE_INVALID_VALUE;
|
||||
|
||||
*result = decoded;
|
||||
return LG_NET_PARSE_OK;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,355 +0,0 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common/network/wire.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static bool writerReserve(LGNetWriter * writer, size_t size)
|
||||
{
|
||||
if (!writer || writer->failed || writer->offset > writer->capacity ||
|
||||
size > writer->capacity - writer->offset)
|
||||
{
|
||||
if (writer)
|
||||
writer->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool readerReserve(LGNetReader * reader, size_t size)
|
||||
{
|
||||
if (!reader || reader->failed || reader->offset > reader->size ||
|
||||
size > reader->size - reader->offset)
|
||||
{
|
||||
if (reader)
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void lgNetWriterInit(LGNetWriter * writer, void * data, size_t capacity)
|
||||
{
|
||||
if (!writer)
|
||||
return;
|
||||
|
||||
writer->data = data;
|
||||
writer->capacity = capacity;
|
||||
writer->offset = 0;
|
||||
writer->failed = capacity && !data;
|
||||
}
|
||||
|
||||
size_t lgNetWriterSize(const LGNetWriter * writer)
|
||||
{
|
||||
return writer ? writer->offset : 0;
|
||||
}
|
||||
|
||||
size_t lgNetWriterRemaining(const LGNetWriter * writer)
|
||||
{
|
||||
return writer && !writer->failed && writer->offset <= writer->capacity ?
|
||||
writer->capacity - writer->offset : 0;
|
||||
}
|
||||
|
||||
bool lgNetWriterValid(const LGNetWriter * writer)
|
||||
{
|
||||
return writer && !writer->failed && writer->offset <= writer->capacity &&
|
||||
(!writer->capacity || writer->data);
|
||||
}
|
||||
|
||||
bool lgNetWriterU8(LGNetWriter * writer, uint8_t value)
|
||||
{
|
||||
if (!writerReserve(writer, 1))
|
||||
return false;
|
||||
|
||||
writer->data[writer->offset++] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetWriterU16(LGNetWriter * writer, uint16_t value)
|
||||
{
|
||||
if (!writerReserve(writer, 2))
|
||||
return false;
|
||||
|
||||
uint8_t * data = writer->data + writer->offset;
|
||||
data[0] = (uint8_t)(value );
|
||||
data[1] = (uint8_t)(value >> 8);
|
||||
writer->offset += 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetWriterU32(LGNetWriter * writer, uint32_t value)
|
||||
{
|
||||
if (!writerReserve(writer, 4))
|
||||
return false;
|
||||
|
||||
uint8_t * data = writer->data + writer->offset;
|
||||
data[0] = (uint8_t)(value );
|
||||
data[1] = (uint8_t)(value >> 8);
|
||||
data[2] = (uint8_t)(value >> 16);
|
||||
data[3] = (uint8_t)(value >> 24);
|
||||
writer->offset += 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetWriterU64(LGNetWriter * writer, uint64_t value)
|
||||
{
|
||||
if (!writerReserve(writer, 8))
|
||||
return false;
|
||||
|
||||
uint8_t * data = writer->data + writer->offset;
|
||||
data[0] = (uint8_t)(value );
|
||||
data[1] = (uint8_t)(value >> 8);
|
||||
data[2] = (uint8_t)(value >> 16);
|
||||
data[3] = (uint8_t)(value >> 24);
|
||||
data[4] = (uint8_t)(value >> 32);
|
||||
data[5] = (uint8_t)(value >> 40);
|
||||
data[6] = (uint8_t)(value >> 48);
|
||||
data[7] = (uint8_t)(value >> 56);
|
||||
writer->offset += 8;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetWriterI32(LGNetWriter * writer, int32_t value)
|
||||
{
|
||||
uint32_t bits;
|
||||
memcpy(&bits, &value, sizeof(bits));
|
||||
return lgNetWriterU32(writer, bits);
|
||||
}
|
||||
|
||||
bool lgNetWriterI64(LGNetWriter * writer, int64_t value)
|
||||
{
|
||||
uint64_t bits;
|
||||
memcpy(&bits, &value, sizeof(bits));
|
||||
return lgNetWriterU64(writer, bits);
|
||||
}
|
||||
|
||||
bool lgNetWriterBytes(
|
||||
LGNetWriter * writer, const void * data, size_t size)
|
||||
{
|
||||
if (!writerReserve(writer, size) || (size && !data))
|
||||
{
|
||||
if (writer)
|
||||
writer->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size)
|
||||
memmove(writer->data + writer->offset, data, size);
|
||||
writer->offset += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetWriterZero(LGNetWriter * writer, size_t size)
|
||||
{
|
||||
if (!writerReserve(writer, size))
|
||||
return false;
|
||||
|
||||
if (size)
|
||||
memset(writer->data + writer->offset, 0, size);
|
||||
writer->offset += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
void lgNetReaderInit(
|
||||
LGNetReader * reader, const void * data, size_t size)
|
||||
{
|
||||
if (!reader)
|
||||
return;
|
||||
|
||||
reader->data = data;
|
||||
reader->size = size;
|
||||
reader->offset = 0;
|
||||
reader->failed = size && !data;
|
||||
}
|
||||
|
||||
size_t lgNetReaderConsumed(const LGNetReader * reader)
|
||||
{
|
||||
return reader ? reader->offset : 0;
|
||||
}
|
||||
|
||||
size_t lgNetReaderRemaining(const LGNetReader * reader)
|
||||
{
|
||||
return reader && !reader->failed && reader->offset <= reader->size ?
|
||||
reader->size - reader->offset : 0;
|
||||
}
|
||||
|
||||
bool lgNetReaderValid(const LGNetReader * reader)
|
||||
{
|
||||
return reader && !reader->failed && reader->offset <= reader->size &&
|
||||
(!reader->size || reader->data);
|
||||
}
|
||||
|
||||
bool lgNetReaderU8(LGNetReader * reader, uint8_t * value)
|
||||
{
|
||||
if (!readerReserve(reader, 1) || !value)
|
||||
{
|
||||
if (reader)
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
*value = reader->data[reader->offset++];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetReaderU16(LGNetReader * reader, uint16_t * value)
|
||||
{
|
||||
if (!readerReserve(reader, 2) || !value)
|
||||
{
|
||||
if (reader)
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t * data = reader->data + reader->offset;
|
||||
*value =
|
||||
(uint16_t)data[0] |
|
||||
(uint16_t)data[1] << 8;
|
||||
reader->offset += 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetReaderU32(LGNetReader * reader, uint32_t * value)
|
||||
{
|
||||
if (!readerReserve(reader, 4) || !value)
|
||||
{
|
||||
if (reader)
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t * data = reader->data + reader->offset;
|
||||
*value =
|
||||
(uint32_t)data[0] |
|
||||
(uint32_t)data[1] << 8 |
|
||||
(uint32_t)data[2] << 16 |
|
||||
(uint32_t)data[3] << 24;
|
||||
reader->offset += 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetReaderU64(LGNetReader * reader, uint64_t * value)
|
||||
{
|
||||
if (!readerReserve(reader, 8) || !value)
|
||||
{
|
||||
if (reader)
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t * data = reader->data + reader->offset;
|
||||
*value =
|
||||
(uint64_t)data[0] |
|
||||
(uint64_t)data[1] << 8 |
|
||||
(uint64_t)data[2] << 16 |
|
||||
(uint64_t)data[3] << 24 |
|
||||
(uint64_t)data[4] << 32 |
|
||||
(uint64_t)data[5] << 40 |
|
||||
(uint64_t)data[6] << 48 |
|
||||
(uint64_t)data[7] << 56;
|
||||
reader->offset += 8;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetReaderI32(LGNetReader * reader, int32_t * value)
|
||||
{
|
||||
uint32_t bits;
|
||||
if (!value || !lgNetReaderU32(reader, &bits))
|
||||
{
|
||||
if (reader)
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(value, &bits, sizeof(*value));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetReaderI64(LGNetReader * reader, int64_t * value)
|
||||
{
|
||||
uint64_t bits;
|
||||
if (!value || !lgNetReaderU64(reader, &bits))
|
||||
{
|
||||
if (reader)
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(value, &bits, sizeof(*value));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetReaderBytes(LGNetReader * reader, void * data, size_t size)
|
||||
{
|
||||
if (!readerReserve(reader, size) || (size && !data))
|
||||
{
|
||||
if (reader)
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size)
|
||||
memcpy(data, reader->data + reader->offset, size);
|
||||
reader->offset += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetReaderView(
|
||||
LGNetReader * reader, const uint8_t ** data, size_t size)
|
||||
{
|
||||
if (!readerReserve(reader, size) || !data)
|
||||
{
|
||||
if (reader)
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = size ? reader->data + reader->offset : NULL;
|
||||
reader->offset += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetReaderSkip(LGNetReader * reader, size_t size)
|
||||
{
|
||||
if (!readerReserve(reader, size))
|
||||
return false;
|
||||
|
||||
reader->offset += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgNetReaderZero(LGNetReader * reader, size_t size)
|
||||
{
|
||||
if (!readerReserve(reader, size))
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
if (reader->data[reader->offset + i])
|
||||
{
|
||||
reader->failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
reader->offset += size;
|
||||
return true;
|
||||
}
|
||||
@@ -69,9 +69,9 @@
|
||||
<ClCompile Include="CClipboardRing.cpp" />
|
||||
<ClCompile Include="CDebug.cpp" />
|
||||
<ClCompile Include="CPipeEndpoint.cpp" />
|
||||
<ClCompile Include="..\..\common\src\network\protocol.c" />
|
||||
<ClCompile Include="..\..\common\src\network\services.c" />
|
||||
<ClCompile Include="..\..\common\src\network\wire.c" />
|
||||
<ClCompile Include="..\..\repos\LGProtocol\src\network\protocol.c" />
|
||||
<ClCompile Include="..\..\repos\LGProtocol\src\network\services.c" />
|
||||
<ClCompile Include="..\..\repos\LGProtocol\src\network\wire.c" />
|
||||
<ClCompile Include="RefreshRate.cpp" />
|
||||
<ClCompile Include="WCCopy.cpp" />
|
||||
<ClCompile Include="WCCopyAVX2.cpp">
|
||||
@@ -89,9 +89,6 @@
|
||||
<ClInclude Include="CDebug.h" />
|
||||
<ClInclude Include="ClipboardRing.h" />
|
||||
<ClInclude Include="CPipeEndpoint.h" />
|
||||
<ClInclude Include="..\..\common\include\common\network\protocol.h" />
|
||||
<ClInclude Include="..\..\common\include\common\network\services.h" />
|
||||
<ClInclude Include="..\..\common\include\common\network\wire.h" />
|
||||
<ClInclude Include="CSRWLock.h" />
|
||||
<ClInclude Include="DefaultDisplayModes.h" />
|
||||
<ClInclude Include="InputPipeProtocol.h" />
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<ClCompile Include="CPipeEndpoint.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\common\src\network\services.c">
|
||||
<ClCompile Include="..\..\repos\LGProtocol\src\network\services.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RefreshRate.cpp">
|
||||
@@ -62,9 +62,6 @@
|
||||
<ClInclude Include="CPipeEndpoint.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\common\include\common\network\services.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CSRWLock.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "CDebug.h"
|
||||
#include "CSRWLock.h"
|
||||
#include "NetworkIdentity.h"
|
||||
#include "common/network/protocol.h"
|
||||
#include <LGProtocol/NetworkProtocol.h>
|
||||
|
||||
#include <msquic.h>
|
||||
#include <bcrypt.h>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/network/protocol.h"
|
||||
#include <LGProtocol/NetworkProtocol.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
Submodule repos/LGProtocol updated: c9659b314a...8693254b9b
Reference in New Issue
Block a user