/************************************************************************** * * Sample program demonstrating how to read a serial time string * from an external device. * * Optionally, a request character can be sent before waiting * for the time string. * * The received time string is printed to stdout. * * For makefiles and build environment setups check the associated * subdirectories. * * Comments can be sent to * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * **************************************************************************/ #include #include #include #include #define MBG_NUMERIC_VERSION_STR "1.4" // If building within a git repo, we prefer the version // string from git, else the version defined above. #if defined( MBG_VERSION_FROM_GIT ) #define MBG_FULL_VERSION_STR STRINGIFY( MBG_VERSION_FROM_GIT ) #else #define MBG_FULL_VERSION_STR MBG_NUMERIC_VERSION_STR #endif static const char *pname = "mbgreadtimestring"; static const char *pcopyright = "(c) Meinberg 2009-2024"; /* other local variables */ static const char *target; static int must_print_usage; static int must_query; static int quiet; static ulong poll_timeout = 2000; // ms static const char *default_target = DEFAULT_SERIAL_DEVICE_NAME; static MBGSERIO_DEV *p_sdev; #if _USE_SERIAL_IO static uint32_t default_baudrate = 19200L; static const char *default_framing = "8N1"; static uint32_t baudrate; static const char *framing; static int must_force_connection; #endif static /*HDR*/ int read_timestring( MBGSERIO_DEV *sdev, char *ts, int max_len ) { char *cp = ts; int received_stx = 0; for (;;) { int i; char buffer[80]; int rc = mbgserio_read_wait( sdev, buffer, sizeof( buffer ) ); if ( mbg_rc_is_error( rc ) ) { fprintf(stderr, "Read failed: %s\n", mbg_strerror( rc ) ); return rc; } // rc holds the number of bytes read. for ( i = 0; i < rc; i++ ) { char c = buffer[i]; switch ( c ) { case 2: // STX: ignore received_stx = 1; // just remember we received it continue; case 3: // ETX: ignore goto done; // but done } if ( !received_stx ) continue; if ( max_len == 0 ) goto done; *cp++ = c; max_len--; } } while ( 0 ); done: return cp - ts; // number of bytes saved } // read_timestring /*HDR*/ static void close_connection( void ) { mbgserio_close( &p_sdev ); } /* close_connection */ static /*HDR*/ void usage( const char *progname ) { printf( "Optionally send a request character, then read a time string\n" "from a Meinberg device connected via serial port.\n" "\n" ); printf( "Usage: %s [-r] [-q] target\n" "\n", progname ); printf( " -r Send a query/request character first\n" ); printf( " -q Quiet, print nothing but the received time string\n" ); printf( "\n" "Optional arguments:\n" " -? or -h Print this usage\n" ); #if _USE_SERIAL_IO printf( " -b speed serial port baud rate, default: %lu\n" " -f xxx serial port framing, default: %s\n" " -F force serial connection to %lu/%s\n", (long) default_baudrate, framing, (long) default_baudrate, framing ); #endif printf( "\n" "Target argument:\n" ); #if _USE_SERIAL_IO printf( " can specify a serial port, default: %s\n", default_target ); #endif printf( "\n" ); } // usage // Do a very simple processing of command line parameters: static /*HDR*/ int check_command_line( int argc, char *argv[] ) { int i; for ( i = 1; i < argc; i++ ) { if ( strcmp( argv[i], "-r" ) == 0 ) { must_query = 1; continue; } if ( strcmp( argv[i], "-q" ) == 0 ) { quiet = 1; continue; } if ( strcmp( argv[i], "-?" ) == 0 ) { must_print_usage = 1; continue; } if ( strcmp( argv[i], "-h" ) == 0 ) { must_print_usage = 1; continue; } #if _USE_SERIAL_IO if ( strcmp( argv[i], "-b" ) == 0 ) { if ( ++i < argc ) baudrate = strtoul( argv[i], NULL, 10 ); else must_print_usage = 1; continue; } #endif #if _USE_SERIAL_IO if ( strcmp( argv[i], "-f" ) == 0 ) { if ( ++i < argc ) framing = argv[i]; else must_print_usage = 1; continue; } #endif #if _USE_SERIAL_IO if ( strcmp( argv[i], "-F" ) == 0 ) { must_force_connection = 1; continue; } #endif if ( argv[i][0] != '-' ) target = argv[i]; else must_print_usage = 1; } if ( target == NULL ) target = default_target; return 0; } // check_command_line int main( int argc, char *argv[] ) { char ts[80]; int rc; check_command_line( argc, argv ); if ( !quiet ) printf( "\n\n\n%s v%s %s\n\n", pname, MBG_FULL_VERSION_STR, pcopyright ); #if _USE_SERIAL_IO baudrate = default_baudrate; framing = default_framing; #endif check_command_line( argc, argv ); if ( must_print_usage ) { if ( !quiet ) usage( pname ); return 1; } #if _USE_SERIAL_IO rc = mbgserio_open( &p_sdev, target ); if ( mbg_rc_is_error( rc ) ) { fprintf( stderr, "Failed to open %s: %s\n", target, mbg_strerror( rc ) ); return 1; // Error ... } mbgserio_set_parms( p_sdev, baudrate, framing ); mbgserio_set_dev_poll_timeout( p_sdev, poll_timeout ); if ( !quiet ) printf( "Using %s with %li baud, %s\n", target, (long) baudrate, framing ); #endif atexit( close_connection ); // now send the new date and time to the device if ( must_query ) { char request_char = '?'; mbgserio_write( p_sdev, &request_char, sizeof( request_char ) ); } rc = read_timestring( p_sdev, ts, sizeof( ts ) ); if ( mbg_rc_is_success( rc ) ) { ts[rc] = 0; // terminating 0 printf( "%s\n", ts ); } return 0; } /* main */