LibVNCServer/LibVNCClient
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
stats.c
Go to the documentation of this file.
1 /*
2  * stats.c
3  */
4 
5 /*
6  * Copyright (C) 2002 RealVNC Ltd.
7  * OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
8  * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
9  * All Rights Reserved.
10  *
11  * This is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This software is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this software; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
24  * USA.
25  */
26 
27 #include <rfb/rfb.h>
28 
29 char *messageNameServer2Client(uint32_t type, char *buf, int len);
30 char *messageNameClient2Server(uint32_t type, char *buf, int len);
31 char *encodingName(uint32_t enc, char *buf, int len);
32 
33 rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type);
34 rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type);
35 
36 void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
37 void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
38 void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
39 void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw);
40 void rfbResetStats(rfbClientPtr cl);
41 void rfbPrintStats(rfbClientPtr cl);
42 
43 
44 
45 
46 char *messageNameServer2Client(uint32_t type, char *buf, int len) {
47  if (buf==NULL) return "error";
48  switch (type) {
49  case rfbFramebufferUpdate: snprintf(buf, len, "FramebufferUpdate"); break;
50  case rfbSetColourMapEntries: snprintf(buf, len, "SetColourMapEntries"); break;
51  case rfbBell: snprintf(buf, len, "Bell"); break;
52  case rfbServerCutText: snprintf(buf, len, "ServerCutText"); break;
53  case rfbResizeFrameBuffer: snprintf(buf, len, "ResizeFrameBuffer"); break;
54  case rfbFileTransfer: snprintf(buf, len, "FileTransfer"); break;
55  case rfbTextChat: snprintf(buf, len, "TextChat"); break;
56  case rfbPalmVNCReSizeFrameBuffer: snprintf(buf, len, "PalmVNCReSize"); break;
57  case rfbXvp: snprintf(buf, len, "XvpServerMessage"); break;
58  default:
59  snprintf(buf, len, "svr2cli-0x%08X", 0xFF);
60  }
61  return buf;
62 }
63 
64 char *messageNameClient2Server(uint32_t type, char *buf, int len) {
65  if (buf==NULL) return "error";
66  switch (type) {
67  case rfbSetPixelFormat: snprintf(buf, len, "SetPixelFormat"); break;
68  case rfbFixColourMapEntries: snprintf(buf, len, "FixColourMapEntries"); break;
69  case rfbSetEncodings: snprintf(buf, len, "SetEncodings"); break;
70  case rfbFramebufferUpdateRequest: snprintf(buf, len, "FramebufferUpdate"); break;
71  case rfbKeyEvent: snprintf(buf, len, "KeyEvent"); break;
72  case rfbPointerEvent: snprintf(buf, len, "PointerEvent"); break;
73  case rfbClientCutText: snprintf(buf, len, "ClientCutText"); break;
74  case rfbFileTransfer: snprintf(buf, len, "FileTransfer"); break;
75  case rfbSetScale: snprintf(buf, len, "SetScale"); break;
76  case rfbSetServerInput: snprintf(buf, len, "SetServerInput"); break;
77  case rfbSetSW: snprintf(buf, len, "SetSingleWindow"); break;
78  case rfbTextChat: snprintf(buf, len, "TextChat"); break;
79  case rfbPalmVNCSetScaleFactor: snprintf(buf, len, "PalmVNCSetScale"); break;
80  case rfbXvp: snprintf(buf, len, "XvpClientMessage"); break;
81  default:
82  snprintf(buf, len, "cli2svr-0x%08X", type);
83 
84 
85  }
86  return buf;
87 }
88 
89 /* Encoding name must be <=16 characters to fit nicely on the status output in
90  * an 80 column terminal window
91  */
92 char *encodingName(uint32_t type, char *buf, int len) {
93  if (buf==NULL) return "error";
94 
95  switch (type) {
96  case rfbEncodingRaw: snprintf(buf, len, "raw"); break;
97  case rfbEncodingCopyRect: snprintf(buf, len, "copyRect"); break;
98  case rfbEncodingRRE: snprintf(buf, len, "RRE"); break;
99  case rfbEncodingCoRRE: snprintf(buf, len, "CoRRE"); break;
100  case rfbEncodingHextile: snprintf(buf, len, "hextile"); break;
101  case rfbEncodingZlib: snprintf(buf, len, "zlib"); break;
102  case rfbEncodingTight: snprintf(buf, len, "tight"); break;
103  case rfbEncodingTightPng: snprintf(buf, len, "tightPng"); break;
104  case rfbEncodingZlibHex: snprintf(buf, len, "zlibhex"); break;
105  case rfbEncodingUltra: snprintf(buf, len, "ultra"); break;
106  case rfbEncodingZRLE: snprintf(buf, len, "ZRLE"); break;
107  case rfbEncodingZYWRLE: snprintf(buf, len, "ZYWRLE"); break;
108  case rfbEncodingCache: snprintf(buf, len, "cache"); break;
109  case rfbEncodingCacheEnable: snprintf(buf, len, "cacheEnable"); break;
110  case rfbEncodingXOR_Zlib: snprintf(buf, len, "xorZlib"); break;
111  case rfbEncodingXORMonoColor_Zlib: snprintf(buf, len, "xorMonoZlib"); break;
112  case rfbEncodingXORMultiColor_Zlib: snprintf(buf, len, "xorColorZlib"); break;
113  case rfbEncodingSolidColor: snprintf(buf, len, "solidColor"); break;
114  case rfbEncodingXOREnable: snprintf(buf, len, "xorEnable"); break;
115  case rfbEncodingCacheZip: snprintf(buf, len, "cacheZip"); break;
116  case rfbEncodingSolMonoZip: snprintf(buf, len, "monoZip"); break;
117  case rfbEncodingUltraZip: snprintf(buf, len, "ultraZip"); break;
118 
119  case rfbEncodingXCursor: snprintf(buf, len, "Xcursor"); break;
120  case rfbEncodingRichCursor: snprintf(buf, len, "RichCursor"); break;
121  case rfbEncodingPointerPos: snprintf(buf, len, "PointerPos"); break;
122 
123  case rfbEncodingLastRect: snprintf(buf, len, "LastRect"); break;
124  case rfbEncodingNewFBSize: snprintf(buf, len, "NewFBSize"); break;
125  case rfbEncodingKeyboardLedState: snprintf(buf, len, "LedState"); break;
126  case rfbEncodingSupportedMessages: snprintf(buf, len, "SupportedMessage"); break;
127  case rfbEncodingSupportedEncodings: snprintf(buf, len, "SupportedEncoding"); break;
128  case rfbEncodingServerIdentity: snprintf(buf, len, "ServerIdentify"); break;
129 
130  /* The following lookups do not report in stats */
131  case rfbEncodingCompressLevel0: snprintf(buf, len, "CompressLevel0"); break;
132  case rfbEncodingCompressLevel1: snprintf(buf, len, "CompressLevel1"); break;
133  case rfbEncodingCompressLevel2: snprintf(buf, len, "CompressLevel2"); break;
134  case rfbEncodingCompressLevel3: snprintf(buf, len, "CompressLevel3"); break;
135  case rfbEncodingCompressLevel4: snprintf(buf, len, "CompressLevel4"); break;
136  case rfbEncodingCompressLevel5: snprintf(buf, len, "CompressLevel5"); break;
137  case rfbEncodingCompressLevel6: snprintf(buf, len, "CompressLevel6"); break;
138  case rfbEncodingCompressLevel7: snprintf(buf, len, "CompressLevel7"); break;
139  case rfbEncodingCompressLevel8: snprintf(buf, len, "CompressLevel8"); break;
140  case rfbEncodingCompressLevel9: snprintf(buf, len, "CompressLevel9"); break;
141 
142  case rfbEncodingQualityLevel0: snprintf(buf, len, "QualityLevel0"); break;
143  case rfbEncodingQualityLevel1: snprintf(buf, len, "QualityLevel1"); break;
144  case rfbEncodingQualityLevel2: snprintf(buf, len, "QualityLevel2"); break;
145  case rfbEncodingQualityLevel3: snprintf(buf, len, "QualityLevel3"); break;
146  case rfbEncodingQualityLevel4: snprintf(buf, len, "QualityLevel4"); break;
147  case rfbEncodingQualityLevel5: snprintf(buf, len, "QualityLevel5"); break;
148  case rfbEncodingQualityLevel6: snprintf(buf, len, "QualityLevel6"); break;
149  case rfbEncodingQualityLevel7: snprintf(buf, len, "QualityLevel7"); break;
150  case rfbEncodingQualityLevel8: snprintf(buf, len, "QualityLevel8"); break;
151  case rfbEncodingQualityLevel9: snprintf(buf, len, "QualityLevel9"); break;
152 
153 
154  default:
155  snprintf(buf, len, "Enc(0x%08X)", type);
156  }
157 
158  return buf;
159 }
160 
161 
162 
163 
164 
165 rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type)
166 {
167  rfbStatList *ptr;
168  if (cl==NULL) return NULL;
169  for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
170  {
171  if (ptr->type==type) return ptr;
172  }
173  /* Well, we are here... need to *CREATE* an entry */
174  ptr = (rfbStatList *)malloc(sizeof(rfbStatList));
175  if (ptr!=NULL)
176  {
177  memset((char *)ptr, 0, sizeof(rfbStatList));
178  ptr->type = type;
179  /* add to the top of the list */
180  ptr->Next = cl->statEncList;
181  cl->statEncList = ptr;
182  }
183  return ptr;
184 }
185 
186 
187 rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type)
188 {
189  rfbStatList *ptr;
190  if (cl==NULL) return NULL;
191  for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
192  {
193  if (ptr->type==type) return ptr;
194  }
195  /* Well, we are here... need to *CREATE* an entry */
196  ptr = (rfbStatList *)malloc(sizeof(rfbStatList));
197  if (ptr!=NULL)
198  {
199  memset((char *)ptr, 0, sizeof(rfbStatList));
200  ptr->type = type;
201  /* add to the top of the list */
202  ptr->Next = cl->statMsgList;
203  cl->statMsgList = ptr;
204  }
205  return ptr;
206 }
207 
208 void rfbStatRecordEncodingSentAdd(rfbClientPtr cl, uint32_t type, int byteCount) /* Specifically for tight encoding */
209 {
210  rfbStatList *ptr;
211 
212  ptr = rfbStatLookupEncoding(cl, type);
213  if (ptr!=NULL)
214  ptr->bytesSent += byteCount;
215 }
216 
217 
218 void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
219 {
220  rfbStatList *ptr;
221 
222  ptr = rfbStatLookupEncoding(cl, type);
223  if (ptr!=NULL)
224  {
225  ptr->sentCount++;
226  ptr->bytesSent += byteCount;
227  ptr->bytesSentIfRaw += byteIfRaw;
228  }
229 }
230 
231 void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
232 {
233  rfbStatList *ptr;
234 
235  ptr = rfbStatLookupEncoding(cl, type);
236  if (ptr!=NULL)
237  {
238  ptr->rcvdCount++;
239  ptr->bytesRcvd += byteCount;
240  ptr->bytesRcvdIfRaw += byteIfRaw;
241  }
242 }
243 
244 void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
245 {
246  rfbStatList *ptr;
247 
248  ptr = rfbStatLookupMessage(cl, type);
249  if (ptr!=NULL)
250  {
251  ptr->sentCount++;
252  ptr->bytesSent += byteCount;
253  ptr->bytesSentIfRaw += byteIfRaw;
254  }
255 }
256 
257 void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw)
258 {
259  rfbStatList *ptr;
260 
261  ptr = rfbStatLookupMessage(cl, type);
262  if (ptr!=NULL)
263  {
264  ptr->rcvdCount++;
265  ptr->bytesRcvd += byteCount;
266  ptr->bytesRcvdIfRaw += byteIfRaw;
267  }
268 }
269 
270 
271 int rfbStatGetSentBytes(rfbClientPtr cl)
272 {
273  rfbStatList *ptr=NULL;
274  int bytes=0;
275  if (cl==NULL) return 0;
276  for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
277  bytes += ptr->bytesSent;
278  for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
279  bytes += ptr->bytesSent;
280  return bytes;
281 }
282 
283 int rfbStatGetSentBytesIfRaw(rfbClientPtr cl)
284 {
285  rfbStatList *ptr=NULL;
286  int bytes=0;
287  if (cl==NULL) return 0;
288  for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
289  bytes += ptr->bytesSentIfRaw;
290  for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
291  bytes += ptr->bytesSentIfRaw;
292  return bytes;
293 }
294 
295 int rfbStatGetRcvdBytes(rfbClientPtr cl)
296 {
297  rfbStatList *ptr=NULL;
298  int bytes=0;
299  if (cl==NULL) return 0;
300  for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
301  bytes += ptr->bytesRcvd;
302  for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
303  bytes += ptr->bytesRcvd;
304  return bytes;
305 }
306 
307 int rfbStatGetRcvdBytesIfRaw(rfbClientPtr cl)
308 {
309  rfbStatList *ptr=NULL;
310  int bytes=0;
311  if (cl==NULL) return 0;
312  for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
313  bytes += ptr->bytesRcvdIfRaw;
314  for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
315  bytes += ptr->bytesRcvdIfRaw;
316  return bytes;
317 }
318 
319 int rfbStatGetMessageCountSent(rfbClientPtr cl, uint32_t type)
320 {
321  rfbStatList *ptr=NULL;
322  if (cl==NULL) return 0;
323  for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
324  if (ptr->type==type) return ptr->sentCount;
325  return 0;
326 }
327 int rfbStatGetMessageCountRcvd(rfbClientPtr cl, uint32_t type)
328 {
329  rfbStatList *ptr=NULL;
330  if (cl==NULL) return 0;
331  for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
332  if (ptr->type==type) return ptr->rcvdCount;
333  return 0;
334 }
335 
336 int rfbStatGetEncodingCountSent(rfbClientPtr cl, uint32_t type)
337 {
338  rfbStatList *ptr=NULL;
339  if (cl==NULL) return 0;
340  for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
341  if (ptr->type==type) return ptr->sentCount;
342  return 0;
343 }
344 int rfbStatGetEncodingCountRcvd(rfbClientPtr cl, uint32_t type)
345 {
346  rfbStatList *ptr=NULL;
347  if (cl==NULL) return 0;
348  for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
349  if (ptr->type==type) return ptr->rcvdCount;
350  return 0;
351 }
352 
353 
354 
355 
356 void rfbResetStats(rfbClientPtr cl)
357 {
358  rfbStatList *ptr;
359  if (cl==NULL) return;
360  while (cl->statEncList!=NULL)
361  {
362  ptr = cl->statEncList;
363  cl->statEncList = ptr->Next;
364  free(ptr);
365  }
366  while (cl->statMsgList!=NULL)
367  {
368  ptr = cl->statMsgList;
369  cl->statMsgList = ptr->Next;
370  free(ptr);
371  }
372 }
373 
374 
375 void rfbPrintStats(rfbClientPtr cl)
376 {
377  rfbStatList *ptr=NULL;
378  char encBuf[64];
379  double savings=0.0;
380  int totalRects=0;
381  double totalBytes=0.0;
382  double totalBytesIfRaw=0.0;
383 
384  char *name=NULL;
385  int bytes=0;
386  int bytesIfRaw=0;
387  int count=0;
388 
389  if (cl==NULL) return;
390 
391  rfbLog("%-21.21s %-6.6s %9.9s/%9.9s (%6.6s)\n", "Statistics", "events", "Transmit","RawEquiv","saved");
392  for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
393  {
394  name = messageNameServer2Client(ptr->type, encBuf, sizeof(encBuf));
395  count = ptr->sentCount;
396  bytes = ptr->bytesSent;
397  bytesIfRaw = ptr->bytesSentIfRaw;
398 
399  savings = 0.0;
400  if (bytesIfRaw>0.0)
401  savings = 100.0 - (((double)bytes / (double)bytesIfRaw) * 100.0);
402  if ((bytes>0) || (count>0) || (bytesIfRaw>0))
403  rfbLog(" %-20.20s: %6d | %9d/%9d (%5.1f%%)\n",
404  name, count, bytes, bytesIfRaw, savings);
405  totalRects += count;
406  totalBytes += bytes;
407  totalBytesIfRaw += bytesIfRaw;
408  }
409 
410  for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
411  {
412  name = encodingName(ptr->type, encBuf, sizeof(encBuf));
413  count = ptr->sentCount;
414  bytes = ptr->bytesSent;
415  bytesIfRaw = ptr->bytesSentIfRaw;
416  savings = 0.0;
417 
418  if (bytesIfRaw>0.0)
419  savings = 100.0 - (((double)bytes / (double)bytesIfRaw) * 100.0);
420  if ((bytes>0) || (count>0) || (bytesIfRaw>0))
421  rfbLog(" %-20.20s: %6d | %9d/%9d (%5.1f%%)\n",
422  name, count, bytes, bytesIfRaw, savings);
423  totalRects += count;
424  totalBytes += bytes;
425  totalBytesIfRaw += bytesIfRaw;
426  }
427  savings=0.0;
428  if (totalBytesIfRaw>0.0)
429  savings = 100.0 - ((totalBytes/totalBytesIfRaw)*100.0);
430  rfbLog(" %-20.20s: %6d | %9.0f/%9.0f (%5.1f%%)\n",
431  "TOTALS", totalRects, totalBytes,totalBytesIfRaw, savings);
432 
433  totalRects=0.0;
434  totalBytes=0.0;
435  totalBytesIfRaw=0.0;
436 
437  rfbLog("%-21.21s %-6.6s %9.9s/%9.9s (%6.6s)\n", "Statistics", "events", "Received","RawEquiv","saved");
438  for (ptr = cl->statMsgList; ptr!=NULL; ptr=ptr->Next)
439  {
440  name = messageNameClient2Server(ptr->type, encBuf, sizeof(encBuf));
441  count = ptr->rcvdCount;
442  bytes = ptr->bytesRcvd;
443  bytesIfRaw = ptr->bytesRcvdIfRaw;
444  savings = 0.0;
445 
446  if (bytesIfRaw>0.0)
447  savings = 100.0 - (((double)bytes / (double)bytesIfRaw) * 100.0);
448  if ((bytes>0) || (count>0) || (bytesIfRaw>0))
449  rfbLog(" %-20.20s: %6d | %9d/%9d (%5.1f%%)\n",
450  name, count, bytes, bytesIfRaw, savings);
451  totalRects += count;
452  totalBytes += bytes;
453  totalBytesIfRaw += bytesIfRaw;
454  }
455  for (ptr = cl->statEncList; ptr!=NULL; ptr=ptr->Next)
456  {
457  name = encodingName(ptr->type, encBuf, sizeof(encBuf));
458  count = ptr->rcvdCount;
459  bytes = ptr->bytesRcvd;
460  bytesIfRaw = ptr->bytesRcvdIfRaw;
461  savings = 0.0;
462 
463  if (bytesIfRaw>0.0)
464  savings = 100.0 - (((double)bytes / (double)bytesIfRaw) * 100.0);
465  if ((bytes>0) || (count>0) || (bytesIfRaw>0))
466  rfbLog(" %-20.20s: %6d | %9d/%9d (%5.1f%%)\n",
467  name, count, bytes, bytesIfRaw, savings);
468  totalRects += count;
469  totalBytes += bytes;
470  totalBytesIfRaw += bytesIfRaw;
471  }
472  savings=0.0;
473  if (totalBytesIfRaw>0.0)
474  savings = 100.0 - ((totalBytes/totalBytesIfRaw)*100.0);
475  rfbLog(" %-20.20s: %6d | %9.0f/%9.0f (%5.1f%%)\n",
476  "TOTALS", totalRects, totalBytes,totalBytesIfRaw, savings);
477 
478 }
479