summaryrefslogtreecommitdiff
path: root/gpsxmple.c
diff options
context:
space:
mode:
Diffstat (limited to 'gpsxmple.c')
-rw-r--r--gpsxmple.c813
1 files changed, 638 insertions, 175 deletions
diff --git a/gpsxmple.c b/gpsxmple.c
index 08ec1dd..30e70e3 100644
--- a/gpsxmple.c
+++ b/gpsxmple.c
@@ -1,14 +1,14 @@
/**************************************************************************
*
- * $Id: gpsxmple.c 1.8 2011/04/15 13:04:14 martin REL_M $
- * $Name: GPSXMPLE_2_3 $
+ * $Id: gpsxmple.c 1.10.1.8 2015/07/25 15:28:12 martin TEST $
+ * $Name: $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
* Description:
* Sample program demonstrating how to access Meinberg devices
- * using the binary data protocol.
+ * using the serial binary data protocol.
*
* Depending on the target operating system this program works
* either via serial port (the default) or via a network socket
@@ -32,6 +32,26 @@
*
* -----------------------------------------------------------------------
* $Log: gpsxmple.c $
+ * Revision 1.10.1.8 2015/07/25 15:28:12 martin
+ * Revision 1.10.1.7 2015/07/24 13:47:32Z martin
+ * Revision 1.10.1.6 2015/07/14 13:01:02 martin
+ * Revision 1.10.1.5 2014/11/04 11:32:25 martin
+ * Started to support XBP addressing.
+ * Revision 1.10.1.4 2014/10/30 13:49:38 martin
+ * Revision 1.10.1.3 2013/02/01 16:11:59 martin
+ * Revision 1.10.1.2 2012/03/13 16:27:44 martin
+ * Revision 1.10.1.1 2012/03/13 11:48:35Z martin
+ * Revision 1.10 2012/01/12 09:57:04 martin
+ * Support selection of SCU port.
+ * Preliminary code to send PCPS_TIME via binary protocol.
+ * Debug code to test TX flushing problems under Windows.
+ * GPSXMPLE code disabled by default to build mbgevlog.
+ * Revision 1.9 2011/12/15 14:35:49Z martin
+ * Started to migrate to opaque stuctures.
+ * Made more functions static.
+ * Added code to show / clear GPS event log.
+ * Used this module for the mbgevlog program and disabled
+ * some GPSXMPLE code using preprocessor symbol.
* Revision 1.8 2011/04/15 13:04:14 martin
* Optionally poll for user capture events.
* Under Unix catch signals to terminate properly.
@@ -45,7 +65,7 @@
* Optionally loop and wait for automatic messages.
* Revision 1.6 2006/10/25 12:31:54Z martin
* Support serial I/O under Windows.
- * Check return codes of API functions and print associated
+ * Check return codes of API functions and print associated
* messages in case of error.
* Revision 1.5 2006/08/24 13:36:38Z martin
* Conditional support for network socket I/O.
@@ -62,7 +82,9 @@
**************************************************************************/
#include <mbgextio.h>
+#include <extiohlp.h>
#include <gpsutils.h>
+#include <pcpsdefs.h>
#include <stdio.h>
#include <stdlib.h>
@@ -82,16 +104,13 @@
#endif
+const char pname[] = "gpsxmple";
+const char pversion[] = "2.5";
+const char pdescr[] = "Example Program Accessing a Meinberg Device via Binary Protocol";
-// the variables below are required for communication
-MBG_MSG_BUFF rbuff;
-MBG_MSG_BUFF tbuff;
-MBG_MSG_CTL mctl =
-{
- { &rbuff, sizeof( rbuff ) },
- { &tbuff, sizeof( tbuff ) }
-};
+// the variables below are required for communication
+MBG_MSG_CTL *pmctlx;
// Define the minimum number of some resource types
@@ -101,9 +120,11 @@ MBG_MSG_CTL mctl =
// Define the maximum number of some resource types
// supported by the software
#define N_COM_MAX 4 // max. number of COM ports
-#define N_STR_TYPE_MAX 20 // max. number of string types
+// #define N_STR_TYPE_MAX 20 // max. number of string types
#define N_POUT_MAX 3 // max. number of programmable outputs
+#define N_SCU_PORT 2
+
#define IDLE_SLEEP_MS 200
@@ -124,8 +145,14 @@ MBG_MSG_CTL mctl =
static const char *target;
static int is_socket;
static int must_force_connection;
+
+static const char *str_new_date;
+static const char *str_new_time;
+
static int must_send_auto;
static int must_poll_ucap;
+
+static int must_clear_event_log;
static RECEIVER_INFO receiver_info;
static const char *feature_names[] = DEFAULT_GPS_FEATURE_NAMES;
@@ -144,6 +171,8 @@ static const char *default_target = DEFAULT_DEV_NAME;
#if _USE_SOCKET_IO
static const char *password;
+ static int scu_port;
+ static int must_set_scu_port;
#endif
@@ -155,6 +184,84 @@ static const char *dow_str[] =
+#if defined( DEBUG )
+
+static /*HDR*/
+void print_original_serial_settings( FILE *fp, SERIAL_IO_STATUS *p )
+{
+ #if defined( MBG_TGT_WIN32 )
+ DCB *dcb = &p->old_dcb;
+ COMMTIMEOUTS *tmo = &p->old_commtimeouts;
+ COMMPROP *prop = &p->comm_prop;
+
+ fprintf( fp, "Comm Properties:\n" );
+ fprintf( fp, " wPacketLength: %u\n", prop->wPacketLength );
+ fprintf( fp, " wPacketVersion: %u\n", prop->wPacketVersion );
+ fprintf( fp, " dwServiceMask: %u (%u)\n", prop->dwServiceMask, SP_SERIALCOMM );
+ fprintf( fp, " dwReserved1: %u\n", prop->dwReserved1 );
+ fprintf( fp, " dwMaxTxQueue: %u\n", prop->dwMaxTxQueue );
+ fprintf( fp, " dwMaxRxQueue: %u\n", prop->dwMaxRxQueue );
+ fprintf( fp, " dwMaxBaud: %u\n", prop->dwMaxBaud );
+ fprintf( fp, " dwProvSubType: %u\n", prop->dwProvSubType );
+ fprintf( fp, " dwProvCapabilities: %u\n", prop->dwProvCapabilities );
+ fprintf( fp, " dwSettableParams: 0x%2X\n", prop->dwSettableParams );
+ fprintf( fp, " dwSettableBaud: 0x%2X\n", prop->dwSettableBaud );
+ fprintf( fp, " wSettableData: 0x%2X\n", prop->wSettableData );
+ fprintf( fp, " wSettableStopParity: 0x%2X\n", prop->wSettableStopParity );
+ fprintf( fp, " dwCurrentTxQueue: %u\n", prop->dwCurrentTxQueue );
+ fprintf( fp, " dwCurrentRxQueue: %u\n", prop->dwCurrentRxQueue );
+ fprintf( fp, " dwProvSpec1: %u\n", prop->dwProvSpec1 );
+ fprintf( fp, " dwProvSpec2: %u\n", prop->dwProvSpec2 );
+ // fprintf( fp, " wcProvChar: %c\n", prop->wcProvChar[0] ); // wchar!!
+ fprintf( fp, "\n" );
+
+ fprintf( fp, "Original serial DCB settings:\n" );
+ fprintf( fp, " DCBlength: %u\n", dcb->DCBlength );
+ fprintf( fp, " BaudRate: %u\n", dcb->BaudRate );
+ fprintf( fp, " fBinary: %u\n", dcb->fBinary );
+ fprintf( fp, " fParity: %u\n", dcb->fParity );
+ fprintf( fp, " fOutxCtsFlow: %u\n", dcb->fOutxCtsFlow );
+ fprintf( fp, " fOutxDsrFlow: %u\n", dcb->fOutxDsrFlow );
+ fprintf( fp, " fDtrControl: %u\n", dcb->fDtrControl );
+ fprintf( fp, " fDsrSensitivity: %u\n", dcb->fDsrSensitivity );
+ fprintf( fp, " fTXContinueOnXoff: %u\n", dcb->fTXContinueOnXoff );
+ fprintf( fp, " fOutX: %u\n", dcb->fOutX );
+ fprintf( fp, " fInX: %u\n", dcb->fInX );
+ fprintf( fp, " fErrorChar: %u\n", dcb->fErrorChar );
+ fprintf( fp, " fNull: %u\n", dcb->fNull );
+ fprintf( fp, " fRtsControl: %u\n", dcb->fRtsControl );
+ fprintf( fp, " fAbortOnError: %u\n", dcb->fAbortOnError );
+ fprintf( fp, " fDummy2: %u\n", dcb->fDummy2 );
+ fprintf( fp, " wReserved: %u\n", dcb->wReserved );
+ fprintf( fp, " XonLim: %u\n", dcb->XonLim );
+ fprintf( fp, " XoffLim: %u\n", dcb->XoffLim );
+ fprintf( fp, " ByteSize: %u\n", dcb->ByteSize );
+ fprintf( fp, " Parity: %u\n", dcb->Parity );
+ fprintf( fp, " StopBits: %u\n", dcb->StopBits );
+ fprintf( fp, " XonChar: %u\n", dcb->XonChar );
+ fprintf( fp, " XoffChar: %u\n", dcb->XoffChar );
+ fprintf( fp, " ErrorChar: %u\n", dcb->ErrorChar );
+ fprintf( fp, " EofChar: %u\n", dcb->EofChar );
+ fprintf( fp, " EvtChar: %u\n", dcb->EvtChar );
+ fprintf( fp, " wReserved1: %u\n", dcb->wReserved1 );
+ fprintf( fp, "\n" );
+
+ fprintf( fp, "Original serial comm timeout settings:\n" );
+ fprintf( fp, " ReadIntervalTimeout: %u\n", tmo->ReadIntervalTimeout );
+ fprintf( fp, " ReadTotalTimeoutMultiplier: %u\n", tmo->ReadTotalTimeoutMultiplier );
+ fprintf( fp, " ReadTotalTimeoutConstant: %u\n", tmo->ReadTotalTimeoutConstant );
+ fprintf( fp, " WriteTotalTimeoutMultiplier: %u\n", tmo->WriteTotalTimeoutMultiplier );
+ fprintf( fp, " WriteTotalTimeoutConstant: %u\n", tmo->WriteTotalTimeoutConstant );
+ fprintf( fp, "\n" );
+
+ #endif
+
+} // print_original_serial_settings
+
+#endif // defined( DEBUG )
+
+
+
static /*HDR*/
void mbg_sleep_msec( long msec )
{
@@ -163,7 +270,7 @@ void mbg_sleep_msec( long msec )
#elif defined( MBG_TGT_WIN32 )
Sleep( msec );
#elif defined( MBG_TGT_DOS )
- delay( msec );
+ delay( (unsigned int) msec );
#endif
} // mbg_sleep_msec
@@ -171,6 +278,28 @@ void mbg_sleep_msec( long msec )
static /*HDR*/
+int set_scu_port( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, int port )
+{
+ // Yet this is preliminary/untested.
+ SCU_STAT_SETTINGS scu_stat_settings = { 0 };
+ int rc;
+
+ scu_stat_settings.epld_control_mask = MSK_EPLD_CNTL_ENA_SNMP | MSK_EPLD_CNTL_SEL_SNMP;
+
+ scu_stat_settings.epld_control_value = MSK_EPLD_CNTL_ENA_SNMP;
+
+ if ( port ) // else leave 0
+ scu_stat_settings.epld_control_value |= MSK_EPLD_CNTL_SEL_SNMP;
+
+ rc = mbgextio_xmt_msg( pmctl, p_addr, GPS_SCU_STAT, &scu_stat_settings, sizeof( scu_stat_settings ) );
+
+ return rc;
+
+} // set_scu_port
+
+
+
+static /*HDR*/
int check_rc( int rc )
{
const char *cp = NULL;
@@ -180,43 +309,31 @@ int check_rc( int rc )
switch ( rc )
{
- case TR_COMPLETE:
+ case MBG_SUCCESS:
cp = "Data received completely.";
break;
- case TR_RECEIVING:
- cp = "Received data not complete.";
- break;
-
- case TR_WAITING:
- cp = "Waiting for data.";
- break;
-
- case TR_TIMEOUT:
+ case MBG_ERR_TIMEOUT:
cp = "Timeout receiving data";
break;
- case TR_CSUM_HDR:
+ case MBG_ERR_HDR_CSUM:
cp = "Header checksum error in received data.";
break;
- case TR_CSUM_DATA:
+ case MBG_ERR_DATA_CSUM:
cp = "Data checksum error in received data.";
break;
- case TR_DECRYPTION:
+ case MBG_ERR_DECRYPT:
cp = "Failed to decrypt received data.";
break;
- case TR_OPEN_ERR:
- cp = "Failed to establish connection.";
- break;
-
- case TR_IO_ERR:
+ case MBG_ERR_IO:
cp = "I/O error receiving data";
break;
- case TR_AUTH_ERR:
+ case MBG_ERR_AUTH:
cp = "Authentication error";
break;
@@ -233,7 +350,7 @@ int check_rc( int rc )
-/*HDR*/
+static /*HDR*/
void sprint_tm( char *s, TM_GPS *tm, int print_frac )
{
int n = 0;
@@ -258,7 +375,7 @@ void sprint_tm( char *s, TM_GPS *tm, int print_frac )
-/*HDR*/
+static /*HDR*/
void sprint_lla( char *s, LLA lla )
{
static const double r2d = 180 / PI;
@@ -273,7 +390,7 @@ void sprint_lla( char *s, LLA lla )
-/*HDR*/
+static /*HDR*/
void print_stat_info( STAT_INFO *p )
{
const char *cp;
@@ -304,7 +421,7 @@ void print_stat_info( STAT_INFO *p )
-/*HDR*/
+static /*HDR*/
void print_time( TTM *p )
{
static const char *s[] =
@@ -333,7 +450,7 @@ void check_receiver_info( RECEIVER_INFO *p, int log )
const char *fmt_min = "Number of %s from device (%u) is less than number required (%u)";
const char *fmt_max = "Number of %s from device (%u) exceeds number supported by the software (%u)";
- // Check if numbers of resources provided by the device
+ // Check if numbers of resources provided by the device
// don't exceed numbers of resources supported by the software
#define _check_min( _n, _min, _info ) \
@@ -373,15 +490,15 @@ void check_receiver_info( RECEIVER_INFO *p, int log )
_check_min( p->n_com_ports, N_COM_MIN, "COM ports" );
_check_max( p->n_com_ports, N_COM_MAX, "COM ports" );
- _check_max( p->n_str_type, N_STR_TYPE_MAX, "string types" );
+ _check_max( p->n_str_type, MAX_PARM_PORT, "string types" );
_check_max( p->n_prg_out, N_POUT_MAX, "progr. outputs" );
} // check_receiver_info
-/*HDR*/
-int get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p )
+static /*HDR*/
+int get_receiver_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, RECEIVER_INFO *p )
{
int rc;
int i;
@@ -389,13 +506,13 @@ int get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p )
printf( fmt, "Receiver info:" );
- rc = mbgextio_get_receiver_info( &mctl, p );
+ rc = mbgextio_setup_receiver_info( pmctl, p_addr, p );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
- if ( rc == TR_TIMEOUT )
+ if ( rc == MBG_ERR_TIMEOUT )
{
printf( "If you are using a very old GPS model then reading the\n"
"receiver info structure may not be supported.\n" );
@@ -457,17 +574,17 @@ int get_receiver_info( MBG_MSG_CTL *pmctl, RECEIVER_INFO *p )
-/*HDR*/
-void show_sw_rev( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_sw_rev( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
SW_REV sw_rev;
int rc;
printf( fmt, "Software Revision:" );
- rc = mbgextio_get_sw_rev( pmctl, &sw_rev );
+ rc = mbgextio_get_sw_rev( pmctl, p_addr, &sw_rev );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -483,17 +600,17 @@ void show_sw_rev( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_bvar_stat( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_bvar_stat( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
BVAR_STAT bvar_stat;
int rc;
printf( fmt, "BVAR status:" );
- rc = mbgextio_get_bvar_stat( pmctl, &bvar_stat );
+ rc = mbgextio_get_bvar_stat( pmctl, p_addr, &bvar_stat );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -505,17 +622,17 @@ void show_bvar_stat( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_stat_info( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_stat_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
STAT_INFO stat_info;
int rc;
printf( fmt, "Receiver status:" );
- rc = mbgextio_get_stat_info( pmctl, &stat_info );
+ rc = mbgextio_get_stat_info( pmctl, p_addr, &stat_info );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -527,17 +644,17 @@ void show_stat_info( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_pos( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_pos( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
LLA lla; // Position as logitude, latitude, altitude
int rc;
printf( fmt, "Receiver Position:" );
- rc = mbgextio_get_pos_lla( pmctl, lla );
+ rc = mbgextio_get_pos_lla( pmctl, p_addr, lla );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -550,17 +667,17 @@ void show_pos( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_tzdl( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_tzdl( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
TZDL tzdl;
int rc;
printf( fmt, "Time Zone:" );
- rc = mbgextio_get_tzdl( pmctl, &tzdl );
+ rc = mbgextio_get_tzdl( pmctl, p_addr, &tzdl );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -603,8 +720,8 @@ void show_tzdl( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void show_synth( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_synth( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
SYNTH synth;
double f;
@@ -612,9 +729,9 @@ void show_synth( MBG_MSG_CTL *pmctl )
printf( fmt, "Synthesizer:" );
- rc = mbgextio_get_synth( pmctl, &synth );
+ rc = mbgextio_get_synth( pmctl, p_addr, &synth );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -629,7 +746,7 @@ void show_synth( MBG_MSG_CTL *pmctl )
if ( synth.range == 0 )
{
- // freq field is in 0.1 Hz units, so if
+ // freq field is in 0.1 Hz units, so if
// the range is 0 we must divide by 10
// to yield the correct result
f = (double) synth.freq / 10.0;
@@ -656,8 +773,8 @@ void show_synth( MBG_MSG_CTL *pmctl )
-/*HDR*/
-void set_synth( void )
+static /*HDR*/
+void set_synth( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
SYNTH synth = { 0 };
int rc;
@@ -673,10 +790,10 @@ void set_synth( void )
// The effective frequency is: (freq/10)*(10^^range)
synth.freq = 1000; // base frequency value in 1/10 Hz Units
- synth.range = 1; // multiplier 10^^range
+ synth.range = 1; // multiplier 10^^range
synth.phase = 1800; // phase in 1/10 degrees
- rc = mbgextio_set_synth( &mctl, &synth );
+ rc = mbgextio_set_synth( pmctl, p_addr, &synth );
if ( rc < 0 )
printf( "Failed to set synthesizer output, code: %i\n", rc );
@@ -689,8 +806,8 @@ void set_synth( void )
// set programmable output mode
-/*HDR*/
-void set_pout_mode( void )
+static /*HDR*/
+void set_pout_mode( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
POUT_INFO_IDX pout_info_idx;
POUT_SETTINGS pout_settings = { 0 }; // new settings, init'd to 0
@@ -712,12 +829,12 @@ void set_pout_mode( void )
return;
}
- // OK, now get the current settings, and see which modes are
+ // OK, now get the current settings, and see which modes are
// supported by the selected programmable pulse output.
- rc = mbgextio_get_pout_info_idx( &mctl, &pout_info_idx, pout_idx );
+ rc = mbgextio_get_pout_info_idx( pmctl, p_addr, &pout_info_idx, pout_idx );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -740,9 +857,9 @@ void set_pout_mode( void )
pout_settings.tm[0].on.t.hour = 0;
pout_settings.tm[0].on.t.min = 20;
pout_settings.tm[0].on.t.sec = 0;
- pout_settings.pulse_len = 30; // 10 millisecond units
+// pout_settings.pulse_len = 30; // 10 millisecond units
- rc = mbgextio_set_pout_settings_idx( &mctl, &pout_settings, pout_idx );
+ rc = mbgextio_set_pout_settings_idx( pmctl, p_addr, &pout_settings, pout_idx );
if ( rc < 0 )
printf( "Failed to set programmable pulse output mode, code: %i\n", rc );
@@ -753,7 +870,9 @@ void set_pout_mode( void )
-/*HDR*/
+#if 0 //##++++++++++++++++
+
+static /*HDR*/
void show_port_parm( MBG_MSG_CTL *pmctl )
{
PORT_PARM port_parm;
@@ -763,7 +882,7 @@ void show_port_parm( MBG_MSG_CTL *pmctl )
rc = mbgextio_get_port_parm( pmctl, &port_parm );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
return;
@@ -795,75 +914,45 @@ void show_port_parm( MBG_MSG_CTL *pmctl )
} /* show_port_parm */
+#endif
+
-/*HDR*/
-void show_port_settings( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_port_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
const char *mode_names[N_STR_MODE] = DEFAULT_ENG_MODE_NAMES;
- STR_TYPE_INFO sti[N_STR_TYPE_MAX];
- STR_TYPE_INFO_IDX stii;
- PORT_INFO_IDX pii;
- PORT_SETTINGS *p;
+ RECEIVER_PORT_CFG rpcfg;
int rc;
int i;
printf( fmt, "Serial ports:" );
- if ( receiver_info.model_code == GPS_MODEL_UNKNOWN )
+ rc = mbgextio_get_serial_settings( pmctl, p_addr, &rpcfg, &receiver_info );
+
+ if ( rc != MBG_SUCCESS )
{
- // This may be an old GPS model which does not provide
- // a receiver info structure.
- show_port_parm( pmctl );
+ check_rc( rc );
return;
}
+
// The number of serial ports and time string formats supported
// by this device is specified in the receiver info structure.
- // Read time string information
+#if 0 //##++ TODO: possibly print supported string types
for ( i = 0; i < receiver_info.n_str_type; i++ )
{
- rc = mbgextio_get_str_type_info_idx( pmctl, &stii, (uint16_t) i );
-
- if ( rc != TR_COMPLETE )
- {
- check_rc( rc );
- return;
- }
-
- if ( stii.idx != i )
- {
- printf( "** Info for string type %i requested, but for %i received.\n",
- stii.idx, i );
- return;
- }
-
sti[i] = stii.str_type_info;
}
+#endif
-
- // Read and print port settings
+ // print port settings
for ( i = 0; ; )
{
- rc = mbgextio_get_port_info_idx( pmctl, &pii, (uint16_t) i );
-
- if ( rc != TR_COMPLETE )
- {
- check_rc( rc );
- return;
- }
-
- if ( pii.idx != i )
- {
- printf( "** Info for port %i requested, but for %i received.\n",
- pii.idx, i );
- return;
- }
-
- p = &pii.port_info.port_settings;
+ PORT_SETTINGS *p = &rpcfg.pii[i].port_info.port_settings;
printf( "COM%i: %5lu Baud, %s",
i,
@@ -874,13 +963,13 @@ void show_port_settings( MBG_MSG_CTL *pmctl )
// Make sure indices received from the device do not exceed
// maximum numbers supported by this program.
- if ( p->str_type >= N_STR_TYPE_MAX )
+ if ( p->str_type >= MAX_PARM_STR_TYPE )
printf( " (string type exceeds max)" );
else
if ( p->mode >= N_STR_MODE )
printf( " (string mode exceeds max)" );
else
- printf( ", \"%s\" string %s", sti[p->str_type].long_name, mode_names[p->mode] );
+ printf( ", \"%s\" string %s", rpcfg.stii[p->str_type].str_type_info.long_name, mode_names[p->mode] );
printf( "\n" );
@@ -894,8 +983,68 @@ void show_port_settings( MBG_MSG_CTL *pmctl )
+static /*HDR*/
+void show_event_log( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
+{
+ static const char *evt_id_names[N_MBG_EVT_ID] = MBG_EVT_ID_NAMES_ENG;
+
+ MBG_NUM_EVT_LOG_ENTRIES log_entries;
+ MBG_EVT_LOG_ENTRY evt_log_entry;
+ time_t t;
+ struct tm *mytime;
+ int n_evt = 0;
+ int event_id = -1;
+
+ if ( mbgextio_get_num_evt_log_entries( pmctl, p_addr, &log_entries ) )
+ printf( "\nEvent Log (%i/%i entries used):\n", log_entries.used, log_entries.max );
+ else
+ {
+ printf( "Failed to read event log entries\n" );
+ return;
+ }
+
+ if ( mbgextio_get_first_evt_log_entry( pmctl, p_addr, &evt_log_entry ) )
+ {
+ unsigned int i;
+
+ for ( i = 0; i < log_entries.max; i++ )
+ {
+ event_id = _mbg_get_evt_id( evt_log_entry.code );
+
+ if ( event_id == 0 )
+ break;
+
+ n_evt++;
+
+ t = evt_log_entry.time;
+ mytime = gmtime( &t );
+
+ printf( "%04i-%02i-%02i %02i:%02i:%02i ",
+ mytime->tm_year + 1900, mytime->tm_mon + 1, mytime->tm_mday,
+ mytime->tm_hour, mytime->tm_min, mytime->tm_sec );
+
+ if ( event_id < N_MBG_EVT_ID )
+ printf( "%s\n", evt_id_names[event_id] );
+ else
+ printf( "Unknown event ID %u", event_id );
+
+ mbgextio_get_next_evt_log_entry( pmctl, p_addr, &evt_log_entry );
+ }
+ }
+ else
+ fprintf( stderr, "** ERROR: failed to read event log\n" );
+
+ if ( n_evt == 0 )
+ fprintf( stderr, "event log is empty\n" );
+
+ printf( "\n" );
+
+} // show_event_log
+
+
+
/*HDR*/ static
-int check_ucap_poll( void )
+int check_ucap_poll( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr )
{
int rc;
@@ -906,9 +1055,9 @@ int check_ucap_poll( void )
{
TTM ttm;
memset( &ttm, 0, sizeof( ttm ) );
- rc = mbgextio_get_ucap( &mctl, &ttm );
+ rc = mbgextio_get_ucap( pmctl, p_addr, &ttm );
- if ( _ttm_time_is_avail( &ttm ) )
+ if ( ( rc == MBG_SUCCESS ) && _ttm_time_is_avail( &ttm ) )
{
printf( "CAP%i: %04u-%02u-%02u %02u:%02u:%02u.%07u",
ttm.channel, ttm.tm.year, ttm.tm.month, ttm.tm.mday,
@@ -931,10 +1080,219 @@ int check_ucap_poll( void )
+static /*HDR*/
+int set_date_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr,
+ const char *str_new_date, const char *str_new_time )
+{
+ PCPS_TIME_UNION u = { { 0 } };
+ TTM ttm = { 0 };
+ unsigned int year = 0;
+ unsigned int month = 0;
+ unsigned int mday = 0;
+ unsigned int hour = 0;
+ unsigned int min = 0;
+ unsigned int sec = 0;
+ unsigned int sec100 = 0;
+ int rc;
+
+ // Either a date string, a time string, or both
+ // may have been passed to this function.
+ // If either of them is NULL read the current date/time
+ // as default values.
+ if ( str_new_date == NULL || str_new_time == NULL )
+ {
+#if 1 //##+++++++++++++
+ return -1;
+#else
+ rc = mbg_get_time( dh, &u.t );
+
+ if ( mbg_ioctl_err( rc, "mbg_get_time" ) )
+ return rc;
+#endif
+ }
+
+
+ if ( str_new_date )
+ {
+ rc = sscanf( str_new_date, "%u-%u-%u", &year, &month, &mday );
+
+ if ( ( rc < 3 )
+ || ( month < 1 ) || ( month > 12 )
+ || ( mday < 1 ) || ( mday > 31 ) )
+ {
+ printf( "** Invalid date: %04u-%02u-%02u\n", year, month, mday );
+ return MBG_ERR_CFG;
+ }
+ }
+
+
+ if ( str_new_time )
+ {
+ rc = sscanf( str_new_time, "%u:%u:%u.%u", &hour, &min, &sec, &sec100 );
+
+ if ( ( rc < 2 ) // at least hours and minutes are required
+ || ( hour > 23 )
+ || ( min > 59 )
+ || ( sec > 60 )
+ || ( sec100 > 99 ) )
+ {
+ printf( "** Invalid time: %02u:%02u:%02u.%02u\n", hour, min, sec, sec100 );
+ return MBG_ERR_CFG;
+ }
+ }
+
+#if 0 //##++++++++++++++++
+ // GPS and non-GPS cards require different API calls which use
+ // different structures to set the on-board date and time,
+ // so we have to distinguish.
+
+ if ( _pcps_is_gps( p_dev ) ) // is a GPS card
+ {
+ ttm.channel = -1;
+
+ if ( str_new_date ) // new date
+ {
+ ttm.tm.year = year;
+ ttm.tm.month = month;
+ ttm.tm.mday = mday;
+ }
+ else // copy current date as default
+ {
+ ttm.tm.year = u.t.year + 2000;
+ ttm.tm.month = u.t.month;
+ ttm.tm.mday = u.t.mday;
+ }
+
+ if ( str_new_time ) // new time
+ {
+ ttm.tm.hour = hour;
+ ttm.tm.min = min;
+ ttm.tm.sec = sec;
+ ttm.tm.frac = sec100;
+ }
+ else // copy current time as default
+ {
+ ttm.tm.hour = u.t.hour;
+ ttm.tm.min = u.t.min;
+ ttm.tm.sec = u.t.sec;
+ ttm.tm.frac = u.t.sec100;
+ }
+
+ ttm.tm.frac *= 100000; // fracs are in 100 ns units
+
+ #if 0
+ // Existing versions of the GPS cards just take
+ // TTM.tm as local time without accounting for
+ // the status flags, or UTC offset.
+ // Instead, the TTM::tm time is converted on-board
+ // to UTC depending on the local TZDL configuration.
+ // This works if the system time and the
+ ttm.tm.offs_from_utc = 7200;
+ ttm.tm.status |= TM_UTC | TM_LOCAL;
+ ttm.tm.status |= TM_DL_ENB;
+ #endif
+
+ rc = mbg_set_gps_time( dh, &ttm );
+
+ if ( mbg_ioctl_err( rc, "mbg_set_gps_time" ) )
+ return rc;
+ }
+ else // is not a GPS card
+ {
+ if ( str_new_date ) // new date
+ {
+ // determine the day-of-week for the given date
+ struct tm tm = { 0 };
+
+ tm.tm_year = year - 1900;
+ tm.tm_mon = month - 1;
+ tm.tm_mday = mday;
+ tm.tm_hour = 12;
+ tm.tm_isdst = -1;
+ mktime( &tm );
+
+ u.stime.year = year % 100;
+ u.stime.month = month;
+ u.stime.mday = mday;
+ u.stime.wday = _wday_sun06_to_mon17( tm.tm_wday );
+ }
+
+ if ( str_new_time ) // new time
+ {
+ u.stime.hour = hour;
+ u.stime.min = min;
+ u.stime.sec = sec;
+ u.stime.sec100 = sec100;
+ }
+
+ if ( u.stime.wday == 0 )
+ u.stime.wday = 1; // dummy
+
+ rc = mbg_set_time( dh, &u.stime );
+
+ if ( mbg_ioctl_err( rc, "mbg_set_time" ) )
+ return rc;
+ }
+#else
+ {
+ //
+ PCPS_TIME t = { 0 };
+
+ // determine the day-of-week for the given date
+ struct tm tm = { 0 };
+
+ tm.tm_year = year - 1900;
+ tm.tm_mon = month - 1;
+ tm.tm_mday = mday;
+ tm.tm_hour = 12;
+ tm.tm_isdst = -1;
+ mktime( &tm );
+
+ t.year = year % 100;
+ t.month = month;
+ t.mday = mday;
+ t.wday = ( tm.tm_wday == 0 ) ? 7 : tm.tm_wday;
+ t.hour = hour;
+ t.min = min;
+ t.sec = sec;
+ t.sec100 = sec100;
+
+#if 0 //##+++++++++++++++++
+ {
+ MBG_PORT_HANDLE port_handle = pmctl->st.serio.port_handle;
+ const char tmp[] = "\xFF\xFF\xFF\xFF";
+
+ // Note: encrypted msgs over serial are not yet supported.
+
+ // _mbgserio_write( port_handle, &tmp, strlen( tmp ) );
+ // _swab_pcps_time( &t );
+ rc = mbgextio_xmt_msg( pmctl, PZF_PCPS_TIME, &t, sizeof( t ) );
+
+ // _mbgserio_write( port_handle, &tmp, strlen( tmp ) );
+ }
+#else
+ // _swab_pcps_time( &t );
+ rc = mbgextio_xmt_msg( pmctl, p_addr, PZF_PCPS_TIME, &t, sizeof( t ) );
+#endif
+
+ if ( rc < 0 )
+ printf( "Failed to set date/time, rc: %i\n", rc );
+ }
+
+#endif
+ printf( "\n\nDevice date/time have been set to %04u-%02u-%02u %02u:%02u:%02u.%02u\n\n",
+ year, month, mday, hour, min, sec, sec100 );
+
+ return MBG_SUCCESS;
+
+} // set_date_time
+
+
+
/*HDR*/ static
void exit_close_connection( void )
{
- mbgextio_close_connection( &mctl );
+ mbgextio_close_connection( &pmctlx );
printf( "Connection closed.\n" );
printf( "\n" );
@@ -946,7 +1304,7 @@ void exit_close_connection( void )
/*HDR*/ static
void exit_auto_off( void )
{
- mbgextio_xmt_cmd( &mctl, GPS_AUTO_OFF );
+ mbgextio_xmt_cmd( pmctlx, NULL, GPS_AUTO_OFF ); //##++++++ TODO: NULL?
#if defined( DEBUG )
printf( "AUTO mode turned off.\n" );
@@ -957,9 +1315,9 @@ void exit_auto_off( void )
/*HDR*/ static
-void set_auto_mode( void )
+void set_auto_mode( MBG_MSG_CTL *pmctl )
{
- mbgextio_xmt_cmd( &mctl, GPS_AUTO_ON );
+ mbgextio_xmt_cmd( pmctl, NULL, GPS_AUTO_ON ); //##++++++ TODO: NULL?
#if defined( DEBUG )
printf( "AUTO mode turned on.\n" );
@@ -998,32 +1356,32 @@ int check_command_line( int argc, char *argv[] )
for ( i = 1; i < argc; i++ )
{
- if ( strcmp( argv[i], "-a" ) == 0 )
+ if ( strcmp( argv[i], "-a" ) == 0 )
{
must_send_auto = 1;
continue;
}
- if ( strcmp( argv[i], "-u" ) == 0 )
+ if ( strcmp( argv[i], "-u" ) == 0 )
{
must_poll_ucap = 1;
continue;
}
- if ( strcmp( argv[i], "-?" ) == 0 )
+ if ( strcmp( argv[i], "-?" ) == 0 )
{
must_print_usage = 1;
continue;
}
- if ( strcmp( argv[i], "-h" ) == 0 )
+ if ( strcmp( argv[i], "-h" ) == 0 )
{
must_print_usage = 1;
continue;
}
#if _USE_SOCKET_IO
- if ( strcmp( argv[i], "-n" ) == 0 )
+ if ( strcmp( argv[i], "-n" ) == 0 )
{
is_socket = 1;
continue;
@@ -1032,7 +1390,7 @@ int check_command_line( int argc, char *argv[] )
#if _USE_SOCKET_IO
if ( strcmp( argv[i], "-p" ) == 0 )
- {
+ {
if ( ++i < argc )
password = argv[i];
else
@@ -1044,7 +1402,7 @@ int check_command_line( int argc, char *argv[] )
#if _USE_SERIAL_IO
if ( strcmp( argv[i], "-b" ) == 0 )
- {
+ {
if ( ++i < argc )
baudrate = strtoul( argv[i], NULL, 10 );
else
@@ -1056,7 +1414,7 @@ int check_command_line( int argc, char *argv[] )
#if _USE_SERIAL_IO
if ( strcmp( argv[i], "-f" ) == 0 )
- {
+ {
if ( ++i < argc )
framing = argv[i];
else
@@ -1074,6 +1432,52 @@ int check_command_line( int argc, char *argv[] )
}
#endif
+ if ( strcmp( argv[i], "-c" ) == 0 )
+ {
+ must_clear_event_log = 1;
+ continue;
+ }
+
+
+ #if _USE_SOCKET_IO
+ if ( strcmp( argv[i], "-P" ) == 0 )
+ {
+ if ( ++i < argc )
+ {
+ scu_port = atoi( argv[i] );
+
+ if ( ( scu_port >= 0 ) && ( scu_port < N_SCU_PORT ) )
+ {
+ must_set_scu_port = 1;
+ continue;
+ }
+ }
+
+ fprintf( stderr, "** invalid parameter for \"-P\"\n" );
+ must_print_usage = 1;
+ continue;
+ }
+ #endif
+
+
+ if ( strcmp( argv[i], "-d" ) == 0 )
+ {
+ if ( ++i < argc )
+ str_new_date = argv[i];
+
+ continue;
+ }
+
+
+ if ( strcmp( argv[i], "-t" ) == 0 )
+ {
+ if ( ++i < argc )
+ str_new_time = argv[i];
+
+ continue;
+ }
+
+
if ( argv[i][0] != '-' )
target = argv[i];
else
@@ -1112,6 +1516,10 @@ int check_command_line( int argc, char *argv[] )
" -f xxx Serial port framing, default: %s\n"
" -F Force serial connection to %lu/%s\n"
#endif
+ " -c clear event log (if supported)\n"
+ #if _USE_SOCKET_IO
+ " -P scu_port Select clock at SCU port 0 or 1 (only with SCU over LAN)\n"
+ #endif
"\n"
"Example:\n"
#if _USE_SERIAL_IO
@@ -1148,9 +1556,10 @@ int check_command_line( int argc, char *argv[] )
int main( int argc, char *argv[] )
{
+ XBP_ADDR *p_addr = NULL;
int rc;
- printf( "\n\n\nExample Program Accessing a Meinberg Device via Binary Protocol\n" );
+ fprintf( stderr, "\n\n\n%s v%s %s\n", pname, pversion, pdescr );
baudrate = default_baudrate;
framing = default_framing;
@@ -1166,16 +1575,12 @@ int main( int argc, char *argv[] )
#if _USE_SOCKET_IO
if ( is_socket )
{
- rc = mbgextio_open_socket( &mctl, target, password );
+ rc = mbgextio_open_socket( target, &pmctlx, password );
- if ( rc < 0 )
+ if ( rc != MBG_SUCCESS )
{
- if ( rc == TR_OPEN_ERR )
- perror( "Error connecting" );
- else
- fprintf( stderr, "mbgextio_open_socket returned %i", rc );
-
- exit( 1 );
+ printf( "Failed to connect to %s, rc: %i\n", target, rc );
+ return 1; // Error ...
}
goto doit;
@@ -1186,21 +1591,25 @@ int main( int argc, char *argv[] )
if ( must_force_connection )
{
printf( "Trying to force connection to 19200/8N1 ..." );
- mbgextio_force_connection( target );
+ mbgextio_force_conn_serial( target );
printf( "\n" );
baudrate = default_baudrate;
framing = default_framing;
}
- rc = mbgextio_open_serial( &mctl, target, baudrate, framing );
+ rc = mbgextio_open_serial( target, &pmctlx, baudrate, framing );
- if ( rc < 0 )
+ if ( rc != MBG_SUCCESS )
{
printf( "Error using port %s.\n", target );
- return -1; // Error ...
+ return 1; // Error ...
}
+ #if defined( DEBUG )
+ print_original_serial_settings( stdout, &pmctlx->st.serio );
+ #endif
+
printf( " (Using %s with %li baud, %s)\n\n",
target, (long) baudrate, framing );
@@ -1218,23 +1627,77 @@ doit:
// now start communication with whichever device has been opened above:
- get_receiver_info( &mctl, &receiver_info );
+ // TODO: make sure xbp is supported.
+ mbgextio_setup_xbp_node_list( pmctlx, p_addr );
+
+ #if _USE_SOCKET_IO
+ if ( must_set_scu_port )
+ {
+ int rc = set_scu_port( pmctlx, p_addr, scu_port );
+
+ if ( rc == MBG_SUCCESS )
+ printf( "\nSCU switched to port %i (clock #%i)\n\n",
+ scu_port, scu_port + 1 );
+ else
+ printf( "\nFailed to switch SCU to port %i (clock #%i)\n\n",
+ scu_port, scu_port + 1 );
+ }
+ #endif
+
+ if ( must_send_auto )
+ set_auto_mode( pmctlx );
+
+
+#if 1 //##+++++++++++++
+ get_receiver_info( pmctlx, p_addr, &receiver_info );
+#else
+ printf( "\n(Skipped getting receiver info)\n\n" );
+#endif
+
+ if ( str_new_date && str_new_time )
+ {
+ set_date_time( pmctlx, p_addr, str_new_date, str_new_time );
+ return 0;
+ }
+
check_receiver_info( &receiver_info, 1 );
/* display system specific values */
- show_sw_rev( &mctl );
- show_bvar_stat( &mctl );
- show_stat_info( &mctl );
- show_pos( &mctl );
- show_tzdl( &mctl );
- show_port_settings( &mctl );
- show_synth( &mctl );
+ show_sw_rev( pmctlx, p_addr );
+ show_bvar_stat( pmctlx, p_addr );
+ show_stat_info( pmctlx, p_addr );
+ show_pos( pmctlx, p_addr );
+ show_tzdl( pmctlx, p_addr );
+ show_port_settings( pmctlx, p_addr );
+ show_synth( pmctlx, p_addr );
+
+ if ( must_clear_event_log )
+ {
+ if ( receiver_info.features & GPS_HAS_EVT_LOG )
+ {
+ int ret = mbgextio_clr_evt_log( pmctlx, p_addr );
+
+ if ( ret != 0 )
+ fprintf( stderr, "Failed to clear event log, rc: %i\n", ret );
+ else
+ fprintf( stderr, "event log has been cleared\n" );
+ }
+ else
+ fprintf( stderr, "This device does not support an event log\n" );
+ }
+
+ if ( receiver_info.features & GPS_HAS_EVT_LOG )
+ show_event_log( pmctlx, p_addr );
+ else
+ if ( !must_clear_event_log )
+ printf( "** Warning: this device does not support an event log!\n" );
+
// set_synth();
// set_pout_mode();
if ( must_poll_ucap )
- return check_ucap_poll();
+ return check_ucap_poll( pmctlx, p_addr );
if ( !must_send_auto )
return 0;
@@ -1245,10 +1708,10 @@ doit:
// We will start to wait for automatically transmitted messages
// which require a longer timeout than we have used by default
// to wait for replies to dedicated request messages.
- mbgextio_set_char_rcv_timeout( &mctl, 2000 ); // [msec]
- mbgextio_set_msg_rcv_timeout( &mctl, 2000 ); // [msec]
+ mbgextio_set_char_rcv_timeout( pmctlx, 2000 ); // [msec]
+ mbgextio_set_msg_rcv_timeout( pmctlx, 2000 ); // [msec]
- set_auto_mode();
+ set_auto_mode( pmctlx );
do
{
@@ -1256,17 +1719,17 @@ doit:
MSG_DATA *p;
- rc = mbgextio_rcv_msg( &mctl, -1 );
+ rc = mbgextio_rcv_msg( pmctlx, p_addr, -1 );
- if ( rc != TR_COMPLETE )
+ if ( rc != MBG_SUCCESS )
{
check_rc( rc );
break;
}
- mbgextio_xmt_cmd( &mctl, GPS_AUTO_ON );
+ mbgextio_xmt_cmd( pmctlx, p_addr, GPS_AUTO_ON );
- pmb = mctl.rcv.pmb;
+ pmb = pmctlx->rcv.pmb;
p = &pmb->u.msg_data;
switch ( pmb->hdr.cmd )
@@ -1276,9 +1739,9 @@ doit:
if ( p->ttm.channel == -1 )
{
- mbgextio_xmt_cmd( &mctl, GPS_AUTO_ON );
- mbgextio_xmt_cmd( &mctl, GPS_STAT_INFO );
- mbgextio_xmt_cmd( &mctl, GPS_UCAP );
+ mbgextio_xmt_cmd( pmctlx, p_addr, GPS_AUTO_ON );
+ mbgextio_xmt_cmd( pmctlx, p_addr, GPS_STAT_INFO );
+ mbgextio_xmt_cmd( pmctlx, p_addr, GPS_UCAP );
}
break;