c1e31766997f13ca29d74c6dad6ebfe09c12c50b
[kismet-logviewer.git] / logviewer / static / js / jquery.kismet.packetrate.js
1 // Packet rate widget
2 //
3 // Requires js-storage, jquery, and sparkline be loaded prior
4 //
5 // dragorn@kismetwireless.net
6 // MIT/GPL License (pick one); the web ui code is licensed more
7 // freely than GPL to reflect the generally MIT-licensed nature
8 // of the web/jquery environment
9 //
10
11 (function ($) {
12     var local_uri_prefix = "";
13     if (typeof(KISMET_URI_PREFIX) !== 'undefined')
14         local_uri_prefix = KISMET_URI_PREFIX;
15
16     var base_options = {
17         use_color: true,
18     };
19
20     var options = base_options;
21
22     var timerid = -1;
23
24     var element = null;
25
26     var dialog = null;
27
28     var click = null;
29
30     var packetgraph = null;
31
32     var popup_content =
33             $('<div>', {
34             style: 'padding: 2px; border: 0px;'
35         })
36         .append(
37             $('<div>', {
38                 id: 'status',
39                 style: 'padding-bottom: 2px;'
40             })
41         )
42         .append(
43             $('<table>', {
44                 id: "statustable",
45                 style: "border: 0px !important; width: 100%;",
46             })
47             .append(
48                 $('<tr>')
49                 .append(
50                     $('<td>').html('Total Packets')
51                 )
52                 .append(
53                     $('<td>', {
54                         id: 'rate'
55                     }).html("n/a")
56                 )
57             )
58             .append(
59                 $('<tr>')
60                 .append(
61                     $('<td>').html('Duplicates')
62                 )
63                 .append(
64                     $('<td>', {
65                         id: 'dupe'
66                     }).html("n/a")
67                 )
68             )
69             .append(
70                 $('<tr>')
71                 .append(
72                     $('<td>').html('Packet queue backlog')
73                 )
74                 .append(
75                     $('<td>', {
76                         id: 'queue'
77                     }).html("n/a")
78                 )
79             )
80             .append(
81                 $('<tr>')
82                 .append(
83                     $('<td>').html('Dropped queue')
84                 )
85                 .append(
86                     $('<td>', {
87                         id: 'drop'
88                     }).html("n/a")
89                 )
90             )
91             .append(
92                 $('<tr>')
93                 .append(
94                     $('<td>').html('Errors')
95                 )
96                 .append(
97                     $('<td>', {
98                         id: 'error'
99                     }).html("n/a")
100                 )
101             )
102         );
103
104     // Close the alert panel if we click outside it
105     var close_dialog_outside = function(e) {
106         if (e == null ||
107             (e != null && $(e.target).closest('#packetdialog').length == 0)) {
108
109             if (dialog != null) {
110                 dialog.remove();
111                 dialog = null;
112             }
113
114             // Remove the handler
115             $('body').off('click', close_dialog_outside);
116
117             // Don't pass the click on
118             e.stopImmediatePropagation();
119         }
120     }
121
122     var open_dialog = function(e) {
123         if (dialog != null) {
124             close_dialog_outside(e);
125
126             e.stopImmediatePropagation();
127             return;
128         }
129
130         var fullscreen = false;
131
132         var nominal_w = 400;
133         //var nominal_h = ($(window).height() / 3) * 2;
134         var nominal_h = 120;
135
136         var pos = { };
137
138         if ($(window).width() < 450) {
139             nominal_w = $(window).width() - 5;
140             nominal_h = $(window).height() - 5;
141
142             pos = {
143                 "my": "left-top",
144                 "at": "left-top",
145                 "of": "window",
146                 "offsetX": 2,
147                 "offsetY": 2,
148                 "autoposition": "RIGHT"
149             };
150
151             fullscreen = true;
152         } else {
153             // Position under the element
154             var off_y = (nominal_h / 2) + (element.outerHeight() / 2) + 3;
155
156             // left-ish of the icon
157             var off_x = (nominal_w / 5) * 2;
158             off_x *= -1;
159
160             // Where the outer border lands
161             var outerborder = off_x + (nominal_w / 2);
162
163             pos = {
164                 of: element,
165                 offsetY: off_y,
166                 offsetX: off_x
167             };
168
169             fullscreen = false;
170         }
171
172         if (fullscreen)
173             $('.kg-header-close', popup_content).show();
174
175         dialog = $.jsPanel({
176             id: "packetdialog",
177             headerRemove: true,
178             position: pos,
179             contentSize: {
180                 width: nominal_w,
181                 height: nominal_h
182             },
183             content: popup_content,
184         });
185
186         $("body").on("click", close_dialog_outside);
187
188         e.stopImmediatePropagation();
189     }
190
191     /*
192     var packet_refresh = function() {
193         if (kismet_ui.window_visible) {
194             $.get(local_uri_prefix + "packetchain/packet_stats.json")
195             .done(function(data) {
196                 data = kismet.sanitizeObject(data);
197
198                 try {
199                     var rate_rrd =
200                         kismet.RecalcRrdData2(data['kismet.packetchain.packets_rrd'], kismet.RRD_SECOND, {
201                                 transform: function(data, opt) {
202                                     var slices = 3;
203                                     var peak = 0;
204                                     var ret = new Array();
205
206                                     for (var ri = 0; ri < data.length; ri++) {
207                                         peak = Math.max(peak, data[ri]);
208
209                                         if ((ri % slices) == (slices - 1)) {
210                                             ret.push(peak);
211                                             peak = 0;
212                                         }
213                                     }
214
215                                     return ret;
216                                 }
217                             });
218
219                     var error_rrd =
220                         kismet.RecalcRrdData2(
221                             data['kismet.packetchain.error_packets_rrd'], kismet.RRD_SECOND, {
222                                 transform: function(data, opt) {
223                                     var slices = 3;
224                                     var peak = 0;
225                                     var ret = new Array();
226
227                                     for (var ri = 0; ri < data.length; ri++) {
228                                         peak = Math.max(peak, data[ri]);
229
230                                         if ((ri % slices) == (slices - 1)) {
231                                             ret.push(peak);
232                                             peak = 0;
233                                         }
234                                     }
235
236                                     return ret;
237                                 }
238                             });
239
240                     var dupe_rrd =
241                         kismet.RecalcRrdData2(
242                             data['kismet.packetchain.dupe_packets_rrd'], kismet.RRD_SECOND, {
243                                 transform: function(data, opt) {
244                                     var slices = 3;
245                                     var peak = 0;
246                                     var ret = new Array();
247
248                                     for (var ri = 0; ri < data.length; ri++) {
249                                         peak = Math.max(peak, data[ri]);
250
251                                         if ((ri % slices) == (slices - 1)) {
252                                             ret.push(peak);
253                                             peak = 0;
254                                         }
255                                     }
256
257                                     return ret;
258                                 }
259                             });
260
261                     var queue_rrd =
262                         kismet.RecalcRrdData2(
263                             data['kismet.packetchain.queued_packets_rrd'], kismet.RRD_SECOND, {
264                                 transform: function(data, opt) {
265                                     var slices = 3;
266                                     var peak = 0;
267                                     var ret = new Array();
268
269                                     for (var ri = 0; ri < data.length; ri++) {
270                                         peak = Math.max(peak, data[ri]);
271
272                                         if ((ri % slices) == (slices - 1)) {
273                                             ret.push(peak);
274                                             peak = 0;
275                                         }
276                                     }
277
278                                     return ret;
279                                 }
280                             });
281
282                     var drop_rrd =
283                         kismet.RecalcRrdData2(
284                             data['kismet.packetchain.dropped_packets_rrd'], kismet.RRD_SECOND, {
285                                 transform: function(data, opt) {
286                                     var slices = 3;
287                                     var peak = 0;
288                                     var ret = new Array();
289
290                                     for (var ri = 0; ri < data.length; ri++) {
291                                         peak = Math.max(peak, data[ri]);
292
293                                         if ((ri % slices) == (slices - 1)) {
294                                             ret.push(peak);
295                                             peak = 0;
296                                         }
297                                     }
298
299                                     return ret;
300                                 }
301                             });
302
303                     var combo_rrd = [];
304
305                     for (var i = 0; i < rate_rrd.length; i++) {
306                         combo_rrd.push([rate_rrd[i], dupe_rrd[i]]);
307                     }
308                     
309
310                     packetgraph.sparkline(combo_rrd, {
311                         type: "bar", 
312                         height: 12, 
313                     });
314
315                     $('#rate', popup_content).sparkline(rate_rrd, {
316                         type: "bar",
317                         height: 12,
318                     });
319
320                     $('#error', popup_content).sparkline(error_rrd, {
321                         type: "bar",
322                         height: 12,
323                     });
324
325                     $('#dupe', popup_content).sparkline(dupe_rrd, {
326                         type: "bar",
327                         height: 12,
328                     });
329
330                     $('#queue', popup_content).sparkline(queue_rrd, {
331                         type: "bar",
332                         height: 12,
333                     });
334
335                     $('#drop', popup_content).sparkline(drop_rrd, {
336                         type: "bar",
337                         height: 12,
338                     });
339
340                 } catch (error) {
341
342                 }
343
344             })
345             .always(function() {
346                 timerid = setTimeout(packet_refresh, 1000);
347             });
348         } else {
349             timerid = setTimeout(packet_refresh, 1000);
350         }
351     }
352     */
353
354     $.fn.packetrate = function(data, inopt) {
355         // Get the stored value if one exists
356         storage = Storages.localStorage;
357
358         element = $(this);
359
360         element.addClass('kg-top-icon');
361
362         options = $.extend(base_options, inopt);
363
364         packetgraph = $('div.icon', this);
365         if (packetgraph.length == 0) {
366             packetgraph = $('<div>', {
367                 class: "icon",
368                 width: "100px",
369                 height: "10px",
370             });
371         }
372
373         click = $('a.packetbutton', this);
374
375         if (click.length != 0) {
376             click.empty();
377         }
378
379         click = $('<a>', {
380             href: "#",
381             class: "packetbutton"
382         })
383         .on('click', open_dialog);
384
385         click.append(packetgraph);
386         element.append(click);
387
388         packetgraph.sparkline([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], {
389             type: "bar", 
390             height: 12, 
391             width: 100,
392         });
393
394
395         element.tooltipster({
396             maxWidth: 450
397         });
398
399         kismet_ui_base.SubscribeEventbus("PACKETCHAIN_STATS", [], function(data) {
400             data = kismet.sanitizeObject(data);
401
402             try {
403                 var rate_rrd =
404                     kismet.RecalcRrdData2(data['kismet.packetchain.packets_rrd'], kismet.RRD_SECOND, {
405                         transform: function(data, opt) {
406                             var slices = 3;
407                             var peak = 0;
408                             var ret = new Array();
409
410                             for (var ri = 0; ri < data.length; ri++) {
411                                 peak = Math.max(peak, data[ri]);
412
413                                 if ((ri % slices) == (slices - 1)) {
414                                     ret.push(peak);
415                                     peak = 0;
416                                 }
417                             }
418
419                             return ret;
420                         }
421                     });
422
423                 var error_rrd =
424                     kismet.RecalcRrdData2(
425                         data['kismet.packetchain.error_packets_rrd'], kismet.RRD_SECOND, {
426                             transform: function(data, opt) {
427                                 var slices = 3;
428                                 var peak = 0;
429                                 var ret = new Array();
430
431                                 for (var ri = 0; ri < data.length; ri++) {
432                                     peak = Math.max(peak, data[ri]);
433
434                                     if ((ri % slices) == (slices - 1)) {
435                                         ret.push(peak);
436                                         peak = 0;
437                                     }
438                                 }
439
440                                 return ret;
441                             }
442                         });
443
444                 var dupe_rrd =
445                     kismet.RecalcRrdData2(
446                         data['kismet.packetchain.dupe_packets_rrd'], kismet.RRD_SECOND, {
447                             transform: function(data, opt) {
448                                 var slices = 3;
449                                 var peak = 0;
450                                 var ret = new Array();
451
452                                 for (var ri = 0; ri < data.length; ri++) {
453                                     peak = Math.max(peak, data[ri]);
454
455                                     if ((ri % slices) == (slices - 1)) {
456                                         ret.push(peak);
457                                         peak = 0;
458                                     }
459                                 }
460
461                                 return ret;
462                             }
463                         });
464
465                 var queue_rrd =
466                     kismet.RecalcRrdData2(
467                         data['kismet.packetchain.queued_packets_rrd'], kismet.RRD_SECOND, {
468                             transform: function(data, opt) {
469                                 var slices = 3;
470                                 var peak = 0;
471                                 var ret = new Array();
472
473                                 for (var ri = 0; ri < data.length; ri++) {
474                                     peak = Math.max(peak, data[ri]);
475
476                                     if ((ri % slices) == (slices - 1)) {
477                                         ret.push(peak);
478                                         peak = 0;
479                                     }
480                                 }
481
482                                 return ret;
483                             }
484                         });
485
486                 var drop_rrd =
487                     kismet.RecalcRrdData2(
488                         data['kismet.packetchain.dropped_packets_rrd'], kismet.RRD_SECOND, {
489                             transform: function(data, opt) {
490                                 var slices = 3;
491                                 var peak = 0;
492                                 var ret = new Array();
493
494                                 for (var ri = 0; ri < data.length; ri++) {
495                                     peak = Math.max(peak, data[ri]);
496
497                                     if ((ri % slices) == (slices - 1)) {
498                                         ret.push(peak);
499                                         peak = 0;
500                                     }
501                                 }
502
503                                 return ret;
504                             }
505                         });
506
507                 var combo_rrd = [];
508
509                 for (var i = 0; i < rate_rrd.length; i++) {
510                     combo_rrd.push([rate_rrd[i], dupe_rrd[i]]);
511                 }
512
513
514                 packetgraph.sparkline(combo_rrd, {
515                     type: "bar", 
516                     height: 12, 
517                 });
518
519                 $('#rate', popup_content).sparkline(rate_rrd, {
520                     type: "bar",
521                     height: 12,
522                 });
523
524                 $('#error', popup_content).sparkline(error_rrd, {
525                     type: "bar",
526                     height: 12,
527                 });
528
529                 $('#dupe', popup_content).sparkline(dupe_rrd, {
530                     type: "bar",
531                     height: 12,
532                 });
533
534                 $('#queue', popup_content).sparkline(queue_rrd, {
535                     type: "bar",
536                     height: 12,
537                 });
538
539                 $('#drop', popup_content).sparkline(drop_rrd, {
540                     type: "bar",
541                     height: 12,
542                 });
543
544             } catch (error) {
545
546             }
547
548         });
549     };
550
551 }(jQuery));