/apps/desktop/libvncserver/stats.c

http://ftk.googlecode.com/ · C · 477 lines · 381 code · 64 blank · 32 comment · 69 complexity · 70e6e26aafe4943db01f3a8744621bc9 MD5 · raw file

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