rfbproto: Add NTP messages

latency-reporting
Andri Yngvason 2023-04-09 10:06:13 +00:00
parent 9fd5caaa4b
commit ea17c642e8
5 changed files with 86 additions and 7 deletions

View File

@ -225,6 +225,9 @@ typedef char* (*GetUserProc)(struct _rfbClient* client);
typedef char* (*GetSASLMechanismProc)(struct _rfbClient* client, char* mechlist);
#endif /* LIBVNCSERVER_HAVE_SASL */
typedef void (*NtpEventProc)(struct _rfbClient* client, uint32_t t0,
uint32_t t1, uint32_t t2, uint32_t t3);
typedef struct _rfbClient {
uint8_t* frameBuffer;
int width, height;
@ -467,6 +470,8 @@ typedef struct _rfbClient {
StartingFrameBufferUpdateProc StartingFrameBufferUpdate;
CancelledFrameBufferUpdateProc CancelledFrameBufferUpdate;
NtpEventProc NtpEvent;
} rfbClient;
/* cursor.c */
@ -612,6 +617,9 @@ extern rfbBool HandleRFBServerMessage(rfbClient* client);
extern rfbBool ReadToBuffer(rfbClient* client);
extern rfbBool SendClientNtpEvent(rfbClient* client, uint32_t t0, uint32_t t1,
uint32_t t2, uint32_t t3);
/**
* Sends a text chat message to the server.
* @param client The client through which to send the message

View File

@ -398,8 +398,7 @@ typedef struct {
#define rfbSetDesktopSize 251
#define rfbQemuEvent 255
#define rfbNtpEvent 160
/*****************************************************************************
*
@ -499,6 +498,7 @@ typedef struct {
#define rfbEncodingServerIdentity 0xFFFE0003
#define rfbEncodingPts -1000
#define rfbEncodingNtp -1001
/*****************************************************************************
*
@ -1139,6 +1139,12 @@ typedef struct rfbExtDesktopScreen {
uint32_t flags;
} rfbExtDesktopScreen;
struct rfbNtpMsg {
uint8_t type;
uint8_t padding[3];
uint32_t t0, t1, t2, t3;
};
#define sz_rfbExtDesktopSizeMsg (4)
#define sz_rfbExtDesktopScreen (16)
@ -1229,6 +1235,7 @@ typedef union {
rfbTextChatMsg tc;
rfbXvpMsg xvp;
rfbExtDesktopSizeMsg eds;
struct rfbNtpMsg ntp;
} rfbServerToClientMsg;

View File

@ -45,6 +45,8 @@ struct vnc_client {
int (*alloc_fb)(struct vnc_client*);
void (*update_fb)(struct vnc_client*);
void (*cut_text)(struct vnc_client*, const char*, size_t);
void (*ntp_event)(struct vnc_client*, uint32_t t0, uint32_t t1,
uint32_t t2, uint32_t t3);
void* userdata;
struct pixman_region16 damage;
@ -79,3 +81,5 @@ void vnc_client_set_compression_level(struct vnc_client* self, int value);
void vnc_client_send_cut_text(struct vnc_client* self, const char* text,
size_t len);
void vnc_client_clear_av_frames(struct vnc_client* self);
void vnc_client_send_ntp_event(struct vnc_client* self, uint32_t t0,
uint32_t t1, uint32_t t2, uint32_t t3);

View File

@ -1398,6 +1398,10 @@ rfbBool SetFormatAndEncodings(rfbClient* client)
if (se->nEncodings < MAX_ENCODINGS)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPts);
/* ntp */
if (se->nEncodings < MAX_ENCODINGS)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNtp);
len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
se->nEncodings = rfbClientSwap16IfLE(se->nEncodings);
@ -1742,6 +1746,22 @@ rfbBool SendClientCutText(rfbClient* client, char* str, int len)
WriteToRFBServer(client, str, len));
}
rfbBool SendClientNtpEvent(rfbClient* client, uint32_t t0, uint32_t t1,
uint32_t t2, uint32_t t3)
{
if (!SupportsClient2Server(client, rfbNtpEvent))
return FALSE;
struct rfbNtpMsg msg = {
.type = rfbNtpEvent,
.t0 = rfbClientSwap32IfLE(t0),
.t1 = rfbClientSwap32IfLE(t1),
.t2 = rfbClientSwap32IfLE(t2),
.t3 = rfbClientSwap32IfLE(t3),
};
return WriteToRFBServer(client, (char*)&msg, sizeof(msg));
}
static rfbBool HandleFramebufferUpdate(rfbClient* client,
rfbServerToClientMsg* msg)
{
@ -2300,6 +2320,10 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
SetClient2Server(client, rfbQemuEvent);
break;
case rfbEncodingNtp:
SetClient2Server(client, rfbNtpEvent);
break;
default: {
rfbBool handled = FALSE;
rfbClientProtocolExtension* e;
@ -2339,6 +2363,22 @@ failure:
return FALSE;
}
rfbBool handleNtpEvent(rfbClient* client, struct rfbNtpMsg* msg)
{
if (!ReadFromRFBServer(client, (char*)msg + 1, sizeof(*msg) - 1))
return FALSE;
uint32_t t0 = rfbClientSwap32IfLE(msg->t0);
uint32_t t1 = rfbClientSwap32IfLE(msg->t1);
uint32_t t2 = rfbClientSwap32IfLE(msg->t2);
uint32_t t3 = rfbClientSwap32IfLE(msg->t3);
if (client->NtpEvent)
client->NtpEvent(client, t0, t1, t2, t3);
return TRUE;
}
/*
* HandleRFBServerMessage.
*/
@ -2527,6 +2567,9 @@ rfbBool HandleRFBServerMessage(rfbClient* client)
break;
}
case rfbNtpEvent:
return handleNtpEvent(client, &msg.ntp);
default: {
rfbBool handled = FALSE;
rfbClientProtocolExtension* e;

View File

@ -136,6 +136,16 @@ static void vnc_client_got_cut_text(rfbClient* client, const char* text,
self->cut_text(self, text, len);
}
static void vnc_client_ntp_event(rfbClient* client, uint32_t t0, uint32_t t1,
uint32_t t2, uint32_t t3)
{
struct vnc_client* self = rfbClientGetClientData(client, NULL);
assert(self);
if (self->ntp_event)
self->ntp_event(self, t0, t1, t2, t3);
}
static rfbBool vnc_client_handle_open_h264_rect(rfbClient* client,
rfbFramebufferUpdateRectHeader* rect_header)
{
@ -246,6 +256,7 @@ struct vnc_client* vnc_client_create(void)
client->StartingFrameBufferUpdate = vnc_client_start_update;
client->CancelledFrameBufferUpdate = vnc_client_cancel_update;
client->GotXCutText = vnc_client_got_cut_text;
client->NtpEvent = vnc_client_ntp_event;
self->pts = NO_PTS;
@ -443,3 +454,9 @@ void vnc_client_send_cut_text(struct vnc_client* self, const char* text,
// libvncclient doesn't modify text, so typecast is OK.
SendClientCutText(self->client, (char*)text, len);
}
void vnc_client_send_ntp_event(struct vnc_client* self, uint32_t t0,
uint32_t t1, uint32_t t2, uint32_t t3)
{
SendClientNtpEvent(self->client, t0, t1, t2, t3);
}