Project

General

Profile

Download (17.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	services_ntpd_gps.php
5

    
6
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
7
	Copyright (C) 2013	Dagorlad
8
	Copyright (C) 2012	Jim Pingle
9
	All rights reserved.
10

    
11
	Redistribution and use in source and binary forms, with or without
12
	modification, are permitted provided that the following conditions are met:
13

    
14
	1. Redistributions of source code must retain the above copyright notice,
15
	   this list of conditions and the following disclaimer.
16

    
17
	2. Redistributions in binary form must reproduce the above copyright
18
	   notice, this list of conditions and the following disclaimer in the
19
	   documentation and/or other materials provided with the distribution.
20

    
21
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
	POSSIBILITY OF SUCH DAMAGE.
31
*/
32
/*
33
	pfSense_MODULE: ntpd_gps
34
*/
35

    
36
##|+PRIV
37
##|*IDENT=page-services-ntpd-gps
38
##|*NAME=Services: NTP Serial GPS page
39
##|*DESCR=Allow access to the 'Services: NTP Serial GPS' page..
40
##|*MATCH=services_ntpd_gps.php*
41
##|-PRIV
42

    
43
require_once("guiconfig.inc");
44

    
45
function set_default_gps() {
46
	global $config;
47

    
48
	if (!is_array($config['ntpd']))
49
		$config['ntpd'] = array();
50

    
51
	if (is_array($config['ntpd']['gps']))
52
		unset($config['ntpd']['gps']);
53

    
54
	$config['ntpd']['gps'] = array();
55
	$config['ntpd']['gps']['type'] = 'Default';
56
	/* copy an existing configured GPS port if it exists, the unset may be uncommented post production */
57
	if (!empty($config['ntpd']['gpsport']) && empty($config['ntpd']['gps']['port'])) {
58
		$config['ntpd']['gps']['port'] = $config['ntpd']['gpsport'];
59
		unset($config['ntpd']['gpsport']); /* this removes the original port config from config.xml */
60
		$config['ntpd']['gps']['speed'] = 0;
61
		$config['ntpd']['gps']['nmea'] = 0;
62
	}
63

    
64
	write_config("Setting default NTPd settings");
65
}
66

    
67
if ($_POST) {
68
	unset($input_errors);
69

    
70
	if (!empty($_POST['gpsport']) && file_exists('/dev/'.$_POST['gpsport']))
71
		$config['ntpd']['gps']['port'] = $_POST['gpsport'];
72
	/* if port is not set, remove all the gps config */
73
	else unset($config['ntpd']['gps']);
74

    
75
	if (!empty($_POST['gpstype']))
76
		$config['ntpd']['gps']['type'] = $_POST['gpstype'];
77
	elseif (isset($config['ntpd']['gps']['type']))
78
		unset($config['ntpd']['gps']['type']);
79

    
80
	if (!empty($_POST['gpsspeed']))
81
		$config['ntpd']['gps']['speed'] = $_POST['gpsspeed'];
82
	elseif (isset($config['ntpd']['gps']['speed']))
83
		unset($config['ntpd']['gps']['speed']);
84

    
85
	if (!empty($_POST['gpsnmea']) && ($_POST['gpsnmea'][0] === "0"))
86
		$config['ntpd']['gps']['nmea'] = "0";
87
	else
88
		$config['ntpd']['gps']['nmea'] = strval(array_sum($_POST['gpsnmea']));
89

    
90
	if (!empty($_POST['gpsfudge1']))
91
		$config['ntpd']['gps']['fudge1'] = $_POST['gpsfudge1'];
92
	elseif (isset($config['ntpd']['gps']['fudge1']))
93
		unset($config['ntpd']['gps']['fudge1']);
94

    
95
	if (!empty($_POST['gpsfudge2']))
96
		$config['ntpd']['gps']['fudge2'] = $_POST['gpsfudge2'];
97
	elseif (isset($config['ntpd']['gps']['fudge2']))
98
		unset($config['ntpd']['gps']['fudge2']);
99

    
100
	if (!empty($_POST['gpsstratum']) && ($_POST['gpsstratum']) < 17 )
101
		$config['ntpd']['gps']['stratum'] = $_POST['gpsstratum'];
102
	elseif (isset($config['ntpd']['gps']['stratum']))
103
		unset($config['ntpd']['gps']['stratum']);
104

    
105
	if (empty($_POST['gpsprefer']))
106
		$config['ntpd']['gps']['prefer'] = 'on';
107
	elseif (isset($config['ntpd']['gps']['prefer']))
108
		unset($config['ntpd']['gps']['prefer']);
109

    
110
	if (!empty($_POST['gpsselect']))
111
		$config['ntpd']['gps']['noselect'] = $_POST['gpsselect'];
112
	elseif (isset($config['ntpd']['gps']['noselect']))
113
		unset($config['ntpd']['gps']['noselect']);
114

    
115
	if (!empty($_POST['gpsflag1']))
116
		$config['ntpd']['gps']['flag1'] = $_POST['gpsflag1'];
117
	elseif (isset($config['ntpd']['gps']['flag1']))
118
		unset($config['ntpd']['gps']['flag1']);
119

    
120
	if (!empty($_POST['gpsflag2']))
121
		$config['ntpd']['gps']['flag2'] = $_POST['gpsflag2'];
122
	elseif (isset($config['ntpd']['gps']['flag2']))
123
		unset($config['ntpd']['gps']['flag2']);
124

    
125
	if (!empty($_POST['gpsflag3']))
126
		$config['ntpd']['gps']['flag3'] = $_POST['gpsflag3'];
127
	elseif (isset($config['ntpd']['gps']['flag3']))
128
		unset($config['ntpd']['gps']['flag3']);
129

    
130
	if (!empty($_POST['gpsflag4']))
131
		$config['ntpd']['gps']['flag4'] = $_POST['gpsflag4'];
132
	elseif (isset($config['ntpd']['gps']['flag4']))
133
		unset($config['ntpd']['gps']['flag4']);
134

    
135
	if (!empty($_POST['gpssubsec']))
136
		$config['ntpd']['gps']['subsec'] = $_POST['gpssubsec'];
137
	elseif (isset($config['ntpd']['gps']['subsec']))
138
		unset($config['ntpd']['gps']['subsec']);
139

    
140
	if (!empty($_POST['gpsrefid']))
141
		$config['ntpd']['gps']['refid'] = $_POST['gpsrefid'];
142
	elseif (isset($config['ntpd']['gps']['refid']))
143
		unset($config['ntpd']['gps']['refid']);
144

    
145
	if (!empty($_POST['gpsinitcmd']))
146
		$config['ntpd']['gps']['initcmd'] = base64_encode($_POST['gpsinitcmd']);
147
	elseif (isset($config['ntpd']['gps']['initcmd']))
148
		unset($config['ntpd']['gps']['initcmd']);
149

    
150
	write_config("Updated NTP GPS Settings");
151

    
152
	$retval = system_ntp_configure();
153
	$savemsg = get_std_save_message($retval);
154
} else {
155
	/* set defaults if they do not already exist */
156
	if (!is_array($config['ntpd']) || !is_array($config['ntpd']['gps']) || empty($config['ntpd']['gps']['type'])) {
157
		set_default_gps();
158
	}
159
}
160

    
161
function build_nmea_list() {
162
	global $pconfig;
163

    
164
	$nmealist = array('options' => array(), 'selected' => array());
165

    
166
	$nmealist['options'][0] = 'All';
167
	$nmealist['options'][1] = 'RMC';
168
	$nmealist['options'][2] = 'GGA';
169
	$nmealist['options'][4] = 'GLL';
170
	$nmealist['options'][8] = 'ZDA or ZDG';
171

    
172
	if(!$pconfig['nmea'])
173
		array_push($nmealist['selected'], 0);
174

    
175
	foreach($nmealist['options'] as $val => $opt) {
176
		if($pconfig['nmea'] & $val)
177
		  array_push($nmealist['selected'], $val);
178
	}
179

    
180
	return($nmealist);
181
}
182

    
183
$closehead = false;
184
$pconfig = &$config['ntpd']['gps'];
185
$pgtitle = array(gettext("Services"),gettext("NTP GPS"));
186
$shortcut_section = "ntp";
187
include("head.inc");
188

    
189
$tab_array = array();
190
$tab_array[] = array(gettext("NTP"), false, "services_ntpd.php");
191
$tab_array[] = array(gettext("Serial GPS"), true, "services_ntpd_gps.php");
192
$tab_array[] = array(gettext("PPS"), false, "services_ntpd_pps.php");
193
display_top_tabs($tab_array);
194

    
195
require('classes/Form.class.php');
196

    
197
$form = new Form;
198

    
199
$section = new Form_Section('NTP Serial GPS Configuration');
200

    
201
$section->addInput(new Form_StaticText(
202
	'Notes',
203
	'A GPS connected via a serial port may be used as a reference clock for NTP. If the GPS also supports PPS and is properly configured, ' .
204
	'and connected, that GPS may also be used as a Pulse Per Second clock reference. NOTE: A USB GPS may work, but is not recommended due to USB bus timing issues.' . '<br />' .
205
	'For the best results, NTP should have at least three sources of time. So it is best to configure at least 2 servers under ' .
206
	'<a href="services_ntpd.php">Services > NTP</a>' .
207
	' to minimize clock drift if the GPS data is not valid over time. Otherwise ntpd may only use values from the unsynchronized local clock when providing time to clients.'
208
));
209

    
210
$gpstypes = array('Custom', 'Default', 'Generic', 'Garmin', 'MediaTek', 'SiRF', 'U-Blox', 'SureGPS');
211

    
212
$section->addInput(new Form_Select(
213
	'gpstype',
214
	'GPS',
215
	$pconfig['type'],
216
	array_combine($gpstypes, $gpstypes)
217
))->setHelp('This option allows you to select a predefined configuration.' .
218
			'Default is the configuration of pfSense 2.1 and earlier (not recommended). Select Generic if your GPS is not listed.' . '<br /><br />' .
219
			'The perdefined configurations assume your GPS has already been set to NMEA mode.');
220

    
221
$serialports = glob("/dev/cua?[0-9]{,.[0-9]}", GLOB_BRACE);
222

    
223
if (!empty($serialports)) {
224
	$splist = array();
225
	
226
	foreach ($serialports as $port) { 
227
		$shortport = substr($port,5);
228
		$splist[$shortport] = $shortport;
229
	}
230
	
231
	$section->addInput(new Form_Select(
232
		'gpsport',
233
		'Serial port',
234
		$pconfig['port'],
235
			$splist
236
	))->setHelp('All serial ports are listed, be sure to pick the port with the GPS attached. ');
237
	
238
	$section->addInput(new Form_Select(
239
		'gpsspeed',
240
		null,
241
		$pconfig['speed'],
242
		[0 => '4800', 15 => '9600', 32 => '19200', 48 => '38400', 64 => '57600', 80 => '115200']
243
	
244
	))->setHelp('A higher baud rate is generally only helpful if the GPS is sending too many sentences. ' .
245
				'It is recommended to configure the GPS to send only one sentence at a baud rate of 4800 or 9600.');
246
}
247

    
248
$nmealist = build_nmea_list();
249
$section->addInput(new Form_Select(
250
	'gpsnmea',
251
	'NMEA Sentences',
252
	$nmealist['selected'],
253
	$nmealist['options'],
254
	true
255
))->setHelp('By default NTP will listen for all supported NMEA sentences. One or more sentences to listen for may be specified.');
256

    
257
$section->addInput(new Form_Input(
258
	'gpsfudge1',
259
	'Fudge time 1',
260
	'text',
261
	$pconfig['fudge1']
262
))->setHelp('Fudge time 1 is used to specify the GPS PPS signal offset (default: 0.0).');
263

    
264
$section->addInput(new Form_Input(
265
	'gpsfudge2',
266
	'Fudge time 2',
267
	'text',
268
	$pconfig['fudge2']
269
))->setHelp('Fudge time 2 is used to specify the GPS time offset (default: 0.0).');
270

    
271
$section->addInput(new Form_Input(
272
	'gpsstratum',
273
	'Stratum (0-16)',
274
	'text',
275
	$pconfig['stratum']
276
))->setHelp('This may be used to change the GPS Clock stratum (default: 0). This may be useful if, for some reason, you want ntpd to prefer a different clock');
277

    
278
$section->addInput(new Form_Checkbox(
279
	'gpsprefer',
280
	'Flags',
281
	'NTP should prefer this clock (default: enabled).',
282
	!$pconfig['prefer']
283
));
284

    
285
$section->addInput(new Form_Checkbox(
286
	'gpsselect',
287
	null,
288
	'NTP should not use this clock, it will be displayed for reference only(default: disabled).',
289
	$pconfig['noselect']
290
));
291

    
292
$section->addInput(new Form_Checkbox(
293
	'gpsflag1',
294
	null,
295
	'Enable PPS signal processing (default: enabled).',
296
	$pconfig['flag1']
297
));
298

    
299
$section->addInput(new Form_Checkbox(
300
	'gpsflag2',
301
	null,
302
	'Enable falling edge PPS signal processing (default: rising edge).',
303
	$pconfig['flag2']
304
));
305

    
306
$section->addInput(new Form_Checkbox(
307
	'gpsflag3',
308
	null,
309
	'Enable kernel PPS clock discipline (default: enabled).',
310
	$pconfig['flag3']
311
));
312

    
313
$section->addInput(new Form_Checkbox(
314
	'gpsflag4',
315
	null,
316
	'Obscure location in timestamp (default: unobscured).',
317
	$pconfig['flag4']
318
));
319

    
320
$section->addInput(new Form_Checkbox(
321
	'gpssubsec',
322
	null,
323
	'Log the sub-second fraction of the received time stamp (default: Not logged).',
324
	$pconfig['subsec']
325
))->setHelp('Enabling this will rapidly fill the log, but is useful for tuning Fudge time 2.');
326

    
327
$section->addInput(new Form_Input(
328
	'gpsrefid',
329
	'Clock ID',
330
	'text',
331
	$pconfig['refid'],
332
	['placeholder' => '1 to 4 characters']
333
))->setHelp('This may be used to change the GPS Clock ID (default: GPS).');
334

    
335
// Statistics logging section
336
$btnadvgps = new Form_Button(
337
	'btnadvgps',
338
	'Advanced'
339
);
340

    
341
$btnadvgps->removeClass('btn-primary')->addClass('btn-default btn-sm');
342

    
343
$section->addInput(new Form_StaticText(
344
	'GPS Initialization',
345
	$btnadvgps . '&nbsp' . 'Show GPS Initialization commands'
346
));
347

    
348
$section->addInput(new Form_Textarea(
349
	'gpsinitcmd',
350
	null,
351
	$pconfig['initcmd']
352
))->setHelp('Commands entered here will be sent to the GPS during initialization. Please read and understand your GPS documentation before making any changes here');
353

    
354
$group = new Form_Group('NMEA Checksum Calculator');
355

    
356
$group->add(new Form_Input(
357
	'nmeastring',
358
	null
359
));
360

    
361
$btncalc = new Form_Button(
362
	'btncalc',
363
	'Calculate'
364
);
365

    
366
$btncalc->removeClass('btn-primary')->addClass('btn-success btn-sm');
367

    
368
$group->add($btncalc);
369

    
370
$group->add(new Form_Input(
371
	'result',
372
	null,
373
	'text',
374
	null,
375
	['placeholder' => 'Result']
376
));
377

    
378
$group->setHelp('Enter the text between &quot;$&quot; and &quot;*&quot; of a NMEA command string:');
379
$group->addClass('calculator');
380

    
381
$section->add($group);
382

    
383
$form->add($section);
384
print($form);
385

    
386
?>
387

    
388
<script>
389
//<![CDATA[
390
events.push(function(){
391

    
392
	function NMEAChecksum(cmd) {
393
		// Compute the checksum by XORing all the character values in the string.
394
		var checksum = 0;
395

    
396
		for(var i = 0; i < cmd.length; i++) {
397
			checksum = checksum ^ cmd.charCodeAt(i);
398
		}
399
		// Convert it to hexadecimal (base-16, upper case, most significant byte first).
400
		var hexsum = Number(checksum).toString(16).toUpperCase();
401

    
402
		if (hexsum.length < 2) {
403
			hexsum = ("00" + hexsum).slice(-2);
404
		}
405

    
406
		return(hexsum);
407
	}
408

    
409
	// Hides the <div> in which the specified input element lives so that the input, its label and help text are hidden
410
	function hideInput(id, hide) {
411
		if(hide)
412
			$('#' + id).parent().parent('div').addClass('hidden');
413
		else
414
			$('#' + id).parent().parent('div').removeClass('hidden');
415
	}
416

    
417
	// Hides all elements of the specified class. This will usually be a section or group
418
	function hideClass(s_class, hide) {
419
		if(hide)
420
			$('.' + s_class).hide();
421
		else
422
			$('.' + s_class).show();
423
	}
424

    
425
	function set_gps_default(type) {
426
		$('#gpsnmea').val(0);
427
		$('#gpsspeed').val(0);
428
		$('#gpsfudge1').val(0);
429

    
430
		//stuff the JS object as needed for each type
431
		switch(type) {
432
			case "Default":
433
				$('#gpsfudge1').val("0.155");
434
				$('#gpsfudge2').val("");
435
				$('#gpsinitcmd').val("JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ0K");
436
				break;
437

    
438
			case "Garmin":
439
				$('#gpsfudge2').val("0.600");
440
				$('#gpsinitcmd').val("JFBHUk1DLCwsLCwsLCwsLDMsLDIsOCo1RQ0KJFBHUk1DMSwsMSwsLCwsLFcsLCwsLCwsKjMwDQokUEdSTU8sLDMqNzQNCiRQR1JNTyxHUFJNQywxKjNEDQokUEdSTU8sR1BHR0EsMSoyMA0KJFBHUk1PLEdQR0xMLDEqMjYNCg==");
441
				break;
442

    
443
			case "Generic":
444
				$('#gpsfudge2').val("0.400");
445
				$('#gpsinitcmd').val("");
446
				break;
447

    
448
			case "MediaTek":
449
				$('#gpsfudge2').val("0.400");
450
				$('#gpsinitcmd').val("JFBNVEsyMjUsMCoyQg0KJFBNVEszMTQsMSwxLDAsMSwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDEsMCoyOA0KJFBNVEszMDEsMioyRQ0KJFBNVEszMjAsMCoyRg0KJFBNVEszMzAsMCoyRQ0KJFBNVEszODYsMCoyMw0KJFBNVEszOTcsMCoyMw0KJFBNVEsyNTEsNDgwMCoxNA0K");
451
				break;
452

    
453
			case "SiRF":
454
				$('#gpsfudge2').val("0.704"); //valid for 4800, 0.688 @ 9600, 0.640 @ USB
455
				$('#gpsinitcmd').val("JFBTUkYxMDMsMDAsMDAsMDEsMDEqMjUNCiRQU1JGMTAzLDAxLDAwLDAxLDAxKjI0DQokUFNSRjEwMywwMiwwMCwwMCwwMSoyNA0KJFBTUkYxMDMsMDMsMDAsMDAsMDEqMjQNCiRQU1JGMTAzLDA0LDAwLDAxLDAxKjI0DQokUFNSRjEwMywwNSwwMCwwMCwwMSoyNA0KJFBTUkYxMDAsMSw0ODAwLDgsMSwwKjBFDQo=");
456
				break;
457

    
458
			case "U-Blox":
459
				$('#gpsfudge2').val("0.400");
460
				$('#gpsinitcmd').val("JFBVQlgsNDAsR0dBLDEsMSwxLDEsMCwwKjVBDQokUFVCWCw0MCxHTEwsMSwxLDEsMSwwLDAqNUMNCiRQVUJYLDQwLEdTQSwwLDAsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR1NWLDAsMCwwLDAsMCwwKjU5DQokUFVCWCw0MCxSTUMsMSwxLDEsMSwwLDAqNDcNCiRQVUJYLDQwLFZURywwLDAsMCwwLDAsMCo1RQ0KJFBVQlgsNDAsR1JTLDAsMCwwLDAsMCwwKjVEDQokUFVCWCw0MCxHU1QsMCwwLDAsMCwwLDAqNUINCiRQVUJYLDQwLFpEQSwxLDEsMSwxLDAsMCo0NA0KJFBVQlgsNDAsR0JTLDAsMCwwLDAsMCwwKjREDQokUFVCWCw0MCxEVE0sMCwwLDAsMCwwLDAqNDYNCiRQVUJYLDQwLEdQUSwwLDAsMCwwLDAsMCo1RA0KJFBVQlgsNDAsVFhULDAsMCwwLDAsMCwwKjQzDQokUFVCWCw0MCxUSFMsMCwwLDAsMCwwLDAqNTQNCiRQVUJYLDQxLDEsMDAwNywwMDAzLDQ4MDAsMCoxMw0K");
461
				break;
462

    
463
			case "SureGPS":
464
				$('#gpsnmea').val(1);
465
				$('#gpsspeed').val(16);
466
				$('#gpsfudge2').val("0.407");
467
				$('#gpsinitcmd').val("JFBNVEsyMjUsMCoyQg0KJFBNVEszMTQsMSwxLDAsMSwwLDUsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDEsMCoyRA0KJFBNVEszMDEsMioyRQ0KJFBNVEszOTcsMCoyMw0KJFBNVEsxMDIqMzENCiRQTVRLMzEzLDEqMkUNCiRQTVRLNTEzLDEqMjgNCiRQTVRLMzE5LDAqMjUNCiRQTVRLNTI3LDAuMDAqMDANCiRQTVRLMjUxLDk2MDAqMTcNCg==");
468
				break;
469
			default:
470
				return;
471
		}
472

    
473
		$('#gpsstratum').val("");
474
		$('#gpsrefid').val("");
475
		$('#gpsflag1').prop('checked', true);
476
		$('#gpsflag2').prop('checked', false);
477
		$('#gpsflag3').prop('checked', true);
478
		$('#gpsflag4').prop('checked', false);
479
		$('#gpssubsec').prop('checked', false);
480
	}
481

    
482
	// Make the ‘Advanced’ button a plain button, not a submit button
483
	$('#btnadvgps').prop('type','button');
484

    
485
	// On click, show the controls in the GPS Initialization section
486
	$("#btnadvgps").click(function() {
487
		hideInput('gpsinitcmd', false);
488
		hideClass('calculator', false);
489
	});
490

    
491
	// Make the ‘Calculate’ button a plain button, not a submit button
492
	$('#btncalc').prop('type','button');
493
	$('#result').prop("disabled", true);
494

    
495
	// Onclick read the string from the nmeastring box, calculate the checksum
496
	// and display the results in the result box
497
	$("#btncalc").click(function() {
498
		$('#result').val(NMEAChecksum($('#nmeastring').val()));
499
	});
500

    
501
	// When the 'GPS' selector is changed, we set tth gps defaults
502
	$('#gpstype').on('change', function() {
503
		set_gps_default($(this).val());
504
	});
505

    
506
	hideInput('gpsinitcmd', true);
507
	hideClass('calculator', true);
508

    
509
	set_gps_default('<?=$pconfig['type']?>');
510

    
511
	//	Checkboxes gpsprefer and gpsselect are mutually exclusive
512
	$('#gpsprefer').click(function() {
513
		if ($(this).is(':checked')) {
514
			$('#gpsselect').prop('checked', false);
515
		}
516
	});
517

    
518
	$('#gpsselect').click(function() {
519
		if ($(this).is(':checked')) {
520
			$('#gpsprefer').prop('checked', false);
521
		}
522
	});
523
});
524
//]]>
525
</script>
526

    
527
<?php include("foot.inc");
(146-146/237)