Any code that wants to call one_step() needs to link with the static global 'assume_two_step'. This patch moves that variable's definition from ptp4l.c to msg.c. Not only is that file the more natural choice (since the variable is used on msg.h) but also this allows other programs to call the one_step() function. Signed-off-by: Richard Cochran <richardcochran@gmail.com>
223 lines
5.6 KiB
C
223 lines
5.6 KiB
C
/**
|
|
* @file ptp4l.c
|
|
* @brief PTP Boundary Clock main program
|
|
* @note Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "clock.h"
|
|
#include "config.h"
|
|
#include "ntpshm.h"
|
|
#include "pi.h"
|
|
#include "print.h"
|
|
#include "raw.h"
|
|
#include "sk.h"
|
|
#include "transport.h"
|
|
#include "udp6.h"
|
|
#include "uds.h"
|
|
#include "util.h"
|
|
#include "version.h"
|
|
|
|
static void usage(char *progname)
|
|
{
|
|
fprintf(stderr,
|
|
"\nusage: %s [options]\n\n"
|
|
" Delay Mechanism\n\n"
|
|
" -A Auto, starting with E2E\n"
|
|
" -E E2E, delay request-response (default)\n"
|
|
" -P P2P, peer delay mechanism\n\n"
|
|
" Network Transport\n\n"
|
|
" -2 IEEE 802.3\n"
|
|
" -4 UDP IPV4 (default)\n"
|
|
" -6 UDP IPV6\n\n"
|
|
" Time Stamping\n\n"
|
|
" -H HARDWARE (default)\n"
|
|
" -S SOFTWARE\n"
|
|
" -L LEGACY HW\n\n"
|
|
" Other Options\n\n"
|
|
" -f [file] read configuration from 'file'\n"
|
|
" -i [dev] interface device to use, for example 'eth0'\n"
|
|
" (may be specified multiple times)\n"
|
|
" -p [dev] PTP hardware clock device to use, default auto\n"
|
|
" (ignored for SOFTWARE/LEGACY HW time stamping)\n"
|
|
" -s slave only mode (overrides configuration file)\n"
|
|
" -l [num] set the logging level to 'num'\n"
|
|
" -m print messages to stdout\n"
|
|
" -q do not print messages to the syslog\n"
|
|
" -v prints the software version and exits\n"
|
|
" -h prints this message and exits\n"
|
|
"\n",
|
|
progname);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
char *config = NULL, *req_phc = NULL, *progname;
|
|
int c, err = -1, index, print_level;
|
|
struct clock *clock = NULL;
|
|
struct option *opts;
|
|
struct config *cfg;
|
|
|
|
if (handle_term_signals())
|
|
return -1;
|
|
|
|
cfg = config_create();
|
|
if (!cfg) {
|
|
return -1;
|
|
}
|
|
opts = config_long_options(cfg);
|
|
|
|
/* Process the command line arguments. */
|
|
progname = strrchr(argv[0], '/');
|
|
progname = progname ? 1+progname : argv[0];
|
|
while (EOF != (c = getopt_long(argc, argv, "AEP246HSLf:i:p:sl:mqvh",
|
|
opts, &index))) {
|
|
switch (c) {
|
|
case 0:
|
|
if (config_parse_option(cfg, opts[index].name, optarg))
|
|
goto out;
|
|
break;
|
|
case 'A':
|
|
if (config_set_int(cfg, "delay_mechanism", DM_AUTO))
|
|
goto out;
|
|
break;
|
|
case 'E':
|
|
if (config_set_int(cfg, "delay_mechanism", DM_E2E))
|
|
goto out;
|
|
break;
|
|
case 'P':
|
|
if (config_set_int(cfg, "delay_mechanism", DM_P2P))
|
|
goto out;
|
|
break;
|
|
case '2':
|
|
if (config_set_int(cfg, "network_transport",
|
|
TRANS_IEEE_802_3))
|
|
goto out;
|
|
break;
|
|
case '4':
|
|
if (config_set_int(cfg, "network_transport",
|
|
TRANS_UDP_IPV4))
|
|
goto out;
|
|
break;
|
|
case '6':
|
|
if (config_set_int(cfg, "network_transport",
|
|
TRANS_UDP_IPV6))
|
|
goto out;
|
|
break;
|
|
case 'H':
|
|
if (config_set_int(cfg, "time_stamping", TS_HARDWARE))
|
|
goto out;
|
|
break;
|
|
case 'S':
|
|
if (config_set_int(cfg, "time_stamping", TS_SOFTWARE))
|
|
goto out;
|
|
break;
|
|
case 'L':
|
|
if (config_set_int(cfg, "time_stamping", TS_LEGACY_HW))
|
|
goto out;
|
|
break;
|
|
case 'f':
|
|
config = optarg;
|
|
break;
|
|
case 'i':
|
|
if (!config_create_interface(optarg, cfg))
|
|
goto out;
|
|
break;
|
|
case 'p':
|
|
req_phc = optarg;
|
|
break;
|
|
case 's':
|
|
if (config_set_int(cfg, "slaveOnly", 1)) {
|
|
goto out;
|
|
}
|
|
break;
|
|
case 'l':
|
|
if (get_arg_val_i(c, optarg, &print_level,
|
|
PRINT_LEVEL_MIN, PRINT_LEVEL_MAX))
|
|
goto out;
|
|
config_set_int(cfg, "logging_level", print_level);
|
|
break;
|
|
case 'm':
|
|
config_set_int(cfg, "verbose", 1);
|
|
break;
|
|
case 'q':
|
|
config_set_int(cfg, "use_syslog", 0);
|
|
break;
|
|
case 'v':
|
|
version_show(stdout);
|
|
return 0;
|
|
case 'h':
|
|
usage(progname);
|
|
return 0;
|
|
case '?':
|
|
usage(progname);
|
|
goto out;
|
|
default:
|
|
usage(progname);
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (config && (c = config_read(config, cfg))) {
|
|
return c;
|
|
}
|
|
|
|
print_set_progname(progname);
|
|
print_set_tag(config_get_string(cfg, NULL, "message_tag"));
|
|
print_set_verbose(config_get_int(cfg, NULL, "verbose"));
|
|
print_set_syslog(config_get_int(cfg, NULL, "use_syslog"));
|
|
print_set_level(config_get_int(cfg, NULL, "logging_level"));
|
|
|
|
assume_two_step = config_get_int(cfg, NULL, "assume_two_step");
|
|
sk_check_fupsync = config_get_int(cfg, NULL, "check_fup_sync");
|
|
sk_tx_timeout = config_get_int(cfg, NULL, "tx_timestamp_timeout");
|
|
|
|
if (config_get_int(cfg, NULL, "clock_servo") == CLOCK_SERVO_NTPSHM) {
|
|
config_set_int(cfg, "kernel_leap", 0);
|
|
config_set_int(cfg, "sanity_freq_limit", 0);
|
|
}
|
|
|
|
if (STAILQ_EMPTY(&cfg->interfaces)) {
|
|
fprintf(stderr, "no interface specified\n");
|
|
usage(progname);
|
|
goto out;
|
|
}
|
|
|
|
clock = clock_create(cfg->n_interfaces > 1 ? CLOCK_TYPE_BOUNDARY :
|
|
CLOCK_TYPE_ORDINARY, cfg, req_phc);
|
|
if (!clock) {
|
|
fprintf(stderr, "failed to create a clock\n");
|
|
goto out;
|
|
}
|
|
|
|
err = 0;
|
|
|
|
while (is_running()) {
|
|
if (clock_poll(clock))
|
|
break;
|
|
}
|
|
out:
|
|
if (clock)
|
|
clock_destroy(clock);
|
|
config_destroy(cfg);
|
|
return err;
|
|
}
|