Coverage Report

Created: 2023-05-19 06:16

/src/ntp-dev/ntpd/refclock_hopfpci.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * refclock_hopfpci.c
3
 *
4
 * - clock driver for hopf 6039 PCI board (GPS or DCF77)
5
 * Bernd Altmeier altmeier@atlsoft.de
6
 *
7
 * latest source and further information can be found at:
8
 * http://www.ATLSoft.de/ntp
9
 *
10
 * In order to run this driver you have to install and test
11
 * the PCI-board driver for your system first.
12
 *
13
 * On Linux/UNIX
14
 *
15
 * The driver attempts to open the device /dev/hopf6039 .
16
 * The device entry will be made by the installation process of
17
 * the kernel module for the PCI-bus board. The driver sources
18
 * belongs to the delivery equipment of the PCI-board.
19
 *
20
 * On Windows NT/2000
21
 *
22
 * The driver attempts to open the device by calling the function
23
 * "OpenHopfDevice()". This function will be installed by the
24
 * Device Driver for the PCI-bus board. The driver belongs to the
25
 * delivery equipment of the PCI-board.
26
 *
27
 *
28
 * Start   21.03.2000 Revision: 01.20
29
 * changes 22.12.2000 Revision: 01.40 flag1 = 1 sync even if Quarz
30
 *
31
 */
32
33
#ifdef HAVE_CONFIG_H
34
# include <config.h>
35
#endif
36
37
#if defined(REFCLOCK) && defined(CLOCK_HOPF_PCI)
38
39
#include "ntpd.h"
40
#include "ntp_io.h"
41
#include "ntp_refclock.h"
42
#include "ntp_unixtime.h"
43
#include "ntp_stdlib.h"
44
45
#undef fileno
46
#include <ctype.h>
47
#undef fileno
48
49
#ifndef SYS_WINNT
50
# include <sys/ipc.h>
51
# include <sys/ioctl.h>
52
# include <assert.h>
53
# include <unistd.h>
54
# include <stdio.h>
55
# include "hopf6039.h"
56
#else
57
# include "hopf_PCI_io.h"
58
#endif
59
60
/*
61
 * hopfpci interface definitions
62
 */
63
0
#define PRECISION       (-10)    /* precision assumed (1 ms) */
64
0
#define REFID           "hopf"   /* reference ID */
65
0
#define DESCRIPTION     "hopf Elektronik PCI radio board"
66
67
#define NSAMPLES        3       /* stages of median filter */
68
#ifndef SYS_WINNT
69
0
# define  DEVICE  "/dev/hopf6039"  /* device name inode*/
70
#else
71
# define  DEVICE  "hopf6039"  /* device name WinNT  */
72
#endif
73
74
0
#define LEWAPWAR  0x20  /* leap second warning bit */
75
76
0
#define HOPF_OPMODE 0xC0  /* operation mode mask */
77
0
#define HOPF_INVALID  0x00  /* no time code available */
78
0
#define HOPF_INTERNAL 0x40  /* internal clock */
79
#define HOPF_RADIO  0x80  /* radio clock */
80
#define HOPF_RADIOHP  0xC0  /* high precision radio clock */
81
82
83
/*
84
 * hopfclock unit control structure.
85
 */
86
struct hopfclock_unit {
87
  short unit;   /* NTP refclock unit number */
88
  char  leap_status;  /* leap second flag */
89
};
90
int fd;     /* file descr. */
91
92
/*
93
 * Function prototypes
94
 */
95
static  int     hopfpci_start       (int, struct peer *);
96
static  void    hopfpci_shutdown    (int, struct peer *);
97
static  void    hopfpci_poll        (int unit, struct peer *);
98
99
/*
100
 * Transfer vector
101
 */
102
struct  refclock refclock_hopfpci = {
103
  hopfpci_start,          /* start up driver */
104
  hopfpci_shutdown,       /* shut down driver */
105
  hopfpci_poll,           /* transmit poll message */
106
  noentry,                /* not used */
107
  noentry,                /* initialize driver (not used) */
108
  noentry,                /* not used */
109
  NOFLAGS                 /* not used */
110
};
111
112
/*
113
 * hopfpci_start - attach to hopf PCI board 6039
114
 */
115
static int
116
hopfpci_start(
117
  int unit,
118
  struct peer *peer
119
  )
120
0
{
121
0
  struct refclockproc *pp;
122
0
  struct hopfclock_unit *up;
123
124
  /*
125
   * Allocate and initialize unit structure
126
   */
127
0
  up = emalloc_zero(sizeof(*up));
128
129
0
#ifndef SYS_WINNT
130
131
0
  fd = open(DEVICE,O_RDWR); /* try to open hopf clock device */
132
133
#else
134
  if (!OpenHopfDevice()) {
135
    msyslog(LOG_ERR, "Start: %s unit: %d failed!", DEVICE, unit);
136
    free(up);
137
    return (0);
138
  }
139
#endif
140
141
0
  pp = peer->procptr;
142
0
  pp->io.clock_recv = noentry;
143
0
  pp->io.srcclock = peer;
144
0
  pp->io.datalen = 0;
145
0
  pp->io.fd = INVALID_SOCKET;
146
0
  pp->unitptr = up;
147
148
0
  get_systime(&pp->lastrec);
149
150
  /*
151
   * Initialize miscellaneous peer variables
152
   */
153
0
  memcpy((char *)&pp->refid, REFID, 4);
154
0
  peer->precision = PRECISION;
155
0
  pp->clockdesc = DESCRIPTION;
156
0
  up->leap_status = 0;
157
0
  up->unit = (short) unit;
158
0
  return (1);
159
0
}
160
161
162
/*
163
 * hopfpci_shutdown - shut down the clock
164
 */
165
static void
166
hopfpci_shutdown(
167
  int unit,
168
  struct peer *peer
169
  )
170
0
{
171
172
0
#ifndef SYS_WINNT
173
0
  close(fd);
174
#else
175
  CloseHopfDevice();
176
#endif
177
0
  if (NULL != peer->procptr->unitptr)
178
0
    free(peer->procptr->unitptr);
179
0
}
180
181
182
/*
183
 * hopfpci_poll - called by the transmit procedure
184
 */
185
static void
186
hopfpci_poll(
187
  int unit,
188
  struct peer *peer
189
  )
190
0
{
191
0
  struct refclockproc *pp;
192
0
  HOPFTIME m_time;
193
194
0
  pp = peer->procptr;
195
196
0
#ifndef SYS_WINNT
197
0
  if (ioctl(fd, HOPF_CLOCK_GET_UTC, &m_time) < 0)
198
0
    msyslog(LOG_ERR, "HOPF_P(%d): HOPF_CLOCK_GET_UTC: %m",
199
0
      unit);
200
#else
201
  GetHopfSystemTime(&m_time);
202
#endif
203
0
  pp->polls++;
204
205
0
  pp->day    = ymd2yd(m_time.wYear,m_time.wMonth,m_time.wDay);
206
0
  pp->hour   = m_time.wHour;
207
0
  pp->minute = m_time.wMinute;
208
0
  pp->second = m_time.wSecond;
209
0
  pp->nsec   = m_time.wMilliseconds * 1000000;
210
0
  if (m_time.wStatus & LEWAPWAR)
211
0
    pp->leap = LEAP_ADDSECOND;
212
0
  else
213
0
    pp->leap = LEAP_NOWARNING;
214
215
0
  snprintf(pp->a_lastcode, sizeof(pp->a_lastcode),
216
0
     "ST: %02X T: %02d:%02d:%02d.%03ld D: %02d.%02d.%04d",
217
0
     m_time.wStatus, pp->hour, pp->minute, pp->second,
218
0
     pp->nsec / 1000000, m_time.wDay, m_time.wMonth,
219
0
     m_time.wYear);
220
0
  pp->lencode = (u_short)strlen(pp->a_lastcode);
221
222
0
  get_systime(&pp->lastrec);
223
224
  /*
225
   * If clock has no valid status then report error and exit
226
   */
227
0
  if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INVALID) {  /* time ok? */
228
0
    refclock_report(peer, CEVNT_BADTIME);
229
0
    pp->leap = LEAP_NOTINSYNC;
230
0
    return;
231
0
  }
232
233
  /*
234
   * Test if time is running on internal quarz
235
   * if CLK_FLAG1 is set, sychronize even if no radio operation
236
   */
237
238
0
  if ((m_time.wStatus & HOPF_OPMODE) == HOPF_INTERNAL){
239
0
    if ((pp->sloppyclockflag & CLK_FLAG1) == 0) {
240
0
      refclock_report(peer, CEVNT_BADTIME);
241
0
      pp->leap = LEAP_NOTINSYNC;
242
0
      return;
243
0
    }
244
0
  }
245
246
0
  if (!refclock_process(pp)) {
247
0
    refclock_report(peer, CEVNT_BADTIME);
248
0
    return;
249
0
  }
250
0
  pp->lastref = pp->lastrec;
251
0
  refclock_receive(peer);
252
0
  record_clock_stats(&peer->srcadr, pp->a_lastcode);
253
0
  return;
254
0
}
255
256
#else
257
int refclock_hopfpci_bs;
258
#endif /* REFCLOCK */