1 /* Metageek WiSPY interface
2  * Mike Kershaw/Dragorn <dragorn@kismetwireless.net>
3  *
4  * This code is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This code is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * Extra thanks to Ryan Woodings @ Metageek for interface documentation
15  */
16 
17 #include <stdlib.h>
18 #include "config.h"
19 #include "spectool_gtk_hw_registry.h"
20 #include "spectool_gtk.h"
21 #include "spectool_net.h"
22 #include "spectool_net_client.h"
23 
wdr_init(spectool_device_registry * wdr)24 void wdr_init(spectool_device_registry *wdr) {
25 	int x = 0;
26 
27 	wdr->max_dev = WDR_MAX_DEV - 1;
28 	wdr->cur_dev = 0;
29 
30 	wdr->max_srv = WDR_MAX_NET - 1;
31 	wdr->cur_srv = 0;
32 
33 	for (x = 0; x < WDR_MAX_DEV; x++) {
34 		wdr->devices[x] = NULL;
35 	}
36 
37 	for (x = 0; x < WDR_MAX_NET; x++) {
38 		wdr->netservers[x] = NULL;
39 	}
40 
41 	wdr->bcastsock = -1;
42 }
43 
wdr_free(spectool_device_registry * wdr)44 void wdr_free(spectool_device_registry *wdr) {
45 	int x = 0;
46 
47 	for (x = 0; x < WDR_MAX_DEV; x++) {
48 		if (wdr->devices[x] == NULL)
49 			continue;
50 
51 		/* Close it */
52 		spectool_phy_close(wdr->devices[x]->phydev);
53 
54 		g_list_free(wdr->devices[x]->sweep_cb_l);
55 
56 		/* remove the polling event */
57 		gdk_input_remove(wdr->devices[x]->poll_tag);
58 		free(wdr->devices[x]->poll_rec);
59 
60 		free(wdr->devices[x]);
61 	}
62 }
63 
wdr_open_add(spectool_device_registry * wdr,spectool_device_rec * devrec,int pos,char * errstr)64 int wdr_open_add(spectool_device_registry *wdr, spectool_device_rec *devrec, int pos,
65 				 char *errstr) {
66 	int x;
67 	spectool_phy *phydev;
68 	wdr_reg_dev *regdev;
69 
70 	for (x = 0; x < wdr->max_dev; x++) {
71 		if (wdr->devices[x] == NULL)
72 			continue;
73 
74 		if (wdr->devices[x]->phydev->device_spec->device_id ==
75 			devrec->device_id) {
76 			return x;
77 		}
78 	}
79 
80 	if (wdr->cur_dev >= wdr->max_dev) {
81 		snprintf(errstr, SPECTOOL_ERROR_MAX, "WDR registry full");
82 		return -1;
83 	}
84 
85 	phydev = (spectool_phy *) malloc(SPECTOOL_PHY_SIZE);
86 
87 	if (spectool_device_init(phydev, devrec) < 0) {
88 		printf("deug - wdr devinit failed\n");
89 		snprintf(errstr, SPECTOOL_ERROR_MAX, "Error initializing WiSPY device %s: %s",
90 				 devrec->name, spectool_get_error(phydev));
91 		free(phydev);
92 		return -1;
93 	}
94 
95 	if (spectool_phy_open(phydev) < 0) {
96 		snprintf(errstr, SPECTOOL_ERROR_MAX, "Error opening WiSPY device %s: %s",
97 				 devrec->name, spectool_get_error(phydev));
98 		free(phydev);
99 		return -1;
100 	}
101 
102 	/* We always want to calibrate it, imho */
103 	spectool_phy_setcalibration(phydev, 1);
104 
105 	/* Set the position to 0 for now */
106 	spectool_phy_setposition(phydev, pos, 0, 0);
107 
108 	regdev = (wdr_reg_dev *) malloc(sizeof(wdr_reg_dev));
109 	regdev->phydev = phydev;
110 	regdev->sweep_cb_l = NULL;
111 	/* The open callback used by the picker/menu needs to claim
112 	 * a reference to this */
113 	regdev->refcount = 0;
114 
115 	/* Queue it for polling */
116 	regdev->poll_rec = (wdr_poll_rec *) malloc(sizeof(wdr_poll_rec));
117 	((wdr_poll_rec *) regdev->poll_rec)->wdr = wdr;
118 
119 	regdev->poll_tag = gdk_input_add(spectool_phy_getpollfd(phydev),
120 									 GDK_INPUT_READ,
121 									 wdr_poll, regdev->poll_rec);
122 
123 	((wdr_poll_rec *) regdev->poll_rec)->poll_tag = regdev->poll_tag;
124 
125 	for (x = 0; x < wdr->max_dev; x++) {
126 		if (wdr->devices[x] != NULL)
127 			continue;
128 
129 		wdr->devices[x] = regdev;
130 		wdr->cur_dev++;
131 		((wdr_poll_rec *) regdev->poll_rec)->slot = x;
132 
133 		return x;
134 	}
135 
136 	return x;
137 }
138 
wdr_open_phy(spectool_device_registry * wdr,spectool_phy * phydev,char * errstr)139 int wdr_open_phy(spectool_device_registry *wdr, spectool_phy *phydev, char *errstr) {
140 	int x;
141 	wdr_reg_dev *regdev;
142 
143 	for (x = 0; x < wdr->max_dev; x++) {
144 		if (wdr->devices[x] == NULL)
145 			continue;
146 
147 		if (wdr->devices[x]->phydev->device_spec->device_id ==
148 			spectool_phy_getdevid(phydev)) {
149 			return x;
150 		}
151 	}
152 
153 	if (wdr->cur_dev >= wdr->max_dev) {
154 		snprintf(errstr, SPECTOOL_ERROR_MAX, "WDR registry full");
155 		return -1;
156 	}
157 
158 	regdev = (wdr_reg_dev *) malloc(sizeof(wdr_reg_dev));
159 	regdev->phydev = phydev;
160 	regdev->sweep_cb_l = NULL;
161 	/* The open callback used by the picker/menu needs to claim
162 	 * a reference to this */
163 	regdev->refcount = 0;
164 
165 	/* Queue it for polling */
166 	regdev->poll_rec = (wdr_poll_rec *) malloc(sizeof(wdr_poll_rec));
167 	((wdr_poll_rec *) regdev->poll_rec)->wdr = wdr;
168 
169 	regdev->poll_tag = gdk_input_add(spectool_phy_getpollfd(phydev),
170 									 GDK_INPUT_READ,
171 									 wdr_poll, regdev->poll_rec);
172 
173 	((wdr_poll_rec *) regdev->poll_rec)->poll_tag = regdev->poll_tag;
174 
175 	for (x = 0; x < wdr->max_dev; x++) {
176 		if (wdr->devices[x] != NULL)
177 			continue;
178 
179 		wdr->devices[x] = regdev;
180 		wdr->cur_dev++;
181 		((wdr_poll_rec *) regdev->poll_rec)->slot = x;
182 
183 		return x;
184 	}
185 
186 	return x;
187 }
188 
wdr_open_net(spectool_device_registry * wdr,char * url,char * errstr)189 int wdr_open_net(spectool_device_registry *wdr, char *url, char *errstr) {
190 	int x;
191 	spectool_server *netptr;
192 
193 	netptr = (spectool_server *) malloc(sizeof(spectool_server));
194 
195 	if (spectool_netcli_init(netptr, url, errstr) < 0)
196 		return -1;
197 
198 	if ((x = wdr_open_netptr(wdr, netptr, errstr)) < 0) {
199 		free(netptr);
200 	}
201 
202 	return x;
203 }
204 
wdr_open_netptr(spectool_device_registry * wdr,spectool_server * netptr,char * errstr)205 int wdr_open_netptr(spectool_device_registry *wdr, spectool_server *netptr,
206 					char *errstr) {
207 	int x;
208 	wdr_reg_srv *wrs;
209 
210 	for (x = 0; x < wdr->max_srv; x++) {
211 		if (wdr->netservers[x] == NULL)
212 			continue;
213 
214 		if (spectool_netcli_getaddr(wdr->netservers[x]->srv) ==
215 			spectool_netcli_getaddr(netptr) &&
216 			spectool_netcli_getport(wdr->netservers[x]->srv) ==
217 			spectool_netcli_getport(netptr)) {
218 			return x;
219 		}
220 	}
221 
222 	if (wdr->cur_srv >= wdr->max_srv) {
223 		snprintf(errstr, SPECTOOL_ERROR_MAX, "WDR registry full");
224 		return -1;
225 	}
226 
227 	wrs = (wdr_reg_srv *) malloc(sizeof(wdr_reg_srv));
228 
229 	wrs->iowtag = -1;
230 	wrs->iortag = -1;
231 
232 	wrs->srv = netptr;
233 
234 	if (spectool_netcli_connect(wrs->srv, errstr) < 0) {
235 		return -1;
236 	}
237 
238 	spectool_netcli_setbufferwrite(wrs->srv, 0);
239 
240 	wrs->poll_rec = (wdr_poll_rec *) malloc(sizeof(wdr_poll_rec));
241 
242 	((wdr_poll_rec *) wrs->poll_rec)->wdr = wdr;
243 
244 	wrs->ioch = g_io_channel_unix_new(spectool_netcli_getpollfd(wrs->srv));
245 	wrs->iortag = g_io_add_watch(wrs->ioch, G_IO_IN, wdr_netrpoll, wrs->poll_rec);
246 
247 	((wdr_poll_rec *) wrs->poll_rec)->poll_tag = wrs->iortag;
248 
249 	wrs->tree_row_ref = NULL;
250 
251 	for (x = 0; x < wdr->max_srv; x++) {
252 		if (wdr->netservers[x] != NULL)
253 			continue;
254 
255 		wdr->netservers[x] = wrs;
256 		wdr->cur_srv++;
257 		((wdr_poll_rec *) wrs->poll_rec)->slot = x;
258 
259 		return x;
260 	}
261 
262 	return x;
263 }
264 
wdr_close_net(spectool_device_registry * wdr,int slot)265 void wdr_close_net(spectool_device_registry *wdr, int slot) {
266 	if (slot < 0 || slot > wdr->max_srv)
267 		return;
268 
269 	if (wdr->netservers[slot] == NULL)
270 		return;
271 
272 	spectool_netcli_close(wdr->netservers[slot]->srv);
273 
274 	/* remove the polling event */
275 	g_io_channel_shutdown(wdr->netservers[slot]->ioch, TRUE, NULL);
276 
277 	free(wdr->netservers[slot]->poll_rec);
278 	free(wdr->netservers[slot]);
279 
280 	wdr->netservers[slot] = NULL;
281 	wdr->cur_srv--;
282 }
283 
wdr_enable_bcast(spectool_device_registry * wdr,char * errstr)284 int wdr_enable_bcast(spectool_device_registry *wdr, char *errstr) {
285 	if ((wdr->bcastsock = spectool_netcli_initbroadcast(SPECTOOL_NET_DEFAULT_PORT,
286 														errstr)) < 0)
287 		return -1;
288 
289 	wdr->bcioc = g_io_channel_unix_new(wdr->bcastsock);
290 	wdr->bcioc_rtag =
291 		g_io_add_watch(wdr->bcioc, G_IO_IN, wdr_bcpoll, wdr);
292 
293 	return 1;
294 }
295 
wdr_disable_bcast(spectool_device_registry * wdr)296 void wdr_disable_bcast(spectool_device_registry *wdr) {
297 	if (wdr->bcastsock >= 0) {
298 		close(wdr->bcastsock);
299 
300 		g_io_channel_shutdown(wdr->bcioc, TRUE, NULL);
301 	}
302 
303 	wdr->bcastsock = -1;
304 }
305 
wdr_bcpoll(GIOChannel * ioch,GIOCondition cond,gpointer data)306 gboolean wdr_bcpoll(GIOChannel *ioch, GIOCondition cond, gpointer data) {
307 	spectool_device_registry *wdr = (spectool_device_registry *) data;
308 	char bcasturl[SPECTOOL_NETCLI_URL_MAX];
309 	char errstr[SPECTOOL_ERROR_MAX];
310 	char reperr[SPECTOOL_ERROR_MAX];
311 	int ret;
312 
313 	if ((ret = spectool_netcli_pollbroadcast(wdr->bcastsock,
314 											 bcasturl, errstr)) < 0) {
315 		snprintf(reperr, SPECTOOL_ERROR_MAX, "Error processing broadcast packet, disabling "
316 				 "broadcast detection: %s", errstr);
317 		Spectool_Alert_Dialog(reperr);
318 		wdr_disable_bcast(wdr);
319 		return FALSE;
320 	} else if (ret > 0) {
321 		wdr_open_net(wdr, bcasturl, errstr);
322 	}
323 
324 	return TRUE;
325 }
326 
wdr_get_phy(spectool_device_registry * wdr,int slot)327 spectool_phy *wdr_get_phy(spectool_device_registry *wdr, int slot) {
328 	if (slot < 0 || slot > wdr->max_dev)
329 		return NULL;
330 
331 	if (wdr->devices[slot] == NULL)
332 		return NULL;
333 
334 	return wdr->devices[slot]->phydev;
335 }
336 
wdr_add_ref(spectool_device_registry * wdr,int slot)337 void wdr_add_ref(spectool_device_registry *wdr, int slot) {
338 	if (slot < 0 || slot > wdr->max_dev)
339 		return;
340 
341 	if (wdr->devices[slot] == NULL)
342 		return;
343 
344 	wdr->devices[slot]->refcount++;
345 }
346 
wdr_del_ref(spectool_device_registry * wdr,int slot)347 void wdr_del_ref(spectool_device_registry *wdr, int slot) {
348 	if (slot < 0 || slot > wdr->max_dev)
349 		return;
350 
351 	if (wdr->devices[slot] == NULL)
352 		return;
353 
354 	wdr->devices[slot]->refcount--;
355 
356 	if (wdr->devices[slot]->refcount > 0)
357 		return;
358 
359 	spectool_phy_close(wdr->devices[slot]->phydev);
360 
361 	g_list_free(wdr->devices[slot]->sweep_cb_l);
362 
363 	/* remove the polling event */
364 	gdk_input_remove(wdr->devices[slot]->poll_tag);
365 	free(wdr->devices[slot]->poll_rec);
366 
367 	free(wdr->devices[slot]);
368 
369 	wdr->devices[slot] = NULL;
370 	wdr->cur_dev--;
371 }
372 
wdr_add_sweepcb(spectool_device_registry * wdr,int slot,void (* cb)(int,int,spectool_sample_sweep *,void *),int nagg,void * aux)373 void wdr_add_sweepcb(spectool_device_registry *wdr, int slot,
374 					 void (*cb)(int, int, spectool_sample_sweep *, void *),
375 					 int nagg, void *aux) {
376 	wdr_reg_sweep_cb *wdrcb;
377 
378 	if (slot < 0 || slot > wdr->max_dev)
379 		return;
380 
381 	if (wdr->devices[slot] == NULL)
382 		return;
383 
384 	wdrcb = (wdr_reg_sweep_cb *) malloc(sizeof(wdr_reg_sweep_cb));
385 
386 	wdrcb->aux = aux;
387 	wdrcb->cb = cb;
388 
389 	if (nagg == 0) {
390 		wdrcb->agg_sweep = NULL;
391 	} else {
392 		wdrcb->agg_sweep = spectool_cache_alloc(nagg, 1, 0);
393 	}
394 	wdrcb->num_agg = nagg;
395 	wdrcb->pos_agg = 0;
396 
397 	wdr->devices[slot]->sweep_cb_l =
398 		g_list_append(wdr->devices[slot]->sweep_cb_l, wdrcb);
399 }
400 
wdr_del_sweepcb(spectool_device_registry * wdr,int slot,void (* cb)(int,int,spectool_sample_sweep *,void *),void * aux)401 void wdr_del_sweepcb(spectool_device_registry *wdr, int slot,
402 					 void (*cb)(int, int, spectool_sample_sweep *, void *),
403 					 void *aux) {
404 	GList *iter;
405 
406 	if (slot < 0 || slot > wdr->max_dev)
407 		return;
408 
409 	if (wdr->devices[slot] == NULL)
410 		return;
411 
412 	iter = wdr->devices[slot]->sweep_cb_l;
413 
414 	/* Simple iterative search */
415 	while (iter != NULL) {
416 		if (((wdr_reg_sweep_cb *) iter->data)->cb == cb &&
417 			((wdr_reg_sweep_cb *) iter->data)->aux == aux) {
418 			wdr->devices[slot]->sweep_cb_l =
419 				g_list_remove(wdr->devices[slot]->sweep_cb_l,
420 							  iter->data);
421 			return;
422 		}
423 
424 		iter = g_list_next(iter);
425 	}
426 }
427 
wdr_sweep_update(spectool_device_registry * wdr,int slot,int mode,spectool_sample_sweep * sweep)428 void wdr_sweep_update(spectool_device_registry *wdr, int slot,
429 					  int mode, spectool_sample_sweep *sweep) {
430 	GList *iter;
431 	wdr_reg_sweep_cb *scb;
432 
433 	if (slot < 0 || slot > wdr->max_dev)
434 		return;
435 
436 	if (wdr->devices[slot] == NULL)
437 		return;
438 
439 	iter = wdr->devices[slot]->sweep_cb_l;
440 
441 	/* Simple iterative search */
442 	while (iter != NULL) {
443 		scb = (wdr_reg_sweep_cb *) iter->data;
444 
445 		/* Only pass along the peak if we've filled the aggregate or
446 		 * we've got no aggregation */
447 		if (scb->agg_sweep == NULL || sweep == NULL) {
448 			(*(scb->cb))(slot, mode, sweep, scb->aux);
449 		} else {
450 			spectool_cache_append(scb->agg_sweep, sweep);
451 			scb->pos_agg++;
452 
453 			if (scb->pos_agg == scb->num_agg) {
454 				(*(scb->cb))(slot, mode, scb->agg_sweep->peak, scb->aux);
455 				spectool_cache_clear(scb->agg_sweep);
456 				scb->pos_agg = 0;
457 			}
458 		}
459 
460 		// (*(scb->cb))(slot, mode, sweep, scb->aux);
461 		iter = g_list_next(iter);
462 	}
463 }
464 
wdr_poll(gpointer data,gint source,GdkInputCondition condition)465 void wdr_poll(gpointer data, gint source, GdkInputCondition condition) {
466 	wdr_poll_rec *wdrpr = (wdr_poll_rec *) data;
467 	spectool_phy *phydev;
468 	int r;
469 	char err[SPECTOOL_ERROR_MAX];
470 	spectool_sample_sweep *sweep;
471 
472 	if (wdrpr->slot < 0 || wdrpr->slot > wdrpr->wdr->max_dev)
473 		return;
474 
475 	if (wdrpr->wdr->devices[wdrpr->slot] == NULL)
476 		return;
477 
478 	phydev = wdrpr->wdr->devices[wdrpr->slot]->phydev;
479 
480 	do {
481 		r = spectool_phy_poll(phydev);
482 
483 		if ((r & SPECTOOL_POLL_ERROR)) {
484 			snprintf(err, SPECTOOL_ERROR_MAX, "Error polling WiSPY device %s: %s",
485 					 spectool_phy_getname(phydev), spectool_get_error(phydev));
486 			/* spectool_phy_close(phydev); */
487 
488 			/* Push the error, this should result in all the graphs removing
489 			 * their references to us */
490 			wdr_sweep_update(wdrpr->wdr, wdrpr->slot, r, NULL);
491 
492 			/* Pop up the error */
493 			Spectool_Alert_Dialog(err);
494 
495 			/* remove us from being pollable, free our tracker ref.  No-one should
496 			 * reference us anymore since we told them there was an error, so we
497 			 * can drop out entirely */
498 			gdk_input_remove(wdrpr->poll_tag);
499 			return;
500 		} else if ((r & SPECTOOL_POLL_CONFIGURED)) {
501 			wdr_sweep_update(wdrpr->wdr, wdrpr->slot, r, NULL);
502 			return;
503 		} else if ((r & SPECTOOL_POLL_SWEEPCOMPLETE)) {
504 			sweep = spectool_phy_getsweep(phydev);
505 
506 			if (sweep == NULL)
507 				continue;
508 
509 			wdr_sweep_update(wdrpr->wdr, wdrpr->slot, r, sweep);
510 
511 			continue;
512 		}
513 
514 	} while ((r & SPECTOOL_POLL_ADDITIONAL));
515 
516 	/* We do nothing otherwise, no events for partial polls */
517 }
518 
wdr_netrpoll(GIOChannel * ioch,GIOCondition cond,gpointer data)519 gboolean wdr_netrpoll(GIOChannel *ioch, GIOCondition cond, gpointer data) {
520 	wdr_poll_rec *wdrpr = (wdr_poll_rec *) data;
521 	spectool_server *sr;
522 	int r;
523 	char err[SPECTOOL_ERROR_MAX];
524 
525 	if (wdrpr->slot < 0 || wdrpr->slot > wdrpr->wdr->max_dev)
526 		return FALSE;
527 
528 	if (wdrpr->wdr->netservers[wdrpr->slot] == NULL)
529 		return FALSE;
530 
531 	sr = wdrpr->wdr->netservers[wdrpr->slot]->srv;
532 
533 	do {
534 		r = spectool_netcli_poll(sr, err);
535 
536 		if (r < 0) {
537 			Spectool_Alert_Dialog(err);
538 
539 			wdr_close_net(wdrpr->wdr, wdrpr->slot);
540 			return FALSE;
541 		}
542 
543 	} while ((r & SPECTOOL_NETCLI_POLL_ADDITIONAL));
544 }
545 
wdr_populate_menu(spectool_device_registry * wdr,GtkWidget * menu,int sep,int fillnodev,GCallback cb,void * aux)546 GList *wdr_populate_menu(spectool_device_registry *wdr, GtkWidget *menu,
547 						 int sep, int fillnodev,
548 						 GCallback cb, void *aux) {
549 	wdr_menu_rec *r;
550 	GtkWidget *mi;
551 	int x;
552 	GList *cbr = NULL;
553 
554 	if (wdr->cur_dev <= 0) {
555 		if (fillnodev) {
556 			mi = gtk_menu_item_new_with_label("No devices open");
557 			gtk_widget_set_sensitive(GTK_WIDGET(mi), 0);
558 			gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
559 			gtk_widget_show(mi);
560 			return NULL;
561 		}
562 
563 		return NULL;
564 	}
565 
566 	for (x = 0; x < wdr->max_dev; x++) {
567 		if (wdr->devices[x] == NULL)
568 			continue;
569 
570 		/* Build the aux */
571 		r = (wdr_menu_rec *) malloc(sizeof(wdr_menu_rec));
572 		r->slot = x;
573 		r->aux = aux;
574 		r->wdr = wdr;
575 
576 		/* Add us to the lists */
577 		cbr = g_list_append(cbr, r);
578 
579 		/* Increase our refcount - we have to do this so that there is
580 		 * no race for devices if a graph is being closed */
581 		wdr_add_ref(wdr, x);
582 
583 		mi = gtk_menu_item_new_with_label(spectool_phy_getname(wdr->devices[x]->phydev));
584 		gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
585 		g_signal_connect_swapped(G_OBJECT(mi), "activate",
586 								 G_CALLBACK(cb), r);
587 		gtk_widget_show(mi);
588 	}
589 
590 	if (sep) {
591 		mi = gtk_separator_menu_item_new();
592 		gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
593 		gtk_widget_show(mi);
594 	}
595 
596 	return cbr;
597 }
598 
wdr_free_menu_fe(gpointer * data,gpointer * user)599 void wdr_free_menu_fe(gpointer *data, gpointer *user) {
600 	wdr_menu_rec *r = (wdr_menu_rec *) data;
601 
602 	/* Unref the device */
603 	wdr_del_ref(r->wdr, r->slot);
604 
605 	/* Free the data hunk */
606 	free(r);
607 }
608 
wdr_free_menu(spectool_device_registry * wdr,GList * gl)609 void wdr_free_menu(spectool_device_registry *wdr, GList *gl) {
610 	g_list_foreach(gl, (GFunc) wdr_free_menu_fe, NULL);
611 	g_list_free(gl);
612 }
613 
wdr_devpicker_onrowactivated(GtkTreeView * treeview,GtkTreePath * path,GtkTreeViewColumn * column,gpointer * aux)614 void wdr_devpicker_onrowactivated(GtkTreeView *treeview, GtkTreePath *path,
615 								  GtkTreeViewColumn *column, gpointer *aux) {
616 	GtkTreeModel *model;
617 	GtkTreeIter iter;
618 	wdr_gtk_devpicker_aux *dpaux = (wdr_gtk_devpicker_aux *) aux;
619 	char err[SPECTOOL_ERROR_MAX];
620 
621 	model = gtk_tree_view_get_model(treeview);
622 
623 	if (gtk_tree_model_get_iter(model, &iter, path)) {
624 		void *phyptr;
625 		int r, p;
626 
627 		gtk_tree_model_get(model, &iter, 1, &phyptr, 2, &p, -1);
628 
629 		/* Open it and add it to the registry */
630 		r = wdr_open_add(dpaux->wdr, phyptr, p, err);
631 
632 		/* Error alert */
633 		if (r < 0) {
634 			Spectool_Alert_Dialog(err);
635 		} else {
636 			/* Call their callback saying we've picked a device */
637 			if (dpaux->pickcb != NULL)
638 				(*(dpaux->pickcb))(r, dpaux->cbaux);
639 		}
640 
641 		gtk_widget_destroy(dpaux->picker_win);
642 	}
643 }
644 
wdr_devpicker_destroy(GtkWidget * widget,gpointer * aux)645 void wdr_devpicker_destroy(GtkWidget *widget, gpointer *aux) {
646 	wdr_gtk_devpicker_aux *dpaux = (wdr_gtk_devpicker_aux *) aux;
647 
648 	spectool_device_scan_free(&(dpaux->devlist));
649 
650 	free(aux);
651 }
652 
wdr_devpicker_populate(wdr_gtk_devpicker_aux * dpaux)653 void wdr_devpicker_populate(wdr_gtk_devpicker_aux *dpaux) {
654 	int ndevs, x, s;
655 	GtkTreeIter iter;
656 	GtkListStore *model;
657 	GtkTreeSelection *selection;
658 	char name[64];
659 
660 	model = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT);
661 	gtk_tree_view_set_model(GTK_TREE_VIEW(dpaux->treeview), GTK_TREE_MODEL(model));
662 
663 	/* So that when we replace it in the tree view it gets released */
664 	g_object_unref(model);
665 
666 	/*
667 	if (dpaux->treemodellist != NULL)
668 		g_free(dpaux->treemodellist);
669 	*/
670 
671 	dpaux->treemodellist = model;
672 
673 	spectool_device_scan_free(&(dpaux->devlist));
674 
675 	/* Scan for Spectool V1 devices */
676 	ndevs = spectool_device_scan(&(dpaux->devlist));
677 
678 	if (ndevs <= 0) {
679 		gtk_list_store_append(GTK_LIST_STORE(dpaux->treemodellist), &iter);
680 		gtk_list_store_set(GTK_LIST_STORE(dpaux->treemodellist), &iter,
681 						   0, "No WiSPY Devices",
682 						   1, NULL,
683 						   2, 0,
684 						   -1);
685 		gtk_widget_set_sensitive(dpaux->okbutton, 0);
686 		gtk_widget_set_sensitive(dpaux->scrolled_win, 0);
687 	} else {
688 		for (x = 0; x < dpaux->devlist.num_devs; x++) {
689 			if (dpaux->devlist.list[x].num_sweep_ranges == 0) {
690 				gtk_list_store_append(GTK_LIST_STORE(dpaux->treemodellist), &iter);
691 
692 				gtk_list_store_set(GTK_LIST_STORE(dpaux->treemodellist), &iter,
693 								   0, dpaux->devlist.list[x].name,
694 								   1, &(dpaux->devlist.list[x]),
695 								   2, 0,
696 								   -1);
697 				/* Handle making sure the first item is always selected by
698 				 * unselecting them all, then selecting one */
699 				if (x == 0) {
700 					selection =
701 						gtk_tree_view_get_selection(GTK_TREE_VIEW(dpaux->treeview));
702 					gtk_tree_selection_unselect_all(selection);
703 					gtk_tree_selection_select_iter(selection, &iter);
704 				}
705 			} else {
706 				for (s = 0; s < dpaux->devlist.list[x].num_sweep_ranges; s++) {
707 					gtk_list_store_append(GTK_LIST_STORE(dpaux->treemodellist), &iter);
708 
709 					snprintf(name, 64, "%s - %s", dpaux->devlist.list[x].name,
710 							 dpaux->devlist.list[x].supported_ranges[s].name);
711 
712 					gtk_list_store_set(GTK_LIST_STORE(dpaux->treemodellist), &iter,
713 									   0, name,
714 									   1, &(dpaux->devlist.list[x]),
715 									   2, s,
716 									   -1);
717 
718 					if (x == 0 && s == 0) {
719 						selection =
720 							gtk_tree_view_get_selection(GTK_TREE_VIEW(dpaux->treeview));
721 						gtk_tree_selection_unselect_all(selection);
722 						gtk_tree_selection_select_iter(selection, &iter);
723 					}
724 				}
725 			}
726 		}
727 		gtk_widget_set_sensitive(dpaux->okbutton, 1);
728 		gtk_widget_set_sensitive(dpaux->scrolled_win, 1);
729 	}
730 }
731 
wdr_devpicker_button(GtkWidget * widget,gpointer * aux)732 void wdr_devpicker_button(GtkWidget *widget, gpointer *aux) {
733 	wdr_gtk_devpicker_aux *dpaux = (wdr_gtk_devpicker_aux *) aux;
734 
735 	if (widget == dpaux->cancelbutton) {
736 		gtk_widget_destroy(dpaux->picker_win);
737 		return;
738 	}
739 
740 	if (widget == dpaux->okbutton) {
741 		GtkTreeSelection *selection;
742 		GtkTreeModel *model;
743 		GtkTreeIter iter;
744 		char err[SPECTOOL_ERROR_MAX];
745 
746 		selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dpaux->treeview));
747 		if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
748 			void *phyptr;
749 			int r;
750 			int p;
751 			gtk_tree_model_get(model, &iter, 1, &phyptr, 2, &p, -1);
752 
753 			/* Open it and add it to the registry */
754 			r = wdr_open_add(dpaux->wdr, phyptr, p, err);
755 
756 			if (r < 0) {
757 				Spectool_Alert_Dialog(err);
758 			} else {
759 				/* Call their callback saying we've picked a device */
760 				if (dpaux->pickcb != NULL)
761 					(*(dpaux->pickcb))(r, dpaux->cbaux);
762 			}
763 		}
764 
765 		gtk_widget_destroy(dpaux->picker_win);
766 		return;
767 	}
768 
769 	if (widget == dpaux->rescanbutton) {
770 		wdr_devpicker_populate(dpaux);
771 		return;
772 	}
773 }
774 
wdr_devpicker_spawn(spectool_device_registry * wdr,void (* cb)(int,void *),void * aux)775 void wdr_devpicker_spawn(spectool_device_registry *wdr,
776 						 void (*cb)(int, void *), void *aux) {
777 	GtkWidget *top_window, *scrolled_window;
778 
779 	GtkWidget *vbox, *hbox;
780 	GtkWidget *tree_view;
781 
782 	GtkTreeIter iter;
783 	GtkCellRenderer *cell;
784 	GtkTreeViewColumn *column;
785 	int x, ndevs;
786 
787 	wdr_gtk_devpicker_aux *dpaux =
788 		(wdr_gtk_devpicker_aux *) malloc(sizeof(wdr_gtk_devpicker_aux));
789 
790 	dpaux->wdr = wdr;
791 	dpaux->pickcb = cb;
792 	dpaux->cbaux = aux;
793 
794 	spectool_device_scan_init(&(dpaux->devlist));
795 
796 	scrolled_window = gtk_scrolled_window_new(NULL, NULL);
797 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
798 								   GTK_POLICY_AUTOMATIC,
799 								   GTK_POLICY_AUTOMATIC);
800 
801 	tree_view = gtk_tree_view_new();
802 	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),
803 										  tree_view);
804 
805 	dpaux->treemodellist = NULL;
806 	dpaux->scrolled_win = scrolled_window;
807 
808 	cell = gtk_cell_renderer_text_new();
809 	column = gtk_tree_view_column_new_with_attributes("USB Devices",
810 													  cell,
811 													  "text", 0,
812 													  NULL);
813 	gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view),
814 								GTK_TREE_VIEW_COLUMN(column));
815 
816 	g_signal_connect(tree_view, "row-activated",
817 					 (GCallback) wdr_devpicker_onrowactivated, dpaux);
818 
819 	dpaux->treeview = GTK_TREE_VIEW(tree_view);
820 	dpaux->treecolumn = column;
821 
822 	top_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
823 	gtk_window_set_title(GTK_WINDOW(top_window), "WiSPY USB Selection");
824 	gtk_container_set_border_width(GTK_CONTAINER(top_window), 10);
825 	gtk_widget_set_size_request(GTK_WIDGET(top_window), 500, 250);
826 
827 	dpaux->picker_win = top_window;
828 
829 	g_signal_connect(G_OBJECT(top_window), "destroy",
830 					 G_CALLBACK(wdr_devpicker_destroy), dpaux);
831 
832 	vbox = gtk_vbox_new(FALSE, 0);
833 	gtk_container_add(GTK_CONTAINER(top_window), vbox);
834 	gtk_widget_show(vbox);
835 
836 	gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 2);
837 
838 	hbox = gtk_hbox_new(FALSE, 0);
839 	gtk_widget_show(hbox);
840 
841 	dpaux->okbutton = gtk_toggle_button_new_with_label("Enable");
842 	gtk_signal_connect(GTK_OBJECT(dpaux->okbutton), "clicked",
843 					   GTK_SIGNAL_FUNC(wdr_devpicker_button), dpaux);
844 
845 	dpaux->cancelbutton = gtk_toggle_button_new_with_label("Cancel");
846 	gtk_signal_connect(GTK_OBJECT(dpaux->cancelbutton), "clicked",
847 					   GTK_SIGNAL_FUNC(wdr_devpicker_button), dpaux);
848 
849 	dpaux->rescanbutton = gtk_toggle_button_new_with_label("Re-Scan");
850 	gtk_signal_connect(GTK_OBJECT(dpaux->rescanbutton), "clicked",
851 					   GTK_SIGNAL_FUNC(wdr_devpicker_button), dpaux);
852 
853 	gtk_box_pack_start(GTK_BOX(hbox), dpaux->okbutton, FALSE, FALSE, 2);
854 	gtk_box_pack_start(GTK_BOX(hbox), dpaux->cancelbutton, FALSE, FALSE, 2);
855 	gtk_box_pack_start(GTK_BOX(hbox), dpaux->rescanbutton, FALSE, FALSE, 2);
856 
857 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
858 
859 	wdr_devpicker_populate(dpaux);
860 
861 	gtk_widget_show(tree_view);
862 	gtk_widget_show(dpaux->okbutton);
863 	gtk_widget_show(dpaux->cancelbutton);
864 	gtk_widget_show(dpaux->rescanbutton);
865 
866 	gtk_widget_show(scrolled_window);
867 	gtk_widget_show(top_window);
868 }
869 
wdr_netmanager_destroy(GtkWidget * widget,gpointer * aux)870 void wdr_netmanager_destroy(GtkWidget *widget, gpointer *aux) {
871 	wdr_gtk_netmanager_aux *nmaux = (wdr_gtk_netmanager_aux *) aux;
872 	int x = 0;
873 
874 	nmaux->wdr->netmanager = NULL;
875 
876 	if (nmaux->timer_ref > 0)
877 		g_source_remove(nmaux->timer_ref);
878 
879 	for (x = 0; x < nmaux->wdr->max_srv; x++) {
880 		if (nmaux->wdr->netservers[x] != NULL) {
881 			gtk_tree_row_reference_free(nmaux->wdr->netservers[x]->tree_row_ref);
882 			nmaux->wdr->netservers[x]->tree_row_ref = NULL;
883 		}
884 	}
885 
886 	free(nmaux);
887 }
888 
wdr_netmanager_populate(wdr_gtk_netmanager_aux * nmaux)889 gint wdr_netmanager_populate(wdr_gtk_netmanager_aux *nmaux) {
890 	int nsrv, x;
891 	GtkTreeIter iter, child;
892 	GtkTreeStore *store;
893 	GtkTreeSelection *selection;
894 	spectool_net_dev *sni = NULL;
895 	GtkTreePath *path;
896 	gboolean expanded;
897 
898 	GList *devrows, *dri;
899 
900 	if (nmaux == NULL)
901 		return FALSE;
902 
903 	if (nmaux->treestore == NULL) {
904 		store = gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_UINT);
905 		gtk_tree_view_set_model(GTK_TREE_VIEW(nmaux->treeview), GTK_TREE_MODEL(store));
906 		g_object_unref(store);
907 		nmaux->treestore = store;
908 		nmaux->noservers = NULL;
909 	} else {
910 		store = nmaux->treestore;
911 	}
912 
913 	if (nmaux->wdr->cur_srv == 0) {
914 		if (nmaux->noservers == NULL) {
915 			gtk_tree_store_append(store, &iter, NULL);
916 			gtk_tree_store_set(store, &iter,
917 							   0, "Not connected to any servers...",
918 							   1, -1,
919 							   2, 0,
920 							   -1);
921 			nmaux->noservers =
922 				gtk_tree_row_reference_new(GTK_TREE_MODEL(store),
923 							gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter));
924 		}
925 	} else if (nmaux->noservers != NULL) {
926 		/* Get rid of our "no servers" element */
927 		if (gtk_tree_row_reference_valid(nmaux->noservers) &&
928 			gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter,
929 					gtk_tree_row_reference_get_path(nmaux->noservers))) {
930 			gtk_tree_store_remove(store, &iter);
931 
932 			gtk_tree_row_reference_free(nmaux->noservers);
933 			nmaux->noservers = NULL;
934 		}
935 	}
936 
937 	for (x = 0; x < nmaux->wdr->max_srv; x++) {
938 		if (nmaux->wdr->netservers[x] != NULL) {
939 			if (nmaux->wdr->netservers[x]->tree_row_ref == NULL ||
940 				!gtk_tree_row_reference_valid(nmaux->wdr->netservers[x]->tree_row_ref)) {
941 				gtk_tree_store_append(store, &iter, NULL);
942 				gtk_tree_store_set(store, &iter,
943 					0, spectool_netcli_geturl(nmaux->wdr->netservers[x]->srv),
944 					1, x,
945 	 				2, 0,
946 					-1);
947 
948 				gtk_tree_row_reference_free(nmaux->wdr->netservers[x]->tree_row_ref);
949 				path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
950 				nmaux->wdr->netservers[x]->tree_row_ref =
951 					gtk_tree_row_reference_new(GTK_TREE_MODEL(store), path);
952 				gtk_tree_path_free(path);
953 			} else {
954 				/* search the child nodes to see what devices are valid and if we
955 				 * need to redo them */
956 				gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter,
957 				gtk_tree_row_reference_get_path(nmaux->wdr->netservers[x]->tree_row_ref));
958 			}
959 
960 			sni = nmaux->wdr->netservers[x]->srv->devlist;
961 
962 			expanded =
963 				gtk_tree_view_row_expanded(nmaux->treeview,
964 										   gtk_tree_row_reference_get_path(
965 											nmaux->wdr->netservers[x]->tree_row_ref));
966 
967 			/* If we have no devices, clear out the list and say something */
968 			if (sni == NULL) {
969 				while (gtk_tree_model_iter_children(GTK_TREE_MODEL(store), &child, &iter)) {
970 					gtk_tree_store_remove(store, &child);
971 				}
972 
973 				gtk_tree_store_append(store, &child, &iter);
974 				if (spectool_netcli_getstate(nmaux->wdr->netservers[x]->srv) ==
975 					SPECTOOL_NET_STATE_CONNECTED) {
976 					gtk_tree_store_set(store, &child,
977 									   0, "Waiting for device list (Press update)...",
978 									   1, -1,
979 									   2, 0,
980 									   -1);
981 				} else if (spectool_netcli_getstate(nmaux->wdr->netservers[x]->srv) ==
982 						   SPECTOOL_NET_STATE_ERROR) {
983 					gtk_tree_store_set(store, &child,
984 									   0, "Server error...",
985 									   1, -1,
986 									   2, 0,
987 									   -1);
988 				} else {
989 					gtk_tree_store_set(store, &child,
990 									   0, "No devices found...",
991 									   1, -1,
992 									   2, 0,
993 									   -1);
994 				}
995 
996 				if (expanded)
997 					gtk_tree_view_expand_row(nmaux->treeview,
998 											 gtk_tree_row_reference_get_path(
999 										nmaux->wdr->netservers[x]->tree_row_ref),
1000 											 TRUE);
1001 
1002 				continue;
1003 			} else {
1004 				/* Look for devices we need to remove */
1005 				devrows = NULL;
1006 				if (gtk_tree_model_iter_children(GTK_TREE_MODEL(store), &child, &iter)) {
1007 					unsigned int devid;
1008 
1009 					do {
1010 						int matched = 0;
1011 						gtk_tree_model_get(GTK_TREE_MODEL(store), &child,
1012 										   2, &devid,
1013 										   -1);
1014 
1015 
1016 						sni = nmaux->wdr->netservers[x]->srv->devlist;
1017 						while (sni != NULL) {
1018 							if (sni->device_id == devid) {
1019 								matched = 1;
1020 								break;
1021 							}
1022 
1023 							sni = sni->next;
1024 						}
1025 
1026 						/* Make a reference to it */
1027 						if (matched == 0) {
1028 							path =
1029 								gtk_tree_model_get_path(GTK_TREE_MODEL(store), &child);
1030 							devrows = g_list_append(devrows,
1031 									gtk_tree_row_reference_new(GTK_TREE_MODEL(store),
1032 															   path));
1033 							gtk_tree_path_free(path);
1034 						}
1035 					} while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &child));
1036 
1037 					/* remove all the references */
1038 					dri = devrows;
1039 					while (devrows) {
1040 						gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &child,
1041 								gtk_tree_row_reference_get_path(devrows->data));
1042 
1043 						gtk_tree_store_remove(store, &child);
1044 
1045 						gtk_tree_row_reference_free(devrows->data);
1046 						devrows = g_list_next(devrows);
1047 					}
1048 					g_list_free(dri);
1049 				}
1050 
1051 				/* Add devices we don't have */
1052 				sni = nmaux->wdr->netservers[x]->srv->devlist;
1053 				while (sni != NULL) {
1054 					int matched = 0;
1055 					if (gtk_tree_model_iter_children(GTK_TREE_MODEL(store),
1056 													 &child, &iter)) {
1057 						unsigned int devid;
1058 
1059 						do {
1060 							gtk_tree_model_get(GTK_TREE_MODEL(store), &child,
1061 											   2, &devid,
1062 											   -1);
1063 
1064 							if (sni->device_id == devid) {
1065 								matched = 1;
1066 								break;
1067 							}
1068 
1069 						} while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &child));
1070 					}
1071 
1072 					if (matched == 0) {
1073 						gtk_tree_store_append(store, &child, &iter);
1074 						gtk_tree_store_set(store, &child,
1075 										   0, sni->device_name,
1076 										   1, x,
1077 										   2, sni->device_id,
1078 										   -1);
1079 					}
1080 
1081 					sni = sni->next;
1082 				}
1083 
1084 				if (expanded)
1085 					gtk_tree_view_expand_row(nmaux->treeview,
1086 											 gtk_tree_row_reference_get_path(
1087 										nmaux->wdr->netservers[x]->tree_row_ref),
1088 											 TRUE);
1089 
1090 			}
1091 		}
1092 	}
1093 
1094 	return TRUE;
1095 }
1096 
wdr_netmanager_selection(GtkTreeSelection * selection,GtkTreeModel * model,GtkTreePath * path,gboolean path_currently_selected,gpointer aux)1097 gboolean wdr_netmanager_selection(GtkTreeSelection *selection,
1098 								  GtkTreeModel     *model,
1099 								  GtkTreePath      *path,
1100 								  gboolean          path_currently_selected,
1101 								  gpointer          aux) {
1102 	GtkTreeIter iter;
1103 	wdr_gtk_netmanager_aux *nmaux = (wdr_gtk_netmanager_aux *) aux;
1104 	int srvid;
1105 	unsigned int devid;
1106 
1107 	if (gtk_tree_model_get_iter(model, &iter, path)) {
1108 		gtk_tree_model_get(model, &iter, 1, &srvid, 2, &devid, -1);
1109 
1110 		if (!path_currently_selected) {
1111 			if (srvid >= 0 && devid == 0) {
1112 				gtk_widget_set_sensitive(GTK_WIDGET(nmaux->dconbutton), 1);
1113 				gtk_widget_set_sensitive(GTK_WIDGET(nmaux->openbutton), 0);
1114 			} else if (srvid >= 0) {
1115 				gtk_widget_set_sensitive(GTK_WIDGET(nmaux->dconbutton), 0);
1116 				gtk_widget_set_sensitive(GTK_WIDGET(nmaux->openbutton), 1);
1117 			} else {
1118 				return FALSE;
1119 			}
1120 		}
1121 	}
1122 
1123 	return TRUE;
1124 }
1125 
wdr_netmanager_button(GtkWidget * widget,gpointer * aux)1126 void wdr_netmanager_button(GtkWidget *widget, gpointer *aux) {
1127 	wdr_gtk_netmanager_aux *nmaux = (wdr_gtk_netmanager_aux *) aux;
1128 
1129 	if (widget == nmaux->closebutton) {
1130 		gtk_widget_destroy(nmaux->picker_win);
1131 		return;
1132 	} else if (widget == nmaux->addbutton) {
1133 		wdr_netentry_spawn(nmaux->wdr);
1134 	} else if (widget == nmaux->openbutton) {
1135 		GtkTreeSelection *selection;
1136 		GtkTreeModel *model;
1137 		GtkTreeIter iter;
1138 		char err[SPECTOOL_ERROR_MAX];
1139 
1140 		selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(nmaux->treeview));
1141 		if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
1142 			spectool_phy *phyptr;
1143 			int srvid;
1144 			unsigned int devid;
1145 			int r;
1146 
1147 			gtk_tree_model_get(model, &iter, 1, &srvid, 2, &devid, -1);
1148 
1149 			if (srvid < 0 || devid == 0)
1150 				return;
1151 
1152 			/* Open it and add it to the registry */
1153 			phyptr =
1154 				spectool_netcli_enabledev(nmaux->wdr->netservers[srvid]->srv,
1155 										  devid, err);
1156 
1157 			if (phyptr == NULL) {
1158 				Spectool_Alert_Dialog(err);
1159 			} else {
1160 				r = wdr_open_phy(nmaux->wdr, phyptr, err);
1161 
1162 				if (r < 0) {
1163 					Spectool_Alert_Dialog(err);
1164 				} else {
1165 					/* Call their callback saying we've picked a device */
1166 					if (nmaux->pickcb != NULL)
1167 						(*(nmaux->pickcb))(r, nmaux->cbaux);
1168 				}
1169 			}
1170 
1171 			gtk_widget_destroy(nmaux->picker_win);
1172 			return;
1173 		}
1174 	}
1175 }
1176 
wdr_netmanager_onrowactivated(GtkTreeView * treeview,GtkTreePath * path,GtkTreeViewColumn * column,gpointer * aux)1177 void wdr_netmanager_onrowactivated(GtkTreeView *treeview, GtkTreePath *path,
1178 								  GtkTreeViewColumn *column, gpointer *aux) {
1179 	wdr_gtk_netmanager_aux *nmaux = (wdr_gtk_netmanager_aux *) aux;
1180 
1181 	wdr_netmanager_button(nmaux->openbutton, aux);
1182 }
1183 
wdr_netmanager_spawn(spectool_device_registry * wdr,void (* cb)(int,void *),void * aux)1184 void wdr_netmanager_spawn(spectool_device_registry *wdr,
1185 						 void (*cb)(int, void *),
1186 						 void *aux) {
1187 	GtkWidget *top_window, *scrolled_window;
1188 
1189 	GtkWidget *vbox, *hbox;
1190 	GtkWidget *tree_view;
1191 
1192 	GtkTreeIter iter;
1193 	GtkCellRenderer *cell;
1194 	GtkTreeViewColumn *column;
1195 	GtkTreeSelection  *selection;
1196 
1197 	int x, ndevs;
1198 
1199 	char url[1024];
1200 	char err[SPECTOOL_ERROR_MAX];
1201 
1202 	wdr_gtk_netmanager_aux *nmaux =
1203 		(wdr_gtk_netmanager_aux *) malloc(sizeof(wdr_gtk_netmanager_aux));
1204 
1205 	nmaux->wdr = wdr;
1206 	nmaux->pickcb = cb;
1207 	nmaux->cbaux = aux;
1208 
1209 	scrolled_window = gtk_scrolled_window_new(NULL, NULL);
1210 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
1211 								   GTK_POLICY_AUTOMATIC,
1212 								   GTK_POLICY_AUTOMATIC);
1213 
1214 	tree_view = gtk_tree_view_new();
1215 	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),
1216 										  tree_view);
1217 
1218 	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
1219 	gtk_tree_selection_set_select_function(selection, wdr_netmanager_selection,
1220 										   nmaux, NULL);
1221 
1222 	nmaux->treestore = NULL;
1223 	nmaux->scrolled_win = scrolled_window;
1224 
1225 	cell = gtk_cell_renderer_text_new();
1226 	column = gtk_tree_view_column_new_with_attributes("Network Devices",
1227 													  cell,
1228 													  "text", 0,
1229 													  NULL);
1230 	gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view),
1231 								GTK_TREE_VIEW_COLUMN(column));
1232 
1233 	g_signal_connect(tree_view, "row-activated",
1234 					 (GCallback) wdr_netmanager_onrowactivated, nmaux);
1235 
1236 	nmaux->treeview = GTK_TREE_VIEW(tree_view);
1237 	nmaux->treecolumn = column;
1238 
1239 	top_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1240 	gtk_window_set_title(GTK_WINDOW(top_window), "Spectool Network Devices");
1241 	gtk_container_set_border_width(GTK_CONTAINER(top_window), 10);
1242 	gtk_widget_set_size_request(GTK_WIDGET(top_window), 500, 250);
1243 
1244 	nmaux->picker_win = top_window;
1245 
1246 	g_signal_connect(G_OBJECT(top_window), "destroy",
1247 					 G_CALLBACK(wdr_netmanager_destroy), nmaux);
1248 
1249 	vbox = gtk_vbox_new(FALSE, 0);
1250 	gtk_container_add(GTK_CONTAINER(top_window), vbox);
1251 	gtk_widget_show(vbox);
1252 
1253 	gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 2);
1254 
1255 	hbox = gtk_hbox_new(FALSE, 0);
1256 	gtk_widget_show(hbox);
1257 
1258 	nmaux->addbutton = gtk_button_new_with_label("Add Server");
1259 	gtk_signal_connect(GTK_OBJECT(nmaux->addbutton), "clicked",
1260 					   GTK_SIGNAL_FUNC(wdr_netmanager_button), nmaux);
1261 
1262 	nmaux->dconbutton = gtk_button_new_with_label("Disconnect Server");
1263 	gtk_signal_connect(GTK_OBJECT(nmaux->dconbutton), "clicked",
1264 					   GTK_SIGNAL_FUNC(wdr_netmanager_button), nmaux);
1265 
1266 	nmaux->openbutton = gtk_button_new_with_label("Open Device");
1267 	gtk_signal_connect(GTK_OBJECT(nmaux->openbutton), "clicked",
1268 					   GTK_SIGNAL_FUNC(wdr_netmanager_button), nmaux);
1269 
1270 	nmaux->closebutton = gtk_button_new_with_label("Close");
1271 	gtk_signal_connect(GTK_OBJECT(nmaux->closebutton), "clicked",
1272 					   GTK_SIGNAL_FUNC(wdr_netmanager_button), nmaux);
1273 
1274 	gtk_widget_set_sensitive(nmaux->dconbutton, 0);
1275 	gtk_widget_set_sensitive(nmaux->openbutton, 0);
1276 
1277 	gtk_box_pack_start(GTK_BOX(hbox), nmaux->addbutton, FALSE, FALSE, 2);
1278 	gtk_box_pack_start(GTK_BOX(hbox), nmaux->dconbutton, FALSE, FALSE, 2);
1279 	gtk_box_pack_start(GTK_BOX(hbox), nmaux->openbutton, FALSE, FALSE, 2);
1280 	gtk_box_pack_start(GTK_BOX(hbox), nmaux->closebutton, FALSE, FALSE, 2);
1281 
1282 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
1283 
1284 	wdr_netmanager_populate(nmaux);
1285 
1286 	gtk_widget_show(tree_view);
1287 	gtk_widget_show(nmaux->addbutton);
1288 	gtk_widget_show(nmaux->dconbutton);
1289 	gtk_widget_show(nmaux->closebutton);
1290 	gtk_widget_show(nmaux->openbutton);
1291 
1292 	gtk_widget_show(scrolled_window);
1293 	gtk_widget_show(top_window);
1294 
1295 	wdr->netmanager = nmaux;
1296 
1297 	nmaux->timer_ref = g_timeout_add(2000,
1298 									 (GSourceFunc) wdr_netmanager_populate,
1299 									 nmaux);
1300 
1301 	snprintf(url, 1024, "tcp://localhost:%d", SPECTOOL_NET_DEFAULT_PORT);
1302 
1303 	if (wdr_open_net(wdr, url, err) >= 0) {
1304 		wdr_netmanager_populate(wdr->netmanager);
1305 	}
1306 }
1307 
wdr_netentry_destroy(GtkWidget * widget,gpointer * aux)1308 void wdr_netentry_destroy(GtkWidget *widget, gpointer *aux) {
1309 	wdr_gtk_netentry_aux *npaux = (wdr_gtk_netentry_aux *) aux;
1310 
1311 	free(aux);
1312 }
1313 
wdr_netentry_button(GtkWidget * widget,gpointer * aux)1314 void wdr_netentry_button(GtkWidget *widget, gpointer *aux) {
1315 	wdr_gtk_netentry_aux *npaux = (wdr_gtk_netentry_aux *) aux;
1316 
1317 	if (widget == npaux->cancelbutton) {
1318 		gtk_widget_destroy(npaux->picker_win);
1319 		return;
1320 	}
1321 
1322 	if (widget == npaux->okbutton) {
1323 		char err[SPECTOOL_ERROR_MAX];
1324 		char url[1024];
1325 		int r;
1326 
1327 		snprintf(url, 1024, "tcp://%s:%s",
1328 				 gtk_entry_get_text(GTK_ENTRY(npaux->hostentry)),
1329 				 gtk_entry_get_text(GTK_ENTRY(npaux->portentry)));
1330 
1331 		if (wdr_open_net(npaux->wdr, url, err) < 0) {
1332 			Spectool_Alert_Dialog(err);
1333 		}
1334 
1335 		wdr_netmanager_populate(npaux->wdr->netmanager);
1336 
1337 		gtk_widget_destroy(npaux->picker_win);
1338 		return;
1339 	}
1340 }
1341 
wdr_netentry_spawn(spectool_device_registry * wdr)1342 void wdr_netentry_spawn(spectool_device_registry *wdr) {
1343 	GtkWidget *top_window;
1344 
1345 	GtkWidget *vbox, *hbox;
1346 
1347 	GtkWidget *label;
1348 
1349 	char port[16];
1350 
1351 	wdr_gtk_netentry_aux *npaux =
1352 		(wdr_gtk_netentry_aux *) malloc(sizeof(wdr_gtk_netentry_aux));
1353 
1354 	npaux->wdr = wdr;
1355 
1356 	top_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1357 	gtk_window_set_title(GTK_WINDOW(top_window), "Spectool Network");
1358 	gtk_container_set_border_width(GTK_CONTAINER(top_window), 10);
1359 	gtk_widget_set_size_request(GTK_WIDGET(top_window), 500, 250);
1360 
1361 	npaux->picker_win = top_window;
1362 
1363 	g_signal_connect(G_OBJECT(top_window), "destroy",
1364 					 G_CALLBACK(wdr_netentry_destroy), npaux);
1365 
1366 	vbox = gtk_vbox_new(FALSE, 0);
1367 	gtk_container_add(GTK_CONTAINER(top_window), vbox);
1368 	gtk_widget_show(vbox);
1369 
1370 	label = gtk_label_new("Host:");
1371 	gtk_widget_show(label);
1372 	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 2);
1373 
1374 	npaux->hostentry = gtk_entry_new();
1375 	gtk_entry_set_text(GTK_ENTRY(npaux->hostentry), "localhost");
1376 	gtk_entry_set_editable(GTK_ENTRY(npaux->hostentry), 1);
1377 	gtk_widget_show(npaux->hostentry);
1378 	gtk_box_pack_start(GTK_BOX(vbox), npaux->hostentry, FALSE, TRUE, 2);
1379 
1380 	label = gtk_label_new("Port:");
1381 	gtk_widget_show(label);
1382 	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 2);
1383 
1384 	npaux->portentry = gtk_entry_new();
1385 	snprintf(port, 16, "%hd", SPECTOOL_NET_DEFAULT_PORT);
1386 	gtk_entry_set_text(GTK_ENTRY(npaux->portentry), port);
1387 	gtk_entry_set_editable(GTK_ENTRY(npaux->portentry), 1);
1388 	gtk_widget_show(npaux->portentry);
1389 	gtk_box_pack_start(GTK_BOX(vbox), npaux->portentry, FALSE, TRUE, 2);
1390 
1391 	hbox = gtk_hbox_new(FALSE, 0);
1392 	gtk_widget_show(hbox);
1393 
1394 	npaux->okbutton = gtk_toggle_button_new_with_label("Enable");
1395 	gtk_signal_connect(GTK_OBJECT(npaux->okbutton), "clicked",
1396 					   GTK_SIGNAL_FUNC(wdr_netentry_button), npaux);
1397 
1398 	npaux->cancelbutton = gtk_toggle_button_new_with_label("Cancel");
1399 	gtk_signal_connect(GTK_OBJECT(npaux->cancelbutton), "clicked",
1400 					   GTK_SIGNAL_FUNC(wdr_netentry_button), npaux);
1401 
1402 	gtk_box_pack_start(GTK_BOX(hbox), npaux->okbutton, FALSE, FALSE, 2);
1403 	gtk_box_pack_start(GTK_BOX(hbox), npaux->cancelbutton, FALSE, FALSE, 2);
1404 
1405 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
1406 
1407 	gtk_widget_show(npaux->okbutton);
1408 	gtk_widget_show(npaux->cancelbutton);
1409 
1410 	gtk_widget_show(top_window);
1411 }
1412 
1413