floormap.php3 13 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
#
# EMULAB-COPYRIGHT
# Copyright (c) 2004 University of Utah and the Flux Group.
# All rights reserved.
#
include("defs.php3");

#
# Standard Testbed Header
#
PAGEHEADER("Wireless Node Map");

#
15
# Only logged in people at the moment; might open up at some point.
16
17
18
19
20
21
22
23
#
$uid = GETLOGIN();
LOGGEDINORDIE($uid);
$isadmin = ISADMIN($uid);

# Careful with this local variable
unset($prefix);

24
#
25
26
27
28
29
30
31
32
33
34
35
# Verify page arguments. First allow user to optionally specify building/floor.
#
if (isset($building) && $building != "") {
    # Sanitize for the shell.
    if (!preg_match("/^[-\w]+$/", $building)) {
	PAGEARGERROR("Invalid building argument.");
    }
    # Optional floor argument. Sanitize for the shell.
    if (isset($floor) && !preg_match("/^[-\w]+$/", $floor)) {
	PAGEARGERROR("Invalid floor argument.");
    }
36
}
37
38
39
else {
    unset($building);
    unset($floor);
40
41
}

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#
# Optional pid,eid. Without a building/floor, show all the nodes for the
# experiment in all buildings/floors. Without pid,eid show all wireless
# nodes in the specified building/floor.
#
if (isset($pid) && $pid != "" && isset($eid) && $eid != "") {
    if (!TBvalid_pid($pid)) {
	PAGEARGERROR("Invalid project ID.");
    }
    if (!TBvalid_eid($eid)) {
	PAGEARGERROR("Invalid experiment ID.");
    }

    if (! TBValidExperiment($pid, $eid)) {
	USERERROR("The experiment $pid/$eid is not a valid experiment!", 1);
    }
    if (! TBExptAccessCheck($uid, $pid, $eid, $TB_EXPT_READINFO)) {
	USERERROR("You do not have permission to view experiment $pid/$eid!", 1);
    }
}
else {
    unset($pid);
    unset($eid);
}

67
68
69
# THIS is ugly...  Value= is not passed by IE on <input type=image>, so we wrap the
# scale value into the button name.  Hence we will see coordinates of scale_1_x
# scale_2_x, etc. when the buttons are pressed.  Decode to just a $scale value here.
70
71
72
if (isset($scale_0_x) && $scale_0_x != "") {
    $scale = 0;
}
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
if (isset($scale_1_x) && $scale_1_x != "") {
    $scale = 1;
}
elseif (isset($scale_2_x) && $scale_2_x != "") {
    $scale = 2;
}
elseif (isset($scale_3_x) && $scale_3_x != "") {
    $scale = 3;
}
elseif (isset($scale_4_x) && $scale_4_x != "") {
    $scale = 4;
}
elseif (isset($scale_5_x) && $scale_5_x != "") {
    $scale = 5;
}

89
90
91
#
# Verify numeric scale and centering arguments.
#
92
if (isset($scale) && $scale !== "") {  # "0" is a valid value for $scale.
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
    # Sanitize for the shell.
    if (!preg_match("/^[0-9]+$/", $scale)) {
	PAGEARGERROR("Invalid scale argument.");
    }
}
else {
    unset($scale);
}
#
# map_x and map_y are the map.x and map.y coordinates from clicking on the map.
#
if (isset($map_x) && $map_x != "") {
    # Sanitize for the shell.
    if (!preg_match("/^[0-9]+$/", $map_x)) {
	PAGEARGERROR("Invalid map_x argument.");
    }
}
else {
    unset($map_x);
}
if (isset($map_y) && $map_y != "") {
    # Sanitize for the shell.
    if (!preg_match("/^[0-9]+$/", $map_y)) {
	PAGEARGERROR("Invalid map_y argument.");
    }
}
else {
    unset($map_y);
}
#
# We need the previous scale and click coords, and offsets to interpret new click coords!
#
125
if (isset($last_scale) && $last_scale !== "") {  # "0" is a valid value.
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    # Sanitize for the shell.
    if (!preg_match("/^[0-9]+$/", $last_scale)) {
	PAGEARGERROR("Invalid last_scale argument.");
    }
}
else {
    unset($last_scale);
}
if (isset($last_x) && $last_x != "") {
    # Sanitize for the shell.
    if (!preg_match("/^[0-9]+$/", $last_x)) {
	PAGEARGERROR("Invalid last_x argument.");
    }
}
else {
    unset($last_x);
}
if (isset($last_y) && $last_y != "") {
    # Sanitize for the shell.
    if (!preg_match("/^[0-9]+$/", $last_y)) {
	PAGEARGERROR("Invalid last_y argument.");
    }
}
else {
    unset($last_y);
}
if (isset($last_x_off) && $last_x_off != "") {
    # Sanitize for the shell.
    if (!preg_match("/^[0-9]+$/", $last_x_off)) {
	PAGEARGERROR("Invalid last_x_off argument.");
    }
}
else {
    unset($last_x_off);
}
if (isset($last_y_off) && $last_y_off != "") {
    # Sanitize for the shell.
    if (!preg_match("/^[0-9]+$/", $last_y_off)) {
	PAGEARGERROR("Invalid last_y_off argument.");
    }
}
else {
    unset($last_y_off);
}
if (isset($last_notitles) && $last_notitles != "") {
    # Sanitize for the shell.
    if (!preg_match("/^[0-9]+$/", $last_notitles)) {
	PAGEARGERROR("Invalid last_notitles argument.");
    }
}
else {
    unset($last_notitles);
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
180
181
182
#
# Figure out what channels are in use for the current building. We only
# have one building (MEB) at the moment, so this is quite easy.
183
# Also determine what the free,reserved,dead counts are. 
Leigh B. Stoller's avatar
Leigh B. Stoller committed
184
#
185
186
$channels   = array();
$nodecounts = array();
187
$nodes      = array();
188
189
190
191

$nodecounts["free"]     = 0;
$nodecounts["reserved"] = 0;
$nodecounts["dead"]     = 0;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
192
193

$query_result =
194
    DBQueryFatal("select loc.*,s.capval,r.pid,r.eid from location_info as loc ".
Leigh B. Stoller's avatar
Leigh B. Stoller committed
195
		 "left join interface_settings as s on ".
196
197
		 "     s.node_id=loc.node_id and s.capkey='channel' ".
		 "left join reserved as r on r.node_id=loc.node_id");
Leigh B. Stoller's avatar
Leigh B. Stoller committed
198
199
200
201
202

while ($row = mysql_fetch_array($query_result)) {
    $channel   = $row["capval"];
    $node_id   = $row["node_id"];
    $locfloor  = $row["floor"];
203
204
205
    $rpid      = $row["pid"];
    $reid      = $row["eid"];

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
    #
    # The above query to get the channels will give us multiple rows
    # if there are multiple interface cards in use; do not want to
    # count those twice.
    # 
    if (!isset($nodes[$node_id])) {
	$nodes[$node_id] = 1;
	
	if ((!isset($pid) && !(isset($rpid))) ||
	    (isset($pid) && isset($rpid) && $pid == $rpid)) {
	    $nodecounts["free"]++;
	}
	elseif ($rpid == $NODEDEAD_PID && $reid == $NODEDEAD_EID) {
	    $nodecounts["dead"]++;
	}
	else {
	    $nodecounts["reserved"]++;
	}
224
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
225

226
227
228
229
230
    # Make sure an empty list is displayed if nothing allocated on a floor.
    if (!isset($channels[$locfloor])) {
	$channels[$locfloor] = array();
    }

Leigh B. Stoller's avatar
Leigh B. Stoller committed
231
232
233
234
235
236
    if (!isset($channel))
	continue;

    $channels[$locfloor][$channel] = $channel;
}

237
#
238
239
# Run the Perl script. It will produce three output files; image, areamap, and state.
# We want to embed all of these images into the page we send back. This is painful!
240
241
242
243
244
#
# Need cleanup "handler" to make sure temp files get deleted! 
#
function CLEANUP()
{
245
246
247
    global $prefix;
    
    if (isset($prefix) && (connection_aborted())) {
248
	unlink("${prefix}.jpg");
249
	unlink("${prefix}.map");
250
	unlink("${prefix}.state");
251
252
253
254
255
256
257
258
	unlink($prefix);
    }
    exit();
}
register_shutdown_function("CLEANUP");

#
# Create a tempfile to use as a unique prefix; it is not actually used but
259
# serves the same purpose (The script uses ${prefix}.jpg and ${prefix}.map .)
260
# 
261
$prefix = tempnam("/tmp", "floormap");
262

263
264
265
266
267
268
269
270
#
# Get the unique part to send back.
#
if (!preg_match("/^\/tmp\/([-\w]+)$/", $prefix, $matches)) {
    TBERROR("Bad tempnam: $prefix", 1);
}
$uniqueid = $matches[1];

271
272
273
274
# Default the ghosting checkbox state to checked the first time through.
if (!isset($last_ghost)) {
    $ghost = 1;	
}
275

276
277
278
$perl_args = "-o $prefix " .
	     # From clicking on a zoom button.
	     (isset($scale) ? "-s $scale " : "") .
279

280
281
	     # From clicking on a map image.
	     (isset($map_x) ? "-c $map_x,$map_y " : "") .
282

283
284
285
286
287
288
289
	     # Previous image state info came from an included .state
	     # file, previously output by the Perl script along with the map.
	     (isset($last_scale) ? "-S $last_scale " : "") .
	     (isset($last_x) ? "-C $last_x,$last_y " : "") .
	     (isset($last_x_off) ? "-O $last_x_off,$last_y_off " : "") .
	     (isset($last_notitles) && $last_notitles ? "-T " : "") .
	     (isset($ghost) ? "-g " : "") .
290

291
292
293
294
295
296
297
298
	     (isset($pid) ? "-e $pid,$eid " : "") .
	     (isset($floor) ? "-f $floor " : "") .
	     (isset($building) ? "$building" : "");  # Building arg must be last!

if (0) {    ### Put the Perl script args into the page when debugging.
    echo "\$btfv/floormap -d $perl_args\n";
}
$retval = SUEXEC($uid, "nobody", "webfloormap $perl_args", SUEXEC_ACTION_IGNORE);
299
300

if ($retval) {
301
    SUEXECERROR(SUEXEC_ACTION_USERERROR);
302
303
304
305
306
307
308
309
310
311
312
313
    # Never returns.
    die("");
}

#
# Spit the areamap contained in the file out; it is fully formatted and
# called "floormap".
#
if (! readfile("${prefix}.map")) {
    TBERROR("Could not read ${prefix}.map", 1);
}

314
315
echo "<font size=+1>For more info on using wireless nodes, see the
     <a href='tutorial/docwrapper.php3?docname=wireless.html'>
316
     wireless tutorial.</a></font>\n";
317

318
echo "<center>\n";
319

320
321
322
323
# Consolidate layout by pulling the info and control tables into a horizontal row.
echo "<table style=\"border-width: 0; background-color: transparent\">
      <tr> <td>\n";

324
325
326
327
328
# Legend
if (isset($pid)) {
    echo "Wireless nodes in experiment <b>".
         "<a href='showproject.php3?pid=$pid'>$pid</a>/".
         "<a href='showexp.php3?pid=$pid&eid=$eid'>$eid</a></b>\n";
329
330

    echo "<table align=center border=2 cellpadding=5 cellspacing=2>
331
 	  <tr>
332
            <td align=right>
333
                <img src='/autostatus-icons/greenball.gif' alt=Experiment>
334
335
                <b>Experiment</b></td>
            <td align=left> &nbsp; " . $nodecounts["free"] . "</td>
336
337
          </tr>
          <tr>
338
            <td align=right>
339
                <img src='/autostatus-icons/blueball.gif' alt=Other>
340
341
                <b>Other Nodes</b></td>
            <td align=left> &nbsp; " . $nodecounts["reserved"] . "</td>
342
343
          </tr>
          <tr>
344
345
346
347
            <td align=right>
                <img src='/autostatus-icons/redball.gif' alt=Dead>
                <b>Dead</b></td>
            <td align=left> &nbsp; " . $nodecounts["dead"] . "</td>
348
          </tr>
349
          </table>\n";
350
351
}
else {
352
    echo "<table align=center border=2 cellpadding=5 cellspacing=2>
353
 	  <tr>
354
            <td align=right>
355
                <img src='/autostatus-icons/greenball.gif' alt=Free>
356
357
                <b>Free</b></td>
            <td align=left> &nbsp; " . $nodecounts["free"] . "</td>
358
359
          </tr>
          <tr>
360
            <td align=right>
361
                <img src='/autostatus-icons/blueball.gif' alt=reserved>
362
363
                <b>Reserved</b></td>
            <td align=left> &nbsp; " . $nodecounts["reserved"] . "</td>
364
365
          </tr>
          <tr>
366
367
368
369
            <td align=right>
                <img src='/autostatus-icons/redball.gif' alt=Dead>
                <b>Dead</b></td>
            <td align=left> &nbsp; " . $nodecounts["dead"] . "</td>
370
          </tr>
371
          </table>\n";
372
373
}

374
echo "</td> <td style=\" background-color: transparent\"> &nbsp; &nbsp; </td> <td>\n";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
375

376
377
378
# Wrap the image and zoom controls together in an input form.
echo "<form method=\"get\" action=\"floormap.php3#zoom\">\n";

379
# Zoom controls may be clicked to set a new scale.  Otherwise, it persists.
380
381
382
383
384
385
$curr_scale = (isset($scale) ? $scale : (isset($last_scale) ? $last_scale : 1));
echo "  <a name=zoom></a>\n";
function zoom_btns($curr_scale) {
echo "  <table align=\"center\" border=\"2\" cellpadding=\"0\" cellspacing=\"2\">\n";
echo "    <tbody>\n";
echo "      <tr>\n";
386
# Wrap the scale into the button name.  Value= is not passed by IE.
387
388
389
echo "        <td><input type=\"image\" src=\"floormap/btn_zoom_out.jpg\"\n";
echo "             name=\"scale_" . max($curr_scale-1,0) . "\"><br></td>\n";
for ($i = 0; $i <= 5; $i++) {
390
    $img = "btn_scale_" . $i . "_" . ($curr_scale==$i?"brt":"dim") . ".jpg";
391
    echo "        <td><input type=\"image\" src=\"floormap/$img\"\n";
392
    echo "             name=\"scale_$i\"><br></td>\n";
393
}
394
395
echo "        <td><input type=\"image\" src=\"floormap/btn_zoom_in.jpg\"\n";
echo "             name=\"scale_" . min($curr_scale+1,5) . "\"><br></td>\n";
396
397
398
399
echo "      </tr>\n";
echo "    </tbody>\n";
echo "  </table>\n";
}
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
zoom_btns($curr_scale);  # Two copies of the zoom buttons bracket the image.

echo "</td> <td style=\" background-color: transparent\"> &nbsp; &nbsp; </td> <td>\n";

if (count($channels)) {
    echo "<table align=center border=2 cellpadding=0 cellspacing=2>
 	  <tr><th>Floor</th><th>Channels in Use</th></tr>\n";
    
    while (list($floor, $chanlist) = each($channels)) {
	echo "<tr><td>$floor</td>\n";
	echo "    <td>";

	echo implode(",", array_keys($chanlist));

	echo "    </td>
              </tr>\n";
    }
    echo "</table>\n";
}

echo "</td> </tr> </table>\n";
421

422
# The image may be clicked to get node info or set a new center-point.
423
424
425
echo "  Click on the dots below to see information about the node.\n";
echo "  <br>\n";
echo "  Clicks elsewhere on the map set the center point for a zoomed-in view.\n";
426
echo "  <br>\n";
427
428
429
430
431
432
# The checkbox value is sent when the box is checked; nothing is sent otherwise.
echo "  <input name=ghost type=checkbox value=\"1\"" .
	  (isset($ghost) ? " checked" : "") . ">\n"; # Current checkbox state.
echo "  Show nodes on other floors as hollow dots.\n";
echo "  <br>\n";
echo "  <input name=map type=image style=\"border: 2px solid\" ";
433
434
435
436
437
438
439
440
441
442
443
444
445
446
echo          "src=\"floormap_aux.php3?prefix=$uniqueid\" usemap=\"#floormap\">\n";
echo "  <br>\n";
zoom_btns($curr_scale);

# Hidden items are all returned as page arguments when any input control is clicked.
echo "  <input type=\"hidden\" name=\"prefix\" value=\"$uniqueid\">\n";

# The last_* items come from a .state file with the map, from the Perl script.
if (! readfile("${prefix}.state")) {
    TBERROR("Could not read ${prefix}.state", 1);
}

echo "</form>\n";
echo "</center>\n";
447

448
449
450
451
452
#
# Standard Testbed Footer
# 
PAGEFOOTER();
?>