Skip to content

Commit

Permalink
Merge pull request #4213 from vktg/ntpgpsautoset
Browse files Browse the repository at this point in the history
  • Loading branch information
rbgarga committed Mar 11, 2020
2 parents 1e39f02 + f662680 commit ee50de4
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 31 deletions.
129 changes: 100 additions & 29 deletions src/etc/inc/system.inc
Expand Up @@ -1503,6 +1503,49 @@ function system_timezone_configure() {
}
}

function check_gps_speed($device) {
usleep(1000);
// Set timeout to 5s
$timeout=microtime(true)+5;
if ($fp = fopen($device, 'r')) {
stream_set_blocking($fp, 0);
stream_set_timeout($fp, 5);
$contents = "";
$cnt = 0;
$buffersize = 256;
do {
$c = fread($fp, $buffersize - $cnt);

// Wait for data to arive
if (($c === false) || (strlen($c) == 0)) {
usleep(500);
continue;
}

$contents.=$c;
$cnt = $cnt + strlen($c);
} while (($cnt < $buffersize) && (microtime(true) < $timeout));
fclose($fp);

$nmeasentences = ['RMC', 'GGA', 'GLL', 'ZDA', 'ZDG', 'PGRMF'];
foreach ($nmeasentences as $sentence) {
if (strpos($contents, $sentence) > 0) {
return true;
}
}
if (strpos($contents, '0') > 0) {
$filters = ['`', '?', '/', '~'];
foreach ($filters as $filter) {
if (strpos($contents, $filter) !== false) {
return false;
}
}
return true;
}
}
return false;
}

/* Generate list of possible NTP poll values
* https://redmine.pfsense.org/issues/9439 */
global $ntp_poll_min_value, $ntp_poll_max_value;
Expand Down Expand Up @@ -1548,6 +1591,8 @@ function system_ntp_fixup_poll_value($type, $configvalue, $default) {

function system_ntp_setup_gps($serialport) {
global $config, $g;

init_config_arr(array('ntpd', 'gps', 'speed'));
$gps_device = '/dev/gps0';
$serialport = '/dev/'.$serialport;

Expand All @@ -1560,29 +1605,43 @@ function system_ntp_setup_gps($serialport) {
@symlink($serialport, $gps_device);

$gpsbaud = '4800';
if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
switch ($config['ntpd']['gps']['speed']) {
case '16':
$gpsbaud = '9600';
break;
case '32':
$gpsbaud = '19200';
break;
case '48':
$gpsbaud = '38400';
break;
case '64':
$gpsbaud = '57600';
break;
case '80':
$gpsbaud = '115200';
$speeds = array(
0 => '4800',
16 => '9600',
32 => '19200',
48 => '38400',
64 => '57600',
80 => '115200'
);
if (!empty($config['ntpd']['gps']['speed']) && array_key_exists($config['ntpd']['gps']['speed'], $speeds)) {
$gpsbaud = $speeds[$config['ntpd']['gps']['speed']];
}

system_ntp_setup_rawspeed($serialport, $gpsbaud);

$autospeed = ($config['ntpd']['gps']['speed'] == 'autoalways' || $config['ntpd']['gps']['speed'] == 'autoset');
if ($autospeed || ($config['ntpd']['gps']['autobaudinit'] && !check_gps_speed($gps_device))) {
$found = false;
foreach ($speeds as $baud) {
system_ntp_setup_rawspeed($serialport, $baud);
if ($found = check_gps_speed($gps_device)) {
if ($autospeed) {
$saveconfig = ($config['ntpd']['gps']['speed'] == 'autoset');
$config['ntpd']['gps']['speed'] = array_search($baud, $speeds);
$gpsbaud = $baud;
if ($saveconfig) {
write_config(sprintf(gettext('Autoset GPS baud rate to %s'), $baud));
}
}
break;
}
}
if ($found === false) {
log_error(gettext("Could not find correct GPS baud rate."));
return false;
}
}

/* Configure the serial port for raw IO and set the speed */
mwexec("stty -f {$serialport}.init raw speed {$gpsbaud}");

/* Send the following to the GPS port to initialize the GPS */
if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
Expand All @@ -1594,15 +1653,29 @@ function system_ntp_setup_gps($serialport) {
@file_put_contents('/tmp/gps.init', $gps_init);
mwexec("cat /tmp/gps.init > {$serialport}");

if ($found && $config['ntpd']['gps']['autobaudinit']) {
system_ntp_setup_rawspeed($serialport, $gpsbaud);
}

/* Remove old /etc/remote entry if it exists */
if (mwexec("/usr/bin/grep -c '^gps0' /etc/remote")) {
mwexec("/usr/bin/sed -i '' -n '/gps0/!p' /etc/remote");
}

/* Add /etc/remote entry in case we need to read from the GPS with tip */
if (intval(`grep -c '^gps0' /etc/remote`) == 0) {
if (intval(`/usr/bin/grep -c '^gps0' /etc/remote`) == 0) {
@file_put_contents("/etc/remote", "gps0:dv={$serialport}:br#{$gpsbaud}:pa=none:\n", FILE_APPEND);
}


return true;
}

// Configure the serial port for raw IO and set the speed
function system_ntp_setup_rawspeed($serialport, $baud) {
mwexec("/bin/stty -f " . escapeshellarg($serialport) . " raw speed " . escapeshellarg($baud));
mwexec("/bin/stty -f " . escapeshellarg($serialport) . ".init raw speed " . escapeshellarg($baud));
}

function system_ntp_setup_pps($serialport) {
global $config, $g;

Expand Down Expand Up @@ -1638,6 +1711,12 @@ function system_ntp_configure() {
$config['ntpd'] = array();
}

/* if ntpd is running, kill it */
while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
killbypid("{$g['varrun_path']}/ntpd.pid");
}
@unlink("{$g['varrun_path']}/ntpd.pid");

$ntpcfg = "# \n";
$ntpcfg .= "# pfSense ntp configuration file \n";
$ntpcfg .= "# \n\n";
Expand Down Expand Up @@ -1695,7 +1774,6 @@ function system_ntp_configure() {

/* Add GPS configuration */
if (is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['port']) &&
file_exists('/dev/'.$config['ntpd']['gps']['port']) &&
system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
$ntpcfg .= "\n";
$ntpcfg .= "# GPS Setup\n";
Expand Down Expand Up @@ -1762,7 +1840,6 @@ function system_ntp_configure() {
}
$ntpcfg .= "\n";
} elseif (is_array($config['ntpd']) && !empty($config['ntpd']['gpsport']) &&
file_exists('/dev/'.$config['ntpd']['gpsport']) &&
system_ntp_setup_gps($config['ntpd']['gpsport'])) {
/* This handles a 2.1 and earlier config */
$ntpcfg .= "# GPS Setup\n";
Expand Down Expand Up @@ -1961,12 +2038,6 @@ function system_ntp_configure() {
return;
}

/* if ntpd is running, kill it */
while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
killbypid("{$g['varrun_path']}/ntpd.pid");
}
@unlink("{$g['varrun_path']}/ntpd.pid");

/* if /var/empty does not exist, create it */
if (!is_dir("/var/empty")) {
mkdir("/var/empty", 0555, true);
Expand Down
37 changes: 35 additions & 2 deletions src/usr/local/www/services_ntpd_gps.php
Expand Up @@ -198,9 +198,18 @@ function autocorrect_initcmd($initcmd) {

if (!empty($_POST['gpsspeed'])) {
$config['ntpd']['gps']['speed'] = $_POST['gpsspeed'];
if ($_POST['gpsspeed'] == 'autoalways') {
$fixghost = true;
}
} elseif (isset($config['ntpd']['gps']['speed'])) {
unset($config['ntpd']['gps']['speed']);
}

if (!empty($_POST['autobaudinit'])) {
$config['ntpd']['gps']['autobaudinit'] = $_POST['autobaudinit'];
} elseif (isset($config['ntpd']['gps']['autobaudinit'])) {
unset($config['ntpd']['gps']['autobaudinit']);
}

if (!empty($_POST['gpsnmea']) && ($_POST['gpsnmea'][0] === "0")) {
$config['ntpd']['gps']['nmea'] = "0";
Expand Down Expand Up @@ -312,6 +321,14 @@ function autocorrect_initcmd($initcmd) {
$changes_applied = true;
$retval = 0;
$retval |= system_ntp_configure();
if ($fixghost) {
$config['ntpd']['gps']['speed'] = 'autoalways';
}
} else {
/* set defaults if they do not already exist */
if (!is_array($config['ntpd']) || !is_array($config['ntpd']['gps']) || empty($config['ntpd']['gps']['type'])) {
set_default_gps();
}
}

function build_nmea_list() {
Expand Down Expand Up @@ -403,10 +420,25 @@ function build_nmea_list() {
'gpsspeed',
null,
$pconfig['speed'],
[0 => '4800', 16 => '9600', 32 => '19200', 48 => '38400', 64 => '57600', 80 => '115200']
[0 => '4800', 16 => '9600', 32 => '19200', 48 => '38400', 64 => '57600', 80 => '115200', 'autoset' => 'Autoset', 'autoalways' => 'Always Auto']

))->setHelp('A higher baud rate is generally only helpful if the GPS is sending too many sentences. ' .
'It is recommended to configure the GPS to send only one sentence at a baud rate of 4800 or 9600.');
'It is recommended to configure the GPS to send only one sentence at a baud rate of 4800 or 9600.%1$s' .
'Autoset tries to find the correct baud rate of the GPS device and then saves the configuration.%1$s' .
'Always Auto tries to find the correct baud rate of the GPS device every time NTPd is started.', '<br /><br />');

$section->addInput(new Form_Checkbox(
'autobaudinit',
null,
'Check baud rate before sending init commands (default: unchecked).',
$pconfig['autobaudinit']
))->setHelp(
'Before sending the initialization commands, check the GPS baud rate. ' .
'If it is not correct try to find the correct baud rate automatically, ' .
'send the initialization commands if the correct rate is found, ' .
'and then set the baud rate to the configured speed.%1$s' .
'This is useful if the GPS device resets back to a default rate on power loss ' .
'or when changing the baud rate.', '<br /><br />');
}

$nmealist = build_nmea_list();
Expand Down Expand Up @@ -652,6 +684,7 @@ function set_gps_default(type) {
$('#gpsnmea').val(0);
$('#processpgrmf').prop('checked', false);
$('#gpsspeed').val(0);
$('#autobaudinit').prop('checked', false);
$('#gpsfudge1').val(0);
$('#gpsinitcmd').val(get_gps_string(type));

Expand Down

0 comments on commit ee50de4

Please sign in to comment.