/* * true_start - open the devices and initialize data for processing */ static int true_start( int unit, struct peer *peer ) { register struct true_unit *up; struct refclockproc *pp; char device[40]; int fd; /* * Open serial port */ (void)snprintf(device, sizeof(device), DEVICE, unit); if (!(fd = refclock_open(device, SPEED232, LDISC_CLK))) return (0); /* * Allocate and initialize unit structure */ if (!(up = (struct true_unit *) emalloc(sizeof(struct true_unit)))) { (void) close(fd); return (0); } memset((char *)up, 0, sizeof(struct true_unit)); pp = peer->procptr; pp->io.clock_recv = true_receive; pp->io.srcclock = (caddr_t)peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { (void) close(fd); free(up); return (0); } pp->unitptr = (caddr_t)up; /* * Initialize miscellaneous variables */ peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; memcpy((char *)&pp->refid, REFID, 4); up->pollcnt = 2; up->type = t_unknown; up->state = s_Base; /* * Send a CTRL-C character at the start, * just in case the clock is already * sending timecodes */ true_send(peer, "\03\r"); true_doevent(peer, e_Init); return (1); }
/* * fg_start - open the device and initialize data for processing */ static int fg_start( int unit, struct peer *peer ) { struct refclockproc *pp; struct fgunit *up; int fd; char device[20]; /* * Open device file for reading. */ snprintf(device, sizeof(device), DEVICE, unit); DPRINTF(1, ("starting FG with device %s\n",device)); fd = refclock_open(device, SPEED232, LDISC_CLK); if (fd <= 0) return (0); /* * Allocate and initialize unit structure */ up = emalloc(sizeof(struct fgunit)); memset(up, 0, sizeof(struct fgunit)); pp = peer->procptr; pp->unitptr = up; pp->io.clock_recv = fg_receive; pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { close(fd); pp->io.fd = -1; return 0; } /* * Initialize miscellaneous variables */ peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; memcpy(&pp->refid, REFID, 3); up->pollnum = 0; /* * Setup dating station to use GPS receiver. * GPS receiver should work before this operation. */ if(!fg_init(pp->io.fd)) refclock_report(peer, CEVNT_FAULT); return (1); }
/* * arb_start - open the devices and initialize data for processing */ static int arb_start( int unit, struct peer *peer ) { register struct arbunit *up; struct refclockproc *pp; int fd; char device[20]; /* * Open serial port. Use CLK line discipline, if available. */ snprintf(device, sizeof(device), DEVICE, unit); fd = refclock_open(device, SPEED232, LDISC_CLK); if (fd <= 0) return (0); /* * Allocate and initialize unit structure */ up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = arb_receive; pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { close(fd); pp->io.fd = -1; free(up); return (0); } pp->unitptr = up; /* * Initialize miscellaneous variables */ peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; memcpy((char *)&pp->refid, REFID, 4); if (peer->MODE > 1) { msyslog(LOG_NOTICE, "ARBITER: Invalid mode %d", peer->MODE); close(fd); pp->io.fd = -1; free(up); return (0); } #ifdef DEBUG if(debug) { printf("arbiter: mode = %d.\n", peer->MODE); } #endif write(pp->io.fd, COMMAND_HALT_BCAST, 2); return (1); }
/* * chronolog_start - open the devices and initialize data for processing */ static int chronolog_start( int unit, struct peer *peer ) { register struct chronolog_unit *up; struct refclockproc *pp; int fd; char device[20]; /* * Open serial port. Don't bother with CLK line discipline, since * it's not available. */ snprintf(device, sizeof(device), DEVICE, unit); #ifdef DEBUG if (debug) printf ("starting Chronolog with device %s\n",device); #endif fd = refclock_open(device, SPEED232, 0); if (fd <= 0) return (0); /* * Allocate and initialize unit structure */ up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->unitptr = up; pp->io.clock_recv = chronolog_receive; pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { close(fd); pp->io.fd = -1; free(up); pp->unitptr = NULL; return (0); } /* * Initialize miscellaneous variables */ peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; memcpy((char *)&pp->refid, REFID, 4); return (1); }
/* * ulink_start - open the devices and initialize data for processing */ static int ulink_start( int unit, struct peer *peer ) { register struct ulinkunit *up; struct refclockproc *pp; int fd; char device[20]; /* * Open serial port. Use CLK line discipline, if available. */ (void)sprintf(device, DEVICE, unit); if (!(fd = refclock_open(device, SPEED232, LDISC_CLK))) return (0); /* * Allocate and initialize unit structure */ if (!(up = (struct ulinkunit *) emalloc(sizeof(struct ulinkunit)))) { (void) close(fd); return (0); } memset((char *)up, 0, sizeof(struct ulinkunit)); pp = peer->procptr; pp->unitptr = (caddr_t)up; pp->io.clock_recv = ulink_receive; pp->io.srcclock = (caddr_t)peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { (void) close(fd); free(up); return (0); } /* * Initialize miscellaneous variables */ peer->precision = PRECISION; peer->burst = NSTAGE; pp->clockdesc = DESCRIPTION; memcpy((char *)&pp->refid, REFID, 4); return (1); }
/* * as2201_start - open the devices and initialize data for processing */ static int as2201_start( int unit, struct peer *peer ) { register struct as2201unit *up; struct refclockproc *pp; int fd; char gpsdev[20]; /* * Open serial port. Use CLK line discipline, if available. */ snprintf(gpsdev, sizeof(gpsdev), DEVICE, unit); if (!(fd = refclock_open(gpsdev, SPEED232, LDISC_CLK))) return (0); /* * Allocate and initialize unit structure */ up = emalloc(sizeof(*up)); memset(up, 0, sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = as2201_receive; pp->io.srcclock = (caddr_t)peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { close(fd); pp->io.fd = -1; free(up); return (0); } pp->unitptr = (caddr_t)up; /* * Initialize miscellaneous variables */ peer->precision = PRECISION; peer->burst = NSTAGE; pp->clockdesc = DESCRIPTION; memcpy((char *)&pp->refid, REFID, 4); up->lastptr = up->stats; up->index = 0; return (1); }
/* * wwvb_start - open the devices and initialize data for processing */ static int wwvb_start( int unit, struct peer *peer ) { register struct wwvbunit *up; struct refclockproc *pp; int fd; char device[20]; /* * Open serial port. Use CLK line discipline, if available. */ snprintf(device, sizeof(device), DEVICE, unit); fd = refclock_open(device, SPEED232, LDISC_CLK); if (fd <= 0) return (0); /* * Allocate and initialize unit structure */ up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = wwvb_receive; pp->io.srcclock = (void *)peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { close(fd); pp->io.fd = -1; free(up); return (0); } pp->unitptr = up; /* * Initialize miscellaneous variables */ peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; memcpy(&pp->refid, REFID, 4); return (1); }
/* * chu_start - open the devices and initialize data for processing */ static int chu_start( int unit, /* instance number (not used) */ struct peer *peer /* peer structure pointer */ ) { struct chuunit *up; struct refclockproc *pp; char device[20]; /* device name */ int fd; /* file descriptor */ #ifdef ICOM int temp; #endif /* ICOM */ #ifdef HAVE_AUDIO int fd_audio; /* audio port file descriptor */ int i; /* index */ double step; /* codec adjustment */ /* * Open audio device. Don't complain if not there. */ fd_audio = audio_init(DEVICE_AUDIO, AUDIO_BUFSIZ, unit); #ifdef DEBUG if (fd_audio >= 0 && debug) audio_show(); #endif /* * If audio is unavailable, Open serial port in raw mode. */ if (fd_audio >= 0) { fd = fd_audio; } else { snprintf(device, sizeof(device), DEVICE, unit); fd = refclock_open(device, SPEED232, LDISC_RAW); } #else /* HAVE_AUDIO */ /* * Open serial port in raw mode. */ snprintf(device, sizeof(device), DEVICE, unit); fd = refclock_open(device, SPEED232, LDISC_RAW); #endif /* HAVE_AUDIO */ if (fd < 0) return (0); /* * Allocate and initialize unit structure */ up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->unitptr = up; pp->io.clock_recv = chu_receive; pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { close(fd); pp->io.fd = -1; free(up); pp->unitptr = NULL; return (0); } /* * Initialize miscellaneous variables */ peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; strlcpy(up->ident, "CHU", sizeof(up->ident)); memcpy(&pp->refid, up->ident, 4); DTOLFP(CHAR, &up->charstamp); #ifdef HAVE_AUDIO /* * The companded samples are encoded sign-magnitude. The table * contains all the 256 values in the interest of speed. We do * this even if the audio codec is not available. C'est la lazy. */ up->fd_audio = fd_audio; up->gain = 127; up->comp[0] = up->comp[OFFSET] = 0.; up->comp[1] = 1; up->comp[OFFSET + 1] = -1.; up->comp[2] = 3; up->comp[OFFSET + 2] = -3.; step = 2.; for (i = 3; i < OFFSET; i++) { up->comp[i] = up->comp[i - 1] + step; up->comp[OFFSET + i] = -up->comp[i]; if (i % 16 == 0) step *= 2.; } DTOLFP(1. / SECOND, &up->tick); #endif /* HAVE_AUDIO */ #ifdef ICOM temp = 0; #ifdef DEBUG if (debug > 1) temp = P_TRACE; #endif if (peer->ttl > 0) { if (peer->ttl & 0x80) up->fd_icom = icom_init("/dev/icom", B1200, temp); else up->fd_icom = icom_init("/dev/icom", B9600, temp); } if (up->fd_icom > 0) { if (chu_newchan(peer, 0) != 0) { msyslog(LOG_NOTICE, "icom: radio not found"); close(up->fd_icom); up->fd_icom = 0; } else { msyslog(LOG_NOTICE, "icom: autotune enabled"); } } #endif /* ICOM */ return (1); }
/* * arc_start - open the devices and initialize data for processing */ static int arc_start( int unit, struct peer *peer ) { register struct arcunit *up; struct refclockproc *pp; int fd; char device[20]; #ifdef HAVE_TERMIOS struct termios arg; #endif msyslog(LOG_NOTICE, "ARCRON: %s: opening unit %d", arc_version, unit); #ifdef DEBUG if(debug) { printf("arc: %s: attempt to open unit %d.\n", arc_version, unit); } #endif /* Prevent a ridiculous device number causing overflow of device[]. */ if((unit < 0) || (unit > 255)) { return(0); } /* * Open serial port. Use CLK line discipline, if available. */ snprintf(device, sizeof(device), DEVICE, unit); if (!(fd = refclock_open(device, SPEED, LDISC_CLK))) return(0); #ifdef DEBUG if(debug) { printf("arc: unit %d using open().\n", unit); } #endif fd = tty_open(device, OPEN_FLAGS, 0777); if(fd < 0) { #ifdef DEBUG if(debug) { printf("arc: failed [tty_open()] to open %s.\n", device); } #endif return(0); } #ifndef SYS_WINNT fcntl(fd, F_SETFL, 0); /* clear the descriptor flags */ #endif #ifdef DEBUG if(debug) { printf("arc: opened RS232 port with file descriptor %d.\n", fd); } #endif #ifdef HAVE_TERMIOS tcgetattr(fd, &arg); arg.c_iflag = IGNBRK | ISTRIP; arg.c_oflag = 0; arg.c_cflag = B300 | CS8 | CREAD | CLOCAL | CSTOPB; arg.c_lflag = 0; arg.c_cc[VMIN] = 1; arg.c_cc[VTIME] = 0; tcsetattr(fd, TCSANOW, &arg); #else msyslog(LOG_ERR, "ARCRON: termios not supported in this driver"); (void)close(fd); return 0; #endif up = emalloc(sizeof(*up)); /* Set structure to all zeros... */ memset(up, 0, sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = arc_receive; pp->io.srcclock = (caddr_t)peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { close(fd); pp->io.fd = -1; free(up); return(0); } pp->unitptr = (caddr_t)up; /* * Initialize miscellaneous variables */ peer->precision = PRECISION; peer->stratum = 2; /* Default to stratum 2 not 0. */ pp->clockdesc = DESCRIPTION; if (peer->MODE > 3) { msyslog(LOG_NOTICE, "ARCRON: Invalid mode %d", peer->MODE); return 0; } #ifdef DEBUG if(debug) { printf("arc: mode = %d.\n", peer->MODE); } #endif switch (peer->MODE) { case 1: memcpy((char *)&pp->refid, REFID_MSF, 4); break; case 2: memcpy((char *)&pp->refid, REFID_DCF77, 4); break; case 3: memcpy((char *)&pp->refid, REFID_WWVB, 4); break; default: memcpy((char *)&pp->refid, REFID, 4); break; } /* Spread out resyncs so that they should remain separated. */ up->next_resync = current_time + INITIAL_RESYNC_DELAY + (67*unit)%1009; #if 0 /* Not needed because of zeroing of arcunit structure... */ up->resyncing = 0; /* Not resyncing yet. */ up->saved_flags = 0; /* Default is all flags off. */ /* Clear send buffer out... */ { int i; for(i = CMDQUEUELEN; i >= 0; --i) { up->cmdqueue[i] = '\0'; } } #endif #ifdef ARCRON_KEEN up->quality = QUALITY_UNKNOWN; /* Trust the clock immediately. */ #else up->quality = MIN_CLOCK_QUALITY;/* Don't trust the clock yet. */ #endif peer->action = arc_event_handler; ENQUEUE(up); return(1); }
/* * acts_timeout - called on timeout */ static void acts_timeout( struct peer *peer ) { struct actsunit *up; struct refclockproc *pp; int fd; char device[20]; char lockfile[128], pidbuf[8]; char tbuf[SMAX]; /* * The state machine is driven by messages from the modem, when * first stated and at timeout. */ pp = peer->procptr; up = (struct actsunit *)pp->unitptr; pp->sloppyclockflag &= ~CLK_FLAG1; if (sys_phone[up->retry] == NULL && !(pp->sloppyclockflag & CLK_FLAG3)) { msyslog(LOG_ERR, "acts: no phones"); return; } switch(up->state) { /* * System poll event. Lock the modem port and open the device. */ case S_IDLE: /* * Lock the modem port. If busy, retry later. Note: if * something fails between here and the close, the lock * file may not be removed. */ if (pp->sloppyclockflag & CLK_FLAG2) { snprintf(lockfile, sizeof(lockfile), LOCKFILE, up->unit); fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0644); if (fd < 0) { msyslog(LOG_ERR, "acts: port busy"); return; } snprintf(pidbuf, sizeof(pidbuf), "%d\n", (u_int)getpid()); write(fd, pidbuf, strlen(pidbuf)); close(fd); } /* * Open the device in raw mode and link the I/O. */ if (!pp->io.fd) { snprintf(device, sizeof(device), DEVICE, up->unit); fd = refclock_open(device, SPEED232, LDISC_ACTS | LDISC_RAW | LDISC_REMOTE); if (fd == 0) { msyslog(LOG_ERR, "acts: open fails"); return; } pp->io.fd = fd; if (!io_addclock(&pp->io)) { msyslog(LOG_ERR, "acts: addclock fails"); close(fd); pp->io.fd = 0; return; } } /* * If the port is directly connected to the device, skip * the modem business and send 'T' for Spectrabum. */ if (pp->sloppyclockflag & CLK_FLAG3) { if (write(pp->io.fd, "T", 1) < 0) { msyslog(LOG_ERR, "acts: write %m"); return; } up->state = S_FIRST; up->timer = CONNECT; return; } /* * Initialize the modem. This works with Hayes commands. */ #ifdef DEBUG if (debug) printf("acts: setup %s\n", MODEM_SETUP); #endif if (write(pp->io.fd, MODEM_SETUP, strlen(MODEM_SETUP)) < 0) { msyslog(LOG_ERR, "acts: write %m"); return; } up->state = S_OK; up->timer = SETUP; return; /* * In OK state the modem did not respond to setup. */ case S_OK: msyslog(LOG_ERR, "acts: no modem"); break; /* * In DTR state we are waiting for the modem to settle down * before hammering it with a dial command. */ case S_DTR: snprintf(tbuf, sizeof(tbuf), "DIAL #%d %s", up->retry, sys_phone[up->retry]); report_event(PEVNT_CLOCK, peer, tbuf); #ifdef DEBUG if (debug) printf("%s\n", tbuf); #endif write(pp->io.fd, sys_phone[up->retry], strlen(sys_phone[up->retry])); write(pp->io.fd, "\r", 1); up->state = S_CONNECT; up->timer = ANSWER; return; /* * In CONNECT state the call did not complete. */ case S_CONNECT: msyslog(LOG_ERR, "acts: no answer"); break; /* * In FIRST state no messages were received. */ case S_FIRST: msyslog(LOG_ERR, "acts: no messages"); break; /* * In CLOSE state hangup is complete. Close the doors and * windows and get some air. */ case S_CLOSE: /* * Close the device and unlock a shared modem. */ if (pp->io.fd) { io_closeclock(&pp->io); close(pp->io.fd); if (pp->sloppyclockflag & CLK_FLAG2) { snprintf(lockfile, sizeof(lockfile), LOCKFILE, up->unit); unlink(lockfile); } pp->io.fd = 0; } /* * If messages were received, fold the tent and wait for * the next poll. If no messages and there are more * numbers to dial, retry after a short wait. */ up->bufptr = pp->a_lastcode; up->timer = 0; up->state = S_IDLE; if ( up->msgcnt == 0) { up->retry++; if (sys_phone[up->retry] == NULL) up->retry = 0; else up->timer = SETUP; } else { up->retry = 0; } up->msgcnt = 0; return; } acts_disc(peer); }
static int neoclock4x_start(int unit, struct peer *peer) { struct neoclock4x_unit *up; struct refclockproc *pp; int fd; char dev[20]; int sl232; #if defined(HAVE_TERMIOS) struct termios termsettings; #endif #if !defined(NEOCLOCK4X_FIRMWARE) int tries; #endif (void) snprintf(dev, sizeof(dev)-1, "/dev/neoclock4x-%d", unit); /* LDISC_STD, LDISC_RAW * Open serial port. Use CLK line discipline, if available. */ fd = refclock_open(dev, B2400, LDISC_STD); if(fd <= 0) { return (0); } #if defined(HAVE_TERMIOS) #if 1 if(tcgetattr(fd, &termsettings) < 0) { msyslog(LOG_CRIT, "NeoClock4X(%d): (tcgetattr) can't query serial port settings: %m", unit); (void) close(fd); return (0); } /* 2400 Baud 8N2 */ termsettings.c_iflag = IGNBRK | IGNPAR | ICRNL; termsettings.c_oflag = 0; termsettings.c_cflag = CS8 | CSTOPB | CLOCAL | CREAD; (void)cfsetispeed(&termsettings, (u_int)B2400); (void)cfsetospeed(&termsettings, (u_int)B2400); if(tcsetattr(fd, TCSANOW, &termsettings) < 0) { msyslog(LOG_CRIT, "NeoClock4X(%d): (tcsetattr) can't set serial port 2400 8N2: %m", unit); (void) close(fd); return (0); } #else if(tcgetattr(fd, &termsettings) < 0) { msyslog(LOG_CRIT, "NeoClock4X(%d): (tcgetattr) can't query serial port settings: %m", unit); (void) close(fd); return (0); } /* 2400 Baud 8N2 */ termsettings.c_cflag &= ~PARENB; termsettings.c_cflag |= CSTOPB; termsettings.c_cflag &= ~CSIZE; termsettings.c_cflag |= CS8; if(tcsetattr(fd, TCSANOW, &termsettings) < 0) { msyslog(LOG_CRIT, "NeoClock4X(%d): (tcsetattr) can't set serial port 2400 8N2: %m", unit); (void) close(fd); return (0); } #endif #elif defined(HAVE_SYSV_TTYS) if(ioctl(fd, TCGETA, &termsettings) < 0) { msyslog(LOG_CRIT, "NeoClock4X(%d): (TCGETA) can't query serial port settings: %m", unit); (void) close(fd); return (0); } /* 2400 Baud 8N2 */ termsettings.c_cflag &= ~PARENB; termsettings.c_cflag |= CSTOPB; termsettings.c_cflag &= ~CSIZE; termsettings.c_cflag |= CS8; if(ioctl(fd, TCSETA, &termsettings) < 0) { msyslog(LOG_CRIT, "NeoClock4X(%d): (TSGETA) can't set serial port 2400 8N2: %m", unit); (void) close(fd); return (0); } #else msyslog(LOG_EMERG, "NeoClock4X(%d): don't know how to set port to 2400 8N2 with this OS!", unit); (void) close(fd); return (0); #endif #if defined(TIOCMSET) && (defined(TIOCM_RTS) || defined(CIOCM_RTS)) /* turn on RTS, and DTR for power supply */ /* NeoClock4x is powered from serial line */ if(ioctl(fd, TIOCMGET, (caddr_t)&sl232) == -1) { msyslog(LOG_CRIT, "NeoClock4X(%d): can't query RTS/DTR state: %m", unit); (void) close(fd); return (0); } #ifdef TIOCM_RTS sl232 = sl232 | TIOCM_DTR | TIOCM_RTS; /* turn on RTS, and DTR for power supply */ #else sl232 = sl232 | CIOCM_DTR | CIOCM_RTS; /* turn on RTS, and DTR for power supply */ #endif if(ioctl(fd, TIOCMSET, (caddr_t)&sl232) == -1) { msyslog(LOG_CRIT, "NeoClock4X(%d): can't set RTS/DTR to power neoclock4x: %m", unit); (void) close(fd); return (0); } #else msyslog(LOG_EMERG, "NeoClock4X(%d): don't know how to set DTR/RTS to power NeoClock4X with this OS!", unit); (void) close(fd); return (0); #endif up = (struct neoclock4x_unit *) emalloc(sizeof(struct neoclock4x_unit)); if(!(up)) { msyslog(LOG_ERR, "NeoClock4X(%d): can't allocate memory for: %m",unit); (void) close(fd); return (0); } memset((char *)up, 0, sizeof(struct neoclock4x_unit)); pp = peer->procptr; pp->clockdesc = "NeoClock4X"; pp->unitptr = up; pp->io.clock_recv = neoclock4x_receive; pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; /* * no fudge time is given by user! * use 169.583333 ms to compensate the serial line delay * formula is: * 2400 Baud / 11 bit = 218.18 charaters per second * (NeoClock4X timecode len) */ pp->fudgetime1 = (NEOCLOCK4X_TIMECODELEN * 11) / 2400.0; /* * Initialize miscellaneous variables */ peer->precision = -10; memcpy((char *)&pp->refid, "neol", 4); up->leap_status = 0; up->unit = unit; strlcpy(up->firmware, "?", sizeof(up->firmware)); up->firmwaretag = '?'; strlcpy(up->serial, "?", sizeof(up->serial)); strlcpy(up->radiosignal, "?", sizeof(up->radiosignal)); up->timesource = '?'; up->dststatus = '?'; up->quarzstatus = '?'; up->antenna1 = -1; up->antenna2 = -1; up->utc_year = 0; up->utc_month = 0; up->utc_day = 0; up->utc_hour = 0; up->utc_minute = 0; up->utc_second = 0; up->utc_msec = 0; #if defined(NEOCLOCK4X_FIRMWARE) #if NEOCLOCK4X_FIRMWARE == NEOCLOCK4X_FIRMWARE_VERSION_A strlcpy(up->firmware, "(c) 2002 NEOL S.A. FRANCE / L0.01 NDF:A:* (compile time)", sizeof(up->firmware)); up->firmwaretag = 'A'; #else msyslog(LOG_EMERG, "NeoClock4X(%d): unknown firmware defined at compile time for NeoClock4X", unit); (void) close(fd); pp->io.fd = -1; free(pp->unitptr); pp->unitptr = NULL; return (0); #endif #else for(tries=0; tries < 5; tries++) { NLOG(NLOG_CLOCKINFO) msyslog(LOG_INFO, "NeoClock4X(%d): checking NeoClock4X firmware version (%d/5)", unit, tries); /* wait 3 seconds for receiver to power up */ sleep(3); if(neol_query_firmware(pp->io.fd, up->unit, up->firmware, sizeof(up->firmware))) { break; } } /* can I handle this firmware version? */ if(!neol_check_firmware(up->unit, up->firmware, &up->firmwaretag)) { (void) close(fd); pp->io.fd = -1; free(pp->unitptr); pp->unitptr = NULL; return (0); } #endif if(!io_addclock(&pp->io)) { msyslog(LOG_ERR, "NeoClock4X(%d): error add peer to ntpd: %m", unit); (void) close(fd); pp->io.fd = -1; free(pp->unitptr); pp->unitptr = NULL; return (0); } NLOG(NLOG_CLOCKINFO) msyslog(LOG_INFO, "NeoClock4X(%d): receiver setup successful done", unit); return (1); }
/* * hopfserial_start - open the devices and initialize data for processing */ static int hopfserial_start ( int unit, struct peer *peer ) { register struct hopfclock_unit *up; struct refclockproc *pp; int fd; char gpsdev[20]; snprintf(gpsdev, sizeof(gpsdev), DEVICE, unit); /* LDISC_STD, LDISC_RAW * Open serial port. Use CLK line discipline, if available. */ fd = refclock_open(gpsdev, SPEED232, LDISC_CLK); if (fd <= 0) { #ifdef DEBUG printf("hopfSerialClock(%d) start: open %s failed\n", unit, gpsdev); #endif return 0; } msyslog(LOG_NOTICE, "hopfSerialClock(%d) fd: %d dev: %s", unit, fd, gpsdev); /* * Allocate and initialize unit structure */ up = emalloc(sizeof(*up)); memset(up, 0, sizeof(*up)); pp = peer->procptr; pp->unitptr = (caddr_t)up; pp->io.clock_recv = hopfserial_receive; pp->io.srcclock = (caddr_t)peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { #ifdef DEBUG printf("hopfSerialClock(%d) io_addclock\n", unit); #endif close(fd); pp->io.fd = -1; free(up); pp->unitptr = NULL; return (0); } /* * Initialize miscellaneous variables */ pp->clockdesc = DESCRIPTION; peer->precision = PRECISION; peer->burst = NSTAGE; memcpy((char *)&pp->refid, REFID, 4); up->leap_status = 0; up->unit = (short) unit; return (1); }
/* * hpgps_start - open the devices and initialize data for processing */ static int hpgps_start( int unit, struct peer *peer ) { register struct hpgpsunit *up; struct refclockproc *pp; int fd; char device[20]; /* * Open serial port. Use CLK line discipline, if available. * Default is HP 58503A, mode arg selects HP Z3801A */ (void)sprintf(device, DEVICE, unit); /* mode parameter to server config line shares ttl slot */ if ((peer->ttl == 1)) { if (!(fd = refclock_open(device, SPEED232Z, LDISC_CLK | LDISC_7O1))) return (0); } else { if (!(fd = refclock_open(device, SPEED232, LDISC_CLK))) return (0); } /* * Allocate and initialize unit structure */ if (!(up = (struct hpgpsunit *) emalloc(sizeof(struct hpgpsunit)))) { (void) close(fd); return (0); } memset((char *)up, 0, sizeof(struct hpgpsunit)); pp = peer->procptr; pp->io.clock_recv = hpgps_receive; pp->io.srcclock = (caddr_t)peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { (void) close(fd); free(up); return (0); } pp->unitptr = (caddr_t)up; /* * Initialize miscellaneous variables */ peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; memcpy((char *)&pp->refid, REFID, 4); up->tzhour = 0; up->tzminute = 0; *up->statscrn = '\0'; up->lastptr = up->statscrn; up->pollcnt = 2; /* * Get the identifier string, which is logged but otherwise ignored, * and get the local timezone information */ up->linecnt = 1; if (write(pp->io.fd, "*IDN?\r:PTIME:TZONE?\r", 20) != 20) refclock_report(peer, CEVNT_FAULT); return (1); }
/* * acts_timeout - called on timeout */ static void acts_timeout( struct peer *peer, teModemState dstate ) { struct actsunit *up; struct refclockproc *pp; int fd; int rc; char device[20]; char lockfile[128], pidbuf[8]; /* * The state machine is driven by messages from the modem, * when first started and at timeout. */ pp = peer->procptr; up = pp->unitptr; switch (dstate) { /* * System poll event. Lock the modem port, open the device * and send the setup command. */ case S_IDLE: if (-1 != pp->io.fd) return; /* port is already open */ /* * Lock the modem port. If busy, retry later. Note: if * something fails between here and the close, the lock * file may not be removed. */ if (pp->sloppyclockflag & CLK_FLAG2) { snprintf(lockfile, sizeof(lockfile), LOCKFILE, up->unit); fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0644); if (fd < 0) { report_event(PEVNT_CLOCK, peer, "acts: port busy"); return; } snprintf(pidbuf, sizeof(pidbuf), "%d\n", (u_int)getpid()); if (write(fd, pidbuf, strlen(pidbuf)) < 0) msyslog(LOG_ERR, "acts: write lock fails %m"); close(fd); } /* * Open the device in raw mode and link the I/O. */ snprintf(device, sizeof(device), DEVICE, up->unit); fd = refclock_open(device, SPEED232, LDISC_ACTS | LDISC_RAW | LDISC_REMOTE); if (fd < 0) { msyslog(LOG_ERR, "acts: open fails %m"); return; } pp->io.fd = fd; if (!io_addclock(&pp->io)) { msyslog(LOG_ERR, "acts: addclock fails"); close(fd); pp->io.fd = -1; return; } up->msgcnt = 0; up->bufptr = up->buf; /* * If the port is directly connected to the device, skip * the modem business and send 'T' for Spectrabum. */ if (sys_phone[up->retry] == NULL) { if (write(pp->io.fd, "T", 1) < 0) msyslog(LOG_ERR, "acts: write T fails %m"); up->state = S_MSG; up->timer = TIMECODE; return; } /* * Initialize the modem. This works with Hayes- * compatible modems. */ mprintf_event(PEVNT_CLOCK, peer, "SETUP %s", modem_setup); rc = write(pp->io.fd, modem_setup, strlen(modem_setup)); if (rc < 0) msyslog(LOG_ERR, "acts: write SETUP fails %m"); write(pp->io.fd, "\r", 1); up->state = S_SETUP; up->timer = SETUP; return; /* * In SETUP state the modem did not respond OK to setup string. */ case S_SETUP: report_event(PEVNT_CLOCK, peer, "no modem"); break; /* * In CONNECT state the call did not complete. Abort the call. */ case S_CONNECT: report_event(PEVNT_CLOCK, peer, "no answer"); break; /* * In MSG states no further timecodes are expected. If any * timecodes have arrived, update the clock. In any case, * terminate the call. */ case S_MSG: if (up->msgcnt == 0) { report_event(PEVNT_CLOCK, peer, "no timecodes"); } else { pp->lastref = pp->lastrec; record_clock_stats(&peer->srcadr, pp->a_lastcode); refclock_receive(peer); } break; } acts_close(peer); }