int rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RDPGFX_FRAME_ACKNOWLEDGE_PDU* pdu) { int status; wStream* s; RDPGFX_HEADER header; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; header.flags = 0; header.cmdId = RDPGFX_CMDID_FRAMEACKNOWLEDGE; header.pduLength = RDPGFX_HEADER_SIZE + 12; WLog_Print(gfx->log, WLOG_DEBUG, "SendFrameAcknowledgePdu: %d", pdu->frameId); s = Stream_New(NULL, header.pduLength); rdpgfx_write_header(s, &header); /* RDPGFX_FRAME_ACKNOWLEDGE_PDU */ Stream_Write_UINT32(s, pdu->queueDepth); /* queueDepth (4 bytes) */ Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */ Stream_Write_UINT32(s, pdu->totalFramesDecoded); /* totalFramesDecoded (4 bytes) */ status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); Stream_Free(s, TRUE); return status; }
static UINT rdpgfx_send_qoe_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback, const RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* pdu) { UINT error; wStream* s; RDPGFX_HEADER header; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; header.flags = 0; header.cmdId = RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE; header.pduLength = RDPGFX_HEADER_SIZE + 12; WLog_Print(gfx->log, WLOG_DEBUG, "SendQoeFrameAcknowledgePdu: %"PRIu32"", pdu->frameId); s = Stream_New(NULL, header.pduLength); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } if ((error = rdpgfx_write_header(s, &header))) goto fail; /* RDPGFX_FRAME_ACKNOWLEDGE_PDU */ Stream_Write_UINT32(s, pdu->frameId); Stream_Write_UINT32(s, pdu->timestamp); Stream_Write_UINT16(s, pdu->timeDiffSE); Stream_Write_UINT16(s, pdu->timeDiffEDR); error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); fail: Stream_Free(s, TRUE); return error; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback, RDPGFX_FRAME_ACKNOWLEDGE_PDU* pdu) { UINT error; wStream* s; RDPGFX_HEADER header; header.flags = 0; header.cmdId = RDPGFX_CMDID_FRAMEACKNOWLEDGE; header.pduLength = RDPGFX_HEADER_SIZE + 12; WLog_DBG(TAG, "SendFrameAcknowledgePdu: %d", pdu->frameId); s = Stream_New(NULL, header.pduLength); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } if ((error = rdpgfx_write_header(s, &header))) { WLog_ERR(TAG, "rdpgfx_write_header failed with error %u!", error); return error; } /* RDPGFX_FRAME_ACKNOWLEDGE_PDU */ Stream_Write_UINT32(s, pdu->queueDepth); /* queueDepth (4 bytes) */ Stream_Write_UINT32(s, pdu->frameId); /* frameId (4 bytes) */ Stream_Write_UINT32(s, pdu->totalFramesDecoded); /* totalFramesDecoded (4 bytes) */ error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); Stream_Free(s, TRUE); return error; }
static INLINE UINT rdpgfx_server_packet_init_header(wStream* s, UINT16 cmdId, UINT32 pduLength) { RDPGFX_HEADER header; header.flags = 0; header.cmdId = cmdId; header.pduLength = pduLength; /* Write header. Note that actual length might be changed * after the entire packet has been constructed. */ return rdpgfx_write_header(s, &header); }
int rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) { int status; wStream* s; UINT16 index; RDPGFX_PLUGIN* gfx; RDPGFX_HEADER header; RDPGFX_CAPSET* capsSet; RDPGFX_CAPSET capsSets[2]; RDPGFX_CAPS_ADVERTISE_PDU pdu; gfx = (RDPGFX_PLUGIN*) callback->plugin; header.flags = 0; header.cmdId = RDPGFX_CMDID_CAPSADVERTISE; pdu.capsSetCount = 0; pdu.capsSets = (RDPGFX_CAPSET*) capsSets; capsSet = &capsSets[pdu.capsSetCount++]; capsSet->version = RDPGFX_CAPVERSION_8; capsSet->flags = 0; if (gfx->ThinClient) capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT; if (gfx->SmallCache) capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE; capsSet = &capsSets[pdu.capsSetCount++]; capsSet->version = RDPGFX_CAPVERSION_81; capsSet->flags = 0; if (gfx->ThinClient) capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT; if (gfx->SmallCache) capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE; if (gfx->H264) capsSet->flags |= RDPGFX_CAPS_FLAG_H264ENABLED; header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount * RDPGFX_CAPSET_SIZE); WLog_Print(gfx->log, WLOG_DEBUG, "SendCapsAdvertisePdu"); s = Stream_New(NULL, header.pduLength); rdpgfx_write_header(s, &header); /* RDPGFX_CAPS_ADVERTISE_PDU */ Stream_Write_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */ for (index = 0; index < pdu.capsSetCount; index++) { capsSet = &(pdu.capsSets[index]); Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */ Stream_Write_UINT32(s, 4); /* capsDataLength (4 bytes) */ Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */ } Stream_SealLength(s); status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); Stream_Free(s, TRUE); return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) { UINT error; wStream* s; UINT16 index; RDPGFX_PLUGIN* gfx; RDPGFX_HEADER header; RDPGFX_CAPSET* capsSet; RDPGFX_CAPSET capsSets[RDPGFX_NUMBER_CAPSETS]; RDPGFX_CAPS_ADVERTISE_PDU pdu; gfx = (RDPGFX_PLUGIN*) callback->plugin; header.flags = 0; header.cmdId = RDPGFX_CMDID_CAPSADVERTISE; pdu.capsSetCount = 0; pdu.capsSets = (RDPGFX_CAPSET*) capsSets; capsSet = &capsSets[pdu.capsSetCount++]; capsSet->version = RDPGFX_CAPVERSION_8; capsSet->flags = 0; if (gfx->ThinClient) capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT; /* in CAPVERSION_8 the spec says that we should not have both * thinclient and smallcache (and thinclient implies a small cache) */ if (gfx->SmallCache && !gfx->ThinClient) capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE; capsSet = &capsSets[pdu.capsSetCount++]; capsSet->version = RDPGFX_CAPVERSION_81; capsSet->flags = 0; if (gfx->ThinClient) capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT; if (gfx->SmallCache) capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE; #ifdef WITH_GFX_H264 if (gfx->H264) capsSet->flags |= RDPGFX_CAPS_FLAG_AVC420_ENABLED; #endif if (!gfx->H264 || gfx->AVC444) { capsSet = &capsSets[pdu.capsSetCount++]; capsSet->version = RDPGFX_CAPVERSION_10; capsSet->flags = 0; if (gfx->SmallCache) capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE; #ifdef WITH_GFX_H264 if (!gfx->AVC444) capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED; #else capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED; #endif capsSets[pdu.capsSetCount] = *capsSet; capsSets[pdu.capsSetCount++].version = RDPGFX_CAPVERSION_102; capsSets[pdu.capsSetCount] = *capsSet; capsSets[pdu.capsSetCount++].version = RDPGFX_CAPVERSION_103; } header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount * RDPGFX_CAPSET_SIZE); WLog_Print(gfx->log, WLOG_DEBUG, "SendCapsAdvertisePdu %"PRIu16"", pdu.capsSetCount); s = Stream_New(NULL, header.pduLength); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } if ((error = rdpgfx_write_header(s, &header))) goto fail; /* RDPGFX_CAPS_ADVERTISE_PDU */ Stream_Write_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */ for (index = 0; index < pdu.capsSetCount; index++) { capsSet = &(pdu.capsSets[index]); Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */ Stream_Write_UINT32(s, 4); /* capsDataLength (4 bytes) */ Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */ } Stream_SealLength(s); error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); fail: Stream_Free(s, TRUE); return error; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) { UINT error; wStream* s; UINT16 index; RDPGFX_PLUGIN* gfx; RDPGFX_HEADER header; RDPGFX_CAPSET* capsSet; RDPGFX_CAPSET capsSets[RDPGFX_NUMBER_CAPSETS]; RDPGFX_CAPS_ADVERTISE_PDU pdu; gfx = (RDPGFX_PLUGIN*) callback->plugin; header.flags = 0; header.cmdId = RDPGFX_CMDID_CAPSADVERTISE; pdu.capsSetCount = 0; pdu.capsSets = (RDPGFX_CAPSET*) capsSets; capsSet = &capsSets[pdu.capsSetCount++]; capsSet->version = RDPGFX_CAPVERSION_8; capsSet->flags = 0; if (gfx->ThinClient) capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT; if (gfx->SmallCache) capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE; capsSet = &capsSets[pdu.capsSetCount++]; capsSet->version = RDPGFX_CAPVERSION_81; capsSet->flags = 0; if (gfx->ThinClient) capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT; if (gfx->SmallCache) capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE; if (gfx->H264) capsSet->flags |= RDPGFX_CAPS_FLAG_AVC420_ENABLED; if (gfx->AVC444) { capsSet = &capsSets[pdu.capsSetCount++]; capsSet->version = RDPGFX_CAPVERSION_10; capsSet->flags = 0; if (gfx->SmallCache) capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE; if (!gfx->H264) capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED; capsSets[pdu.capsSetCount] = *capsSet; capsSets[pdu.capsSetCount++].version = RDPGFX_CAPVERSION_102; } header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount * RDPGFX_CAPSET_SIZE); WLog_DBG(TAG, "SendCapsAdvertisePdu %d", pdu.capsSetCount); s = Stream_New(NULL, header.pduLength); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } if ((error = rdpgfx_write_header(s, &header))) { WLog_ERR(TAG, "rdpgfx_write_header failed with error %u!", error); return error; } /* RDPGFX_CAPS_ADVERTISE_PDU */ Stream_Write_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */ for (index = 0; index < pdu.capsSetCount; index++) { capsSet = &(pdu.capsSets[index]); Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */ Stream_Write_UINT32(s, 4); /* capsDataLength (4 bytes) */ Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */ } Stream_SealLength(s); error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); Stream_Free(s, TRUE); return error; }