/* * 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); }
/* * leitch_start - open the LEITCH devices and initialize data for processing */ static int leitch_start( int unit, struct peer *peer ) { struct leitchunit *leitch; int fd232; char leitchdev[20]; /* * Check configuration info. */ if (unit >= MAXUNITS) { msyslog(LOG_ERR, "leitch_start: unit %d invalid", unit); return (0); } if (unitinuse[unit]) { msyslog(LOG_ERR, "leitch_start: unit %d in use", unit); return (0); } /* * Open serial port. */ snprintf(leitchdev, sizeof(leitchdev), LEITCH232, unit); fd232 = open(leitchdev, O_RDWR, 0777); if (fd232 == -1) { msyslog(LOG_ERR, "leitch_start: open of %s: %m", leitchdev); return (0); } leitch = &leitchunits[unit]; memset(leitch, 0, sizeof(*leitch)); #if defined(HAVE_SYSV_TTYS) /* * System V serial line parameters (termio interface) * */ { struct termio ttyb; if (ioctl(fd232, TCGETA, &ttyb) < 0) { msyslog(LOG_ERR, "leitch_start: ioctl(%s, TCGETA): %m", leitchdev); goto screwed; } ttyb.c_iflag = IGNBRK|IGNPAR|ICRNL; ttyb.c_oflag = 0; ttyb.c_cflag = SPEED232|CS8|CLOCAL|CREAD; ttyb.c_lflag = ICANON; ttyb.c_cc[VERASE] = ttyb.c_cc[VKILL] = '\0'; if (ioctl(fd232, TCSETA, &ttyb) < 0) { msyslog(LOG_ERR, "leitch_start: ioctl(%s, TCSETA): %m", leitchdev); goto screwed; } } #endif /* HAVE_SYSV_TTYS */ #if defined(HAVE_TERMIOS) /* * POSIX serial line parameters (termios interface) */ { struct termios ttyb, *ttyp; ttyp = &ttyb; if (tcgetattr(fd232, ttyp) < 0) { msyslog(LOG_ERR, "leitch_start: tcgetattr(%s): %m", leitchdev); goto screwed; } ttyp->c_iflag = IGNBRK|IGNPAR|ICRNL; ttyp->c_oflag = 0; ttyp->c_cflag = SPEED232|CS8|CLOCAL|CREAD; ttyp->c_lflag = ICANON; ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\0'; if (tcsetattr(fd232, TCSANOW, ttyp) < 0) { msyslog(LOG_ERR, "leitch_start: tcsetattr(%s): %m", leitchdev); goto screwed; } if (tcflush(fd232, TCIOFLUSH) < 0) { msyslog(LOG_ERR, "leitch_start: tcflush(%s): %m", leitchdev); goto screwed; } } #endif /* HAVE_TERMIOS */ #if defined(HAVE_BSD_TTYS) /* * 4.3bsd serial line parameters (sgttyb interface) */ { struct sgttyb ttyb; if (ioctl(fd232, TIOCGETP, &ttyb) < 0) { msyslog(LOG_ERR, "leitch_start: ioctl(%s, TIOCGETP): %m", leitchdev); goto screwed; } ttyb.sg_ispeed = ttyb.sg_ospeed = SPEED232; ttyb.sg_erase = ttyb.sg_kill = '\0'; ttyb.sg_flags = EVENP|ODDP|CRMOD; if (ioctl(fd232, TIOCSETP, &ttyb) < 0) { msyslog(LOG_ERR, "leitch_start: ioctl(%s, TIOCSETP): %m", leitchdev); goto screwed; } } #endif /* HAVE_BSD_TTYS */ /* * Set up the structures */ leitch->peer = peer; leitch->unit = unit; leitch->state = STATE_IDLE; leitch->fudge1 = 15; /* 15ms */ leitch->leitchio.clock_recv = leitch_receive; leitch->leitchio.srcclock = peer; leitch->leitchio.datalen = 0; leitch->leitchio.fd = fd232; if (!io_addclock(&leitch->leitchio)) { leitch->leitchio.fd = -1; goto screwed; } /* * All done. Initialize a few random peer variables, then * return success. */ peer->precision = PRECISION; peer->stratum = stratumtouse[unit]; peer->refid = refid[unit]; unitinuse[unit] = 1; return(1); /* * Something broke; abandon ship. */ screwed: close(fd232); return(0); }
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); }
static void gpsd_test_socket( peerT * const peer) { clockprocT * const pp = peer->procptr; gpsd_unitT * const up = (gpsd_unitT *)pp->unitptr; int ec, rc; socklen_t lc; /* Check if the non-blocking connect was finished by testing the * socket for writeability. Use the 'poll()' API if available * and 'select()' otherwise. */ DPRINTF(2, ("GPSD_JSON(%d): check connect, fd=%d\n", up->unit, up->fdt)); #if defined(HAVE_SYS_POLL_H) { struct pollfd pfd; pfd.events = POLLOUT; pfd.fd = up->fdt; rc = poll(&pfd, 1, 0); if (1 != rc || !(pfd.revents & POLLOUT)) return; } #elif defined(HAVE_SYS_SELECT_H) { struct timeval tout; fd_set wset; memset(&tout, 0, sizeof(tout)); FD_ZERO(&wset); FD_SET(up->fdt, &wset); rc = select(up->fdt+1, NULL, &wset, NULL, &tout); if (0 == rc || !(FD_ISSET(up->fdt, &wset))) return; } #else # error Blooper! That should have been found earlier! #endif /* next timeout is a full one... */ up->tickover = TICKOVER_LOW; /* check for socket error */ ec = 0; lc = sizeof(ec); rc = getsockopt(up->fdt, SOL_SOCKET, SO_ERROR, &ec, &lc); DPRINTF(1, ("GPSD_JSON(%d): connect finshed, fd=%d, ec=%d(%s)\n", up->unit, up->fdt, ec, strerror(ec))); if (-1 == rc || 0 != ec) { errno = ec; if (syslogok(pp, up)) msyslog(LOG_ERR, "%s: (async)cannot connect GPSD socket: %m", refnumtoa(&peer->srcadr)); goto no_socket; } /* swap socket FDs, and make sure the clock was added */ pp->io.fd = up->fdt; up->fdt = -1; if (0 == io_addclock(&pp->io)) { if (syslogok(pp, up)) msyslog(LOG_ERR, "%s: failed to register with I/O engine", refnumtoa(&peer->srcadr)); goto no_socket; } return; no_socket: if (-1 != up->fdt) close(up->fdt); up->fdt = -1; up->tickover = up->tickpres; up->tickpres = min(up->tickpres + 5, TICKOVER_HIGH); }