Add byteswapping macros for big-endian systems

This commit is contained in:
Cameron Gutman
2021-04-17 21:43:13 -05:00
parent efaeade7a6
commit 4304e597d8
8 changed files with 146 additions and 92 deletions

View File

@@ -221,9 +221,9 @@ static void ReceiveThreadProc(void* context) {
} }
// Convert fields to host byte-order // Convert fields to host byte-order
rtp->sequenceNumber = htons(rtp->sequenceNumber); rtp->sequenceNumber = BE16(rtp->sequenceNumber);
rtp->timestamp = htonl(rtp->timestamp); rtp->timestamp = BE32(rtp->timestamp);
rtp->ssrc = htonl(rtp->ssrc); rtp->ssrc = BE32(rtp->ssrc);
queueStatus = RtpqAddPacket(&rtpReorderQueue, (PRTP_PACKET)packet, &packet->q.rentry); queueStatus = RtpqAddPacket(&rtpReorderQueue, (PRTP_PACKET)packet, &packet->q.rentry);
if (RTPQ_HANDLE_NOW(queueStatus)) { if (RTPQ_HANDLE_NOW(queueStatus)) {

View File

@@ -10,30 +10,30 @@ void BbInitializeWrappedBuffer(PBYTE_BUFFER buff, char* data, int offset, int le
// Get the long long in the correct byte order // Get the long long in the correct byte order
static uint64_t byteSwap64(PBYTE_BUFFER buff, uint64_t l) { static uint64_t byteSwap64(PBYTE_BUFFER buff, uint64_t l) {
if (buff->byteOrder == BYTE_ORDER_BIG) { if (buff->byteOrder == BYTE_ORDER_BIG) {
return HTONLL(l); return BE64(l);
} }
else { else {
return l; return LE64(l);
} }
} }
// Get the int in the correct byte order // Get the int in the correct byte order
static uint32_t byteSwap32(PBYTE_BUFFER buff, uint32_t i) { static uint32_t byteSwap32(PBYTE_BUFFER buff, uint32_t i) {
if (buff->byteOrder == BYTE_ORDER_BIG) { if (buff->byteOrder == BYTE_ORDER_BIG) {
return htonl(i); return BE32(i);
} }
else { else {
return i; return LE32(i);
} }
} }
// Get the short in the correct byte order // Get the short in the correct byte order
static uint16_t byteSwap16(PBYTE_BUFFER buff, uint16_t s) { static uint16_t byteSwap16(PBYTE_BUFFER buff, uint16_t s) {
if (buff->byteOrder == BYTE_ORDER_BIG) { if (buff->byteOrder == BYTE_ORDER_BIG) {
return htons(s); return BE16(s);
} }
else { else {
return s; return LE16(s);
} }
} }

View File

@@ -5,18 +5,6 @@
#define BYTE_ORDER_LITTLE 1 #define BYTE_ORDER_LITTLE 1
#define BYTE_ORDER_BIG 2 #define BYTE_ORDER_BIG 2
#ifndef HTONLL
#define HTONLL(x) \
((((x) & 0xff00000000000000ull) >> 56) \
| (((x) & 0x00ff000000000000ull) >> 40) \
| (((x) & 0x0000ff0000000000ull) >> 24) \
| (((x) & 0x000000ff00000000ull) >> 8) \
| (((x) & 0x00000000ff000000ull) << 8) \
| (((x) & 0x0000000000ff0000ull) << 24) \
| (((x) & 0x000000000000ff00ull) << 40) \
| (((x) & 0x00000000000000ffull) << 56))
#endif
typedef struct _BYTE_BUFFER { typedef struct _BYTE_BUFFER {
char* buffer; char* buffer;
unsigned int length; unsigned int length;

View File

@@ -369,6 +369,9 @@ static PNVCTL_TCP_PACKET_HEADER readNvctlPacketTcp(void) {
return NULL; return NULL;
} }
staticHeader.type = LE16(staticHeader.type);
staticHeader.payloadLength = LE16(staticHeader.payloadLength);
fullPacket = (PNVCTL_TCP_PACKET_HEADER)malloc(staticHeader.payloadLength + sizeof(staticHeader)); fullPacket = (PNVCTL_TCP_PACKET_HEADER)malloc(staticHeader.payloadLength + sizeof(staticHeader));
if (fullPacket == NULL) { if (fullPacket == NULL) {
return NULL; return NULL;
@@ -390,6 +393,13 @@ static bool encryptControlMessage(PNVCTL_ENCRYPTED_PACKET_HEADER encPacket, PNVC
unsigned char iv[16]; unsigned char iv[16];
int encryptedSize = sizeof(*packet) + packet->payloadLength; int encryptedSize = sizeof(*packet) + packet->payloadLength;
encPacket->encryptedHeaderType = LE16(encPacket->encryptedHeaderType);
encPacket->length = LE16(encPacket->length);
encPacket->seq = LE32(encPacket->seq);
packet->type = LE16(packet->type);
packet->payloadLength = LE16(packet->payloadLength);
// This is a truncating cast, but it's what Nvidia does, so we have to mimic it. // This is a truncating cast, but it's what Nvidia does, so we have to mimic it.
memset(iv, 0, sizeof(iv)); memset(iv, 0, sizeof(iv));
iv[0] = (unsigned char)encPacket->seq; iv[0] = (unsigned char)encPacket->seq;
@@ -479,7 +489,7 @@ static bool sendMessageEnet(short ptype, short paylen, const void* payload) {
packet->payloadLength = paylen; packet->payloadLength = paylen;
memcpy(&packet[1], payload, paylen); memcpy(&packet[1], payload, paylen);
// Encrypt the data into the final packet // Encrypt the data into the final packet (and byteswap for BE machines)
if (!encryptControlMessage(encPacket, packet)) { if (!encryptControlMessage(encPacket, packet)) {
Limelog("Failed to encrypt control stream message\n"); Limelog("Failed to encrypt control stream message\n");
enet_packet_destroy(enetPacket); enet_packet_destroy(enetPacket);
@@ -497,7 +507,7 @@ static bool sendMessageEnet(short ptype, short paylen, const void* payload) {
} }
packet = (PNVCTL_ENET_PACKET_HEADER_V1)enetPacket->data; packet = (PNVCTL_ENET_PACKET_HEADER_V1)enetPacket->data;
packet->type = ptype; packet->type = LE16(ptype);
memcpy(&packet[1], payload, paylen); memcpy(&packet[1], payload, paylen);
} }
@@ -528,8 +538,8 @@ static bool sendMessageTcp(short ptype, short paylen, const void* payload) {
return false; return false;
} }
packet->type = ptype; packet->type = LE16(ptype);
packet->payloadLength = paylen; packet->payloadLength = LE16(paylen);
memcpy(&packet[1], payload, paylen); memcpy(&packet[1], payload, paylen);
err = send(ctlSock, (char*) packet, sizeof(*packet) + paylen, 0); err = send(ctlSock, (char*) packet, sizeof(*packet) + paylen, 0);
@@ -680,23 +690,34 @@ static void controlReceiveThreadFunc(void* context) {
} }
ctlHdr = (PNVCTL_ENET_PACKET_HEADER_V1)event.packet->data; ctlHdr = (PNVCTL_ENET_PACKET_HEADER_V1)event.packet->data;
ctlHdr->type = LE16(ctlHdr->type);
if (encryptedControlStream) { if (encryptedControlStream) {
// V2 headers can be interpreted as V1 headers for the purpose of examining type, // V2 headers can be interpreted as V1 headers for the purpose of examining type,
// so this check is safe. // so this check is safe.
if (ctlHdr->type == 0x0001) { if (ctlHdr->type == 0x0001) {
PNVCTL_ENCRYPTED_PACKET_HEADER encHdr;
if (event.packet->dataLength < sizeof(NVCTL_ENCRYPTED_PACKET_HEADER)) { if (event.packet->dataLength < sizeof(NVCTL_ENCRYPTED_PACKET_HEADER)) {
Limelog("Discarding runt encrypted control packet: %d < %d\n", event.packet->dataLength, (int)sizeof(NVCTL_ENCRYPTED_PACKET_HEADER)); Limelog("Discarding runt encrypted control packet: %d < %d\n", event.packet->dataLength, (int)sizeof(NVCTL_ENCRYPTED_PACKET_HEADER));
enet_packet_destroy(event.packet); enet_packet_destroy(event.packet);
continue; continue;
} }
// encryptedHeaderType is already byteswapped by aliasing through ctlHdr above
encHdr = (PNVCTL_ENCRYPTED_PACKET_HEADER)event.packet->data;
encHdr->length = LE16(encHdr->length);
encHdr->seq = LE32(encHdr->seq);
ctlHdr = NULL; ctlHdr = NULL;
if (!decryptControlMessageToV1((PNVCTL_ENCRYPTED_PACKET_HEADER)event.packet->data, &ctlHdr, &packetLength)) { if (!decryptControlMessageToV1(encHdr, &ctlHdr, &packetLength)) {
Limelog("Failed to decrypt control packet of size %d\n", event.packet->dataLength); Limelog("Failed to decrypt control packet of size %d\n", event.packet->dataLength);
enet_packet_destroy(event.packet); enet_packet_destroy(event.packet);
continue; continue;
} }
// We need to byteswap the unsealed header too
ctlHdr->type = LE16(ctlHdr->type);
} }
else { else {
// What do we do here??? // What do we do here???
@@ -706,7 +727,6 @@ static void controlReceiveThreadFunc(void* context) {
} }
else { else {
// Take ownership of the packet data directly for the non-encrypted case // Take ownership of the packet data directly for the non-encrypted case
ctlHdr = (PNVCTL_ENET_PACKET_HEADER_V1)event.packet->data;
packetLength = event.packet->dataLength; packetLength = event.packet->dataLength;
event.packet->data = NULL; event.packet->data = NULL;
} }
@@ -879,11 +899,11 @@ static void requestIdrFrame(void) {
// Form the payload // Form the payload
if (lastSeenFrame < 0x20) { if (lastSeenFrame < 0x20) {
payload[0] = 0; payload[0] = 0;
payload[1] = lastSeenFrame; payload[1] = LE64(lastSeenFrame);
} }
else { else {
payload[0] = lastSeenFrame - 0x20; payload[0] = LE64(lastSeenFrame - 0x20);
payload[1] = lastSeenFrame; payload[1] = LE64(lastSeenFrame);
} }
payload[2] = 0; payload[2] = 0;
@@ -912,6 +932,8 @@ static void requestIdrFrame(void) {
static void requestInvalidateReferenceFrames(void) { static void requestInvalidateReferenceFrames(void) {
int64_t payload[3]; int64_t payload[3];
PQUEUED_FRAME_INVALIDATION_TUPLE qfit; PQUEUED_FRAME_INVALIDATION_TUPLE qfit;
int startFrame;
int endFrame;
LC_ASSERT(isReferenceFrameInvalidationEnabled()); LC_ASSERT(isReferenceFrameInvalidationEnabled());
@@ -921,17 +943,20 @@ static void requestInvalidateReferenceFrames(void) {
LC_ASSERT(qfit->startFrame <= qfit->endFrame); LC_ASSERT(qfit->startFrame <= qfit->endFrame);
payload[0] = qfit->startFrame; startFrame = qfit->startFrame;
payload[1] = qfit->endFrame; endFrame = qfit->endFrame;
payload[2] = 0;
// Aggregate all lost frames into one range // Aggregate all lost frames into one range
do { do {
LC_ASSERT(qfit->endFrame >= payload[1]); LC_ASSERT(qfit->endFrame >= endFrame);
payload[1] = qfit->endFrame; endFrame = qfit->endFrame;
free(qfit); free(qfit);
} while (getNextFrameInvalidationTuple(&qfit)); } while (getNextFrameInvalidationTuple(&qfit));
payload[0] = LE64(startFrame);
payload[1] = LE64(endFrame);
payload[2] = 0;
// Send the reference frame invalidation request and read the response // Send the reference frame invalidation request and read the response
if (!sendMessageAndDiscardReply(packetTypes[IDX_INVALIDATE_REF_FRAMES], if (!sendMessageAndDiscardReply(packetTypes[IDX_INVALIDATE_REF_FRAMES],
payloadLengths[IDX_INVALIDATE_REF_FRAMES], payload)) { payloadLengths[IDX_INVALIDATE_REF_FRAMES], payload)) {
@@ -940,7 +965,7 @@ static void requestInvalidateReferenceFrames(void) {
return; return;
} }
Limelog("Invalidate reference frame request sent (%d to %d)\n", (int)payload[0], (int)payload[1]); Limelog("Invalidate reference frame request sent (%d to %d)\n", startFrame, endFrame);
} }
static void invalidateRefFramesFunc(void* context) { static void invalidateRefFramesFunc(void* context) {

View File

@@ -110,7 +110,7 @@ static void inputSendThreadProc(void* context) {
} }
// If it's a multi-controller packet we can do batching // If it's a multi-controller packet we can do batching
if (holder->packet.multiController.header.packetType == htonl(PACKET_TYPE_MULTI_CONTROLLER)) { if (holder->packet.multiController.header.packetType == BE32(PACKET_TYPE_MULTI_CONTROLLER)) {
PPACKET_HOLDER controllerBatchHolder; PPACKET_HOLDER controllerBatchHolder;
PNV_MULTI_CONTROLLER_PACKET origPkt; PNV_MULTI_CONTROLLER_PACKET origPkt;
@@ -124,7 +124,7 @@ static void inputSendThreadProc(void* context) {
} }
// If it's not a controller packet, we're done // If it's not a controller packet, we're done
if (controllerBatchHolder->packet.multiController.header.packetType != htonl(PACKET_TYPE_MULTI_CONTROLLER)) { if (controllerBatchHolder->packet.multiController.header.packetType != BE32(PACKET_TYPE_MULTI_CONTROLLER)) {
break; break;
} }
@@ -159,10 +159,10 @@ static void inputSendThreadProc(void* context) {
} }
} }
// If it's a relative mouse move packet, we can also do batching // If it's a relative mouse move packet, we can also do batching
else if (holder->packet.mouseMoveRel.header.packetType == htonl(PACKET_TYPE_REL_MOUSE_MOVE)) { else if (holder->packet.mouseMoveRel.header.packetType == BE32(PACKET_TYPE_REL_MOUSE_MOVE)) {
PPACKET_HOLDER mouseBatchHolder; PPACKET_HOLDER mouseBatchHolder;
int totalDeltaX = (short)htons(holder->packet.mouseMoveRel.deltaX); int totalDeltaX = (short)BE16(holder->packet.mouseMoveRel.deltaX);
int totalDeltaY = (short)htons(holder->packet.mouseMoveRel.deltaY); int totalDeltaY = (short)BE16(holder->packet.mouseMoveRel.deltaY);
for (;;) { for (;;) {
int partialDeltaX; int partialDeltaX;
@@ -174,12 +174,12 @@ static void inputSendThreadProc(void* context) {
} }
// If it's not a mouse move packet, we're done // If it's not a mouse move packet, we're done
if (mouseBatchHolder->packet.mouseMoveRel.header.packetType != htonl(PACKET_TYPE_REL_MOUSE_MOVE)) { if (mouseBatchHolder->packet.mouseMoveRel.header.packetType != BE32(PACKET_TYPE_REL_MOUSE_MOVE)) {
break; break;
} }
partialDeltaX = (short)htons(mouseBatchHolder->packet.mouseMoveRel.deltaX); partialDeltaX = (short)BE16(mouseBatchHolder->packet.mouseMoveRel.deltaX);
partialDeltaY = (short)htons(mouseBatchHolder->packet.mouseMoveRel.deltaY); partialDeltaY = (short)BE16(mouseBatchHolder->packet.mouseMoveRel.deltaY);
// Check for overflow // Check for overflow
if (partialDeltaX + totalDeltaX > INT16_MAX || if (partialDeltaX + totalDeltaX > INT16_MAX ||
@@ -203,11 +203,11 @@ static void inputSendThreadProc(void* context) {
} }
// Update the original packet // Update the original packet
holder->packet.mouseMoveRel.deltaX = htons((short)totalDeltaX); holder->packet.mouseMoveRel.deltaX = BE16((short)totalDeltaX);
holder->packet.mouseMoveRel.deltaY = htons((short)totalDeltaY); holder->packet.mouseMoveRel.deltaY = BE16((short)totalDeltaY);
} }
// If it's an absolute mouse move packet, we should only send the latest // If it's an absolute mouse move packet, we should only send the latest
else if (holder->packet.mouseMoveAbs.header.packetType == htonl(PACKET_TYPE_ABS_MOUSE_MOVE)) { else if (holder->packet.mouseMoveAbs.header.packetType == BE32(PACKET_TYPE_ABS_MOUSE_MOVE)) {
for (;;) { for (;;) {
PPACKET_HOLDER mouseBatchHolder; PPACKET_HOLDER mouseBatchHolder;
@@ -217,7 +217,7 @@ static void inputSendThreadProc(void* context) {
} }
// If it's not a mouse position packet, we're done // If it's not a mouse position packet, we're done
if (mouseBatchHolder->packet.mouseMoveAbs.header.packetType != htonl(PACKET_TYPE_ABS_MOUSE_MOVE)) { if (mouseBatchHolder->packet.mouseMoveAbs.header.packetType != BE32(PACKET_TYPE_ABS_MOUSE_MOVE)) {
break; break;
} }
@@ -257,7 +257,7 @@ static void inputSendThreadProc(void* context) {
} }
// Prepend the length to the message // Prepend the length to the message
encryptedLengthPrefix = htonl(encryptedSize); encryptedLengthPrefix = BE32(encryptedSize);
memcpy(&encryptedBuffer[0], &encryptedLengthPrefix, 4); memcpy(&encryptedBuffer[0], &encryptedLengthPrefix, 4);
if (AppVersionQuad[0] < 5) { if (AppVersionQuad[0] < 5) {
@@ -310,9 +310,9 @@ static int sendEnableHaptics(void) {
} }
holder->packetLength = sizeof(NV_HAPTICS_PACKET); holder->packetLength = sizeof(NV_HAPTICS_PACKET);
holder->packet.haptics.header.packetType = htonl(PACKET_TYPE_HAPTICS); holder->packet.haptics.header.packetType = BE32(PACKET_TYPE_HAPTICS);
holder->packet.haptics.magicA = H_MAGIC_A; holder->packet.haptics.magicA = LE32(H_MAGIC_A);
holder->packet.haptics.magicB = H_MAGIC_B; holder->packet.haptics.magicB = LE32(H_MAGIC_B);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) { if (err != LBQ_SUCCESS) {
@@ -398,14 +398,15 @@ int LiSendMouseMoveEvent(short deltaX, short deltaY) {
} }
holder->packetLength = sizeof(NV_REL_MOUSE_MOVE_PACKET); holder->packetLength = sizeof(NV_REL_MOUSE_MOVE_PACKET);
holder->packet.mouseMoveRel.header.packetType = htonl(PACKET_TYPE_REL_MOUSE_MOVE); holder->packet.mouseMoveRel.header.packetType = BE32(PACKET_TYPE_REL_MOUSE_MOVE);
holder->packet.mouseMoveRel.magic = MOUSE_MOVE_REL_MAGIC; holder->packet.mouseMoveRel.magic = MOUSE_MOVE_REL_MAGIC;
// On Gen 5 servers, the header code is incremented by one // On Gen 5 servers, the header code is incremented by one
if (AppVersionQuad[0] >= 5) { if (AppVersionQuad[0] >= 5) {
holder->packet.mouseMoveRel.magic++; holder->packet.mouseMoveRel.magic++;
} }
holder->packet.mouseMoveRel.deltaX = htons(deltaX); holder->packet.mouseMoveRel.magic = LE32(holder->packet.mouseMoveRel.magic);
holder->packet.mouseMoveRel.deltaY = htons(deltaY); holder->packet.mouseMoveRel.deltaX = BE16(deltaX);
holder->packet.mouseMoveRel.deltaY = BE16(deltaY);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) { if (err != LBQ_SUCCESS) {
@@ -430,10 +431,10 @@ int LiSendMousePositionEvent(short x, short y, short referenceWidth, short refer
} }
holder->packetLength = sizeof(NV_ABS_MOUSE_MOVE_PACKET); holder->packetLength = sizeof(NV_ABS_MOUSE_MOVE_PACKET);
holder->packet.mouseMoveAbs.header.packetType = htonl(PACKET_TYPE_ABS_MOUSE_MOVE); holder->packet.mouseMoveAbs.header.packetType = BE32(PACKET_TYPE_ABS_MOUSE_MOVE);
holder->packet.mouseMoveAbs.magic = MOUSE_MOVE_ABS_MAGIC; holder->packet.mouseMoveAbs.magic = LE32(MOUSE_MOVE_ABS_MAGIC);
holder->packet.mouseMoveAbs.x = htons(x); holder->packet.mouseMoveAbs.x = BE16(x);
holder->packet.mouseMoveAbs.y = htons(y); holder->packet.mouseMoveAbs.y = BE16(y);
holder->packet.mouseMoveAbs.unused = 0; holder->packet.mouseMoveAbs.unused = 0;
// There appears to be a rounding error in GFE's scaling calculation which prevents // There appears to be a rounding error in GFE's scaling calculation which prevents
@@ -441,8 +442,8 @@ int LiSendMousePositionEvent(short x, short y, short referenceWidth, short refer
// resolutions with a higher desktop resolution (like streaming 720p with a desktop // resolutions with a higher desktop resolution (like streaming 720p with a desktop
// resolution of 1080p, or streaming 720p/1080p with a desktop resolution of 4K). // resolution of 1080p, or streaming 720p/1080p with a desktop resolution of 4K).
// Subtracting one from the reference dimensions seems to work around this issue. // Subtracting one from the reference dimensions seems to work around this issue.
holder->packet.mouseMoveAbs.width = htons(referenceWidth - 1); holder->packet.mouseMoveAbs.width = BE16(referenceWidth - 1);
holder->packet.mouseMoveAbs.height = htons(referenceHeight - 1); holder->packet.mouseMoveAbs.height = BE16(referenceHeight - 1);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) { if (err != LBQ_SUCCESS) {
@@ -467,12 +468,12 @@ int LiSendMouseButtonEvent(char action, int button) {
} }
holder->packetLength = sizeof(NV_MOUSE_BUTTON_PACKET); holder->packetLength = sizeof(NV_MOUSE_BUTTON_PACKET);
holder->packet.mouseButton.header.packetType = htonl(PACKET_TYPE_MOUSE_BUTTON); holder->packet.mouseButton.header.packetType = BE32(PACKET_TYPE_MOUSE_BUTTON);
holder->packet.mouseButton.action = action; holder->packet.mouseButton.action = action;
if (AppVersionQuad[0] >= 5) { if (AppVersionQuad[0] >= 5) {
holder->packet.mouseButton.action++; holder->packet.mouseButton.action++;
} }
holder->packet.mouseButton.button = htonl(button); holder->packet.mouseButton.button = BE32(button);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) { if (err != LBQ_SUCCESS) {
@@ -539,10 +540,10 @@ int LiSendKeyboardEvent(short keyCode, char keyAction, char modifiers) {
} }
holder->packetLength = sizeof(NV_KEYBOARD_PACKET); holder->packetLength = sizeof(NV_KEYBOARD_PACKET);
holder->packet.keyboard.header.packetType = htonl(PACKET_TYPE_KEYBOARD); holder->packet.keyboard.header.packetType = BE32(PACKET_TYPE_KEYBOARD);
holder->packet.keyboard.keyAction = keyAction; holder->packet.keyboard.keyAction = keyAction;
holder->packet.keyboard.zero1 = 0; holder->packet.keyboard.zero1 = 0;
holder->packet.keyboard.keyCode = keyCode; holder->packet.keyboard.keyCode = LE16(keyCode);
holder->packet.keyboard.modifiers = modifiers; holder->packet.keyboard.modifiers = modifiers;
holder->packet.keyboard.zero2 = 0; holder->packet.keyboard.zero2 = 0;
@@ -574,41 +575,42 @@ static int sendControllerEventInternal(short controllerNumber, short activeGamep
// Generation 3 servers don't support multiple controllers so we send // Generation 3 servers don't support multiple controllers so we send
// the legacy packet // the legacy packet
holder->packetLength = sizeof(NV_CONTROLLER_PACKET); holder->packetLength = sizeof(NV_CONTROLLER_PACKET);
holder->packet.controller.header.packetType = htonl(PACKET_TYPE_CONTROLLER); holder->packet.controller.header.packetType = BE32(PACKET_TYPE_CONTROLLER);
holder->packet.controller.headerA = C_HEADER_A; holder->packet.controller.headerA = LE32(C_HEADER_A);
holder->packet.controller.headerB = C_HEADER_B; holder->packet.controller.headerB = LE16(C_HEADER_B);
holder->packet.controller.buttonFlags = buttonFlags; holder->packet.controller.buttonFlags = LE16(buttonFlags);
holder->packet.controller.leftTrigger = leftTrigger; holder->packet.controller.leftTrigger = leftTrigger;
holder->packet.controller.rightTrigger = rightTrigger; holder->packet.controller.rightTrigger = rightTrigger;
holder->packet.controller.leftStickX = leftStickX; holder->packet.controller.leftStickX = LE16(leftStickX);
holder->packet.controller.leftStickY = leftStickY; holder->packet.controller.leftStickY = LE16(leftStickY);
holder->packet.controller.rightStickX = rightStickX; holder->packet.controller.rightStickX = LE16(rightStickX);
holder->packet.controller.rightStickY = rightStickY; holder->packet.controller.rightStickY = LE16(rightStickY);
holder->packet.controller.tailA = C_TAIL_A; holder->packet.controller.tailA = LE32(C_TAIL_A);
holder->packet.controller.tailB = C_TAIL_B; holder->packet.controller.tailB = LE16(C_TAIL_B);
} }
else { else {
// Generation 4+ servers support passing the controller number // Generation 4+ servers support passing the controller number
holder->packetLength = sizeof(NV_MULTI_CONTROLLER_PACKET); holder->packetLength = sizeof(NV_MULTI_CONTROLLER_PACKET);
holder->packet.multiController.header.packetType = htonl(PACKET_TYPE_MULTI_CONTROLLER); holder->packet.multiController.header.packetType = BE32(PACKET_TYPE_MULTI_CONTROLLER);
holder->packet.multiController.headerA = MC_HEADER_A; holder->packet.multiController.headerA = MC_HEADER_A;
// On Gen 5 servers, the header code is decremented by one // On Gen 5 servers, the header code is decremented by one
if (AppVersionQuad[0] >= 5) { if (AppVersionQuad[0] >= 5) {
holder->packet.multiController.headerA--; holder->packet.multiController.headerA--;
} }
holder->packet.multiController.headerB = MC_HEADER_B; holder->packet.multiController.headerA = LE32(holder->packet.multiController.headerA);
holder->packet.multiController.controllerNumber = controllerNumber; holder->packet.multiController.headerB = LE16(MC_HEADER_B);
holder->packet.multiController.activeGamepadMask = activeGamepadMask; holder->packet.multiController.controllerNumber = LE16(controllerNumber);
holder->packet.multiController.midB = MC_MID_B; holder->packet.multiController.activeGamepadMask = LE16(activeGamepadMask);
holder->packet.multiController.buttonFlags = buttonFlags; holder->packet.multiController.midB = LE16(MC_MID_B);
holder->packet.multiController.buttonFlags = LE16(buttonFlags);
holder->packet.multiController.leftTrigger = leftTrigger; holder->packet.multiController.leftTrigger = leftTrigger;
holder->packet.multiController.rightTrigger = rightTrigger; holder->packet.multiController.rightTrigger = rightTrigger;
holder->packet.multiController.leftStickX = leftStickX; holder->packet.multiController.leftStickX = LE16(leftStickX);
holder->packet.multiController.leftStickY = leftStickY; holder->packet.multiController.leftStickY = LE16(leftStickY);
holder->packet.multiController.rightStickX = rightStickX; holder->packet.multiController.rightStickX = LE16(rightStickX);
holder->packet.multiController.rightStickY = rightStickY; holder->packet.multiController.rightStickY = LE16(rightStickY);
holder->packet.multiController.tailA = MC_TAIL_A; holder->packet.multiController.tailA = LE32(MC_TAIL_A);
holder->packet.multiController.tailB = MC_TAIL_B; holder->packet.multiController.tailB = LE16(MC_TAIL_B);
} }
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry); err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
@@ -656,7 +658,7 @@ int LiSendHighResScrollEvent(short scrollAmount) {
} }
holder->packetLength = sizeof(NV_SCROLL_PACKET); holder->packetLength = sizeof(NV_SCROLL_PACKET);
holder->packet.scroll.header.packetType = htonl(PACKET_TYPE_SCROLL); holder->packet.scroll.header.packetType = BE32(PACKET_TYPE_SCROLL);
holder->packet.scroll.magicA = MAGIC_A; holder->packet.scroll.magicA = MAGIC_A;
// On Gen 5 servers, the header code is incremented by one // On Gen 5 servers, the header code is incremented by one
if (AppVersionQuad[0] >= 5) { if (AppVersionQuad[0] >= 5) {
@@ -664,7 +666,7 @@ int LiSendHighResScrollEvent(short scrollAmount) {
} }
holder->packet.scroll.zero1 = 0; holder->packet.scroll.zero1 = 0;
holder->packet.scroll.zero2 = 0; holder->packet.scroll.zero2 = 0;
holder->packet.scroll.scrollAmt1 = htons(scrollAmount); holder->packet.scroll.scrollAmt1 = BE16(scrollAmount);
holder->packet.scroll.scrollAmt2 = holder->packet.scroll.scrollAmt1; holder->packet.scroll.scrollAmt2 = holder->packet.scroll.scrollAmt1;
holder->packet.scroll.zero3 = 0; holder->packet.scroll.zero3 = 0;

View File

@@ -61,6 +61,41 @@
#define LC_ASSERT(x) assert(x) #define LC_ASSERT(x) assert(x)
#endif #endif
#ifdef _MSC_VER
#pragma intrinsic(_byteswap_ushort)
#define BSWAP16(x) _byteswap_ushort(x)
#pragma intrinsic(_byteswap_ulong)
#define BSWAP32(x) _byteswap_ulong(x)
#pragma intrinsic(_byteswap_uint64)
#define BSWAP64(x) _byteswap_uint64(x)
#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
#define BSWAP16(x) __builtin_bswap16(x)
#define BSWAP32(x) __builtin_bswap32(x)
#define BSWAP64(x) __builtin_bswap64(x)
#elif defined(__has_builtin) && __has_builtin(__builtin_bswap16)
#define BSWAP16(x) __builtin_bswap16(x)
#define BSWAP32(x) __builtin_bswap32(x)
#define BSWAP64(x) __builtin_bswap64(x)
#else
#error Please define your platform's byteswap macros!
#endif
#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__)
#define LE16(x) BSWAP16(x)
#define LE32(x) BSWAP32(x)
#define LE64(x) BSWAP64(x)
#define BE16(x) (x)
#define BE32(x) (x)
#define BE64(x) (x)
#else
#define LE16(x) (x)
#define LE32(x) (x)
#define LE64(x) (x)
#define BE16(x) BSWAP16(x)
#define BE32(x) BSWAP32(x)
#define BE64(x) BSWAP64(x)
#endif
int initializePlatform(void); int initializePlatform(void);
void cleanupPlatform(void); void cleanupPlatform(void);

View File

@@ -413,6 +413,10 @@ int RtpfAddPacket(PRTP_FEC_QUEUE queue, PRTP_PACKET packet, int length, PRTPFEC_
} }
PNV_VIDEO_PACKET nvPacket = (PNV_VIDEO_PACKET)(((char*)packet) + dataOffset); PNV_VIDEO_PACKET nvPacket = (PNV_VIDEO_PACKET)(((char*)packet) + dataOffset);
nvPacket->streamPacketIndex = LE32(nvPacket->streamPacketIndex);
nvPacket->frameIndex = LE32(nvPacket->frameIndex);
nvPacket->fecInfo = LE32(nvPacket->fecInfo);
if (isBefore16(nvPacket->frameIndex, queue->currentFrameNumber)) { if (isBefore16(nvPacket->frameIndex, queue->currentFrameNumber)) {
// Reject frames behind our current frame number // Reject frames behind our current frame number

View File

@@ -142,9 +142,9 @@ static void ReceiveThreadProc(void* context) {
// Convert fields to host byte-order // Convert fields to host byte-order
packet = (PRTP_PACKET)&buffer[0]; packet = (PRTP_PACKET)&buffer[0];
packet->sequenceNumber = htons(packet->sequenceNumber); packet->sequenceNumber = BE16(packet->sequenceNumber);
packet->timestamp = htonl(packet->timestamp); packet->timestamp = BE32(packet->timestamp);
packet->ssrc = htonl(packet->ssrc); packet->ssrc = BE32(packet->ssrc);
queueStatus = RtpfAddPacket(&rtpQueue, packet, err, (PRTPFEC_QUEUE_ENTRY)&buffer[receiveSize]); queueStatus = RtpfAddPacket(&rtpQueue, packet, err, (PRTPFEC_QUEUE_ENTRY)&buffer[receiveSize]);