'GPGLL', 2 => 'GPRMC', 3 => 'GPVTG', 4 => 'GPGGA', 5 => 'GPGSA', 6 => 'GPGSV', 7 => 'GPGRS', 8 => 'GPGST', ]; for ($x = 1; $x < 9; $x++) { if($splitline[$x]) { $nmeaset[$nmeamap[$x]] = 1; } } } function parse_sirf(&$nmeaset, $splitline) { $msg_idx = 1; $mode_idx = 2; $rate_idx = 3; $nmeamap = [ 0 => 'GPGGA', 1 => 'GPGLL', 2 => 'GPGSA', 3 => 'GPGSV', 4 => 'GPRMC', 5 => 'GPVTG', ]; if (!(int)$splitline[$mode_idx] && (int)$splitline[$rate_idx]) { $nmeaset[$nmeamap[(int)$splitline[$msg_idx]]] = 1; } } function parse_initcmd(&$nmeaset, $initcmd) { $type_idx = 0; $nmeaset = []; $split_initcmd = preg_split('/[\s]+/', $initcmd); foreach ($split_initcmd as $line) { $splitline = preg_split('/[,\*]+/', $line); if ($splitline[$type_idx] == '$PUBX') { parse_ublox($nmeaset, $splitline); } elseif ($splitline[$type_idx] == '$PGRMO') { parse_garmin($nmeaset, $splitline); } elseif ($splitline[$type_idx] == '$PMTK314') { parse_mtk($nmeaset, $splitline); } elseif ($splitline[$type_idx] == '$PSRF103') { parse_sirf($nmeaset, $splitline); } } } function NMEAChecksum($cmd) { $checksum = 0; for ($i=0; $i array(), 'selected' => array()); $nmealist['options'][0] = gettext('All'); $nmealist['options'][1] = gettext('RMC'); $nmealist['options'][2] = gettext('GGA'); $nmealist['options'][4] = gettext('GLL'); $nmealist['options'][8] = gettext('ZDA or ZDG'); if (!$pconfig['nmea']) { array_push($nmealist['selected'], 0); } foreach ($nmealist['options'] as $val => $opt) { if ($pconfig['nmea'] & $val) { array_push($nmealist['selected'], $val); } } return($nmealist); } $pconfig = &$config['ntpd']['gps']; $pgtitle = array(gettext("Services"), gettext("NTP"), gettext("Serial GPS")); $pglinks = array("", "services_ntpd.php", "@self"); $shortcut_section = "ntp"; include("head.inc"); if ($changes_applied) { print_apply_result_box($retval); } $tab_array = array(); $tab_array[] = array(gettext("Settings"), false, "services_ntpd.php"); $tab_array[] = array(gettext("ACLs"), false, "services_ntpd_acls.php"); $tab_array[] = array(gettext("Serial GPS"), true, "services_ntpd_gps.php"); $tab_array[] = array(gettext("PPS"), false, "services_ntpd_pps.php"); display_top_tabs($tab_array); $form = new Form; $section = new Form_Section('NTP Serial GPS Configuration'); $section->addInput(new Form_StaticText( 'Notes', '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, ' . '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.' . '
' . 'For the best results, NTP should have at least three sources of time. So it is best to configure at least 2 servers under ' . 'Services > NTP > Settings' . ' 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.' )); $gpstypes = array(gettext('Custom'), gettext('Default'), 'Generic', 'Garmin', 'MediaTek', 'SiRF', 'U-Blox', 'SureGPS'); $section->addInput(new Form_Select( 'gpstype', 'GPS Type', $pconfig['type'], array_combine($gpstypes, $gpstypes) ))->setHelp('This option allows a predefined configuration to be selected. ' . 'Default is the configuration of pfSense 2.1 and earlier (not recommended). Select Generic if the GPS is not listed.%1$s' . 'The predefined configurations assume the GPS has already been set to NMEA mode.', '

'); $serialports = glob("/dev/cua?[0-9]{,.[0-9]}", GLOB_BRACE); if (!empty($serialports)) { $splist = array(); foreach ($serialports as $port) { $shortport = substr($port, 5); $splist[$shortport] = $shortport; } $section->addInput(new Form_Select( 'gpsport', 'Serial Port', $pconfig['port'], ['' => gettext('None')] + $splist ))->setHelp('All serial ports are listed, be sure to pick the port with the GPS attached. '); $section->addInput(new Form_Select( 'gpsspeed', null, $pconfig['speed'], [0 => '4800', 16 => '9600', 32 => '19200', 48 => '38400', 64 => '57600', 80 => '115200'] ))->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.'); } $nmealist = build_nmea_list(); $section->addInput(new Form_Select( 'gpsnmea', 'NMEA Sentences', $nmealist['selected'], $nmealist['options'], true ))->setHelp('By default NTP will listen for all supported NMEA sentences. One or more sentences to listen for may be specified.'); $section->addInput(new Form_Checkbox( 'processpgrmf', null, 'Process PGRMF. Ignores ALL other NMEA sentences. (default: unchecked).', $pconfig['processpgrmf'] )); $section->addInput(new Form_Input( 'gpsfudge1', 'Fudge Time 1', 'text', $pconfig['fudge1'] ))->setHelp('Fudge time 1 is used to specify the GPS PPS signal offset (default: 0.0).'); $section->addInput(new Form_Input( 'gpsfudge2', 'Fudge Time 2', 'text', $pconfig['fudge2'] ))->setHelp('Fudge time 2 is used to specify the GPS time offset (default: 0.0).'); $section->addInput(new Form_Input( 'gpsstratum', 'Stratum (0-16)', 'text', $pconfig['stratum'] ))->setHelp('This may be used to change the GPS Clock stratum (default: 0). This may be useful to, for some reason, have ntpd prefer a different clock.'); $section->addInput(new Form_Checkbox( 'gpsprefer', 'Flags', 'Prefer this clock (default: checked).', !$pconfig['prefer'] )); $section->addInput(new Form_Checkbox( 'gpsnoselect', null, 'Do not use this clock, display for reference only (default: unchecked).', $pconfig['noselect'] )); $section->addInput(new Form_Checkbox( 'gpsflag1', null, 'Enable PPS signal processing (default: checked).', $pconfig['flag1'] )); $section->addInput(new Form_Checkbox( 'gpsflag2', null, 'Enable falling edge PPS signal processing (default: unchecked, rising edge).', $pconfig['flag2'] )); $section->addInput(new Form_Checkbox( 'gpsflag3', null, 'Enable kernel PPS clock discipline (default: checked).', $pconfig['flag3'] )); $section->addInput(new Form_Checkbox( 'gpsflag4', null, 'Obscure location in timestamp (default: unchecked, unobscured).', $pconfig['flag4'] )); $section->addInput(new Form_Checkbox( 'gpssubsec', null, 'Log the sub-second fraction of the received time stamp (default: unchecked, not logged).', $pconfig['subsec'] ))->setHelp('Enabling this will rapidly fill the log, but is useful for tuning Fudge time 2.'); $section->addInput(new Form_Checkbox( 'extstatus', null, 'Display extended GPS status (default: checked).', $pconfig['extstatus'] ))->setHelp('Enable extended GPS status if GPGSV or GPGGA are explicitly enabled by GPS initialization commands.'); $section->addInput(new Form_Input( 'gpsrefid', 'Clock ID', 'text', $pconfig['refid'], ['placeholder' => '1 to 4 characters'] ))->setHelp('This may be used to change the GPS Clock ID (default: GPS).'); // Statistics logging section $btnadv = new Form_Button( 'btnadvgps', 'Display Advanced', null, 'fa-cog' ); $btnadv->setAttribute('type','button')->addClass('btn-info btn-sm'); $section->addInput(new Form_StaticText( 'GPS Initialization', $btnadv )); $section->addInput(new Form_Textarea( 'gpsinitcmd', null, base64_decode($pconfig['initcmd']) ))->setHelp('Commands entered here will be sent to the GPS during initialization. Please read and understand the GPS documentation before making any changes here.'); $section->addInput(new Form_Checkbox( 'autocorrect_initcmd', null, 'Auto correct malformed initialization commands. (default: unchecked).', $pconfig['autocorrect_initcmd'] ))->setHelp('Calculates and appends checksum and missing special characters "$" and "*". May not work with some GPS models.'); $group = new Form_Group('NMEA Checksum Calculator'); $group->add(new Form_Input( 'nmeastring', null )); $btncalc = new Form_Button( 'btncalc', 'Calculate', null, 'fa-calculator' ); $btncalc->setAttribute('type','button')->removeClass('btn-primary')->addClass('btn-success btn-sm'); $group->add($btncalc); $group->add(new Form_Input( 'result', null, 'text', null, ['placeholder' => 'Result'] )); $group->setHelp('Enter the text between "$" and "*" of a NMEA command string:'); $group->addClass('calculator'); $section->add($group); $form->add($section); print($form); ?>