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); typedef char* (*GetSASLMechanismProc)(struct _rfbClient* client, char* mechlist);
#endif /* LIBVNCSERVER_HAVE_SASL */ #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 { typedef struct _rfbClient {
uint8_t* frameBuffer; uint8_t* frameBuffer;
int width, height; int width, height;
@ -467,6 +470,8 @@ typedef struct _rfbClient {
StartingFrameBufferUpdateProc StartingFrameBufferUpdate; StartingFrameBufferUpdateProc StartingFrameBufferUpdate;
CancelledFrameBufferUpdateProc CancelledFrameBufferUpdate; CancelledFrameBufferUpdateProc CancelledFrameBufferUpdate;
NtpEventProc NtpEvent;
} rfbClient; } rfbClient;
/* cursor.c */ /* cursor.c */
@ -612,6 +617,9 @@ extern rfbBool HandleRFBServerMessage(rfbClient* client);
extern rfbBool ReadToBuffer(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. * Sends a text chat message to the server.
* @param client The client through which to send the message * @param client The client through which to send the message

View File

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

View File

@ -45,6 +45,8 @@ struct vnc_client {
int (*alloc_fb)(struct vnc_client*); int (*alloc_fb)(struct vnc_client*);
void (*update_fb)(struct vnc_client*); void (*update_fb)(struct vnc_client*);
void (*cut_text)(struct vnc_client*, const char*, size_t); 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; void* userdata;
struct pixman_region16 damage; 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, void vnc_client_send_cut_text(struct vnc_client* self, const char* text,
size_t len); size_t len);
void vnc_client_clear_av_frames(struct vnc_client* self); 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) if (se->nEncodings < MAX_ENCODINGS)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPts); encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPts);
/* ntp */
if (se->nEncodings < MAX_ENCODINGS)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNtp);
len = sz_rfbSetEncodingsMsg + se->nEncodings * 4; len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
se->nEncodings = rfbClientSwap16IfLE(se->nEncodings); se->nEncodings = rfbClientSwap16IfLE(se->nEncodings);
@ -1742,6 +1746,22 @@ rfbBool SendClientCutText(rfbClient* client, char* str, int len)
WriteToRFBServer(client, str, 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, static rfbBool HandleFramebufferUpdate(rfbClient* client,
rfbServerToClientMsg* msg) rfbServerToClientMsg* msg)
{ {
@ -2300,6 +2320,10 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
SetClient2Server(client, rfbQemuEvent); SetClient2Server(client, rfbQemuEvent);
break; break;
case rfbEncodingNtp:
SetClient2Server(client, rfbNtpEvent);
break;
default: { default: {
rfbBool handled = FALSE; rfbBool handled = FALSE;
rfbClientProtocolExtension* e; rfbClientProtocolExtension* e;
@ -2339,6 +2363,22 @@ failure:
return FALSE; 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. * HandleRFBServerMessage.
*/ */
@ -2527,6 +2567,9 @@ rfbBool HandleRFBServerMessage(rfbClient* client)
break; break;
} }
case rfbNtpEvent:
return handleNtpEvent(client, &msg.ntp);
default: { default: {
rfbBool handled = FALSE; rfbBool handled = FALSE;
rfbClientProtocolExtension* e; 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); 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, static rfbBool vnc_client_handle_open_h264_rect(rfbClient* client,
rfbFramebufferUpdateRectHeader* rect_header) rfbFramebufferUpdateRectHeader* rect_header)
{ {
@ -246,6 +256,7 @@ struct vnc_client* vnc_client_create(void)
client->StartingFrameBufferUpdate = vnc_client_start_update; client->StartingFrameBufferUpdate = vnc_client_start_update;
client->CancelledFrameBufferUpdate = vnc_client_cancel_update; client->CancelledFrameBufferUpdate = vnc_client_cancel_update;
client->GotXCutText = vnc_client_got_cut_text; client->GotXCutText = vnc_client_got_cut_text;
client->NtpEvent = vnc_client_ntp_event;
self->pts = NO_PTS; 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. // libvncclient doesn't modify text, so typecast is OK.
SendClientCutText(self->client, (char*)text, len); 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);
}