diff options
author | Martin Burnicki <martin.burnicki@meinberg.de> | 2017-04-12 12:00:00 +0200 |
---|---|---|
committer | Martin Burnicki <martin.burnicki@meinberg.de> | 2017-04-12 12:00:00 +0200 |
commit | 495354cece98f393292716f0dd396d635aac8875 (patch) | |
tree | df945d9b43e7f196067c064d5f9a98d65ee1274b | |
parent | 5b8da0b6113840a19166272b2046f1e920e91f51 (diff) | |
download | gpsxmple-495354cece98f393292716f0dd396d635aac8875.tar.gz gpsxmple-495354cece98f393292716f0dd396d635aac8875.zip |
Feature and API updatesgpsxmple-2.7-dos-win
Device open function now read the RECEIVER_INFO and store it inside the
opaque MBG_MSG_CTL structure. As a consequence, the API calls that check
for specific features could be refactored and simplified.
mbgextio_get_receiver_info_addr() can be used to retrieve the address of
the RECEIVER_INFO structure from the MBG_MSG_CTL structure associated
with a device.
Use new inline functions mbg_rc_is_error() and mbg_rc_is_success()
to check return codes.
Use mbg_strerror() to have common error messages.
Update mbglib functions to provide new functions and
make do_connect_serial() more fault tolerant.
Display PTP state, if supported.
Fix compiler warnings.
42 files changed, 41040 insertions, 4290 deletions
diff --git a/dos/gpsxmple.prj b/dos/gpsxmple.prj Binary files differindex fd543dc..7b4b2ba 100644 --- a/dos/gpsxmple.prj +++ b/dos/gpsxmple.prj @@ -1,28 +1,24 @@ /************************************************************************** * - * $Id: gpsxmple.c 1.10.1.8 2015/07/25 15:28:12Z martin TEST $ - * $Name: GPSXMPLE_2_5 $ + * $Id: gpsxmple.c 1.10.1.11 2017/04/11 13:55:50Z martin TEST $ + * $Name: GPSXMPLE_2_7 $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * * Description: * Sample program demonstrating how to access Meinberg devices - * using the serial binary data protocol. + * using the binary data protocol. * * Depending on the target operating system this program works * either via serial port (the default) or via a network socket - * connection. - * - * Other modules needed to build the executable: - * mbgextio.c, mbgserio.c, gpsserio.c, gpsutils.c - * optionally aes128.c, if network socket I/O is used + * connection, or via USB. * * Supported target environments: - * Windows / VC6 (serial and socket) - * Linux / gcc (serial and socket) - * QNX 6.x / gcc (socket only) - * DOS / BC3.1 (serial only) + * Windows / VC6 (serial and socket) + * Linux / gcc or clang (serial, socket, USB) + * QNX 6.x / gcc (socket only) + * DOS / BC3.1 (serial only) * * For makefiles and build environment setups check the * corresponding subdirectories. @@ -32,7 +28,18 @@ * * ----------------------------------------------------------------------- * $Log: gpsxmple.c $ - * Revision 1.10.1.8 2015/07/25 15:28:12Z martin + * Revision 1.10.1.11 2017/04/11 13:55:50Z martin + * New version code 2.7. + * Made do_connect_serial() more fault tolerant. + * Fixed build under Windows. + * Removed obsolete code. + * Cleanup. + * Revision 1.10.1.10 2017/04/10 13:31:06Z martin + * Fixed some compiler warnings. + * Revision 1.10.1.9 2017/04/05 16:08:24Z martin + * Adapted to new library functions. + * Display PTP state, if supported. + * 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 @@ -85,6 +92,9 @@ #include <extiohlp.h> #include <gpsutils.h> #include <pcpsdefs.h> +#include <str_util.h> +#include <lan_util.h> +#include <timeutil.h> #include <stdio.h> #include <stdlib.h> @@ -105,26 +115,24 @@ const char pname[] = "gpsxmple"; -const char pversion[] = "2.5"; +const char pversion[] = "2.7"; const char pdescr[] = "Example Program Accessing a Meinberg Device via Binary Protocol"; // the variables below are required for communication -MBG_MSG_CTL *pmctlx; +MBG_MSG_CTL *msg_ctl; + + +#define _DO_SET_TIME 0 // not yet ported // Define the minimum number of some resource types // required by the software #define N_COM_MIN 1 // minimum number of COM ports -// 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_POUT_MAX 3 // max. number of programmable outputs - #define N_SCU_PORT 2 + #define IDLE_SLEEP_MS 200 @@ -144,30 +152,23 @@ MBG_MSG_CTL *pmctlx; static const char *target; static int is_socket; -static int must_force_connection; + +static BAUD_RATE baudrate; +static const char *framing = MBG_DEFAULT_FRAMING; + 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; - -#if !defined( DEFAULT_DEV_NAME ) - #define DEFAULT_DEV_NAME NULL -#endif +static int must_set_synth; +static int must_set_pout_mode; +static int must_force_connection; +static int verbose; -static const char *default_target = DEFAULT_DEV_NAME; - -#if _USE_SERIAL_IO - static uint32_t default_baudrate = 19200L; - static const char *default_framing = "8N1"; - static uint32_t baudrate; - static const char *framing; -#endif +static const char *default_target = DEFAULT_SERIAL_DEVICE_NAME; #if _USE_SOCKET_IO static const char *password; @@ -187,12 +188,12 @@ static const char *dow_str[] = #if defined( DEBUG ) static /*HDR*/ -void print_original_serial_settings( FILE *fp, SERIAL_IO_STATUS *p ) +void print_original_serial_settings( FILE *fp, const MBGSERIO_DEV *p ) { #if defined( MBG_TGT_WIN32 ) - DCB *dcb = &p->old_dcb; - COMMTIMEOUTS *tmo = &p->old_commtimeouts; - COMMPROP *prop = &p->comm_prop; + const DCB *dcb = &p->org_dcb; + const COMMTIMEOUTS *tmo = &p->org_commtimeouts; + const COMMPROP *prop = &p->comm_prop; fprintf( fp, "Comm Properties:\n" ); fprintf( fp, " wPacketLength: %u\n", prop->wPacketLength ); @@ -302,47 +303,11 @@ int set_scu_port( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, int port ) static /*HDR*/ int check_rc( int rc ) { - const char *cp = NULL; - if ( done ) - return 0; // we are going to exit - - switch ( rc ) - { - case MBG_SUCCESS: - cp = "Data received completely."; - break; - - case MBG_ERR_TIMEOUT: - cp = "Timeout receiving data"; - break; + return 0; // we are going to exit anyway - case MBG_ERR_HDR_CSUM: - cp = "Header checksum error in received data."; - break; - - case MBG_ERR_DATA_CSUM: - cp = "Data checksum error in received data."; - break; - - case MBG_ERR_DECRYPT: - cp = "Failed to decrypt received data."; - break; - - case MBG_ERR_IO: - cp = "I/O error receiving data"; - break; - - case MBG_ERR_AUTH: - cp = "Authentication error"; - break; - - } // switch - - if ( cp ) - printf( "%s\n", cp ); - else - printf( "Unknow error code: %i\n", rc ); + if ( mbg_rc_is_error( rc ) ) + printf( "%s\n", mbg_strerror( rc ) ); return rc; @@ -351,42 +316,36 @@ int check_rc( int rc ) static /*HDR*/ -void sprint_tm( char *s, TM_GPS *tm, int print_frac ) +void snprint_tm( char *s, size_t max_len, TM_GPS *tm, int print_frac ) { - int n = 0; + size_t n = 0; int year = tm->year & ( DL_AUTO_FLAG - 1 ); - n += sprintf( &s[n], "%02i.%02i.%04i %02i:%02i:%02i", - tm->mday, - tm->month, - year, - tm->hour, - tm->min, - tm->sec - ); + n += snprintf_safe( &s[n], max_len - n, "%02i.%02i.%04i %02i:%02i:%02i", + tm->mday, tm->month, year, + tm->hour, tm->min, tm->sec ); if ( tm->year & DL_AUTO_FLAG ) - strncpy( &s[6], "****", 4 ); + strncpy_safe( &s[6], "****", 4 ); if ( print_frac ) - n += sprintf( &s[n], ".%07li", (long) tm->frac ); + n += snprintf_safe( &s[n], max_len - n, ".%07li", (long) tm->frac ); -} /* sprint_tm */ +} /* snprint_tm */ static /*HDR*/ -void sprint_lla( char *s, LLA lla ) +void snprint_lla( char *s, size_t max_len, LLA lla ) { static const double r2d = 180 / PI; - sprintf( s, "%c %.4f deg, %c %.4f deg, %.0fm", - ( lla[LAT] < 0 ) ? 'S' : 'N', lla[LAT] * r2d, - ( lla[LON] < 0 ) ? 'W' : 'E', lla[LON] * r2d, - lla[ALT] - ); + snprintf_safe( s, max_len, "%c %.4f deg, %c %.4f deg, %.0fm", + ( lla[LAT] < 0 ) ? 'S' : 'N', lla[LAT] * r2d, + ( lla[LON] < 0 ) ? 'W' : 'E', lla[LON] * r2d, + lla[ALT] ); -} /* sprint_lla */ +} /* snprint_lla */ @@ -431,7 +390,7 @@ void print_time( TTM *p ) "(capture 1)" }; - sprint_tm( ws, &p->tm, 1 ); + snprint_tm( ws, sizeof( ws ), &p->tm, 1 ); printf( "\rCh: %2i %-14s %s Status: %04X\n", p->channel, @@ -445,10 +404,13 @@ void print_time( TTM *p ) static /*HDR*/ -void check_receiver_info( RECEIVER_INFO *p, int log ) +void show_device_info( MBG_MSG_CTL *pmctl, 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)"; + size_t i; + size_t l; + RECEIVER_INFO *p = mbgextio_get_receiver_info_addr( pmctl ); // Check if numbers of resources provided by the device // don't exceed numbers of resources supported by the software @@ -473,53 +435,7 @@ void check_receiver_info( RECEIVER_INFO *p, int log ) } \ } - if ( p->model_code == GPS_MODEL_UNKNOWN ) - { - _log_msg_0( LOG_ERR, "Refclock model_code not set: maybe receiver_info " - "has not been received correctly" ); - } - else - if ( log ) - { - if ( p->model_code >= N_GPS_MODEL ) - { - _log_msg_2( LOG_WARNING, "Unsupported refclock model_code %u (name: %s)", - p->model_code, p->model_name ); - } - } - - _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, MAX_PARM_PORT, "string types" ); - _check_max( p->n_prg_out, N_POUT_MAX, "progr. outputs" ); - -} // check_receiver_info - - - -static /*HDR*/ -int get_receiver_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, RECEIVER_INFO *p ) -{ - int rc; - int i; - int l; - - printf( fmt, "Receiver info:" ); - - rc = mbgextio_setup_receiver_info( pmctl, p_addr, p ); - - if ( rc != MBG_SUCCESS ) - { - check_rc( rc ); - - 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" ); - } - - return rc; - } + printf( fmt, "Device info:" ); printf( "%s v%X.%02X", p->model_name, @@ -539,8 +455,8 @@ int get_receiver_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, RECEIVER_INFO *p ) if ( i != 0 ) printf( " \"%s\"", p->sw_rev.name ); - #if 0 // hex output for testing - for ( i= 0; i < l; i++ ) + #if 0 && defined( DEBUG ) // hex output for testing + for ( i = 0; i < l; i++ ) printf( " %02X", p->sw_rev.name[i] ); #endif } @@ -548,55 +464,27 @@ int get_receiver_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, RECEIVER_INFO *p ) printf( ", S/N: %s", p->sernum ); printf( "\n" ); - // print features - printf( fmt, "" ); - printf( "Features: 0x%08lX\n", (long) p->features ); - - for ( i = 0; i < 8 * sizeof( p->features ); i++ ) + if ( p->model_code == GPS_MODEL_UNKNOWN ) { - if ( p->features & (1UL << i) ) + _log_msg_0( LOG_ERR, "Refclock model_code not set: maybe receiver_info " + "has not been received correctly" ); + } + else + if ( log ) { - printf( fmt, "" ); - printf( " - " ); - - if ( i < N_GPS_FEATURE ) - printf( "%s\n", feature_names[i] ); - else - printf( "Unknown feature flag 0x%08lX\n", (1UL << i) ); + if ( p->model_code >= N_GPS_MODEL ) + { + _log_msg_2( LOG_WARNING, "Unsupported refclock model_code %u (name: %s)", + p->model_code, p->model_name ); + } } - } - - printf( "\n" ); - - return rc; - -} // get_receiver_info + _check_min( p->n_com_ports, N_COM_MIN, "COM ports" ); + _check_max( p->n_com_ports, MAX_PARM_PORT, "COM ports" ); + _check_max( p->n_str_type, MAX_PARM_STR_TYPE, "string types" ); + _check_max( p->n_prg_out, MAX_PARM_POUT, "progr. outputs" ); - -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, p_addr, &sw_rev ); - - if ( rc != MBG_SUCCESS ) - { - check_rc( rc ); - return; - } - - printf( "%X.%02X %s\n", - sw_rev.code >> 8, - sw_rev.code & 0xFF, - sw_rev.name - ); - -} /* show_sw_rev */ +} // show_device_info @@ -610,7 +498,7 @@ void show_bvar_stat( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) rc = mbgextio_get_bvar_stat( pmctl, p_addr, &bvar_stat ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) { check_rc( rc ); return; @@ -630,9 +518,9 @@ void show_stat_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) printf( fmt, "Receiver status:" ); - rc = mbgextio_get_stat_info( pmctl, p_addr, &stat_info ); + rc = mbgextio_get_gps_stat_info( pmctl, p_addr, &stat_info ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) { check_rc( rc ); return; @@ -645,7 +533,7 @@ void show_stat_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) static /*HDR*/ -void show_pos( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) +void show_pos_lla( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) { LLA lla; // Position as logitude, latitude, altitude int rc; @@ -654,16 +542,16 @@ void show_pos( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) rc = mbgextio_get_pos_lla( pmctl, p_addr, lla ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) { check_rc( rc ); return; } - sprint_lla( ws, lla ); + snprint_lla( ws, sizeof( ws ), lla ); printf( "%s\n", ws ); -} /* show_pos */ +} /* show_pos_lla */ @@ -677,7 +565,7 @@ void show_tzdl( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) rc = mbgextio_get_tzdl( pmctl, p_addr, &tzdl ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) { check_rc( rc ); return; @@ -702,7 +590,7 @@ void show_tzdl( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) dow_str[(int) tzdl.tm_on.wday] ); } - sprint_tm( ws, &tzdl.tm_on, 0 ); + snprint_tm( ws, sizeof( ws ), &tzdl.tm_on, 0 ); printf( "%sh\n", ws ); printf( fmt, " " ); @@ -713,7 +601,7 @@ void show_tzdl( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) dow_str[(int) tzdl.tm_off.wday] ); } - sprint_tm( ws, &tzdl.tm_off, 0 ); + snprint_tm( ws, sizeof( ws ), &tzdl.tm_off, 0 ); printf( "%sh\n", ws ); } /* show_tzdl */ @@ -721,6 +609,229 @@ void show_tzdl( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) static /*HDR*/ +void show_ptp_state( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) +{ + static const char *ptp_role_strs[N_PTP_ROLES] = PTP_ROLE_STRS; + static const char *ptp_state_strs[N_PTP_PORT_STATE] = PTP_PORT_STATE_STRS; + static const char *ptp_nw_prot_strs[N_PTP_NW_PROT] = PTP_NW_PROT_STRS; + static const char *ptp_delay_mech_names[N_PTP_DELAY_MECH] = PTP_DELAY_MECH_NAMES; + static const PTP_TABLE ptp_time_source_tbl[] = PTP_TIME_SOURCE_TABLE; + static const char *ptp_clock_accuracy_strs[] = PTP_CLOCK_ACCURACY_STRS; + + char ws[100]; + const char *cp; + int must_show_slave_mode_info; + int must_show_master_mode_info; + int slave_mode_active; + int master_mode_active; + int any_mode_active; + int utc_offset_valid; + PTP_STATE ptp_state = { 0 }; + PTP_CFG_INFO ptp_info = { { 0 } }; + int tmp; + int rc; + + printf( "\n" ); + printf( "PTP State:\n" ); + + rc = mbgextio_get_ptp_state( pmctl, p_addr, &ptp_state ); + + if ( mbg_rc_is_error( rc ) ) + { + check_rc( rc ); + return; + } + + + rc = mbgextio_get_ptp_cfg_info( pmctl, p_addr, &ptp_info ); + + if ( mbg_rc_is_error( rc ) ) + { + check_rc( rc ); + return; + } + + + // set up some flags controlling which information to be shown + + must_show_slave_mode_info = ( verbose > 1 ) || + ( ( ( 1UL << ptp_info.settings.ptp_role ) & PTP_ROLE_MSK_SLAVES ) != 0 ); + + must_show_master_mode_info = ( verbose > 1 ) || + ( ( ( 1UL << ptp_info.settings.ptp_role ) & PTP_ROLE_MSK_MASTERS ) != 0 ); + + slave_mode_active = ( ptp_state.port_state == PTP_PORT_STATE_UNCALIBRATED ) + || ( ptp_state.port_state == PTP_PORT_STATE_SLAVE ); + + master_mode_active = ( ptp_state.port_state == PTP_PORT_STATE_PRE_MASTER ) + || ( ptp_state.port_state == PTP_PORT_STATE_MASTER ) + || ( ptp_state.port_state == PTP_PORT_STATE_PASSIVE ); + + any_mode_active = slave_mode_active || master_mode_active; + + + // PTP role and port state + + printf( " Port mode: " ); + + if ( any_mode_active ) + printf( "%s", ( ptp_state.flags & PTP_FLAG_MSK_IS_UNICAST ) ? + "Unicast " : "Multicast " ); + + if ( ptp_state.port_state < N_PTP_PORT_STATE ) + printf( "%s", ptp_state_strs[ptp_state.port_state] ); + else + printf( "%s, code %i", str_undefined, ptp_state.port_state ); + + if ( !any_mode_active || ( verbose > 1 ) ) + printf( " in %s role", + ( ptp_info.settings.ptp_role < N_PTP_ROLES ) ? + ptp_role_strs[ptp_info.settings.ptp_role] : str_undefined ); + + printf( "\n" ); + + + if ( !any_mode_active || verbose ) + { + printf( " PTP protocol: " ); + + // If not fully synchronized then not all fields of the PTP_STATE + // structure may have been filled, so we show configuration settings + // in this case. + + if ( ptp_state.ptp_prot_version ) + printf( "v%i, ", ptp_state.ptp_prot_version ); + + tmp = any_mode_active ? ptp_state.nw_prot : ptp_info.settings.nw_prot; + printf( "%s", ( tmp < N_PTP_NW_PROT ) ? + ptp_nw_prot_strs[tmp] : str_undefined ); + + printf( ", %s step", + ( ptp_state.flags & PTP_FLAG_MSK_ONE_STEP ) ? "one" : "two" ); + + tmp = any_mode_active ? ptp_state.domain_number : ptp_info.settings.domain_number; + printf( ", domain %i", tmp ); + + tmp = any_mode_active ? ptp_state.delay_mech : ptp_info.settings.delay_mech; + printf( ", delay mech. %s", ( tmp < N_PTP_DELAY_MECH ) ? + ptp_delay_mech_names[tmp] : str_undefined ); + + tmp = any_mode_active ? ptp_state.log_delay_req_intv : ptp_info.settings.delay_req_intv; + printf( ", dly req. intv. 2^%i s", tmp ); + + printf( "\n" ); + } + + + if ( must_show_slave_mode_info ) + { + cp = ( slave_mode_active || ( verbose > 1 ) ) ? ws : str_not_avail; + + snprint_octets( ws, sizeof( ws ), ptp_state.gm_id.b, + sizeof( ptp_state.gm_id.b ), MAC_SEP_CHAR_ALT, NULL ); + printf( " Grandmaster ID: %s\n", cp ); + + snprint_nano_time( ws, sizeof( ws ), &ptp_state.offset ); + printf( " PTP time offset: %s\n", cp ); + + snprint_nano_time( ws, sizeof( ws ), &ptp_state.path_delay ); + printf( " PTP path delay: %s\n", cp ); + + if ( verbose > 1 ) + { + snprint_nano_time( ws, sizeof( ws ), &ptp_state.mean_path_delay ); + printf( " Mean path delay: %s\n", cp ); + + snprint_nano_time( ws, sizeof( ws ), &ptp_state.delay_asymmetry ); + printf( " Delay asymmetry: %s\n", cp ); + } + } + + + // PTP time scale + + cp = NULL; + + if ( ptp_state.flags & PTP_FLAG_MSK_TIMESCALE_IS_PTP ) // this is the default + { + if ( must_show_master_mode_info || verbose ) + cp = "TAI (standard)"; + } + else // unusual case, print info if available + if ( any_mode_active ) + cp = "arbitrary (non-standard)"; + + if ( cp ) + printf( " PTP time scale: %s\n", cp ); + + + // UTC offset and leap second status + + utc_offset_valid = ( ptp_state.flags & PTP_FLAG_MSK_UTC_VALID ) != 0; + + printf( " PTP UTC offset: " ); + + if ( !utc_offset_valid ) + printf( " %s", str_unknown ); // UTC offset not valid + + if ( utc_offset_valid || ( verbose > 1 ) ) + { + printf( utc_offset_valid ? " " : " (" ); + + printf( "%+i s", ptp_state.utc_offset ); + + if ( ptp_state.flags & PTP_FLAG_MSK_LS_ANN ) // leap second is announced + { + // distinguish between leap second insertion and deletion + printf( ", leap second %s scheduled", + ( ptp_state.flags & PTP_FLAG_MSK_LS_ANN_NEG ) ? "deletion" : "insertion" ); + } + + if ( !utc_offset_valid ) + printf( ")" ); + } + + printf( "\n" ); + + + if ( verbose > 1 ) + { + const PTP_TABLE *p_tbl; + + printf( "PTP clock state:\n" ); + + for ( p_tbl = ptp_time_source_tbl; p_tbl->name; p_tbl++ ) + if ( p_tbl->value == ptp_state.time_source ) + break; + + printf( " Time source: %s\n", p_tbl->name ? p_tbl->name : str_unknown ); + + printf( " Clock class: %i\n", ptp_state.clock_class ); + + tmp = N_PTP_CLOCK_ACCURACY - PTP_CLOCK_ACCURACY_NUM_BIAS; + + if ( ( ptp_state.clock_accuracy >= PTP_CLOCK_ACCURACY_NUM_BIAS ) && + ( ptp_state.clock_accuracy < N_PTP_CLOCK_ACCURACY ) ) + cp = ptp_clock_accuracy_strs[ptp_state.clock_accuracy - PTP_CLOCK_ACCURACY_NUM_BIAS]; + else + cp = str_undefined; + + printf( " Clock accuracy: %s\n", cp ); + +#if 0 + time_source + clock_class + clock_accuracy +#endif + printf( " Offs sc. log var: %u", ptp_state.clock_offset_scaled_log_variance ); + printf( "\n" ); + } + +} // show_ptp_state + + + +static /*HDR*/ void show_synth( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) { SYNTH synth; @@ -731,7 +842,7 @@ void show_synth( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) rc = mbgextio_get_synth( pmctl, p_addr, &synth ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) { check_rc( rc ); return; @@ -779,7 +890,7 @@ void set_synth( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) SYNTH synth = { 0 }; int rc; - if ( !( receiver_info.features & GPS_HAS_SYNTH ) ) + if ( mbg_rc_is_error( mbgextio_dev_has_synth( pmctl ) ) ) { printf( "The device doesn't provide a synthesizer.\n" ); return; @@ -795,8 +906,9 @@ void set_synth( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) rc = mbgextio_set_synth( pmctl, p_addr, &synth ); - if ( rc < 0 ) - printf( "Failed to set synthesizer output, code: %i\n", rc ); + if ( mbg_rc_is_error( rc ) ) + printf( "Failed to set synthesizer output: %s (rc: %i)\n", + mbg_strerror( rc ), rc ); else printf( "Synthesizer has been modified.\n" ); @@ -809,12 +921,13 @@ void set_synth( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) static /*HDR*/ void set_pout_mode( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) { + RECEIVER_INFO *p_ri = mbgextio_get_receiver_info_addr( pmctl ); POUT_INFO_IDX pout_info_idx; POUT_SETTINGS pout_settings = { 0 }; // new settings, init'd to 0 uint16_t pout_idx = 0; // index of the programmable output int rc; - if ( receiver_info.n_prg_out == 0 ) + if ( p_ri->n_prg_out == 0 ) { printf( "The device doesn't support programmable outputs.\n" ); return; @@ -822,10 +935,10 @@ void set_pout_mode( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) // valid pout_idx numbers include 0..receiver_info.n_prg_out-1 - if ( pout_idx >= receiver_info.n_prg_out ) + if ( pout_idx >= p_ri->n_prg_out ) { printf( "Programmable output index %u out of range (%u..%u)\n", - pout_idx, 0, receiver_info.n_prg_out - 1 ); + pout_idx, 0, p_ri->n_prg_out - 1 ); return; } @@ -834,7 +947,7 @@ void set_pout_mode( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) rc = mbgextio_get_pout_info_idx( pmctl, p_addr, &pout_info_idx, pout_idx ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) { check_rc( rc ); return; @@ -854,9 +967,9 @@ void set_pout_mode( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) // In this example we want an interval of 20 minutes, and a pulse length // of 300 milliseconds pout_settings.mode = POUT_CYCLIC_PULSE; - 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.pout_data.tm[0].on.t.hour = 0; + pout_settings.pout_data.tm[0].on.t.min = 20; + pout_settings.pout_data.tm[0].on.t.sec = 0; // pout_settings.pulse_len = 30; // 10 millisecond units rc = mbgextio_set_pout_settings_idx( pmctl, p_addr, &pout_settings, pout_idx ); @@ -882,7 +995,7 @@ void show_port_parm( MBG_MSG_CTL *pmctl ) rc = mbgextio_get_port_parm( pmctl, &port_parm ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) { check_rc( rc ); return; @@ -919,18 +1032,19 @@ void show_port_parm( MBG_MSG_CTL *pmctl ) static /*HDR*/ -void show_port_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) +void show_serial_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) { const char *mode_names[N_STR_MODE] = DEFAULT_ENG_MODE_NAMES; + RECEIVER_INFO *p_ri = mbgextio_get_receiver_info_addr( pmctl ); RECEIVER_PORT_CFG rpcfg; int rc; int i; printf( fmt, "Serial ports:" ); - rc = mbgextio_get_serial_settings( pmctl, p_addr, &rpcfg, &receiver_info ); + rc = mbgextio_get_serial_settings( pmctl, p_addr, &rpcfg ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) { check_rc( rc ); return; @@ -942,7 +1056,7 @@ void show_port_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) #if 0 //##++ TODO: possibly print supported string types - for ( i = 0; i < receiver_info.n_str_type; i++ ) + for ( i = 0; i < p_ri->n_str_type; i++ ) { sti[i] = stii.str_type_info; } @@ -973,13 +1087,13 @@ void show_port_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) printf( "\n" ); - if ( ++i >= receiver_info.n_com_ports ) + if ( ++i >= p_ri->n_com_ports ) break; printf( fmt, "" ); } -} /* show_port_settings */ +} /* show_serial_settings */ @@ -991,48 +1105,53 @@ void show_event_log( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) MBG_NUM_EVT_LOG_ENTRIES log_entries; MBG_EVT_LOG_ENTRY evt_log_entry; time_t t; - struct tm *mytime; + struct tm tm = { 0 }; int n_evt = 0; int event_id = -1; + unsigned int i; + int rc = mbgextio_get_num_evt_log_entries( pmctl, p_addr, &log_entries ); - 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 + if ( mbg_rc_is_error( rc ) ) { - printf( "Failed to read event log entries\n" ); + fprintf( stderr, "** ERROR: failed to read event log: %s\n", mbg_strerror( rc ) ); return; } - if ( mbgextio_get_first_evt_log_entry( pmctl, p_addr, &evt_log_entry ) ) + printf( "\nEvent Log (%i/%i entries used):\n", log_entries.used, log_entries.max ); + + for ( i = 0; i < log_entries.max; i++ ) { - unsigned int i; + rc = ( i == 0 ) ? mbgextio_get_first_evt_log_entry( pmctl, p_addr, &evt_log_entry ) + : mbgextio_get_next_evt_log_entry( pmctl, p_addr, &evt_log_entry ); - for ( i = 0; i < log_entries.max; i++ ) + if ( mbg_rc_is_error( rc ) ) { - event_id = _mbg_get_evt_id( evt_log_entry.code ); + fprintf( stderr, "Failed to read event log entry %i: %s\n", i, mbg_strerror( rc ) ); + break; + } - if ( event_id == 0 ) - break; + event_id = _mbg_get_evt_id( evt_log_entry.code ); - n_evt++; + if ( event_id == 0 ) + break; - t = evt_log_entry.time; - mytime = gmtime( &t ); + n_evt++; - 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 ); + t = evt_log_entry.time; + rc = mbg_gmtime( &tm, &t ); - if ( event_id < N_MBG_EVT_ID ) - printf( "%s\n", evt_id_names[event_id] ); - else - printf( "Unknown event ID %u", event_id ); + if ( mbg_rc_is_success( rc ) ) + printf( "%04i-%02i-%02i %02i:%02i:%02i ", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec ); + else + printf( "(inv. time) " ); - mbgextio_get_next_evt_log_entry( pmctl, p_addr, &evt_log_entry ); - } + if ( event_id < N_MBG_EVT_ID ) + printf( "%s\n", evt_id_names[event_id] ); + else + printf( "Unknown event ID %u", event_id ); } - else - fprintf( stderr, "** ERROR: failed to read event log\n" ); if ( n_evt == 0 ) fprintf( stderr, "event log is empty\n" ); @@ -1057,7 +1176,7 @@ int check_ucap_poll( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr ) memset( &ttm, 0, sizeof( ttm ) ); rc = mbgextio_get_ucap( pmctl, p_addr, &ttm ); - if ( ( rc == MBG_SUCCESS ) && _ttm_time_is_avail( &ttm ) ) + if ( mbg_rc_is_success( rc ) && _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, @@ -1084,8 +1203,10 @@ 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 }; + #if _DO_SET_TIME + PCPS_TIME_UNION u = { { 0 } }; + #endif + unsigned int year = 0; unsigned int month = 0; unsigned int mday = 0; @@ -1101,14 +1222,14 @@ int set_date_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, // 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 0 && _DO_SET_TIME + rc = mbg_get_time( dh, &u.t ); - if ( mbg_ioctl_err( rc, "mbg_get_time" ) ) - return rc; -#endif + if ( mbg_ioctl_err( rc, "mbg_get_time" ) ) + return rc; + #else + return -1; + #endif } @@ -1141,13 +1262,15 @@ int set_date_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, } } -#if 0 //##++++++++++++++++ + #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 ttm = { 0 }; ttm.channel = -1; if ( str_new_date ) // new date @@ -1233,7 +1356,7 @@ int set_date_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, if ( mbg_ioctl_err( rc, "mbg_set_time" ) ) return rc; } -#else + #else { // PCPS_TIME t = { 0 }; @@ -1257,7 +1380,7 @@ int set_date_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, t.sec = sec; t.sec100 = sec100; -#if 0 //##+++++++++++++++++ + #if 0 //##+++++++++++++++++ { MBG_PORT_HANDLE port_handle = pmctl->st.serio.port_handle; const char tmp[] = "\xFF\xFF\xFF\xFF"; @@ -1270,16 +1393,16 @@ int set_date_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, // _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 + #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 -#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 ); @@ -1289,13 +1412,80 @@ int set_date_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, +#if _USE_SERIAL_IO + +static /*HDR*/ +BAUD_RATE do_connect_serial( const char *port_name, BAUD_RATE baudrate, bool force_connection ) +{ + int rc; + + if ( force_connection ) + { + // Try to force the device to some useful settings, and return the baud rate + // that can be used for communication. If the returned number is negative then + // it's one of the Meinberg error codes. + printf( "Trying to force connection via %s ... ", port_name ); + + baudrate = mbgextio_force_conn_serial( port_name ); + + if ( baudrate < 0 ) + { + printf( "FAILED: %s (rc:%li)\n", mbg_strerror( (int) baudrate ), (long) baudrate ); + goto out; + } + + printf( "using %li/%s\n", (long) baudrate, framing ); + } + else + { + if ( baudrate == 0 ) // no specific value specified + { + // Some newer devices support MBG_DEFAULT_BAUDRATE_HS for the binary protocol, + // which is faster, but older devices support only MBG_DEFAULT_BAUDRATE, so we + // may want to try both. + baudrate = MBG_DEFAULT_BAUDRATE_HS; + rc = mbgextio_open_serial( port_name, &msg_ctl, baudrate, framing ); + + if ( mbg_rc_is_success( rc ) ) + goto opened_successfully; + + baudrate = MBG_DEFAULT_BAUDRATE; // next try this one + } + } + + // Now try to connect to the device with whichever baudrate has been determined + rc = mbgextio_open_serial( port_name, &msg_ctl, baudrate, framing ); + + if ( mbg_rc_is_error( rc ) ) + { + baudrate = rc; + goto out; + } + +opened_successfully: + + #if defined( DEBUG ) + print_original_serial_settings( stdout, msg_ctl->st.p_serio ); + #endif + + printf( "Using %s with %li baud, %s\n\n", + port_name, (long) baudrate, framing ); + +out: + return baudrate; + +} // do_connect_serial + +#endif + + + /*HDR*/ static void exit_close_connection( void ) { - mbgextio_close_connection( &pmctlx ); + mbgextio_close_connection( &msg_ctl ); - printf( "Connection closed.\n" ); - printf( "\n" ); + printf( "\nConnection closed.\n\n" ); } /* exit_close_connection */ @@ -1304,7 +1494,7 @@ void exit_close_connection( void ) /*HDR*/ static void exit_auto_off( void ) { - mbgextio_xmt_cmd( pmctlx, NULL, GPS_AUTO_OFF ); //##++++++ TODO: NULL? + mbgextio_xmt_cmd( msg_ctl, NULL, GPS_AUTO_OFF ); //##++++++ TODO: NULL? #if defined( DEBUG ) printf( "AUTO mode turned off.\n" ); @@ -1368,6 +1558,12 @@ int check_command_line( int argc, char *argv[] ) continue; } + if ( strcmp( argv[i], "-v" ) == 0 ) + { + verbose++; + continue; + } + if ( strcmp( argv[i], "-?" ) == 0 ) { must_print_usage = 1; @@ -1494,56 +1690,47 @@ int check_command_line( int argc, char *argv[] ) if ( must_print_usage ) { - printf( "Usage: %s [options] target\n" - "\n" - #if _USE_SERIAL_IO - " target can specify a serial port\n" - #endif - #if _USE_SOCKET_IO - " target can specify a network host name or IP address\n" - #endif - "\n" - "Options\n" - " -? or -h Print this usage\n" - " -a Set auto mode\n" - " -u Poll user capture events\n" - #if _USE_SOCKET_IO - " -n Connect to network target, not serial port\n" - " -p passwd Use specified password to connect\n" - #endif - #if _USE_SERIAL_IO - " -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" - #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 - " %s Connect to serial port %s using %lu/%s\n" - #endif - #if _USE_SOCKET_IO - " %s -n -p secret 172.16.1.1 Connect to the specified network host\n" - #endif - "\n", - argv[0] - #if _USE_SERIAL_IO - , (long) default_baudrate - , framing - , (long) default_baudrate - , framing - , argv[0] - , default_target - , (long) default_baudrate - , framing - #endif - #if _USE_SOCKET_IO - , argv[0] - #endif - ); + printf( "Usage: %s [options] target\n", argv[0] ); + printf( "\n" ); + #if _USE_SERIAL_IO + printf( " target can specify a serial port\n" ); + #endif + #if _USE_SOCKET_IO + printf( " target can specify a network host name or IP address\n" ); + #endif + printf( "\n" ); + printf( "Options\n" ); + printf( " -? or -h Print this usage\n" ); + printf( " -v Increase verbosity\n" ); + printf( " -a Set auto mode\n" ); + printf( " -u Poll user capture events\n" ); + #if _USE_SOCKET_IO + printf( " -n Connect to network target, not serial port\n" ); + printf( " -p passwd Use specified password to connect\n" ); + #endif + #if _USE_SERIAL_IO + printf( " -b speed Serial port baud rate, default: %lu or %lu\n", + (long) MBG_DEFAULT_BAUDRATE_HS, (long) MBG_DEFAULT_BAUDRATE ); + printf( " -f xxx Serial port framing, default: %s\n", framing ); + printf( " -F Force serial connection\n" ); + #endif + printf( " -c clear event log (if supported by device)\n" ); + #if _USE_SOCKET_IO + printf( " -P scu_port Select clock at SCU port 0 or 1 (only with SCU over LAN)\n" ); + #endif + printf( "\n" ); + printf( "Example:\n" ); + #if _USE_SERIAL_IO + printf( " %s Connect to serial port %s using %li/%s or %li/%s\n", + argv[0], default_target, + (long) MBG_DEFAULT_BAUDRATE_HS, framing, + (long) MBG_DEFAULT_BAUDRATE, framing ); + #endif + #if _USE_SOCKET_IO + printf( " %s -n -p secret 172.16.1.1 Connect to the specified network host\n", + argv[0] ); + #endif + printf( "\n" ); return -1; } @@ -1554,15 +1741,23 @@ int check_command_line( int argc, char *argv[] ) +static /*HDR*/ +void exit_with_error_serial( int rc, const char *target ) +{ + printf( "Failed to connect to device at %s: %s (rc: %i)\n", + target, mbg_strerror( rc ), rc ); + exit( 1 ); + +} // exit_with_error_serial + + + int main( int argc, char *argv[] ) { XBP_ADDR *p_addr = NULL; int rc; - fprintf( stderr, "\n\n\n%s v%s %s\n", pname, pversion, pdescr ); - - baudrate = default_baudrate; - framing = default_framing; + fprintf( stderr, "\n\n\n%s v%s %s\n\n", pname, pversion, pdescr ); if ( check_command_line( argc, argv ) < 0 ) return 1; @@ -1575,45 +1770,20 @@ int main( int argc, char *argv[] ) #if _USE_SOCKET_IO if ( is_socket ) { - rc = mbgextio_open_socket( target, &pmctlx, password ); + rc = mbgextio_open_socket( target, &msg_ctl, password ); - if ( rc != MBG_SUCCESS ) - { - printf( "Failed to connect to %s, rc: %i\n", target, rc ); - return 1; // Error ... - } + if ( mbg_rc_is_error( rc ) ) + exit_with_error_serial( rc, target ); goto doit; } #endif #if _USE_SERIAL_IO - if ( must_force_connection ) - { - printf( "Trying to force connection to 19200/8N1 ..." ); - mbgextio_force_conn_serial( target ); - printf( "\n" ); - - baudrate = default_baudrate; - framing = default_framing; - } - - rc = mbgextio_open_serial( target, &pmctlx, baudrate, framing ); - - if ( rc != MBG_SUCCESS ) - { - printf( "Error using port %s.\n", target ); - 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 ); + baudrate = do_connect_serial( target, baudrate, must_force_connection ); - goto doit; + if ( baudrate <= 0 ) + exit_with_error_serial( (int) baudrate, target ); #endif #if !_USE_SOCKET_IO && !_USE_SERIAL_IO @@ -1621,21 +1791,22 @@ int main( int argc, char *argv[] ) #endif - doit: atexit( exit_close_connection ); // now start communication with whichever device has been opened above: - // TODO: make sure xbp is supported. - mbgextio_setup_xbp_node_list( pmctlx, p_addr ); + #if 0 + // TODO: make sure xbp is supported. + mbgextio_setup_xbp_node_list( msg_ctl, p_addr ); + #endif #if _USE_SOCKET_IO if ( must_set_scu_port ) { - int rc = set_scu_port( pmctlx, p_addr, scu_port ); + int rc = set_scu_port( msg_ctl, p_addr, scu_port ); - if ( rc == MBG_SUCCESS ) + if ( mbg_rc_is_success( rc ) ) printf( "\nSCU switched to port %i (clock #%i)\n\n", scu_port, scu_port + 1 ); else @@ -1645,59 +1816,78 @@ doit: #endif if ( must_send_auto ) - set_auto_mode( pmctlx ); - + set_auto_mode( msg_ctl ); -#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 ); + set_date_time( msg_ctl, p_addr, str_new_date, str_new_time ); return 0; } - check_receiver_info( &receiver_info, 1 ); + show_device_info( msg_ctl, 1 ); /* display system specific values */ - 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 ( mbg_rc_is_success( mbgextio_dev_has_bvar_stat( msg_ctl ) ) ) + show_bvar_stat( msg_ctl, p_addr ); + + if ( mbg_rc_is_success( mbgextio_dev_has_gps_stat_info( msg_ctl ) ) ) + show_stat_info( msg_ctl, p_addr ); + + if ( mbg_rc_is_success( mbgextio_dev_has_pos_lla( msg_ctl ) ) ) + show_pos_lla( msg_ctl, p_addr ); + + if ( mbg_rc_is_success( mbgextio_dev_has_tzdl( msg_ctl ) ) ) + show_tzdl( msg_ctl, p_addr ); + + if ( mbg_rc_is_success( mbgextio_dev_has_serouts( msg_ctl ) ) ) + show_serial_settings( msg_ctl, p_addr ); + + if ( mbg_rc_is_success( mbgextio_dev_has_synth( msg_ctl ) ) ) + show_synth( msg_ctl, p_addr ); + + if ( mbg_rc_is_success( mbgextio_dev_has_ptp( msg_ctl ) ) ) + show_ptp_state( msg_ctl, p_addr ); + + if ( mbg_rc_is_success( mbgextio_dev_has_evt_log( msg_ctl ) ) ) + show_event_log( msg_ctl, p_addr ); if ( must_clear_event_log ) { - if ( receiver_info.features & GPS_HAS_EVT_LOG ) + if ( mbg_rc_is_success( mbgextio_dev_has_evt_log( msg_ctl ) ) ) { - int ret = mbgextio_clr_evt_log( pmctlx, p_addr ); + rc = mbgextio_clr_evt_log( msg_ctl, p_addr ); - if ( ret != 0 ) - fprintf( stderr, "Failed to clear event log, rc: %i\n", ret ); + if ( mbg_rc_is_error( rc ) ) + fprintf( stderr, "Failed to clear event log: %s (rc: %i)\n", + mbg_strerror( rc ), rc ); else - fprintf( stderr, "event log has been cleared\n" ); + 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" ); + if ( must_set_synth ) + { + if ( mbg_rc_is_success( mbgextio_dev_has_synth( msg_ctl ) ) ) + set_synth( msg_ctl, p_addr ); + else + fprintf( stderr, "Can't set synthesizer output: not supported by device\n" ); + } + if ( must_set_pout_mode ) + { + if ( mbg_rc_is_success( mbgextio_dev_has_prog_pulses( msg_ctl ) ) ) + set_pout_mode(msg_ctl, p_addr ); + else + fprintf( stderr, "Can't set programmable output mode: not supported by device\n" ); + } -// set_synth(); -// set_pout_mode(); if ( must_poll_ucap ) - return check_ucap_poll( pmctlx, p_addr ); + return check_ucap_poll( msg_ctl, p_addr ); if ( !must_send_auto ) return 0; @@ -1708,10 +1898,8 @@ 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( pmctlx, 2000 ); // [msec] - mbgextio_set_msg_rcv_timeout( pmctlx, 2000 ); // [msec] - - set_auto_mode( pmctlx ); + mbgextio_set_dev_poll_timeout( msg_ctl, 2000 ); // [msec] + mbgextio_set_msg_rcv_timeout( msg_ctl, 2000 ); // [msec] do { @@ -1719,17 +1907,17 @@ doit: MSG_DATA *p; - rc = mbgextio_rcv_msg( pmctlx, p_addr, -1 ); + rc = mbgextio_rcv_msg( msg_ctl, p_addr, GPS_WILDCARD, NULL, 0 ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) { check_rc( rc ); break; } - mbgextio_xmt_cmd( pmctlx, p_addr, GPS_AUTO_ON ); + mbgextio_xmt_cmd( msg_ctl, p_addr, GPS_AUTO_ON ); - pmb = pmctlx->rcv.pmb; + pmb = msg_ctl->rcv.pmb; p = &pmb->u.msg_data; switch ( pmb->hdr.cmd ) @@ -1739,9 +1927,9 @@ doit: if ( p->ttm.channel == -1 ) { - 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 ); + mbgextio_xmt_cmd( msg_ctl, p_addr, GPS_AUTO_ON ); + mbgextio_xmt_cmd( msg_ctl, p_addr, GPS_STAT_INFO ); + mbgextio_xmt_cmd( msg_ctl, p_addr, GPS_UCAP ); } break; diff --git a/mbglib/common/aes128.c b/mbglib/common/aes128.c index 14f4f34..07eec13 100644 --- a/mbglib/common/aes128.c +++ b/mbglib/common/aes128.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: aes128.c 1.2 2009/10/01 14:03:09Z martin REL_M $ + * $Id: aes128.c 1.2.1.1 2009/12/22 12:23:00Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,9 @@ * * ----------------------------------------------------------------------- * $Log: aes128.c $ - * Revision 1.2 2009/10/01 14:03:09Z martin + * Revision 1.2.1.1 2009/12/22 12:23:00Z martin + * Started to fix possible 32/64 bit issues. + * Revision 1.2 2009/10/01 14:03:09 martin * Added standard file header. * Fixed compiler warnings. * Support prototype generation by makehdr tool. @@ -36,26 +38,28 @@ #define FTABLE_ENTRIES 256 -static ulong FSb[FTABLE_ENTRIES]; -static ulong FT0[FTABLE_ENTRIES]; -static ulong FT1[FTABLE_ENTRIES]; -static ulong FT2[FTABLE_ENTRIES]; -static ulong FT3[FTABLE_ENTRIES]; +static uint32_t FSb[FTABLE_ENTRIES]; +static uint32_t FT0[FTABLE_ENTRIES]; +static uint32_t FT1[FTABLE_ENTRIES]; +static uint32_t FT2[FTABLE_ENTRIES]; +static uint32_t FT3[FTABLE_ENTRIES]; /* rounding constants */ #define RCON_TABLE_ENTRIES 10 -ulong RCON[RCON_TABLE_ENTRIES]; +uint32_t RCON[RCON_TABLE_ENTRIES]; /* tables generation flag */ static int initialized; -#define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFFUL ) | \ - ( ( x & 0xFFFFFFFFUL ) >> 8 ) ) -#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) -#define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 ) +#define ROTR8( _x ) ( ( ( (_x) << 24 ) & 0xFFFFFFFFUL ) | \ + ( ( (_x) & 0xFFFFFFFFUL ) >> 8 ) ) + +#define XTIME( _x ) ( ( (_x) << 1 ) ^ ( ( (_x) & 0x80 ) ? 0x1B : 0x00 ) ) + +#define MUL( _x, _y ) ( ( (_x) && (_y) ) ? pow[(log[_x] + log[_y]) % 255] : 0 ) @@ -63,7 +67,8 @@ static int initialized; void aes_gen_tables( void ) { int i; - uint8_t x, y; + uint8_t x; + uint8_t y; uint8_t pow[FTABLE_ENTRIES]; uint8_t log[FTABLE_ENTRIES]; @@ -78,7 +83,7 @@ void aes_gen_tables( void ) /* calculate the round constants */ for ( i = 0, x = 1; i < RCON_TABLE_ENTRIES; i++, x = XTIME( x ) ) - RCON[i] = (ulong) x << 24; + RCON[i] = (uint32_t) x << 24; /* generate the forward and reverse S-boxes */ @@ -104,10 +109,10 @@ void aes_gen_tables( void ) x = (uint8_t) FSb[i]; y = XTIME( x ); - FT0[i] = (ulong) ( x ^ y ) ^ - ( (ulong) x << 8 ) ^ - ( (ulong) x << 16 ) ^ - ( (ulong) y << 24 ); + FT0[i] = (uint32_t) ( x ^ y ) ^ + ( (uint32_t) x << 8 ) ^ + ( (uint32_t) x << 16 ) ^ + ( (uint32_t) y << 24 ); FT0[i] &= 0xFFFFFFFFUL; @@ -122,20 +127,20 @@ void aes_gen_tables( void ) /* platform-independant 32-bit integer manipulation macros */ -#define GET_ulong(n,b,i) \ -{ \ - (n) = ( (ulong) (b)[(i) ] << 24 ) \ - | ( (ulong) (b)[(i) + 1] << 16 ) \ - | ( (ulong) (b)[(i) + 2] << 8 ) \ - | ( (ulong) (b)[(i) + 3] ); \ +#define GET_ulong( _n, _b, _i ) \ +{ \ + (_n) = ( (uint32_t) (_b)[(_i) ] << 24 ) \ + | ( (uint32_t) (_b)[(_i) + 1] << 16 ) \ + | ( (uint32_t) (_b)[(_i) + 2] << 8 ) \ + | ( (uint32_t) (_b)[(_i) + 3] ); \ } -#define PUT_ulong(n,b,i) \ -{ \ - (b)[(i) ] = (uint8_t) ( (n) >> 24 ); \ - (b)[(i) + 1] = (uint8_t) ( (n) >> 16 ); \ - (b)[(i) + 2] = (uint8_t) ( (n) >> 8 ); \ - (b)[(i) + 3] = (uint8_t) ( (n) ); \ +#define PUT_ulong( _n, _b, _i ) \ +{ \ + (_b)[(_i) ] = (uint8_t) ( (_n) >> 24 ); \ + (_b)[(_i) + 1] = (uint8_t) ( (_n) >> 16 ); \ + (_b)[(_i) + 2] = (uint8_t) ( (_n) >> 8 ); \ + (_b)[(_i) + 3] = (uint8_t) ( (_n) ); \ } @@ -150,7 +155,7 @@ void aes_gen_tables( void ) int aes128_set_key( aes128_context *ctx, uint8_t *key ) { int i; - ulong *RK; + uint32_t *RK; if ( !initialized ) { @@ -188,7 +193,7 @@ int aes128_set_key( aes128_context *ctx, uint8_t *key ) static /*HDR*/ void aes128_encrypt( aes128_context *ctx, uint8_t input[16], uint8_t output[16] ) { - ulong *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = ctx->erk; @@ -199,23 +204,23 @@ void aes128_encrypt( aes128_context *ctx, uint8_t input[16], uint8_t output[16] #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ { \ - RK += 4; \ - \ + RK += 4; \ + \ X0 = RK[0] ^ FT0[ (uint8_t) ( Y0 >> 24 ) ] ^ \ FT1[ (uint8_t) ( Y1 >> 16 ) ] ^ \ FT2[ (uint8_t) ( Y2 >> 8 ) ] ^ \ FT3[ (uint8_t) ( Y3 ) ]; \ - \ + \ X1 = RK[1] ^ FT0[ (uint8_t) ( Y1 >> 24 ) ] ^ \ FT1[ (uint8_t) ( Y2 >> 16 ) ] ^ \ FT2[ (uint8_t) ( Y3 >> 8 ) ] ^ \ FT3[ (uint8_t) ( Y0 ) ]; \ - \ + \ X2 = RK[2] ^ FT0[ (uint8_t) ( Y2 >> 24 ) ] ^ \ FT1[ (uint8_t) ( Y3 >> 16 ) ] ^ \ FT2[ (uint8_t) ( Y0 >> 8 ) ] ^ \ FT3[ (uint8_t) ( Y1 ) ]; \ - \ + \ X3 = RK[3] ^ FT0[ (uint8_t) ( Y3 >> 24 ) ] ^ \ FT1[ (uint8_t) ( Y0 >> 16 ) ] ^ \ FT2[ (uint8_t) ( Y1 >> 8 ) ] ^ \ diff --git a/mbglib/common/aes128.h b/mbglib/common/aes128.h index 6a12516..ac4a16e 100644 --- a/mbglib/common/aes128.h +++ b/mbglib/common/aes128.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: aes128.h 1.3 2009/10/01 14:04:52Z martin REL_M $ + * $Id: aes128.h 1.3.1.1 2009/12/22 12:23:09Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,9 @@ * * ----------------------------------------------------------------------- * $Log: aes128.h $ - * Revision 1.3 2009/10/01 14:04:52Z martin + * Revision 1.3.1.1 2009/12/22 12:23:09Z martin + * Started to fix possible 32/64 bit issues. + * Revision 1.3 2009/10/01 14:04:52 martin * Code cleanup. * Updated function prototypes. * Revision 1.2 2006/08/22 15:28:11Z martin @@ -42,8 +44,8 @@ typedef struct { - unsigned long erk[64]; /* encryption round keys */ - unsigned long drk[64]; /* decryption round keys */ + uint32_t erk[64]; /* encryption round keys */ + uint32_t drk[64]; /* decryption round keys */ } aes128_context; /* function prototypes: */ diff --git a/mbglib/common/cfg_hlp.c b/mbglib/common/cfg_hlp.c new file mode 100644 index 0000000..1cfa4bc --- /dev/null +++ b/mbglib/common/cfg_hlp.c @@ -0,0 +1,1747 @@ + +/************************************************************************** + * + * $Id: cfg_hlp.c 1.1.1.85 2017/04/11 14:47:08Z martin TEST $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Meinberg device configuration helper functions. + * + * ----------------------------------------------------------------------- + * $Log: cfg_hlp.c $ + * Revision 1.1.1.85 2017/04/11 14:47:08Z martin + * Revision 1.1.1.84 2017/04/06 09:16:16Z thomas-b + * mbg_snprint_revision is not preliminary any longer + * Revision 1.1.1.83 2017/03/27 10:37:18 thomas-b + * Added ALL_PTP_V1_COMMON_DATASETS and the appropriate free function + * Revision 1.1.1.82 2017/03/22 09:07:52 thomas-b + * Added function get_io_port_type_info_idx + * Revision 1.1.1.81 2017/03/02 15:29:27 thomas-b + * Adapted free_all_ntp_cfg_info for new ALL_NTP_CFG_INFO structure + * Revision 1.1.1.80 2017/02/28 15:24:27 gregoire + * peer strucutre in ALL_NTP_CFG_INFO renamed + * Revision 1.1.1.79 2017/02/24 09:38:25 philipp + * Do not use fixed buffers for monitorung event info and status + * Revision 1.1.1.78 2017/02/22 14:28:57 martin + * Fixed some warnings from clang compiler. + * Revision 1.1.1.77 2017/02/22 11:40:17 martin + * Account for preliminary code. + * Revision 1.1.1.76 2017/02/21 15:51:40 thomas-b + * Added ALL_MONITORING_STATUS and free function and extended ALL_MONITORING_INFO by events + * Revision 1.1.1.75 2017/02/16 12:58:01 thomas-b + * Added ALL_PTP_V2_COMMON_DATASETS structure and the appropriate free function + * Revision 1.1.1.74 2017/02/08 13:16:07 thomas-b + * Added ALL_MONITORING_INFO and the appropriate free function + * Revision 1.1.1.73 2017/02/07 09:46:51 thomas-b + * Added ALL_SNMP_INFO and the appropriate free function + * Revision 1.1.1.72 2016/12/19 12:13:55 philipp + * Added GPIO associated index helper + * Revision 1.1.1.71 2016/11/22 12:40:46 philipp + * Added I/O port helper functions + * Revision 1.1.1.70 2016/11/08 17:21:19 martin + * Doxygen fixes. + * Revision 1.1.1.69 2016/11/01 14:51:54 udo + * *** empty log message *** + * Revision 1.1.1.68 2016/11/01 09:24:01 martin + * *** empty log message *** + * Revision 1.1.1.67 2016/10/25 07:48:27 martin + * Doxygen fixes. + * Revision 1.1.1.66 2016/10/21 09:39:25 thomas-b + * Added struct ALL_XBP_INFO and appropriate free function + * Revision 1.1.1.65 2016/10/14 11:10:02 thomas-b + * Added ALL_UCAP_NET_INFO and the appropriate free function + * Revision 1.1.1.64 2016/09/28 15:04:02 thomas-b + * Added function to check whether NET_CFG_API stage 2 is supported + * Revision 1.1.1.63 2016/07/26 08:07:10 philipp + * Fixed compiler errors (name clash, syntax error) + * Revision 1.1.1.62 2016/07/15 14:09:48 martin + * Use functions from new module timeutil. + * Revision 1.1.1.61 2016/06/21 13:51:23 philipp + * Fixed nasty segfault due to pointer corruption + * Revision 1.1.1.60 2016/06/21 12:06:59 thomas-b + * Added function calloc_ucap_entry + * Revision 1.1.1.59 2016/06/21 10:25:30 philipp + * Freeing ucap entry list is now portable + * Revision 1.1.1.58 2016/06/21 07:39:21 philipp + * Use mbg_klist for ucap events and not an array -> Easier to handle MAX_UCAP_ENTRIES + * Revision 1.1.1.57 2016/06/16 07:46:45 philipp + * Fixed checking flags for IMS sensor specific features + * Revision 1.1.1.56 2016/06/15 14:04:27 thomas-b + * Added ALL_UCAP_INFO structure and function free_all_ucap_info + * Revision 1.1.1.55 2016/06/03 09:00:13 thomas-b + * tm structure does not have gmtoff field under Windows + * Revision 1.1.1.54 2016/06/02 10:24:22 philipp + * Renaming all revision macros and helper functions + * Revision 1.1.1.53 2016/05/27 07:27:43 philipp + * Fixed (potential) memleak + * Revision 1.1.1.52 2016/05/27 05:48:08 philipp + * Refactoring to support XMR_METRICS properly + * Revision 1.1.1.51 2016/05/26 11:01:09 thomas-b + * Removed info structures from ALL_NTP_STATUS + * Moved check functions of specific features to cfg_hlp + * Revision 1.1.1.50 2016/05/25 08:43:35 philipp + * Redesign of ALL_[xxx]_[XXX] structures and (helper) functions + * Revision 1.1.1.49 2016/05/23 09:37:40 philipp + * Extended ALL_XMULTI_REF_STATUS by holdover_status + * Revision 1.1.1.48 2016/05/23 08:59:03 philipp + * New function free_all_gpio_state + * Revision 1.1.1.47 2016/05/23 08:24:37 philipp + * New function free_all_ims_state + * Revision 1.1.1.46 2016/05/11 13:20:55 thomas-b + * Added ALL_NET_STATUS_INFO and the appropriate free function + * Revision 1.1.1.45 2016/04/26 14:21:58 thomas-b + * Renamed ALL_NET_CFG_INFO structure members + * Revision 1.1.1.44 2016/04/26 13:45:36 martin + * Tried portable printing of int64_t types. + * Revision 1.1.1.43 2016/04/26 08:40:17Z philipp + * Fixed compiler warning due to invalid format specifier + * Revision 1.1.1.42 2016/04/26 08:23:45 thomas-b + * Extended ALL_NET_CFG_INFO by DNS configurations + * Revision 1.1.1.41 2016/04/26 06:29:27 thomas-b + * Added ALL_NET_CFG_INFO for network configuration + * Revision 1.1.1.40 2016/04/25 14:55:32 martin + * *** empty log message *** + * Revision 1.1.1.39 2016/04/25 14:42:18 martin + * *** empty log message *** + * Revision 1.1.1.38 2016/04/25 11:22:41 martin + * Revision 1.1.1.37 2016/04/25 09:01:29Z martin + * *** empty log message *** + * Revision 1.1.1.36 2016/04/22 07:11:50 philipp + * Use pointer to pointer in get_all_* functions + * Revision 1.1.1.35 2016/04/20 14:45:46 thomas-b + * Renamed ALL_NTP_STATE_INFO to ALL_NTP_STATUS + * Revision 1.1.1.34 2016/04/20 13:49:12 thomas-b + * Added structure definitions and free functions for NTP + * Revision 1.1.1.33 2016/04/20 12:37:53 thomas-b + * Moved free functions for ALL_XMULTI_REF_INFO and ALL_XMULTI_REF_STATUS to cfg_hlp + * Revision 1.1.1.32 2016/04/08 07:54:17 philipp + * Added function mbg_print_ext_rev_info + * Revision 1.1.1.31 2016/04/07 08:07:38 philipp + * Added function normalize_nano_time_64 (Clemens) + * Revision 1.1.1.30 2016/04/04 15:08:45 martin + * Replaced chk_model_is_vsg() by xdevfeat::xdevfeat_is_vsg(). + * Revision 1.1.1.29 2016/03/03 11:16:50 martin + * Utility functions to alloc and free memory for hardware ID. + * Revision 1.1.1.28 2016/02/17 12:00:06Z gregoire + * new function chk_model_is_vsg + * Revision 1.1.1.27 2015/11/24 13:12:04Z philipp + * Extended / modified TLV functions + * Revision 1.1.1.26 2015/11/23 14:15:40 philipp + * Moved TLV related initializing functions to here + * Revision 1.1.1.25 2015/10/30 15:33:48 martin + * Revision 1.1.1.24 2015/10/27 16:17:32Z martin + * *** empty log message *** + * Revision 1.1.1.23 2015/10/26 16:31:52 martin + * *** empty log message *** + * Revision 1.1.1.22 2015/10/26 13:36:44 martin + * Revision 1.1.1.21 2015/10/15 12:49:09Z marvin + * Revision 1.1.1.20 2015/10/12 10:01:59Z martin + * *** empty log message *** + * Revision 1.1.1.19 2015/10/09 11:09:13 martin + * *** empty log message *** + * Revision 1.1.1.18 2015/10/08 10:32:16 martin + * *** empty log message *** + * Revision 1.1.1.17 2015/10/08 09:30:34 martin + * *** empty log message *** + * Revision 1.1.1.16 2015/10/07 16:03:19 martin + * *** empty log message *** + * Revision 1.1.1.15 2015/10/07 09:59:00 martin + * More common GNSS support. + * Revision 1.1.1.14 2015/10/05 13:29:45 martin + * Revision 1.1.1.13 2015/10/01 10:58:35Z thomas-b + * fixed call of mbgmktm with correct month and day values in nano_time_64_to_tm_gps + * Revision 1.1.1.12 2015/09/15 09:11:13 martin + * Moved some functions into a _PRELIMINARY_CODE section. + * Revision 1.1.1.11 2015/09/14 08:56:05 thomas-b + * Sustract 1900 from year when calling mbg_mktime + * Revision 1.1.1.10 2015/09/14 07:34:08 thomas-b + * Added missing includes of time.h and mbgmktm.h + * Revision 1.1.1.9 2015/09/11 12:09:04 thomas-b + * Added nano_time_64_to_tm_gps and tm_gps_to_nano_time_64 functions + * Revision 1.1.1.8 2015/08/31 14:55:11 martin + * Moved string trim functions to str_util module. + * Revision 1.1.1.7 2015/08/31 13:41:56 martin + * Revision 1.1.1.6 2014/10/29 16:25:31 martin + * Moved some functions and structures to more convenient files. + * Revision 1.1.1.5 2014/10/14 10:20:18 martin + * Revision 1.1.1.4 2014/10/14 10:05:10 martin + * Revision 1.1.1.3 2014/09/26 11:43:24Z martin + * Revision 1.1.1.2 2014/07/22 13:05:34 martin + * Revision 1.1.1.1 2014/04/28 12:29:45Z martin + * Revision 1.1 2014/04/25 09:14:49 martin + * Initial revision. + * + **************************************************************************/ + +#define _CFG_HLP + #include <cfg_hlp.h> +#undef _CFG_HLP + +#include <mbgerror.h> +#include <timeutil.h> +#include <str_util.h> +#include <myutil.h> +#include <mbgtime.h> + +#if defined( _PRELIMINARY_CODE ) + #include <mbgmktm.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + + +#if !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + +/*HDR*/ +/** + * @brief Normalize a ::NANO_TIME_64 struct + * + * After normalization, the following can be assumed:<br> + * - nano_secs is in the range [-10^9 + 1, 10^9 - 1]<br> + * - if secs is not 0, secs and nano_secs have the same sign + * + * @param[in,out] nt The NANO_TIME_64 to be normalized + */ +void normalize_nano_time_64( NANO_TIME_64 *nt ) +{ + int64_t additional_secs; + + // Step 1: Make sure nano seconds are in the interval [-10^9 + 1, 10^9 - 1] + additional_secs = nt->nano_secs / NSECS_PER_SEC; + nt->nano_secs -= additional_secs * NSECS_PER_SEC; + nt->secs += additional_secs; + + // Step 2: Make sure seconds and nanoseconds have same sign if seconds is not 0 + if ( nt->secs > 0 && nt->nano_secs < 0 ) + { + nt->secs -= 1; + nt->nano_secs += NSECS_PER_SEC; + } + else if ( nt->secs < 0 && nt->nano_secs > 0 ) + { + nt->secs += 1; + nt->nano_secs -= NSECS_PER_SEC; + } + +} // normalize_nano_time_64 + +#endif // !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + + + +#if !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + +/*HDR*/ +/** + * @brief Print a normalized ::NANO_TIME_64 into a string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] nt The ::NANO_TIME_64 to be printed + */ +size_t snprint_nano_time_64( char *s, size_t max_len, const NANO_TIME_64 *nt ) +{ + size_t n = snprintf_safe( s, max_len, "%c%" PRId64 ".%09" PRId64, + _nano_time_negative( nt ) ? '-' : '+', + _abs64( nt->secs ), + _abs64( nt->nano_secs ) ); + return n; + +} // snprint_nano_time_64 + +#endif // !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + + + +/*HDR*/ +/** + * @brief Print nano time into string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] nt The ::NANO_TIME to be printed + */ +size_t snprint_nano_time( char *s, size_t max_len, const NANO_TIME *nt ) +{ + size_t n = snprintf_safe( s, max_len, "%c%li.%09li", + _nano_time_negative( nt ) ? '-' : '+', + labs( (long) nt->secs ), + labs( (long) nt->nano_secs ) ); + return n; + +} // snprint_nano_time + + + +#if defined( _PRELIMINARY_CODE ) + +//### TODO: eventually move these functions to a different module + +#if !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + +/*HDR*/ +/** + * @brief Convert ::NANO_TIME_64 to ::TM_GPS + * + * @param[out] tm_gps The ::TM_GPS to be filled + * @param[in] nt The ::NANO_TIME_64 to be converted + * + * @return 1 on success, 0 on error + * + * @see ::tm_gps_to_nano_time_64 + */ +int nano_time_64_to_tm_gps( TM_GPS *tm_gps, const NANO_TIME_64 *nt ) +{ + struct tm tm = { 0 }; + time_t t = cvt_to_time_t( nt->secs ); + int rc = mbg_gmtime( &tm, &t ); + + if ( mbg_rc_is_success( rc ) ) + { + tm_gps->year = tm.tm_year + 1900; + tm_gps->month = tm.tm_mon + 1; + tm_gps->mday = tm.tm_mday; + tm_gps->yday = tm.tm_yday; + tm_gps->wday = tm.tm_wday; + tm_gps->hour = tm.tm_hour; + tm_gps->min = tm.tm_min; + tm_gps->sec = tm.tm_sec; + tm_gps->frac = 0; //### TODO convert fractions +#if defined( MBG_TGT_POSIX ) + tm_gps->offs_from_utc = tm.tm_gmtoff; //### TODO Is tm.tm_gmtoff even valid? +#endif + return 1; //### TODO return MBG_SUCCESS + } + + return 0; //### TODO return rc + +} // nano_time_64_to_tm_gps + + + +/*HDR*/ +/** + * @brief Convert ::TM_GPS to ::NANO_TIME_64 + * + * @param[out] nt The ::NANO_TIME_64 to be filled + * @param[in] tm The ::TM_GPS to be converted + * + * @return 1 on success, 0 on error + * + * @see ::nano_time_64_to_tm_gps + */ +int tm_gps_to_nano_time_64( NANO_TIME_64 *nt, const TM_GPS *tm ) +{ + time_t t = mbg_mktime( tm->year - 1900, tm->month - 1, tm->mday - 1, tm->hour, tm->min, tm->sec ); + + if ( t != (time_t) -1 ) + { + nt->secs = (uint64_t) t; + nt->nano_secs = 0; //### TODO: convert fractions + return 1; + } + + return 0; + +} // tm_gps_to_nano_time_64 + +#endif // !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + +#endif // defined( _PRELIMINARY_CODE ) + + + +/*HDR*/ +/** + * @brief Check if a software revision name should be displayed + * + * The software revision name is usually empty, except if the + * firmware is a customized version, in which case the field + * contains an identifier string. + * + * There are some standard firmware versions where this string + * is not empty but padded with spaces, etc., so we try to + * clean this up and display the string properly, if appropriate. + * + * @param[in,out] p The ::SW_REV name to check + * @param[in] verbose The app's verbosity level + * + * @return != 0 if SW name should be displayed + */ +int chk_sw_rev_name( SW_REV *p, int verbose ) +{ + if ( verbose > 1 ) // more than just verbose + return 1; // just return raw string + + trim_whitespace( p->name ); + + // Some firmware versions have "CC_STANDARD" in their standard version, + // which doesn't provide any valuable information. + // We discard this by default. + if ( strstr( p->name, "CC_STANDARD" ) ) + p->name[0] = 0; + + if ( verbose ) + return 1; // calling app should display string, even if empty + + // calling app should display string only if not empty + return strlen( p->name ) != 0; + +} // chk_sw_rev_name + + + +/*HDR*/ +int get_str_idx( const char *search, + const char *str_table[], + int n_entries ) +{ + int i; + + for ( i = 0; i < n_entries; i++ ) + if ( strcmp( search, str_table[i] ) == 0 ) + return i; + + return -1; + +} // get_str_idx + + + +/*HDR*/ +int get_baud_rate_idx( BAUD_RATE baud_rate ) +{ + int i; + + for ( i = 0; i < N_MBG_BAUD_RATES; i++ ) + if ( baud_rate == mbg_baud_rate[i] ) + return i; + + return -1; + +} // get_baud_rate_idx + + + +/*HDR*/ +int get_framing_idx( const char *framing ) +{ + return get_str_idx( framing, mbg_framing_str, N_MBG_FRAMINGS ); + +} // get_framing_idx + + + +/*HDR*/ +void port_settings_from_port_parm_mode( + PORT_SETTINGS *p_ps, + uint8_t pp_mode, + int str_type_cap + ) +{ + if ( pp_mode >= STR_UCAP ) + { + p_ps->str_type = str_type_cap; + p_ps->mode = ( pp_mode == STR_UCAP ) ? STR_AUTO : STR_ON_REQ; + } + else + { + p_ps->str_type = 0; + p_ps->mode = pp_mode; + } + +} // port_settings_from_port_parm_mode + + + +/*HDR*/ +void port_parm_mode_from_port_settings( + uint8_t *pp_mode, + const PORT_SETTINGS *p_ps, + int str_type_cap + ) +{ + if ( p_ps->str_type == str_type_cap ) + *pp_mode = ( p_ps->mode == STR_ON_REQ ) ? STR_UCAP_REQ : STR_UCAP; + else + *pp_mode = p_ps->mode; + +} // port_parm_mode_from_port_settings + + + +/*HDR*/ +void port_settings_from_port_parm( + PORT_SETTINGS *p_ps, + int port_num, + const PORT_PARM *p_pp, + int cap_str_idx +) +{ + p_ps->parm = p_pp->com[port_num]; + + port_settings_from_port_parm_mode( p_ps, p_pp->mode[port_num], + cap_str_idx ); + +} // port_info_from_port_parm + + + +/*HDR*/ +void port_parm_from_port_settings( + PORT_PARM *p_pp, + int port_num, + const PORT_SETTINGS *p_ps, + int cap_str_idx +) +{ + p_pp->com[port_num] = p_ps->parm; + + port_parm_mode_from_port_settings( &p_pp->mode[port_num], + p_ps, cap_str_idx ); + +} // port_parm_from_port_settings + + + +/*HDR*/ +uint32_t check_valid_port_info( const PORT_INFO *p_pi, + const STR_TYPE_INFO_IDX str_type_info_idx[], + int n_str_type ) +{ + const PORT_SETTINGS *p_ps = &p_pi->port_settings; + int idx; + uint32_t flags = 0; + + + if ( p_pi->supp_baud_rates & ~_mask( N_MBG_BAUD_RATES ) ) + flags |= MBG_PS_MSK_BAUD_RATE_OVR_SW; // dev. supports more baud rates than driver + + idx = get_baud_rate_idx( p_ps->parm.baud_rate ); + + if ( !_inrange( idx, 0, N_MBG_BAUD_RATES ) || + !_is_supported( idx, p_pi->supp_baud_rates ) ) + flags |= MBG_PS_MSK_BAUD_RATE; + + + if ( p_pi->supp_framings & ~_mask( N_MBG_FRAMINGS ) ) + flags |= MBG_PS_MSK_FRAMING_OVR_SW; // dev. supports more framings than driver + + idx = get_framing_idx( p_ps->parm.framing ); + + if ( !_inrange( idx, 0, N_MBG_FRAMINGS ) || + !_is_supported( idx, p_pi->supp_framings ) ) + flags |= MBG_PS_MSK_FRAMING; + + + if ( p_ps->parm.handshake >= N_COM_HS ) + flags |= MBG_PS_MSK_HS_OVR_SW; // handshake index exceeds max. + + if ( p_ps->parm.handshake != HS_NONE ) // currently no device supports any handshake + flags |= MBG_PS_MSK_HS; // handshake mode not supp. by dev. + + + if ( p_pi->supp_str_types & ~_mask( n_str_type ) ) + flags |= MBG_PS_MSK_STR_TYPE_OVR_SW; // firmware error: more string types supported than reported + + idx = p_ps->str_type; + + if ( idx >= n_str_type ) + flags |= MBG_PS_MSK_STR_TYPE_OVR_DEV; // string type index exceeds max. + else + { + if ( !_is_supported( idx, p_pi->supp_str_types ) ) + flags |= MBG_PS_MSK_STR_TYPE; // string type not supported by this port + else + { + // Use the str_type index to get the supported output mode mask + // from the string type info table. This is required to check + // whether the selected mode is supported by the selected + // string type. + ulong supp_modes = str_type_info_idx[idx].str_type_info.supp_modes; + + if ( supp_modes & ~_mask( N_STR_MODE ) ) + flags |= MBG_PS_MSK_STR_MODE_OVR_SW; // dev. supports more string modes than driver + + idx = p_ps->mode; + + if ( idx >= N_STR_MODE ) // mode is always >= 0 + flags |= MBG_PS_MSK_STR_MODE_OVR_SW; // string mode index exceeds max. + else + if ( !_is_supported( idx, supp_modes ) ) + flags |= MBG_PS_MSK_STR_MODE; // string mode not supp. by this string type and port + } + } + + + if ( p_ps->flags != 0 ) /* currently always 0 */ + flags |= MBG_PS_MSK_FLAGS_OVR_SW | MBG_PS_MSK_FLAGS; + + + return flags; + +} // check_valid_port_info + + + +/*HDR*/ +int valid_port_info( const PORT_INFO *p_pi, + const STR_TYPE_INFO_IDX str_type_info_idx[], + int n_str_type ) +{ + return check_valid_port_info( p_pi, str_type_info_idx, n_str_type ) == 0; + +} // valid_port_info + + + +/*HDR*/ +int setup_port_info_from_port_settings( PORT_INFO_IDX pii[], const PORT_PARM *p_pp, + const RECEIVER_INFO *p_ri ) +{ + int i; + + for ( i = 0; i < p_ri->n_com_ports; i++ ) + { + PORT_INFO_IDX *p_pii = &pii[i]; + PORT_INFO *p_pi = &p_pii->port_info; + + p_pii->idx = i; + port_settings_from_port_parm( &p_pi->port_settings, i, p_pp, 1 ); + + p_pi->supp_baud_rates = DEFAULT_GPS_BAUD_RATES_C166; + p_pi->supp_framings = DEFAULT_GPS_FRAMINGS_C166; + p_pi->supp_str_types = DEFAULT_SUPP_STR_TYPES_GPS; + } + + return MBG_SUCCESS; + +} // setup_port_info_from_port_settings + + + +/*HDR*/ +int setup_default_str_type_info_idx( STR_TYPE_INFO_IDX stii[], const RECEIVER_INFO *p_ri ) +{ + int i; + + for ( i = 0; i < p_ri->n_str_type; i++ ) + { + STR_TYPE_INFO_IDX *stip = &stii[i]; + stip->idx = i; + stip->str_type_info = default_str_type_info[i]; + } + + return MBG_SUCCESS; + +} // setup_default_str_type_info_idx + + + +/*HDR*/ +int chk_set_n_gnss_supp( ALL_GNSS_INFO *p_agi ) +{ + p_agi->n_gnss_supp = num_bits_set( p_agi->gnss_mode_info.supp_gnss_types ); + + if ( p_agi->n_gnss_supp > N_GNSS_TYPES ) + return MBG_ERR_N_GNSS_EXCEEDS_SUPP; + + return MBG_SUCCESS; + +} // chk_set_n_gnss_supp + + + +/*HDR*/ +/** + * @brief + * + * ### Setup GNSS info from stat_info so we can use the same printing routine + */ +void setup_gps_only_sat_info_idx_from_statinfo( ALL_GNSS_INFO *p_agi ) +{ + STAT_INFO *p_si = &p_agi->stat_info; + GNSS_SAT_INFO_IDX *p_gsii = &p_agi->gnss_sat_info_idx[GNSS_TYPE_GPS]; + GNSS_SAT_INFO *p_gsi = &p_gsii->gnss_sat_info; + + memset( p_gsii, 0, sizeof( *p_gsii ) ); + p_gsii->idx = GNSS_TYPE_GPS; + + p_gsi->gnss_type = GNSS_TYPE_GPS; + p_gsi->svs_in_view = p_si->svs_in_view; + p_gsi->good_svs = p_si->good_svs; + +} // setup_gps_only_sat_info_idx_from_statinfo + + + +/*HDR*/ +/** + * @brief + * + * Setup GNSS info from stat_info so we can use the same printing routine + */ +int setup_gps_only_gnss_info_from_statinfo( ALL_GNSS_INFO *p_agi ) +{ + MBG_GNSS_MODE_INFO *p_gmi = &p_agi->gnss_mode_info; + + memset( p_gmi, 0, sizeof( *p_gmi ) ); + + p_gmi->supp_gnss_types = MBG_GNSS_TYPE_MSK_GPS; + p_gmi->settings.gnss_set = p_gmi->supp_gnss_types; + + memset( p_agi->gnss_sat_info_idx, 0, sizeof( p_agi->gnss_sat_info_idx ) ); + + setup_gps_only_sat_info_idx_from_statinfo( p_agi ); + + return chk_set_n_gnss_supp( p_agi ); + +} // setup_gps_only_gnss_info_from_statinfo + + + +/*HDR*/ +void chk_free_dev_hw_id( DEVICE_INFO *p ) +{ + if ( p->hw_id ) + { + free( p->hw_id ); + p->hw_id = NULL; + } + +} // chk_free_dev_hw_id + + + +/*HDR*/ +int alloc_dev_hw_id( DEVICE_INFO *p, size_t len ) +{ + if ( p->hw_id ) + return MBG_ERR_ALREADY_ALLOC; + + + p->hw_id = (char *) malloc( len ); + + if ( p->hw_id == NULL ) + return MBG_ERR_NO_MEM; + + return MBG_SUCCESS; + +} // alloc_dev_hw_id + + + +/*HDR*/ +const char *get_fw_id_from_hw_id( const char *hw_id ) +{ + int i; + + for ( i = 0; i < N_SUPP_DEV_TOTAL; i++ ) + { + DEVICE_INFO *p = &device_list[i]; + + if ( strlen( p->fw_id ) && p->hw_id ) //### TODO check if this still works as expected + { + if ( strcmp( hw_id, p->hw_id ) == 0 ) + { + if ( strlen( p->fw_id ) > 0 ) + return p->fw_id; + + #if defined( DEBUG ) + fprintf( stderr, "Length of fw_id is 0 in %s for device %i (%s)\n", + __func__, i, p->hw_id ); + #endif + } + } + } + + return NULL; + +} // get_fw_id_from_hw_id + + + +/*HDR*/ +const char *get_hw_id_from_fw_id( const char *fw_id ) +{ + int i; + + for ( i = 0; i < N_SUPP_DEV_TOTAL; i++ ) + { + DEVICE_INFO *p = &device_list[i]; + + if ( strlen( p->fw_id ) && p->hw_id ) //### TODO check if this still works as expected + { + if ( strcmp( fw_id, p->fw_id ) == 0 ) + { + if ( strlen( p->hw_id ) > 0 ) + return p->hw_id; + + #if defined( DEBUG ) + fprintf( stderr, "Length of hw_id is 0 in %s for device %i (%s)\n", + __func__, i, p->fw_id ); + #endif + } + } + } + + return NULL; + +} // get_hw_id_from_fw_id + + + +/*HDR*/ +/** + * @brief Returns the currently used ::MBG_IO_PORT_TYPE_INFO_IDX for the appropriate ::MBG_IO_PORT_INFO_IDX + * + * @param[in] all_io_port_info Pointer to the ::ALL_IO_PORT_INFO, containing the current configuration + * @param[in] io_port_info_idx Pointer to the ::MBG_IO_PORT_INFO_IDX, for which the ::MBG_IO_PORT_TYPE_INFO_IDX shall be found + * + * @return Pointer to the found ::MBG_IO_PORT_TYPE_INFO_IDX or NULL + * + */ +MBG_IO_PORT_TYPE_INFO_IDX *get_io_port_type_info_idx(ALL_IO_PORT_INFO *all_io_port_info, MBG_IO_PORT_INFO_IDX *io_port_info_idx) +{ + uint8_t i; + + if(!all_io_port_info || !io_port_info_idx) + return NULL; + + for(i = 0; i < io_port_info_idx->info.num_types; ++i) + { + if(all_io_port_info->pt_infos[io_port_info_idx->idx][i].info.port_type == io_port_info_idx->info.settings.type) + { + if(all_io_port_info->pt_infos[io_port_info_idx->idx][i].info.port_type == MBG_IO_PORT_TYPE_GPIO) + { + if(all_io_port_info->pt_infos[io_port_info_idx->idx][i].info.data.gpio_limits.type == io_port_info_idx->info.settings.data.gpio_settings.type) + return &all_io_port_info->pt_infos[io_port_info_idx->idx][i]; + } + else return &all_io_port_info->pt_infos[io_port_info_idx->idx][i]; + } + } + + return NULL; + +} + + + +/*HDR*/ +/** + * @brief Initializes a ::MBG_TLV_ANNOUNCE structure + * + * @param[out] tlv Pointer to a ::MBG_TLV_ANNOUNCE structure + * @param[in] uid Unique sender ID used as identifier with all + * subsequent messages related to this transaction. + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] total_bytes Total number of bytes of all upcoming TLVs + */ +void mbg_tlv_announce_init( MBG_TLV_ANNOUNCE *tlv, MBG_TLV_UID uid, + MBG_TLV_TYPE tlv_feat_type, uint32_t total_bytes ) +{ + memset( tlv, 0, sizeof( *tlv ) ); + tlv->data.uid = uid; + tlv->data.type = tlv_feat_type; + tlv->data.total_bytes = total_bytes; + tlv->data.reserved_1 = 0; + tlv->reserved_1 = 0; + tlv->reserved_2 = 0; + +} // mbg_tlv_announce_init + + + +/*HDR*/ +/** + * @brief Initializes a ::MBG_TLV + * + * @param[out] tlv Pointer to a valid ::MBG_TLV structure + * @param[in] uid Unique sender ID used as identifier for each further + * TLV message related to this type. + * @param[in] tlv_type Type identifier, see ::MBG_TLV_TYPES + * @param[in] total_bytes Total number of bytes belonging to this + * TLV transaction (which is very likely split into several TLVs) + */ +void mbg_tlv_init( MBG_TLV *tlv, MBG_TLV_UID uid, + MBG_TLV_TYPE tlv_type, uint32_t total_bytes ) +{ + memset( tlv, 0, sizeof( *tlv ) ); + tlv->hdr.uid = uid; + tlv->hdr.tlv_type = tlv_type; + tlv->hdr.cur_bytes = 0; + tlv->hdr.trans_bytes = 0; + tlv->hdr.total_bytes = total_bytes; + tlv->hdr.reserved_1 = 0; + tlv->hdr.reserved_2 = 0; + tlv->hdr.reserved_3 = 0; + +} // mbg_tlv_init + + + +/*HDR*/ +/** + * @brief Initializes ::MBG_TLV_RCV_STATE structure + * + * @param[in,out] state Pointer to ::MBG_TLV_RCV_STATE structure + * @param[in] uid Unique sender ID used as identifier for each further + * TLV message related to this type. + * @param[in] total_bytes Total number of bytes belonging to this + * TLV transaction (which is very likely split into several TLVS) + */ +void mbg_tlv_rcv_state_init( MBG_TLV_RCV_STATE *state, MBG_TLV_UID uid, uint32_t total_bytes ) +{ + state->data.uid = uid; + state->data.type = 0; + state->data.total_bytes = total_bytes; + state->data.reserved_1 = 0; + state->read_bytes = 0; + state->reserved_1 = 0; + +} // mbg_tlv_state_init + + + +/*HDR*/ +size_t mbg_snprint_revision( char *buf, size_t buflen, + const char *prefix, const char *suffix, + uint32_t rev) +{ + size_t bytes = 0; + uint32_t major, minor, patch; + + if ( prefix ) + bytes += snprintf_safe( &buf[bytes], buflen, "%s", prefix ); + + _mbg_decode_revision( rev, major, minor, patch ); + bytes += snprintf_safe( &buf[bytes], buflen - bytes, "%u.%u.%u", + major, minor, patch); + + if ( suffix ) + bytes += snprintf_safe( &buf[bytes], buflen - bytes, "%s", suffix ); + + return bytes; + +} // mbg_snprint_revision + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_xbp_supp_nodes( const ALL_XBP_INFO *info ) +{ + if ( info ) + { + if ( ( info->limits.features & XBP_FEAT_MASK_NODES ) == XBP_FEAT_MASK_NODES ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + } + + return MBG_ERR_INV_PARM; + +} // chk_dev_xbp_supp_nodes + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_net_cfg_supp_stage_2( const ALL_NET_CFG_INFO *info ) +{ + if ( info->glb_cfg_info.feat_flags & MBG_NET_GLB_SUPP_STAGE_2_MASK ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_net_cfg_supp_stage_2 + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_ntp_supp_client( const ALL_NTP_CFG_INFO *info ) +{ + if ( ( ( info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT ) == NTP_MSK_ROLE_CLIENT ) || + ( ( info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT_SERVER ) == NTP_MSK_ROLE_CLIENT_SERVER ) ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_ntp_supp_client + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_ntp_supp_server( const ALL_NTP_CFG_INFO *info ) +{ + if ( ( ( info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_SERVER ) == NTP_MSK_ROLE_SERVER ) || + ( ( info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT_SERVER ) == NTP_MSK_ROLE_CLIENT_SERVER ) ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_ntp_supp_server + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_mrf_none( const ALL_XMULTI_REF_INFO *info ) +{ + if ( ( info->instances.flags & XMRIF_MSK_MRF_NONE_SUPP ) == XMRIF_MSK_MRF_NONE_SUPP ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_xmulti_ref_supp_mrf_none + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_src_info( const ALL_XMULTI_REF_INFO *info ) +{ + if ( ( info->instances.flags & XMRIF_MSK_EXT_SRC_INFO_SUPP ) == XMRIF_MSK_EXT_SRC_INFO_SUPP ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_xmulti_ref_supp_ext_src_info + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_holdover_status( const ALL_XMULTI_REF_INFO *info ) +{ + if ( ( info->instances.flags & XMRIF_MSK_HOLDOVER_STATUS_SUPP ) == XMRIF_MSK_HOLDOVER_STATUS_SUPP ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_xmulti_ref_supp_holdover_status + + +/*HDR*/ +/* + * Type is NOT an index of ::XMULTI_REF_INSTANCES::n_xmr_settings, + * but of ::MULTI_REF_TYPES. + * Depends on chk_dev_supp_xmulti_ref_ext_src_info. + * @see chk_dev_supp_xmulti_ref_ext_src_info + */ +_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_source_stats( const ALL_XMULTI_REF_INFO *info, int type ) +{ + if ( + ( type < N_MULTI_REF ) && + (( info->ext_src_infos[type].info.feat_flags & XMR_EXT_SRC_FEAT_FLAG_MSK_STATS ) == XMR_EXT_SRC_FEAT_FLAG_MSK_STATS ) + ) return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_xmulti_ref_supp_ext_source_stats + + +/*HDR*/ +/* + * Type is NOT an index of ::XMULTI_REF_INSTANCES::n_xmr_settings, + * but of ::MULTI_REF_TYPES. + * Depends on chk_dev_supp_xmulti_ref_ext_src_info. + * @see chk_dev_supp_xmulti_ref_ext_src_info + */ +_NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_source_metrics( const ALL_XMULTI_REF_INFO *info, int type ) +{ + if ( + ( type < N_MULTI_REF ) && + (( info->ext_src_infos[type].info.feat_flags & XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS ) == XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS ) + ) return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_xmulti_ref_supp_ext_source_metrics + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_ims_has_fdm( const ALL_IMS_INFO *info ) +{ + if ( ( info->state.flags & MBG_IMS_STATE_FLAG_MSK_HAS_FDM ) == MBG_IMS_STATE_FLAG_MSK_HAS_FDM ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_ims_has_fdm + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_volt_out_enabled( const ALL_IMS_STATE *ims_state, unsigned idx ) +{ + const MBG_IMS_SENSOR_STATE *sstate = &ims_state->sensor_state_idx[idx].state; + + if ( + ( sstate->type == MBG_IMS_SENSOR_VOLTAGE ) && + ( ( sstate->flags & MBG_IMS_SENSOR_VOLTAGE_OUT_ENB ) == MBG_IMS_SENSOR_VOLTAGE_OUT_ENB ) + ) return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_ims_is_volt_out_enabled + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_volt_out_overload( const ALL_IMS_STATE *ims_state, unsigned idx ) +{ + const MBG_IMS_SENSOR_STATE *sstate = &ims_state->sensor_state_idx[idx].state; + + if ( + ( sstate->type == MBG_IMS_SENSOR_VOLTAGE ) && + ( ( sstate->flags & MBG_IMS_SENSOR_VOLTAGE_OUT_OVR ) == MBG_IMS_SENSOR_VOLTAGE_OUT_OVR ) + ) return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_ims_is_volt_out_overload + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_pll_locked( const ALL_IMS_STATE *ims_state, unsigned idx ) +{ + const MBG_IMS_SENSOR_STATE *sstate = &ims_state->sensor_state_idx[idx].state; + + if ( + ( sstate->type == MBG_IMS_SENSOR_PLL ) && + ( ( sstate->flags & MBG_IMS_SENSOR_PLL_LOCKED ) == MBG_IMS_SENSOR_PLL_LOCKED ) + ) return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_ims_is_pll_locked + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_supp_ass_idx( const ALL_GPIO_INFO *gpio_info, unsigned idx ) +{ + const MBG_GPIO_LIMITS *limits = &gpio_info->infos[idx].info.limits; + + if ( ( limits->supp_flags & MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX ) == MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_gpio_supp_ass_idx + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_dep_on_ass_idx( const ALL_GPIO_INFO *gpio_info, unsigned idx ) +{ + const MBG_GPIO_SETTINGS *settings = &gpio_info->infos[idx].info.settings; + + if ( ( settings->flags & MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX ) == MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_gpio_dep_on_ass_idx + + +/*HDR*/ +/** + * @brief Checks whether GPIO supports status function + * + * @param[out] info Pointer to a ::ALL_GPIO_INFO structure to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::mbg_chk_dev_supp_gpio + * @see ::free_all_gpio_info + */ +_NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_has_status( const ALL_GPIO_INFO *info ) +{ + if ( ( info->cfg_limits.flags & MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP ) == MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // chk_dev_gpio_has_status + + + +/*HDR*/ +/** + * @brief Frees ::ALL_XBP_INFO structure + * + * @param[in] p Pointer to the ::ALL_XBP_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_xbp_info + */ +void free_all_xbp_info ( ALL_XBP_INFO *p ) +{ + if ( p ) + { + if ( p->node_limits ) + free( p->node_limits ); + + if ( p->node_infos ) + free( p->node_infos ); + + free( p ); + } + +} // free_all_xbp_info + + + +/*HDR*/ +/** + * @brief Frees ::ALL_NET_CFG_INFO structure + * + * @param[in] p Pointer to the ::ALL_NET_CFG_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_net_cfg_info + */ +void free_all_net_cfg_info ( ALL_NET_CFG_INFO *p ) +{ + if ( p ) + { + if ( p->link_infos ) + free( p->link_infos ); + + if ( p->addr_infos ) + free( p->addr_infos ); + + if ( p->dns_srvrs ) + free( p->dns_srvrs ); + + if ( p->dns_srch_doms ) + free( p->dns_srch_doms ); + + if ( p->route_infos ) + free( p->route_infos ); + + free( p ); + } + +} // free_all_net_cfg_info + + + +/*HDR*/ +/** + * @brief Frees ::ALL_NET_STATUS_INFO structure + * + * @param[in] p Pointer to the ::ALL_NET_STATUS_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_net_status_info + */ +void free_all_net_status_info ( ALL_NET_STATUS_INFO *p ) +{ + if ( p ) + { + if ( p->link_infos ) + free( p->link_infos ); + + if ( p->addr_infos ) + free( p->addr_infos ); + + if ( p->dns_srvrs ) + free( p->dns_srvrs ); + + if ( p->dns_srch_doms ) + free( p->dns_srch_doms ); + + if ( p->route_infos ) + free( p->route_infos ); + + free( p ); + } + +} // free_all_net_status_info + + + +/*HDR*/ +/** + * @brief Frees ::ALL_SNMP_INFO structure + * + * @param[in] p Pointer to the ::ALL_SNMP_INFO structure, which will be freed + * + */ +void free_all_snmp_info ( ALL_SNMP_INFO *p ) +{ + if ( p ) + { + if ( p->v12_infos ) + free( p->v12_infos ); + + if ( p->v12_trap_infos ) + free( p->v12_trap_infos ); + + if ( p->v3_infos ) + free( p->v3_infos ); + + if ( p->v3_trap_infos ) + free( p->v3_trap_infos ); + + free( p ); + } + +} // free_all_snmp_info + + + +/*HDR*/ +/** + * @brief Frees ::ALL_MONITORING_INFO structure + * + * @param[in] p Pointer to the ::ALL_MONITORING_INFO structure, which will be freed + * + */ +void free_all_monitoring_info ( ALL_MONITORING_INFO *p ) +{ + if ( p ) + { + if ( p->all_snmp_info ) + free_all_snmp_info( p->all_snmp_info ); + + if ( p->event_infos ) + free( p->event_infos ); + + free ( p ); + } +} + + +/*HDR*/ +/** + * @brief Frees ::ALL_MONITORING_STATUS structure + * + * @param[in] p Pointer to the ::ALL_MONITORING_STATUS structure, which will be freed + * + */ +void free_all_monitoring_status ( ALL_MONITORING_STATUS *p ) +{ + if ( p ) + { + if ( p->event_stati ) + free( p->event_stati ); + + free ( p ); + } +} + + + +/*HDR*/ +/** + * @brief Frees ::ALL_XMULTI_REF_INFO structure + * + * @param[in] p Pointer to the ::ALL_XMULTI_REF_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_xmulti_ref_info + * @see ::mbg_get_all_xmulti_ref_info + */ +void free_all_xmulti_ref_info( ALL_XMULTI_REF_INFO *p ) +{ + if ( p ) + { + if ( p->infos ) + free( p->infos ); + + if ( p->ext_src_infos ) + free( p->ext_src_infos ); + + free ( p ); + } + +} // free_all_xmulti_ref_info + + + +/*HDR*/ +/** + * @brief Frees ::ALL_XMULTI_REF_STATUS structure + * + * @param[in] p Pointer to the ::ALL_XMULTI_REF_STATUS structure, which will be freed + * + * @see ::mbgextio_get_all_xmulti_ref_status + * @see ::mbg_get_all_xmulti_ref_status + */ +void free_all_xmulti_ref_status( ALL_XMULTI_REF_STATUS *p ) +{ + if ( p ) + { + if ( p->status ) + free( p->status ); + + if ( p->holdover_status ) + free( p->holdover_status ); + + if ( p->stats_idx ) + free( p->stats_idx ); + + if ( p->metrics_idx ) + free( p->metrics_idx ); + + free( p ); + } + +} // free_all_xmulti_ref_status + + + +/*HDR*/ +/** + * @brief Frees ::ALL_PTP_V1_COMMON_DATASETS structure allocated by ::mbgextio_get_all_ptp_v1_common_datasets + * + * @param[in] p Pointer to the ::ALL_PTP_V1_COMMON_DATASETS structure, which will be freed + * + * @see ::mbgextio_get_all_ptp_v1_common_datasets + */ +void free_all_ptp_v1_common_datasets( ALL_PTP_V1_COMMON_DATASETS *p ) +{ + if ( p ) + { + if ( p->port_datasets ) + free( p->port_datasets ); + + free( p ); + } + +} // free_all_ptp_v1_common_datasets + + + +/*HDR*/ +/** + * @brief Frees ::ALL_PTP_V2_COMMON_DATASETS structure allocated by ::mbgextio_get_all_ptp_v2_common_datasets + * + * @param[in] p Pointer to the ::ALL_PTP_V2_COMMON_DATASETS structure, which will be freed + * + * @see ::mbgextio_get_all_ptp_v2_common_datasets + */ +void free_all_ptp_v2_common_datasets( ALL_PTP_V2_COMMON_DATASETS *p ) +{ + if ( p ) + { + if ( p->port_datasets ) + free( p->port_datasets ); + + free( p ); + } + +} // free_all_ptp_v2_common_datasets + + + +/*HDR*/ +/** + * @brief Frees ::ALL_NTP_CFG_INFO structure + * + * @param[in] p Pointer to the ::ALL_NTP_CFG_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_ntp_cfg_info + */ +void free_all_ntp_cfg_info( ALL_NTP_CFG_INFO *p ) +{ + if ( p ) + { + if ( p->symm_key_limits ) + free( p->symm_key_limits ); + + if ( p->symm_key_info_idx ) + free( p->symm_key_info_idx ); + + if ( p->trusted_key_info_idx ) + free( p->trusted_key_info_idx ); + + if ( p->clnt_info ) + free( p->clnt_info ); + + if ( p->peer_settings_idx ) + free( p->peer_settings_idx ); + + if ( p->srv_info ) + free( p->srv_info ); + + if ( p->refclk_info_idx ) + free( p->refclk_info_idx ); + + if ( p->misc_limits ) + free( p->misc_limits ); + + if ( p->orphan_mode_info ) + free( p->orphan_mode_info ); + + free( p ); + } + +} // free_all_ntp_cfg_info + + + +/*HDR*/ +/** + * @brief Frees ::ALL_NTP_STATUS structure + * + * @param[in] p Pointer to the ::ALL_NTP_STATUS structure, which will be freed + * + * @see ::mbgextio_get_all_ntp_status + */ +void free_all_ntp_status( ALL_NTP_STATUS *p ) +{ + if ( p ) + { + if ( p->peer_states ) + free( p->peer_states ); + + free( p ); + } + +} // free_all_ntp_status + + + +/*HDR*/ +/** + * @brief Frees memory allocated by ::mbgextio_get_all_ims_info + * + * @param[in] p Pointer to the ::ALL_IMS_INFO structure, which will be freed + * + * @see ::mbgextio_dev_has_ims + * @see ::mbgextio_dev_ims_has_fdm + * @see ::mbgextio_get_all_ims_info + * @see ::mbgextio_get_all_ims_state + */ +void free_all_ims_info( ALL_IMS_INFO *p ) +{ + if ( p ) + { + if ( p->fdm_info ) + free( p->fdm_info ); + + if ( p->fdm_limits ) + free( p->fdm_limits ); + + if ( p->fdm_outinfo_idx ) + free( p->fdm_outinfo_idx ); + + free( p ); + } + +} // free_all_ims_info + + + +/*HDR*/ +/** + * @brief Frees memory allocated by ::mbgextio_get_all_ims_state + * + * @param[in] p Pointer to the ::ALL_IMS_STATE structure, which will be freed + * + * @see ::mbgextio_dev_has_ims + * @see ::mbgextio_dev_ims_has_fdm + * @see ::mbgextio_get_all_ims_info + * @see ::mbgextio_get_all_ims_state + */ +void free_all_ims_state( ALL_IMS_STATE *p ) +{ + if ( p ) + { + if ( p->sensor_state_idx ) + free( p->sensor_state_idx ); + + if ( p->fdm_state ) + free( p->fdm_state ); + + if ( p->fdm_output_state_idx ) + free( p->fdm_output_state_idx ); + + free( p ); + } + +} // free_all_ims_state + + + +/*HDR*/ +/** + * @brief Frees memory allocated by ::mbgextio_get_all_gpio_info + * + * @param[in] p Pointer to the ::ALL_GPIO_INFO structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::mbgextio_get_all_gpio_info + */ +void free_all_gpio_info( ALL_GPIO_INFO *p ) +{ + if ( p ) + { + if ( p->infos ) + free( p->infos ); + + free( p ); + } + +} // free_all_gpio_info + + + +/*HDR*/ +/** + * @brief Frees memory allocated by ::mbgextio_get_all_io_port_info + * + * @param[in] p Pointer to the ::ALL_IO_PORT_INFO structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_io_ports + * @see ::mbgextio_get_all_io_port_info + * @see ::mbgextio_get_all_io_port_status + * @see ::free_all_io_port_status + */ +void free_all_io_port_info( ALL_IO_PORT_INFO *p ) +{ + uint8_t i; + + if ( p ) + { + if ( p->pt_infos ) + { + for ( i = 0; i < p->limits.num_ports; ++i ) + { + if ( p->pt_infos[i] ) + free( p->pt_infos[i] ); + } + + free ( p->pt_infos ); + } + + if ( p->p_infos ) + free( p->p_infos ); + + free( p ); + } + +} // free_all_io_port_info + + + +/*HDR*/ +/** + * @brief Frees memory allocated by ::mbgextio_get_all_io_port_status + * + * @param[in] p Pointer to the ::ALL_IO_PORT_STATUS structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_io_ports + * @see ::mbgextio_get_all_io_port_info + * @see ::mbgextio_get_all_io_port_status + * @see ::free_all_io_port_info + */ +void free_all_io_port_status( ALL_IO_PORT_STATUS *p ) +{ + if ( p ) + { + if ( p->status ) + free ( p->status ); + + free( p ); + } + +} // free_all_io_port_status + + + +/*HDR*/ +/** + * @brief Frees memory allocated by ::mbgextio_get_all_gpio_state + * + * @param[in] p Pointer to the ::ALL_GPIO_STATE structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::mbgextio_get_all_gpio_state + */ +void free_all_gpio_state( ALL_GPIO_STATE *p ) +{ + if ( p ) + { + if ( p->states ) + free( p->states ); + + free( p ); + } + +} // free_all_gpio_state + + + +/*HDR*/ +/** + * Allocates memory for a new ::UCAP_ENTRY structure + * + * @return The new allocated ::UCAP_ENTRY or NULL if the calloc call was not successful + */ +UCAP_ENTRY* calloc_ucap_entry( void ) +{ + UCAP_ENTRY *entry = (UCAP_ENTRY *) calloc( 1, sizeof( *entry ) ); + if ( entry ) + { + mbg_klist_init(&entry->head); + } + return entry; + +} // calloc_ucap_entry + + +/*HDR*/ +/** + * @brief Frees memory allocated by ::mbgextio_get_all_ucap_info + * + * @param[in] p Pointer to the ::ALL_UCAP_INFO structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap + * @see ::mbg_chk_dev_has_ucap + * @see ::mbgextio_get_all_ucap_info + * @see ::mbg_get_all_ucap_info + */ +void free_all_ucap_info( ALL_UCAP_INFO *p ) +{ + if ( p ) + { + UCAP_ENTRY *entry; + + while ( !mbg_klist_is_empty( &p->list ) ) + { + entry = mbg_klist_first_entry( &p->list, UCAP_ENTRY, head ); + mbg_klist_delete_item( &entry->head ); + free( entry ); + } + + free( p ); + } + +} // free_all_ucap_info + + +/*HDR*/ +/** + * @brief Frees ::ALL_UCAP_NET_INFO structure + * + * @param[in] p Pointer to the ::ALL_UCAP_NET_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_ucap_net_info + */ +void free_all_ucap_net_info( ALL_UCAP_NET_INFO *p ) +{ + if ( p ) + { + if ( p->recv_infos ) + free( p->recv_infos ); + + free( p ); + } + +} // free_all_ucap_net_info + + diff --git a/mbglib/common/cfg_hlp.h b/mbglib/common/cfg_hlp.h index 46609c1..075523b 100644 --- a/mbglib/common/cfg_hlp.h +++ b/mbglib/common/cfg_hlp.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: cfg_hlp.h 1.3.1.19 2014/10/29 16:25:31Z martin TEST martin $ + * $Id: cfg_hlp.h 1.3.1.100 2017/03/29 12:33:26Z philipp TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -19,7 +19,165 @@ * * ----------------------------------------------------------------------- * $Log: cfg_hlp.h $ - * Revision 1.3.1.19 2014/10/29 16:25:31Z martin + * Revision 1.3.1.100 2017/03/29 12:33:26Z philipp + * Extended event info and event status index structures by data pointer + * Revision 1.3.1.99 2017/03/27 10:37:18 thomas-b + * Added ALL_PTP_V1_COMMON_DATASETS and the appropriate free function + * Revision 1.3.1.98 2017/03/22 09:07:53 thomas-b + * Added function get_io_port_type_info_idx + * Revision 1.3.1.97 2017/03/17 12:01:02 martin + * Moved definitions of PCPS_HRT_FRAC_CONVERSION_TYPE, + * PCPS_HRT_BIN_FRAC_SCALE, and PCPS_HRT_FRAC_SCALE_FMT + * here. + * Revision 1.3.1.96 2017/03/17 11:45:17 martin + * Moved binary fraction conversion functions here. + * Revision 1.3.1.95 2017/03/02 14:03:00 gregoire + * ALL_NTP_CFG_INFO reworked + * Revision 1.3.1.94 2017/03/02 08:34:08 gregoire + * ALL_NTP_CFG_INFO: NTP_REFCLK_CFG_INFO_IDX added + * Revision 1.3.1.93 2017/02/28 15:25:17 gregoire + * ALL_NTP_CFG_INFO extended + * Revision 1.3.1.92 2017/02/24 09:38:25 philipp + * Do not use fixed buffers for monitorung event info and status + * Revision 1.3.1.91 2017/02/22 11:40:17 martin + * Account for preliminary code. + * Revision 1.3.1.90 2017/02/21 15:51:40 thomas-b + * Added ALL_MONITORING_STATUS and free function and extended ALL_MONITORING_INFO by events + * Revision 1.3.1.89 2017/02/16 12:58:01 thomas-b + * Added ALL_PTP_V2_COMMON_DATASETS structure and the appropriate free function + * Revision 1.3.1.88 2017/02/08 13:16:08 thomas-b + * Added ALL_MONITORING_INFO and the appropriate free function + * Revision 1.3.1.87 2017/02/07 09:46:51 thomas-b + * Added ALL_SNMP_INFO and the appropriate free function + * Revision 1.3.1.86 2016/12/19 12:13:55 philipp + * Added GPIO associated index helper + * Revision 1.3.1.85 2016/12/13 13:46:22 martin + * Increased MAX_PARM_PORT and MAX_PARM_POUT to 10. + * Revision 1.3.1.84 2016/11/22 12:40:46Z philipp + * Added I/O port helper functions + * Revision 1.3.1.83 2016/11/08 17:21:35 martin + * Updated function prototypes. + * Revision 1.3.1.82 2016/11/01 09:24:02 martin + * *** empty log message *** + * Revision 1.3.1.81 2016/10/25 07:48:27 martin + * Doxygen fixes. + * Revision 1.3.1.80 2016/10/21 09:39:26 thomas-b + * Added struct ALL_XBP_INFO and appropriate free function + * Revision 1.3.1.79 2016/10/14 11:10:03 thomas-b + * Added ALL_UCAP_NET_INFO and the appropriate free function + * Revision 1.3.1.78 2016/09/28 15:04:03 thomas-b + * Added function to check whether NET_CFG_API stage 2 is supported + * Revision 1.3.1.77 2016/08/11 13:25:06 martin + * Use mbgklist.h instead of mbg_klist.h. + * Revision 1.3.1.76 2016/08/11 08:36:56Z martin + * Exclude function prototypes from build for kernel space. + * Revision 1.3.1.75 2016/08/10 12:25:02Z martin + * Support FreeBSD. + * Revision 1.3.1.74 2016/08/09 07:09:28 martin + * Support QNX Neutrino. + * Revision 1.3.1.73 2016/06/21 12:06:59 thomas-b + * Added function calloc_ucap_entry + * Revision 1.3.1.72 2016/06/21 07:39:21 philipp + * Use mbg_klist for ucap events and not an array -> Easier to handle MAX_UCAP_ENTRIES + * Revision 1.3.1.71 2016/06/16 07:46:45 philipp + * Fixed checking flags for IMS sensor specific features + * Revision 1.3.1.70 2016/06/15 14:04:27 thomas-b + * Added ALL_UCAP_INFO structure and function free_all_ucap_info + * Revision 1.3.1.69 2016/06/02 10:24:22 philipp + * Renaming all revision macros and helper functions + * Revision 1.3.1.68 2016/05/31 11:29:15 philipp + * Extended ALL_XMULTI_REF_STATUS by flags if at least one ref type supports stats and/or metrics + * Revision 1.3.1.67 2016/05/27 05:48:08 philipp + * Refactoring to support XMR_METRICS properly + * Revision 1.3.1.66 2016/05/26 11:01:03 thomas-b + * Removed info structures from ALL_NTP_STATUS + * Moved check functions of specific features to cfg_hlp + * Revision 1.3.1.65 2016/05/25 08:43:36 philipp + * Redesign of ALL_[xxx]_[XXX] structures and (helper) functions + * Revision 1.3.1.64 2016/05/23 09:37:40 philipp + * Extended ALL_XMULTI_REF_STATUS by holdover_status + * Revision 1.3.1.63 2016/05/23 08:59:03 philipp + * New function free_all_gpio_state + * Revision 1.3.1.62 2016/05/23 08:24:38 philipp + * New function free_all_ims_state + * Revision 1.3.1.61 2016/05/11 13:20:59 thomas-b + * Added ALL_NET_STATUS_INFO and the appropriate free function + * Revision 1.3.1.60 2016/04/26 14:21:58 thomas-b + * Renamed ALL_NET_CFG_INFO structure members + * Revision 1.3.1.59 2016/04/26 08:23:45 thomas-b + * Extended ALL_NET_CFG_INFO by DNS configurations + * Revision 1.3.1.58 2016/04/26 06:29:30 thomas-b + * Added ALL_NET_CFG_INFO for network configuration + * Revision 1.3.1.57 2016/04/25 11:22:31 martin + * Revision 1.3.1.56 2016/04/25 10:43:38Z martin + * *** empty log message *** + * Revision 1.3.1.55 2016/04/22 07:11:50 philipp + * Use pointer to pointer in get_all_* functions + * Revision 1.3.1.54 2016/04/20 14:45:46 thomas-b + * Renamed ALL_NTP_STATE_INFO to ALL_NTP_STATUS + * Revision 1.3.1.53 2016/04/20 13:49:13 thomas-b + * Added structure definitions and free functions for NTP + * Revision 1.3.1.52 2016/04/20 12:37:53 thomas-b + * Moved free functions for ALL_XMULTI_REF_INFO and ALL_XMULTI_REF_STATUS to cfg_hlp + * Revision 1.3.1.51 2016/04/12 13:28:39 philipp + * New helper functions to get all feature related structures at once + * Revision 1.3.1.50 2016/04/12 08:25:10 thomas-b + * Added ALL_XMULTI_REF_STATUS structure + * Revision 1.3.1.49 2016/04/11 13:56:24 thomas-b + * Added ALL_XMULTI_REF_INFO structure + * Revision 1.3.1.48 2016/04/08 07:54:26 philipp + * Added function prototype mbg_print_ext_rev_info + * Revision 1.3.1.47 2016/04/04 15:08:45 martin + * Replaced chk_model_is_vsg() by xdevfeat::xdevfeat_is_vsg(). + * Revision 1.3.1.46 2016/03/03 11:20:30 martin + * Updated function prototypes. + * Revision 1.3.1.45 2016/02/17 12:00:07Z gregoire + * new function chk_model_is_vsg + * Revision 1.3.1.44 2016/02/10 15:45:32Z martin + * *** empty log message *** + * Revision 1.3.1.43 2015/11/24 13:12:04 philipp + * Extended / modified TLV functions + * Revision 1.3.1.42 2015/11/23 14:15:40 philipp + * Moved TLV related initializing functions to here + * Revision 1.3.1.41 2015/11/20 14:51:10 martin + * Revision 1.3.1.40 2015/11/02 11:00:48Z martin + * *** empty log message *** + * Revision 1.3.1.39 2015/11/02 09:20:02 martin + * *** empty log message *** + * Revision 1.3.1.38 2015/10/27 16:21:31 martin + * Older defines N_SUPP_DEV, PCPS_MAX_DDEVS, and MBG_MAX_DEVICES + * have been obsoleted by new defines N_SUPP_DEV_BUS, N_SUPP_DEV_EXT, + * and N_SUPP_DEV_TOTAL. + * Revision 1.3.1.37 2015/10/26 16:31:53 martin + * *** empty log message *** + * Revision 1.3.1.36 2015/10/26 14:18:34 martin + * Revision 1.3.1.35 2015/10/15 12:49:10Z marvin + * Revision 1.3.1.34 2015/10/12 10:01:59Z martin + * *** empty log message *** + * Revision 1.3.1.33 2015/10/08 13:27:37 martin + * *** empty log message *** + * Revision 1.3.1.32 2015/10/08 10:32:16 martin + * *** empty log message *** + * Revision 1.3.1.31 2015/10/08 09:30:34 martin + * *** empty log message *** + * Revision 1.3.1.30 2015/10/07 10:12:08 martin + * *** empty log message *** + * Revision 1.3.1.29 2015/10/07 10:08:34 martin + * *** empty log message *** + * Revision 1.3.1.28 2015/10/07 09:59:00 martin + * More common GNSS support. + * Revision 1.3.1.27 2015/09/15 09:10:40 martin + * Updated function prototypes. + * Revision 1.3.1.26 2015/09/11 12:09:09 thomas-b + * Added nano_time_64_to_tm_gps and tm_gps_to_nano_time_64 functions + * Revision 1.3.1.25 2015/08/31 14:55:11 martin + * Moved string trim functions to str_util module. + * Revision 1.3.1.24 2015/08/31 14:49:25 martin + * Revision 1.3.1.23 2015/08/31 09:58:08 martin + * Revision 1.3.1.22 2015/08/27 16:30:10Z martin + * Revision 1.3.1.21 2015/08/26 07:31:51 martin + * Revision 1.3.1.20 2015/08/21 14:22:59 martin + * Revision 1.3.1.19 2014/10/29 16:25:31 martin * Moved some functions and structures to more convenient files. * Revision 1.3.1.18 2014/10/29 16:00:37 martin * Revision 1.3.1.17 2014/10/29 14:21:55 martin @@ -62,7 +220,20 @@ /* Other headers to be included */ #include <gpsdefs.h> +#include <mbgklist.h> + +#if !defined( MBG_TGT_KERNEL ) + #include <stdlib.h> + #include <string.h> +#endif +#if defined( _PRELIMINARY_CODE ) + #if defined( MBG_TGT_POSIX ) + #include <sys/stat.h> + #include <sys/sysinfo.h> + #include <time.h> + #endif // MBG_TGT_POSIX +#endif // _PRELIMINARY_CODE #ifdef _CFG_HLP #define _ext @@ -78,16 +249,69 @@ extern "C" { #endif -/// @brief The max number of serial ports supported by configuration programs -#define MAX_PARM_PORT 4 -/// @brief An array of configuration settings for all serial ports -typedef PORT_INFO_IDX ALL_PORT_INFO_IDX[MAX_PARM_PORT]; +#if 1 // ### TODO cleanup +#define N_SUPP_DEV_BUS 16 +#define N_SUPP_DEV_EXT 1 + +#define N_SUPP_DEV_TOTAL ( N_SUPP_DEV_BUS + N_SUPP_DEV_EXT ) + +typedef struct _DEVICE_INFO +{ + char *hw_id; + char fw_id[100]; + +} DEVICE_INFO; + +_ext DEVICE_INFO device_list[N_SUPP_DEV_TOTAL]; + +#endif + + + +/// @brief The max number of serial ports supported by configuration programs +#define MAX_PARM_PORT 10 /// @brief The max number of serial string types supported by configuration programs #define MAX_PARM_STR_TYPE 20 +/// @brief The max number of programmable pulse outputs supported by configuration programs +#define MAX_PARM_POUT 10 + +/// @brief The max number of GNSS settings supported by configuration programs +#define MAX_PARM_GNSS_SAT N_GNSS_TYPES + +/// @brief The max number of PTP unicast masters supported by configuration programs +#define MAX_PARM_PTP_UC_MASTER 3 + +/// @brief The max number of external NTP server associations to be handled by configuration programs +#define MAX_PARM_EXT_NTP_SRVR 20 + +/// @brief The max number of GPIO ports supported by configuration programs +#define MAX_PARM_GPIO 10 + +/// @brief The max number of XMR sources supported by configuration programs +#define MAX_PARM_XMR 10 + +/// @brief The max number of external NTP servers supported by configuration programs +#define MAX_EXT_NTP_SERVERS 20 + +/// @brief The max. number of time monitoring modules supported by configuration programs +/// Each module may support a different number of targets to be monitored. +/// @see ### TODO +#define MAX_MBG_TIME_MON_MODULES 10 + +/// @brief The max. number of time monitoring targets supported by configuration programs +/// This is the sum of all targets from all monitoring modules. +/// @see ### TODO +#define MAX_MBG_TIME_MON_TARGETS 100 + + + +/// @brief An array of configuration settings for all serial ports +typedef PORT_INFO_IDX ALL_PORT_INFO_IDX[MAX_PARM_PORT]; + /// @brief An array of configuration settings for all serial string types typedef STR_TYPE_INFO_IDX ALL_STR_TYPE_INFO_IDX[MAX_PARM_STR_TYPE]; @@ -110,8 +334,21 @@ typedef struct -/// @brief The max number of programmable pulse outputs supported by configuration programs -#define MAX_PARM_POUT 4 +/** + * @brief All XBP information of a XBP supporting device + * + * This structure represents a list of connected devices + * + * @see ::GPS_HAS_XBP + */ +typedef struct +{ + XBP_LIMITS limits; + XBP_NODE_LIMITS* node_limits; + XBP_NODE_INFO_IDX* node_infos; +} ALL_XBP_INFO; + + /** * @brief An array of configuration settings for all programmable pulse outputs @@ -125,8 +362,94 @@ typedef POUT_INFO_IDX ALL_POUT_INFO_IDX[MAX_PARM_POUT]; -/// @brief The max number of PTP unicast masters supported by configuration programs -#define MAX_PARM_PTP_UC_MASTER 3 +/** + * @brief All network configuration parameters + * + * Used to collect all configuration parameters for networking + * + * @see ::GPS_HAS_NET_CFG + * @see ::GPS_HAS_LAN_IP4 + */ +typedef struct +{ + MBG_NET_GLB_CFG_INFO glb_cfg_info; + MBG_NET_INTF_LINK_INFO_IDX *link_infos; + MBG_NET_INTF_ADDR_INFO_IDX *addr_infos; + MBG_IP_ADDR_IDX *dns_srvrs; + MBG_NET_NAME_IDX *dns_srch_doms; + MBG_NET_INTF_ROUTE_INFO_IDX *route_infos; +} ALL_NET_CFG_INFO; + +typedef ALL_NET_CFG_INFO ALL_NET_STATUS_INFO; + + + +/** + * @brief All SNMP configuration information + * + * Used to collect all configuration parameters for monitoring via SNMP + * Can be used, if ::MBG_MONITORING_TYPE_MSK_SNMP is set in ::MBG_MONITORING_LIMITS::supp_types + * + * @see ::MBG_XFEATURE_MONITORING + */ +typedef struct +{ + MBG_SNMP_GLB_INFO glb_info; + MBG_SNMP_V12_INFO_IDX *v12_infos; + MBG_SNMP_V12_TRAP_INFO_IDX *v12_trap_infos; + MBG_SNMP_V3_INFO_IDX *v3_infos; + MBG_SNMP_V3_TRAP_INFO_IDX *v3_trap_infos; + +} ALL_SNMP_INFO; + + +/** + * @brief All monitoring information + * + * Used to collect all configuration parameters for monitoring of a device + * Depending on the ::MBG_MONITORING_LIMITS::supp_types, + * the approriate configurations can be found in the sub structures + * + * @see ::MBG_XFEATURE_MONITORING + */ +typedef struct +{ + MBG_EVENT_INFO_IDX info; + void *priv_data; + +} MBG_EVENT_INFO_IDX_DATA; + +typedef struct +{ + MBG_MONITORING_LIMITS limits; + ALL_SNMP_INFO *all_snmp_info; + MBG_EVENT_INFO_IDX_DATA *event_infos; + +} ALL_MONITORING_INFO; + + + +/** + * @brief All monitoring status + * + * Used to collect all status information for monitoring of a device + * Depending on the ::MBG_MONITORING_LIMITS::supp_events, the + * appropriate event status for each event can be found in ::event_stati. + */ +typedef struct +{ + MBG_EVENT_STATUS_IDX status; + void *priv_data; + +} MBG_EVENT_STATUS_IDX_DATA; + +typedef struct +{ + MBG_MONITORING_STATUS status; + MBG_EVENT_STATUS_IDX_DATA *event_stati; + +} ALL_MONITORING_STATUS; + /// @brief Configuration settings for all unicast master specifications typedef PTP_UC_MASTER_INFO_IDX ALL_PTP_UC_MASTER_INFO_IDX[MAX_PARM_PTP_UC_MASTER]; @@ -150,8 +473,55 @@ typedef struct -/// @brief The max number of GNSS settings supported by configuration programs -#define MAX_PARM_GNSS_SAT N_GNSS_TYPES +/** + * @brief All PTPv1 common datasets for a PTP device + * + * Contains one of each common datasets plus one port dataset + * for each port of a device. The number of port datasets is + * defined in ::default_dataset::number_ports. + * + * @see ::MBG_PTP_V1_DEFAULT_DATASET + * @see ::MBG_PTP_V1_CURRENT_DATASET + * @see ::MBG_PTP_V1_PARENT_DATASET + * @see ::MBG_PTP_V1_TIME_PROPERTIES_DATASET + * @see ::MBG_PTP_V1_PORT_DATASET_IDX + */ +typedef struct +{ + MBG_PTP_V1_DEFAULT_DATASET default_dataset; + MBG_PTP_V1_CURRENT_DATASET current_dataset; + MBG_PTP_V1_PARENT_DATASET parent_dataset; + MBG_PTP_V1_TIME_PROPERTIES_DATASET time_properties_dataset; + MBG_PTP_V1_PORT_DATASET_IDX *port_datasets; + +} ALL_PTP_V1_COMMON_DATASETS; + + + +/** + * @brief All PTPv2 common datasets for a PTP device + * + * Contains one of each common datasets plus one port dataset + * for each port of a device. The number of port datasets is + * defined in ::default_dataset::number_ports. + * + * @see ::MBG_PTP_V2_DEFAULT_DATASET + * @see ::MBG_PTP_V2_CURRENT_DATASET + * @see ::MBG_PTP_V2_PARENT_DATASET + * @see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET + * @see ::MBG_PTP_V2_PORT_DATASET_IDX + */ +typedef struct +{ + MBG_PTP_V2_DEFAULT_DATASET default_dataset; + MBG_PTP_V2_CURRENT_DATASET current_dataset; + MBG_PTP_V2_PARENT_DATASET parent_dataset; + MBG_PTP_V2_TIME_PROPERTIES_DATASET time_properties_dataset; + MBG_PTP_V2_PORT_DATASET_IDX *port_datasets; + +} ALL_PTP_V2_COMMON_DATASETS; + + /** * @brief An array of configuration settings for all programmable pulse outputs @@ -163,11 +533,25 @@ typedef GNSS_SAT_INFO_IDX ALL_GNSS_SAT_INFO_IDX[MAX_PARM_GNSS_SAT]; -/// @brief The max number of NTP server associations to be handled by configuration programs -#define MAX_EXTERNAL_SERVER 20 +/** + * @brief An array of configuration settings for all programmable pulse outputs #### + * + * Used to collect all configuration parameters of a clock's programmable pulse outputs + * that can be handled by a configuration program. ##### + */ +typedef struct +{ + STAT_INFO stat_info; + int n_gnss_supp; + MBG_GNSS_MODE_INFO gnss_mode_info; + ALL_GNSS_SAT_INFO_IDX gnss_sat_info_idx; + +} ALL_GNSS_INFO; + + /// @brief Configuration settings for all NTP server associatioions -typedef NTP_PEER_SETTINGS ALL_NTP_PEER_SETTINGS[MAX_EXTERNAL_SERVER]; +typedef NTP_PEER_SETTINGS ALL_NTP_PEER_SETTINGS[MAX_EXT_NTP_SERVERS]; /** * @brief All NTP configuration parameters @@ -184,10 +568,31 @@ typedef struct } NTP_CLIENT_CFG_PEER_SETTINGS; +typedef struct +{ + NTP_GLB_INFO glb_info; + NTP_SYMM_KEY_LIMITS *symm_key_limits; + NTP_SYMM_KEY_INFO_IDX *symm_key_info_idx; + NTP_TRUSTED_KEY_INFO_IDX *trusted_key_info_idx; + + NTP_CLNT_MODE_INFO *clnt_info; + NTP_PEER_SETTINGS_IDX *peer_settings_idx; + + NTP_SRV_MODE_INFO *srv_info; + NTP_REFCLK_CFG_INFO_IDX *refclk_info_idx; + NTP_MISC_LIMITS *misc_limits; + NTP_MISC_ORPHAN_MODE_INFO *orphan_mode_info; + +} ALL_NTP_CFG_INFO; + + +typedef struct +{ + NTP_SYS_STATE sys_state; + NTP_PEER_STATE_IDX *peer_states; +} ALL_NTP_STATUS; -/// @brief The max number of GPIO ports supported by configuration programs -#define MAX_PARM_GPIO 10 /// @brief Configuration settings for all GPIO ports typedef MBG_GPIO_INFO_IDX ALL_GPIO_INFO_IDX[MAX_PARM_GPIO]; @@ -198,9 +603,6 @@ typedef MBG_GPIO_STATUS_IDX ALL_GPIO_STATUS_IDX[MAX_PARM_GPIO]; -/// @brief The max number of XMR sources supported by configuration programs -#define MAX_PARM_XMR 10 - /// @brief Status of all XMR inputs typedef XMULTI_REF_STATUS_IDX ALL_XMULTI_REF_STATUS_IDX[MAX_PARM_XMR]; @@ -209,6 +611,101 @@ typedef XMULTI_REF_INFO_IDX ALL_XMULTI_REF_INFO_IDX[MAX_PARM_XMR]; +typedef struct +{ + XMULTI_REF_INSTANCES instances; + XMULTI_REF_INFO_IDX *infos; + XMR_EXT_SRC_INFO_IDX *ext_src_infos; +} ALL_XMULTI_REF_INFO; + + +typedef struct +{ + XMULTI_REF_STATUS_IDX *status; + XMR_HOLDOVER_STATUS *holdover_status; + XMR_STATS_IDX *stats_idx; + XMR_METRICS_IDX *metrics_idx; + /* ALL_XMULTI_REF_STATUS related flag if at least one ref type supports stats */ + unsigned char has_stats; + /* ALL_XMULTI_REF_STATUS related flag if at least one ref type supports metrics */ + unsigned char has_metrics; +} ALL_XMULTI_REF_STATUS; + + + +typedef struct +{ + MBG_IMS_STATE state; + MBG_IMS_FDM_INFO *fdm_info; + MBG_IMS_FDM_LIMITS *fdm_limits; + MBG_IMS_FDM_OUTPUT_INFO_IDX *fdm_outinfo_idx; +} ALL_IMS_INFO; + + +typedef struct +{ + MBG_IMS_SENSOR_STATE_IDX *sensor_state_idx; + MBG_IMS_FDM_STATE *fdm_state; + MBG_IMS_FDM_OUTPUT_STATE_IDX *fdm_output_state_idx; +} ALL_IMS_STATE; + + + +typedef struct +{ + MBG_GPIO_CFG_LIMITS cfg_limits; + MBG_GPIO_INFO_IDX *infos; +} ALL_GPIO_INFO; + + +typedef struct +{ + MBG_GPIO_STATUS_IDX *states; +} ALL_GPIO_STATE; + + +typedef struct +{ + MBG_IO_PORT_LIMITS limits; + MBG_IO_PORT_INFO_IDX *p_infos; + MBG_IO_PORT_TYPE_INFO_IDX **pt_infos; +} ALL_IO_PORT_INFO; + + +typedef struct +{ + MBG_IO_PORT_STATUS_IDX *status; +} ALL_IO_PORT_STATUS; + + +#ifndef MAX_UCAP_ENTRIES +/* + * According to Andre's GPS firmware this is the maximum + * number of user captures that are preserved. + */ +#define MAX_UCAP_ENTRIES 585 +#endif + +typedef struct +{ + struct mbg_klist_head head; + TTM ttm; +} UCAP_ENTRY; + +typedef struct +{ + uint32_t num_ucaps; /// User capture counter, see ::MAX_UCAP_ENTRIES + struct mbg_klist_head list; +} ALL_UCAP_INFO; + +// User Captures via Network configuration, see ::MBG_XFEATURE_UCAP_NET +typedef struct +{ + MBG_UCAP_NET_GLB_INFO glb_info; + MBG_UCAP_NET_RECV_INFO_IDX *recv_infos; +} ALL_UCAP_NET_INFO; + + /** * @brief A mode specifying how to interpret a ::PCPS_SIG_VAL @@ -256,6 +753,24 @@ enum PCPS_TIME_EXT_FLAGS +_ext BAUD_RATE mbg_baud_rate[N_MBG_BAUD_RATES] +#ifdef _DO_INIT + = MBG_BAUD_RATES +#endif +; + +_ext const char *mbg_baud_str[N_MBG_BAUD_RATES] +#ifdef _DO_INIT + = MBG_BAUD_STRS +#endif +; + +_ext const char *mbg_framing_str[N_MBG_FRAMINGS] +#ifdef _DO_INIT + = MBG_FRAMING_STRS +#endif +; + _ext const char *str_unknown #ifdef _DO_INIT = "unknown" @@ -278,6 +793,20 @@ _ext const char *str_not_spc +//### TODO +#define DEFAULT_MAX_STR_TYPE 2 // DEFAULT_N_STR_TYPE_GPS ? + +_ext STR_TYPE_INFO default_str_type_info[DEFAULT_MAX_STR_TYPE] +#ifdef _DO_INIT + = { + { DEFAULT_STR_MODES, "Default Time String", "Time", 0 }, + { DEFAULT_STR_MODES_UCAP, "Capture String", "Cap", 0 } + } +#endif +; + + + _ext const char *mbg_gpio_type_names[N_MBG_GPIO_TYPES] #ifdef _DO_INIT = DEFAULT_GPIO_TYPES_SHORT_STRS @@ -344,7 +873,7 @@ static __mbg_inline int num_bits_set( long val ) { int bits_set = 0; - int i; + size_t i; for ( i = 0; i < ( 8 * sizeof( val ) ); i++ ) { @@ -360,6 +889,229 @@ int num_bits_set( long val ) +/** + * @brief Check if a device ID refers to a serial port + * + * @param[in] dev_id A string with the device name or port name + * + * @see ::DEFAULT_SERIAL_DEVICE_NAME + * + * @return true if the device id contains the name of a serial port, else false + */ +static __mbg_inline +bool device_id_is_serial( const char *dev_id ) +{ + #if defined( MBG_TGT_WIN32 ) + //##++++ There may be also serial ports under Windows + // which don't have "COM" in their name. + return strstr( dev_id, "COM" ) != NULL; + #elif defined( MBG_TGT_LINUX ) + return strstr( dev_id, "/dev/ttyS" ) != NULL // standard serial device + || strstr( dev_id, "/dev/ttyUSB" ) != NULL; // serial-to-USB adapter + #elif defined( MBG_TGT_FREEBSD ) + return strstr( dev_id, "/dev/ttyu" ) != NULL // dial-in device (standard), FreeBSD 10 and newer + || strstr( dev_id, "/dev/cuau" ) != NULL // dial out device, FreeBSD 10 and newer + || strstr( dev_id, "/dev/ttyd" ) != NULL // dial-in device (standard), before FreeBSD 10 + || strstr( dev_id, "/dev/cuad" ) != NULL; // dial-out device, before FreeBSD 10 + #elif defined( MBG_TGT_QNX_NTO ) + return strstr( dev_id, "/dev/ser" ) != NULL; + #elif defined( MBG_TGT_DOS ) + return strstr( dev_id, "COM" ) != NULL; + #else + #error device_id_is_serial() needs to be implemented for this platform + #endif + +} // device_id_is_serial + + + +/** + * @brief Check if a device ID refers to a LAN connection + * + * @param[in] dev_id A string with the device ID + * + * @return true if the device id specifies a LAN connection, else false + */ +static __mbg_inline +bool device_id_is_lan( const char *dev_id ) +{ + return strstr( dev_id, "LAN" ) != NULL; + +} // device_id_is_lan + + + +#if defined( _PRELIMINARY_CODE ) + +static __mbg_inline +MBG_TLV_UID mbg_tlv_create_id( void ) +{ +#if defined( MBG_TGT_POSIX ) + struct sysinfo info; + + // Linux specific, implement Windows equivalent + sysinfo( &info ); + return ( (MBG_TLV_UID) ( ( time( NULL ) >> 16 ) | ( info.uptime << 16 ) ) ); +#else + return 0; +#endif +} // mbg_tlv_create_id + +#endif // defined( _PRELIMINARY_CODE ) + + + +// Depending on the target environment define a data type +// which can be used to convert binary fractions without +// range overflow. +#if defined( MBG_TGT_MISSING_64_BIT_TYPES ) + #define PCPS_HRT_FRAC_CONVERSION_TYPE double +#else + #define PCPS_HRT_FRAC_CONVERSION_TYPE int64_t +#endif + +/** + * @brief Constant used to convert ::PCPS_TIME_STAMP::frac values + * + * Max value of ::PCPS_TIME_STAMP::frac + 1, used for scaling + */ +#define PCPS_HRT_BIN_FRAC_SCALE ( (PCPS_HRT_FRAC_CONVERSION_TYPE) 4294967296.0 ) // == 0x100000000 + + +#ifndef PCPS_HRT_FRAC_SCALE + /** + * @brief Scale to be used to print ::PCPS_TIME_STAMP::frac values + * + * The function ::frac_sec_from_bin can be used for the conversion. + * + * @see ::PCPS_HRT_FRAC_SCALE_FMT + */ + #define PCPS_HRT_FRAC_SCALE 10000000UL +#endif + +#ifndef PCPS_HRT_FRAC_SCALE_FMT + /** + * @brief Format specifier used to print ::PCPS_TIME_STAMP::frac values + * + * Used to print values scaled with ::frac_sec_from_bin called + * with ::PCPS_HRT_FRAC_SCALE. + * + * @see ::PCPS_HRT_FRAC_SCALE + */ + #define PCPS_HRT_FRAC_SCALE_FMT "%07lu" +#endif + + +static __mbg_inline +uint32_t bin_frac_16_to_dec_frac( uint16_t bin, uint32_t scale ) +{ + return (uint32_t) ( (PCPS_HRT_FRAC_CONVERSION_TYPE) bin * scale + / 0x10000UL ); + +} // bin_frac_16_to_dec_frac + + +static __mbg_inline +uint32_t bin_frac_32_to_dec_frac( uint32_t bin, uint32_t scale ) +{ + return (uint32_t) ( (PCPS_HRT_FRAC_CONVERSION_TYPE) bin * scale + / PCPS_HRT_BIN_FRAC_SCALE ); + +} // bin_frac_32_to_dec_frac + + +#if !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + +// On targets which don't provide 64 bit data types +// PCPS_HRT_FRAC_CONVERSION_TYPE is defined as double, +// in which case the ">> 1" operation in the 2 functions +// below yields an "invalid use of floating point" error. +// This could probably be fixed by a different way of +// casting, at least for a partial expression. + +static __mbg_inline +uint16_t dec_frac_to_bin_frac_16( uint32_t dec, uint32_t scale ) +{ + return (uint16_t) ( ( ( (PCPS_HRT_FRAC_CONVERSION_TYPE) dec * 0x20000 / scale ) + 1 ) >> 1 ); + +} // dec_frac_to_bin_frac_16 + + +static __mbg_inline +uint32_t dec_frac_to_bin_frac_32( uint32_t dec, uint32_t scale ) +{ + return (uint32_t) ( ( ( (PCPS_HRT_FRAC_CONVERSION_TYPE) dec * PCPS_HRT_BIN_FRAC_SCALE * 2 / scale ) + 1 ) >> 1 ); + +} // dec_frac_to_bin_frac_32 + +#endif + + +#define bin_frac_32_to_msec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000 ) +#define bin_frac_32_to_usec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000000 ) +#define bin_frac_32_to_nsec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000000000 ) +#define bin_frac_16_to_msec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000 ) +#define bin_frac_16_to_usec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000000 ) +#define bin_frac_16_to_nsec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000000000 ) + + +#define msec_to_bin_frac_32( _msec ) dec_frac_to_bin_frac_32( (_msec), 1000 ) +#define usec_to_bin_frac_32( _usec ) dec_frac_to_bin_frac_32( (_usec), 1000000 ) +#define nsec_to_bin_frac_32( _nsec ) dec_frac_to_bin_frac_32( (_nsec), 1000000000 ) +#define msec_to_bin_frac_16( _msec ) dec_frac_to_bin_frac_16( (_msec), 1000 ) +#define usec_to_bin_frac_16( _usec ) dec_frac_to_bin_frac_16( (_usec), 1000000 ) +#define nsec_to_bin_frac_16( _nsec ) dec_frac_to_bin_frac_16( (_nsec), 1000000000 ) + + + +/** + * @brief Convert a fraction of a second from binary + * + * Convert a fraction of a second from binary format (as returned + * as part of the ::PCPS_HR_TIME structure) to a decimal fraction, + * using a specified scale factor. + * + * @param[in] b The binary fraction + * @param[in] scale The scale factor + * + * @return The calculated number + * + * @see ::PCPS_HRT_FRAC_SCALE + * @see ::PCPS_HRT_FRAC_SCALE_FMT + */ +static __mbg_inline +uint32_t frac_sec_from_bin( uint32_t b, uint32_t scale ) +{ + return bin_frac_32_to_dec_frac( b, scale ); + +} // frac_sec_from_bin + + + +/** + * @brief Convert a fraction of a second to double + * + * Convert a fraction of a second from binary format (as returned + * as part of the ::PCPS_HR_TIME structure) to a double with the + * units of seconds, e.g. 0xFFFFFFFF yields 0.9999999999.... + * + * @param[in] b The binary fraction + * + * @return The calculated fraction + * + * @see ::PCPS_HRT_FRAC_SCALE + */ +static __mbg_inline +double dfrac_sec_from_bin( uint32_t b ) +{ + return (double) b / (double) PCPS_HRT_BIN_FRAC_SCALE; + +} // dfrac_sec_from_bin + + + +#if !defined( MBG_TGT_KERNEL ) + /* function prototypes: */ /* ----- function prototypes begin ----- */ @@ -368,34 +1120,57 @@ int num_bits_set( long val ) /* by MAKEHDR, do not remove the comments. */ /** - * @brief Trim whitespace at the end of a string + * @brief Normalize a ::NANO_TIME_64 struct + * + * After normalization, the following can be assumed:<br> + * - nano_secs is in the range [-10^9 + 1, 10^9 - 1]<br> + * - if secs is not 0, secs and nano_secs have the same sign * - * @param[in,out] s The string to be trimmed + * @param[in,out] nt The NANO_TIME_64 to be normalized */ - void trim_trailing_whitespace( char *s ) ; + void normalize_nano_time_64( NANO_TIME_64 *nt ) ; /** - * @brief Trim whitespace at the beginning of a string + * @brief Print a normalized ::NANO_TIME_64 into a string buffer * - * @param[in,out] s The string to be trimmed + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] nt The ::NANO_TIME_64 to be printed */ - void trim_leading_whitespace( char *s ) ; + size_t snprint_nano_time_64( char *s, size_t max_len, const NANO_TIME_64 *nt ) ; /** - * @brief Trim both leading and trailing whitespace from a string + * @brief Print nano time into string buffer * - * @param[in,out] s The string to be trimmed + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] nt The ::NANO_TIME to be printed */ - void trim_whitespace( char *s ) ; + size_t snprint_nano_time( char *s, size_t max_len, const NANO_TIME *nt ) ; /** - * @brief Print nano time into string buffer + * @brief Convert ::NANO_TIME_64 to ::TM_GPS + * + * @param[out] tm_gps The ::TM_GPS to be filled + * @param[in] nt The ::NANO_TIME_64 to be converted + * + * @return 1 on success, 0 on error + * + * @see ::tm_gps_to_nano_time_64 + */ + int nano_time_64_to_tm_gps( TM_GPS *tm_gps, const NANO_TIME_64 *nt ) ; + + /** + * @brief Convert ::TM_GPS to ::NANO_TIME_64 + * + * @param[out] nt The ::NANO_TIME_64 to be filled + * @param[in] tm The ::TM_GPS to be converted * - * @param[out] s The string buffer to be filled - * @param[in] len Size of the string buffer, i.e. max length - * @param[in] nt The ::NANO_TIME to be printed + * @return 1 on success, 0 on error + * + * @see ::nano_time_64_to_tm_gps */ - int snprint_nano_time( char *s, int len, const NANO_TIME *nt ) ; + int tm_gps_to_nano_time_64( NANO_TIME_64 *nt, const TM_GPS *tm ) ; /** * @brief Check if a software revision name should be displayed @@ -415,9 +1190,342 @@ int num_bits_set( long val ) */ int chk_sw_rev_name( SW_REV *p, int verbose ) ; + int get_str_idx( const char *search, const char *str_table[], int n_entries ) ; + int get_baud_rate_idx( BAUD_RATE baud_rate ) ; + int get_framing_idx( const char *framing ) ; + void port_settings_from_port_parm_mode( PORT_SETTINGS *p_ps, uint8_t pp_mode, int str_type_cap ) ; + void port_parm_mode_from_port_settings( uint8_t *pp_mode, const PORT_SETTINGS *p_ps, int str_type_cap ) ; + void port_settings_from_port_parm( PORT_SETTINGS *p_ps, int port_num, const PORT_PARM *p_pp, int cap_str_idx ) ; + void port_parm_from_port_settings( PORT_PARM *p_pp, int port_num, const PORT_SETTINGS *p_ps, int cap_str_idx ) ; + uint32_t check_valid_port_info( const PORT_INFO *p_pi, const STR_TYPE_INFO_IDX str_type_info_idx[], int n_str_type ) ; + int valid_port_info( const PORT_INFO *p_pi, const STR_TYPE_INFO_IDX str_type_info_idx[], int n_str_type ) ; + int setup_port_info_from_port_settings( PORT_INFO_IDX pii[], const PORT_PARM *p_pp, const RECEIVER_INFO *p_ri ) ; + int setup_default_str_type_info_idx( STR_TYPE_INFO_IDX stii[], const RECEIVER_INFO *p_ri ) ; + int chk_set_n_gnss_supp( ALL_GNSS_INFO *p_agi ) ; + /** + * @brief + * + * ### Setup GNSS info from stat_info so we can use the same printing routine + */ + void setup_gps_only_sat_info_idx_from_statinfo( ALL_GNSS_INFO *p_agi ) ; + + /** + * @brief + * + * Setup GNSS info from stat_info so we can use the same printing routine + */ + int setup_gps_only_gnss_info_from_statinfo( ALL_GNSS_INFO *p_agi ) ; + + void chk_free_dev_hw_id( DEVICE_INFO *p ) ; + int alloc_dev_hw_id( DEVICE_INFO *p, size_t len ) ; + const char *get_fw_id_from_hw_id( const char *hw_id ) ; + const char *get_hw_id_from_fw_id( const char *fw_id ) ; + /** + * @brief Returns the currently used ::MBG_IO_PORT_TYPE_INFO_IDX for the appropriate ::MBG_IO_PORT_INFO_IDX + * + * @param[in] all_io_port_info Pointer to the ::ALL_IO_PORT_INFO, containing the current configuration + * @param[in] io_port_info_idx Pointer to the ::MBG_IO_PORT_INFO_IDX, for which the ::MBG_IO_PORT_TYPE_INFO_IDX shall be found + * + * @return Pointer to the found ::MBG_IO_PORT_TYPE_INFO_IDX or NULL + * + */ + MBG_IO_PORT_TYPE_INFO_IDX *get_io_port_type_info_idx(ALL_IO_PORT_INFO *all_io_port_info, MBG_IO_PORT_INFO_IDX *io_port_info_idx) ; + + /** + * @brief Initializes a ::MBG_TLV_ANNOUNCE structure + * + * @param[out] tlv Pointer to a ::MBG_TLV_ANNOUNCE structure + * @param[in] uid Unique sender ID used as identifier with all + * subsequent messages related to this transaction. + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] total_bytes Total number of bytes of all upcoming TLVs + */ + void mbg_tlv_announce_init( MBG_TLV_ANNOUNCE *tlv, MBG_TLV_UID uid, MBG_TLV_TYPE tlv_feat_type, uint32_t total_bytes ) ; + + /** + * @brief Initializes a ::MBG_TLV + * + * @param[out] tlv Pointer to a valid ::MBG_TLV structure + * @param[in] uid Unique sender ID used as identifier for each further + * TLV message related to this type. + * @param[in] tlv_type Type identifier, see ::MBG_TLV_TYPES + * @param[in] total_bytes Total number of bytes belonging to this + * TLV transaction (which is very likely split into several TLVs) + */ + void mbg_tlv_init( MBG_TLV *tlv, MBG_TLV_UID uid, MBG_TLV_TYPE tlv_type, uint32_t total_bytes ) ; + + /** + * @brief Initializes ::MBG_TLV_RCV_STATE structure + * + * @param[in,out] state Pointer to ::MBG_TLV_RCV_STATE structure + * @param[in] uid Unique sender ID used as identifier for each further + * TLV message related to this type. + * @param[in] total_bytes Total number of bytes belonging to this + * TLV transaction (which is very likely split into several TLVS) + */ + void mbg_tlv_rcv_state_init( MBG_TLV_RCV_STATE *state, MBG_TLV_UID uid, uint32_t total_bytes ) ; + + size_t mbg_snprint_revision( char *buf, size_t buflen, const char *prefix, const char *suffix, uint32_t rev) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_xbp_supp_nodes( const ALL_XBP_INFO *info ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_net_cfg_supp_stage_2( const ALL_NET_CFG_INFO *info ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_ntp_supp_client( const ALL_NTP_CFG_INFO *info ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_ntp_supp_server( const ALL_NTP_CFG_INFO *info ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_mrf_none( const ALL_XMULTI_REF_INFO *info ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_src_info( const ALL_XMULTI_REF_INFO *info ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_holdover_status( const ALL_XMULTI_REF_INFO *info ) ; + /* + * Type is NOT an index of ::XMULTI_REF_INSTANCES::n_xmr_settings, + * but of ::MULTI_REF_TYPES. + * Depends on chk_dev_supp_xmulti_ref_ext_src_info. + * @see chk_dev_supp_xmulti_ref_ext_src_info + */ + _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_source_stats( const ALL_XMULTI_REF_INFO *info, int type ) ; + + /* + * Type is NOT an index of ::XMULTI_REF_INSTANCES::n_xmr_settings, + * but of ::MULTI_REF_TYPES. + * Depends on chk_dev_supp_xmulti_ref_ext_src_info. + * @see chk_dev_supp_xmulti_ref_ext_src_info + */ + _NO_MBG_API_ATTR int _MBG_API chk_dev_xmulti_ref_supp_ext_source_metrics( const ALL_XMULTI_REF_INFO *info, int type ) ; + + _NO_MBG_API_ATTR int _MBG_API chk_dev_ims_has_fdm( const ALL_IMS_INFO *info ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_volt_out_enabled( const ALL_IMS_STATE *ims_state, unsigned idx ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_volt_out_overload( const ALL_IMS_STATE *ims_state, unsigned idx ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_ims_is_pll_locked( const ALL_IMS_STATE *ims_state, unsigned idx ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_supp_ass_idx( const ALL_GPIO_INFO *gpio_info, unsigned idx ) ; + _NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_dep_on_ass_idx( const ALL_GPIO_INFO *gpio_info, unsigned idx ) ; + /** + * @brief Checks whether GPIO supports status function + * + * @param[out] info Pointer to a ::ALL_GPIO_INFO structure to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::mbg_chk_dev_supp_gpio + * @see ::free_all_gpio_info + */ + _NO_MBG_API_ATTR int _MBG_API chk_dev_gpio_has_status( const ALL_GPIO_INFO *info ) ; + + /** + * @brief Frees ::ALL_XBP_INFO structure + * + * @param[in] p Pointer to the ::ALL_XBP_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_xbp_info + */ + void free_all_xbp_info ( ALL_XBP_INFO *p ) ; + + /** + * @brief Frees ::ALL_NET_CFG_INFO structure + * + * @param[in] p Pointer to the ::ALL_NET_CFG_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_net_cfg_info + */ + void free_all_net_cfg_info ( ALL_NET_CFG_INFO *p ) ; + + /** + * @brief Frees ::ALL_NET_STATUS_INFO structure + * + * @param[in] p Pointer to the ::ALL_NET_STATUS_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_net_status_info + */ + void free_all_net_status_info ( ALL_NET_STATUS_INFO *p ) ; + + /** + * @brief Frees ::ALL_SNMP_INFO structure + * + * @param[in] p Pointer to the ::ALL_SNMP_INFO structure, which will be freed + * + */ + void free_all_snmp_info ( ALL_SNMP_INFO *p ) ; + + /** + * @brief Frees ::ALL_MONITORING_INFO structure + * + * @param[in] p Pointer to the ::ALL_MONITORING_INFO structure, which will be freed + * + */ + void free_all_monitoring_info ( ALL_MONITORING_INFO *p ) ; + + /** + * @brief Frees ::ALL_MONITORING_STATUS structure + * + * @param[in] p Pointer to the ::ALL_MONITORING_STATUS structure, which will be freed + * + */ + void free_all_monitoring_status ( ALL_MONITORING_STATUS *p ) ; + + /** + * @brief Frees ::ALL_XMULTI_REF_INFO structure + * + * @param[in] p Pointer to the ::ALL_XMULTI_REF_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_xmulti_ref_info + * @see ::mbg_get_all_xmulti_ref_info + */ + void free_all_xmulti_ref_info( ALL_XMULTI_REF_INFO *p ) ; + + /** + * @brief Frees ::ALL_XMULTI_REF_STATUS structure + * + * @param[in] p Pointer to the ::ALL_XMULTI_REF_STATUS structure, which will be freed + * + * @see ::mbgextio_get_all_xmulti_ref_status + * @see ::mbg_get_all_xmulti_ref_status + */ + void free_all_xmulti_ref_status( ALL_XMULTI_REF_STATUS *p ) ; + + /** + * @brief Frees ::ALL_PTP_V1_COMMON_DATASETS structure allocated by ::mbgextio_get_all_ptp_v1_common_datasets + * + * @param[in] p Pointer to the ::ALL_PTP_V1_COMMON_DATASETS structure, which will be freed + * + * @see ::mbgextio_get_all_ptp_v1_common_datasets + */ + void free_all_ptp_v1_common_datasets( ALL_PTP_V1_COMMON_DATASETS *p ) ; + + /** + * @brief Frees ::ALL_PTP_V2_COMMON_DATASETS structure allocated by ::mbgextio_get_all_ptp_v2_common_datasets + * + * @param[in] p Pointer to the ::ALL_PTP_V2_COMMON_DATASETS structure, which will be freed + * + * @see ::mbgextio_get_all_ptp_v2_common_datasets + */ + void free_all_ptp_v2_common_datasets( ALL_PTP_V2_COMMON_DATASETS *p ) ; + + /** + * @brief Frees ::ALL_NTP_CFG_INFO structure + * + * @param[in] p Pointer to the ::ALL_NTP_CFG_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_ntp_cfg_info + */ + void free_all_ntp_cfg_info( ALL_NTP_CFG_INFO *p ) ; + + /** + * @brief Frees ::ALL_NTP_STATUS structure + * + * @param[in] p Pointer to the ::ALL_NTP_STATUS structure, which will be freed + * + * @see ::mbgextio_get_all_ntp_status + */ + void free_all_ntp_status( ALL_NTP_STATUS *p ) ; + + /** + * @brief Frees memory allocated by ::mbgextio_get_all_ims_info + * + * @param[in] p Pointer to the ::ALL_IMS_INFO structure, which will be freed + * + * @see ::mbgextio_dev_has_ims + * @see ::mbgextio_dev_ims_has_fdm + * @see ::mbgextio_get_all_ims_info + * @see ::mbgextio_get_all_ims_state + */ + void free_all_ims_info( ALL_IMS_INFO *p ) ; + + /** + * @brief Frees memory allocated by ::mbgextio_get_all_ims_state + * + * @param[in] p Pointer to the ::ALL_IMS_STATE structure, which will be freed + * + * @see ::mbgextio_dev_has_ims + * @see ::mbgextio_dev_ims_has_fdm + * @see ::mbgextio_get_all_ims_info + * @see ::mbgextio_get_all_ims_state + */ + void free_all_ims_state( ALL_IMS_STATE *p ) ; + + /** + * @brief Frees memory allocated by ::mbgextio_get_all_gpio_info + * + * @param[in] p Pointer to the ::ALL_GPIO_INFO structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::mbgextio_get_all_gpio_info + */ + void free_all_gpio_info( ALL_GPIO_INFO *p ) ; + + /** + * @brief Frees memory allocated by ::mbgextio_get_all_io_port_info + * + * @param[in] p Pointer to the ::ALL_IO_PORT_INFO structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_io_ports + * @see ::mbgextio_get_all_io_port_info + * @see ::mbgextio_get_all_io_port_status + * @see ::free_all_io_port_status + */ + void free_all_io_port_info( ALL_IO_PORT_INFO *p ) ; + + /** + * @brief Frees memory allocated by ::mbgextio_get_all_io_port_status + * + * @param[in] p Pointer to the ::ALL_IO_PORT_STATUS structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_io_ports + * @see ::mbgextio_get_all_io_port_info + * @see ::mbgextio_get_all_io_port_status + * @see ::free_all_io_port_info + */ + void free_all_io_port_status( ALL_IO_PORT_STATUS *p ) ; + + /** + * @brief Frees memory allocated by ::mbgextio_get_all_gpio_state + * + * @param[in] p Pointer to the ::ALL_GPIO_STATE structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::mbgextio_get_all_gpio_state + */ + void free_all_gpio_state( ALL_GPIO_STATE *p ) ; + + /** + * Allocates memory for a new ::UCAP_ENTRY structure + * + * @return The new allocated ::UCAP_ENTRY or null if the calloc call was not successful + */ + UCAP_ENTRY* calloc_ucap_entry(void) ; + + /** + * @brief Frees memory allocated by ::mbgextio_get_all_ucap_info + * + * @param[in] p Pointer to the ::ALL_UCAP_INFO structure, which will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap + * @see ::mbg_chk_dev_has_ucap + * @see ::mbgextio_get_all_ucap_info + * @see ::mbg_get_all_ucap_info + */ + void free_all_ucap_info( ALL_UCAP_INFO *p ) ; + + /** + * @brief Frees ::ALL_UCAP_NET_INFO structure + * + * @param[in] p Pointer to the ::ALL_UCAP_NET_INFO structure, which will be freed + * + * @see ::mbgextio_get_all_ucap_net_info + */ + void free_all_ucap_net_info( ALL_UCAP_NET_INFO *p ) ; + /* ----- function prototypes end ----- */ +#endif // !defined( MBG_TGT_KERNEL ) + #ifdef __cplusplus } #endif diff --git a/mbglib/common/extiohlp.c b/mbglib/common/extiohlp.c index 064f2ec..c35e985 100644 --- a/mbglib/common/extiohlp.c +++ b/mbglib/common/extiohlp.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: extiohlp.c 1.3.1.4.1.2 2015/01/21 13:24:44Z marvin TEST martin $ + * $Id: extiohlp.c 1.3.1.4.1.129 2017/04/12 07:59:04Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -18,7 +18,264 @@ * * ----------------------------------------------------------------------- * $Log: extiohlp.c $ - * Revision 1.3.1.4.1.2 2015/01/21 13:24:44Z marvin + * Revision 1.3.1.4.1.129 2017/04/12 07:59:04Z martin + * Fixed build under DOS. + * Revision 1.3.1.4.1.128 2017/04/11 15:16:26Z martin + * Revision 1.3.1.4.1.127 2017/04/11 13:08:56Z martin + * Use symbolic code instead of hardcoded number. + * Revision 1.3.1.4.1.126 2017/04/06 12:34:28Z thomas-b + * Copy TLV header before and after each chunk transmission due to swab and encryption + * Revision 1.3.1.4.1.125 2017/04/04 10:06:03 thomas-b + * Added transactions for monitoring and events + * Revision 1.3.1.4.1.124 2017/03/29 12:33:26 philipp + * Extended event info and event status index structures by data pointer + * Revision 1.3.1.4.1.123 2017/03/27 10:37:41 thomas-b + * Added function mbgextio_get_all_ptp_v1_common_datasets + * Revision 1.3.1.4.1.122 2017/03/22 13:54:05 thomas-b + * Added transaction to mbgextio_get_all_io_port_status + * Revision 1.3.1.4.1.121 2017/03/22 09:46:05 thomas-b + * Added transaction to mbgextio_get_all_io_port_info and function mbgextio_save_all_io_port_info + * Revision 1.3.1.4.1.120 2017/03/20 13:34:49 martin + * Fixed clang warnings. + * Revision 1.3.1.4.1.119 2017/03/20 10:10:02 martin + * Fixed build without _PRELIMINARY_CODE. + * Revision 1.3.1.4.1.118 2017/03/14 12:39:26 thomas-b + * Do not write ref clock settings if NTP_MSK_FIXED_REFCLOCKS is set + * Revision 1.3.1.4.1.117 2017/03/14 10:53:56 thomas-b + * Fixed bug in NTP save function + * Revision 1.3.1.4.1.116 2017/03/08 13:35:20 thomas-b + * Do not read more than num_peers, instead of n_supp_peers when getting all NTP status + * Revision 1.3.1.4.1.115 2017/03/08 12:37:51 thomas-b + * Added set bit for transaction type in mbgextio_begin_transaction + * Revision 1.3.1.4.1.114 2017/03/03 08:29:27 thomas-b + * Adapted get and save all NTP functions to new ALL_NTP_CFG_INFO design + * Revision 1.3.1.4.1.113 2017/03/02 15:46:32 thomas-b + * Set empty peer settings for all supported but not configured peers for compatibility with N2x + * Revision 1.3.1.4.1.112 2017/03/02 15:33:10 thomas-b + * Do not read/write more than num_peers from NTP_CLNT_MODE_SETTINGS + * Revision 1.3.1.4.1.111 2017/02/28 15:21:49 gregoire + * peer_settings_idx in ntp_cfg_info renamed + * Revision 1.3.1.4.1.110 2017/02/24 09:38:25 philipp + * Do not use fixed buffers for monitorung event info and status + * Revision 1.3.1.4.1.109 2017/02/22 08:32:19 thomas-b + * Extended get and set of ALL_MONITORING_INFO by event structures + * Added get function for ALL_MONITORING_STATUS + * Revision 1.3.1.4.1.108 2017/02/16 12:59:51 thomas-b + * Renamed mbgextio_get_ptp_v2_common_datasets to mbgextio_get_all_ptp_v2_common_datasets + * Use ALL_PTP_V2_COMMON_DATASETS structure instead of MBG_PTP_V2_COMMON_DATASETS + * Revision 1.3.1.4.1.107 2017/02/16 10:19:43 martin + * *** empty log message *** + * Revision 1.3.1.4.1.106 2017/02/16 09:32:32 thomas-b + * Added function mbgextio_get_ptp_v2_common_datasets + * Revision 1.3.1.4.1.105 2017/02/15 14:09:35 martin + * Test, the previous version eventually contained mixed line endings. + * Revision 1.3.1.4.1.104 2017/02/08 13:15:43 thomas-b + * Added functions to get and save all monitoring, especially SNMP, configuration + * Revision 1.3.1.4.1.103 2016/12/08 14:39:31 martin + * Made XBP_ADDR * parameter const. + * Revision 1.3.1.4.1.102 2016/11/29 14:44:20Z philipp + * Fixed memleaks + * Revision 1.3.1.4.1.101 2016/11/24 07:06:33 philipp + * Honour big endian system when swapping bytes + * Revision 1.3.1.4.1.100 2016/11/22 12:40:46 philipp + * Added I/O port helper functions + * Revision 1.3.1.4.1.99 2016/11/21 15:15:53 martin + * Define a default for UINT8_MAX if it's not defined elsewhere. + * Revision 1.3.1.4.1.98 2016/11/01 14:58:09Z udo + * *** empty log message *** + * Revision 1.3.1.4.1.97 2016/11/01 09:30:48 thomas-b + * Fixed mbgextio subfunction calls with fix NULL XBP addr + * Revision 1.3.1.4.1.96 2016/11/01 09:19:29 martin + * Use new data types and account for structure fields which + * have been renamed to reduce ambiguity. + * Updated doxygen comments. + * Revision 1.3.1.4.1.95 2016/10/25 07:48:27 martin + * Doxygen fixes. + * Revision 1.3.1.4.1.94 2016/10/21 09:39:43 thomas-b + * Added function mbgextio_get_all_xbp_info + * Revision 1.3.1.4.1.93 2016/10/20 09:14:59 thomas-b + * Removed debug code + * Revision 1.3.1.4.1.92 2016/10/19 14:33:06 thomas-b + * Added functions mbgextio_get_all_ucap_net_info and mbgextio_save_all_ucap_net_info + * Revision 1.3.1.4.1.91 2016/10/06 10:10:39 thomas-b + * Added several security checks for older network API + * Revision 1.3.1.4.1.90 2016/10/06 07:12:35 thomas-b + * Set index before setting link, route and addr settings + * Revision 1.3.1.4.1.89 2016/10/04 07:54:34 thomas-b + * Fixed reading and settings of DNS server and search domain status and config + * Revision 1.3.1.4.1.88 2016/09/30 11:11:22 thomas-b + * If NET_CFG_API stage 2 is not supported, check if DNS server or DNS search domain is empty and decrease num + * Revision 1.3.1.4.1.87 2016/09/29 14:35:10 thomas-b + * Moved new get and set functions for NET_CFG_API stage 2 to mbgextio + * Revision 1.3.1.4.1.86 2016/09/29 13:38:11 thomas-b + * Fix for LAN_IP4 compatibility + * Revision 1.3.1.4.1.85 2016/09/29 12:16:36 thomas-b + * Added set functions for NET_CFG_API stage 2 + * Revision 1.3.1.4.1.84 2016/09/29 09:09:02 thomas-b + * Added more functions for NET_CFG_API stage 2, especially status + * Revision 1.3.1.4.1.83 2016/09/29 06:12:38 philipp + * Added support for beginning / ending typed transactions + * Revision 1.3.1.4.1.82 2016/09/29 05:56:55 thomas-b + * Added first functions for NET_CFG_API stage 2 + * Revision 1.3.1.4.1.81 2016/09/27 09:26:08 udo + * fixed wrong rcv- and xmt- buffer handling in mbgextio_req_generic_file() + * Revision 1.3.1.4.1.79 2016/09/16 08:28:50 thomas-b + * Fixed conversion warning by adding cast to uint8_t + * Revision 1.3.1.4.1.78 2016/09/15 09:20:44 thomas-b + * Fixed two bugs in mbgextio_get_all_net_status_info + * Revision 1.3.1.4.1.77 2016/08/16 12:48:30 gregoire.diehl + * CVI fixes + * Revision 1.3.1.4.1.76 2016/08/11 11:28:10Z martin + * *** empty log message *** + * Revision 1.3.1.4.1.75 2016/08/09 07:09:55 martin + * *** empty log message *** + * Revision 1.3.1.4.1.74 2016/08/03 08:06:56 thomas-b + * Adapted net_cfg functions to the structure changes + * Revision 1.3.1.4.1.73 2016/07/07 15:04:33 martin + * Fixed compiler warning. + * Revision 1.3.1.4.1.72 2016/06/23 09:24:01 thomas-b + * Adapted net_cfg functions to the new structure of MBG_NET_GLB_CFG_SETTINGS + * Revision 1.3.1.4.1.71 2016/06/21 12:06:46 thomas-b + * Moved mbgextio_calloc_ucap_entry to cfg_hlp so it can be used in deviohlp as well + * Revision 1.3.1.4.1.70 2016/06/21 08:41:29 thomas-b + * Removed old mbgextio_get_all_ucap_info function and static flag from mbgextio_calloc_ucap_entry + * Revision 1.3.1.4.1.69 2016/06/21 07:39:22 philipp + * Use mbg_klist for ucap events and not an array -> Easier to handle MAX_UCAP_ENTRIES + * Revision 1.3.1.4.1.68 2016/06/15 14:03:56 thomas-b + * Added function mbgextio_get_all_ucap_info + * Revision 1.3.1.4.1.67 2016/06/03 11:09:43 thomas-b + * Fixed Windows compatibility issues in mbgextio_xmt_file + * Revision 1.3.1.4.1.66 2016/06/01 10:07:39 daniel + * Fix using _PRELIMINARY_CODE define for route_infos + * Revision 1.3.1.4.1.65 2016/06/01 06:04:25 philipp + * Added compiler warning as reminder + * Revision 1.3.1.4.1.64 2016/05/31 11:35:45 philipp + * Extended ALL_XMULTI_REF_STATUS by flags if at least one ref type supports stats and/or metrics + * Revision 1.3.1.4.1.63 2016/05/31 06:32:27 thomas-b + * Initialize rc in mbgextio_get_all_xmulti_ref_status + * Revision 1.3.1.4.1.62 2016/05/30 14:25:41 daniel + * Added missing code for HPS firmware rollback + * Revision 1.3.1.4.1.61 2016/05/27 05:48:08 philipp + * Refactoring to support XMR_METRICS properly + * Revision 1.3.1.4.1.60 2016/05/26 10:59:26 thomas-b + * Added parameter ALL_NTP_CFG_INFO to mbgextio_get_all_ntp_status + * Moved check functions of specific features to cfg_hlp + * Revision 1.3.1.4.1.59 2016/05/25 08:43:36 philipp + * Redesign of ALL_[xxx]_[XXX] structures and (helper) functions + * Revision 1.3.1.4.1.58 2016/05/24 07:26:19 philipp + * Use calloc instead of realloc (and only if needed) when fetching structures 'ALL_[xxx]_[xxx]' + * Revision 1.3.1.4.1.57 2016/05/23 09:46:52 philipp + * Increase performance + * Revision 1.3.1.4.1.56 2016/05/23 09:37:41 philipp + * Extended ALL_XMULTI_REF_STATUS by holdover_status + * Revision 1.3.1.4.1.55 2016/05/23 08:58:01 philipp + * New function mbgextio_get_all_gpio_state + * Revision 1.3.1.4.1.54 2016/05/23 08:27:51 philipp + * Fixed compiler warning + * Revision 1.3.1.4.1.53 2016/05/23 08:24:16 philipp + * New function mbgextio_get_all_ims_state + * Revision 1.3.1.4.1.52 2016/05/11 14:38:49 thomas-b + * Changed link status evaluation in mbgextio_get_all_net_status_info + * Revision 1.3.1.4.1.51 2016/05/11 13:59:37 thomas-b + * Adapted comments and fixed bug in mbgextio_get_all_net_status_info + * Revision 1.3.1.4.1.50 2016/05/11 13:21:34 thomas-b + * Implemented mbgextio_get_all_net_status_info + * Revision 1.3.1.4.1.49 2016/05/04 13:07:49 thomas-b + * Added function mbgextio_save_all_net_cfg_info + * Revision 1.3.1.4.1.48 2016/05/04 07:46:52 thomas-b + * Copy link mac address to route info only, if gateway is set + * Revision 1.3.1.4.1.47 2016/04/27 07:12:02 thomas-b + * Improved comments for mbgextio_get_all_net_cfg_info + * Revision 1.3.1.4.1.46 2016/04/26 14:42:56 thomas-b + * Added function mbgextio_get_all_net_cfg_info + * Revision 1.3.1.4.1.45 2016/04/25 14:47:43 martin + * *** empty log message *** + * Revision 1.3.1.4.1.44 2016/04/22 07:11:50 philipp + * Use pointer to pointer in get_all_* functions + * Revision 1.3.1.4.1.43 2016/04/22 05:01:48 thomas-b + * Added function mbgextio_save_all_ntp_cfg_info + * Revision 1.3.1.4.1.42 2016/04/20 14:54:33 thomas-b + * Added functions mbgextio_get_all_ntp_cfg_info and mbgextio_get_all_ntp_status + * Revision 1.3.1.4.1.41 2016/04/20 12:37:55 thomas-b + * Moved free functions for ALL_XMULTI_REF_INFO and ALL_XMULTI_REF_STATUS to cfg_hlp + * Revision 1.3.1.4.1.40 2016/04/18 14:06:19 thomas-b + * Changed comment + * Revision 1.3.1.4.1.39 2016/04/18 12:57:44 thomas-b + * Renamed mbgextio_set_all_xmulti_ref_settings to mbgextio_save_all_xmulti_ref_info + * Revision 1.3.1.4.1.38 2016/04/15 11:12:22 thomas-b + * Changed xmulti ref functions to alloc/free the whole struct + * Revision 1.3.1.4.1.37 2016/04/13 11:00:40 thomas-b + * Apply changes by sending dummy settings with index -1 + * Revision 1.3.1.4.1.36 2016/04/13 07:16:48 thomas-b + * Added function mbgextio_set_all_xmulti_ref_settings + * Revision 1.3.1.4.1.35 2016/04/12 13:28:40 philipp + * New helper functions to get all feature related structures at once + * Revision 1.3.1.4.1.34 2016/04/12 08:44:03 thomas-b + * Fixed several errors in xmulti ref functions + * Revision 1.3.1.4.1.33 2016/04/12 08:26:09 thomas-b + * Added mbgextio_get_all_xmulti_ref_info and mbgextio_get_all_xmulti_ref_status and appropriate free functions + * Revision 1.3.1.4.1.32 2016/04/11 11:14:38 daniel + * Support incremental update + * Revision 1.3.1.4.1.31 2016/03/22 11:51:41 thomas-b + * Moved new xport functions and structure definitions to mbgextio + * Revision 1.3.1.4.1.30 2016/03/18 07:10:14Z thomas-b + * Renamed new xport functions and structures + * Revision 1.3.1.4.1.29 2016/03/16 15:58:47 thomas-b + * Added functions mbgextio_setup_xport_list and mbgextio_free_xport_list + * Will have to be extended for use under Windows + * Revision 1.3.1.4.1.28 2016/03/16 13:47:15 martin + * *** empty log message *** + * Revision 1.3.1.4.1.27 2016/03/14 09:46:35 marvin + * Added function to set all ptp settings. + * Revision 1.3.1.4.1.26 2016/02/18 15:52:31Z daniel + * Account for diag file and license upgrade + * Revision 1.3.1.4.1.25 2016/02/15 12:13:14 daniel + * Support for getting diag file + * Revision 1.3.1.4.1.24 2015/12/01 11:34:06 martin + * *** empty log message *** + * Revision 1.3.1.4.1.23 2015/11/30 07:06:35 philipp + * Access function for control message's opaque / internal USB device info structure + * Revision 1.3.1.4.1.22 2015/11/26 16:19:25 martin + * Reworked check feature API causing some other API calls to be + * simplified/changed since receiver info is now stored inside + * the message control block. + * Revision 1.3.1.4.1.21 2015/11/25 10:59:52 philipp + * Extended TLV xmt functions by uid parameter + * Revision 1.3.1.4.1.20 2015/11/25 09:58:13 philipp + * Fixed TLV receive functions to work properly and as expected + * Revision 1.3.1.4.1.19 2015/11/24 13:12:58 philipp + * Added / redesigned TLV functions + * Revision 1.3.1.4.1.18 2015/11/23 15:08:40 daniel + * More work on TLV stuff + * Revision 1.3.1.4.1.17 2015/11/23 14:17:02 philipp + * Moved TLV related sending / receiving functions to here + * Revision 1.3.1.4.1.16 2015/10/28 16:22:55 martin + * Revision 1.3.1.4.1.15 2015/10/19 16:42:16Z martin + * *** empty log message *** + * Revision 1.3.1.4.1.14 2015/10/19 09:35:10 martin + * *** empty log message *** + * Revision 1.3.1.4.1.13 2015/10/12 13:31:23 martin + * *** empty log message *** + * Revision 1.3.1.4.1.12 2015/10/12 10:01:59 martin + * *** empty log message *** + * Revision 1.3.1.4.1.11 2015/10/09 12:20:17 martin + * *** empty log message *** + * Revision 1.3.1.4.1.10 2015/10/09 11:09:13 martin + * *** empty log message *** + * Revision 1.3.1.4.1.9 2015/10/08 10:24:30 martin + * *** empty log message *** + * Revision 1.3.1.4.1.8 2015/10/08 09:30:49 martin + * *** empty log message *** + * Revision 1.3.1.4.1.7 2015/10/08 08:04:10 martin + * *** empty log message *** + * Revision 1.3.1.4.1.6 2015/10/07 16:03:21 martin + * *** empty log message *** + * Revision 1.3.1.4.1.5 2015/10/07 09:59:01 martin + * More common GNSS support. + * Revision 1.3.1.4.1.4 2015/10/06 14:12:16 martin + * Account for library module chk_tstr renamed to mbg_tstr. + * Revision 1.3.1.4.1.3 2015/09/07 13:24:10 martin + * Revision 1.3.1.4.1.2 2015/01/21 13:24:44 marvin * Added XBP Adress specifier to mbgextio functions. * Revision 1.3.1.4.1.1 2014/10/31 12:04:45Z martin * Started to support XBP addressing. @@ -44,7 +301,56 @@ #include <extiohlp.h> #undef _EXTIOHLP +#include <cfg_hlp.h> +#include <lan_util.h> #include <mbggeo.h> +#include <str_util.h> + +#if defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_CVI ) + #include <sys/types.h> + #include <sys/stat.h> +#elif defined( MBG_TGT_DOS ) + #include <sys/stat.h> +#endif + +#define TLV_REQ_FILE_TIMEOUT 3000 // [ms] + +#if !defined( UINT8_MAX ) + #define UINT8_MAX 255 +#endif + + +#if _USE_MBG_TSTR + +/*HDR*/ +/** + * @brief Set a callback function and argument used to decode a time string + * + * Some devices send a serial time string interleaved with some binary messages. + * If a callback function has been specified then the binary message receiver + * function invokes that callback function whenever some characters are received + * which don't belong to a binary message. A callback function like ::mbg_tstr_receive + * can then try to decode a serial time string from such spurious characters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] fnc Address of a ::MBG_TSTR_RCV_FNC-style callback function + * @param[in] arg A prepared ::MBG_TSTR_RCV_ARG structure passed to the callback + * function whenever it is invoked. + * + * @see ::MBG_TSTR_RCV_FNC + * @see ::MBG_TSTR_RCV_ARG + * @see ::mbg_tstr_set_rcv_callback + */ +void mbgextio_set_chk_tstr( MBG_MSG_CTL *pmctl, MBG_TSTR_RCV_FNC *fnc, MBG_TSTR_RCV_ARG *arg ) +{ + MBG_MSG_RCV_CTL *prctl = &pmctl->rcv; + + prctl->tstr_rcv_fnc = fnc; + prctl->tstr_rcv_arg = arg; + +} // mbgextio_set_chk_tstr + +#endif // _USE_MBG_TSTR @@ -52,167 +358,3585 @@ /** * @brief Read all serial port settings and supported configuration parameters * - * @note The function mbgextio_setup_receiver_info() must have been called before, - * and the returned ::RECEIVER_INFO has to be passed to this function. + * ::mbgextio_setup_receiver_info should have been called before to set up + * a ::RECEIVER_INFO structure to be passed to this function, so this + * function can determine how many serial ports and associated structures + * are supported by this device. * - * The complementary function mbgextio_save_serial_settings() should + * The complementary function ::mbgextio_save_serial_settings should * be used to write a modified port configuration back to the device. * - * @param pmctl Pointer to a valid message control structure - * @param p_addr Pointer to XBP address specifier - * @param p_cfg Pointer to a ::RECEIVER_PORT_CFG structure to be set up - * @param p_ri Pointer to a valid ::RECEIVER_INFO structure + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p_rpcfg Pointer to a ::RECEIVER_PORT_CFG structure to be set up * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_save_serial_settings * @see ::mbgextio_get_receiver_info */ -int mbgextio_get_serial_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, - RECEIVER_PORT_CFG *p_cfg, const RECEIVER_INFO *p_ri ) +int mbgextio_get_serial_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + RECEIVER_PORT_CFG *p_rpcfg ) { - int rc = 0; + const RECEIVER_INFO *p_ri = mbgextio_get_receiver_info_addr( pmctl ); + int rc = MBG_SUCCESS; - memset( p_cfg, 0, sizeof( *p_cfg ) ); + memset( p_rpcfg, 0, sizeof( *p_rpcfg ) ); if ( p_ri->model_code != GPS_MODEL_UNKNOWN ) { - rc = mbgextio_get_all_port_info( pmctl, p_addr, p_cfg->pii, p_ri ); + // The device provided a RECEIVER_INFO, so we can simply read all + // serial port configuration and supported string types directly. + + rc = mbgextio_get_all_port_info( pmctl, p_addr, p_rpcfg->pii ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error (rc ) ) goto out; - rc = mbgextio_get_all_str_type_info( pmctl, p_addr, p_cfg->stii, p_ri ); + rc = mbgextio_get_all_str_type_info( pmctl, p_addr, p_rpcfg->stii ); } else { - #if 0 // TODO ##+++++++ provide some symbols - uint16_t i; + // The device didn't provide a RECEIVER_INFO. If the binary protocol is + // supported then the device is old GPS receiver. Other legacy devices + // didn't support the binary protocol. + + // We read the serial port configuration using a legacy API call + // and set up current structures accordingly. + + rc = mbgextio_get_port_parm( pmctl, p_addr, &p_rpcfg->tmp_pp ); + + if ( mbg_rc_is_error (rc ) ) + goto out; + + rc = setup_port_info_from_port_settings( p_rpcfg->pii, &p_rpcfg->tmp_pp, p_ri ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + // Also set up default string type information. + rc = setup_default_str_type_info_idx( p_rpcfg->stii, p_ri ); + } + +out: + return rc; + +} // mbgextio_get_serial_settings - rc = mbgextio_get_port_parm( pmctl, p_addr, &p_cfg->tmp_pp ); - if ( rc != MBG_SUCCESS ) + +/*HDR*/ +/** + * @brief Send the configuration settings for a single serial port to a device + * + * The function ::mbgextio_get_serial_settings must have been called before + * to read the current settings and configuration options and fill up a + * ::RECEIVER_PORT_CFG structure. + * + * After the settings for a port have been changed according to the supported + * features this function can be used to write the new settings for a specific + * port addressed by the port_idx parameter to the device. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p_rpcfg Pointer to a ::RECEIVER_PORT_CFG structure containg valid data + * @param[in] port_idx Index of the serial port for which to save the settings + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_serial_settings + */ +int mbgextio_save_serial_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const RECEIVER_PORT_CFG *p_rpcfg, uint16_t port_idx ) +{ + int rc = mbgextio_set_port_settings_idx( pmctl, p_addr, + &p_rpcfg->pii[port_idx].port_info.port_settings, port_idx ); + + return rc; + +} // mbgextio_save_serial_settings + + + +/*HDR*/ +/** + * @brief Read all XBP information from a device into a newly or re-allocated ::ALL_XBP_INFO structure + * + * @note ::mbgextio_dev_has_xbp should be called to check if this API is supported. + * + * The allocated ::ALL_XBP_INFO needs to be freed ::free_all_ntp_cfg_info, + * as soon as it is not needed any longer. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_XBP_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_xbp + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_xbp_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_XBP_INFO **p ) +{ + ALL_XBP_INFO *xbp_info = *p; + uint16_t i; + int rc; + + if ( xbp_info == NULL ) + { + xbp_info = (ALL_XBP_INFO *) calloc( 1, sizeof( *xbp_info ) ); + if ( xbp_info == NULL ) + { + rc = MBG_ERR_NO_MEM; goto out; + } + } + + rc = mbgextio_get_xbp_limits( pmctl, p_addr, &xbp_info->limits ); - for ( i = 0; i < p_ri->n_com_ports; i++ ) + if ( mbg_rc_is_success( rc ) ) + { + if ( mbg_rc_is_success( chk_dev_xbp_supp_nodes( xbp_info ) ) ) { - PORT_INFO_IDX *p_pii = &p_cfg->pii[i]; - PORT_INFO *p_pi = &p_pii->port_info; + if ( xbp_info->node_limits == NULL ) + { + xbp_info->node_limits = (XBP_NODE_LIMITS *) calloc( 1, sizeof( *xbp_info->node_limits ) ); + if ( xbp_info->node_limits == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_xbp_node_limits( pmctl, p_addr, xbp_info->node_limits ); - p_pii->idx = i; - port_settings_from_port_parm( &p_pi->port_settings, - i, &p_cfg->tmp_pp, 1 ); + if ( mbg_rc_is_error( rc ) ) + goto out; - p_pi->supp_baud_rates = DEFAULT_GPS_BAUD_RATES_C166; - p_pi->supp_framings = DEFAULT_GPS_FRAMINGS_C166; - p_pi->supp_str_types = DEFAULT_SUPP_STR_TYPES_GPS; + if ( xbp_info->node_limits->node_count > 0 ) + { + xbp_info->node_infos = ( XBP_NODE_INFO_IDX * )realloc( xbp_info->node_infos, xbp_info->node_limits->node_count * sizeof( *xbp_info->node_infos ) ); + if ( xbp_info->node_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < xbp_info->node_limits->node_count; i++ ) + { + xbp_info->node_infos[i].idx = i; + rc = mbgextio_get_xbp_node_info_idx( pmctl, p_addr, &xbp_info->node_infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + else + { + if ( xbp_info->node_infos ) + free( xbp_info->node_infos ); + xbp_info->node_infos = NULL; + } } + } - for ( i = 0; i < p_ri->n_str_type; i++ ) +out: + if ( mbg_rc_is_error( rc ) ) + { + if( xbp_info != NULL ) { - STR_TYPE_INFO_IDX *stip = &p_cfg->stii[i]; - stip->idx = i; - stip->str_type_info = default_str_type_info[i]; + free_all_xbp_info( xbp_info ); + xbp_info = NULL; } + } + + *p = xbp_info; + + return rc; + +} // mbgextio_get_all_xbp_info + + + +/*HDR*/ +/** + * @brief Read all network configuration into an ::ALL_NET_CFG_INFO structure + * + * Reads the complete network configuration of a device. Depending on the + * supported API (NET_CFG or LAN_IP4), the appropriate settings are requested and, + * if neccessary, translated into the NET_CFG structures. The filled structures + * can then be used as if the NET_CFG API was completely supported + * + * If NET_CFG or parts of it are not supported, the appropriate n_supp... members + * of ::ALL_NET_CFG_INFO::glb_cfg_info are set to 0, whereas the num... members of + * ::ALL_NET_CFG_INFO::glb_cfg_info::glb_settings may be 1 or bigger. + * + * A ::ALL_NET_CFG_INFO and the appropriate number of ::MBG_NET_INTF_LINK_INFO_IDX, + * ::MBG_NET_INTF_ADDR_INFO_IDX, ::MBG_IP_ADDR_IDX, ::MBG_NET_NAME_IDX and + * ::MBG_NET_INTF_ROUTE_INFO_IDX will be allocated and need to be freed later + * by calling ::free_all_net_cfg_info + * + * @note ::mbgextio_dev_has_net_cfg and mbgextio_dev_has_lan_ip4 are used in the function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_NET_CFG_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_net_cfg + * @see ::mbgextio_get_net_glb_cfg_info + * @see ::mbgextio_get_net_dns_srvr_idx + * @see ::mbgextio_get_net_dns_srch_dom_idx + * @see ::mbgextio_dev_has_lan_ip4 + * @see ::mbgextio_get_lan_if_info + * @see ::mbgextio_get_ip4_settings + * @see ::free_all_net_cfg_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_net_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NET_CFG_INFO **p ) +{ + ALL_NET_CFG_INFO *net_cfg_info = *p; + int rc; + int rc_lan_ip4; + int16_t i; + + if ( net_cfg_info == NULL ) + { + net_cfg_info = (ALL_NET_CFG_INFO *) calloc( 1, sizeof( *net_cfg_info ) ); + if ( net_cfg_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_dev_has_net_cfg( pmctl ); + + if ( mbg_rc_is_success( rc ) ) + { + rc = mbgextio_get_net_glb_cfg_info( pmctl, p_addr, &net_cfg_info->glb_cfg_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( net_cfg_info ) ) && + ( net_cfg_info->glb_cfg_info.glb_settings.num_intf_link > 0 ) ) + { + net_cfg_info->link_infos = ( MBG_NET_INTF_LINK_INFO_IDX * )realloc( net_cfg_info->link_infos, net_cfg_info->glb_cfg_info.glb_settings.num_intf_link * sizeof( *net_cfg_info->link_infos ) ); + if ( net_cfg_info->link_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_cfg_info->glb_cfg_info.glb_settings.num_intf_link; ++i ) + { + rc = mbgextio_get_net_intf_link_info_idx( pmctl, p_addr, &net_cfg_info->link_infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + else + { + if ( net_cfg_info->link_infos ) + free( net_cfg_info->link_infos ); + net_cfg_info->link_infos = NULL; + } + + if ( mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( net_cfg_info ) ) && + ( net_cfg_info->glb_cfg_info.glb_settings.num_intf_addr > 0 ) ) + { + net_cfg_info->addr_infos = ( MBG_NET_INTF_ADDR_INFO_IDX * )realloc( net_cfg_info->addr_infos, net_cfg_info->glb_cfg_info.glb_settings.num_intf_addr * sizeof( *net_cfg_info->addr_infos ) ); + if ( net_cfg_info->addr_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_cfg_info->glb_cfg_info.glb_settings.num_intf_addr; i++ ) + { + rc = mbgextio_get_net_intf_addr_info_idx( pmctl, p_addr, &net_cfg_info->addr_infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + else + { + if ( net_cfg_info->addr_infos ) + free( net_cfg_info->addr_infos ); + net_cfg_info->addr_infos = NULL; + } + + if ( mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( net_cfg_info ) ) && + ( net_cfg_info->glb_cfg_info.glb_settings.num_intf_route > 0 ) ) + { + net_cfg_info->route_infos = ( MBG_NET_INTF_ROUTE_INFO_IDX * )realloc( net_cfg_info->route_infos, net_cfg_info->glb_cfg_info.glb_settings.num_intf_route * sizeof( *net_cfg_info->route_infos ) ); + if ( net_cfg_info->route_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_cfg_info->glb_cfg_info.glb_settings.num_intf_route; i++ ) + { + rc = mbgextio_get_net_intf_route_info_idx( pmctl, p_addr, &net_cfg_info->route_infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + else + { + if ( net_cfg_info->route_infos ) + free( net_cfg_info->route_infos ); + net_cfg_info->route_infos = NULL; + } + + if ( net_cfg_info->glb_cfg_info.n_supp_dns_srvr > 0 ) + { + // If the new API is only partly supported (Syncbox N2x), set the number of DNS servers to the number of supported DNS servers, + // as net_cfg_info->glb_cfg_info.glb_settings.num_dns_srvr is newer than N2x firmware + if ( mbg_rc_is_error( chk_dev_net_cfg_supp_stage_2( net_cfg_info ) ) ) + net_cfg_info->glb_cfg_info.glb_settings.num_dns_srvr = (uint8_t)net_cfg_info->glb_cfg_info.n_supp_dns_srvr; + } + + if ( ( net_cfg_info->glb_cfg_info.n_supp_dns_srvr > 0 ) && + ( net_cfg_info->glb_cfg_info.glb_settings.num_dns_srvr > 0 ) ) + { + net_cfg_info->dns_srvrs = ( MBG_IP_ADDR_IDX * )realloc( net_cfg_info->dns_srvrs, net_cfg_info->glb_cfg_info.glb_settings.num_dns_srvr * sizeof( *net_cfg_info->dns_srvrs ) ); + if ( net_cfg_info->dns_srvrs == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_cfg_info->glb_cfg_info.glb_settings.num_dns_srvr; ++i ) + { + net_cfg_info->dns_srvrs[i].idx = i; + rc = mbgextio_get_net_dns_srvr_idx( pmctl, p_addr, &net_cfg_info->dns_srvrs[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + else + { + if((net_cfg_info->dns_srvrs[i].addr.type == MBG_IP_ADDR_TYPE_UNKNOWN) || + ((net_cfg_info->dns_srvrs[i].addr.type == MBG_IP_ADDR_TYPE_IP4) && + (net_cfg_info->dns_srvrs[i].addr.u_addr.ip4_addr == 0))) + { + net_cfg_info->glb_cfg_info.glb_settings.num_dns_srvr--; + if( net_cfg_info->glb_cfg_info.glb_settings.num_dns_srvr == 0 ) + { + free( net_cfg_info->dns_srvrs ); + net_cfg_info->dns_srvrs = NULL; + } + else + { + net_cfg_info->dns_srvrs = ( MBG_IP_ADDR_IDX * )realloc( net_cfg_info->dns_srvrs, net_cfg_info->glb_cfg_info.glb_settings.num_dns_srvr * sizeof( *net_cfg_info->dns_srvrs ) ); + if ( net_cfg_info->dns_srvrs == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + i--; + } + } + } + } + else + { + if ( net_cfg_info->dns_srvrs ) + free( net_cfg_info->dns_srvrs ); + net_cfg_info->dns_srvrs = NULL; + } + + if ( net_cfg_info->glb_cfg_info.n_supp_dns_srch_dom > 0 ) + { + // If the new API is only partly supported (Syncbox N2x), set the number of DNS search domains to the number of supported DNS search domains, + // as net_cfg_info->glb_cfg_info.glb_settings.num_dns_srch_dom is newer than N2x firmware + if ( mbg_rc_is_error( chk_dev_net_cfg_supp_stage_2( net_cfg_info ) ) ) + net_cfg_info->glb_cfg_info.glb_settings.num_dns_srch_dom = (uint8_t)net_cfg_info->glb_cfg_info.n_supp_dns_srch_dom; + } + + if ( ( net_cfg_info->glb_cfg_info.n_supp_dns_srch_dom > 0 ) && + ( net_cfg_info->glb_cfg_info.glb_settings.num_dns_srch_dom > 0 ) ) + { + net_cfg_info->dns_srch_doms = ( MBG_NET_NAME_IDX * )realloc( net_cfg_info->dns_srch_doms, net_cfg_info->glb_cfg_info.glb_settings.num_dns_srch_dom * sizeof( *net_cfg_info->dns_srch_doms ) ); + if ( net_cfg_info->dns_srch_doms == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_cfg_info->glb_cfg_info.glb_settings.num_dns_srch_dom; ++i ) + { + net_cfg_info->dns_srch_doms[i].idx = i; + rc = mbgextio_get_net_dns_srch_dom_idx( pmctl, p_addr, &net_cfg_info->dns_srch_doms[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + else + { + if( strcmp( net_cfg_info->dns_srch_doms[i].net_name.name, "" ) == 0 ) + { + net_cfg_info->glb_cfg_info.glb_settings.num_dns_srch_dom--; + if( net_cfg_info->glb_cfg_info.glb_settings.num_dns_srch_dom == 0 ) + { + free( net_cfg_info->dns_srch_doms ); + net_cfg_info->dns_srch_doms = NULL; + } + else + { + net_cfg_info->dns_srch_doms = ( MBG_NET_NAME_IDX * )realloc( net_cfg_info->dns_srch_doms, net_cfg_info->glb_cfg_info.glb_settings.num_dns_srch_dom * sizeof( *net_cfg_info->dns_srch_doms ) ); + if ( net_cfg_info->dns_srch_doms == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + i--; + } + } + } + } + else + { + if ( net_cfg_info->dns_srch_doms ) + free( net_cfg_info->dns_srch_doms ); + net_cfg_info->dns_srch_doms = NULL; + } + + } + + if ( mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( net_cfg_info ) ) ) + goto out; + + rc_lan_ip4 = mbgextio_dev_has_lan_ip4( pmctl ); + + if ( mbg_rc_is_success( rc_lan_ip4 ) ) + { + LAN_IF_INFO lan_if_info; + IP4_SETTINGS ip4_settings; + + rc = mbgextio_get_lan_if_info( pmctl, p_addr, &lan_if_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( net_cfg_info->link_infos == NULL ) + { + net_cfg_info->link_infos = (MBG_NET_INTF_LINK_INFO_IDX *) calloc( 1, sizeof( *net_cfg_info->link_infos ) ); + if ( net_cfg_info->link_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + net_cfg_info->glb_cfg_info.n_supp_intf_link = UINT8_MAX; + net_cfg_info->glb_cfg_info.glb_settings.num_intf_link = 1; + + memset( &net_cfg_info->link_infos[0], 0, sizeof( net_cfg_info->link_infos[0] ) ); + + net_cfg_info->link_infos[0].info.supp_states = MBG_NET_INTF_LINK_STATE_MASK_UP; + net_cfg_info->link_infos[0].info.supp_types = MBG_NET_INTF_LINK_TYPE_MASK_PHYS | MBG_NET_INTF_LINK_TYPE_MASK_VLAN; + net_cfg_info->link_infos[0].info.supp_speed_modes = MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL; + net_cfg_info->link_infos[0].info.supp_port_types = MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP; + + snprintf_safe( net_cfg_info->link_infos[0].info.link_settings.name, sizeof( net_cfg_info->link_infos[0].info.link_settings.name ), "lan0" ); + net_cfg_info->link_infos[0].info.link_settings.mac_addr = lan_if_info.mac_addr; + net_cfg_info->link_infos[0].info.link_settings.if_index = 0; + net_cfg_info->link_infos[0].info.link_settings.hw_type = MBG_ARPHRD_ETHER; + net_cfg_info->link_infos[0].info.link_settings.type = MBG_NET_INTF_LINK_TYPE_PHYS; + net_cfg_info->link_infos[0].info.link_settings.port_type = MBG_NET_INTF_LINK_PORT_TYPE_TP; + + rc = mbgextio_get_ip4_settings( pmctl, p_addr, &ip4_settings ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if( ip4_settings.flags & IP4_MSK_LINK ) + { + net_cfg_info->link_infos[0].info.link_settings.states |= MBG_NET_INTF_LINK_STATE_MASK_UP; + net_cfg_info->link_infos[0].info.link_settings.states |= MBG_NET_INTF_LINK_STATE_MASK_LOWER_UP; + } + + if ( net_cfg_info->addr_infos == NULL ) + { + net_cfg_info->addr_infos = (MBG_NET_INTF_ADDR_INFO_IDX *) calloc( 1, sizeof( *net_cfg_info->addr_infos ) ); + if ( net_cfg_info->addr_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + net_cfg_info->glb_cfg_info.n_supp_intf_addr = 1; + net_cfg_info->glb_cfg_info.glb_settings.num_intf_addr = 1; + + memset( &net_cfg_info->addr_infos[0], 0, sizeof( net_cfg_info->addr_infos[0] ) ); + + net_cfg_info->addr_infos[0].info.supp_flags = MBG_NET_INTF_ADDR_MASK_DHCP4; + + snprintf_safe( net_cfg_info->addr_infos[0].info.addr_settings.label, sizeof( net_cfg_info->addr_infos[0].info.addr_settings.label ), "lan0:0" ); + + if ( ip4_settings.flags & IP4_MSK_VLAN ) + { + net_cfg_info->link_infos = ( MBG_NET_INTF_LINK_INFO_IDX * )realloc( net_cfg_info->link_infos, 2 * sizeof( *net_cfg_info->link_infos ) ); + if ( net_cfg_info->link_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + net_cfg_info->glb_cfg_info.glb_settings.num_intf_link = 2; + + memset(&net_cfg_info->link_infos[1], 0, sizeof(net_cfg_info->link_infos[1])); + + net_cfg_info->link_infos[1].idx = 1; + net_cfg_info->link_infos[1].info.supp_states = MBG_NET_INTF_LINK_STATE_MASK_UP; + net_cfg_info->link_infos[1].info.supp_types = MBG_NET_INTF_LINK_TYPE_MASK_VLAN; + net_cfg_info->link_infos[1].info.supp_speed_modes = MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL; + net_cfg_info->link_infos[1].info.supp_port_types = MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP; + + snprintf_safe( net_cfg_info->link_infos[1].info.link_settings.name, sizeof( net_cfg_info->link_infos[1].info.link_settings.name ), "vlan0" ); + net_cfg_info->link_infos[1].info.link_settings.mac_addr = net_cfg_info->link_infos[0].info.link_settings.mac_addr; + net_cfg_info->link_infos[1].info.link_settings.if_index = 1; + net_cfg_info->link_infos[1].info.link_settings.ass_if_index = 0; + net_cfg_info->link_infos[1].info.link_settings.states = net_cfg_info->link_infos[0].info.link_settings.states; + net_cfg_info->link_infos[1].info.link_settings.type = MBG_NET_INTF_LINK_TYPE_VLAN; + net_cfg_info->link_infos[1].info.link_settings.vlan_cfg = ip4_settings.vlan_cfg; + + net_cfg_info->addr_infos[0].info.addr_settings.ass_if_index = 1; + } + + if ( ip4_settings.flags & IP4_MSK_DHCP ) + net_cfg_info->addr_infos[0].info.addr_settings.flags |= MBG_NET_INTF_ADDR_MASK_DHCP4; + + net_cfg_info->addr_infos[0].info.addr_settings.ip.type = MBG_IP_ADDR_TYPE_IP4; + net_cfg_info->addr_infos[0].info.addr_settings.ip.u_addr.ip4_addr = ip4_settings.ip_addr; + + net_cfg_info->addr_infos[0].info.addr_settings.broadcast.type = MBG_IP_ADDR_TYPE_IP4; + net_cfg_info->addr_infos[0].info.addr_settings.broadcast.u_addr.ip4_addr = ip4_settings.broad_addr; + + net_cfg_info->addr_infos[0].info.addr_settings.prefix_bits = get_ip4_net_mask_bits(&ip4_settings.netmask); + + if ( net_cfg_info->route_infos == NULL ) + { + net_cfg_info->route_infos = (MBG_NET_INTF_ROUTE_INFO_IDX *) calloc( 1, sizeof( *net_cfg_info->route_infos ) ); + if ( net_cfg_info->route_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + net_cfg_info->glb_cfg_info.n_supp_intf_route = 1; + net_cfg_info->glb_cfg_info.glb_settings.num_intf_route = 1; + + memset( &net_cfg_info->route_infos[0], 0, sizeof( net_cfg_info->route_infos[0] ) ); + + net_cfg_info->route_infos[0].info.route_settings.type = MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY; + net_cfg_info->route_infos[0].info.route_settings.gateway.type = MBG_IP_ADDR_TYPE_IP4; + net_cfg_info->route_infos[0].info.route_settings.gateway.u_addr.ip4_addr = ip4_settings.gateway; + if ( ip4_settings.gateway != 0 ) + { + if(net_cfg_info->glb_cfg_info.glb_settings.num_intf_link == 2) + net_cfg_info->route_infos[0].info.route_settings.ass_if_index = 1; + } + else net_cfg_info->route_infos[0].info.route_settings.ass_if_index = (uint32_t)-1; - rc = MBG_SUCCESS; - #endif } + if ( mbg_rc_is_error( rc ) && mbg_rc_is_error( rc_lan_ip4 ) ) + rc = rc_lan_ip4; + out: + if ( mbg_rc_is_error( rc ) ) + { + free_all_net_cfg_info( net_cfg_info ); + net_cfg_info = NULL; + } + + *p = net_cfg_info; + return rc; -} // mbgextio_get_serial_settings +} // mbgextio_get_all_net_cfg_info /*HDR*/ /** - * @brief Send the configuration settings for a single serial port to a device + * @brief Write all network settings to a device + * + * The complementary function ::mbgextio_get_all_net_cfg_info should + * have been used to read the original network settings and supported + * configuration parameters. * - * @note The function mbgextio_setup_receiver_info() must have been called before, - * and the returned ::RECEIVER_INFO has to be passed to this function as well as - * to mbgextio_get_serial_settings() which should have been called before to read - * the current settings and supported features for each port. + * Depending on the supported API (NET_CFG or LAN_IP4 or both partly), + * the appropriate settings are, if neccessary, translated into LAN_IP4 structures + * and send to the device using the appropriate API functions. * - * @param pmctl Pointer to a valid message control structure - * @param p_addr Pointer to XBP address specifier - * @param pcfg Pointer to a ::RECEIVER_PORT_CFG structure - * @param port_idx Index of the serial port to be saved + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the ::ALL_NET_CFG_INFO * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_get_serial_settings - * @see ::mbgextio_get_receiver_info */ -int mbgextio_save_serial_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, - const RECEIVER_PORT_CFG *pcfg, uint16_t port_idx ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_net_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NET_CFG_INFO *p ) +{ + int rc = MBG_ERR_NOT_SUPP_BY_DEV; + int16_t i; + + // Check if stage 2 of NET_CFG_API is supported + // If it isn't, the current configuration has to be set using the LAN_IP4 API. + if ( mbg_rc_is_error( chk_dev_net_cfg_supp_stage_2( p ) ) ) + { + rc = mbgextio_dev_has_lan_ip4( pmctl ); + + if ( mbg_rc_is_success( rc ) ) + { + IP4_SETTINGS ip4_settings; + memset( &ip4_settings, 0, sizeof( ip4_settings ) ); + + if (p->glb_cfg_info.glb_settings.num_intf_addr > 0) + { + if ( p->addr_infos[0].info.addr_settings.ip.type == MBG_IP_ADDR_TYPE_IP4 ) + ip4_settings.ip_addr = p->addr_infos[0].info.addr_settings.ip.u_addr.ip4_addr; + + ip4_settings.netmask = ip4_net_mask_from_cidr( p->addr_infos[0].info.addr_settings.prefix_bits ); + ip4_settings.broad_addr = ip4_broad_addr_from_addr( &ip4_settings.ip_addr, &ip4_settings.netmask ); + + if ( ( p->addr_infos[0].info.addr_settings.flags & MBG_NET_INTF_ADDR_MASK_DHCP4 ) == MBG_NET_INTF_ADDR_MASK_DHCP4 ) + ip4_settings.flags |= IP4_MSK_DHCP; + } + + if (p->glb_cfg_info.glb_settings.num_intf_route > 0) + { + if ( p->route_infos[0].info.route_settings.gateway.type == MBG_IP_ADDR_TYPE_IP4 ) + ip4_settings.gateway = p->route_infos[0].info.route_settings.gateway.u_addr.ip4_addr; + } + + if ( ( p->glb_cfg_info.glb_settings.num_intf_link > 1 ) && ( p->addr_infos[0].info.addr_settings.ass_if_index == 1 ) ) + { + ip4_settings.flags |= IP4_MSK_VLAN; + ip4_settings.vlan_cfg = p->link_infos[1].info.link_settings.vlan_cfg; + } + + rc = mbgextio_set_ip4_settings( pmctl, p_addr, &ip4_settings ); + } + } + + if ( mbg_rc_is_success( mbgextio_dev_has_net_cfg( pmctl ) ) ) + { + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_NETWORK, 1 ); + + if ( mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( p ) ) ) + { + // If stage 2 is supported, write ::MBG_NET_GLB_CFG_SETTINGS first + rc = mbgextio_set_net_glb_cfg_settings( pmctl, p_addr, &p->glb_cfg_info.glb_settings ); + + for ( i = 0; ( i < p->glb_cfg_info.glb_settings.num_intf_link ) && mbg_rc_is_success( rc ) ; ++i ) + { + p->link_infos[i].idx = i; + rc = mbgextio_set_net_intf_link_settings_idx( pmctl, p_addr, &p->link_infos[i].info.link_settings, i ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + for ( i = 0; ( i < p->glb_cfg_info.glb_settings.num_intf_addr ) && mbg_rc_is_success( rc ) ; ++i ) + { + p->addr_infos[i].idx = i; + rc = mbgextio_set_net_intf_addr_settings_idx( pmctl, p_addr, &p->addr_infos[i].info.addr_settings, i ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + for ( i = 0; ( i < p->glb_cfg_info.glb_settings.num_intf_route ) && mbg_rc_is_success( rc ) ; ++i ) + { + p->route_infos[i].idx = i; + rc = mbgextio_set_net_intf_route_settings_idx( pmctl, p_addr, &p->route_infos[i].info.route_settings, i ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + for ( i = 0; ( i < p->glb_cfg_info.glb_settings.num_dns_srch_dom ) && mbg_rc_is_success( rc ) ; ++i ) + { + p->dns_srch_doms[i].idx = i; + rc = mbgextio_set_net_dns_srch_dom_idx( pmctl, p_addr, &p->dns_srch_doms[i].net_name, i ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + for ( i = 0; ( i < p->glb_cfg_info.glb_settings.num_dns_srvr ) && mbg_rc_is_success( rc ) ; ++i ) + { + p->dns_srvrs[i].idx = i; + rc = mbgextio_set_net_dns_srvr_idx( pmctl, p_addr, &p->dns_srvrs[i].addr, i ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + } + else + { + MBG_NET_NAME_IDX no_dns_srch_dom; + MBG_IP_ADDR_IDX no_dns_srvr; + + memset(&no_dns_srch_dom, 0, sizeof(no_dns_srch_dom)); + memset(&no_dns_srvr, 0, sizeof(no_dns_srvr)); + no_dns_srvr.addr.type = MBG_IP_ADDR_TYPE_IP4; + + for ( i = 0; ( i < p->glb_cfg_info.n_supp_dns_srch_dom ) && mbg_rc_is_success( rc ) ; ++i ) + { + if( i >= p->glb_cfg_info.glb_settings.num_dns_srch_dom ) + { + no_dns_srch_dom.idx = i; + rc = mbgextio_set_net_dns_srch_dom_idx( pmctl, p_addr, &no_dns_srch_dom.net_name, i ); + } + else + { + p->dns_srch_doms[i].idx = i; + rc = mbgextio_set_net_dns_srch_dom_idx( pmctl, p_addr, &p->dns_srch_doms[i].net_name, i ); + } + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + for ( i = 0; ( i < p->glb_cfg_info.n_supp_dns_srvr ) && mbg_rc_is_success( rc ) ; ++i ) + { + if( i >= p->glb_cfg_info.glb_settings.num_dns_srvr ) + { + no_dns_srvr.idx = i; + rc = mbgextio_set_net_dns_srvr_idx( pmctl, p_addr, &no_dns_srvr.addr, i ); + } + else + { + p->dns_srvrs[i].idx = i; + rc = mbgextio_set_net_dns_srvr_idx( pmctl, p_addr, &p->dns_srvrs[i].addr, i ); + } + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + // If stage 2 is not supported, write ::MBG_NET_GLB_CFG_SETTINGS at the end + rc = mbgextio_set_net_glb_cfg_settings( pmctl, p_addr, &p->glb_cfg_info.glb_settings ); + } + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_NETWORK ); + + } + +out: + return rc; + +} // mbgextio_save_all_net_cfg_info + + + +/*HDR*/ +/** + * @brief Read current network status into an ::ALL_NET_STATUS_INFO structure + * + * Depending on the supported API (NET_CFG or LAN_IP4), the appropriate status + * is requested and, if neccessary, translated into the NET_CFG structures. + * The filled structures can then be used as if the NET_CFG API was completely supported. + * + * A ::ALL_NET_STATUS_INFO and the appropriate number of ::MBG_NET_INTF_LINK_INFO_IDX, + * ::MBG_NET_INTF_ADDR_INFO_IDX, ::MBG_IP_ADDR_IDX, ::MBG_NET_NAME_IDX and + * ::MBG_NET_INTF_ROUTE_INFO_IDX will be allocated and need to be freed later + * by calling ::free_all_net_status_info + * + * @note ::mbgextio_dev_has_net_cfg and mbgextio_dev_has_lan_ip4 are used in the function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_NET_STATUS_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_net_cfg + * @see ::mbgextio_get_net_glb_cfg_info + * @see ::mbgextio_get_net_stat_dns_srvr_idx + * @see ::mbgextio_get_net_stat_dns_srch_dom_stat_idx + * @see ::mbgextio_dev_has_lan_ip4 + * @see ::mbgextio_get_lan_if_info + * @see ::mbgextio_get_ip4_state + * @see ::free_all_net_status_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_net_status_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NET_STATUS_INFO **p ) { + ALL_NET_STATUS_INFO *net_status_info = *p; int rc; + int rc_lan_ip4; + int16_t i; - rc = mbgextio_set_port_settings_idx( pmctl, p_addr, - &pcfg->pii[port_idx].port_info.port_settings, port_idx ); + if ( net_status_info == NULL ) + { + net_status_info = (ALL_NET_STATUS_INFO *) calloc( 1, sizeof( *net_status_info ) ); + if ( net_status_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } - return rc; //##++ MBG_SUCCESS or < 0 on error + rc = mbgextio_dev_has_net_cfg( pmctl ); -} // mbgextio_save_serial_settings + if ( mbg_rc_is_success( rc ) ) + { + rc = mbgextio_get_net_glb_cfg_info( pmctl, p_addr, &net_status_info->glb_cfg_info ); + + if( mbg_rc_is_success( rc ) && mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( net_status_info ) ) ) + rc = mbgextio_get_net_stat_glb_cfg_info( pmctl, p_addr, &net_status_info->glb_cfg_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( net_status_info ) ) && + ( net_status_info->glb_cfg_info.glb_settings.num_intf_link > 0 ) ) + { + net_status_info->link_infos = ( MBG_NET_INTF_LINK_INFO_IDX * )realloc( net_status_info->link_infos, net_status_info->glb_cfg_info.glb_settings.num_intf_link * sizeof( *net_status_info->link_infos ) ); + if ( net_status_info->link_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_status_info->glb_cfg_info.glb_settings.num_intf_link; ++i ) + { + rc = mbgextio_get_net_stat_intf_link_info_idx( pmctl, p_addr, &net_status_info->link_infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + else + { + if ( net_status_info->link_infos ) + free( net_status_info->link_infos ); + net_status_info->link_infos = NULL; + } + + if ( mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( net_status_info ) ) && + ( net_status_info->glb_cfg_info.glb_settings.num_intf_addr > 0 ) ) + { + net_status_info->addr_infos = ( MBG_NET_INTF_ADDR_INFO_IDX * )realloc( net_status_info->addr_infos, net_status_info->glb_cfg_info.glb_settings.num_intf_addr * sizeof( *net_status_info->addr_infos ) ); + if ( net_status_info->addr_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_status_info->glb_cfg_info.glb_settings.num_intf_addr; ++i ) + { + rc = mbgextio_get_net_stat_intf_addr_info_idx( pmctl, p_addr, &net_status_info->addr_infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + else + { + if ( net_status_info->addr_infos ) + free( net_status_info->addr_infos ); + net_status_info->addr_infos = NULL; + } + + if ( mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( net_status_info ) ) && + ( net_status_info->glb_cfg_info.glb_settings.num_intf_route > 0 ) ) + { + net_status_info->route_infos = ( MBG_NET_INTF_ROUTE_INFO_IDX * )realloc( net_status_info->route_infos, net_status_info->glb_cfg_info.glb_settings.num_intf_route * sizeof( *net_status_info->route_infos ) ); + if ( net_status_info->route_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_status_info->glb_cfg_info.glb_settings.num_intf_route; ++i ) + { + rc = mbgextio_get_net_stat_intf_route_info_idx( pmctl, p_addr, &net_status_info->route_infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + else + { + if ( net_status_info->route_infos ) + free( net_status_info->route_infos ); + net_status_info->route_infos = NULL; + } + + if ( net_status_info->glb_cfg_info.n_supp_dns_srvr > 0 ) + { + // If the new API is only partly supported (Syncbox N2x), set the number of DNS servers to the number of supported DNS servers, + // as net_status_info->glb_cfg_info.glb_settings.num_dns_srvr is newer than N2x firmware + if ( mbg_rc_is_error( chk_dev_net_cfg_supp_stage_2( net_status_info ) ) ) + net_status_info->glb_cfg_info.glb_settings.num_dns_srvr = (uint8_t)net_status_info->glb_cfg_info.n_supp_dns_srvr; + } + + if ( ( net_status_info->glb_cfg_info.n_supp_dns_srvr > 0 ) && + ( net_status_info->glb_cfg_info.glb_settings.num_dns_srvr > 0 ) ) + { + net_status_info->dns_srvrs = ( MBG_IP_ADDR_IDX * )realloc( net_status_info->dns_srvrs, net_status_info->glb_cfg_info.glb_settings.num_dns_srvr * sizeof( *net_status_info->dns_srvrs ) ); + if ( net_status_info->dns_srvrs == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_status_info->glb_cfg_info.glb_settings.num_dns_srvr; i++ ) + { + net_status_info->dns_srvrs[i].idx = i; + rc = mbgextio_get_net_stat_dns_srvr_idx( pmctl, p_addr, &net_status_info->dns_srvrs[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + else + { + if((net_status_info->dns_srvrs[i].addr.type == MBG_IP_ADDR_TYPE_UNKNOWN) || + ((net_status_info->dns_srvrs[i].addr.type == MBG_IP_ADDR_TYPE_IP4) && + (net_status_info->dns_srvrs[i].addr.u_addr.ip4_addr == 0))) + { + net_status_info->glb_cfg_info.glb_settings.num_dns_srvr--; + if( net_status_info->glb_cfg_info.glb_settings.num_dns_srvr == 0 ) + { + free( net_status_info->dns_srvrs ); + net_status_info->dns_srvrs = NULL; + } + else + { + net_status_info->dns_srvrs = ( MBG_IP_ADDR_IDX * )realloc( net_status_info->dns_srvrs, net_status_info->glb_cfg_info.glb_settings.num_dns_srvr * sizeof( *net_status_info->dns_srvrs ) ); + if ( net_status_info->dns_srvrs == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + i--; + } + } + } + } + else + { + if ( net_status_info->dns_srvrs ) + free( net_status_info->dns_srvrs ); + net_status_info->dns_srvrs = NULL; + } + + if ( net_status_info->glb_cfg_info.n_supp_dns_srch_dom > 0 ) + { + // If the new API is only partly supported (Syncbox N2x), set the number of DNS search domains to the number of supported DNS search domains, + // as net_status_info->glb_cfg_info.glb_settings.num_dns_srch_dom is newer than N2x firmware + if ( mbg_rc_is_error( chk_dev_net_cfg_supp_stage_2( net_status_info ) ) ) + net_status_info->glb_cfg_info.glb_settings.num_dns_srch_dom = (uint8_t)net_status_info->glb_cfg_info.n_supp_dns_srch_dom; + } + + if ( ( net_status_info->glb_cfg_info.n_supp_dns_srch_dom > 0 ) && + ( net_status_info->glb_cfg_info.glb_settings.num_dns_srch_dom > 0 ) ) + { + net_status_info->dns_srch_doms = ( MBG_NET_NAME_IDX * )realloc( net_status_info->dns_srch_doms, net_status_info->glb_cfg_info.glb_settings.num_dns_srch_dom * sizeof( *net_status_info->dns_srch_doms ) ); + if ( net_status_info->dns_srch_doms == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < net_status_info->glb_cfg_info.glb_settings.num_dns_srch_dom; i++ ) + { + net_status_info->dns_srch_doms[i].idx = i; + rc = mbgextio_get_net_stat_dns_srch_dom_stat_idx( pmctl, p_addr, &net_status_info->dns_srch_doms[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + else + { + if( strcmp( net_status_info->dns_srch_doms[i].net_name.name, "" ) == 0 ) + { + net_status_info->glb_cfg_info.glb_settings.num_dns_srch_dom--; + if( net_status_info->glb_cfg_info.glb_settings.num_dns_srch_dom == 0 ) + { + free( net_status_info->dns_srch_doms ); + net_status_info->dns_srch_doms = NULL; + } + else + { + net_status_info->dns_srch_doms = ( MBG_NET_NAME_IDX * )realloc( net_status_info->dns_srch_doms, net_status_info->glb_cfg_info.glb_settings.num_dns_srch_dom * sizeof( *net_status_info->dns_srch_doms ) ); + if ( net_status_info->dns_srch_doms == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + i--; + } + } + } + } + else + { + if ( net_status_info->dns_srch_doms ) + free( net_status_info->dns_srch_doms ); + net_status_info->dns_srch_doms = NULL; + } + + } + + if ( mbg_rc_is_success( chk_dev_net_cfg_supp_stage_2( net_status_info ) ) ) + goto out; + + rc_lan_ip4 = mbgextio_dev_has_lan_ip4( pmctl ); + + if ( mbg_rc_is_success( rc_lan_ip4 ) ) + { + LAN_IF_INFO lan_if_info; + IP4_SETTINGS ip4_state; + + if ( net_status_info->glb_cfg_info.n_supp_intf_link != 0 ) + goto out; + + rc = mbgextio_get_lan_if_info( pmctl, p_addr, &lan_if_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( net_status_info->link_infos == NULL ) + { + net_status_info->link_infos = (MBG_NET_INTF_LINK_INFO_IDX *) calloc( 1, sizeof( *net_status_info->link_infos ) ); + if ( net_status_info->link_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + net_status_info->glb_cfg_info.n_supp_intf_link = UINT8_MAX; + net_status_info->glb_cfg_info.glb_settings.num_intf_link = 1; + + memset( &net_status_info->link_infos[0], 0, sizeof( net_status_info->link_infos[0] ) ); + + net_status_info->link_infos[0].info.supp_states = MBG_NET_INTF_LINK_STATE_MASK_UP; + net_status_info->link_infos[0].info.supp_types = MBG_NET_INTF_LINK_TYPE_MASK_PHYS | MBG_NET_INTF_LINK_TYPE_MASK_VLAN; + net_status_info->link_infos[0].info.supp_speed_modes = MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL; + net_status_info->link_infos[0].info.supp_port_types = MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP; + + snprintf_safe( net_status_info->link_infos[0].info.link_settings.name, sizeof( net_status_info->link_infos[0].info.link_settings.name ), "lan0" ); + net_status_info->link_infos[0].info.link_settings.mac_addr = lan_if_info.mac_addr; + net_status_info->link_infos[0].info.link_settings.if_index = 0; + net_status_info->link_infos[0].info.link_settings.hw_type = MBG_ARPHRD_ETHER; + net_status_info->link_infos[0].info.link_settings.type = MBG_NET_INTF_LINK_TYPE_PHYS; + net_status_info->link_infos[0].info.link_settings.port_type = MBG_NET_INTF_LINK_PORT_TYPE_TP; + + if ( net_status_info->glb_cfg_info.n_supp_intf_addr != 0 ) + goto out; + + rc = mbgextio_get_ip4_state( pmctl, p_addr, &ip4_state ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if( ip4_state.flags & IP4_MSK_LINK ) + { + net_status_info->link_infos[0].info.link_settings.states |= MBG_NET_INTF_LINK_STATE_MASK_UP; + net_status_info->link_infos[0].info.link_settings.states |= MBG_NET_INTF_LINK_STATE_MASK_LOWER_UP; + } + + if ( net_status_info->addr_infos == NULL ) + { + net_status_info->addr_infos = (MBG_NET_INTF_ADDR_INFO_IDX *) calloc( 1, sizeof( *net_status_info->addr_infos ) ); + if ( net_status_info->addr_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + net_status_info->glb_cfg_info.n_supp_intf_addr = 1; + net_status_info->glb_cfg_info.glb_settings.num_intf_addr = 1; + + memset( &net_status_info->addr_infos[0], 0, sizeof( net_status_info->addr_infos[0] ) ); + + net_status_info->addr_infos[0].info.supp_flags = MBG_NET_INTF_ADDR_MASK_DHCP4; + + snprintf_safe( net_status_info->addr_infos[0].info.addr_settings.label, sizeof( net_status_info->addr_infos[0].info.addr_settings.label ), "lan0:0" ); + + if ( ip4_state.flags & IP4_MSK_VLAN ) + { + net_status_info->link_infos = ( MBG_NET_INTF_LINK_INFO_IDX * )realloc( net_status_info->link_infos, 2 * sizeof( *net_status_info->link_infos ) ); + if ( net_status_info->link_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + net_status_info->glb_cfg_info.glb_settings.num_intf_link = 2; + + memset(&net_status_info->link_infos[1], 0, sizeof(net_status_info->link_infos[1])); + + net_status_info->link_infos[1].idx = 1; + net_status_info->link_infos[1].info.supp_states = MBG_NET_INTF_LINK_STATE_MASK_UP; + net_status_info->link_infos[1].info.supp_types = MBG_NET_INTF_LINK_TYPE_MASK_VLAN; + net_status_info->link_infos[1].info.supp_speed_modes = MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF | MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL; + net_status_info->link_infos[1].info.supp_port_types = MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP; + + snprintf_safe( net_status_info->link_infos[1].info.link_settings.name, sizeof( net_status_info->link_infos[1].info.link_settings.name ), "vlan0" ); + net_status_info->link_infos[1].info.link_settings.mac_addr = net_status_info->link_infos[0].info.link_settings.mac_addr; + net_status_info->link_infos[1].info.link_settings.if_index = 1; + net_status_info->link_infos[1].info.link_settings.ass_if_index = 0; + net_status_info->link_infos[1].info.link_settings.states = net_status_info->link_infos[0].info.link_settings.states; + net_status_info->link_infos[1].info.link_settings.type = MBG_NET_INTF_LINK_TYPE_VLAN; + net_status_info->link_infos[1].info.link_settings.vlan_cfg = ip4_state.vlan_cfg; + + net_status_info->addr_infos[0].info.addr_settings.ass_if_index = 1; + } + + if ( ip4_state.flags & IP4_MSK_DHCP ) + net_status_info->addr_infos[0].info.addr_settings.flags |= MBG_NET_INTF_ADDR_MASK_DHCP4; + + net_status_info->addr_infos[0].info.addr_settings.ip.type = MBG_IP_ADDR_TYPE_IP4; + net_status_info->addr_infos[0].info.addr_settings.ip.u_addr.ip4_addr = ip4_state.ip_addr; + + net_status_info->addr_infos[0].info.addr_settings.broadcast.type = MBG_IP_ADDR_TYPE_IP4; + net_status_info->addr_infos[0].info.addr_settings.broadcast.u_addr.ip4_addr = ip4_state.broad_addr; + + net_status_info->addr_infos[0].info.addr_settings.prefix_bits = get_ip4_net_mask_bits(&ip4_state.netmask); + + if ( net_status_info->glb_cfg_info.n_supp_intf_route == 0 ) + { + if ( net_status_info->route_infos == NULL ) + { + net_status_info->route_infos = (MBG_NET_INTF_ROUTE_INFO_IDX *) calloc( 1, sizeof( *net_status_info->route_infos ) ); + if ( net_status_info->route_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + net_status_info->glb_cfg_info.n_supp_intf_route = 1; + net_status_info->glb_cfg_info.glb_settings.num_intf_route = 1; + + memset( &net_status_info->route_infos[0], 0, sizeof( net_status_info->route_infos[0] ) ); + + net_status_info->route_infos[0].info.route_settings.type = MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY; + net_status_info->route_infos[0].info.route_settings.gateway.type = MBG_IP_ADDR_TYPE_IP4; + net_status_info->route_infos[0].info.route_settings.gateway.u_addr.ip4_addr = ip4_state.gateway; + if ( ip4_state.gateway != 0 ) + { + if(net_status_info->glb_cfg_info.glb_settings.num_intf_link == 2) + net_status_info->route_infos[0].info.route_settings.ass_if_index = 1; + } + else net_status_info->route_infos[0].info.route_settings.ass_if_index = (uint32_t)-1; + + } + + } + + if ( mbg_rc_is_error( rc ) && mbg_rc_is_error( rc_lan_ip4 ) ) + rc = rc_lan_ip4; + +out: + if ( mbg_rc_is_error( rc ) ) + { + free_all_net_status_info( net_status_info ); + net_status_info = NULL; + } + + *p = net_status_info; + + return rc; + +} // mbgextio_get_all_net_status_info /*HDR*/ /** - * @brief Read all PTP configuration in ::ALL_PTP_CFG_INFO format + * @brief Read all monitoring configuration into an ::ALL_MONITORING_INFO structure * - * @note Only supported if ::GPS_HAS_PTP + * A ::ALL_MONITORING_INFO will be allocated and needs + * to be freed later by calling ::free_all_monitoring_info. + * A ::ALL_SNMP_INFO may be allocated, if SNMP is supported. * - * @param pmctl Pointer to a valid message control structure - * @param p_addr Pointer to XBP address specifier - * @param p Pointer to the data structure to return the received data + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_MONITORING_INFO * * @return One of the @ref MBG_RETURN_CODES * - * @see //##++++++++++++++++++++++++++++++ - * @see ::mbgextio_get_receiver_info + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_all_snmp_info + * @see ::free_all_monitoring_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_monitoring_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_MONITORING_INFO **p ) +{ + ALL_MONITORING_INFO *monitoring_info = *p; + int rc; + int16_t i; + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING, 0 ); + + if ( monitoring_info == NULL ) + { + monitoring_info = (ALL_MONITORING_INFO *) calloc( 1, sizeof( *monitoring_info ) ); + if ( monitoring_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_monitoring_limits( pmctl, p_addr, &monitoring_info->limits ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( monitoring_info->event_infos == NULL ) + { + monitoring_info->event_infos = (MBG_EVENT_INFO_IDX_DATA *) calloc( monitoring_info->limits.supp_num_events, sizeof( *monitoring_info->event_infos ) ); + if ( monitoring_info->event_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + if ( ( monitoring_info->limits.supp_types & MBG_MONITORING_TYPE_MSK_SNMP ) == MBG_MONITORING_TYPE_MSK_SNMP ) + rc = mbgextio_get_all_snmp_info( pmctl, p_addr, &monitoring_info->all_snmp_info ); + + if ( monitoring_info->limits.supp_num_events > 0 ) + { + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_EVENTS, 0 ); + + for ( i = 0; (i < monitoring_info->limits.supp_num_events) && mbg_rc_is_success( rc ) ; ++i ) + { + monitoring_info->event_infos[i].info.idx = i; + rc = mbgextio_get_event_info_idx( pmctl, p_addr, &monitoring_info->event_infos[i].info, i ); + } + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_EVENTS ); + } + +out: + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING ); + + if ( mbg_rc_is_error( rc ) ) + { + free_all_monitoring_info( monitoring_info ); + monitoring_info = NULL; + } + + *p = monitoring_info; + + return rc; + +} // mbgextio_get_all_monitoring_info + + + +/*HDR*/ +/** + * @brief Write all monitoring configuration to a device + * + * The complementary function ::mbgextio_get_all_monitoring_info should have been used + * to read the original monitoring settings and supported configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_MONITORING_INFO structure with all monitoring parameters + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_all_monitoring_info + * @see ::mbgextio_save_all_snmp_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_monitoring_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_MONITORING_INFO *p ) +{ + int rc = MBG_SUCCESS; + int16_t i; + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING, 1 ); + + if ( ( p->limits.supp_types & MBG_MONITORING_TYPE_MSK_SNMP ) == MBG_MONITORING_TYPE_MSK_SNMP ) + rc = mbgextio_save_all_snmp_info( pmctl, p_addr, p->all_snmp_info ); + + if ( p->limits.supp_num_events > 0 ) + { + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_EVENTS, 1 ); + + for ( i = 0; (i < p->limits.supp_num_events) && mbg_rc_is_success( rc ) ; ++i ) + rc = mbgextio_set_event_settings_idx( pmctl, p_addr, &p->event_infos[i].info.info.settings, i ); + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_EVENTS ); + } + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING ); + + return rc; + +} // mbgextio_save_all_monitoring_info + + + +/*HDR*/ +/** + * @brief Read all monitoring status into an ::ALL_MONITORING_STATUS structure + * + * A ::ALL_MONITORING_STATUS will be allocated and needs + * to be freed later by calling ::free_all_monitoring_status. + * The ::ALL_MONITORING_INFO::limits is used to check which events are supported + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to a ::ALL_MONITORING_INFO structure which has been read before + * @param[out] p Pointer to a pointer to ::ALL_MONITORING_STATUS + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::free_all_monitoring_status + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_monitoring_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_MONITORING_INFO *info, ALL_MONITORING_STATUS **p ) +{ + ALL_MONITORING_STATUS *monitoring_status = *p; + int rc; + int16_t i; + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING, 0 ); + + if ( monitoring_status == NULL ) + { + monitoring_status = (ALL_MONITORING_STATUS *) calloc( 1, sizeof( *monitoring_status ) ); + if ( monitoring_status == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_monitoring_status( pmctl, p_addr, &monitoring_status->status ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( monitoring_status->event_stati == NULL ) + { + monitoring_status->event_stati = (MBG_EVENT_STATUS_IDX_DATA *) calloc( info->limits.supp_num_events, sizeof( *monitoring_status->event_stati ) ); + if ( monitoring_status->event_stati == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + if ( info->limits.supp_num_events > 0 ) + { + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_EVENTS, 0 ); + + for ( i = 0; (i < info->limits.supp_num_events) && mbg_rc_is_success( rc ) ; ++i ) + { + monitoring_status->event_stati[i].status.idx = i; + rc = mbgextio_get_event_status_idx( pmctl, p_addr, &monitoring_status->event_stati[i].status, i ); + } + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_EVENTS ); + } + +out: + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING ); + + if ( mbg_rc_is_error( rc ) ) + { + free_all_monitoring_status( monitoring_status ); + monitoring_status = NULL; + } + + *p = monitoring_status; + + return rc; + +} // mbgextio_get_all_monitoring_status + + + +/*HDR*/ +/** + * @brief Read all SNMP configuration into an ::ALL_SNMP_INFO structure + * + * A ::ALL_SNMP_INFO and the appropriate number of ::MBG_SNMP_V12_INFO_IDX, + * ::MBG_SNMP_V12_TRAP_INFO_IDX, ::MBG_SNMP_V3_INFO_IDX, and ::MBG_SNMP_V3_TRAP_INFO_IDX + * will be allocated and need to be freed later by calling ::free_all_snmp_info + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_SNMP_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v12_info_idx + * @see ::mbgextio_get_snmp_v12_trap_info_idx + * @see ::mbgextio_get_snmp_v3_info_idx + * @see ::mbgextio_get_snmp_v3_trap_info_idx + * @see ::free_all_snmp_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_snmp_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_SNMP_INFO **p ) +{ + ALL_SNMP_INFO *snmp_info = *p; + int rc; + int16_t i; + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING_SNMP, 0 ); + + if ( snmp_info == NULL ) + { + snmp_info = (ALL_SNMP_INFO *) calloc( 1, sizeof( *snmp_info ) ); + if ( snmp_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_snmp_glb_info( pmctl, p_addr, &snmp_info->glb_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( ( ( snmp_info->glb_info.supp_versions & MBG_SNMP_VERSION_MSK_V1 ) == MBG_SNMP_VERSION_MSK_V1 ) || + ( ( snmp_info->glb_info.supp_versions & MBG_SNMP_VERSION_MSK_V2c ) == MBG_SNMP_VERSION_MSK_V2c ) ) + { + snmp_info->v12_infos = ( MBG_SNMP_V12_INFO_IDX * )realloc( snmp_info->v12_infos, snmp_info->glb_info.settings.num_v12_settings * sizeof( *snmp_info->v12_infos ) ); + if ( snmp_info->v12_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; ( i < snmp_info->glb_info.settings.num_v12_settings ) && mbg_rc_is_success( rc ) ; ++i ) + { + snmp_info->v12_infos[i].idx = i; + rc = mbgextio_get_snmp_v12_info_idx( pmctl, p_addr, &snmp_info->v12_infos[i], i ); + } + if ( mbg_rc_is_error( rc ) ) + goto out; + + snmp_info->v12_trap_infos = ( MBG_SNMP_V12_TRAP_INFO_IDX * )realloc( snmp_info->v12_trap_infos, snmp_info->glb_info.settings.num_v12_trap_receivers * sizeof( *snmp_info->v12_trap_infos ) ); + if ( snmp_info->v12_trap_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; ( i < snmp_info->glb_info.settings.num_v12_trap_receivers ) && mbg_rc_is_success( rc ) ; ++i ) + { + snmp_info->v12_trap_infos[i].idx = i; + rc = mbgextio_get_snmp_v12_trap_info_idx( pmctl, p_addr, &snmp_info->v12_trap_infos[i], i ); + } + if ( mbg_rc_is_error( rc ) ) + goto out; + + } + + if ( ( snmp_info->glb_info.supp_versions & MBG_SNMP_VERSION_MSK_V3 ) == MBG_SNMP_VERSION_MSK_V3 ) + { + snmp_info->v3_infos = ( MBG_SNMP_V3_INFO_IDX * )realloc( snmp_info->v3_infos, snmp_info->glb_info.settings.num_v3_settings * sizeof( *snmp_info->v3_infos ) ); + if ( snmp_info->v3_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; ( i < snmp_info->glb_info.settings.num_v3_settings ) && mbg_rc_is_success( rc ) ; ++i ) + { + snmp_info->v3_infos[i].idx = i; + rc = mbgextio_get_snmp_v3_info_idx( pmctl, p_addr, &snmp_info->v3_infos[i], i ); + } + if ( mbg_rc_is_error( rc ) ) + goto out; + + snmp_info->v3_trap_infos = ( MBG_SNMP_V3_TRAP_INFO_IDX * )realloc( snmp_info->v3_trap_infos, snmp_info->glb_info.settings.num_v3_trap_receivers * sizeof( *snmp_info->v3_trap_infos ) ); + if ( snmp_info->v3_trap_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; ( i < snmp_info->glb_info.settings.num_v3_trap_receivers ) && mbg_rc_is_success( rc ) ; ++i ) + { + snmp_info->v3_trap_infos[i].idx = i; + rc = mbgextio_get_snmp_v3_trap_info_idx( pmctl, p_addr, &snmp_info->v3_trap_infos[i], i ); + } + if ( mbg_rc_is_error( rc ) ) + goto out; + + } + +out: + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING_SNMP ); + + if ( mbg_rc_is_error( rc ) ) + { + free_all_snmp_info( snmp_info ); + snmp_info = NULL; + } + + *p = snmp_info; + + return rc; + +} // mbgextio_get_all_snmp_info + + + +/*HDR*/ +/** + * @brief Write all SNMP settings to a device + * + * The complementary function ::mbgextio_get_all_snmp_info should have been used + * to read the original SNMP settings and supported configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_SNMP_INFO structure with all SNMP parameters + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_snmp_info + * @see ::mbgextio_set_snmp_glb_settings + * @see ::mbgextio_set_snmp_v12_settings_idx + * @see ::mbgextio_set_snmp_v12_trap_settings_idx + * @see ::mbgextio_set_snmp_v3_settings_idx + * @see ::mbgextio_set_snmp_v3_trap_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_snmp_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_SNMP_INFO *p ) +{ + int rc; + int16_t i; + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING_SNMP, 1 ); + + rc = mbgextio_set_snmp_glb_settings( pmctl, p_addr, &p->glb_info.settings ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( ( ( p->glb_info.supp_versions & MBG_SNMP_VERSION_MSK_V1 ) == MBG_SNMP_VERSION_MSK_V1 ) || + ( ( p->glb_info.supp_versions & MBG_SNMP_VERSION_MSK_V2c ) == MBG_SNMP_VERSION_MSK_V2c ) ) + { + for ( i = 0; ( i < p->glb_info.settings.num_v12_settings ) && mbg_rc_is_success( rc ); ++i ) + rc = mbgextio_set_snmp_v12_settings_idx( pmctl, p_addr, &p->v12_infos[i].info.settings, i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + for ( i = 0; ( i < p->glb_info.settings.num_v12_trap_receivers ) && mbg_rc_is_success( rc ); ++i ) + rc = mbgextio_set_snmp_v12_trap_settings_idx( pmctl, p_addr, &p->v12_trap_infos[i].info.settings, i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + if ( ( p->glb_info.supp_versions & MBG_SNMP_VERSION_MSK_V3 ) == MBG_SNMP_VERSION_MSK_V3 ) + { + for ( i = 0; ( i < p->glb_info.settings.num_v3_settings ) && mbg_rc_is_success( rc ); ++i ) + rc = mbgextio_set_snmp_v3_settings_idx( pmctl, p_addr, &p->v3_infos[i].info.settings, i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + for ( i = 0; ( i < p->glb_info.settings.num_v3_trap_receivers ) && mbg_rc_is_success( rc ); ++i ) + rc = mbgextio_set_snmp_v3_trap_settings_idx( pmctl, p_addr, &p->v3_trap_infos[i].info.settings, i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + +out: + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_MONITORING_SNMP ); + + return rc; + +} // mbgextio_save_all_snmp_info + + + +/*HDR*/ +/** + * @brief Read all PTP configuration into an ::ALL_PTP_CFG_INFO structure + * + * @note ::mbgextio_dev_has_ptp should be called to check if this API is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a ::ALL_PTP_CFG_INFO structure to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ptp */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_cfg_info( MBG_MSG_CTL *pmctl, - XBP_ADDR *p_addr, +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_PTP_CFG_INFO *p ) { - int rc = mbgextio_get_ptp_cfg_info( pmctl, p_addr, &p->ptp_cfg_info ); + int rc; + + memset( p, 0, sizeof( *p ) ); + + // First check if the device supports PTP. + rc = mbgextio_dev_has_ptp( pmctl ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + - if ( rc != MBG_SUCCESS ) + // First get general PTP configuration information + rc = mbgextio_get_ptp_cfg_info( pmctl, p_addr, &p->ptp_cfg_info ); + + if ( mbg_rc_is_error( rc ) ) goto out; + + // PTP unicast may not be supported by all devices, so check if it is. if ( p->ptp_cfg_info.supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST ) { + // Read PTP parameters specific to unicast. rc = mbgextio_get_ptp_uc_master_cfg_limits( pmctl, p_addr, &p->ptp_uc_master_cfg_limits ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) goto out; + if ( p->ptp_uc_master_cfg_limits.n_supp_master > MAX_PARM_PTP_UC_MASTER ) { // The number of PTP unicast masters supported by this device - // exceeds the number of unicast masters supporterd by this driver. + // exceeds the number of unicast masters supported by this API, + // so the driver library needs to be updated. rc = MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP; goto out; } + // Read all PTP unicas master configuration. rc = mbgextio_get_all_ptp_uc_master_info( pmctl, p_addr, p->all_ptp_uc_master_info_idx, &p->ptp_uc_master_cfg_limits ); + } + +out: + return rc; + +} // mbgextio_get_all_ptp_cfg_info + + + +/*HDR*/ +/** + * @brief Write all PTP settings to a device + * + * The complementary function ::mbgextio_get_all_ptp_cfg_info should + * have been used to read the original PTP settings and supported + * configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_PTP_CFG_INFO structure with all ptp parameters + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_ptp_cfg_settings + * @see ::mbgextio_set_ptp_uc_master_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_ptp_cfg_info(MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_PTP_CFG_INFO *p ) +{ + int rc = mbgextio_set_ptp_cfg_settings( pmctl, p_addr, &p->ptp_cfg_info.settings ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( p->ptp_cfg_info.supp_flags & PTP_CFG_MSK_SUPPORT_PTP_UNICAST ) + { + int16_t i; + + for ( i = 0; i < p->ptp_uc_master_cfg_limits.n_supp_master && i < MAX_PARM_PTP_UC_MASTER; i++ ) + { + rc = mbgextio_set_ptp_uc_master_settings_idx( pmctl, p_addr, &p->all_ptp_uc_master_info_idx[i].info.settings, i ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + +out: + return rc; + +} // mbgextio_save_all_ptp_cfg_info + + + +/*HDR*/ +/** + * @brief Read all PTPv1 common datasets into a newly or re-allocated ::ALL_PTP_V1_COMMON_DATASETS structure + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * A number of ::MBG_PTP_V1_DEFAULT_DATASET::number_ports port datasets will be allocated. + * To free the allocated ::ALL_PTP_V1_COMMON_DATASETS, ::free_all_ptp_v1_common_datasets should be called. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer of ::ALL_PTP_V1_COMMON_DATASETS structure to be allocated and filled + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_default_dataset + * @see ::mbgextio_get_ptp_v1_current_dataset + * @see ::mbgextio_get_ptp_v1_parent_dataset + * @see ::mbgextio_get_ptp_v1_time_properties_dataset + * @see ::mbgextio_get_ptp_v1_port_dataset_idx + * @see ::free_all_ptp_v1_common_datasets + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_v1_common_datasets( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + ALL_PTP_V1_COMMON_DATASETS **p ) +{ + ALL_PTP_V1_COMMON_DATASETS *ptp_v1_common_datasets = *p; + int rc; + int16_t i; + + if ( ptp_v1_common_datasets == NULL ) + { + ptp_v1_common_datasets = (ALL_PTP_V1_COMMON_DATASETS *) calloc( 1, sizeof( *ptp_v1_common_datasets ) ); + if ( ptp_v1_common_datasets == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_ptp_v1_default_dataset( pmctl, p_addr, &ptp_v1_common_datasets->default_dataset ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + rc = mbgextio_get_ptp_v1_current_dataset( pmctl, p_addr, &ptp_v1_common_datasets->current_dataset ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + rc = mbgextio_get_ptp_v1_parent_dataset( pmctl, p_addr, &ptp_v1_common_datasets->parent_dataset ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + rc = mbgextio_get_ptp_v1_time_properties_dataset( pmctl, p_addr, &ptp_v1_common_datasets->time_properties_dataset ); + if ( mbg_rc_is_error( rc ) ) + goto out; - if ( rc != MBG_SUCCESS ) + if ( ptp_v1_common_datasets->default_dataset.number_ports > 0 ) + { + ptp_v1_common_datasets->port_datasets = ( MBG_PTP_V1_PORT_DATASET_IDX* )realloc( ptp_v1_common_datasets->port_datasets, ptp_v1_common_datasets->default_dataset.number_ports * sizeof( *ptp_v1_common_datasets->port_datasets ) ); + if ( ptp_v1_common_datasets->port_datasets == NULL ) + { + rc = MBG_ERR_NO_MEM; goto out; + } + + for ( i = 0; ( i < ptp_v1_common_datasets->default_dataset.number_ports ) && mbg_rc_is_success( rc ) ; ++i ) + { + ptp_v1_common_datasets->port_datasets[i].idx = i; + rc = mbgextio_get_ptp_v1_port_dataset_idx( pmctl, p_addr, &ptp_v1_common_datasets->port_datasets[i], i ); + } + } + else + { + if ( ptp_v1_common_datasets->port_datasets ) + free( ptp_v1_common_datasets->port_datasets ); + ptp_v1_common_datasets->port_datasets = NULL; } out: + if ( mbg_rc_is_error( rc ) ) + { + free_all_ptp_v1_common_datasets( ptp_v1_common_datasets ); + ptp_v1_common_datasets = NULL; + } + + *p = ptp_v1_common_datasets; + return rc; -} // mbgextio_get_all_ptp_cfg_info +} // mbgextio_get_ptp_v1_common_datasets + + + +/*HDR*/ +/** + * @brief Read all PTPv2 common datasets into a newly or re-allocated ::ALL_PTP_V2_COMMON_DATASETS structure + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * A number of ::MBG_PTP_V2_DEFAULT_DATASET::number_ports port datasets will be allocated. + * To free the allocated ::ALL_PTP_V2_COMMON_DATASETS, ::free_all_ptp_v2_common_datasets should be called. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer of ::ALL_PTP_V2_COMMON_DATASETS structure to be allocated and filled + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_default_dataset + * @see ::mbgextio_get_ptp_v2_current_dataset + * @see ::mbgextio_get_ptp_v2_parent_dataset + * @see ::mbgextio_get_ptp_v2_time_properties_dataset + * @see ::mbgextio_get_ptp_v2_port_dataset_idx + * @see ::free_all_ptp_v2_common_datasets + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_v2_common_datasets( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + ALL_PTP_V2_COMMON_DATASETS **p ) +{ + ALL_PTP_V2_COMMON_DATASETS *ptp_v2_common_datasets = *p; + int rc; + int16_t i; + + if ( ptp_v2_common_datasets == NULL ) + { + ptp_v2_common_datasets = (ALL_PTP_V2_COMMON_DATASETS *) calloc( 1, sizeof( *ptp_v2_common_datasets ) ); + if ( ptp_v2_common_datasets == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_ptp_v2_default_dataset( pmctl, p_addr, &ptp_v2_common_datasets->default_dataset ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + rc = mbgextio_get_ptp_v2_current_dataset( pmctl, p_addr, &ptp_v2_common_datasets->current_dataset ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + rc = mbgextio_get_ptp_v2_parent_dataset( pmctl, p_addr, &ptp_v2_common_datasets->parent_dataset ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + rc = mbgextio_get_ptp_v2_time_properties_dataset( pmctl, p_addr, &ptp_v2_common_datasets->time_properties_dataset ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( ptp_v2_common_datasets->default_dataset.number_ports > 0 ) + { + ptp_v2_common_datasets->port_datasets = ( MBG_PTP_V2_PORT_DATASET_IDX* )realloc( ptp_v2_common_datasets->port_datasets, ptp_v2_common_datasets->default_dataset.number_ports * sizeof( *ptp_v2_common_datasets->port_datasets ) ); + if ( ptp_v2_common_datasets->port_datasets == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; ( i < ptp_v2_common_datasets->default_dataset.number_ports ) && mbg_rc_is_success( rc ) ; ++i ) + { + ptp_v2_common_datasets->port_datasets[i].idx = i; + rc = mbgextio_get_ptp_v2_port_dataset_idx( pmctl, p_addr, &ptp_v2_common_datasets->port_datasets[i], i ); + } + } + else + { + if ( ptp_v2_common_datasets->port_datasets ) + free( ptp_v2_common_datasets->port_datasets ); + ptp_v2_common_datasets->port_datasets = NULL; + } + +out: + if ( mbg_rc_is_error( rc ) ) + { + free_all_ptp_v2_common_datasets( ptp_v2_common_datasets ); + ptp_v2_common_datasets = NULL; + } + + *p = ptp_v2_common_datasets; + + return rc; + +} // mbgextio_get_ptp_v2_common_datasets + + + +#if defined( _PRELIMINARY_CODE ) + +/*HDR*/ +/** + * @brief Read all NTP configuration into a newly or re-allocated ::ALL_NTP_CFG_INFO structure + * + * @note ::mbgextio_dev_has_ntp should be called to check if this API is supported. + * + * A ::ALL_NTP_CFG_INFO and ::NTP_SRV_MODE_INFO, ::NTP_CLNT_MODE_INFO and a number of + * ::NTP_CLNT_MODE_INFO::settings::num_peers of ::NTP_PEER_SETTINGS_IDX will be allocated and + * needs to be freed by calling ::free_all_ntp_cfg_info + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_NTP_CFG_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ntp + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ntp_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NTP_CFG_INFO **p ) +{ + ALL_NTP_CFG_INFO *ntp_cfg_info = *p; + int rc, i; + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_NTP, 0 ); + + if ( ntp_cfg_info == NULL ) + { + ntp_cfg_info = (ALL_NTP_CFG_INFO *) calloc( 1, sizeof( *ntp_cfg_info ) ); + if ( ntp_cfg_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + // read NTP_GLB_INFO + rc = mbgextio_get_ntp_glb_info( pmctl, p_addr, &ntp_cfg_info->glb_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + // read NTP_SYMM_KEY_LIMITS and NTP_SYMM_KEY_INFO_IDX + if ( ( ntp_cfg_info->glb_info.supp_flags & NTP_MSK_SYMM_KEYS ) == NTP_MSK_SYMM_KEYS ) + { + if ( ntp_cfg_info->symm_key_limits == NULL ) + { + ntp_cfg_info->symm_key_limits = (NTP_SYMM_KEY_LIMITS *) calloc( 1, sizeof( *ntp_cfg_info->symm_key_limits ) ); + if ( ntp_cfg_info->symm_key_limits == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_ntp_symm_key_limits( pmctl, p_addr, ntp_cfg_info->symm_key_limits ); + + if ( mbg_rc_is_error ( rc ) ) + goto out; + + if ( ntp_cfg_info->glb_info.settings.num_symm_keys > 0 ) + { + ntp_cfg_info->symm_key_info_idx = ( NTP_SYMM_KEY_INFO_IDX * )realloc( ntp_cfg_info->symm_key_info_idx, ntp_cfg_info->glb_info.settings.num_symm_keys * sizeof( *ntp_cfg_info->symm_key_info_idx ) ); + if ( ntp_cfg_info->symm_key_info_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; ( i < ntp_cfg_info->glb_info.settings.num_symm_keys ) && mbg_rc_is_success( rc ); ++i ) + { + ntp_cfg_info->symm_key_info_idx[i].idx = i; + rc = mbgextio_get_ntp_symm_key_info_idx( pmctl, p_addr, &ntp_cfg_info->symm_key_info_idx[i], i ); + } + + if ( mbg_rc_is_error ( rc ) ) + goto out; + } + else + { + if ( ntp_cfg_info->symm_key_info_idx != NULL ) + { + free( ntp_cfg_info->symm_key_info_idx ); + ntp_cfg_info->symm_key_info_idx = NULL; + } + } + } + + // read NTP_TRUSTED_KEY_INFO_IDX + if ( ( ntp_cfg_info->glb_info.supp_flags & NTP_MSK_TRUSTED_KEYS ) == NTP_MSK_TRUSTED_KEYS ) + { + if ( ntp_cfg_info->glb_info.settings.num_trusted_keys > 0 ) + { + ntp_cfg_info->trusted_key_info_idx = ( NTP_TRUSTED_KEY_INFO_IDX * )realloc( ntp_cfg_info->trusted_key_info_idx, ntp_cfg_info->glb_info.settings.num_trusted_keys * sizeof( *ntp_cfg_info->trusted_key_info_idx ) ); + if ( ntp_cfg_info->trusted_key_info_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; ( i < ntp_cfg_info->glb_info.settings.num_trusted_keys ) && mbg_rc_is_success( rc ); ++i ) + { + ntp_cfg_info->trusted_key_info_idx[i].idx = i; + rc = mbgextio_get_ntp_trusted_key_info_idx( pmctl, p_addr, &ntp_cfg_info->trusted_key_info_idx[i], i ); + } + + if ( mbg_rc_is_error ( rc ) ) + goto out; + } + else + { + if ( ntp_cfg_info->trusted_key_info_idx != NULL ) + { + free( ntp_cfg_info->trusted_key_info_idx ); + ntp_cfg_info->trusted_key_info_idx = NULL; + } + } + } + + // read NTP_CLNT_MODE_INFO and NTP_PEER_SETTINGS_IDX + if ( ( ( ntp_cfg_info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT ) == NTP_MSK_ROLE_CLIENT ) || + ( ( ntp_cfg_info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT_SERVER ) == NTP_MSK_ROLE_CLIENT_SERVER ) ) + { + if ( ntp_cfg_info->clnt_info == NULL ) + { + ntp_cfg_info->clnt_info = (NTP_CLNT_MODE_INFO *) calloc( 1, sizeof( *ntp_cfg_info->clnt_info ) ); + if ( ntp_cfg_info->clnt_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_ntp_clnt_mode_info( pmctl, p_addr, ntp_cfg_info->clnt_info ); + + if ( mbg_rc_is_error ( rc ) ) + goto out; + + if ( ntp_cfg_info->clnt_info->settings.num_peers > 0 ) + { + ntp_cfg_info->peer_settings_idx = ( NTP_PEER_SETTINGS_IDX * )realloc( ntp_cfg_info->peer_settings_idx, ntp_cfg_info->clnt_info->settings.num_peers * sizeof( *ntp_cfg_info->peer_settings_idx ) ); + if ( ntp_cfg_info->peer_settings_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; ( i < ntp_cfg_info->clnt_info->settings.num_peers ) && mbg_rc_is_success( rc ); ++i ) + { + ntp_cfg_info->peer_settings_idx[i].idx = i; + rc = mbgextio_get_ntp_peer_settings_idx( pmctl, p_addr, &ntp_cfg_info->peer_settings_idx[i], i ); + } + + if ( mbg_rc_is_error ( rc ) ) + goto out; + } + else + { + if ( ntp_cfg_info->peer_settings_idx != NULL ) + { + free( ntp_cfg_info->peer_settings_idx ); + ntp_cfg_info->peer_settings_idx = NULL; + } + } + } + + // read NTP_SRV_MODE_INFO and NTP_REFCLK_CFG_INFO_IDX + if ( ( ( ntp_cfg_info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_SERVER ) == NTP_MSK_ROLE_SERVER ) || + ( ( ntp_cfg_info->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT_SERVER ) == NTP_MSK_ROLE_CLIENT_SERVER ) ) + { + if ( ntp_cfg_info->srv_info == NULL ) + { + ntp_cfg_info->srv_info = (NTP_SRV_MODE_INFO *) calloc( 1, sizeof( *ntp_cfg_info->srv_info ) ); + if ( ntp_cfg_info->srv_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_ntp_srv_mode_info( pmctl, p_addr, ntp_cfg_info->srv_info ); + + if ( mbg_rc_is_error ( rc ) ) + goto out; + + if ( ntp_cfg_info->srv_info->settings.num_refclks > 0 ) + { + ntp_cfg_info->refclk_info_idx = ( NTP_REFCLK_CFG_INFO_IDX * )realloc( ntp_cfg_info->refclk_info_idx, ntp_cfg_info->srv_info->settings.num_refclks * sizeof( *ntp_cfg_info->refclk_info_idx ) ); + if ( ntp_cfg_info->refclk_info_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; ( i < ntp_cfg_info->srv_info->settings.num_refclks ) && mbg_rc_is_success( rc ); ++i ) + { + ntp_cfg_info->refclk_info_idx[i].idx = i; + rc = mbgextio_get_ntp_refclk_cfg_info_idx( pmctl, p_addr, &ntp_cfg_info->refclk_info_idx[i], i ); + } + + if ( mbg_rc_is_error ( rc ) ) + goto out; + } + else + { + if ( ntp_cfg_info->refclk_info_idx != NULL ) + { + free( ntp_cfg_info->refclk_info_idx ); + ntp_cfg_info->refclk_info_idx = NULL; + } + } + } + + // read NTP_MISC_LIMITS + if ( ( ntp_cfg_info->glb_info.supp_flags & NTP_MSK_MISCELLANEOUS ) == NTP_MSK_MISCELLANEOUS ) + { + if ( ntp_cfg_info->misc_limits == NULL ) + { + ntp_cfg_info->misc_limits = (NTP_MISC_LIMITS *) calloc( 1, sizeof( *ntp_cfg_info->misc_limits ) ); + if ( ntp_cfg_info->misc_limits == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_ntp_misc_limits( pmctl, p_addr, ntp_cfg_info->misc_limits ); + + if ( mbg_rc_is_error ( rc ) ) + goto out; + + // read NTP_MISC_ORPHAN_MODE_INFO + if ( ( ntp_cfg_info->misc_limits->supp_flags & NTP_MISC_MSK_ORPHAN_MODE ) == NTP_MISC_MSK_ORPHAN_MODE ) + { + if ( ntp_cfg_info->orphan_mode_info == NULL ) + { + ntp_cfg_info->orphan_mode_info = (NTP_MISC_ORPHAN_MODE_INFO *) calloc( 1, sizeof( *ntp_cfg_info->orphan_mode_info ) ); + if ( ntp_cfg_info->orphan_mode_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_ntp_misc_orphan_mode_info( pmctl, p_addr, ntp_cfg_info->orphan_mode_info ); + } + } + +out: + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_NTP ); + + if ( mbg_rc_is_error( rc ) ) + { + free_all_ntp_cfg_info( ntp_cfg_info ); + ntp_cfg_info = NULL; + } + + *p = ntp_cfg_info; + + return rc; + +} // mbgextio_get_all_ntp_cfg_info + +#endif // defined( _PRELIMINARY_CODE ) + + + +#if defined( _PRELIMINARY_CODE ) + +/*HDR*/ +/** + * @brief Write all NTP settings to a device + * + * The complementary function ::mbgextio_get_all_ntp_cfg_info should + * have been used to read the original NTP settings and supported + * configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_NTP_CFG_INFO structure with all ntp parameters + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_ptp_cfg_settings + * @see ::mbgextio_set_ptp_uc_master_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_ntp_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NTP_CFG_INFO *p ) +{ + int rc, i; + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_NTP, 1 ); + + // set NTP_GLB_SETTINGS + rc = mbgextio_set_ntp_glb_info( pmctl, p_addr, &p->glb_info.settings ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + // set NTP_SYMM_KEY_SETTINGS_IDX + if ( ( p->glb_info.supp_flags & NTP_MSK_SYMM_KEYS ) == NTP_MSK_SYMM_KEYS ) + { + for ( i = 0; ( i < p->glb_info.settings.num_symm_keys ) && mbg_rc_is_success( rc ); ++i ) + rc = mbgextio_set_ntp_symm_key_settings_idx( pmctl, p_addr, &p->symm_key_info_idx[i].info.settings, i ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + // set NTP_TRUSTED_KEY_SETTINGS_IDX + if ( ( p->glb_info.supp_flags & NTP_MSK_TRUSTED_KEYS ) == NTP_MSK_TRUSTED_KEYS ) + { + for ( i = 0; ( i < p->glb_info.settings.num_trusted_keys ) && mbg_rc_is_success( rc ); ++i ) + rc = mbgextio_set_ntp_trusted_key_settings_idx( pmctl, p_addr, &p->trusted_key_info_idx[i].info.settings, i ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + // set NTP_CLNT_MODE_SETTINGS and NTP_PEER_SETTINGS + if ( ( ( p->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT ) == NTP_MSK_ROLE_CLIENT ) || + ( ( p->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT_SERVER ) == NTP_MSK_ROLE_CLIENT_SERVER ) ) + { + NTP_PEER_SETTINGS_IDX peer_settings_idx; + + rc = mbgextio_set_ntp_clnt_mode_cfg( pmctl, p_addr, &p->clnt_info->settings ); + + for ( i = 0; ( i < p->clnt_info->settings.num_peers ) && mbg_rc_is_success( rc ); ++i ) + rc = mbgextio_set_ntp_peer_settings_idx( pmctl, p_addr, &p->peer_settings_idx[i].peer_settings, i ); + + if(mbg_rc_is_error(rc)) + goto out; + + // this is for compatibility with older Syncbox N2x versions + memset(&peer_settings_idx, 0, sizeof(peer_settings_idx)); + for ( i = p->clnt_info->settings.num_peers; ( i < p->clnt_info->n_supp_peers ) && mbg_rc_is_success( rc ); ++i ) + { + peer_settings_idx.idx = i; + rc = mbgextio_set_ntp_peer_settings_idx( pmctl, p_addr, &peer_settings_idx.peer_settings, i ); + } + rc = MBG_SUCCESS; + } + + // set NTP_SRV_MODE_SETTINGS and NTP_REFCLK_CFG_SETTINGS + if ( ( ( p->glb_info.supp_ntp_roles & NTP_MSK_ROLE_SERVER ) == NTP_MSK_ROLE_SERVER ) || + ( ( p->glb_info.supp_ntp_roles & NTP_MSK_ROLE_CLIENT_SERVER ) == NTP_MSK_ROLE_CLIENT_SERVER ) ) + { + rc = mbgextio_set_ntp_srv_mode_cfg( pmctl, p_addr, &p->srv_info->settings ); + + if ( ( p->glb_info.supp_flags & NTP_MSK_FIXED_REFCLOCKS) != NTP_MSK_FIXED_REFCLOCKS ) + { + for ( i = 0; ( i < p->srv_info->settings.num_refclks ) && mbg_rc_is_success( rc ); ++i ) + rc = mbgextio_set_ntp_refclk_cfg_settings_idx( pmctl, p_addr, &p->refclk_info_idx[i].info.settings, i ); + } + + if(mbg_rc_is_error(rc)) + goto out; + } + + if ( ( p->glb_info.supp_flags & NTP_MSK_MISCELLANEOUS ) == NTP_MSK_MISCELLANEOUS ) + { + // set NTP_MISC_ORPHAN_MODE_SETTINGS + if ( ( p->misc_limits->supp_flags & NTP_MISC_MSK_ORPHAN_MODE ) == NTP_MISC_MSK_ORPHAN_MODE ) + rc = mbgextio_set_ntp_misc_orphan_mode_settings( pmctl, p_addr, &p->orphan_mode_info->settings ); + } + +out: + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_NTP ); + + return rc; + +} // mbgextio_save_all_ntp_cfg_info + +#endif // defined( _PRELIMINARY_CODE ) + + + +#if defined( _PRELIMINARY_CODE ) + +/*HDR*/ +/** + * @brief Read all NTP status info into a newly or re-allocated ::ALL_NTP_STATUS structure + * + * @note ::mbgextio_dev_has_ntp should be called to check if this API is supported. + * + * A ::ALL_NTP_STATUS and ::NTP_SRV_MODE_INFO, ::NTP_CLNT_MODE_INFO and a number of + * ::NTP_CLNT_MODE_INFO::settings::num_peers of ::NTP_PEER_STATE_IDX will be allocated and + * needs to be freed by calling ::free_all_ntp_status + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to the appropriate info structure + * @param[out] p Pointer to a pointer to ::ALL_NTP_STATUS + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ntp + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ntp_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_NTP_CFG_INFO *info, ALL_NTP_STATUS **p ) +{ + ALL_NTP_STATUS *ntp_status = *p; + int rc, i; + + if ( info == NULL ) + return MBG_ERR_INV_PARM; + + if ( ntp_status == NULL ) + { + ntp_status = (ALL_NTP_STATUS *) calloc( 1, sizeof( *ntp_status ) ); + if ( ntp_status == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_ntp_sys_state( pmctl, p_addr, &ntp_status->sys_state ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( mbg_rc_is_success( chk_dev_ntp_supp_client( info ) ) ) + { + if ( mbg_rc_is_error ( rc ) ) + goto out; + + if ( ntp_status->peer_states == NULL ) + { + ntp_status->peer_states = (NTP_PEER_STATE_IDX *) calloc(info->clnt_info->settings.num_peers, sizeof( *ntp_status->peer_states ) ); + if ( ntp_status->peer_states == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + for ( i = 0; i < info->clnt_info->settings.num_peers; ++i ) + { + ntp_status->peer_states[i].idx = i; + rc = mbgextio_get_ntp_peer_state_idx( pmctl, p_addr, &ntp_status->peer_states[i], i ); + } + } + + if ( mbg_rc_is_success( chk_dev_ntp_supp_server(info) ) ) + { + // TODO: At this point, server status has to bread as soon as its implemented + } + +out: + if ( mbg_rc_is_error( rc ) ) + { + free_all_ntp_status( ntp_status ); + ntp_status = NULL; + } + + *p = ntp_status; + + return rc; + +} // mbgextio_get_all_ntp_status + +#endif // defined( _PRELIMINARY_CODE ) + + + +/*HDR*/ +/** + * @brief Read all XMR info into a newly or re-allocated ::ALL_XMULTI_REF_INFO + * + * @note ::mbgextio_dev_has_xmulti_ref should be called before using this function + * + * A ::ALL_XMULTI_REF_INFO and a number of ::XMULTI_REF_INSTANCES::n_xmr_settings + * of ::XMULTI_REF_INFO_IDX and ::XMR_EXT_SRC_INFO_IDX will be allocated and needs + * to be freed by calling ::free_all_xmulti_ref_info + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer of ::ALL_XMULTI_REF_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::free_all_xmulti_ref_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_xmulti_ref_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_XMULTI_REF_INFO **p ) +{ + ALL_XMULTI_REF_INFO *xmr_info = *p; + int rc; + int16_t i; + + if ( xmr_info == NULL ) + { + xmr_info = (ALL_XMULTI_REF_INFO *) calloc( 1, sizeof( *xmr_info ) ); + if ( xmr_info == NULL ) + return MBG_ERR_NO_MEM; + } + + // First, get the XMULTI_REF_INSTANCES to check how many sources are supported + rc = mbgextio_get_xmr_instances( pmctl, p_addr, &xmr_info->instances ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( xmr_info->infos == NULL ) + { + xmr_info->infos = (XMULTI_REF_INFO_IDX *) calloc( xmr_info->instances.n_xmr_settings, sizeof( *xmr_info->infos ) ); + + if ( xmr_info->infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + for ( i = 0; i < xmr_info->instances.n_xmr_settings; i++ ) + { + xmr_info->infos[i].idx = i; + rc = mbgextio_get_xmr_info_idx( pmctl, p_addr, &xmr_info->infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + if ( mbg_rc_is_success( chk_dev_xmulti_ref_supp_ext_src_info( xmr_info ) ) ) + { + if ( xmr_info->ext_src_infos == NULL ) + { + xmr_info->ext_src_infos = (XMR_EXT_SRC_INFO_IDX *) calloc( N_MULTI_REF, sizeof( *xmr_info->ext_src_infos ) ); + + if ( xmr_info->ext_src_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + for ( i = 0; i < N_MULTI_REF; i++ ) + { + xmr_info->ext_src_infos[i].idx = i; + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XMR_EXT_SRC_INFO_IDX, i, &xmr_info->ext_src_infos[i], sizeof( xmr_info->ext_src_infos[i] ) ); + if ( ( mbg_rc_is_error( rc ) ) ) + goto out; + } + } + +out: + if ( mbg_rc_is_error( rc ) ) + { + free_all_xmulti_ref_info( xmr_info ); + xmr_info = NULL; + } + + *p = xmr_info; + + return rc; + +} // mbgextio_get_all_xmulti_ref_info + + +/*HDR*/ +/** + * @brief Set all extended multi ref settings to a device + * + * The complementary function ::mbgextio_get_all_xmulti_ref_info should + * have been used to read the original extended multi ref settings. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_XMULTI_REF_INFO structure with all settings + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_xmr_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_xmulti_ref_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_XMULTI_REF_INFO *p ) +{ + int rc = MBG_SUCCESS; + int16_t i; + + for (i = 0; ( i < p->instances.n_xmr_settings ) && mbg_rc_is_success( rc ); i++ ) + rc = mbgextio_set_xmr_settings_idx( pmctl, p_addr, &p->infos[i].info.settings, i ); + + // if all settings have been successully set, send dummy structure with index -1 to apply settings + if( mbg_rc_is_success( rc ) ) + { + XMULTI_REF_SETTINGS dummy_settings; + memset( &dummy_settings, 0, sizeof( dummy_settings ) ); + dummy_settings.id.type = MULTI_REF_NONE; + rc = mbgextio_set_xmr_settings_idx( pmctl, p_addr, &dummy_settings, -1 ); + } + + return rc; + +} // mbgextio_save_all_xmulti_ref_info + + +/*HDR*/ +/** + * @brief Read all XMR status info into a newly or re-allocated ::ALL_XMULTI_REF_STATUS + * + * @note ::mbgextio_dev_has_xmulti_ref should be called before using this function + * + * A ::ALL_XMULTI_REF_STATUS and a number of ::XMULTI_REF_INSTANCES::n_xmr_settings + * of ::XMULTI_REF_STATUS_IDX will be allocated and needs to be freed by calling + * ::free_all_xmulti_ref_status + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to an ::ALL_XMULTI_REF_INFO list which has been read before + * @param[out] p Pointer to a pointer of ::ALL_XMULTI_REF_STATUS + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::free_all_xmulti_ref_status + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_xmulti_ref_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_XMULTI_REF_INFO* info, ALL_XMULTI_REF_STATUS **p ) +{ + ALL_XMULTI_REF_STATUS *xmr_status = *p; + int rc = MBG_SUCCESS; + int16_t i; + + if ( info == NULL ) + return MBG_ERR_INV_PARM; + + if ( xmr_status == NULL ) + { + xmr_status = (ALL_XMULTI_REF_STATUS *) calloc( 1, sizeof( *xmr_status ) ); + if ( xmr_status == NULL ) + return MBG_ERR_NO_MEM; + } + + if ( xmr_status->status == NULL ) + { + xmr_status->status = (XMULTI_REF_STATUS_IDX *) calloc( info->instances.n_xmr_settings, sizeof( *xmr_status->status ) ); + + if ( xmr_status->status == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + for ( i = 0; i < info->instances.n_xmr_settings; i++ ) + { + xmr_status->status[i].idx = i; + rc = mbgextio_get_xmr_status_idx( pmctl, p_addr, &xmr_status->status[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + if ( mbg_rc_is_success( chk_dev_xmulti_ref_supp_holdover_status( info ) ) ) + { + if ( xmr_status->holdover_status == NULL ) + { + xmr_status->holdover_status = (XMR_HOLDOVER_STATUS *) calloc( 1, sizeof( *xmr_status->holdover_status ) ); + + if ( xmr_status->holdover_status == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_xmr_holdover_status(pmctl, p_addr, xmr_status->holdover_status); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + if ( mbg_rc_is_success( chk_dev_xmulti_ref_supp_ext_src_info( info ) ) ) + { + uint8_t type; + + if ( xmr_status->stats_idx == NULL ) + { + xmr_status->stats_idx = (XMR_STATS_IDX *) calloc( info->instances.n_xmr_settings, sizeof( *xmr_status->stats_idx ) ); + + if ( xmr_status->stats_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + xmr_status->has_stats = 0; + + for ( i = 0; i < info->instances.n_xmr_settings; ++i ) + { + type = info->infos[i].info.settings.id.type; + + /* We only malloced N_MULTI_REF ext source info idxs... */ + if ( mbg_rc_is_success( chk_dev_xmulti_ref_supp_ext_source_stats( info, type ) ) ) + { + rc = mbgextio_get_xmr_ext_source_stats_idx( pmctl, p_addr, &xmr_status->stats_idx[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + xmr_status->has_stats = 1; + } + + if ( xmr_status->metrics_idx == NULL ) + { + xmr_status->metrics_idx = (XMR_METRICS_IDX *) calloc( info->instances.n_xmr_settings, sizeof( *xmr_status->metrics_idx ) ); + + if ( xmr_status->metrics_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + xmr_status->has_metrics = 0; + + for ( i = 0; i < info->instances.n_xmr_settings; ++i ) + { + type = info->infos[i].info.settings.id.type; + + /* We only malloced N_MULTI_REF ext source info idxs... */ + if ( mbg_rc_is_success( chk_dev_xmulti_ref_supp_ext_source_metrics( info, type ) ) ) + { + rc = mbgextio_get_xmr_ext_source_metrics_idx( pmctl, p_addr, &xmr_status->metrics_idx[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + xmr_status->has_metrics = 1; + } + } + + } + +out: + if ( mbg_rc_is_error( rc ) ) + { + free_all_xmulti_ref_status( xmr_status ); + xmr_status = NULL; + } + + *p = xmr_status; + + return rc; + +} // mbgextio_get_all_xmulti_ref_status + + + +#if defined( _PRELIMINARY_CODE ) + +/*HDR*/ +/** + * @brief Read all IMS related information / configuration into an ::ALL_IMS_INFO structure + * + * @note ::mbgextio_dev_has_ims should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in,out] pp Pointer to a pointer of ::ALL_IMS_INFO structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ims + * @see ::mbgextio_dev_ims_has_fdm + * @see ::free_all_ims_info + * @see ::mbgextio_get_all_ims_state + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ims_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_IMS_INFO **pp ) +{ + int rc; + uint16_t i; + ALL_IMS_INFO *p = *pp; + + if ( p == NULL ) + { + p = (ALL_IMS_INFO *) calloc( 1, sizeof( *p ) ); + if ( p == NULL ) + return MBG_ERR_NO_MEM; + } + + rc = mbgextio_get_ims_state(pmctl, p_addr, &p->state); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + + if ( mbg_rc_is_error( chk_dev_ims_has_fdm( p ) ) ) + goto success_out; + + if ( p->fdm_info == NULL ) + { + p->fdm_info = (MBG_IMS_FDM_INFO *) calloc( 1, sizeof( *p->fdm_info ) ); + if ( p->fdm_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto err_out; + } + } + + rc = mbgextio_get_ims_fdm_info(pmctl, p_addr, p->fdm_info); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + + + if ( p->fdm_limits == NULL ) + { + p->fdm_limits = (MBG_IMS_FDM_LIMITS *) calloc( 1, sizeof( *p->fdm_limits ) ); + if ( p->fdm_limits == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto err_out; + } + } + + rc = mbgextio_get_ims_fdm_limits(pmctl, p_addr, p->fdm_limits); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + + + if ( p->fdm_outinfo_idx == NULL ) + { + p->fdm_outinfo_idx = (MBG_IMS_FDM_OUTPUT_INFO_IDX *) calloc( p->fdm_limits->n_outputs, sizeof( *p->fdm_outinfo_idx ) ); + if ( p->fdm_outinfo_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto err_out; + } + } + + for ( i = 0; i < p->fdm_limits->n_outputs; ++i ) + { + rc = mbgextio_get_ims_fdm_output_info_idx( pmctl, p_addr, &p->fdm_outinfo_idx[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + } + +success_out: + + *pp = p; + + return MBG_SUCCESS; + +err_out: + free_all_ims_info( p ); + + *pp = NULL; + + return rc; + +} // mbgextio_get_all_ims_info + + + +/*HDR*/ +/** + * @brief Read all IMS related states into an ::ALL_IMS_STATE structure + * + * @note ::mbgextio_dev_has_ims should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to a ::ALL_GPIO_INFO structure which has been read before + * @param[in,out] pp Pointer to a pointer of ::ALL_IMS_STATE structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ims + * @see ::chk_dev_ims_has_fdm + * @see ::free_all_ims_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ims_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_IMS_INFO *info, ALL_IMS_STATE **pp ) +{ + int rc; + uint16_t i; + ALL_IMS_STATE *p = *pp; + + if ( info == NULL ) + return MBG_ERR_INV_PARM; + + if ( p == NULL ) + { + p = (ALL_IMS_STATE *) calloc( 1, sizeof( *p ) ); + if ( p == NULL ) + return MBG_ERR_NO_MEM; + } + + if ( p->sensor_state_idx == NULL ) + { + p->sensor_state_idx = (MBG_IMS_SENSOR_STATE_IDX *) calloc( info->state.num_sensors, sizeof( *p->sensor_state_idx ) ); + if ( p->sensor_state_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto err_out; + } + } + + for ( i = 0; i < info->state.num_sensors; ++i ) + { + rc = mbgextio_get_ims_sensor_state_idx( pmctl, p_addr, &p->sensor_state_idx[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + } + + + if ( mbg_rc_is_error( chk_dev_ims_has_fdm( info ) ) ) + goto success_out; + + + if ( p->fdm_state == NULL ) + { + p->fdm_state = (MBG_IMS_FDM_STATE *) calloc( 1, sizeof( *p->fdm_state ) ); + if ( p->fdm_state == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto err_out; + } + } + + rc = mbgextio_get_ims_fdm_state( pmctl, p_addr, p->fdm_state ); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + + + if ( p->fdm_output_state_idx == NULL ) + { + p->fdm_output_state_idx = (MBG_IMS_FDM_OUTPUT_STATE_IDX *) calloc( info->fdm_limits->n_outputs, sizeof( *p->fdm_output_state_idx ) ); + if ( p->fdm_output_state_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto err_out; + } + } + + for ( i = 0; i < info->fdm_limits->n_outputs; ++i ) + { + rc = mbgextio_get_ims_fdm_output_state_idx( pmctl, p_addr, &p->fdm_output_state_idx[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + } + + +success_out: + + *pp = p; + + return MBG_SUCCESS; + +err_out: + + free_all_ims_state( p ); + + *pp = NULL; + + return rc; + +} // mbgextio_get_all_ims_state + +#endif // defined( _PRELIMINARY_CODE ) + + +/*HDR*/ +/** + * @brief Read all GPIO related information / configuration into an ::ALL_GPIO_INFO structure + * + * @note ::mbgextio_dev_has_gpio should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in,out] pp Pointer to a pointer of ::ALL_GPIO_INFO structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::chk_dev_gpio_has_status + * @see ::free_all_gpio_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gpio_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_GPIO_INFO **pp ) +{ + int rc; + uint16_t i; + ALL_GPIO_INFO *p = *pp; + + if ( p == NULL ) + { + p = (ALL_GPIO_INFO *) calloc( 1, sizeof( *p ) ); + if ( p == NULL ) + return MBG_ERR_NO_MEM; + } + + rc = mbgextio_req_data(pmctl, p_addr, GPS_GPIO_CFG_LIMITS, &p->cfg_limits, sizeof( p->cfg_limits ) ); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + _mbg_swab_mbg_gpio_cfg_limits( &p->cfg_limits ); + + if ( p->infos == NULL ) + { + p->infos = (MBG_GPIO_INFO_IDX *) calloc( p->cfg_limits.num_io, sizeof( *p->infos ) ); + if ( p == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto err_out; + } + } + + for ( i = 0; i < p->cfg_limits.num_io; ++i ) + { + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_GPIO_INFO_IDX, i, &p->infos[i], sizeof( *p->infos ) ); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + _mbg_swab_mbg_gpio_info_idx( &p->infos[i], 1 ); + } + + *pp = p; + + return MBG_SUCCESS; + +err_out: + free_all_gpio_info( p ); + + *pp = NULL; + + return rc; +} + + + +/*HDR*/ +/** + * @brief Read all GPIO related state information to an ::ALL_GPIO_STATE structure + * + * @note ::mbgextio_dev_has_gpio should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to a ::ALL_GPIO_INFO structure which has been read before + * @param[in,out] pp Pointer to a pointer of ::ALL_GPIO_STATE structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::chk_dev_gpio_has_status + * @see ::free_all_gpio_info + * @see ::free_all_gpio_state + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gpio_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_GPIO_INFO *info, ALL_GPIO_STATE **pp ) +{ + int rc; + uint16_t i; + ALL_GPIO_STATE *p = *pp; + + if ( info == NULL ) + return MBG_ERR_INV_PARM; + + rc = chk_dev_gpio_has_status( info ); + if ( mbg_rc_is_error( rc ) ) + return rc; + + if ( p == NULL ) + { + p = (ALL_GPIO_STATE *) calloc( 1, sizeof( *p ) ); + if ( p == NULL ) + return MBG_ERR_NO_MEM; + } + + if ( p->states == NULL ) + { + p->states = (MBG_GPIO_STATUS_IDX *) calloc( info->cfg_limits.num_io, sizeof( *p->states ) ); + if ( p == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto err_out; + } + } + + for ( i = 0; i < info->cfg_limits.num_io; ++i ) + { + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_GPIO_STATUS_IDX, i, &p->states[i], sizeof( *p->states ) ); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + _mbg_swab_mbg_gpio_status_idx( &p->states[i] ); + } + + *pp = p; + + return MBG_SUCCESS; + +err_out: + free_all_gpio_state( p ); + + *pp = NULL; + + return rc; + +} // mbgextio_get_all_gpio_state + + +/*HDR*/ +/** + * @brief Read all I/O port related information to an ::ALL_IO_PORT_INFO structure + + * + * @note ::mbgextio_dev_has_io_ports should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in,out] pp Pointer to a pointer of ::ALL_IO_PORT_INFO structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_io_ports + * @see ::free_all_io_port_info + * @see ::free_all_io_port_state + * @see ::mbgextio_get_all_io_port_status + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_io_port_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_IO_PORT_INFO **pp ) +{ + int rc; + uint8_t i, k; + ALL_IO_PORT_INFO *p = *pp; + MBG_IO_PORT_TYPE_INFO_IDX *pti_idx; + + if ( p == NULL ) + { + p = (ALL_IO_PORT_INFO *) calloc( 1, sizeof( *p ) ); + if ( p == NULL ) + return MBG_ERR_NO_MEM; + } + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_IO_PORT, 0 ); + + rc = mbgextio_get_io_port_limits( pmctl, p_addr, &p->limits ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( p->p_infos == NULL ) + { + p->p_infos = (MBG_IO_PORT_INFO_IDX *) calloc( p->limits.num_ports, sizeof( *p->p_infos ) ); + if ( p->p_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + if ( p->pt_infos == NULL ) + { + p->pt_infos = ( MBG_IO_PORT_TYPE_INFO_IDX **) calloc( p->limits.num_ports, sizeof( p->pt_infos ) ); + if ( p->pt_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + for ( i = 0; i < p->limits.num_ports; ++i ) + { + rc = mbgextio_get_io_port_info_idx( pmctl, p_addr, &p->p_infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( p->pt_infos[i] == NULL ) + { + pti_idx = (MBG_IO_PORT_TYPE_INFO_IDX *) calloc( p->p_infos[i].info.num_types, sizeof( *pti_idx ) ); + if ( pti_idx == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + p->pt_infos[i] = pti_idx; + } + else + { + pti_idx = p->pt_infos[i]; + } + + for ( k = 0; k < p->p_infos[i].info.num_types; ++k ) + { + rc = mbgextio_get_io_port_type_info_idx( pmctl, p_addr, &pti_idx[k], i ,k ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + +out: + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_IO_PORT ); + + if( mbg_rc_is_error( rc ) ) + { + free_all_io_port_info( p ); + p = NULL; + } + + *pp = p; + + return rc; + +} // mbgextio_get_all_io_port_info + + + +/*HDR*/ +/** + * @brief Write all I/O port related configuration to a device + * + * The complementary function ::mbgextio_get_all_io_port_info should + * have been used to read the original I/O port settings and supported + * configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_IO_PORT_INFO structure with all I/O port settings + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_io_port_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_io_port_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_IO_PORT_INFO *p ) +{ + int rc = MBG_SUCCESS; + uint8_t i; + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_IO_PORT, 1 ); + + for ( i = 0; ( i < p->limits.num_ports ) && mbg_rc_is_success( rc ); ++i ) + { + if(p->p_infos[i].info.settings.type != (uint16_t)MBG_IO_PORT_TYPE_NONE) + rc = mbgextio_set_io_port_settings_idx( pmctl, p_addr, &p->p_infos[i].info.settings, i ); + } + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_IO_PORT ); + + return rc; + +} + + + +/*HDR*/ +/** + * @brief Read all I/O port related status information to an ::ALL_IO_PORT_STATUS structure + * + * @note ::mbgextio_dev_has_io_ports should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to ::ALL_IO_PORT_INFO + * @param[in,out] pp Pointer to a pointer of ::ALL_IO_PORT_STATUS structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_io_ports + * @see ::free_all_io_port_info + * @see ::free_all_io_port_state + * @see ::mbgextio_get_all_io_port_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_io_port_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_IO_PORT_INFO *info, ALL_IO_PORT_STATUS **pp ) +{ + ALL_IO_PORT_STATUS *p = *pp; + int rc = MBG_SUCCESS; + uint8_t i; + + if ( p == NULL ) + { + p = (ALL_IO_PORT_STATUS *) calloc( 1, sizeof( *p ) ); + if ( p == NULL ) + return MBG_ERR_NO_MEM; + } + + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_begin_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_IO_PORT, 0 ); + + if ( p->status == NULL ) + { + p->status = (MBG_IO_PORT_STATUS_IDX *) calloc( info->limits.num_ports, sizeof( *p->status ) ); + if ( p->status == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + for ( i = 0; i < info->limits.num_ports; ++i ) + { + rc = mbgextio_get_io_port_status_idx( pmctl, p_addr, &p->status[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + +out: + if ( mbg_rc_is_success( mbgextio_dev_has_transactions( pmctl ) ) ) + mbgextio_end_transaction( pmctl, p_addr, MBG_TRANSACTION_TYPE_IO_PORT ); + + if ( mbg_rc_is_error( rc ) ) + { + free_all_io_port_status( p ); + p = NULL; + } + + *pp = p; + + return rc; +} + + +/*HDR*/ +/** + * @brief Read all user capture information and store it into a newly allocated or reused ::ALL_UCAP_INFO + * + * @note ::mbgextio_dev_has_ucap should be called to check if this API is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_UCAP_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap + * @see ::free_all_ucap_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ucap_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_UCAP_INFO **p ) +{ + int rc; + ALL_UCAP_INFO *ucap_info = *p; + UCAP_ENTRY *new_entry, *old_entry; + + // if this function is called for the first time, allocate a new ::ALL_UCAP_INFO structure + if ( ucap_info == NULL ) + { + ucap_info = (ALL_UCAP_INFO *) calloc( 1, sizeof( *ucap_info ) ); + if ( ucap_info == NULL ) + { + *p = NULL; + return MBG_ERR_NO_MEM; + } + mbg_klist_init(&ucap_info->list); + } + + do + { + new_entry = calloc_ucap_entry(); + if ( !new_entry ) + { + rc = MBG_ERR_NO_MEM; + goto err_out; + } + + rc = mbgextio_get_ucap( pmctl, p_addr, &new_entry->ttm ); + if ( mbg_rc_is_error( rc ) ) + goto err_out; + + if ( !_ttm_time_is_avail( &new_entry->ttm ) ) + { + free ( new_entry ); + new_entry = NULL; + break; + } + + if ( ucap_info->num_ucaps < MAX_UCAP_ENTRIES ) + { + mbg_klist_append_item(&ucap_info->list, &new_entry->head); + ++ucap_info->num_ucaps; + } + else + { + old_entry = mbg_klist_first_entry(&ucap_info->list, UCAP_ENTRY, head); + mbg_klist_delete_item(&old_entry->head); + free(old_entry); + mbg_klist_append_item(&ucap_info->list, &new_entry->head); + } + + } while (1); + + rc = MBG_SUCCESS; + + goto success_out; + +err_out: + free_all_ucap_info( ucap_info ); + ucap_info = NULL; + if ( new_entry ) + free( new_entry ); + +success_out: + *p = ucap_info; + + return rc; +} + + +/*HDR*/ +/** + * @brief Read all user capture network info and store it into a newly allocated or reused ::ALL_UCAP_NET_INFO + * + * @note ::mbgextio_dev_has_ucap_net should be called to check if this API is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_UCAP_NET_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + * @see ::free_all_ucap_net_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ucap_net_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_UCAP_NET_INFO **p ) +{ + ALL_UCAP_NET_INFO *ucap_net_info = *p; + uint16_t i; + int rc; + + if ( ucap_net_info == NULL ) + { + ucap_net_info = (ALL_UCAP_NET_INFO *) calloc( 1, sizeof( *ucap_net_info ) ); + if ( ucap_net_info == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + } + + rc = mbgextio_get_ucap_net_glb_info( pmctl, p_addr, &ucap_net_info->glb_info ); + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( ucap_net_info->glb_info.settings.num_recvs > 0 ) + { + ucap_net_info->recv_infos = ( MBG_UCAP_NET_RECV_INFO_IDX* )realloc( ucap_net_info->recv_infos, ucap_net_info->glb_info.settings.num_recvs * sizeof( *ucap_net_info->recv_infos ) ); + if ( ucap_net_info->recv_infos == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto out; + } + + for ( i = 0; i < ucap_net_info->glb_info.settings.num_recvs; i++ ) + { + rc = mbgextio_get_ucap_net_recv_info_idx( pmctl, p_addr, &ucap_net_info->recv_infos[i], i ); + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + else + { + if ( ucap_net_info->recv_infos != NULL ) + free( ucap_net_info->recv_infos ); + ucap_net_info->recv_infos = NULL; + } + +out: + if ( mbg_rc_is_error( rc ) ) + { + free_all_ucap_net_info( ucap_net_info ); + ucap_net_info = NULL; + } + + *p = ucap_net_info; + + return rc; + +} // mbgextio_get_all_ucap_net_info + + + +/*HDR*/ +/** + * @brief Write all user capture network settings to a device + * + * The complementary function ::mbgextio_get_all_ucap_net_info should + * have been used to read the original user capture settings and supported + * configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the ::ALL_UCAP_NET_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_ucap_net_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_UCAP_NET_INFO *p ) +{ + MBG_UCAP_NET_RECV_SETTINGS_IDX settings_idx; + uint16_t i; + int rc; + + rc = mbgextio_set_ucap_net_glb_settings( pmctl, p_addr, &p->glb_info.settings ); + + if ( mbg_rc_is_success( rc ) ) + { + for ( i = 0; i < p->glb_info.settings.num_recvs; i++ ) + { + settings_idx.idx = i; + settings_idx.settings = p->recv_infos[i].info.settings; + + rc = mbgextio_set_ucap_net_recv_settings_idx( pmctl, p_addr, &settings_idx, i ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + } + +out: + return rc; + +} // mbgextio_save_all_ucap_net_info + + + +/*HDR*/ +/** + * @brief Read or setup all GNSS status information + * + * This function should be called preferably to get a GNSS status summary + * from GNSS receivers (GPS, GLONASS, ...). + * + * The function ::mbgextio_setup_receiver_info must have been called before, and + * the returned ::RECEIVER_INFO structure has to be passed to this function. + * + * If the device supports this then the low level GNSS API functions + * are called directly to collect the status information. If the device + * doesn't support the GNSS API but is a pure GPS receiver then the GPS + * API functions are called and the GNSS data structures are filled up + * accordingly, so the calling application can always evaluate the + * GNSS data structures in ::ALL_GNSS_INFO. + * + * If neither GPS nor another GNSS system is supported then this function + * returns the ::MBG_ERR_NOT_SUPP_BY_DEV error. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p_agi Pointer to a ::ALL_GNSS_INFO to be filled + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_gps_stat_info + * @see ::mbgextio_get_gnss_mode_info + * @see ::mbgextio_get_all_gnss_sat_info + */ +int mbgextio_chk_get_all_gnss_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + ALL_GNSS_INFO *p_agi ) +{ + GNSS_SAT_INFO_IDX *p_gsii; + int rc; + + memset( p_agi, 0, sizeof( *p_agi ) ); + + // First we check if the device is a GPS receiver, + // which includes GNSS receivers. + rc = mbgextio_dev_is_gps( pmctl ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + + // Read the STAT_INFO structure which is supported by all GPS + // and GNSS receivers. + rc = mbgextio_get_gps_stat_info( pmctl, p_addr, &p_agi->stat_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + + // Check if the device is a GNSS receiver, i.e. can track satellites + // from different systems (GPS, GLONASS, Beidou, ...). + rc = mbgextio_dev_is_gnss( pmctl ); + + if ( mbg_rc_is_success( rc ) ) + { + // The device is a GNSS receiver, i.e. it can track satellites + // from different systems (GPS, GLONASS, Beidou, ...). + // Read some specific GNSS information. + rc = mbgextio_get_gnss_mode_info( pmctl, p_addr, &p_agi->gnss_mode_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + rc = chk_set_n_gnss_supp( p_agi ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + + // If the the device supports the current API we can simply + // retrieve status information for each individual GNSS system. + if ( p_agi->gnss_mode_info.flags & MBG_GNSS_FLAG_MSK_SAT_INFO_IDX_SUPP_SER ) + { + rc = mbgextio_get_all_gnss_sat_info( pmctl, p_addr, p_agi->gnss_sat_info_idx, + &p_agi->gnss_mode_info ); + goto out; + } + + + // The device is a GNSS receiver but only supports a preliminary API + // which is now obsolete. We expect that this receiver can (only) + // track GLONASS satellites in addition to GPS. + if ( p_agi->gnss_mode_info.supp_gnss_types != ( MBG_GNSS_TYPE_MSK_GPS | MBG_GNSS_TYPE_MSK_GLONASS ) ) + { + rc = MBG_ERR_INV_CFG; + goto out; + } + + + // First we set up GNSS info for GPS from STAT_INFO. + setup_gps_only_sat_info_idx_from_statinfo( p_agi ); + + // Then we read the GLONASS status information from the device. + p_gsii = &p_agi->gnss_sat_info_idx[GNSS_TYPE_GLONASS]; + + rc = mbgextio_get_gnss_sat_info( pmctl, p_addr, &p_gsii->gnss_sat_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + + p_gsii->idx = GNSS_TYPE_GLONASS; + + #if 1 // ### TODO + { + // This type of receiver provides the numbers of GPS satellites in + // STAT_INFO from which we have set up gnss_sat_info[GPS], and the + // GLONASS-only numbers of satellites info has been read to + // gnss_sat_info[GLONASS]. We want the summary numbers of GPS and + // GLONASS satellites in STAT_INFO, though, so we add the numbers + // of GLONASS satellites to the numbers in STAT_INFO. + STAT_INFO *p_si = &p_agi->stat_info; + GNSS_SAT_INFO *p_gsi_gln = &p_agi->gnss_sat_info_idx[GNSS_TYPE_GLONASS].gnss_sat_info; + + p_si->svs_in_view += p_gsi_gln->svs_in_view; + p_si->good_svs += p_gsi_gln->good_svs; + } + #else + { + // This type of receiver provides the summary numbers of GPS and GLONASS + // satellites in STAT_INFO from which we have set up gnss_sat_info[GPS], + // and the GLONASS-only numbers of satellites info has been read to + // gnss_sat_info[GLONASS]. + // We want the GPS-only numbers of satellites in gnss_sat_info[GPS], + // so we have to subtract the numbers of GLONASS satellites. + GNSS_SAT_INFO *p_gsi_gps = &p_agi->gnss_sat_info_idx[GNSS_TYPE_GPS].gnss_sat_info; + GNSS_SAT_INFO *p_gsi_gln = &p_agi->gnss_sat_info_idx[GNSS_TYPE_GLONASS].gnss_sat_info; + + p_gsi_gps->svs_in_view -= p_gsi_gln->svs_in_view; + + if ( p_gsi_gps->svs_in_view < 0 ) // this should never happen + p_gsi_gps->svs_in_view = 0; + + p_gsi_gps->good_svs -= p_gsi_gln->good_svs; + + if ( p_gsi_gps->good_svs < 0 ) // this should never happen + p_gsi_gps->good_svs = 0; + } + #endif + + goto out; + } + + + // If we get here then the device is a pure GPS receiver + // which neither supports additional GNSS systems nor the + // associated data structures, so we set up all GNSS + // data structures for GPS only. + rc = setup_gps_only_gnss_info_from_statinfo( p_agi ); + +out: + return rc; + +} // mbgextio_chk_get_all_gnss_info -//#warning mbgextio_save_all_ptp_cfg_settings missing /*HDR*/ @@ -273,3 +3997,1142 @@ void lla_to_dms( POS *pos ) +/*HDR*/ +/** + * @brief Transmit an ACK response to the sender. + * + * A device should call this function if it has accepted a parameter set, + * and an acknowledgement has been requested by the sender by or'ing + * the ::GPS_CMD code with ::GPS_REQACK. If a parameter set has not been + * accepted then ::mbgextio_xmt_nack should be called instead. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_xmt_nack + * @see ::mbgextio_xmt_cmd + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_ack( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) +{ + if ( cmd & GPS_REQACK ) + return mbgextio_xmt_cmd( pmctl, p_addr, (GPS_CMD) ( ( cmd & ~GPS_CTRL_MSK ) | GPS_ACK ) ); + + return MBG_SUCCESS; + +} // mbgextio_xmt_ack + + + +/*HDR*/ +/** + * @brief Transmit a NACK response to the sender. + * + * A device should call this function if a request has been received + * which is not supported, or if a data set has been received which + * contains invalid/unsupported data and thus is ignored. Otherwise + * ::mbgextio_xmt_ack should be called to return an acknowledge code + * to the sender, if requested. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, including the ::GPS_CMD_CTRL_CODES flags + * @param[in] error One of the @ref MBG_ERROR_CODES to be returned to the caller + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_xmt_ack + * @see ::mbgextio_xmt_cmd + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_nack( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, int error ) +{ + if ( cmd & GPS_REQACK ) + return mbgextio_xmt_cmd_us( pmctl, p_addr, (GPS_CMD) ( ( cmd & ~GPS_CTRL_MSK ) | GPS_NACK ), (uint16_t ) error ); //### TODO check error cast + + return MBG_SUCCESS; + +} // mbgextio_xmt_nack + + +/*HDR*/ +/** + * @brief Begin a transaction + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] type One of ::MBG_TRANSACTION_TYPES + * @param[in] set Indicates, that this is a set transaction + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_end_transaction + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_begin_transaction( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, uint16_t type, uint8_t set ) +{ + GPS_CMD cmd = GPS_BEGIN_TRANSACTION | OPT_GPS_ACK_CODE; + + if ( set ) + _mbg_transaction_type_set( type ); + + return mbgextio_xmt_cmd_us( pmctl, p_addr, cmd, type ); +} + + +/*HDR*/ +/** + * @brief End a transaction + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] type One of ::MBG_TRANSACTION_TYPES + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_begin_transaction + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_end_transaction( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, uint16_t type ) +{ + GPS_CMD cmd = GPS_END_TRANSACTION | OPT_GPS_ACK_CODE; + + return mbgextio_xmt_cmd_us( pmctl, p_addr, cmd, type ); +} + + +#if defined( _PRELIMINARY_CODE ) + +/*HDR*/ +/** + * @brief Get control message's internal TLV state + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Pointer to internal ::MBG_TLV_RCV_STATE structure + */ +_NO_MBG_API_ATTR MBG_TLV_RCV_STATE* _MBG_API mbgextio_get_tlv_rcv_state( MBG_MSG_CTL *pmctl ) +{ + return &pmctl->tlv_rcv_state; + +} // mbgextio_get_tlv_rcv_state + + + +#if _USE_USB_IO + +/*HDR*/ +/** + * @brief Get control message's internal USB device info structure + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Pointer to internal ::MBG_USB_DEV_INFO structure + */ +_NO_MBG_API_ATTR MBG_USB_DEV_INFO * _MBG_API mbgextio_get_usb_dev_info( MBG_MSG_CTL *pmctl ) +{ + return &pmctl->st.usbio.mdev_info; + +} // mbgextio_get_usb_dev_info + +#endif // _USE_USB_IO + + + +/*HDR*/ +/** + * @brief Send a ::MBG_TLV_ANNOUNCE structure to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_tlv_announce( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const MBG_TLV_ANNOUNCE *p ) +{ + GPS_CMD cmd = GPS_TLV_ANNOUNCE | GPS_REQACK; + MBG_TLV_ANNOUNCE *tlv = &pmctl->xmt.pmb->u.msg_data.tlv_announce; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *tlv = *p; + _mbg_swab_tlv_announce( tlv ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *tlv ) ); + +} // mbgextio_xmt_tlv_announce + + + +/*HDR*/ +/** + * @brief Send a buffer with variable length to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] buf Pointer to data to be sent to the device + * @param[in] buflen Length / size of data + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_tlv_chunk( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + void *buf, size_t buflen ) +{ + int rc; + size_t chunk_size; + uint8_t *pos; + uint8_t *end; + GPS_CMD cmd = GPS_TLV_DATA | GPS_REQACK; + MBG_MSG_BUFF *mbuf = mbgextio_get_xmt_buffer_addr( pmctl ); + MBG_TLV *tlv = &mbuf->u.msg_data.tlv; + MBG_TLV_HDR tlv_hdr; + + if ( buf ) + pos = (uint8_t*) buf; + else + pos = (uint8_t*) tlv->value; + + end = pos + buflen; + + while ( pos < end ) + { + /* Calculate max bytes to be sent */ + chunk_size = end - pos; + if ( chunk_size > sizeof( tlv->value ) ) + chunk_size = sizeof( tlv->value ); + tlv->hdr.cur_bytes = chunk_size; + tlv->hdr.trans_bytes += chunk_size; + + /* Copy and send chunk. If NULL, data is already inside TLV's value */ + if ( buf ) + memcpy( tlv->value, pos, chunk_size ); + + tlv_hdr = tlv->hdr; + _mbg_swab_tlv( tlv ); + rc = mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( tlv->hdr ) + chunk_size ); + if ( mbg_rc_is_error( rc ) ) + return rc; + tlv->hdr = tlv_hdr; + + pos += chunk_size; + } + + return MBG_SUCCESS; + +} // mbgextio_xmt_tlv_chunk + + + +/*HDR*/ +/** + * @brief Send a file to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] f Pointer to an opened file to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_do_xmt_file( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + FILE *f ) +{ + int rc; + size_t num; + unsigned char buf[1024]; + + do + { + num = fread( buf, 1, sizeof( buf ), f ); + + /* Error? */ + if ( ferror ( f ) ) + return MBG_ERR_UNSPEC; + + /* There are bytes to send */ + if ( num > 0 ) + { + rc = mbgextio_xmt_tlv_chunk( pmctl, p_addr, buf, num ); + if ( mbg_rc_is_error( rc ) ) + return rc; + } + + + /* End of file? */ + if ( feof ( f ) ) + break; + + } while ( 1 ); + + return MBG_SUCCESS; + +} // mbgextio_do_xmt_file + + + +/*HDR*/ +/** + * @brief Send a file with a specific command to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] file Name of file to be sent + * @param[in] rev Name of software revision + * @param[in] dest_path Name of destination path on target + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] uid If uid == 0 create random uid, otherwise use the specified one + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_file( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *file, + const char *rev, + const char *dest_path, + MBG_TLV_TYPE tlv_feat_type, + MBG_TLV_UID uid ) +{ + int rc; + FILE *f; + MBG_TLV_ANNOUNCE tlv_announce; + MBG_MSG_BUFF *buf = mbgextio_get_xmt_buffer_addr( pmctl ); + MBG_TLV *tlv = &buf->u.msg_data.tlv; + uint32_t announce_size; + size_t rev_len = 0; + size_t dest_len = 0; + +#if defined( MBG_TGT_WIN32 ) + struct _stat st; + if ( _stat( file, &st ) < 0 ) +#else + struct stat st; + if ( stat( file, &st ) < 0 ) +#endif + return mbg_get_last_error( NULL ); + + f = fopen( file, "rb" ); + + if ( f == NULL ) + return mbg_get_last_error( NULL ); + + if ( uid == 0 ) + uid = mbg_tlv_create_id(); + + announce_size = (uint32_t) st.st_size + sizeof( tlv->hdr ); + + if ( rev ) + { + rev_len = strlen( rev ) + 1; // Transfer terminating 0 ;) + + if ( rev_len > sizeof( tlv->value ) ) + rev_len = sizeof( tlv->value ); + + announce_size += ( rev_len + sizeof( tlv->hdr ) ); + } + + if ( dest_path ) + { + dest_len = strlen( dest_path ) + 1; // Transfer terminating 0 ;) + + if ( dest_len > sizeof( tlv->value ) ) + dest_len = sizeof( tlv->value ); + + announce_size += ( dest_len + sizeof( tlv->hdr ) ); + } + + mbg_tlv_announce_init( &tlv_announce, uid, tlv_feat_type, announce_size ); + + rc = mbgextio_xmt_tlv_announce( pmctl, p_addr, &tlv_announce ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( rev ) + { + mbg_tlv_init( tlv, uid, MBG_TLV_TYPE_STR, rev_len ); + strncpy_safe( (char*) tlv->value, rev, sizeof( tlv->value ) ); + rc = mbgextio_xmt_tlv_chunk( pmctl, p_addr, NULL, rev_len ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + if ( dest_path ) + { + mbg_tlv_init( tlv, uid, MBG_TLV_TYPE_STR, dest_len ); + strncpy_safe( (char*) tlv->value, dest_path, sizeof( tlv->value ) ); + + rc = mbgextio_xmt_tlv_chunk( pmctl, p_addr, NULL, dest_len ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + + mbg_tlv_init( tlv, uid, MBG_TLV_TYPE_FILE, ( uint32_t ) st.st_size ); + + rc = mbgextio_do_xmt_file( pmctl, p_addr, f ); + +out: + fclose( f ); + + return rc; + +} // mbgextio_xmt_file + + + +/*HDR*/ +/** + * @brief Send a cmd line to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd_line Full command line to be executed as system call on target + * @param[in] uid If uid == 0, create random uid. Otherwise use given one + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_line( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *cmd_line, + MBG_TLV_UID uid ) +{ + int rc; + MBG_TLV_ANNOUNCE tlv_announce; + MBG_MSG_BUFF *buf = mbgextio_get_xmt_buffer_addr( pmctl ); + MBG_TLV *tlv = &buf->u.msg_data.tlv; + uint32_t announce_size; + size_t cmd_line_len = 0; + + if ( uid == 0 ) + uid = mbg_tlv_create_id(); + + announce_size = sizeof( tlv->hdr ); + + if ( cmd_line ) + { + cmd_line_len = strlen( cmd_line ) + 1; // Transfer terminating 0 ;) + + if ( cmd_line_len > sizeof( tlv->value ) ) + cmd_line_len = sizeof( tlv->value ); + + announce_size += ( cmd_line_len + sizeof( tlv->hdr ) ); + } + + mbg_tlv_announce_init( &tlv_announce, uid, MBG_TLV_FEAT_TYPE_EXEC_CMD, announce_size ); + + rc = mbgextio_xmt_tlv_announce( pmctl, p_addr, &tlv_announce ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( cmd_line ) + { + mbg_tlv_init( tlv, uid, MBG_TLV_TYPE_STR, cmd_line_len ); + strncpy_safe( (char*) tlv->value, cmd_line, sizeof( tlv->value ) ); + + rc = mbgextio_xmt_tlv_chunk( pmctl, p_addr, NULL, cmd_line_len ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + +out: + return rc; + +} // mbgextio_xmt_cmd_line + + +/*HDR*/ +/** + * @brief Request a generic file of a target. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] filename Name of the source file + * @param[in] dest_path Name of destination path and filename on target + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] uid If uid == 0, create random uid. Otherwise use given one + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_req_generic_file( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *filename, + const char *dest_path, + MBG_TLV_TYPE tlv_feat_type, + MBG_TLV_UID uid ) +{ + int rc; + MBG_TLV_ANNOUNCE tlv_announce; + MBG_MSG_BUFF *xmt_buf = mbgextio_get_xmt_buffer_addr( pmctl ); + MBG_MSG_BUFF *rcv_buf = mbgextio_get_rcv_buffer_addr( pmctl ); + MBG_TLV_ANNOUNCE *rcv_ann = &rcv_buf->u.msg_data.tlv_announce; + MBG_TLV_RCV_STATE *state = mbgextio_get_tlv_rcv_state( pmctl ); + MBG_TLV *tlv = &xmt_buf->u.msg_data.tlv; + ulong tmo = mbgextio_get_msg_rcv_timeout( pmctl ); + uint32_t announce_size; + size_t filename_len = 0; + + if ( uid == 0 ) + uid = mbg_tlv_create_id(); + + if ( filename ) + { + filename_len = strlen( filename ) + 1; // Transfer terminating 0 ;) + + if ( filename_len > sizeof( tlv->value ) ) + filename_len = sizeof( tlv->value ); + + announce_size = ( filename_len + sizeof( tlv->hdr ) ); + } + else + { + rc = MBG_ERR_INV_PARM; + goto out; + } + + mbg_tlv_announce_init( &tlv_announce, uid, tlv_feat_type, announce_size ); + + rc = mbgextio_xmt_tlv_announce( pmctl, p_addr, &tlv_announce ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + mbg_tlv_init( tlv, uid, MBG_TLV_TYPE_STR, filename_len ); + strncpy_safe( (char *) tlv->value, filename, sizeof( tlv->value ) ); + + rc = mbgextio_xmt_tlv_chunk( pmctl, p_addr, NULL, filename_len ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + /* Wait for announce */ + mbgextio_set_msg_rcv_timeout( pmctl, TLV_REQ_FILE_TIMEOUT ); + + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, GPS_TLV_ANNOUNCE, NULL, 0 ); + + if ( mbg_rc_is_error( rc ) ) + { + if ( rc != MBG_ERR_TIMEOUT ) + mbgextio_xmt_nack( pmctl, p_addr, rcv_buf->hdr.cmd, rc ); + + goto out; + } + + if ( tlv_announce.data.uid != rcv_ann->data.uid ) + { + rc = MBG_ERR_INV_TLV_UID; + mbgextio_xmt_nack( pmctl, p_addr, rcv_buf->hdr.cmd, rc ); + goto out; + } + + if ( rcv_ann->data.type != tlv_feat_type ) + { + rc = MBG_ERR_INV_TYPE; + mbgextio_xmt_nack( pmctl, p_addr, rcv_buf->hdr.cmd, rc ); + goto out; + } + + mbgextio_xmt_ack( pmctl, p_addr, rcv_buf->hdr.cmd ); + + mbg_tlv_rcv_state_init( state, tlv_announce.data.uid, rcv_ann->data.total_bytes ); + + state->data.type = MBG_TLV_TYPE_FILE; + + rc = mbgextio_tlv_to_file( pmctl, p_addr, filename ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + +out: + mbgextio_set_msg_rcv_timeout( pmctl, tmo ); + + return rc; + +} // mbgextio_req_generic_file + + + +/*HDR*/ +/** + * @brief Request a file with a specific command from a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] file Name of file to be sent + * @param[in] dest_path Name of destination path on target + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] uid If uid == 0, create random uid. Otherwise use given one + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_req_file_with_cmd( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *file, + const char *dest_path, + MBG_TLV_TYPE tlv_feat_type, + MBG_TLV_UID uid ) +{ + int rc; + MBG_TLV_ANNOUNCE tlv_announce; + MBG_MSG_BUFF *buf = mbgextio_get_rcv_buffer_addr( pmctl ); + MBG_TLV_ANNOUNCE *rcv_ann = &buf->u.msg_data.tlv_announce; + MBG_TLV_RCV_STATE *state = mbgextio_get_tlv_rcv_state( pmctl ); + ulong tmo = mbgextio_get_msg_rcv_timeout( pmctl ); + + if ( uid == 0 ) + uid = mbg_tlv_create_id(); + + mbg_tlv_announce_init( &tlv_announce, uid, tlv_feat_type, 0 ); + + rc = mbgextio_xmt_tlv_announce( pmctl, p_addr, &tlv_announce ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + /* Wait for announce */ + mbgextio_set_msg_rcv_timeout( pmctl, TLV_REQ_FILE_TIMEOUT ); + + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, GPS_TLV_ANNOUNCE, NULL, 0 ); + + if ( mbg_rc_is_error( rc ) ) + { + if (rc != MBG_ERR_TIMEOUT ) + mbgextio_xmt_nack( pmctl, p_addr, buf->hdr.cmd, rc ); + + goto out; + } + + if ( tlv_announce.data.uid != rcv_ann->data.uid ) + { + rc = MBG_ERR_INV_TLV_UID; + mbgextio_xmt_nack( pmctl, p_addr, buf->hdr.cmd, rc ); + goto out; + } + + if ( rcv_ann->data.type != tlv_feat_type ) + { + rc = MBG_ERR_INV_TYPE; + mbgextio_xmt_nack( pmctl, p_addr, buf->hdr.cmd, rc ); + goto out; + } + + mbgextio_xmt_ack( pmctl, p_addr, buf->hdr.cmd ); + + mbg_tlv_rcv_state_init( state, tlv_announce.data.uid, rcv_ann->data.total_bytes ); + + /* Expect a string that contains firmware version first */ + /* Expect firmware update as data blob */ + state->data.type = MBG_TLV_TYPE_FILE; + + if ( dest_path ) + { + rc = mbgextio_tlv_to_file( pmctl, p_addr, dest_path ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + } + +out: + mbgextio_set_msg_rcv_timeout( pmctl, tmo ); + + return rc; + +} + + + +/*HDR*/ +/** + * @brief Send a tlv cmd to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] uid If uid == 0, create random uid. Otherwise use given one + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_tlv_cmd( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + MBG_TLV_TYPE tlv_feat_type, + MBG_TLV_UID uid ) +{ + int rc; + MBG_TLV_ANNOUNCE tlv_announce; + + if ( uid == 0 ) + uid = mbg_tlv_create_id(); + + mbg_tlv_announce_init( &tlv_announce, uid, tlv_feat_type, 0 ); + + rc = mbgextio_xmt_tlv_announce( pmctl, p_addr, &tlv_announce ); + + return rc; + +} + + + +/*HDR*/ +/** + * @brief Wrapper function for ::mbgextio_xmt_file ::TODO + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_fw_update( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *file, + const char *rev, + const char *dest_path, + MBG_TLV_UID uid ) +{ + return mbgextio_xmt_file( pmctl, p_addr, file, rev, dest_path, + MBG_TLV_FEAT_TYPE_FW_UPDATE, uid ); + +} // mbgextio_xmt_fw_update + + + +/*HDR*/ +/** + * @brief Wrapper function for ::mbgextio_xmt_tlv_cmd + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_fw_rollback( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + MBG_TLV_UID uid ) +{ + return mbgextio_xmt_tlv_cmd( pmctl, p_addr, MBG_TLV_FEAT_TYPE_FW_ROLLBACK, uid ); + +} // mbgextio_xmt_fw_rollback + + + +/*HDR*/ +/** + * @brief Wrapper function for ::mbgextio_xmt_file ::TODO + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_binary_file( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *file, + const char *dest_path, + MBG_TLV_UID uid ) +{ + return mbgextio_xmt_file( pmctl, p_addr, file, NULL, dest_path, + MBG_TLV_FEAT_TYPE_FILE_TRANSFER, uid ); + +} // mbgextio_xmt_binary_file + + + +/*HDR*/ +/** + * @brief Wrapper function for ::mbgextio_xmt_file ::TODO + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_apply_license_file( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *file, + MBG_TLV_UID uid ) +{ + return mbgextio_xmt_file( pmctl, p_addr, file, NULL, NULL, + MBG_TLV_FEAT_TYPE_LICENSE_UPGRADE, uid ); + +} // mbgextio_apply_license_file + + + +/*HDR*/ +/** + * @brief Wrapper function for ::mbgextio_xmt_file ::TODO move to firmware-specific module + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_diag_file( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *file, + MBG_TLV_UID uid ) +{ + return mbgextio_xmt_file( pmctl, p_addr, file, NULL, NULL, + MBG_TLV_FEAT_TYPE_DIAG_FILE, uid ); + +} // mbgextio_xmt_diag_file + + + +/*HDR*/ +/** + * @brief Wrapper function + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_req_diag_file( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *dest_path, + MBG_TLV_UID uid ) +{ + return mbgextio_req_file_with_cmd( pmctl, p_addr, NULL, dest_path, + MBG_TLV_FEAT_TYPE_DIAG_FILE, uid ); + +} // mbgextio_xmt_diag_file + +#define HPS_TEMP_UPDATE_DEST_FILE "/tmp/update.tgz" + +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_incremental_fw_update( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *update_src_file, + MBG_TLV_UID uid ) +{ + int rc; + static const char *update_cmd = "mkdir -p /mnt/data;mount /dev/mmcblk0p3 /mnt/data; mkdir -p /mnt/data/usr/bin; tar xzf /tmp/update.tgz -C /mnt/data;sync;umount /mnt/data; reboot "; + + rc = mbgextio_xmt_file( pmctl, p_addr, update_src_file, NULL, HPS_TEMP_UPDATE_DEST_FILE, MBG_TLV_FEAT_TYPE_FILE_TRANSFER, uid ); + + if ( rc == MBG_SUCCESS ) + { + return mbgextio_xmt_cmd_line( pmctl, p_addr, update_cmd, uid ); + } + else + return rc; +} + + + +static int +mbgextio_tlv_type_checks( MBG_TLV *tlv, MBG_TLV_RCV_STATE *state ) +{ + if ( tlv->hdr.uid != state->data.uid ) + return MBG_ERR_INV_TLV_UID; + + if ( tlv->hdr.tlv_type != state->data.type ) + return MBG_ERR_INV_TYPE; + + return MBG_SUCCESS; + +} // mbgextio_type_checks + + + +static int +mbgextio_tlv_size_checks( MBG_TLV *tlv, MBG_TLV_RCV_STATE *state, uint32_t bytes ) +{ + /* TLV has been announced incorrectly? */ + if ( ( bytes + tlv->hdr.cur_bytes ) > tlv->hdr.total_bytes ) + return MBG_ERR_INV_TLV_ANN_BYTES; + + /* Overall size has been announced incorrectly? */ + if ( ( tlv->hdr.cur_bytes + state->read_bytes ) > state->data.total_bytes ) + return MBG_ERR_INV_TLV_ANN_BYTES; + + return MBG_SUCCESS; + +} // mbgextio_tlv_size_checks + + + +static int +mbgextio_tlv_do_checks( MBG_TLV *tlv, MBG_TLV_RCV_STATE *state, uint32_t bytes ) +{ + int rc; + + rc = mbgextio_tlv_type_checks( tlv, state ); + + if ( mbg_rc_is_error( rc ) ) + return rc; + + rc = mbgextio_tlv_size_checks( tlv, state, bytes ); + + if ( mbg_rc_is_error( rc ) ) + return rc; + + return MBG_SUCCESS; + +} // mbgextio_tlv_do_checks + + + +/*HDR*/ +/** + * @brief Read TLV data into a single structure + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] buf Pointer to a buffer / data structure to be filled + * @param[in] buflen Size of buffer + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_tlv_to_struct( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + void *buf, size_t buflen ) +{ + int rc; + uint32_t bytes = 0; + unsigned char *buf8 = ( unsigned char* )buf; + MBG_MSG_BUFF *msg_buf = mbgextio_get_rcv_buffer_addr( pmctl ); + MBG_TLV_RCV_STATE *state = mbgextio_get_tlv_rcv_state( pmctl ); + MBG_TLV *tlv = &msg_buf->u.msg_data.tlv; + + do + { + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, GPS_TLV_DATA, NULL, 0 ); + /* + * Timeout error needs special handling: Sender already stopped + * sending TLVS, so it does not respond to (n)acks anymore. + * Thus, we simply step out here. Any other error should be + * (n)acknowledged + */ + if ( rc == MBG_ERR_TIMEOUT ) + return rc; + + if ( mbg_rc_is_error( rc ) ) + goto err; + + /* + * We need to check this here as we have to receive a TLV first + * before we can decide whether our expected structure size + * fits to the size of the structure that is going to be sent. + */ + //### TODO Pretty sure tlv->hdr.cur_bytes needs to be used below as tlv->hdr.total_bytes contains TLV header size.... + + if ( buflen != tlv->hdr.total_bytes ) + { + rc = MBG_ERR_INV_TLV_SIZE; + goto err; + } + + rc = mbgextio_tlv_do_checks( tlv, state, bytes ); + + if ( mbg_rc_is_error( rc ) ) + goto err; + + /* Send ack if requested */ + mbgextio_xmt_ack( pmctl, p_addr, msg_buf->hdr.cmd ); + + memcpy( &buf8[ bytes ], tlv->value, tlv->hdr.cur_bytes ); + bytes += tlv->hdr.cur_bytes; + state->read_bytes += tlv->hdr.cur_bytes; + + } while ( bytes < tlv->hdr.total_bytes ); + + return MBG_SUCCESS; + +err: + mbgextio_xmt_nack( pmctl, p_addr, msg_buf->hdr.cmd, rc ); + + return rc; + +} // mbgextio_tlv_to_struct + + + +static int +mbgextio_tlv_xmt_early_nack( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_MSG_BUFF *msg_buf, int err ) +{ + int rc; + + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, GPS_TLV_DATA, NULL, 0 ); + + if ( rc == MBG_ERR_TIMEOUT ) + return rc; + + mbgextio_xmt_nack( pmctl, p_addr, msg_buf->hdr.cmd, err ); + + return err; + +} // mbgextio_tlv_xmt_early_nack + + + +/*HDR*/ +/** + * @brief Read TLV into memory + * + * If this function succeeds then an array of memory has been allocated + * using a malloc() call, and the pointer returned via the buf parameter + * has to be freed afterwards by the caller. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] buf Address of a pointer to a buffer to be allocated and filled + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_tlv_to_mem( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + void **buf ) +{ + int rc; + unsigned char *buf8 = NULL; + uint32_t bytes; + MBG_MSG_BUFF *msg_buf = mbgextio_get_rcv_buffer_addr( pmctl ); + MBG_TLV_RCV_STATE *state = mbgextio_get_tlv_rcv_state( pmctl ); + MBG_TLV *tlv = &msg_buf->u.msg_data.tlv; + + *buf = NULL; + bytes = 0; + + do + { + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, GPS_TLV_DATA, NULL, 0 ); + /* + * Timeout error needs special handling: Sender already stopped + * sending TLVS, so it does not respond to (n)acks anymore. + * Thus, we simply step out here. Any other error should be + * (n)acknowledged + */ + if ( rc == MBG_ERR_TIMEOUT ) + { + if ( *buf ) + { + free( *buf ); + *buf = NULL; + } + return rc; + } + + if ( mbg_rc_is_error( rc ) ) + goto err; + + rc = mbgextio_tlv_do_checks( tlv, state, bytes ); + + if ( mbg_rc_is_error( rc ) ) + goto err; + + /* + * We need to malloc the buffer here as we have to receive a TLV first + * before we know which amount of data is going to be sent. + */ + if ( *buf == NULL ) + { + *buf = malloc( tlv->hdr.total_bytes ); + + if ( *buf == NULL ) + { + rc = MBG_ERR_NO_MEM; + goto err; + } + buf8 = ( unsigned char* ) *buf; + } + + /* Send ack if requested */ + mbgextio_xmt_ack( pmctl, p_addr, msg_buf->hdr.cmd ); + + memcpy( &buf8[ bytes ], tlv->value, tlv->hdr.cur_bytes ); + bytes += tlv->hdr.cur_bytes; + state->read_bytes += tlv->hdr.cur_bytes; + + } while ( bytes < tlv->hdr.total_bytes ); + + return MBG_SUCCESS; + +err: + if ( *buf ) + { + free( *buf ); + *buf = NULL; + } + + mbgextio_xmt_nack( pmctl, p_addr, msg_buf->hdr.cmd, rc ); + + return rc; + +} // mbgextio_tlv_to_mem + + + +/*HDR*/ +/** + * @brief Read TLV into a single file. See ::mbgextio_tlv_to_mem ::TODO + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_tlv_to_file( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const char *file ) +{ + int rc; + uint32_t bytes; + FILE *f; + MBG_MSG_BUFF *msg_buf = mbgextio_get_rcv_buffer_addr( pmctl ); + MBG_TLV_RCV_STATE *state = mbgextio_get_tlv_rcv_state( pmctl ); + MBG_TLV *tlv = &msg_buf->u.msg_data.tlv; + + f = fopen( file, "wb" ); + + if ( f == NULL ) + return mbgextio_tlv_xmt_early_nack( pmctl, p_addr, msg_buf, MBG_ERR_IO ); + + bytes = 0; + + do + { + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, GPS_TLV_DATA, NULL, 0 ); + /* + * Timeout error needs special handling: Sender already stopped + * sending TLVS, so it does not respond to (n)acks anymore. + * Thus, we simply step out here. Any other error should be + * (n)acknowledged + */ + if ( rc == MBG_ERR_TIMEOUT ) + goto err; + + if ( mbg_rc_is_error( rc ) ) + goto err; + + rc = mbgextio_tlv_do_checks( tlv, state, bytes ); + + if ( mbg_rc_is_error( rc ) ) + goto err; + + if ( fwrite( tlv->value, tlv->hdr.cur_bytes, 1, f ) != 1 ) + { + if ( ferror( f ) ) + { + rc = mbg_get_last_error( NULL ); + goto err; + } + + if ( !feof( f ) ) + { + rc = MBG_ERR_IO; + goto err; + } + } + + /* Send ack if requested */ + mbgextio_xmt_ack( pmctl, p_addr, msg_buf->hdr.cmd ); + + bytes += tlv->hdr.cur_bytes; + state->read_bytes += tlv->hdr.cur_bytes; + + } while ( bytes < tlv->hdr.total_bytes ); + + rc = MBG_SUCCESS; + +err: + fflush( f ); + fclose( f ); + + if ( mbg_rc_is_error( rc ) ) + { + mbgextio_xmt_nack( pmctl, p_addr, msg_buf->hdr.cmd, rc ); + remove( file ); + } + + return rc; + +} // mbgextio_tlv_to_file + +#endif // _PRELIMINARY_CODE + diff --git a/mbglib/common/extiohlp.h b/mbglib/common/extiohlp.h index 27ccd7b..7d34d88 100644 --- a/mbglib/common/extiohlp.h +++ b/mbglib/common/extiohlp.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: extiohlp.h 1.3.1.5.1.2 2015/01/21 13:24:47Z marvin TEST martin $ + * $Id: extiohlp.h 1.3.1.5.1.70 2017/03/27 10:37:41Z thomas-b TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,149 @@ * * ----------------------------------------------------------------------- * $Log: extiohlp.h $ - * Revision 1.3.1.5.1.2 2015/01/21 13:24:47Z marvin + * Revision 1.3.1.5.1.70 2017/03/27 10:37:41Z thomas-b + * Added function mbgextio_get_all_ptp_v1_common_datasets + * Revision 1.3.1.5.1.69 2017/03/22 09:46:16 thomas-b + * Added function mbgextio_save_all_io_port_info + * Revision 1.3.1.5.1.68 2017/03/20 10:10:02 martin + * Fixed build without _PRELIMINARY_CODE. + * Revision 1.3.1.5.1.67 2017/03/08 12:37:51 thomas-b + * Added set bit for transaction type in mbgextio_begin_transaction + * Revision 1.3.1.5.1.66 2017/02/22 08:32:20 thomas-b + * Extended get and set of ALL_MONITORING_INFO by event structures + * Added get function for ALL_MONITORING_STATUS + * Revision 1.3.1.5.1.65 2017/02/16 12:59:52 thomas-b + * Renamed mbgextio_get_ptp_v2_common_datasets to mbgextio_get_all_ptp_v2_common_datasets + * Use ALL_PTP_V2_COMMON_DATASETS structure instead of MBG_PTP_V2_COMMON_DATASETS + * Revision 1.3.1.5.1.64 2017/02/16 09:32:33 thomas-b + * Added function mbgextio_get_ptp_v2_common_datasets + * Revision 1.3.1.5.1.63 2017/02/15 14:00:07 martin + * Fixed function prototypes. + * Revision 1.3.1.5.1.62 2017/02/08 13:15:44 thomas-b + * Added functions to get and save all monitoring, especially SNMP, configuration + * Revision 1.3.1.5.1.61 2016/12/08 14:46:26 martin + * Updated function prototypes. + * Revision 1.3.1.5.1.60 2016/11/22 12:40:47Z philipp + * Added I/O port helper functions + * Revision 1.3.1.5.1.59 2016/10/27 08:01:37 martin + * Doxygen fixes. + * Updated function prototypes. + * Revision 1.3.1.5.1.58 2016/10/25 07:48:28 martin + * Doxygen fixes. + * Revision 1.3.1.5.1.57 2016/10/21 09:39:43 thomas-b + * Added function mbgextio_get_all_xbp_info + * Revision 1.3.1.5.1.56 2016/10/19 14:33:07 thomas-b + * Added functions mbgextio_get_all_ucap_net_info and mbgextio_save_all_ucap_net_info + * Revision 1.3.1.5.1.55 2016/09/29 14:35:11 thomas-b + * Moved new get and set functions for NET_CFG_API stage 2 to mbgextio + * Revision 1.3.1.5.1.54 2016/09/29 12:16:37 thomas-b + * Added set functions for NET_CFG_API stage 2 + * Revision 1.3.1.5.1.53 2016/09/29 09:09:03 thomas-b + * Added more functions for NET_CFG_API stage 2, especially status + * Revision 1.3.1.5.1.52 2016/09/29 06:13:06 philipp + * Added support for beginning / ending typed transactions + * Revision 1.3.1.5.1.51 2016/09/29 05:56:59 thomas-b + * Added first functions for NET_CFG_API stage 2 + * Revision 1.3.1.5.1.50 2016/09/27 09:27:53 udo + * added new function mbgextio_req_generic_file() + * Revision 1.3.1.5.1.49 2016/06/28 13:39:21 philipp + * Added missing include files if _USE_SERIAL_IO is 0 + * Revision 1.3.1.5.1.48 2016/06/21 12:06:46 thomas-b + * Moved mbgextio_calloc_ucap_entry to cfg_hlp so it can be used in deviohlp as well + * Revision 1.3.1.5.1.47 2016/06/21 08:41:30 thomas-b + * Removed old mbgextio_get_all_ucap_info function and static flag from mbgextio_calloc_ucap_entry + * Revision 1.3.1.5.1.46 2016/06/15 14:03:56 thomas-b + * Added function mbgextio_get_all_ucap_info + * Revision 1.3.1.5.1.45 2016/05/30 14:25:41 daniel + * Added missing code for HPS firmware rollback + * Revision 1.3.1.5.1.44 2016/05/30 13:57:59 daniel + * Support firmware rollback + * Revision 1.3.1.5.1.43 2016/05/26 10:59:27 thomas-b + * Added parameter ALL_NTP_CFG_INFO to mbgextio_get_all_ntp_status + * Moved check functions of specific features to cfg_hlp + * Revision 1.3.1.5.1.42 2016/05/25 08:43:37 philipp + * Redesign of ALL_[xxx]_[XXX] structures and (helper) functions + * Revision 1.3.1.5.1.41 2016/05/23 08:58:17 philipp + * New function mbgextio_get_all_gpio_state + * Revision 1.3.1.5.1.40 2016/05/23 08:24:17 philipp + * New function mbgextio_get_all_ims_state + * Revision 1.3.1.5.1.39 2016/05/11 13:21:36 thomas-b + * Implemented mbgextio_get_all_net_status_info + * Revision 1.3.1.5.1.38 2016/05/04 13:07:50 thomas-b + * Added function mbgextio_save_all_net_cfg_info + * Revision 1.3.1.5.1.37 2016/04/27 07:12:03 thomas-b + * Improved comments for mbgextio_get_all_net_cfg_info + * Revision 1.3.1.5.1.36 2016/04/26 14:42:57 thomas-b + * Added function mbgextio_get_all_net_cfg_info + * Revision 1.3.1.5.1.35 2016/04/25 14:47:43 martin + * *** empty log message *** + * Revision 1.3.1.5.1.34 2016/04/22 07:11:51 philipp + * Use pointer to pointer in get_all_* functions + * Revision 1.3.1.5.1.33 2016/04/22 05:01:49 thomas-b + * Added function mbgextio_save_all_ntp_cfg_info + * Revision 1.3.1.5.1.32 2016/04/20 14:54:33 thomas-b + * Added functions mbgextio_get_all_ntp_cfg_info and mbgextio_get_all_ntp_status + * Revision 1.3.1.5.1.31 2016/04/20 12:37:56 thomas-b + * Moved free functions for ALL_XMULTI_REF_INFO and ALL_XMULTI_REF_STATUS to cfg_hlp + * Revision 1.3.1.5.1.30 2016/04/18 14:07:04 thomas-b + * Changed comment + * Revision 1.3.1.5.1.29 2016/04/18 12:57:45 thomas-b + * Renamed mbgextio_set_all_xmulti_ref_settings to mbgextio_save_all_xmulti_ref_info + * Revision 1.3.1.5.1.28 2016/04/15 11:12:26 thomas-b + * Changed xmulti ref functions to alloc/free the whole struct + * Revision 1.3.1.5.1.27 2016/04/13 07:16:48 thomas-b + * Added function mbgextio_set_all_xmulti_ref_settings + * Revision 1.3.1.5.1.26 2016/04/12 13:28:40 philipp + * New helper functions to get all feature related structures at once + * Revision 1.3.1.5.1.25 2016/04/12 08:26:10 thomas-b + * Added mbgextio_get_all_xmulti_ref_info and mbgextio_get_all_xmulti_ref_status and appropriate free functions + * Revision 1.3.1.5.1.24 2016/04/11 11:14:39 daniel + * Support incremental update + * Revision 1.3.1.5.1.23 2016/03/22 11:51:42 thomas-b + * Moved new xport functions and structure definitions to mbgextio + * Revision 1.3.1.5.1.22 2016/03/18 07:10:18Z thomas-b + * Renamed new xport functions and structures + * Revision 1.3.1.5.1.21 2016/03/17 07:11:36 thomas-b + * Added functions mbgextio_setup_xport_list and mbgextio_free_xport_list + * Will have to be extended for use under Windows + * Revision 1.3.1.5.1.20 2016/03/16 13:47:15 martin + * *** empty log message *** + * Revision 1.3.1.5.1.19 2016/03/14 09:46:35 marvin + * Added function to set all ptp settings. + * Revision 1.3.1.5.1.18 2016/02/18 15:52:32Z daniel + * Account for diag file and license upgrade + * Revision 1.3.1.5.1.17 2016/02/15 12:13:23 daniel + * Updated function prototypes + * Revision 1.3.1.5.1.16 2015/12/01 11:34:06 martin + * *** empty log message *** + * Revision 1.3.1.5.1.15 2015/11/30 07:06:36 philipp + * Access function for control message's opaque / internal USB device info structure + * Revision 1.3.1.5.1.14 2015/11/26 16:19:26 martin + * Reworked check feature API causing some other API calls to be + * simplified/changed since receiver info is now stored inside + * the message control block. + * Revision 1.3.1.5.1.13 2015/11/25 10:59:52 philipp + * Extended TLV xmt functions by uid parameter + * Revision 1.3.1.5.1.12 2015/11/24 13:13:07 philipp + * Added / redesigned TLV functions + * Revision 1.3.1.5.1.11 2015/11/23 15:08:41 daniel + * More work on TLV stuff + * Revision 1.3.1.5.1.10 2015/11/23 14:17:02 philipp + * Moved TLV related sending / receiving functions to here + * Revision 1.3.1.5.1.9 2015/10/19 16:42:16 martin + * *** empty log message *** + * Revision 1.3.1.5.1.8 2015/10/19 09:35:10 martin + * *** empty log message *** + * Revision 1.3.1.5.1.7 2015/10/09 11:09:13 martin + * *** empty log message *** + * Revision 1.3.1.5.1.6 2015/10/07 16:03:21 martin + * *** empty log message *** + * Revision 1.3.1.5.1.5 2015/10/07 09:59:01 martin + * More common GNSS support. + * Revision 1.3.1.5.1.4 2015/10/06 14:12:27 martin + * Account for library module chk_tstr renamed to mbg_tstr. + * Revision 1.3.1.5.1.3 2015/09/07 13:24:10 martin + * Revision 1.3.1.5.1.2 2015/01/21 13:24:47 marvin * Added XBP Adress specifier to mbgextio functions. * Revision 1.3.1.5.1.1 2014/10/31 12:03:34Z martin * Started to support XBP addressing. @@ -36,10 +178,10 @@ /* Other headers to be included */ #include <mbgextio.h> - #include <cfg_hlp.h> #include <mbgerror.h> - +#include <stdio.h> +#include <mbgserio.h> #ifdef _EXTIOHLP #define _ext @@ -48,17 +190,12 @@ #define _ext extern #endif - /* Start of header body */ #ifdef __cplusplus extern "C" { #endif - - - - /* function prototypes: */ /* ----- function prototypes begin ----- */ @@ -67,61 +204,670 @@ extern "C" { /* by MAKEHDR, do not remove the comments. */ /** + * @brief Set a callback function and argument used to decode a time string + * + * Some devices send a serial time string interleaved with some binary messages. + * If a callback function has been specified then the binary message receiver + * function invokes that callback function whenever some characters are received + * which don't belong to a binary message. A callback function like ::mbg_tstr_receive + * can then try to decode a serial time string from such spurious characters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] fnc Address of a ::MBG_TSTR_RCV_FNC-style callback function + * @param[in] arg A prepared ::MBG_TSTR_RCV_ARG structure passed to the callback + * function whenever it is invoked. + * + * @see ::MBG_TSTR_RCV_FNC + * @see ::MBG_TSTR_RCV_ARG + * @see ::mbg_tstr_set_rcv_callback + */ + void mbgextio_set_chk_tstr( MBG_MSG_CTL *pmctl, MBG_TSTR_RCV_FNC *fnc, MBG_TSTR_RCV_ARG *arg ) ; + + /** * @brief Read all serial port settings and supported configuration parameters * - * @note The function mbgextio_setup_receiver_info() must have been called before, - * and the returned ::RECEIVER_INFO has to be passed to this function. + * ::mbgextio_setup_receiver_info should have been called before to set up + * a ::RECEIVER_INFO structure to be passed to this function, so this + * function can determine how many serial ports and associated structures + * are supported by this device. * - * The complementary function mbgextio_save_serial_settings() should + * The complementary function ::mbgextio_save_serial_settings should * be used to write a modified port configuration back to the device. * - * @param pmctl Pointer to a valid message control structure - * @param p_addr Pointer to XBP address specifier - * @param p_cfg Pointer to a ::RECEIVER_PORT_CFG structure to be set up - * @param p_ri Pointer to a valid ::RECEIVER_INFO structure + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p_rpcfg Pointer to a ::RECEIVER_PORT_CFG structure to be set up * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_save_serial_settings * @see ::mbgextio_get_receiver_info */ - int mbgextio_get_serial_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, RECEIVER_PORT_CFG *p_cfg, const RECEIVER_INFO *p_ri ) ; + int mbgextio_get_serial_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, RECEIVER_PORT_CFG *p_rpcfg ) ; /** * @brief Send the configuration settings for a single serial port to a device * - * @note The function mbgextio_setup_receiver_info() must have been called before, - * and the returned ::RECEIVER_INFO has to be passed to this function as well as - * to mbgextio_get_serial_settings() which should have been called before to read - * the current settings and supported features for each port. + * The function ::mbgextio_get_serial_settings must have been called before + * to read the current settings and configuration options and fill up a + * ::RECEIVER_PORT_CFG structure. + * + * After the settings for a port have been changed according to the supported + * features this function can be used to write the new settings for a specific + * port addressed by the port_idx parameter to the device. * - * @param pmctl Pointer to a valid message control structure - * @param p_addr Pointer to XBP address specifier - * @param pcfg Pointer to a ::RECEIVER_PORT_CFG structure - * @param port_idx Index of the serial port to be saved + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p_rpcfg Pointer to a ::RECEIVER_PORT_CFG structure containg valid data + * @param[in] port_idx Index of the serial port for which to save the settings * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_get_serial_settings - * @see ::mbgextio_get_receiver_info */ - int mbgextio_save_serial_settings( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, const RECEIVER_PORT_CFG *pcfg, uint16_t port_idx ) ; + int mbgextio_save_serial_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const RECEIVER_PORT_CFG *p_rpcfg, uint16_t port_idx ) ; /** - * @brief Read all PTP configuration in ::ALL_PTP_CFG_INFO format + * @brief Read all XBP information from a device into a newly or re-allocated ::ALL_XBP_INFO structure + * + * @note ::mbgextio_dev_has_xbp should be called to check if this API is supported. * - * @note Only supported if ::GPS_HAS_PTP + * The allocated ::ALL_XBP_INFO needs to be freed ::free_all_ntp_cfg_info, + * as soon as it is not needed any longer. * - * @param pmctl Pointer to a valid message control structure - * @param p_addr Pointer to XBP address specifier - * @param p Pointer to the data structure to return the received data + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_XBP_INFO * * @return One of the @ref MBG_RETURN_CODES * - * @see //##++++++++++++++++++++++++++++++ - * @see ::mbgextio_get_receiver_info + * @see ::mbgextio_dev_has_xbp + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_xbp_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_XBP_INFO **p ) ; + + /** + * @brief Read all network configuration into an ::ALL_NET_CFG_INFO structure + * + * Reads the complete network configuration of a device. Depending on the + * supported API (NET_CFG or LAN_IP4), the appropriate settings are requested and, + * if neccessary, translated into the NET_CFG structures. The filled structures + * can then be used as if the NET_CFG API was completely supported + * + * If NET_CFG or parts of it are not supported, the appropriate n_supp... members + * of ::ALL_NET_CFG_INFO::glb_cfg_info are set to 0, whereas the num... members of + * ::ALL_NET_CFG_INFO::glb_cfg_info::glb_settings may be 1 or bigger. + * + * A ::ALL_NET_CFG_INFO and the appropriate number of ::MBG_NET_INTF_LINK_INFO_IDX, + * ::MBG_NET_INTF_ADDR_INFO_IDX, ::MBG_IP_ADDR_IDX, ::MBG_NET_NAME_IDX and + * ::MBG_NET_INTF_ROUTE_INFO_IDX will be allocated and need to be freed later + * by calling ::free_all_net_cfg_info + * + * @note ::mbgextio_dev_has_net_cfg and mbgextio_dev_has_lan_ip4 are used in the function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_NET_CFG_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_net_cfg + * @see ::mbgextio_get_net_glb_cfg_info + * @see ::mbgextio_get_net_dns_srvr_idx + * @see ::mbgextio_get_net_dns_srch_dom_idx + * @see ::mbgextio_dev_has_lan_ip4 + * @see ::mbgextio_get_lan_if_info + * @see ::mbgextio_get_ip4_settings + * @see ::free_all_net_cfg_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_net_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NET_CFG_INFO **p ) ; + + /** + * @brief Write all network settings to a device + * + * The complementary function ::mbgextio_get_all_net_cfg_info should + * have been used to read the original network settings and supported + * configuration parameters. + * + * Depending on the supported API (NET_CFG or LAN_IP4 or both partly), + * the appropriate settings are, if neccessary, translated into LAN_IP4 structures + * and send to the device using the appropriate API functions. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the ::ALL_NET_CFG_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_net_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NET_CFG_INFO *p ) ; + + /** + * @brief Read current network status into an ::ALL_NET_STATUS_INFO structure + * + * Depending on the supported API (NET_CFG or LAN_IP4), the appropriate status + * is requested and, if neccessary, translated into the NET_CFG structures. + * The filled structures can then be used as if the NET_CFG API was completely supported. + * + * A ::ALL_NET_STATUS_INFO and the appropriate number of ::MBG_NET_INTF_LINK_INFO_IDX, + * ::MBG_NET_INTF_ADDR_INFO_IDX, ::MBG_IP_ADDR_IDX, ::MBG_NET_NAME_IDX and + * ::MBG_NET_INTF_ROUTE_INFO_IDX will be allocated and need to be freed later + * by calling ::free_all_net_status_info + * + * @note ::mbgextio_dev_has_net_cfg and mbgextio_dev_has_lan_ip4 are used in the function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_NET_STATUS_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_net_cfg + * @see ::mbgextio_get_net_glb_cfg_info + * @see ::mbgextio_get_net_stat_dns_srvr_idx + * @see ::mbgextio_get_net_stat_dns_srch_dom_stat_idx + * @see ::mbgextio_dev_has_lan_ip4 + * @see ::mbgextio_get_lan_if_info + * @see ::mbgextio_get_ip4_state + * @see ::free_all_net_status_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_net_status_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NET_STATUS_INFO **p ) ; + + /** + * @brief Read all monitoring configuration into an ::ALL_MONITORING_INFO structure + * + * A ::ALL_MONITORING_INFO will be allocated and needs + * to be freed later by calling ::free_all_monitoring_info. + * A ::ALL_SNMP_INFO may be allocated, if SNMP is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_MONITORING_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_all_snmp_info + * @see ::free_all_monitoring_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_monitoring_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_MONITORING_INFO **p ) ; + + /** + * @brief Write all monitoring configuration to a device + * + * The complementary function ::mbgextio_get_all_monitoring_info should have been used + * to read the original monitoring settings and supported configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_MONITORING_INFO structure with all monitoring parameters + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_all_monitoring_info + * @see ::mbgextio_save_all_snmp_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_monitoring_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_MONITORING_INFO *p ) ; + + /** + * @brief Read all monitoring status into an ::ALL_MONITORING_STATUS structure + * + * A ::ALL_MONITORING_STATUS will be allocated and needs + * to be freed later by calling ::free_all_monitoring_status. + * The ::ALL_MONITORING_INFO::limits is used to check which events are supported + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to a ::ALL_MONITORING_INFO structure which has been read before + * @param[out] p Pointer to a pointer to ::ALL_MONITORING_STATUS + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::free_all_monitoring_status + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_monitoring_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_MONITORING_INFO *info, ALL_MONITORING_STATUS **p ) ; + + /** + * @brief Read all SNMP configuration into an ::ALL_SNMP_INFO structure + * + * A ::ALL_SNMP_INFO and the appropriate number of ::MBG_SNMP_V12_INFO_IDX, + * ::MBG_SNMP_V12_TRAP_INFO_IDX, ::MBG_SNMP_V3_INFO_IDX, and ::MBG_SNMP_V3_TRAP_INFO_IDX + * will be allocated and need to be freed later by calling ::free_all_snmp_info + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_SNMP_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v12_info_idx + * @see ::mbgextio_get_snmp_v12_trap_info_idx + * @see ::mbgextio_get_snmp_v3_info_idx + * @see ::mbgextio_get_snmp_v3_trap_info_idx + * @see ::free_all_snmp_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_snmp_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_SNMP_INFO **p ) ; + + /** + * @brief Write all SNMP settings to a device + * + * The complementary function ::mbgextio_get_all_snmp_info should have been used + * to read the original SNMP settings and supported configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_SNMP_INFO structure with all SNMP parameters + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_snmp_info + * @see ::mbgextio_set_snmp_glb_settings + * @see ::mbgextio_set_snmp_v12_settings_idx + * @see ::mbgextio_set_snmp_v12_trap_settings_idx + * @see ::mbgextio_set_snmp_v3_settings_idx + * @see ::mbgextio_set_snmp_v3_trap_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_snmp_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_SNMP_INFO *p ) ; + + /** + * @brief Read all PTP configuration into an ::ALL_PTP_CFG_INFO structure + * + * @note ::mbgextio_dev_has_ptp should be called to check if this API is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a ::ALL_PTP_CFG_INFO structure to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ptp + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_PTP_CFG_INFO *p ) ; + + /** + * @brief Write all PTP settings to a device + * + * The complementary function ::mbgextio_get_all_ptp_cfg_info should + * have been used to read the original PTP settings and supported + * configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_PTP_CFG_INFO structure with all ptp parameters + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_ptp_cfg_settings + * @see ::mbgextio_set_ptp_uc_master_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_ptp_cfg_info(MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_PTP_CFG_INFO *p ) ; + + /** + * @brief Read all PTPv1 common datasets into a newly or re-allocated ::ALL_PTP_V1_COMMON_DATASETS structure + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * A number of ::MBG_PTP_V1_DEFAULT_DATASET::number_ports port datasets will be allocated. + * To free the allocated ::ALL_PTP_V1_COMMON_DATASETS, ::free_all_ptp_v1_common_datasets should be called. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer of ::ALL_PTP_V1_COMMON_DATASETS structure to be allocated and filled + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_default_dataset + * @see ::mbgextio_get_ptp_v1_current_dataset + * @see ::mbgextio_get_ptp_v1_parent_dataset + * @see ::mbgextio_get_ptp_v1_time_properties_dataset + * @see ::mbgextio_get_ptp_v1_port_dataset_idx + * @see ::free_all_ptp_v1_common_datasets + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_v1_common_datasets( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_PTP_V1_COMMON_DATASETS **p ) ; + + /** + * @brief Read all PTPv2 common datasets into a newly or re-allocated ::ALL_PTP_V2_COMMON_DATASETS structure + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * A number of ::MBG_PTP_V2_DEFAULT_DATASET::number_ports port datasets will be allocated. + * To free the allocated ::ALL_PTP_V2_COMMON_DATASETS, ::free_all_ptp_v2_common_datasets should be called. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer of ::ALL_PTP_V2_COMMON_DATASETS structure to be allocated and filled + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_default_dataset + * @see ::mbgextio_get_ptp_v2_current_dataset + * @see ::mbgextio_get_ptp_v2_parent_dataset + * @see ::mbgextio_get_ptp_v2_time_properties_dataset + * @see ::mbgextio_get_ptp_v2_port_dataset_idx + * @see ::free_all_ptp_v2_common_datasets + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_v2_common_datasets( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_PTP_V2_COMMON_DATASETS **p ) ; + + /** + * @brief Read all NTP configuration into a newly or re-allocated ::ALL_NTP_CFG_INFO structure + * + * @note ::mbgextio_dev_has_ntp should be called to check if this API is supported. + * + * A ::ALL_NTP_CFG_INFO and ::NTP_SRV_MODE_INFO, ::NTP_CLNT_MODE_INFO and a number of + * ::NTP_CLNT_MODE_INFO::settings::num_peers of ::NTP_PEER_SETTINGS_IDX will be allocated and + * needs to be freed by calling ::free_all_ntp_cfg_info + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_NTP_CFG_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ntp + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ntp_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NTP_CFG_INFO **p ) ; + + /** + * @brief Write all NTP settings to a device + * + * The complementary function ::mbgextio_get_all_ntp_cfg_info should + * have been used to read the original NTP settings and supported + * configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_NTP_CFG_INFO structure with all ntp parameters + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_ptp_cfg_settings + * @see ::mbgextio_set_ptp_uc_master_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_ntp_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_NTP_CFG_INFO *p ) ; + + /** + * @brief Read all NTP status info into a newly or re-allocated ::ALL_NTP_STATUS structure + * + * @note ::mbgextio_dev_has_ntp should be called to check if this API is supported. + * + * A ::ALL_NTP_STATUS and ::NTP_SRV_MODE_INFO, ::NTP_CLNT_MODE_INFO and a number of + * ::NTP_CLNT_MODE_INFO::settings::num_peers of ::NTP_PEER_STATE_IDX will be allocated and + * needs to be freed by calling ::free_all_ntp_status + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to the appropriate info structure + * @param[out] p Pointer to a pointer to ::ALL_NTP_STATUS + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ntp + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ntp_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_NTP_CFG_INFO *info, ALL_NTP_STATUS **p ) ; + + /** + * @brief Read all XMR info into a newly or re-allocated ::ALL_XMULTI_REF_INFO + * + * @note ::mbgextio_dev_has_xmulti_ref should be called before using this function + * + * A ::ALL_XMULTI_REF_INFO and a number of ::XMULTI_REF_INSTANCES::n_xmr_settings + * of ::XMULTI_REF_INFO_IDX and ::XMR_EXT_SRC_INFO_IDX will be allocated and needs + * to be freed by calling ::free_all_xmulti_ref_info + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer of ::ALL_XMULTI_REF_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::free_all_xmulti_ref_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_xmulti_ref_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_XMULTI_REF_INFO **p ) ; + + /** + * @brief Set all extended multi ref settings to a device + * + * The complementary function ::mbgextio_get_all_xmulti_ref_info should + * have been used to read the original extended multi ref settings. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_XMULTI_REF_INFO structure with all settings + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_xmr_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_xmulti_ref_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_XMULTI_REF_INFO *p ) ; + + /** + * @brief Read all XMR status info into a newly or re-allocated ::ALL_XMULTI_REF_STATUS + * + * @note ::mbgextio_dev_has_xmulti_ref should be called before using this function + * + * A ::ALL_XMULTI_REF_STATUS and a number of ::XMULTI_REF_INSTANCES::n_xmr_settings + * of ::XMULTI_REF_STATUS_IDX will be allocated and needs to be freed by calling + * ::free_all_xmulti_ref_status + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to an ::ALL_XMULTI_REF_INFO list which has been read before + * @param[out] p Pointer to a pointer of ::ALL_XMULTI_REF_STATUS + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::free_all_xmulti_ref_status + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_xmulti_ref_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_XMULTI_REF_INFO* info, ALL_XMULTI_REF_STATUS **p ) ; + + /** + * @brief Read all IMS related information / configuration into an ::ALL_IMS_INFO structure + * + * @note ::mbgextio_dev_has_ims should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in,out] pp Pointer to a pointer of ::ALL_IMS_INFO structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ims + * @see ::mbgextio_dev_ims_has_fdm + * @see ::free_all_ims_info + * @see ::mbgextio_get_all_ims_state */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_cfg_info( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, ALL_PTP_CFG_INFO *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ims_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_IMS_INFO **pp ) ; + + /** + * @brief Read all IMS related states into an ::ALL_IMS_STATE structure + * + * @note ::mbgextio_dev_has_ims should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to a ::ALL_GPIO_INFO structure which has been read before + * @param[in,out] pp Pointer to a pointer of ::ALL_IMS_STATE structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ims + * @see ::chk_dev_ims_has_fdm + * @see ::free_all_ims_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ims_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_IMS_INFO *info, ALL_IMS_STATE **pp ) ; + + /** + * @brief Read all GPIO related information / configuration into an ::ALL_GPIO_INFO structure + * + * @note ::mbgextio_dev_has_gpio should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in,out] pp Pointer to a pointer of ::ALL_GPIO_INFO structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::chk_dev_gpio_has_status + * @see ::free_all_gpio_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gpio_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_GPIO_INFO **pp ) ; + + /** + * @brief Read all GPIO related state information to an ::ALL_GPIO_STATE structure + * + * @note ::mbgextio_dev_has_gpio should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to a ::ALL_GPIO_INFO structure which has been read before + * @param[in,out] pp Pointer to a pointer of ::ALL_GPIO_STATE structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_gpio + * @see ::chk_dev_gpio_has_status + * @see ::free_all_gpio_info + * @see ::free_all_gpio_state + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gpio_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_GPIO_INFO *info, ALL_GPIO_STATE **pp ) ; + + /** + * @brief Read all I/O port related information to an ::ALL_IO_PORT_INFO structure + + * + * @note ::mbgextio_dev_has_io_ports should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in,out] pp Pointer to a pointer of ::ALL_IO_PORT_INFO structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_io_ports + * @see ::free_all_io_port_info + * @see ::free_all_io_port_state + * @see ::mbgextio_get_all_io_port_status + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_io_port_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_IO_PORT_INFO **pp ) ; + + /** + * @brief Write all I/O port related configuration to a device + * + * The complementary function ::mbgextio_get_all_io_port_info should + * have been used to read the original I/O port settings and supported + * configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to a ::ALL_IO_PORT_INFO structure with all I/O port settings + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_io_port_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_io_port_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_IO_PORT_INFO *p ) ; + + /** + * @brief Read all I/O port related status information to an ::ALL_IO_PORT_STATUS structure + * + * @note ::mbgextio_dev_has_io_ports should be called before using this function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] info Pointer to ::ALL_IO_PORT_INFO + * @param[in,out] pp Pointer to a pointer of ::ALL_IO_PORT_STATUS structure which will be malloced + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_io_ports + * @see ::free_all_io_port_info + * @see ::free_all_io_port_state + * @see ::mbgextio_get_all_io_port_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_io_port_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const ALL_IO_PORT_INFO *info, ALL_IO_PORT_STATUS **pp ) ; + + /** + * @brief Read all user capture information and store it into a newly allocated or reused ::ALL_UCAP_INFO + * + * @note ::mbgextio_dev_has_ucap should be called to check if this API is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_UCAP_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap + * @see ::free_all_ucap_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ucap_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_UCAP_INFO **p ) ; + + /** + * @brief Read all user capture network info and store it into a newly allocated or reused ::ALL_UCAP_NET_INFO + * + * @note ::mbgextio_dev_has_ucap_net should be called to check if this API is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to a pointer to ::ALL_UCAP_NET_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + * @see ::free_all_ucap_net_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ucap_net_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_UCAP_NET_INFO **p ) ; + + /** + * @brief Write all user capture network settings to a device + * + * The complementary function ::mbgextio_get_all_ucap_net_info should + * have been used to read the original user capture settings and supported + * configuration parameters. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the ::ALL_UCAP_NET_INFO + * + * @return One of the @ref MBG_RETURN_CODES + * + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_save_all_ucap_net_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_UCAP_NET_INFO *p ) ; + + /** + * @brief Read or setup all GNSS status information + * + * This function should be called preferably to get a GNSS status summary + * from GNSS receivers (GPS, GLONASS, ...). + * + * The function ::mbgextio_setup_receiver_info must have been called before, and + * the returned ::RECEIVER_INFO structure has to be passed to this function. + * + * If the device supports this then the low level GNSS API functions + * are called directly to collect the status information. If the device + * doesn't support the GNSS API but is a pure GPS receiver then the GPS + * API functions are called and the GNSS data structures are filled up + * accordingly, so the calling application can always evaluate the + * GNSS data structures in ::ALL_GNSS_INFO. + * + * If neither GPS nor another GNSS system is supported then this function + * returns the ::MBG_ERR_NOT_SUPP_BY_DEV error. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p_agi Pointer to a ::ALL_GNSS_INFO to be filled + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_gps_stat_info + * @see ::mbgextio_get_gnss_mode_info + * @see ::mbgextio_get_all_gnss_sat_info + */ + int mbgextio_chk_get_all_gnss_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ALL_GNSS_INFO *p_agi ) ; /** * @brief Convert a mathematical angle [rad] to a geographic angle [degree, minute, second] @@ -142,6 +888,266 @@ extern "C" { */ void lla_to_dms( POS *pos ) ; + /** + * @brief Transmit an ACK response to the sender. + * + * A device should call this function if it has accepted a parameter set, + * and an acknowledgement has been requested by the sender by or'ing + * the ::GPS_CMD code with ::GPS_REQACK. If a parameter set has not been + * accepted then ::mbgextio_xmt_nack should be called instead. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_xmt_nack + * @see ::mbgextio_xmt_cmd + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_ack( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) ; + + /** + * @brief Transmit a NACK response to the sender. + * + * A device should call this function if a request has been received + * which is not supported, or if a data set has been received which + * contains invalid/unsupported data and thus is ignored. Otherwise + * ::mbgextio_xmt_ack should be called to return an acknowledge code + * to the sender, if requested. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, including the ::GPS_CMD_CTRL_CODES flags + * @param[in] error One of the @ref MBG_ERROR_CODES to be returned to the caller + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_xmt_ack + * @see ::mbgextio_xmt_cmd + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_nack( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, int error ) ; + + /** + * @brief Begin a transaction + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] type One of ::MBG_TRANSACTION_TYPES + * @param[in] set Indicates, that this is a set transaction + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_end_transaction + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_begin_transaction( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, uint16_t type, uint8_t set ) ; + + /** + * @brief End a transaction + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] type One of ::MBG_TRANSACTION_TYPES + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_begin_transaction + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_end_transaction( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, uint16_t type ) ; + + /** + * @brief Get control message's internal TLV state + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Pointer to internal ::MBG_TLV_RCV_STATE structure + */ + _NO_MBG_API_ATTR MBG_TLV_RCV_STATE* _MBG_API mbgextio_get_tlv_rcv_state( MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Get control message's internal USB device info structure + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Pointer to internal ::MBG_USB_DEV_INFO structure + */ + _NO_MBG_API_ATTR MBG_USB_DEV_INFO * _MBG_API mbgextio_get_usb_dev_info( MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Send a ::MBG_TLV_ANNOUNCE structure to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_tlv_announce( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_TLV_ANNOUNCE *p ) ; + + /** + * @brief Send a buffer with variable length to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] buf Pointer to data to be sent to the device + * @param[in] buflen Length / size of data + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_tlv_chunk( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, void *buf, size_t buflen ) ; + + /** + * @brief Send a file to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] f Pointer to an opened file to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_do_xmt_file( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, FILE *f ) ; + + /** + * @brief Send a file with a specific command to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] file Name of file to be sent + * @param[in] rev Name of software revision + * @param[in] dest_path Name of destination path on target + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] uid If uid == 0 create random uid, otherwise use the specified one + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_file( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *file, const char *rev, const char *dest_path, MBG_TLV_TYPE tlv_feat_type, MBG_TLV_UID uid ) ; + + /** + * @brief Send a cmd line to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd_line Full command line to be executed as system call on target + * @param[in] uid If uid == 0, create random uid. Otherwise use given one + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_line( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *cmd_line, MBG_TLV_UID uid ) ; + + /** + * @brief Request a generic file of a target. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] filename Name of the source file + * @param[in] dest_path Name of destination path and filename on target + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] uid If uid == 0, create random uid. Otherwise use given one + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_req_generic_file( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *filename, const char *dest_path, MBG_TLV_TYPE tlv_feat_type, MBG_TLV_UID uid ) ; + + /** + * @brief Request a file with a specific command from a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] file Name of file to be sent + * @param[in] dest_path Name of destination path on target + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] uid If uid == 0, create random uid. Otherwise use given one + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_req_file_with_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *file, const char *dest_path, MBG_TLV_TYPE tlv_feat_type, MBG_TLV_UID uid ) ; + + /** + * @brief Send a tlv cmd to a host. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] uid If uid == 0, create random uid. Otherwise use given one + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_tlv_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_TLV_TYPE tlv_feat_type, MBG_TLV_UID uid ) ; + + /** + * @brief Wrapper function for ::mbgextio_xmt_file ::TODO + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_fw_update( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *file, const char *rev, const char *dest_path, MBG_TLV_UID uid ) ; + + /** + * @brief Wrapper function for ::mbgextio_xmt_tlv_cmd + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_fw_rollback( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_TLV_UID uid ) ; + + /** + * @brief Wrapper function for ::mbgextio_xmt_file ::TODO + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_binary_file( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *file, const char *dest_path, MBG_TLV_UID uid ) ; + + /** + * @brief Wrapper function for ::mbgextio_xmt_file ::TODO + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_apply_license_file( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *file, MBG_TLV_UID uid ) ; + + /** + * @brief Wrapper function for ::mbgextio_xmt_file ::TODO move to firmware-specific module + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_diag_file( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *file, MBG_TLV_UID uid ) ; + + /** + * @brief Wrapper function + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_req_diag_file( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *dest_path, MBG_TLV_UID uid ) ; + + /** + * @brief Read TLV data into a single structure + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] buf Pointer to a buffer / data structure to be filled + * @param[in] buflen Size of buffer + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_tlv_to_struct( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, void *buf, size_t buflen ) ; + + /** + * @brief Read TLV into memory + * + * If this function succeeds then an array of memory has been allocated + * using a malloc() call, and the pointer returned via the buf parameter + * has to be freed afterwards by the caller. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] buf Address of a pointer to a buffer to be allocated and filled + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_tlv_to_mem( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, void **buf ) ; + + /** + * @brief Read TLV into a single file. See ::mbgextio_tlv_to_mem ::TODO + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_tlv_to_file( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const char *file ) ; + /* ----- function prototypes end ----- */ diff --git a/mbglib/common/gpsdefs.h b/mbglib/common/gpsdefs.h index 2cbe939..20b269f 100644 --- a/mbglib/common/gpsdefs.h +++ b/mbglib/common/gpsdefs.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: gpsdefs.h 1.124 2015/07/14 14:22:46Z martin REL_M $ + * $Id: gpsdefs.h 1.124.1.310 2017/04/11 10:30:14Z philipp TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -13,7 +13,653 @@ * * ----------------------------------------------------------------------- * $Log: gpsdefs.h $ - * Revision 1.124 2015/07/14 14:22:46Z martin + * Revision 1.124.1.310 2017/04/11 10:30:14Z philipp + * Added USB lock swap macros + * Revision 1.124.1.309 2017/04/11 06:42:41 philipp + * Renamed MBG_USB_INTR structures to MBG_USB_LOCK + * Revision 1.124.1.308 2017/04/11 06:22:29 philipp + * Put MBG_USB_INTR_SETTINGS into MBG_USB_INTR_INFO + * Revision 1.124.1.307 2017/04/11 05:29:56 philipp + * Added commands, structures and defines for feature USB interrupt + * Revision 1.124.1.306 2017/04/04 10:57:27 paul.kretz + * Added FDM180M and associated definitions + * Revision 1.124.1.305 2017/04/04 09:06:40Z philipp + * Added general monitoring and event transactions + * Revision 1.124.1.304 2017/04/04 06:20:49 andre.hartmann + * xfeature for xhe unit added + * Revision 1.124.1.303 2017/03/28 09:38:45Z paul.kretz + * added support for MircoSync power supply module + * Revision 1.124.1.302 2017/03/27 10:38:13Z thomas-b + * Renamed PTPv1 common datasets, added swab macros, feature flag and comments + * Revision 1.124.1.301 2017/03/24 10:18:56 paul.kretz + * removed ENABLE_FLAGS in BUILTIN_FEAT_VSG180 + * Revision 1.124.1.300 2017/03/23 08:55:57Z thomas-b + * Fixed wrong documentation for MBG_IO_PORT_STATUS_BUFFER + * Revision 1.124.1.299 2017/03/22 09:46:28 thomas-b + * Added transaction for IO ports + * Revision 1.124.1.298 2017/03/22 08:54:45 thomas-b + * Fixed string initializer for POUT IO port type + * Revision 1.124.1.297 2017/03/22 08:28:21 philipp + * Added MBG_IO_PORT_OP_MODE_NONE to enum MBG_IO_PORT_OP_MODE_BITS + * Revision 1.124.1.296 2017/03/21 13:32:55 thomas-b + * Added relation string variable to MBG_IO_PORT_INFO structure + * Revision 1.124.1.295 2017/03/21 08:46:46 thomas-b + * Added support for physical and logical IO port groups + * Revision 1.124.1.294 2017/03/20 17:10:23 martin + * Fixed and added lots of swab..() macros. + * Revision 1.124.1.293 2017/03/20 10:10:02 martin + * Fixed build without _PRELIMINARY_CODE. + * Revision 1.124.1.292 2017/03/17 11:59:47 thomas-b + * Added directio in/out and io port positions + * Revision 1.124.1.291 2017/03/16 07:47:51 thomas-b + * Added several missing IO port conn types + * Added new IO port type prog. pulse and appropriate structures + * Revision 1.124.1.290 2017/03/15 09:08:12 philipp + * Added I/O port types + * Revision 1.124.1.289 2017/03/15 09:00:49 gregoire + * str initializer for NTP_SYMM_KEY_HASHES added + * Revision 1.124.1.288 2017/03/15 06:46:24 thomas-b + * Shortened string defines for IO port OP modes + * Revision 1.124.1.287 2017/03/14 13:44:41 philipp + * Added size initializer for new I/O port type ethernet + * Revision 1.124.1.286 2017/03/14 08:55:17 thomas-b + * Added IO port type for network + * Reworked event info structure + * Revision 1.124.1.285 2017/03/13 11:42:13 gregoire.diehl + * New PTP preset DOCSIS 3.1 added + * Revision 1.124.1.284 2017/03/10 10:36:41Z paul.kretz + * extended MBG_GPIO_VIDEO_TC_MODES enum + * Revision 1.124.1.283 2017/03/10 09:03:22Z philipp + * Added event_cfg_counter to MBG_MONITORING_STATUS + * Revision 1.124.1.282 2017/03/10 07:23:52 thomas-b + * Added define for invalid event sub_idx + * Revision 1.124.1.281 2017/03/08 12:44:25 thomas-b + * Added mask MBG_TRANSACTION_MSK_SET + * Revision 1.124.1.280 2017/03/08 12:35:44 thomas-b + * Added macros for transaction type set + * Revision 1.124.1.279 2017/03/08 11:42:41 paul.kretz + * bugfix in MBG_GPIO_VIDEO_TC_MODE_MASKS + * Revision 1.124.1.278 2017/03/07 13:56:35Z paul.kretz + * extended GPIO structs for time code support + * Revision 1.124.1.277 2017/03/07 13:46:12Z thomas-b + * Removed builtin feature for ignore lock + * Revision 1.124.1.276 2017/03/07 09:08:43 thomas-b + * *** empty log message *** + * Revision 1.124.1.275 2017/03/07 08:11:01 thomas-b + * Added global feature flag for bonding + * Revision 1.124.1.274 2017/03/03 07:26:53 thomas-b + * Renamed NTP transaction + * Revision 1.124.1.273 2017/03/03 06:42:39 thomas-b + * Relocated NTP_GLB_INFO, fixed several swab macros of new NTP structures + * Revision 1.124.1.272 2017/03/02 14:02:25 gregoire + * NTP related structures reworked + * MBG_TRANSACTION_TYPE_MONITORING_NTP added + * Revision 1.124.1.271 2017/03/01 10:44:26 philipp + * Use _PRELIMINARY_CODE macro instead of debug macro + * Revision 1.124.1.270 2017/02/28 15:31:08 gregoire + * NTP_GLB_INFO: field max_trusted_keys added + * NTP_CLNT_MODE_SETTINGS: field num_peers added + * NTP_SRV_MODE_SETTINGS: field num_refclks added + * NTP_SRV_MODE_INFO: field max_refclks added + * Revision 1.124.1.269 2017/02/27 09:20:34 thomas-b + * Fixed typo in GNSS_SV_STAT_QUALITY_INDS + * Revision 1.124.1.268 2017/02/27 07:44:30 thomas-b + * Changed builtin features for GNS181_UC from preset GPS to preset GNSS + * Revision 1.124.1.267 2017/02/24 11:00:55 philipp + * Moved event type from settings to info + * Revision 1.124.1.266 2017/02/24 09:38:25 philipp + * Do not use fixed buffers for monitorung event info and status + * Revision 1.124.1.265 2017/02/22 12:21:45 thomas-b + * Added string initializers for event types and severities + * Revision 1.124.1.264 2017/02/22 07:53:35 thomas-b + * Added swab macros for monitoring event and status structures + * Revision 1.124.1.263 2017/02/21 15:53:47 philipp + * Added monitoring event and status structures and defines + * Revision 1.124.1.262 2017/02/16 13:00:57 thomas-b + * Added MBG_PTP_V2_PORT_DATASET_IDX structure and removed MBG_PTP_V2_COMMON_DATASETS + * Revision 1.124.1.261 2017/02/16 09:01:31 martin + * New field MBG_GNSS_MODE_INFO::n_sv_status. + * Revision 1.124.1.260 2017/02/16 08:13:00 thomas-b + * Added structures and supp. flag for PTPv2 common datasets defined in IEEE1588-2008, chapter 8.2 + * Revision 1.124.1.259 2017/02/15 16:14:47 martin + * New GNSS type QZSS. + * Renamed GNSS_SV_INFO to GNSS_SV_STATUS. + * New flag MBG_GNSS_FLAG_MSK_HAS_SV_STATUS. + * Revision 1.124.1.258 2017/02/13 08:32:12 philipp + * Fixed GNSS swap macro redefinitions + * Revision 1.124.1.257 2017/02/13 08:26:53 philipp + * Fixed some typos in SNMP structures + * Revision 1.124.1.256 2017/02/10 15:21:11 martin + * Added swab macros for new structures. + * Revision 1.124.1.255 2017/02/10 14:26:22 martin + * New extended feature MBG_XFEATURE_GNSS_SV_INFO + * and associated structures. + * Revision 1.124.1.254 2017/02/08 13:33:42 philipp + * Removed redundant information MBG_SNMP_V12_TRAP_SETTINGS + * Revision 1.124.1.253 2017/02/08 12:49:30 thomas-b + * Changed all int8_t to char in SNMP structs, fixed typo and added some documentation + * Revision 1.124.1.252 2017/02/08 07:04:53 philipp + * Added swaP macros for SNMP monitoring structures + * Revision 1.124.1.251 2017/02/07 11:46:19 philipp + * Fixed duplicate members + * Revision 1.124.1.250 2017/02/07 11:39:42 philipp + * Added destination port for SNMP trap receivers + * Revision 1.124.1.249 2017/02/07 11:34:46 daniel + * *** empty log message *** + * Revision 1.124.1.248 2017/02/07 10:15:19 daniel + * Removed unneccessary xfeature LICENSE_LIMITS + * Revision 1.124.1.247 2017/02/06 13:10:25 philipp + * Added SNMP monitoring structures and defines + * Revision 1.124.1.246 2017/02/06 10:47:49 philipp + * Added monitoring XFeature skeleton + * Revision 1.124.1.245 2017/02/06 08:57:58 daniel + * Added XFEATURE for License Limits + * Revision 1.124.1.244 2017/02/01 09:45:25 daniel + * Added new TLV License types for PTPv1 and Time Monitor + * Revision 1.124.1.243 2017/02/01 09:35:38 martin + * Defined DEFAULT_POUT_PULSE_SHIFT_MIN and + * DEFAULT_POUT_PULSE_SHIFT_MAX. + * Revision 1.124.1.242 2017/01/27 10:24:11 philipp + * Fixed missing while in macro + * Revision 1.124.1.241 2017/01/27 09:13:15 martin + * Fixed macro syntax. + * Revision 1.124.1.240 2017/01/26 15:24:36 martin + * Support new model RSC180RDU. + * Revision 1.124.1.239 2017/01/26 15:13:57 martin + * Fixed some macros. + * Revision 1.124.1.238 2017/01/25 14:34:12 martin + * Added definition POUT_MODES_SUPP_TIMEBASE_UTC. + * Updated comments for POUT_SETTINGS_FLAG_BITS. + * Revision 1.124.1.237 2017/01/25 13:10:38 martin + * Added POUT bit masks definitions indicating which parameter fields + * are relevant for which POUT modes. + * Fixed macros _mbg_swab_pout_settings_on_get() and + * _mbg_swab_pout_settings_on_set(). + * Updated comments, and fixed some typos in comments. + * Revision 1.124.1.236 2017/01/24 14:15:44 daniel + * Started to define structures for PTPv1 datasets + * Revision 1.124.1.235 2017/01/10 16:17:11 daniel + * Added PTPv1 roles + * Revision 1.124.1.234 2017/01/06 15:53:20 martin + * More POUT pulse shift support. + * Revision 1.124.1.233 2017/01/05 14:16:35 martin + * Added missing definitions for PSX_4GE. + * Revision 1.124.1.232 2017/01/02 10:43:39 andre.hartmann + * Added model code for PSX_4GE board. + * Revision 1.124.1.231 2016/12/22 11:21:32Z philipp + * Added NTP and PTP hardware timestamping flags to MBG_NET_INTF_LINK_OPTS + * Revision 1.124.1.230 2016/12/22 10:19:21 martin + * Doxygen fix. + * Revision 1.124.1.229 2016/12/21 09:15:23 martin + * Added GPS_MODEL_HAS_SV_INFO to the BUILTIN_FEAT_GPS mask. + * Support new model GNS180_UC. + * Revision 1.124.1.228 2016/12/08 11:44:17 paul.kretz + * Updated masks for SCU_STAT_INFO + * Revision 1.124.1.227 2016/12/07 14:44:44Z paul.kretz + * Added new masks for SCU_STAT_INFO to support up to 4 power supplies + * Revision 1.124.1.226 2016/12/07 09:34:40Z martin + * Removed trailing spaces. + * Revision 1.124.1.225 2016/12/06 14:50:15 andre.hartmann + * Added model code for GPS165 + * Revision 1.124.1.224 2016/12/06 09:15:58Z thomas-b + * Added builtin feature HAS_SV_INFO for all GPS (only) receivers + * Revision 1.124.1.223 2016/12/01 11:20:08 philipp + * Fixed MBG_IO_PORT_INFO_MIN_SIZE + * Revision 1.124.1.222 2016/11/30 11:25:07 thomas-b + * Added builtin feature for SCU_STAT and added it to RSC180 and MDU180 + * Revision 1.124.1.221 2016/11/29 14:07:00 philipp + * Added MBG_IO_PORT_INFO_IDX_SIZES + * Revision 1.124.1.220 2016/11/25 11:32:15 philipp + * Finalized I/O port structures, enums, defines + * Revision 1.124.1.219 2016/11/24 07:06:34 philipp + * Honour big endian system when swapping bytes + * Revision 1.124.1.218 2016/11/23 12:41:12 philipp + * Fixed GPIO swap macro typos + * Revision 1.124.1.217 2016/11/23 09:36:30 paul.kretz + * added swab macros for GPIO's + * extended MBG_IO_PORT structs + * removed unused preprocessor symbol in FPGA_INFO struct + * Revision 1.124.1.216 2016/11/22 10:33:16Z philipp + * Implemented I/O ports + * Revision 1.124.1.215 2016/11/21 12:22:44 thomas-b + * Added enable flags as builtin feature for FDM180 + * Revision 1.124.1.214 2016/11/16 11:00:36 thomas-b + * Added core module type and revision to MBG_EXT_SYS_INFO + * Revision 1.124.1.213 2016/11/10 14:08:17 thomas-b + * Changed string name for GPS_MODEL_NAME_UNKNOWN + * Revision 1.124.1.212 2016/11/08 17:22:11 martin + * Doxygen fixes. + * Revision 1.124.1.211 2016/11/04 11:48:35 paul.kretz + * Support MDU312. + * Revision 1.124.1.210 2016/11/04 07:21:26Z thomas-b + * Added flag, mask, and idx for GPIO, which indicates that a GPIO configuration depends on another GPIO + * Revision 1.124.1.209 2016/11/02 11:54:57 paul.kretz + * added new xfeature MBG_XFEATURE_REQ_TTM + * Revision 1.124.1.208 2016/11/01 09:27:49Z thomas-b + * Added builtin feature for TZDL to FDM180 + * Revision 1.124.1.207 2016/11/01 09:24:12 martin + * *** empty log message *** + * Revision 1.124.1.206 2016/10/25 13:24:37 martin + * *** empty log message *** + * Revision 1.124.1.205 2016/10/25 08:56:40 martin + * Renamed MSK_ICODE_RX_HAS_SHORT_YEAR to MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5. + * New MSK_ICODE_RX_HAS_ANY_SHORT_YEAR which includes + * all codes providing a year number, either after P5 or after P6. + * Doxygen fixes. + * Changes to builtin feature definitions. + * Revision 1.124.1.204 2016/10/24 08:12:04 martin + * Support MDU180. + * Revision 1.124.1.203 2016/10/20 10:43:20 thomas-b + * Added builtin feature GPS_MODEL_IS_BUS_LVL_DEV + * Revision 1.124.1.202 2016/10/19 10:19:59 thomas-b + * Added define for default user capture network UDP port + * Revision 1.124.1.201 2016/10/19 09:07:28 thomas-b + * Added supported flags for MBG_UCAP_NET_GLB_INFO + * Revision 1.124.1.200 2016/10/13 07:30:10 paul.kretz + * Extended sysinfo proc and fpga types by SAM3s, STM32F4, Cyclone4GX15 and Cyclone4CE22 + * Revision 1.124.1.199 2016/10/10 10:36:35Z thomas-b + * Added transfer protocol for ucap network receivers and added destination port + * Revision 1.124.1.198 2016/10/10 10:17:37 thomas-b + * Removed _PRELIMINARY_CODE_AUDIO restrictions + * Added new extended feature and structure definitions for ucap via network + * Revision 1.124.1.197 2016/10/07 11:24:50 thomas-b + * Fixed swab makro for addr settings + * Revision 1.124.1.196 2016/10/05 08:26:36 andre.hartmann + * Revision 1.124.1.195 2016/09/29 11:56:43Z philipp + * Added documentation for MBG_TRANSACTION_TYPE_NETWORK + * Revision 1.124.1.194 2016/09/29 10:43:41 thomas-b + * Added define for MBG_ARPHRD_ETHER + * Revision 1.124.1.193 2016/09/29 06:13:07 philipp + * Added support for beginning / ending typed transactions + * Revision 1.124.1.192 2016/09/28 13:35:00 philipp + * Renamed flag field + * Revision 1.124.1.191 2016/09/28 13:29:22 thomas-b + * Added feature flags for MBG_NET_GLB_CFG_INFO + * Revision 1.124.1.190 2016/09/26 13:04:54 udo + * added missing comma in MBG_TLV_FEAT_TYPE_NAMES + * Revision 1.124.1.189 2016/09/26 10:08:14 udo + * added TLV Feature MBG_TLV_FEAT_TYPE_FILE_REQUEST to request a generic file from HPS + * Revision 1.124.1.188 2016/09/23 08:29:09 martin + * Fixed missing comma in string table initializer. + * Revision 1.124.1.187 2016/09/22 12:12:29 philipp + * Split ::MBG_NET_INTF_LINK_OPTS::MBG_NET_INTF_LINK_OPT_CAN_SYNCE up into SyncE In and SyncE Out option + * Revision 1.124.1.186 2016/09/15 14:54:30 martin + * Support GRC181PEX. + * Revision 1.124.1.185 2016/09/12 09:16:49 martin + * Fixed cascaded comment characters. + * Revision 1.124.1.184 2016/09/08 10:25:03 martin + * Fixed build for 16 bit targets. + * Revision 1.124.1.183 2016/09/05 13:23:04 paul.kretz + * Added ENABLE_FLAGS to BUILTIN_FEAT_VSG180 + * Revision 1.124.1.182 2016/08/25 14:37:16Z paul.kretz + * added new gpio video type PAL_M + * Revision 1.124.1.181 2016/08/23 15:47:04Z martin + * Moved macros _setup_default_receiver_info_dcf() and + * _setup_default_receiver_info_gps() here. + * Revision 1.124.1.180 2016/08/16 13:01:13 martin + * Syntax fix. + * Revision 1.124.1.179 2016/08/12 11:05:14 paul.kretz + * Added digital audio output as new gpio type which is only included + * if symbol _PRELIMINARY_CODE_AUDIO is defined. + * Revision 1.124.1.178 2016/08/11 11:34:06Z martin + * Modified MBG_REF_OFFS_NOT_CFGD to avoid compiler warning. + * Revision 1.124.1.177 2016/08/11 11:30:16 martin + * Moved time monitoring stuff to new file time_mon.h. + * Revision 1.124.1.176 2016/08/11 10:28:09 udo + * prepare extended data set for time monitor + * Revision 1.124.1.175 2016/08/10 05:17:08 udo + * added domain number to Time Monitor Target Settings + * Revision 1.124.1.174 2016/08/09 14:48:06 martin + * Revision 1.124.1.173 2016/08/03 08:05:11Z thomas-b + * Finished new network structures, definitions and relations + * Revision 1.124.1.172 2016/07/29 09:36:21 paul.kretz + * Added definitions for N2X180. + * Revision 1.124.1.171 2016/07/15 14:08:09Z martin + * Fixed a typo. + * Revision 1.124.1.170 2016/07/07 14:17:02 martin + * Cleaned up POUT API. + * Doxygen fixes. + * Revision 1.124.1.169 2016/07/07 09:57:10 andre.hartmann + * added mbg_clk_res_info + * Revision 1.124.1.168 2016/06/28 15:42:16Z martin + * *** empty log message *** + * Revision 1.124.1.167 2016/06/28 15:04:40 martin + * Added definitions for GRC181. + * Added missing definitions for GPS180CSM. + * Revision 1.124.1.166 2016/06/23 09:23:24 thomas-b + * Added num_dns_srvr and num_dns_srch_dom to MBG_NET_GLB_CFG_SETTINGS + * Revision 1.124.1.165 2016/06/22 06:58:37 udo + * added new parameters to MBG_TIME_MON_TARGET_STATUS + * Revision 1.124.1.164 2016/06/21 06:34:54 andre + * QL alarms now separated for TDEV and MTIE + * comment for QL hysteresis added + * Revision 1.124.1.163 2016/06/10 07:59:09Z philipp + * Extended sysinfo proc and fpga types by SAM3u and Cyclone5 + * Revision 1.124.1.162 2016/06/09 09:17:08 thomas-b + * Added builtin features TIME and TZDL for TCR cards + * Revision 1.124.1.161 2016/06/06 08:59:45 andre + * Revision 1.124.1.160 2016/06/02 13:36:11Z philipp + * Extended MBG_EXT_SYS_INFO proc and fpga types + * Revision 1.124.1.159 2016/06/02 10:57:51 philipp + * Added string initializers for MBG_EXT_SYS_INFO's proc and FPGA types + * Revision 1.124.1.158 2016/06/02 10:24:22 philipp + * Renaming all revision macros and helper functions + * Revision 1.124.1.157 2016/06/02 10:15:35 philipp + * Renaming all MBG_EXT_REV_INFO related stuff to MBG_EXT_SYS_INFO. + * Revision 1.124.1.156 2016/06/01 10:49:49 andre + * Revision 1.124.1.155 2016/06/01 09:51:26Z philipp + * Added structures and definitions for new type MBG_LICENSE to be queried via TLV_API. + * Revision 1.124.1.154 2016/06/01 06:59:00 andre + * Revision 1.124.1.153 2016/05/31 14:32:27Z andre + * Revision 1.124.1.152 2016/05/31 14:32:02Z andre + * Revision 1.124.1.151 2016/05/30 08:14:09Z thomas-b + * Added builtin feature GPS_MODEL_HAS_TIME to GPS receivers and N2x + * Revision 1.124.1.150 2016/05/27 06:32:12 philipp + * Changed XMR_HOLDOVER_STATUS_MODE_NAMES + * Revision 1.124.1.149 2016/05/26 08:01:16 andre + * Revision 1.124.1.148 2016/05/24 14:43:10Z andre + * Revision 1.124.1.147 2016/05/24 13:32:24Z philipp + * Added PTP Statistics + * Revision 1.124.1.146 2016/05/20 08:58:52 thomas-b + * New BUILTIN_FEATURE GPS_HAS_TZCODE for older PZF cards + * Revision 1.124.1.145 2016/05/20 06:41:42 thomas-b + * Added TZDL and ENABLE_FLAGS to BUILTIN_FEAT_N2X + * Revision 1.124.1.144 2016/05/19 13:12:32 paul + * renamed two video HD formats: + * 1080i29.97Hz to 1080i59.94Hz and 1080i25Hz to 1080i50Hz + * Revision 1.124.1.143 2016/05/11 13:20:20Z thomas-b + * Changed several fields and flags in NET_CFG structures + * Revision 1.124.1.142 2016/05/09 08:06:53 philipp + * New array string initializers for LED modes and colors + * Revision 1.124.1.141 2016/05/04 09:57:27 thomas-b + * Comment changed + * Revision 1.124.1.140 2016/04/26 09:17:41 thomas-b + * Changed structure MBG_NET_GLB_CFG_SETTINGS + * Revision 1.124.1.139 2016/04/26 08:51:47 philipp + * New multi reference input type SyncE + * Revision 1.124.1.138 2016/04/26 08:18:58 thomas-b + * Added typedefs for interface route structures if _PRELIMINARY_CODE is not defined + * Revision 1.124.1.137 2016/04/26 07:39:45 thomas-b + * Changed names and descriptions in net_cfg structures + * Relocated preliminary code areas in net_cfg and ntp definitions + * Revision 1.124.1.136 2016/04/26 06:05:44 philipp + * Removed space to fix compiler error on ARM GCC 4.9.3 + * Revision 1.124.1.135 2016/04/25 15:13:58 martin + * *** empty log message *** + * Revision 1.124.1.134 2016/04/25 14:34:46 martin + * *** empty log message *** + * Revision 1.124.1.133 2016/04/25 10:23:22Z martin + * TLV code isn't preliminary anymore. + * Enums with more than 16 entries are not supported by 16 bit compilers. + * Revision 1.124.1.132 2016/04/22 08:36:27 philipp + * Added String initializers for GPIO bit out flags + * Revision 1.124.1.131 2016/04/21 10:53:29 philipp + * Added GPIO bits format strings. + * Added T1 SSM quality levels. + * Revision 1.124.1.130 2016/04/20 14:43:29 udo + * use NANO_TIME instead of double + * Revision 1.124.1.129 2016/04/20 13:16:58 thomas-b + * Added typedefs for NTP_SRV_MODE_INFO and NTP_SRV_MODE_SETTINGS + * Revision 1.124.1.128 2016/04/20 09:26:05 philipp + * Moved all HPS-PTP related structures to gpspriv.h and removed related extended feature bit from gpsdefs.h. + * Also removed functions from mbgextio and xdevfeat since HPS-PTP handling needs a redesign concerning structures. + * Thus, handle everything explicitly for now! + * -> Redesing this A.S.A.P.!!! + * Revision 1.124.1.127 2016/04/18 12:37:02 thomas-b + * New network structures and definitions for bonding and routing + * Revision 1.124.1.126 2016/04/15 13:14:08 daniel + * Added PTP profile ITU-T. G. 8275.2 + * Revision 1.124.1.125 2016/04/15 09:22:16 udo + * fixed alignment problem in PTP_DEV_CFG_GLB + * Revision 1.124.1.124 2016/04/15 08:17:28 philipp + * New feature MBG_XFEATURE_EXT_PTP + * Revision 1.124.1.123 2016/04/15 07:31:46 andre + * Revision 1.124.1.122 2016/04/08 10:18:02Z daniel + * Fixed MBG_ENCODE_EXT_REV macro + * Revision 1.124.1.121 2016/04/08 10:16:29 martin + * *** empty log message *** + * Revision 1.124.1.120 2016/04/07 13:20:23 philipp + * Extended NTP definitions and added new structure MBG_EXT_REV_INFO including enums, masks, etc.. + * Revision 1.124.1.119 2016/04/05 13:29:25 daniel + * Adjust ptp cfg and state structures to take care of unified data type sizes and alignment + * Revision 1.124.1.118 2016/04/04 14:46:13 martin + * Added TLV feature type names. + * Revision 1.124.1.117 2016/03/24 14:08:47 martin + * *** empty log message *** + * Revision 1.124.1.116 2016/03/24 09:14:52 martin + * New extended feature MBG_XFEATURE_PWR_CTL_API. + * Revision 1.124.1.115 2016/03/18 11:21:52 martin + * *** empty log message *** + * Revision 1.124.1.114 2016/03/18 10:32:25 martin + * *** empty log message *** + * Revision 1.124.1.113 2016/03/17 09:21:01 martin + * *** empty log message *** + * Revision 1.124.1.112 2016/03/16 15:13:37 martin + * *** empty log message *** + * Revision 1.124.1.111 2016/03/16 08:29:13 martin + * Removed ..._MODEL_HAS_GNSS_MODE definitions, use ..._MODEL_IS_GNSS + * instead. + * Revision 1.124.1.110 2016/03/15 14:55:04 martin + * Modified LNE and LED API. + * Revision 1.124.1.109 2016/03/14 11:54:06 martin + * Fixed duplicate macro name. + * Revision 1.124.1.108 2016/03/11 15:12:08 martin + * Started to refactor LED and LNE API. + * Revision 1.124.1.107 2016/03/11 11:25:26 martin + * Made XMR_STATS::step_det_val a reserved, unused field. + * Cleanup. + * Revision 1.124.1.106 2016/03/11 10:09:44 andre + * Revision 1.124.1.105 2016/03/02 15:03:42Z daniel + * Updates for new PTP Utility profile and PTP statistics + * Revision 1.124.1.104 2016/02/29 15:51:31 andre + * added estimated holdover var to XMR_HOLDOVER_STATUS + * Revision 1.124.1.103 2016/02/25 08:47:32Z paul + * Added definitions for GTS180. + * Revision 1.124.1.102 2016/02/24 09:23:55Z gregoire + * change PTP_ANN_RCPT_TIMEOUT_MAX from 255 to 8 + * Revision 1.124.1.101 2016/02/19 12:11:21Z udo + * added MBG_LNE_INFO_EXT + * Revision 1.124.1.100 2016/02/18 14:56:37 daniel + * Added TLV FEAT_TYPE LICENSE UPGRADE + * Revision 1.124.1.99 2016/02/18 11:27:27 udo + * added MBG_LNE_LED_STATUS + * Revision 1.124.1.98 2016/02/16 08:38:50 gregoire + * added new initializer to MBG_XFEATURE_NAMES + * Revision 1.124.1.97 2016/02/11 12:02:39Z daniel + * Added two TLV_FEAT_TYPES + * Revision 1.124.1.96 2016/02/10 15:52:36 thomas-b + * Added enum MBG_IMS_FDM_FLAGS and appropriate masks enum + * Revision 1.124.1.95 2016/02/03 13:27:44 martin + * Added definitions for LNE180SFP. + * Revision 1.124.1.94 2016/02/03 09:41:32 martin + * Fixed build without _PRELIMINARY_CODE. + * Revision 1.124.1.93 2016/02/02 15:53:46Z martin + * Added definitions for CSM100. + * Revision 1.124.1.92 2016/01/29 09:06:32 udo + * Added time-protocol type to Time Monitor Target settings. + * Revision 1.124.1.91 2016/01/22 11:34:39 gregoire + * Added string initializers for XMR_STATS_FLAGS_BITS. + * Revision 1.124.1.90 2016/01/22 08:16:07Z gregoire + * Renamed DEFAULT_MULTI_REF_NAMES_SHORT strings. + * Revision 1.124.1.89 2016/01/21 08:59:03Z andre + * Added auto_bis field in XMR_STATS. + * Revision 1.124.1.88 2016/01/19 14:11:47Z udo + * Modified time monitor structures. + * Revision 1.124.1.87 2016/01/18 08:37:03 udo + * Added support for PTP Time Monitoring on TSU/HPS100. + * Revision 1.124.1.86 2016/01/15 11:30:14 martin + * New field 'timestamp' in XMR_STATS. + * Revision 1.124.1.85 2016/01/15 08:52:51 martin + * Some flag masks for XMR_STATS. + * Revision 1.124.1.84 2016/01/13 15:26:00 martin + * Removed obsolete code added in the previous version. + * Revision 1.124.1.83 2016/01/13 15:09:17 martin + * Support XMR_STATS. + * Revision 1.124.1.82 2015/12/14 13:03:09 lars + * Fixes / changes in IRIG TX / RX masks. + * Revision 1.124.1.81 2015/12/14 11:09:01Z lars + * *** preliminary *** + * Revision 1.124.1.80 2015/12/09 17:34:56Z martin + * *** empty log message *** + * Revision 1.124.1.79 2015/12/09 10:21:18 martin + * *** empty log message *** + * Revision 1.124.1.78 2015/12/09 08:28:36 martin + * New legacy model codes. + * Changed/Added some IRIG enums. + * Revision 1.124.1.77 2015/12/07 14:43:04 martin + * Doxygen fixes. + * Revision 1.124.1.76 2015/12/04 14:20:18 paul + * Fixed a typo in comment of video string initialzier. + * Added support for configurable epochs for video outputs. + * Revision 1.124.1.75 2015/12/02 16:51:19Z martin + * *** empty log message *** + * Revision 1.124.1.74 2015/12/02 16:35:32 martin + * *** empty log message *** + * Revision 1.124.1.73 2015/12/01 11:34:33 martin + * *** empty log message *** + * Revision 1.124.1.72 2015/11/30 16:51:12 martin + * *** empty log message *** + * Revision 1.124.1.71 2015/11/30 16:22:30 martin + * *** empty log message *** + * Revision 1.124.1.70 2015/11/30 09:02:47 philipp + * Added TLV feature MBG_TLV_CTX_FLAG_FW_ROLLBACK. + * Revision 1.124.1.69 2015/11/30 08:16:57 philipp + * Added MBG_TLV_INFO feature macros. + * Revision 1.124.1.68 2015/11/26 17:01:08 martin + * *** empty log message *** + * Revision 1.124.1.67 2015/11/26 08:32:54 martin + * *** empty log message *** + * Revision 1.124.1.66 2015/11/25 16:55:08 martin + * Started to implement extended features. + * Revision 1.124.1.65 2015/11/24 13:10:54 philipp + * TLV additions / partly redesign and feature inline functions. + * Revision 1.124.1.64 2015/11/23 10:23:47 philipp + * Added Doxygen documentation for TLV structures, flags and masks. + * Revision 1.124.1.63 2015/11/23 10:11:28 martin + * *** empty log message *** + * Revision 1.124.1.62 2015/11/23 08:27:32 gregoire + * Added initializers for MBG_IMS_FDM_LINE_FREQS. + * Revision 1.124.1.61 2015/11/20 09:16:39Z philipp + * Fixed macro _mbg_swab_tlv_announce. + * Revision 1.124.1.60 2015/11/20 08:14:29 philipp + * Added id member to struct MBG_TLV_ANNOUNCE. + * Revision 1.124.1.59 2015/11/20 07:26:29 philipp + * Moved TLV structures here. + * Revision 1.124.1.58 2015/11/18 13:51:50 philipp + * Added leapfile to NTP miscellaneous structures. + * Revision 1.124.1.57 2015/11/18 13:39:22 philipp + * Added NTP miscellaneous structures. + * Revision 1.124.1.56 2015/11/06 12:42:08 philipp + * Added NTP statistics structures. + * Revision 1.124.1.55 2015/11/06 11:25:22 philipp + * Removed member symlink in NTP_REFCLK_CFG_SPEC since it is implementation defined. + * Revision 1.124.1.54 2015/11/06 11:16:35 philipp + * Added NTP symmetric key structures. + * Revision 1.124.1.53 2015/11/06 09:17:40 philipp + * Added byte swap macros to NTP restriction and NTP refclock configuration structures. + * Revision 1.124.1.52 2015/11/05 12:20:12 martin + * New define MBG_MAX_HOSTNAME_LEN. + * Preliminary fix for TZDL initializers. + * Updated some comments. + * Revision 1.124.1.51 2015/11/05 09:07:56 philipp + * Added structures for NTP restriction and refclock configuration (preliminary code). + * Revision 1.124.1.50 2015/10/28 12:09:26 martin + * GPIO types for SCG not preliminary anymore. + * Added definitions for LUE180. + * Revision 1.124.1.49 2015/10/26 11:55:19 daniel + * Merged aligned PTP SMPTE and TELECOM PHASE profile structures from previous branch here. + * Revision 1.124.1.48 2015/10/26 11:24:04 daniel + * Support for PTP Preset 802.1AS + * Revision 1.124.1.47 2015/10/26 10:56:42 paul + * added a new flag for GPIO studio clock out + * Revision 1.124.1.46 2015/10/26 09:47:53Z paul + * added a missing GPIO studio clock scale string initializer + * Revision 1.124.1.45 2015/10/23 11:00:27Z paul + * Revision 1.124.1.44 2015/10/22 14:35:51Z paul + * fixed a typo + * Revision 1.124.1.43 2015/10/22 14:17:34Z martin + * *** empty log message *** + * Revision 1.124.1.42 2015/10/22 14:15:02 paul + * some changes in GPIO structs + * Revision 1.124.1.41 2015/10/21 14:36:32Z paul + * renamed stud_clk_out in studio_clk_out and vid_sync_out in video_sync_out + * Revision 1.124.1.40 2015/10/20 13:38:57Z paul + * renamed HD format in GPIO video type + * Revision 1.124.1.39 2015/10/20 12:11:36Z paul + * Revision 1.124.1.38 2015/10/20 10:58:01Z martin + * *** empty log message *** + * Revision 1.124.1.37 2015/10/20 10:43:39 paul + * Revision 1.124.1.36 2015/10/20 10:15:57Z paul + * added preliminary studio clock structs and defines + * Revision 1.124.1.35 2015/10/19 10:48:00Z gregoire + * Revision 1.124.1.34 2015/10/19 10:08:47Z gregoire + * Revision 1.124.1.33 2015/10/16 11:03:06Z martin + * *** empty log message *** + * Revision 1.124.1.32 2015/10/15 14:17:22 martin + * *** empty log message *** + * Revision 1.124.1.31 2015/10/15 08:40:37 paul + * added two new HD video formats + * Revision 1.124.1.30 2015/10/15 07:38:14Z gregoire + * AES67 Media Profile added + * Revision 1.124.1.29 2015/10/13 08:44:08Z gregoire + * smpte_jam_event added to PTP_DEV_CFG_GLB + * Revision 1.124.1.28 2015/10/12 10:01:59Z martin + * *** empty log message *** + * Revision 1.124.1.27 2015/10/09 11:09:13 martin + * *** empty log message *** + * Revision 1.124.1.26 2015/10/09 09:03:50 gregoire + * Revision 1.124.1.25 2015/10/09 07:18:49Z gregoire + * Builtin feature BUILTIN_FEAT_GNSS set for GRC models. + * Revision 1.124.1.24 2015/10/08 13:27:37Z martin + * *** empty log message *** + * Revision 1.124.1.23 2015/10/06 10:33:39 paul + * Changed GPIO names. + * Added two defines for GPIO_TYPE_VIDEO_SYNC. + * Revision 1.124.1.22 2015/10/06 07:55:11Z paul + * Changed names of GPIO types and structs. + * Revision 1.124.1.21 2015/10/02 13:07:11Z martin + * Doxygen fixes. + * Revision 1.124.1.20 2015/10/02 10:33:00 martin + * *** empty log message *** + * Revision 1.124.1.19 2015/10/01 10:51:32 martin + * *** empty log message *** + * Revision 1.124.1.18 2015/09/30 08:03:45 paul + * Bug fix in some GPIO structs. + * Added comments. + * Revision 1.124.1.17 2015/09/29 09:55:22Z paul + * added video output and sync output as two new GPIO types + * Revision 1.124.1.16 2015/09/28 09:34:56Z thomas-b + * Renamed td_max_limit in MBG_IMS_FDM_LIMITS to td_pos_limit + * Revision 1.124.1.15 2015/09/18 13:58:44 martin + * *** empty log message *** + * Revision 1.124.1.14 2015/09/17 14:56:57 thomas-b + * Renamed several variables in MBG_FDM_SETTINGS and MBG_FDM_LIMITS + * Revision 1.124.1.13 2015/09/15 13:15:01 martin + * Moved definitions for NANO_TIME and NANO_TIME_64 to words.h. + * Revision 1.124.1.12 2015/09/15 11:08:22 martin + * Support new model TCR180. + * Added missing comma in DEFAULT_GPS_MODEL_NAMES. + * Revision 1.124.1.11 2015/09/07 09:19:21 martin + * Revision 1.124.1.10 2015/09/04 09:19:17 daniel + * Moved 2 additional TSU strcutures to PREMINARY_CODE block + * Revision 1.124.1.9 2015/09/03 09:17:41 martin + * Doxygen fixes. + * Revision 1.124.1.8 2015/09/02 16:42:17 martin + * Preliminary code which is only included if a preprocessor symbol + * _PRELIMINARY_CODE is defined in the project Makefile. + * Revision 1.124.1.7 2015/08/25 10:30:13 daniel + * Revision 1.124.1.6 2015/08/25 10:02:37 daniel + * Revision 1.124.1.5 2015/08/25 09:16:39 daniel + * Changed reserved member in PTP_STATE to include tsu_secs + * Revision 1.124.1.4 2015/08/10 07:37:09 daniel + * Added sync_e byte swab macros + * Revision 1.124.1.3 2015/08/07 10:51:10 daniel + * Fixed typo in CTC100 declaration + * Revision 1.124.1.2 2015/08/07 10:49:40 daniel + * RE-added temp. PTP structures PTP_DEV_CFG_GLB and PTP_DEV_CFG_NET + * Added new model CTC100 + * Revision 1.124.1.1 2015/07/29 07:40:55 daniel + * Revision 1.124 2015/07/14 14:22:46 martin * Doxygen fix. * Revision 1.123 2015/07/06 13:00:10 martin * Added definitions for VSG180, MSF180, WWVB180, and CPC180. @@ -508,6 +1154,7 @@ #endif + /* Start of header body */ #if defined( _USE_PACK ) @@ -580,10 +1227,11 @@ typedef uint16_t IOD; ///< Issue-Of-Data code #ifndef _CSUM_DEFINED typedef uint16_t CSUM; ///< checksum used by some structures stored in non-volatile memory #define _CSUM_DEFINED - - #define _mbg_swab_csum( _p ) _mbg_swab16( _p ) #endif +#define _mbg_swab_csum( _p ) _mbg_swab16( _p ) + + /** * @brief The type of a GPS command code @@ -601,19 +1249,22 @@ typedef uint16_t GPS_CMD; * * Contains a software revision code, plus an optional * identifier for a customized version. + * + * @see @ref group_ext_sys_info */ typedef struct { uint16_t code; ///< Version number, e.g. 0x0120 means v1.20 - char name[GPS_ID_STR_SIZE]; ///< Optional string identifying a customized version + char name[GPS_ID_STR_SIZE]; ///< Optional string identifying a customized firmware version, should be empty in standard versions uint8_t reserved; ///< Reserved field to yield even structure size } SW_REV; #define _mbg_swab_sw_rev( _p ) \ +do \ { \ _mbg_swab16( &(_p)->code ); \ -} +} while ( 0 ) @@ -723,10 +1374,11 @@ typedef struct } FIXED_FREQ_INFO; #define _mbg_swab_fixed_freq_info( _p ) \ +do \ { \ _mbg_swab16( &(_p)->khz_val ); \ _mbg_swab16( &(_p)->range ); \ -} +} while ( 0 ) /** @@ -758,11 +1410,12 @@ typedef struct uint8_t n_com_ports; ///< number of on-board serial ports uint8_t n_str_type; ///< max num of string types supported by any port uint8_t n_prg_out; ///< number of programmable pulse outputs - uint16_t flags; ///< additional information, see ::RECEIVER_INFO_FLAG_BITS + uint16_t flags; ///< additional information, see ::RECEIVER_INFO_FLAG_MASKS } RECEIVER_INFO; #define _mbg_swab_receiver_info( _p ) \ +do \ { \ _mbg_swab16( &(_p)->model_code ); \ _mbg_swab_sw_rev( &(_p)->sw_rev ); \ @@ -770,7 +1423,7 @@ typedef struct _mbg_swab32( &(_p)->features ); \ _mbg_swab_fixed_freq_info( &(_p)->fixed_freq ); \ _mbg_swab16( &(_p)->flags ); \ -} +} while ( 0 ) /** @@ -848,6 +1501,29 @@ enum GPS_MODEL_CODES GPS_MODEL_MSF180, GPS_MODEL_WWVB180, GPS_MODEL_CPC180, + GPS_MODEL_CTC100, + GPS_MODEL_TCR180, + GPS_MODEL_LUE180, + GPS_MODEL_CPC_01, + GPS_MODEL_TSU_01, + GPS_MODEL_CMC_01, + GPS_MODEL_SCU_01, + GPS_MODEL_FCU_01, + GPS_MODEL_CSM100, + GPS_MODEL_LNE180SFP, + GPS_MODEL_GTS180, + GPS_MODEL_GPS180CSM, + GPS_MODEL_GRC181, + GPS_MODEL_N2X180, + GPS_MODEL_GRC181PEX, + GPS_MODEL_MDU180, + GPS_MODEL_MDU312, + GPS_MODEL_GPS165, + GPS_MODEL_GNS181_UC, + GPS_MODEL_PSX_4GE, + GPS_MODEL_RSC180RDU, + GPS_MODEL_USYNCPWR, + GPS_MODEL_FDM180M, N_GPS_MODEL /* If new model codes are added then care must be taken * to update the associated string initializers GPS_MODEL_NAMES @@ -869,7 +1545,7 @@ enum GPS_MODEL_CODES * * @anchor GPS_MODEL_NAMES @{ */ -#define GPS_MODEL_NAME_UNKNOWN "(unknown)" +#define GPS_MODEL_NAME_UNKNOWN "Unknown" #define GPS_MODEL_NAME_GPS166 "GPS166" #define GPS_MODEL_NAME_GPS167 "GPS167" #define GPS_MODEL_NAME_GPS167SV "GPS167SV" @@ -936,6 +1612,29 @@ enum GPS_MODEL_CODES #define GPS_MODEL_NAME_MSF180 "MSF180" #define GPS_MODEL_NAME_WWVB180 "WWVB180" #define GPS_MODEL_NAME_CPC180 "CPC180" +#define GPS_MODEL_NAME_CTC100 "CTC100" +#define GPS_MODEL_NAME_TCR180 "TCR180" +#define GPS_MODEL_NAME_LUE180 "LUE180" +#define GPS_MODEL_NAME_CPC_01 "CPC_01" +#define GPS_MODEL_NAME_TSU_01 "TSU_01" +#define GPS_MODEL_NAME_CMC_01 "CMC_01" +#define GPS_MODEL_NAME_SCU_01 "SCU_01" +#define GPS_MODEL_NAME_FCU_01 "FCU_01" +#define GPS_MODEL_NAME_CSM100 "CSM100" +#define GPS_MODEL_NAME_LNE180SFP "LNE180SFP" +#define GPS_MODEL_NAME_GTS180 "GTS180" +#define GPS_MODEL_NAME_GPS180CSM "GPS180CSM" +#define GPS_MODEL_NAME_GRC181 "GRC181" +#define GPS_MODEL_NAME_N2X180 "N2X180" +#define GPS_MODEL_NAME_GRC181PEX "GRC181PEX" +#define GPS_MODEL_NAME_MDU180 "MDU180" +#define GPS_MODEL_NAME_MDU312 "MDU312" +#define GPS_MODEL_NAME_GPS165 "GPS165" +#define GPS_MODEL_NAME_GNS181_UC "GNS181_UC" +#define GPS_MODEL_NAME_PSX_4GE "PSX_4GE" +#define GPS_MODEL_NAME_RSC180RDU "RSC180RDU" +#define GPS_MODEL_NAME_USYNCPWR "MICROSYNC-PWR" +#define GPS_MODEL_NAME_FDM180M "FDM180M" /** @} anchor GPS_MODEL_NAMES */ @@ -1021,7 +1720,30 @@ enum GPS_MODEL_CODES GPS_MODEL_NAME_VSG180, \ GPS_MODEL_NAME_MSF180, \ GPS_MODEL_NAME_WWVB180, \ - GPS_MODEL_NAME_CPC180 \ + GPS_MODEL_NAME_CPC180, \ + GPS_MODEL_NAME_CTC100, \ + GPS_MODEL_NAME_TCR180, \ + GPS_MODEL_NAME_LUE180, \ + GPS_MODEL_NAME_CPC_01, \ + GPS_MODEL_NAME_TSU_01, \ + GPS_MODEL_NAME_CMC_01, \ + GPS_MODEL_NAME_SCU_01, \ + GPS_MODEL_NAME_FCU_01, \ + GPS_MODEL_NAME_CSM100, \ + GPS_MODEL_NAME_LNE180SFP, \ + GPS_MODEL_NAME_GTS180, \ + GPS_MODEL_NAME_GPS180CSM, \ + GPS_MODEL_NAME_GRC181, \ + GPS_MODEL_NAME_N2X180, \ + GPS_MODEL_NAME_GRC181PEX, \ + GPS_MODEL_NAME_MDU180, \ + GPS_MODEL_NAME_MDU312, \ + GPS_MODEL_NAME_GPS165, \ + GPS_MODEL_NAME_GNS181_UC, \ + GPS_MODEL_NAME_PSX_4GE, \ + GPS_MODEL_NAME_RSC180RDU, \ + GPS_MODEL_NAME_USYNCPWR, \ + GPS_MODEL_NAME_FDM180M \ } @@ -1051,24 +1773,31 @@ enum GPS_BUILTIN_FEATURE_BITS GPS_BIT_MODEL_IS_DCF_PZF, GPS_BIT_MODEL_IS_MSF, GPS_BIT_MODEL_IS_JJY, - GPS_BIT_MODEL_IS_WWV, - - GPS_BIT_MODEL_IS_LNO, - GPS_BIT_MODEL_IS_SCU, + GPS_BIT_MODEL_IS_WWVB, + GPS_BIT_MODEL_IS_BUS_LVL_DEV, GPS_BIT_MODEL_HAS_BVAR_STAT, GPS_BIT_MODEL_HAS_POS_XYZ, GPS_BIT_MODEL_HAS_POS_LLA, + GPS_BIT_MODEL_HAS_TIME_TTM, GPS_BIT_MODEL_HAS_TZDL, + GPS_BIT_MODEL_HAS_TZCODE, GPS_BIT_MODEL_HAS_ANT_INFO, + GPS_BIT_MODEL_HAS_ENABLE_FLAGS, GPS_BIT_MODEL_HAS_STAT_INFO, - GPS_BIT_MODEL_HAS_ANT_CABLE_LENGTH, - GPS_BIT_MODEL_HAS_GPS_IGNORE_LOCK, + GPS_BIT_MODEL_HAS_ANT_CABLE_LEN, + GPS_BIT_MODEL_HAS_SCU_STAT, + GPS_BIT_MODEL_HAS_SV_INFO, + GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV, - GPS_BIT_MODEL_HAS_GNSS_MODE, - N_GPS_BIT_MODEL +#if 0 //### TODO This has to be discussed + GPS_BIT_MODEL_IS_LNO, + GPS_BIT_MODEL_IS_SCU, +#endif + + N_GPS_BUILTIN_FEATURE_BITS }; @@ -1088,25 +1817,32 @@ enum GPS_BUILTIN_FEATURE_BITS #define GPS_MODEL_IS_DCF_PZF ( 1UL << GPS_BIT_MODEL_IS_DCF_PZF ) ///< see ::GPS_BIT_MODEL_IS_DCF_PZF #define GPS_MODEL_IS_MSF ( 1UL << GPS_BIT_MODEL_IS_MSF ) ///< see ::GPS_BIT_MODEL_IS_MSF #define GPS_MODEL_IS_JJY ( 1UL << GPS_BIT_MODEL_IS_JJY ) ///< see ::GPS_BIT_MODEL_IS_JJY -#define GPS_MODEL_IS_WWV ( 1UL << GPS_BIT_MODEL_IS_WWV ) ///< see ::GPS_BIT_MODEL_IS_WWV - -#define GPS_MODEL_IS_LNO ( 1UL << GPS_BIT_MODEL_IS_LNO ) ///< see ::GPS_BIT_MODEL_IS_LNO -#define GPS_MODEL_IS_SCU ( 1UL << GPS_BIT_MODEL_IS_SCU ) ///< see ::GPS_BIT_MODEL_IS_SCU +#define GPS_MODEL_IS_WWVB ( 1UL << GPS_BIT_MODEL_IS_WWVB ) ///< see ::GPS_BIT_MODEL_IS_WWVB +#define GPS_MODEL_IS_BUS_LVL_DEV ( 1UL << GPS_BIT_MODEL_IS_BUS_LVL_DEV ) ///< see ::GPS_BIT_MODEL_IS_BUS_LVL_DEV #define GPS_MODEL_HAS_BVAR_STAT ( 1UL << GPS_BIT_MODEL_HAS_BVAR_STAT ) ///< see ::GPS_BIT_MODEL_HAS_BVAR_STAT #define GPS_MODEL_HAS_POS_XYZ ( 1UL << GPS_BIT_MODEL_HAS_POS_XYZ ) ///< see ::GPS_BIT_MODEL_HAS_POS_XYZ #define GPS_MODEL_HAS_POS_LLA ( 1UL << GPS_BIT_MODEL_HAS_POS_LLA ) ///< see ::GPS_BIT_MODEL_HAS_POS_LLA +#define GPS_MODEL_HAS_TIME_TTM ( 1UL << GPS_BIT_MODEL_HAS_TIME_TTM ) ///< see ::GPS_BIT_MODEL_HAS_TIME_TTM #define GPS_MODEL_HAS_TZDL ( 1UL << GPS_BIT_MODEL_HAS_TZDL ) ///< see ::GPS_BIT_MODEL_HAS_TZDL +#define GPS_MODEL_HAS_TZCODE ( 1UL << GPS_BIT_MODEL_HAS_TZCODE ) ///< see ::GPS_BIT_MODEL_HAS_TZCODE #define GPS_MODEL_HAS_ANT_INFO ( 1UL << GPS_BIT_MODEL_HAS_ANT_INFO ) ///< see ::GPS_BIT_MODEL_HAS_ANT_INFO + #define GPS_MODEL_HAS_ENABLE_FLAGS ( 1UL << GPS_BIT_MODEL_HAS_ENABLE_FLAGS ) ///< see ::GPS_BIT_MODEL_HAS_ENABLE_FLAGS #define GPS_MODEL_HAS_STAT_INFO ( 1UL << GPS_BIT_MODEL_HAS_STAT_INFO ) ///< see ::GPS_BIT_MODEL_HAS_STAT_INFO -#define GPS_MODEL_HAS_ANT_CABLE_LENGTH ( 1UL << GPS_BIT_MODEL_HAS_ANT_CABLE_LENGTH ) ///< see ::GPS_BIT_MODEL_HAS_ANT_CABLE_LENGTH -#define GPS_MODEL_HAS_GPS_IGNORE_LOCK ( 1UL << GPS_BIT_MODEL_HAS_GPS_IGNORE_LOCK ) ///< see ::GPS_BIT_MODEL_HAS_GPS_IGNORE_LOCK -#define GPS_MODEL_HAS_XMR_HOLDOVER_INTV ( 1UL << GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV ) ///< see ::GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV +#define GPS_MODEL_HAS_ANT_CABLE_LEN ( 1UL << GPS_BIT_MODEL_HAS_ANT_CABLE_LEN ) ///< see ::GPS_BIT_MODEL_HAS_ANT_CABLE_LEN +#define GPS_MODEL_HAS_SCU_STAT ( 1UL << GPS_BIT_MODEL_HAS_SCU_STAT ) ///< see ::GPS_BIT_MODEL_HAS_SCU_STAT +#define GPS_MODEL_HAS_SV_INFO ( 1UL << GPS_BIT_MODEL_HAS_SV_INFO ) ///< see ::GPS_BIT_MODEL_HAS_SV_INFO + +#if 0 // ### TODO This has to be discussed + #define GPS_MODEL_IS_LNO ( 1UL << GPS_BIT_MODEL_IS_LNO ) ///< see ::GPS_BIT_MODEL_IS_LNO + #define GPS_MODEL_IS_SCU ( 1UL << GPS_BIT_MODEL_IS_SCU ) ///< see ::GPS_BIT_MODEL_IS_SCU +#endif -#define GPS_MODEL_HAS_GNSS_MODE ( 1UL << GPS_BIT_MODEL_HAS_GNSS_MODE ) ///< see ::GPS_BIT_MODEL_HAS_GNSS_MODE +// ### TODO do we need the next one? +#define GPS_MODEL_HAS_XMR_HOLDOVER_INTV ( 1UL << GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV ) ///< see ::GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV -//##+++++ TODO: should we use an extra flag? +//### TODO: should we use an extra flag? #define GPS_MODEL_HAS_POS ( GPS_MODEL_HAS_POS_XYZ | GPS_MODEL_HAS_POS_LLA ) /** @} anchor GPS_BUILTIN_FEATURE_MASKS */ @@ -1124,7 +1860,6 @@ enum GPS_BUILTIN_FEATURE_BITS #define GPS_MODEL_HAS_AUTO_OFF // -- #define GPS_MODEL_HAS_SW_REV // deprecated, use only if ri not supported #define GPS_MODEL_HAS_BVAR_STAT // req -#define GPS_MODEL_HAS_TIME // ? #define GPS_MODEL_HAS_POS_XYZ // GPS_MODEL_IS_GPS, GPS_MODEL_HAS_POS, GPS_MODEL_HAS_POS_XYZ ? #define GPS_MODEL_HAS_POS_LLA // GPS_MODEL_IS_GPS, GPS_MODEL_HAS_POS, GPS_MODEL_HAS_POS_LLA ? #define GPS_MODEL_HAS_TZDL // req @@ -1136,7 +1871,7 @@ enum GPS_BUILTIN_FEATURE_BITS #define GPS_MODEL_HAS_STAT_INFO // req #define GPS_MODEL_HAS_SWITCH_PARMS // deprecated, use ... #define GPS_MODEL_HAS_STRING_PARMS // deprecated, use ... -#define GPS_MODEL_HAS_ANT_CABLE_LENGTH // GPS_MODEL_IS_GPS, also GNSS, or req? +#define GPS_MODEL_HAS_ANT_CABLE_LEN // GPS_MODEL_IS_GPS, also GNSS, or req? #define GPS_MODEL_HAS_SYNC_OUTAGE_DELAY // custom #define GPS_MODEL_HAS_PULSE_INFO // custom #define GPS_MODEL_HAS_OPT_FEATURES // deprecated, use ri @@ -1153,7 +1888,6 @@ enum GPS_BUILTIN_FEATURE_BITS #define GPS_MODEL_HAS_ROM_CSUM // ? #define GPS_MODEL_HAS_MULTI_REF_STATUS // ri ... #define GPS_MODEL_HAS_RCV_TIMEOUT // ri ... -#define GPS_MODEL_HAS_IGNORE_LOCK // ? #define GPS_MODEL_HAS_IRIG_RX_SETTINGS // ri ... #define GPS_MODEL_HAS_IRIG_RX_INFO // ri ... #define GPS_MODEL_HAS_REF_OFFS // ri ... @@ -1211,14 +1945,12 @@ enum GPS_BUILTIN_FEATURE_BITS #define GPS_MODEL_HAS_GLNS_ALM // #define GPS_MODEL_HAS_GNSS_SAT_INFO // -#define GPS_MODEL_HAS_GNSS_MODE // +//#define GPS_MODEL_HAS_GNSS_MODE // #define GPS_MODEL_HAS_IP4_SETTINGS // #define GPS_MODEL_HAS_LAN_IF_INFO // #define GPS_MODEL_HAS_IP4_STATE // -#define GPS_MODEL_HAS_SCU_STAT // - #define GPS_MODEL_HAS_CRYPTED_PACKET // #define GPS_MODEL_HAS_CRYPTED_RAW_PACKET // @@ -1232,6 +1964,9 @@ enum GPS_BUILTIN_FEATURE_BITS /** * @brief Common builtin features of all GPS receivers + * + * @see ::BUILTIN_FEAT_GPS_BUS_LVL + * @see ::BUILTIN_FEAT_GNSS */ #define BUILTIN_FEAT_GPS \ ( \ @@ -1239,11 +1974,13 @@ enum GPS_BUILTIN_FEATURE_BITS GPS_MODEL_HAS_BVAR_STAT | \ GPS_MODEL_HAS_POS_XYZ | \ GPS_MODEL_HAS_POS_LLA | \ + GPS_MODEL_HAS_TIME_TTM | \ GPS_MODEL_HAS_TZDL | \ GPS_MODEL_HAS_ANT_INFO | \ GPS_MODEL_HAS_ENABLE_FLAGS | \ GPS_MODEL_HAS_STAT_INFO | \ - GPS_MODEL_HAS_ANT_CABLE_LENGTH \ + GPS_MODEL_HAS_ANT_CABLE_LEN | \ + GPS_MODEL_HAS_SV_INFO \ ) @@ -1252,15 +1989,195 @@ enum GPS_BUILTIN_FEATURE_BITS * * GNSS includes GPS but optionally other satellite systems, * and the associated API. + * + * @see ::BUILTIN_FEAT_GNSS_BUS_LVL + * @see ::BUILTIN_FEAT_GPS */ #define BUILTIN_FEAT_GNSS \ ( \ BUILTIN_FEAT_GPS | \ - GPS_MODEL_IS_GNSS | \ - GPS_MODEL_HAS_GNSS_MODE \ + GPS_MODEL_IS_GNSS \ +) + + + +/** + * @brief Common builtin features of all simple TCR devices + */ +#define BUILTIN_FEAT_TCR_1 \ +( \ + GPS_MODEL_IS_TCR \ +) + + +/** + * @brief Common builtin features of all enhanced TCR devices + */ +#define BUILTIN_FEAT_TCR_2 \ +( \ + GPS_MODEL_IS_TCR | \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ANT_INFO | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + + +/** + * @brief Common builtin features of all simple DCF77 AM receivers + */ +#define BUILTIN_FEAT_DCF_1 \ +( \ + GPS_MODEL_IS_DCF_AM | \ + GPS_MODEL_HAS_TZCODE \ ) +/** + * @brief Common builtin features of all enhanced DCF77 AM receivers + */ +#define BUILTIN_FEAT_DCF_2 \ +( \ + GPS_MODEL_IS_DCF_AM | \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ANT_INFO | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + +/** + * @brief Common builtin features of all simple DCF77 PZF receivers + */ +#define BUILTIN_FEAT_DCF_PZF_1 \ +( \ + GPS_MODEL_IS_DCF_PZF | \ + GPS_MODEL_HAS_TZCODE \ +) + + +/** + * @brief Common builtin features of all enhanced DCF77 PZF receivers + */ +#define BUILTIN_FEAT_DCF_PZF_2 \ +( \ + GPS_MODEL_IS_DCF_PZF | \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ANT_INFO | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + + +/** + * @brief Common builtin features of all simple MSF receivers + */ +#define BUILTIN_FEAT_MSF_1 \ +( \ + GPS_MODEL_IS_MSF | \ + GPS_MODEL_HAS_TZCODE \ +) + + +/** + * @brief Common builtin features of all enhanced MSF receivers + */ +#define BUILTIN_FEAT_MSF_2 \ +( \ + GPS_MODEL_IS_MSF | \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ANT_INFO | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + + +/** + * @brief Common builtin features of all simple WWVB receivers + */ +#define BUILTIN_FEAT_WVB_1 \ +( \ + GPS_MODEL_IS_WWVB | \ + GPS_MODEL_HAS_TZCODE \ +) + + +/** + * @brief Common builtin features of all enhanced WWVB receivers + */ +#define BUILTIN_FEAT_WVB_2 \ +( \ + GPS_MODEL_IS_WWVB | \ + GPS_MODEL_HAS_TZDL \ +) + + + +/** + * @brief Common builtin features of all simple JJY receivers + */ +#define BUILTIN_FEAT_JJY_1 \ +( \ + GPS_MODEL_IS_JJY | \ + GPS_MODEL_HAS_TZCODE \ +) + + + +/** + * @brief Common builtin features of all N2X devices + */ +#define BUILTIN_FEAT_COMM_N2X \ +( \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + + +/** + * @brief Common builtin features of all bus-level GPS receivers + */ +#define BUILTIN_FEAT_GPS_BUS_LVL ( BUILTIN_FEAT_GPS | GPS_MODEL_IS_BUS_LVL_DEV ) + + +/** + * @brief Common builtin features of all bus-level GNSS receivers + */ +#define BUILTIN_FEAT_GNSS_BUS_LVL ( BUILTIN_FEAT_GNSS | GPS_MODEL_IS_BUS_LVL_DEV ) + + +/** + * @brief Common builtin features of all simple, bus-level TCR devices + */ +#define BUILTIN_FEAT_TCR_1_BUS_LVL ( BUILTIN_FEAT_TCR_1 | GPS_MODEL_IS_BUS_LVL_DEV ) + +/** + * @brief Common builtin features of all enhanced, bus-level TCR devices + */ +#define BUILTIN_FEAT_TCR_2_BUS_LVL ( BUILTIN_FEAT_TCR_2 | GPS_MODEL_IS_BUS_LVL_DEV ) + + +/** + * @brief Common builtin features of all simple, bus-level DCF77 AM receivers + */ +#define BUILTIN_FEAT_DCF_1_BUS_LVL ( BUILTIN_FEAT_DCF_1 | GPS_MODEL_IS_BUS_LVL_DEV ) + +/** + * @brief Common builtin features of all enhanced, bus-level DCF77 AM receivers + */ +#define BUILTIN_FEAT_DCF_2_BUS_LVL ( BUILTIN_FEAT_DCF_2 | GPS_MODEL_IS_BUS_LVL_DEV ) + +/** + * @brief Common builtin features of all enhanced, bus-level DCF77 PZF receivers + */ +#define BUILTIN_FEAT_DCF_PZF_2_BUS_LVL ( BUILTIN_FEAT_DCF_PZF_2 | GPS_MODEL_IS_BUS_LVL_DEV ) + + /** * @brief Definitions of builtin features per device type @@ -1273,69 +2190,92 @@ enum GPS_BUILTIN_FEATURE_BITS #define BUILTIN_FEAT_GPS166 ( BUILTIN_FEAT_GPS ) #define BUILTIN_FEAT_GPS167 ( BUILTIN_FEAT_GPS ) #define BUILTIN_FEAT_GPS167SV ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_GPS167PC ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_GPS167PCI ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS167PC ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_GPS167PCI ( BUILTIN_FEAT_GPS_BUS_LVL ) #define BUILTIN_FEAT_GPS163 ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_GPS168PCI ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS168PCI ( BUILTIN_FEAT_GPS_BUS_LVL ) #define BUILTIN_FEAT_GPS161 ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_GPS169PCI ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_TCR167PCI ( 0 ) +#define BUILTIN_FEAT_GPS169PCI ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_TCR167PCI ( BUILTIN_FEAT_TCR_2_BUS_LVL ) #define BUILTIN_FEAT_GPS164 ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_GPS170PCI ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_PZF511 ( 0 ) +#define BUILTIN_FEAT_GPS170PCI ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_PZF511 ( BUILTIN_FEAT_DCF_PZF_1 ) #define BUILTIN_FEAT_GPS170 ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_TCR511 ( 0 ) -#define BUILTIN_FEAT_AM511 ( 0 ) -#define BUILTIN_FEAT_MSF511 ( 0 ) -#define BUILTIN_FEAT_GRC170 ( 0 ) -#define BUILTIN_FEAT_GPS170PEX ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_TCR511 ( BUILTIN_FEAT_TCR_1_BUS_LVL | GPS_MODEL_HAS_TIME_TTM ) //### TODO Or full TCR_2? +#define BUILTIN_FEAT_AM511 ( BUILTIN_FEAT_DCF_1 ) +#define BUILTIN_FEAT_MSF511 ( BUILTIN_FEAT_MSF_1 ) +#define BUILTIN_FEAT_GRC170 ( BUILTIN_FEAT_GNSS ) +#define BUILTIN_FEAT_GPS170PEX ( BUILTIN_FEAT_GPS_BUS_LVL ) #define BUILTIN_FEAT_GPS162 ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_PTP270PEX ( 0 ) -#define BUILTIN_FEAT_FRC511PEX ( 0 ) +#define BUILTIN_FEAT_PTP270PEX ( GPS_MODEL_IS_BUS_LVL_DEV ) +#define BUILTIN_FEAT_FRC511PEX ( GPS_MODEL_IS_BUS_LVL_DEV ) #define BUILTIN_FEAT_GEN170 ( 0 ) -#define BUILTIN_FEAT_TCR170PEX ( 0 ) -#define BUILTIN_FEAT_WWVB511 ( 0 ) +#define BUILTIN_FEAT_TCR170PEX ( BUILTIN_FEAT_TCR_2_BUS_LVL ) +#define BUILTIN_FEAT_WWVB511 ( BUILTIN_FEAT_WVB_1 ) #define BUILTIN_FEAT_MGR170 ( 0 ) -#define BUILTIN_FEAT_JJY511 ( 0 ) -#define BUILTIN_FEAT_PZF600 ( 0 ) -#define BUILTIN_FEAT_TCR600 ( 0 ) +#define BUILTIN_FEAT_JJY511 ( BUILTIN_FEAT_JJY_1 ) +#define BUILTIN_FEAT_PZF600 ( BUILTIN_FEAT_DCF_PZF_1 ) //### TODO Or full PZF_2? +#define BUILTIN_FEAT_TCR600 ( BUILTIN_FEAT_TCR_1 | GPS_MODEL_HAS_TIME_TTM ) //### TODO Or full TCR_2? #define BUILTIN_FEAT_GPS180 ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_GLN170 ( 0 ) -#define BUILTIN_FEAT_GPS180PEX ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_TCR180PEX ( 0 ) -#define BUILTIN_FEAT_PZF180PEX ( 0 ) +#define BUILTIN_FEAT_GLN170 ( BUILTIN_FEAT_GNSS) +#define BUILTIN_FEAT_GPS180PEX ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_TCR180PEX ( BUILTIN_FEAT_TCR_2_BUS_LVL ) +#define BUILTIN_FEAT_PZF180PEX ( BUILTIN_FEAT_DCF_PZF_2_BUS_LVL ) #define BUILTIN_FEAT_MGR180 ( 0 ) -#define BUILTIN_FEAT_MSF600 ( 0 ) -#define BUILTIN_FEAT_WWVB600 ( 0 ) -#define BUILTIN_FEAT_JJY600 ( 0 ) +#define BUILTIN_FEAT_MSF600 ( BUILTIN_FEAT_MSF_1 ) //### TODO Or full MSF_2? +#define BUILTIN_FEAT_WWVB600 ( BUILTIN_FEAT_WVB_1 ) //### TODO Or full WVB_2? +#define BUILTIN_FEAT_JJY600 ( BUILTIN_FEAT_JJY_1 ) //### TODO Or full JJY_2? #define BUILTIN_FEAT_GPS180HS ( BUILTIN_FEAT_GPS ) -#define BUILTIN_FEAT_GPS180AMC ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS180AMC ( BUILTIN_FEAT_GPS_BUS_LVL ) #define BUILTIN_FEAT_ESI180 ( 0 ) #define BUILTIN_FEAT_CPE180 ( 0 ) #define BUILTIN_FEAT_LNO180 ( 0 ) -#define BUILTIN_FEAT_GRC180 ( 0 ) +#define BUILTIN_FEAT_GRC180 ( BUILTIN_FEAT_GNSS ) #define BUILTIN_FEAT_LIU ( 0 ) -#define BUILTIN_FEAT_DCF600HS ( 0 ) -#define BUILTIN_FEAT_DCF600RS ( 0 ) +#define BUILTIN_FEAT_DCF600HS ( BUILTIN_FEAT_DCF_2 ) //### TODO +#define BUILTIN_FEAT_DCF600RS ( BUILTIN_FEAT_DCF_2 ) //### TODO #define BUILTIN_FEAT_MRI ( 0 ) #define BUILTIN_FEAT_BPE ( 0 ) -#define BUILTIN_FEAT_GLN180PEX ( BUILTIN_FEAT_GNSS ) -#define BUILTIN_FEAT_N2X ( 0 ) -#define BUILTIN_FEAT_RSC180 ( 0 ) +#define BUILTIN_FEAT_GLN180PEX ( BUILTIN_FEAT_GNSS_BUS_LVL ) +#define BUILTIN_FEAT_N2X ( BUILTIN_FEAT_COMM_N2X ) +#define BUILTIN_FEAT_RSC180 ( GPS_MODEL_HAS_SCU_STAT ) #define BUILTIN_FEAT_LNE_GB ( 0 ) #define BUILTIN_FEAT_PPG180 ( 0 ) #define BUILTIN_FEAT_SCG ( 0 ) #define BUILTIN_FEAT_MDU300 ( 0 ) #define BUILTIN_FEAT_SDI ( 0 ) -#define BUILTIN_FEAT_FDM180 ( 0 ) +#define BUILTIN_FEAT_FDM180 ( GPS_MODEL_HAS_TZDL | GPS_MODEL_HAS_ENABLE_FLAGS ) #define BUILTIN_FEAT_SPT ( 0 ) -#define BUILTIN_FEAT_PZF180 ( 0 ) +#define BUILTIN_FEAT_PZF180 ( BUILTIN_FEAT_DCF_PZF_2 ) #define BUILTIN_FEAT_REL1000 ( 0 ) #define BUILTIN_FEAT_HPS100 ( 0 ) #define BUILTIN_FEAT_VSG180 ( 0 ) -#define BUILTIN_FEAT_MSF180 ( 0 ) -#define BUILTIN_FEAT_WWVB180 ( 0 ) +#define BUILTIN_FEAT_MSF180 ( BUILTIN_FEAT_MSF_2 ) +#define BUILTIN_FEAT_WWVB180 ( BUILTIN_FEAT_WVB_2 ) #define BUILTIN_FEAT_CPC180 ( 0 ) +#define BUILTIN_FEAT_CTC100 ( 0 ) +#define BUILTIN_FEAT_TCR180 ( BUILTIN_FEAT_TCR_2 ) +#define BUILTIN_FEAT_LUE180 ( 0 ) +#define BUILTIN_FEAT_CPC_01 ( 0 ) +#define BUILTIN_FEAT_TSU_01 ( 0 ) +#define BUILTIN_FEAT_CMC_01 ( 0 ) +#define BUILTIN_FEAT_SCU_01 ( 0 ) +#define BUILTIN_FEAT_FCU_01 ( 0 ) +#define BUILTIN_FEAT_CSM100 ( 0 ) +#define BUILTIN_FEAT_LNE180SFP ( 0 ) +#define BUILTIN_FEAT_GTS180 ( 0 ) +#define BUILTIN_FEAT_GPS180CSM ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GRC181 ( BUILTIN_FEAT_GNSS ) +#define BUILTIN_FEAT_N2X180 ( BUILTIN_FEAT_COMM_N2X ) +#define BUILTIN_FEAT_GRC181PEX ( BUILTIN_FEAT_GNSS_BUS_LVL ) +#define BUILTIN_FEAT_MDU180 ( GPS_MODEL_HAS_SCU_STAT ) +#define BUILTIN_FEAT_MDU312 ( 0 ) +#define BUILTIN_FEAT_GPS165 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GNS181_UC ( BUILTIN_FEAT_GNSS ) +#define BUILTIN_FEAT_PSX_4GE ( 0 ) +#define BUILTIN_FEAT_RSC180RDU ( GPS_MODEL_HAS_SCU_STAT ) +#define BUILTIN_FEAT_USYNCPWR ( 0 ) +#define BUILTIN_FEAT_FDM180M ( GPS_MODEL_HAS_TZDL | GPS_MODEL_HAS_ENABLE_FLAGS ) /** @} anchor GPS_MODEL_BUILTIN_FEATURE_MASKS */ @@ -1417,6 +2357,29 @@ enum GPS_BUILTIN_FEATURE_BITS { GPS_MODEL_MSF180, BUILTIN_FEAT_MSF180 }, \ { GPS_MODEL_WWVB180, BUILTIN_FEAT_WWVB180 }, \ { GPS_MODEL_CPC180, BUILTIN_FEAT_CPC180 }, \ + { GPS_MODEL_CTC100, BUILTIN_FEAT_CTC100 }, \ + { GPS_MODEL_TCR180, BUILTIN_FEAT_TCR180 }, \ + { GPS_MODEL_LUE180, BUILTIN_FEAT_LUE180 }, \ + { GPS_MODEL_CPC_01, BUILTIN_FEAT_CPC_01 }, \ + { GPS_MODEL_TSU_01, BUILTIN_FEAT_TSU_01 }, \ + { GPS_MODEL_CMC_01, BUILTIN_FEAT_CMC_01 }, \ + { GPS_MODEL_SCU_01, BUILTIN_FEAT_SCU_01 }, \ + { GPS_MODEL_FCU_01, BUILTIN_FEAT_FCU_01 }, \ + { GPS_MODEL_CSM100, BUILTIN_FEAT_CSM100 }, \ + { GPS_MODEL_LNE180SFP, BUILTIN_FEAT_LNE180SFP }, \ + { GPS_MODEL_GTS180, BUILTIN_FEAT_GTS180 }, \ + { GPS_MODEL_GPS180CSM, BUILTIN_FEAT_GPS180CSM }, \ + { GPS_MODEL_GRC181, BUILTIN_FEAT_GRC181 }, \ + { GPS_MODEL_N2X180, BUILTIN_FEAT_N2X180 }, \ + { GPS_MODEL_GRC181PEX, BUILTIN_FEAT_GRC181PEX }, \ + { GPS_MODEL_MDU180, BUILTIN_FEAT_MDU180 }, \ + { GPS_MODEL_MDU312, BUILTIN_FEAT_MDU312 }, \ + { GPS_MODEL_GPS165, BUILTIN_FEAT_GPS165 }, \ + { GPS_MODEL_GNS181_UC, BUILTIN_FEAT_GNS181_UC }, \ + { GPS_MODEL_PSX_4GE, BUILTIN_FEAT_PSX_4GE }, \ + { GPS_MODEL_RSC180RDU, BUILTIN_FEAT_RSC180RDU }, \ + { GPS_MODEL_USYNCPWR, BUILTIN_FEAT_USYNCPWR }, \ + { GPS_MODEL_FDM180M, BUILTIN_FEAT_FDM180M }, \ { 0, 0 } \ } @@ -1424,6 +2387,56 @@ enum GPS_BUILTIN_FEATURE_BITS +/** + * @brief Initialize a ::RECEIVER_INFO structure for legacy DCF77 receivers + * + * Legacy DCF77 receivers may not provide a ::RECEIVER_INFO structure, + * but have well-known properties which can be used to set up a + * default ::RECEIVER_INFO. + * + * @param[in,out] _p Pointer to a ::RECEIVER_INFO STRUCTURE to be set up + * @param[in] _pdev Pointer to a ::PCPS_DEV structure read before + * + * @see ::_setup_default_receiver_info_gps + */ +#define _setup_default_receiver_info_dcf( _p, _pdev ) \ +do \ +{ \ + memset( (_p), 0, sizeof( *(_p) ) ); \ + \ + (_p)->ticks_per_sec = DEFAULT_GPS_TICKS_PER_SEC; \ + (_p)->n_ucaps = 0; \ + (_p)->n_com_ports = _pcps_has_serial( _pdev ) ? 1 : 0; \ + (_p)->n_str_type = ( (_p)->n_com_ports != 0 ) ? \ + DEFAULT_N_STR_TYPE_DCF : 0; \ +} while ( 0 ) + + + +/** + * @brief Initialize a ::RECEIVER_INFO structure for legacy GPS receivers + * + * Legacy GPS receivers may not provide a ::RECEIVER_INFO structure, + * but have well-known properties which can be used to set up a + * default ::RECEIVER_INFO. + * + * @param[in,out] _p Pointer to a ::RECEIVER_INFO STRUCTURE to be set up + * + * @see ::_setup_default_receiver_info_dcf + */ +#define _setup_default_receiver_info_gps( _p ) \ +do \ +{ \ + memset( (_p), 0, sizeof( *(_p) ) ); \ + \ + (_p)->ticks_per_sec = DEFAULT_GPS_TICKS_PER_SEC; \ + (_p)->n_ucaps = 2; \ + (_p)->n_com_ports = DEFAULT_N_COM; \ + (_p)->n_str_type = DEFAULT_N_STR_TYPE_GPS; \ +} while ( 0 ) + + + /* * The macros below can be used to classify a receiver, * e.g. depending on the time source and/or depending on @@ -1581,9 +2594,20 @@ enum GPS_OSC_TYPES /** - * @brief Enumeration of device features flags reported in ::RECEIVER_INFO::features + * @brief Enumeration of device features flags reported in ::RI_FEATURES + * + * Used with ::RECEIVER_INFO::features. Each flags indicates if a device + * supports the associated feature, but due to the limited bit size of + * the ::RI_FEATURES type the number of these features is limited to 32. + * + * To extend the number of possible features the ::MBG_XFEATURE_BITS, the + * ::MBG_XFEATURE_BUFFER structure and associated definitions have been + * introduced, which are supported by devices which have ::GPS_HAS_XFEATURE + * set in ::RI_FEATURES. * - * Each flags indicates if a device supports the associated feature. + * @see ::RI_FEATURES + * @see ::MBG_XFEATURE_BITS + * @see ::MBG_XFEATURE_BUFFER */ enum GPS_FEATURE_BITS { @@ -1621,13 +2645,11 @@ enum GPS_FEATURE_BITS GPS_FEAT_VST, ///< supports VST (Versatile Storage) API and structures GPS_FEAT_SHS, ///< supports SHS (Secure Hybrid System) API and structures GPS_FEAT_XBP, ///< supports XBP (eXtended Binary Protocol) API and structures, see @ref group_xbp - // WARNING: There are no more unassigned feature bits available here. - // The MSB has to be reserved to indicate that a new, extended feature - // reporting scheme is supported, which still has to be defined. + GPS_FEAT_XFEATURE, ///< support eXtended features, see @ref group_xfeature + N_GPS_FEATURE ///< the number of known ::GPS_FEATURE_BITS, should now be at its limit, i.e. 32. - N_GPS_FEATURE ///< the number of known features - // If new features are added then care must be taken to update the associated - // definitions below accordingly, e.g. string initializers and bit masks. + // WARNING: There are no more unassigned feature bits available here. + // New features have to be defined using the ::MBG_XFEATURE_BITS }; @@ -1668,7 +2690,8 @@ enum GPS_FEATURE_BITS "Ext. Network Config", \ "Versatile Storage", \ "SHS", \ - "Extended Binary Protocol" \ + "Extended Binary Protocol", \ + "Extended Features" \ } @@ -1713,6 +2736,7 @@ enum GPS_FEATURE_BITS #define GPS_HAS_VST ( 1UL << GPS_FEAT_VST ) ///< see ::GPS_FEAT_VST #define GPS_HAS_SHS ( 1UL << GPS_FEAT_SHS ) ///< see ::GPS_FEAT_SHS #define GPS_HAS_XBP ( 1UL << GPS_FEAT_XBP ) ///< see ::GPS_FEAT_XBP +#define GPS_HAS_XFEATURE ( 1UL << GPS_FEAT_XFEATURE ) ///< see ::GPS_FEAT_XFEATURE // the next ones are special since they just shadow another flag: #define GPS_HAS_REF_OFFS GPS_HAS_IRIG_RX ///< always supported with IRIG inputs, see ::GPS_HAS_IRIG_RX @@ -1721,6 +2745,134 @@ enum GPS_FEATURE_BITS /** @} anchor GPS_FEATURE_MASKS */ +/** + * @defgroup group_xfeature Extended feature definitions + * + * @note These structures and definitions are only supported by a device + * if ::GPS_HAS_XFEATURE is set in ::RECEIVER_INFO::features. + * + * @{ */ + + +/** + * @brief The maximum number of feature bits supported by the MBG_XFEATURE API. + * + * Warning: Changing this number breaks API compatibility! + * + * @see ::MBG_XFEATURE_BITS + */ +#define MAX_XFEATURE_BITS 1024 + + + +/** + * @brief Enumeration of defined extended features. + * + * @see ::MBG_XFEATURE_NAMES + * @see ::MBG_XFEATURE_BUFFER + */ +enum MBG_XFEATURE_BITS +{ + MBG_XFEATURE_TLV_API, ///< Supports generic TLV API, see @ref group_tlv_api + MBG_XFEATURE_SAVE_CFG, ///< Supports the ::GPS_SAVE_CFG command + MBG_XFEATURE_LED_API, ///< Supports programmable LED API, see @ref group_led_api + MBG_XFEATURE_LNE_API, ///< Supports specific LNE API, see @ref group_lne_api + MBG_XFEATURE_PWR_CTL_API, ///< Supports power control, see @ref group_pwr_ctl_api + MBG_XFEATURE_EXT_SYS_INFO, ///< Supports extended revision information, see @ref group_ext_sys_info + MBG_XFEATURE_TRANSACTIONS, ///< Supports the ::GPS_BEGIN_TRANSACTION and ::GPS_END_TRANSACTION commands, see also ::MBG_TRANSACTION_TYPES + MBG_XFEATURE_REBOOT, ///< Supports the ::GPS_REBOOT command + MBG_XFEATURE_CLK_RES_INFO, ///< Supports the ::GPS_CLK_RES_INFO command, see @ref group_clk_res_info + MBG_XFEATURE_UCAP_NET, ///< Supports the ::GPS_UCAP_NET_GLB_INFO and ::GPS_UCAP_NET_RECV_INFO_IDX commands, see @ref group_ucap_net + MBG_XFEATURE_REQ_TTM, ///< Supports TTM requests via GPS_TIME command + MBG_XFEATURE_IO_PORTS, ///< Supports I/O port structures, see @ref group_io_ports + MBG_XFEATURE_MONITORING, ///< Supports monitoring / notifications, see @ref group_monitoring + MBG_XFEATURE_XHE, ///< Supports XHE external rubidium unit I/O commands + MBG_XFEATURE_USB_LOCK, ///< Supports USB interrupt structures, see @ref group_usb_lock + N_MBG_XFEATURE ///< Number of defined extended features + // NOTE If new features are appended here then an appropriate feature + // name string has to be appended to ::MBG_XFEATURE_NAMES, and care must + // be taken that ::N_MBG_XFEATURE doesn't exceed ::MAX_XFEATURE_BITS. +}; + + + +/** + * @brief Names of extended device features + * + * Can be used to initialize a string array of ::N_MBG_XFEATURE entries, + * so the number of strings must correspond to ::N_MBG_XFEATURE. + * + * @see ::MBG_XFEATURE_BITS + */ +#define MBG_XFEATURE_NAMES \ +{ \ + "Generic TLV API", \ + "Save Config On Card", \ + "Programmable LED API", \ + "LNE API", \ + "Power Control API", \ + "Extended Revision Info", \ + "Transaction commands", \ + "Reboot command", \ + "Clock Resolution Info", \ + "Extended User Captures", \ + "Request TTM", \ + "I/O Ports", \ + "Monitoring", \ + "XHE unit", \ + "USB lock" \ +} + + + +/** + * @brief Array size required to store all extended features + * + * The number of bytes required to store up to ::MAX_XFEATURE_BITS + * feature bits in a byte array. + */ +#define MAX_XFEATURE_BYTES ( MAX_XFEATURE_BITS / 8 ) + + + +/** + * @brief A structure used to store extended device features. + * + * Up to ::MAX_XFEATURE_BITS totally can be stored, but only + * ::N_MBG_XFEATURE extended features are currently defined. + * The ::_set_xfeature_bit macro should be used by the firmware + * to set a feature bit in the buffer, and the ::check_xfeature + * function should be used to implement API calls which test if an + * extended feature is supported. + * + * @see ::_set_xfeature_bit + * @see ::check_xfeature + */ +typedef struct +{ + uint8_t b[MAX_XFEATURE_BYTES]; + +} MBG_XFEATURE_BUFFER; + + + +/** + * @brief Set an extended feature bit in a ::MBG_XFEATURE_BUFFER + * + * Should be used by the firmware only to set one of the ::MBG_XFEATURE_BITS + * in an ::MBG_XFEATURE_BUFFER after power-up. + * + * @param[in] _xf_bit One of the ::MBG_XFEATURE_BITS + * @param[in] _xf_buffp Pointer to an ::MBG_XFEATURE_BUFFER + */ +#define _set_xfeature_bit( _xf_bit, _xf_buffp ) \ + _set_array_bit( _xf_bit, (_xf_buffp)->b, MAX_XFEATURE_BYTES ) + + +/** @} defgroup group_xfeature */ + + + /* * The features below are supported by default by older * C166 based GPS receivers: @@ -1773,11 +2925,7 @@ typedef union { CSUM csum; uint32_t fsize; - #if _IS_MBG_FIRMWARE - uint32_t start_addr; - #else - uint8_t *start_addr; - #endif + uint32_t start_addr; char name[FPGA_NAME_SIZE]; } hdr; @@ -1821,24 +2969,25 @@ typedef struct * the receiver's internal time. * * %UTC time differs from GPS time since a number of leap seconds have - * been inserted in the %UTC time scale after the GPS epoche. The number + * been inserted in the %UTC time scale after the GPS epoch. The number * of leap seconds is disseminated by the satellites using the ::UTC * parameter set, which also provides info on pending leap seconds. */ typedef struct { - uint16_t wn; ///< the week number since GPS has been installed + uint16_t wn; ///< the week number since the GPS system has been put into operation uint32_t sec; ///< the second of that week uint32_t tick; ///< fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units } T_GPS; #define _mbg_swab_t_gps( _p ) \ +do \ { \ _mbg_swab16( &(_p)->wn ); \ _mbg_swab32( &(_p)->sec ); \ _mbg_swab32( &(_p)->tick ); \ -} +} while ( 0 ) /** @@ -1871,13 +3020,14 @@ typedef struct } TM_GPS; #define _mbg_swab_tm_gps( _p ) \ +do \ { \ _mbg_swab16( &(_p)->year ); \ _mbg_swab16( &(_p)->yday ); \ _mbg_swab32( &(_p)->frac ); \ _mbg_swab32( &(_p)->offs_from_utc ); \ _mbg_swab16( &(_p)->status ); \ -} +} while ( 0 ) /** @@ -1902,9 +3052,9 @@ enum TM_GPS_STATUS_BITS TM_BIT_EXT_SYNC, ///< synchronized externally TM_BIT_HOLDOVER, ///< in holdover mode after previous synchronization TM_BIT_ANT_SHORT, ///< antenna cable short circuited - TM_BIT_NO_WARM, ///< OCXO has not warmed up + TM_BIT_NO_WARM, ///< oscillator control loop not settled TM_BIT_ANT_DISCONN, ///< antenna currently disconnected - TM_BIT_SYN_FLAG, ///< TIME_SYN output is low + TM_BIT_SYN_FLAG, ///< clock not synchronized, reflects the state of the "time sync error" output pin TM_BIT_NO_SYNC, ///< time sync actually not verified TM_BIT_NO_POS ///< position actually not verified, LOCK LED off }; @@ -1982,67 +3132,12 @@ typedef struct } TTM; #define _mbg_swab_ttm( _p ) \ +do \ { \ _mbg_swab16( &(_p)->channel ); \ _mbg_swab_t_gps( &(_p)->t ); \ _mbg_swab_tm_gps( &(_p)->tm ); \ -} - - - -/** - * @brief A timestamp with nanosecond resolution - * - * @note The secs field will roll over on 2038-01-19 03:14:07 - * if used for the number of seconds since 1970-01-01, just like - * 32 bit POSIX time_t. - * - * @see ::NANO_TIME_64 - */ -typedef struct -{ - // ATTENTION: - // This structure is and has has been used in public API calls for a long time, - // so even though the order of member fields is different than in NANO_TIME_64 - // this must *NOT* be changed, or API compatibility will get lost! - int32_t nano_secs; ///< [nanoseconds] - int32_t secs; ///< [seconds] - -} NANO_TIME; - -#define _mbg_swab_nano_time( _p ) \ -{ \ - _mbg_swab32( &(_p)->nano_secs ); \ - _mbg_swab32( &(_p)->secs ); \ -} - -// The macro below checks if a ::NANO_TIME value is negative. -#define _nano_time_negative( _nt ) \ - ( ( (_nt)->secs < 0 ) || ( (_nt)->nano_secs < 0 ) ) - - - -/** - * @brief A timestamp with nanosecond resolution, but 64 bit size - * - * @see ::NANO_TIME - */ -typedef struct -{ - // ATTENTION: - // This structure is and has been used in public API calls for a long time, - // so even though the order of member fields is different than in NANO_TIME - // this must *NOT* be changed, or API compatibility will get lost! - uint64_t secs; ///< [seconds] - uint64_t nano_secs; ///< [nanoseconds] - -} NANO_TIME_64; - -#define _mbg_swab_nano_time_64( _p ) \ -{ \ - _mbg_swab64( &(_p)->secs ); \ - _mbg_swab64( &(_p)->nano_secs ); \ -} +} while ( 0 ) @@ -2180,11 +3275,12 @@ typedef struct } SYNTH; #define _mbg_swab_synth( _p ) \ +do \ { \ _mbg_swab16( &(_p)->freq ); \ _mbg_swab16( &(_p)->range ); \ _mbg_swab16( &(_p)->phase ); \ -} +} while ( 0 ) /** @@ -2265,12 +3361,13 @@ typedef struct } TZDL; #define _mbg_swab_tzdl( _p ) \ +do \ { \ _mbg_swab32( &(_p)->offs ); \ _mbg_swab32( &(_p)->offs_dl ); \ _mbg_swab_tm_gps( &(_p)->tm_on ); \ _mbg_swab_tm_gps( &(_p)->tm_off ); \ -} +} while ( 0 ) /** @@ -2285,7 +3382,7 @@ typedef struct // Below there are some initializers for commonly used TZDL configurations: -#define DEFAULT_TZDL_AUTO_YEAR ( 2007 | DL_AUTO_FLAG ) +#define DEFAULT_TZDL_AUTO_YEAR ( (int16_t) ( 2007L | DL_AUTO_FLAG ) ) #define DEFAULt_TZDL_OFFS_DL 3600L ///< usually DST is +1 hour @@ -2423,12 +3520,13 @@ typedef struct } ANT_INFO; #define _mbg_swab_ant_info( _p ) \ +do \ { \ _mbg_swab16( &(_p)->status ); \ _mbg_swab_tm_gps( &(_p)->tm_disconn ); \ _mbg_swab_tm_gps( &(_p)->tm_reconn ); \ _mbg_swab32( &(_p)->delta_t ); \ -} +} while ( 0 ) /** @@ -2464,12 +3562,13 @@ typedef struct } ENABLE_FLAGS; #define _mbg_swab_enable_flags( _p ) \ +do \ { \ _mbg_swab16( &(_p)->serial ); \ _mbg_swab16( &(_p)->pulses ); \ _mbg_swab16( &(_p)->freq ); \ _mbg_swab16( &(_p)->synth ); \ -} +} while ( 0 ) /** @@ -2527,10 +3626,11 @@ enum ENABLE_FLAGS_CODES #define _mbg_swab_baud_rate( _p ) _mbg_swab32( _p ) #define _mbg_swab_com_parm( _p ) \ +do \ { \ _mbg_swab_baud_rate( &(_p)->baud_rate ); \ _mbg_swab16( &(_p)->handshake ); \ -} +} while ( 0 ) /** @@ -2827,10 +3927,11 @@ typedef struct } PORT_SETTINGS; #define _mbg_swab_port_settings( _p ) \ +do \ { \ _mbg_swab_com_parm( &(_p)->parm ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) /** @@ -2911,10 +4012,11 @@ typedef struct } PORT_SETTINGS_IDX; #define _mbg_swab_port_settings_idx( _p ) \ +do \ { \ _mbg_swab16( &(_p)->idx ); \ _mbg_swab_port_settings( &(_p)->port_settings ); \ -} +} while ( 0 ) /** @@ -2938,6 +4040,7 @@ typedef struct } PORT_INFO; #define _mbg_swab_port_info( _p ) \ +do \ { \ _mbg_swab_port_settings( &(_p)->port_settings ); \ _mbg_swab32( &(_p)->supp_baud_rates ); \ @@ -2945,7 +4048,7 @@ typedef struct _mbg_swab32( &(_p)->supp_str_types ); \ _mbg_swab32( &(_p)->reserved ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) /** @@ -2992,10 +4095,11 @@ typedef struct } PORT_INFO_IDX; #define _mbg_swab_port_info_idx( _p ) \ +do \ { \ _mbg_swab16( &(_p)->idx ); \ _mbg_swab_port_info( &(_p)->port_info ); \ -} +} while ( 0 ) /** @@ -3020,10 +4124,11 @@ typedef struct } STR_TYPE_INFO; #define _mbg_swab_str_type_info( _p ) \ +do \ { \ _mbg_swab32( &(_p)->supp_modes ); \ _mbg_swab16( &(_p)->flags ); \ -} +} while ( 0 ) @@ -3046,10 +4151,11 @@ typedef struct } STR_TYPE_INFO_IDX; #define _mbg_swab_str_type_info_idx( _p ) \ +do \ { \ _mbg_swab16( &(_p)->idx ); \ _mbg_swab_str_type_info( &(_p)->str_type_info ); \ -} +} while ( 0 ) /** @@ -3158,6 +4264,52 @@ enum STR_MODE_MASKS +/** + * @brief The number of string types supported by legacy DCF77 receivers + * + * For receivers supporting a ::RECEIVER_INFO this should be determined + * from ::RECEIVER_INFO::n_str_type. + * + * @see ::DEFAULT_SUPP_STR_TYPES_DCF + */ +#define DEFAULT_N_STR_TYPE_DCF 1 + +/** + * @brief Bit mask of string types supported by legacy DCF77 receivers + * + * For receivers supporting a ::RECEIVER_INFO this should be determined + * from ::PORT_INFO::supp_str_types. + * + * @see ::DEFAULT_N_STR_TYPE_DCF + */ +#define DEFAULT_SUPP_STR_TYPES_DCF \ + ( ( 1UL << DEFAULT_N_STR_TYPE_DCF ) - 1 ) + + + +/** + * @brief The number of string types supported by legacy GPS receivers + * + * For receivers supporting a ::RECEIVER_INFO this should be determined + * from ::RECEIVER_INFO::n_str_type. + * + * @see ::DEFAULT_SUPP_STR_TYPES_GPS + */ +#define DEFAULT_N_STR_TYPE_GPS 2 + +/** + * @brief Bit mask of string types supported by legacy GPS receivers + * + * For receivers supporting a ::RECEIVER_INFO this should be determined + * from ::PORT_INFO::supp_str_types. + * + * @see ::DEFAULT_N_STR_TYPE_GPS + */ +#define DEFAULT_SUPP_STR_TYPES_GPS \ + ( ( 1UL << DEFAULT_N_STR_TYPE_GPS ) - 1 ) + + + /* * The number of serial ports which are at least available * even with very old GPS receiver models. For devices providing @@ -3188,6 +4340,7 @@ typedef struct } PORT_PARM; #define _mbg_swab_port_parm( _p ) \ +do \ { \ int i; \ for ( i = 0; i < DEFAULT_N_COM; i++ ) \ @@ -3195,7 +4348,7 @@ typedef struct _mbg_swab_com_parm( &(_p)->com[i] ); \ /* no need to swap mode byte */ \ } \ -} +} while ( 0 ) /** @@ -3236,6 +4389,50 @@ enum * well defined extensions like the year number, local time offset, DST status, * etc., in the control fields: * + * The following specification can be found in IRIG Standard 200-04 (September 2004): + * + * Format A: 1k pps + * Format B: 100 pps + * Format D: 1 ppm + * Format E: 10 pps + * Format G: 10k pps + * Format H: 1 pps + * + * 1st digit: Modulation Frequency + * 0 Pulse width code + * 1 Sine wave, amplitude modulated + * 2 Manchester modulated + * + * 2nd digit: Frequency / Resolution + * 0: No carrier / index count interval + * 1: 100 Hz / 10 ms + * 2: 1 kHz / 1 ms + * 3: 10 kHz / 0.1 ms + * 4: 100 kHz / 10 ms + * 5: 1 MHz / 1 ms + * + * 3rd digit: Coded expressions + * 0: DOY+TOD, CF, SBS + * 1: DOY+TOD, CF + * 2: DOY+TOD + * 3: DOY+TOD, SBS + * 4: DOY+TOD, Year, CF, SBS + * 5: DOY+TOD, Year, CF + * 6: DOY+TOD, Year + * 7: DOY+TOD, Year, SBS + * + * + * Table of Permissible Code Formats + * + * Letter 1st digit 2nd digit 3rd digit + * ---------------------------------------------- + * A 0,1,2 0,3,4,5 0,1,2,3,4,5,6,7 + * B 0,1,2 0,2,3,4,5 0,1,2,3,4,5,6,7 + * D 0,1 0,1,2 1,2 + * E 0,1 0,1,2 1,2,5,6 + * G 0,1,2 0,4,5 1,2,5,6 + * H 0,1 0,1,2 1,2 + * * - Known IRIG signal code types: * - \b A002: 1000 bps, DCLS, time-of-year * - \b A003: 1000 bps, DCLS, time-of-year, SBS @@ -3324,38 +4521,42 @@ enum ICODE_TX_CODES ICODE_TX_TXC101, ICODE_TX_E002_E112, ICODE_TX_NASA36, + ICODE_TX_A006_A136, + ICODE_TX_A007_A137, N_ICODE_TX ///< number of known codes }; /** - * @brief Initializers for timecode format name strings + * @brief Initializers for TX timecode format name strings * * @see ::ICODE_TX_CODES */ -#define DEFAULT_ICODE_TX_NAMES \ -{ \ - "B002+B122", \ - "B003+B123", \ - "A002+A132", \ - "A003+A133", \ - "AFNOR NF S87-500", \ - "IEEE1344", \ - "B220(1344) DCLS", \ - "B222 DCLS", \ - "B223 DCLS", \ - "B006+B126", \ - "B007+B127", \ - "G002+G142", \ - "G006+G146", \ - "C37.118", \ - "TXC-101 DTR-6", \ - "E002+E112", \ - "NASA 36" \ -} - -/** - * @brief Initializers for short timecode format name strings +#define DEFAULT_ICODE_TX_NAMES \ +{ \ + /* B002_B122 */ "B002+B122", \ + /* B003_B123 */ "B003+B123", \ + /* A002_A132 */ "A002+A132", \ + /* A003_A133 */ "A003+A133", \ + /* AFNOR */ "AFNOR NF S87-500", \ + /* IEEE1344 */ "IEEE 1344", \ + /* B2201344 */ "B220(1344) DCLS", \ + /* B222 */ "B222 DCLS", \ + /* B223 */ "B223 DCLS", \ + /* B006_B126 */ "B006+B126", \ + /* B007_B127 */ "B007+B127", \ + /* G002_G142 */ "G002+G142", \ + /* G006_G146 */ "G006+G146", \ + /* C37118 */ "IEEE C37.118", \ + /* TXC101 */ "TXC-101 DTR-6", \ + /* E002_E112 */ "E002+E112", \ + /* NASA36 */ "NASA 36", \ + /* A006_A136 */ "A006+A136", \ + /* A007_A137 */ "A007+A137" \ +} + +/** + * @brief Initializers for short TX timecode format name strings * * @note Must not be longer than 10 printable characters * @@ -3363,55 +4564,59 @@ enum ICODE_TX_CODES */ #define DEFAULT_ICODE_TX_NAMES_SHORT \ { \ - "B002+B122", \ - "B003+B123", \ - "A002+A132", \ - "A003+A133", \ - "AFNOR NF S", \ - "IEEE1344", \ - "B220/1344", \ - "B222 DC", \ - "B223 DC", \ - "B006+B126", \ - "B007+B127", \ - "G002+G142", \ - "G006+G146", \ - "C37.118", \ - "TXC-101", \ - "E002+E112", \ - "NASA 36" \ + /* B002_B122 */ "B002+B122", \ + /* B003_B123 */ "B003+B123", \ + /* A002_A132 */ "A002+A132", \ + /* A003_A133 */ "A003+A133", \ + /* AFNOR */ "AFNOR NF S", \ + /* IEEE1344 */ "IEEE 1344", \ + /* B2201344 */ "B220/1344", \ + /* B222 */ "B222 DC", \ + /* B223 */ "B223 DC", \ + /* B006_B126 */ "B006+B126", \ + /* B007_B127 */ "B007+B127", \ + /* G002_G142 */ "G002+G142", \ + /* G006_G146 */ "G006+G146", \ + /* C37118 */ "C37.118", \ + /* TXC101 */ "TXC-101", \ + /* E002_E112 */ "E002+E112", \ + /* NASA36 */ "NASA 36", \ + /* A006_A136 */ "A006+A136", \ + /* A007_A137 */ "A007+A137" \ } /** - * @brief Initializers for English format description strings + * @brief Initializers for English TX format description strings * * @see ::ICODE_TX_CODES */ -#define DEFAULT_ICODE_TX_DESCRIPTIONS_ENG \ -{ \ - "100 bps, DCLS or 1 kHz carrier", \ - "100 bps, DCLS or 1 kHz carrier, SBS", \ - "1000 bps, DCLS or 10 kHz carrier", \ - "1000 bps, DCLS or 10 kHz carrier, SBS", \ - "100 bps, DCLS or 1 kHz carrier, SBS, complete date", \ - "100 bps, DCLS or 1 kHz carrier, SBS, complete date, time zone info", \ - "100 bps, Manchester enc., DCLS only, SBS, complete date, time zone info", \ - "100 bps, Manchester enc., DCLS only", \ - "100 bps, Manchester enc., DCLS only, SBS", \ - "100 bps, DCLS or 1 kHz carrier, complete date", \ - "100 bps, DCLS or 1 kHz carrier, complete date, SBS", \ - "10 kbps, DCLS or 100 kHz carrier", \ - "10 kbps, DCLS or 100 kHz carrier, complete date", \ - "like IEEE1344, but UTC offset with reversed sign", \ - "code from TV time sync device TXC-101 DTR-6", \ - "10 bps, DCLS or 100 Hz carrier", \ - "100 bps, DCLS or 1 kHz carrier" \ +#define DEFAULT_ICODE_TX_DESCRIPTIONS_ENG \ +{ \ + /* B002_B122 */ "100 bps, DCLS or 1 kHz carrier", \ + /* B003_B123 */ "100 bps, DCLS or 1 kHz carrier, SBS", \ + /* A002_A132 */ "1000 bps, DCLS or 10 kHz carrier", \ + /* A003_A133 */ "1000 bps, DCLS or 10 kHz carrier, SBS", \ + /* AFNOR */ "100 bps, DCLS or 1 kHz carrier, complete date, SBS", \ + /* IEEE1344 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number, SBS, UTC offset, DST and Leap sec status", \ + /* B2201344 */ "100 bps, Manchester enc., DCLS only, 2 digit year number, SBS, UTC offset, DST and Leap sec status", \ + /* B222 */ "100 bps, Manchester enc., DCLS only", \ + /* B223 */ "100 bps, Manchester enc., DCLS only, SBS", \ + /* B006_B126 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number", \ + /* B007_B127 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number, SBS", \ + /* G002_G142 */ "10 kbps, DCLS or 100 kHz carrier", \ + /* G006_G146 */ "10 kbps, DCLS or 100 kHz carrier, 2 digit year number", \ + /* C37118 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number, SBS, UTC offs. reverse to 1344, DST/Leap sec status", \ + /* TXC101 */ "code from TV time sync device TXC-101 DTR-6", \ + /* E002_E112 */ "10 bps, DCLS or 100 Hz carrier", \ + /* NASA36 */ "100 bps, DCLS or 1 kHz carrier", \ + /* A006_A136 */ "1000 bps, DCLS or 10 kHz carrier, 2 digit year number", \ + /* A007_A137 */ "1000 bps, DCLS or 10 kHz carrier, 2 digit year number, SBS" \ } /** - * @brief Bit masks used with ::IRIG_INFO::supp_codes + * @brief Bit masks used with ::IRIG_INFO::supp_codes for TX * * These bit masks are used with timecode receivers only * @@ -3438,12 +4643,14 @@ enum ICODE_TX_CODES #define MSK_ICODE_TX_TXC101 ( 1UL << ICODE_TX_TXC101 ) #define MSK_ICODE_TX_E002_E112 ( 1UL << ICODE_TX_E002_E112 ) #define MSK_ICODE_TX_NASA36 ( 1UL << ICODE_TX_NASA36 ) +#define MSK_ICODE_TX_A006_A136 ( 1UL << ICODE_TX_A006_A136 ) +#define MSK_ICODE_TX_A007_A137 ( 1UL << ICODE_TX_A007_A137 ) /** @} anchor ICODE_TX_MASKS */ /** - * @brief A mask of IRIG formats with manchester encoded DC output + * @brief A mask of IRIG TX formats with manchester encoded DC output */ #define MSK_ICODE_TX_DC_MANCH \ ( \ @@ -3453,7 +4660,7 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats with 100 Hz carrier + * @brief A mask of IRIG TX formats with 100 Hz carrier */ #define MSK_ICODE_TX_100HZ \ ( \ @@ -3461,7 +4668,7 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats with 1 kHz carrier + * @brief A mask of IRIG TX formats with 1 kHz carrier */ #define MSK_ICODE_TX_1KHZ \ ( \ @@ -3479,16 +4686,18 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats with 10 kHz carrier + * @brief A mask of IRIG TX formats with 10 kHz carrier */ #define MSK_ICODE_TX_10KHZ \ ( \ MSK_ICODE_TX_A002_A132 | \ - MSK_ICODE_TX_A003_A133 \ + MSK_ICODE_TX_A003_A133 | \ + MSK_ICODE_TX_A006_A136 | \ + MSK_ICODE_TX_A007_A137 \ ) /** - * @brief A mask of IRIG formats with 100 kHz carrier + * @brief A mask of IRIG TX formats with 100 kHz carrier */ #define MSK_ICODE_TX_100KHZ \ ( \ @@ -3497,7 +4706,7 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats with 10 bps data rate + * @brief A mask of IRIG TX formats with 10 bps data rate */ #define MSK_ICODE_TX_10BPS \ ( \ @@ -3505,7 +4714,7 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats with 100 bps data rate + * @brief A mask of IRIG TX formats with 100 bps data rate */ #define MSK_ICODE_TX_100BPS \ ( \ @@ -3519,16 +4728,18 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats with 1000 bps data rate + * @brief A mask of IRIG TX formats with 1000 bps data rate */ #define MSK_ICODE_TX_1000BPS \ ( \ MSK_ICODE_TX_A002_A132 | \ - MSK_ICODE_TX_A003_A133 \ + MSK_ICODE_TX_A003_A133 | \ + MSK_ICODE_TX_A006_A136 | \ + MSK_ICODE_TX_A007_A137 \ ) /** - * @brief A mask of IRIG formats with 10 kbps data rate + * @brief A mask of IRIG TX formats with 10 kbps data rate */ #define MSK_ICODE_TX_10000BPS \ ( \ @@ -3537,18 +4748,20 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats supporting 10ths of seconds + * @brief A mask of IRIG TX formats supporting 10ths of seconds */ #define MSK_ICODE_TX_HAS_SEC10THS \ ( \ MSK_ICODE_TX_A002_A132 | \ MSK_ICODE_TX_A003_A133 | \ MSK_ICODE_TX_G002_G142 | \ - MSK_ICODE_TX_G006_G146 \ + MSK_ICODE_TX_G006_G146 | \ + MSK_ICODE_TX_A006_A136 | \ + MSK_ICODE_TX_A007_A137 \ ) /** - * @brief A mask of IRIG formats supporting 100ths of seconds + * @brief A mask of IRIG TX formats supporting 100ths of seconds */ #define MSK_ICODE_TX_HAS_SEC100THS \ ( \ @@ -3557,19 +4770,33 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats supporting a 2 digit year number + * @brief A mask of IRIG TX formats supporting a 2 digit year number */ #define MSK_ICODE_TX_HAS_SHORT_YEAR \ ( \ MSK_ICODE_TX_AFNOR | \ MSK_ICODE_TX_IEEE1344 | \ + MSK_ICODE_TX_B2201344 | \ MSK_ICODE_TX_B006_B126 | \ MSK_ICODE_TX_B007_B127 | \ - MSK_ICODE_TX_C37118 \ + MSK_ICODE_TX_G006_G146 | \ + MSK_ICODE_TX_C37118 | \ + MSK_ICODE_TX_A006_A136 | \ + MSK_ICODE_TX_A007_A137 \ ) /** - * @brief A mask of IRIG formats supporting TFOM + * @brief A mask of IRIG TX formats supporting a 2 digit year number + * + * This is after the P6 identifier. + */ + #define MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P6 \ +( \ + MSK_ICODE_TX_G006_G146 \ +) + +/** + * @brief A mask of IRIG TX formats supporting TFOM */ #define MSK_ICODE_TX_HAS_TFOM \ ( \ @@ -3578,7 +4805,7 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats supporting CTQ continuous time quality + * @brief A mask of IRIG TX formats supporting CTQ continuous time quality * * This has been introduced in IEEE C37.118.1-2011 */ @@ -3589,7 +4816,7 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats supporting time zone information + * @brief A mask of IRIG TX formats supporting time zone information */ #define MSK_ICODE_TX_HAS_TZI \ ( \ @@ -3598,7 +4825,7 @@ enum ICODE_TX_CODES ) /** - * @brief IRIG formats where UTC offset must be subtracted to yield UTC + * @brief IRIG TX formats where UTC offset must be subtracted to yield UTC * * A mask of IRIG formats where the decoded UTC offset must be * subtracted from the time decoded from the IRIG signal to yield UTC, e.g.:<br> @@ -3610,7 +4837,7 @@ enum ICODE_TX_CODES ) /** - * @brief IRIG formats where UTC offset must be added to yield UTC + * @brief IRIG TX formats where UTC offset must be added to yield UTC * * A mask of IRIG formats where the decoded UTC offset must be * added to the time decoded from the IRIG signal to yield UTC, e.g.:<br> @@ -3622,7 +4849,7 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats supporting a day of week number + * @brief A mask of IRIG TX formats supporting a day of week number */ #define MSK_ICODE_TX_HAS_AFNOR_WDAY \ ( \ @@ -3631,7 +4858,7 @@ enum ICODE_TX_CODES ) /** - * @brief A mask of IRIG formats supporting a date (day-of-month, month) + * @brief A mask of IRIG TX formats supporting a date (day-of-month, month) */ #define MSK_ICODE_TX_HAS_AFNOR_DATE \ ( \ @@ -3641,7 +4868,7 @@ enum ICODE_TX_CODES /** - * @brief The default mask of IRIG formats supported by IRIG transmitters + * @brief The default mask of IRIG TX formats supported by IRIG transmitters * * @note The formats which are actually supported should be retrieved * from the device @@ -3683,8 +4910,8 @@ enum ICODE_RX_CODES ICODE_RX_IEEE1344_DC, ///< DCLS ICODE_RX_B126_B127, ///< modulated ICODE_RX_B006_B007, ///< DCLS - ICODE_RX_G142_G146, ///< modulated - ICODE_RX_G002_G006, ///< DCLS + ICODE_RX_G142, ///< modulated (G143 is undefined, SBS not supported with Gxxx) + ICODE_RX_G002, ///< DCLS (G003 is undefined, SBS not supported with Gxxx) ICODE_RX_C37118, ///< modulated ICODE_RX_C37118_DC, ///< DCLS ICODE_RX_TXC101, ///< modulated @@ -3693,101 +4920,117 @@ enum ICODE_RX_CODES ICODE_RX_E002, ///< DCLS ICODE_RX_NASA36, ///< modulated ICODE_RX_NASA36_DC, ///< DCLS + ICODE_RX_A136_A137, ///< modulated + ICODE_RX_A006_A007, ///< DCLS + ICODE_RX_G146, ///< modulated (G147 is undefined, SBS not supported with Gxxx) + ICODE_RX_G006, ///< DCLS (G007 is undefined, SBS not supported with Gxxx) N_ICODE_RX ///< the number of known codes }; /** - * @brief Initializers for timecode format name strings + * @brief Initializers for RX timecode format name strings * * @see ::ICODE_RX_CODES */ #define DEFAULT_ICODE_RX_NAMES \ { \ - "B122/B123", \ - "A132/A133", \ - "B002/B003 (DCLS)", \ - "A002/A003 (DCLS)", \ - "AFNOR NF S87-500", \ - "AFNOR NF S87-500 (DCLS)", \ - "IEEE1344", \ - "IEEE1344 (DCLS)", \ - "B126/B127", \ - "B006/B007 (DCLS)", \ - "G142/G146", \ - "G002/G006 (DCLS)", \ - "C37.118", \ - "C37.118 (DCLS)", \ - "TXC-101 DTR-6", \ - "TXC-101 DTR-6 (DCLS)", \ - "E112", \ - "E002 (DCLS)", \ - "NASA-36", \ - "NASA-36 (DCLS)" \ -} - -/** - * @brief Initializers for short timecode format name strings + /* B122_B123 */ "B122/B123", \ + /* A132_A133 */ "A132/A133", \ + /* B002_B003 */ "B002/B003 (DCLS)", \ + /* A002_A003 */ "A002/A003 (DCLS)", \ + /* AFNOR */ "AFNOR NF S87-500", \ + /* AFNOR_DC */ "AFNOR NF S87-500 (DCLS)", \ + /* IEEE1344 */ "IEEE1344", \ + /* IEEE1344_DC */ "IEEE1344 (DCLS)", \ + /* B126_B127 */ "B126/B127", \ + /* B006_B007 */ "B006/B007 (DCLS)", \ + /* G142 */ "G142", \ + /* G002 */ "G002 (DCLS)", \ + /* C37118 */ "C37.118", \ + /* C37118_DC */ "C37.118 (DCLS)", \ + /* TXC101 */ "TXC-101 DTR-6", \ + /* TXC101_DC */ "TXC-101 DTR-6 (DCLS)", \ + /* E112 */ "E112", \ + /* E002 */ "E002 (DCLS)", \ + /* NASA36 */ "NASA-36", \ + /* NASA36_DC */ "NASA-36 (DCLS)", \ + /* A136_A137 */ "A136/A137", \ + /* A006_A007 */ "A006/A007 (DCLS)", \ + /* G146 */ "G146", \ + /* G006 */ "G006 (DCLS)" \ +} + +/** + * @brief Initializers for short RX timecode format name strings * * @note Must not be longer than 11 printable characters * * @see ::ICODE_RX_CODES */ -#define DEFAULT_ICODE_RX_NAMES_SHORT \ -{ \ - "B122/B123", \ - "A132/A133", \ - "B002/B003", \ - "A002/A003", \ - "AFNOR NF S", \ - "AFNOR DC", \ - "IEEE1344", \ - "IEEE1344 DC", \ - "B126/B127", \ - "B006/B007", \ - "G142/G146", \ - "G002/G006", \ - "C37.118", \ - "C37.118 DC", \ - "TXC-101", \ - "TXC-101 DC", \ - "E112", \ - "E002 DC", \ - "NASA-36", \ - "NASA-36 DC" \ -} - - -/** - * @brief Initializers for English format description strings +#define DEFAULT_ICODE_RX_NAMES_SHORT \ +{ \ + /* B122_B123 */ "B122/B123", \ + /* A132_A133 */ "A132/A133", \ + /* B002_B003 */ "B002/B003", \ + /* A002_A003 */ "A002/A003", \ + /* AFNOR */ "AFNOR NF S", \ + /* AFNOR_DC */ "AFNOR DC", \ + /* IEEE1344 */ "IEEE1344", \ + /* IEEE1344_DC */ "IEEE1344 DC", \ + /* B126_B127 */ "B126/B127", \ + /* B006_B007 */ "B006/B007", \ + /* G142 */ "G142", \ + /* G002 */ "G002 DC", \ + /* C37118 */ "C37.118", \ + /* C37118_DC */ "C37.118 DC", \ + /* TXC101 */ "TXC-101", \ + /* TXC101_DC */ "TXC-101 DC", \ + /* E112 */ "E112", \ + /* E002 */ "E002 DC", \ + /* NASA36 */ "NASA-36", \ + /* NASA36_DC */ "NASA-36 DC", \ + /* A136_A137 */ "A136/A137", \ + /* A006_A007 */ "A006/A007", \ + /* G146 */ "G146", \ + /* G006 */ "G006 DC" \ +} + + +/** + * @brief Initializers for English RX format description strings * * @see ::ICODE_RX_CODES */ -#define DEFAULT_ICODE_RX_DESCRIPTIONS_ENG \ -{ \ - "100 bps, 1 kHz carrier, SBS optionally", \ - "1000 bps, 10 kHz carrier, SBS optionally", \ - "100 bps, DCLS, SBS optionally", \ - "1000 bps, DCLS, SBS optionally", \ - "100 bps, 1 kHz carrier, SBS, complete date", \ - "100 bps, DCLS, SBS, complete date", \ - "100 bps, 1 kHz carrier, SBS, time zone info", \ - "100 bps, DCLS, SBS, time zone info", \ - "100 bps, 1 kHz carrier, complete date, SBS optionally", \ - "100 bps, DCLS, complete date, SBS optionally", \ - "10 kbps, 100 kHz carrier, complete date optionally", \ - "10 kbps, DCLS, complete date optionally", \ - "like IEEE1344, but UTC offset with reversed sign", \ - "like IEEE1344 DC, but UTC offset with reversed sign", \ - "code from TV time sync device TXC-101 DTR-6", \ - "DC code from TV time sync device TXC-101 DTR-6", \ - "10 bps, 100 Hz carrier", \ - "10 bps, DCLS", \ - "100 bps, 1 kHz carrier", \ - "100 bps, DCLS" \ -} - -/** - * @brief Bit masks used with ::IRIG_INFO::supp_codes +#define DEFAULT_ICODE_RX_DESCRIPTIONS_ENG \ +{ \ + /* B122_B123 */ "100 bps, 1 kHz carrier, SBS optionally", \ + /* A132_A133 */ "1000 bps, 10 kHz carrier, SBS optionally", \ + /* B002_B003 */ "100 bps, DCLS, SBS optionally", \ + /* A002_A003 */ "1000 bps, DCLS, SBS optionally", \ + /* AFNOR */ "100 bps, 1 kHz carrier, complete date, SBS", \ + /* AFNOR_DC */ "100 bps, DCLS, complete date, SBS", \ + /* IEEE1344 */ "100 bps, 1 kHz carrier, SBS, time zone info", \ + /* IEEE1344_DC */ "100 bps, DCLS, SBS, time zone info", \ + /* B126_B127 */ "100 bps, 1 kHz carrier, 2 digit year number, SBS optionally", \ + /* B006_B007 */ "100 bps, DCLS, 2 digit year number, SBS optionally", \ + /* G142 */ "10 kbps, 100 kHz carrier", \ + /* G002 */ "10 kbps, DCLS", \ + /* C37118 */ "like IEEE1344, but UTC offset with reversed sign", \ + /* C37118_DC */ "like IEEE1344 DC, but UTC offset with reversed sign", \ + /* TXC101 */ "code from TV time sync device TXC-101 DTR-6", \ + /* TXC101_DC */ "DC code from TV time sync device TXC-101 DTR-6", \ + /* E112 */ "10 bps, 100 Hz carrier", \ + /* E002 */ "10 bps, DCLS", \ + /* NASA36 */ "100 bps, 1 kHz carrier", \ + /* NASA36_DC */ "100 bps, DCLS", \ + /* A136_A137 */ "1000 bps, 10 kHz carrier, 2 digit year number, SBS optionally", \ + /* A006_A007 */ "1000 bps, DCLS, 2 digit year number, SBS optionally", \ + /* G146 */ "10 kbps, 100 kHz carrier, 2 digit year number", \ + /* G006 */ "10 kbps, DCLS, 2 digit year number" \ +} + +/** + * @brief Bit masks used with ::IRIG_INFO::supp_codes for RX * * These bit masks are used with timecode receivers only * @@ -3807,8 +5050,8 @@ enum ICODE_RX_CODES #define MSK_ICODE_RX_IEEE1344_DC ( 1UL << ICODE_RX_IEEE1344_DC ) #define MSK_ICODE_RX_B126_B127 ( 1UL << ICODE_RX_B126_B127 ) #define MSK_ICODE_RX_B006_B007 ( 1UL << ICODE_RX_B006_B007 ) -#define MSK_ICODE_RX_G142_G146 ( 1UL << ICODE_RX_G142_G146 ) -#define MSK_ICODE_RX_G002_G006 ( 1UL << ICODE_RX_G002_G006 ) +#define MSK_ICODE_RX_G142 ( 1UL << ICODE_RX_G142 ) +#define MSK_ICODE_RX_G002 ( 1UL << ICODE_RX_G002 ) #define MSK_ICODE_RX_C37118 ( 1UL << ICODE_RX_C37118 ) #define MSK_ICODE_RX_C37118_DC ( 1UL << ICODE_RX_C37118_DC ) #define MSK_ICODE_RX_TXC101 ( 1UL << ICODE_RX_TXC101 ) @@ -3817,12 +5060,16 @@ enum ICODE_RX_CODES #define MSK_ICODE_RX_E002 ( 1UL << ICODE_RX_E002 ) #define MSK_ICODE_RX_NASA36 ( 1UL << ICODE_RX_NASA36 ) #define MSK_ICODE_RX_NASA36_DC ( 1UL << ICODE_RX_NASA36_DC ) +#define MSK_ICODE_RX_A136_A137 ( 1UL << ICODE_RX_A136_A137 ) +#define MSK_ICODE_RX_A006_A007 ( 1UL << ICODE_RX_A006_A007 ) +#define MSK_ICODE_RX_G146 ( 1UL << ICODE_RX_G146 ) +#define MSK_ICODE_RX_G006 ( 1UL << ICODE_RX_G006 ) /** @} anchor ICODE_RX_MASKS */ /** - * @brief A mask of IRIG DCLS formats + * @brief A mask of IRIG RX DCLS formats */ #define MSK_ICODE_RX_DC \ ( \ @@ -3831,24 +5078,25 @@ enum ICODE_RX_CODES MSK_ICODE_RX_AFNOR_DC | \ MSK_ICODE_RX_IEEE1344_DC | \ MSK_ICODE_RX_B006_B007 | \ - MSK_ICODE_RX_G002_G006 | \ + MSK_ICODE_RX_G002 | \ MSK_ICODE_RX_C37118_DC | \ MSK_ICODE_RX_TXC101_DC | \ MSK_ICODE_RX_E002 | \ - MSK_ICODE_RX_NASA36_DC \ + MSK_ICODE_RX_NASA36_DC | \ + MSK_ICODE_RX_A006_A007 | \ + MSK_ICODE_RX_G006 \ ) /** - * @brief A mask of IRIG formats with 100 Hz carrier + * @brief A mask of IRIG RX formats with 100 Hz carrier */ #define MSK_ICODE_RX_100HZ \ ( \ - MSK_ICODE_RX_E112 | \ - MSK_ICODE_RX_E002 \ + MSK_ICODE_RX_E112 \ ) /** - * @brief A mask of IRIG formats with 1 kHz carrier + * @brief A mask of IRIG RX formats with 1 kHz carrier */ #define MSK_ICODE_RX_1KHZ \ ( \ @@ -3862,23 +5110,25 @@ enum ICODE_RX_CODES ) /** - * @brief A mask of IRIG formats with 10 kHz carrier + * @brief A mask of IRIG RX formats with 10 kHz carrier */ #define MSK_ICODE_RX_10KHZ \ ( \ - MSK_ICODE_RX_A132_A133 \ + MSK_ICODE_RX_A132_A133 | \ + MSK_ICODE_RX_A136_A137 \ ) /** - * @brief A mask of IRIG formats with 100 kHz carrier + * @brief A mask of IRIG RX formats with 100 kHz carrier */ #define MSK_ICODE_RX_100KHZ \ ( \ - MSK_ICODE_RX_G142_G146 \ + MSK_ICODE_RX_G142 | \ + MSK_ICODE_RX_G146 \ ) /** - * @brief A mask of IRIG formats with 10 bps data rate + * @brief A mask of IRIG RX formats with 10 bps data rate */ #define MSK_ICODE_RX_10BPS \ ( \ @@ -3887,7 +5137,7 @@ enum ICODE_RX_CODES ) /** - * @brief A mask of IRIG formats with 100 bps data rate + * @brief A mask of IRIG RX formats with 100 bps data rate */ #define MSK_ICODE_RX_100BPS \ ( \ @@ -3908,60 +5158,110 @@ enum ICODE_RX_CODES ) /** - * @brief A mask of IRIG formats with 1000 bps data rate + * @brief A mask of IRIG RX formats with 1000 bps data rate */ #define MSK_ICODE_RX_1000BPS \ ( \ MSK_ICODE_RX_A132_A133 | \ - MSK_ICODE_RX_A002_A003 \ + MSK_ICODE_RX_A002_A003 | \ + MSK_ICODE_RX_A136_A137 | \ + MSK_ICODE_RX_A006_A007 \ ) /** - * @brief A mask of IRIG formats with 10 kbps data rate + * @brief A mask of IRIG RX formats with 10 kbps data rate */ #define MSK_ICODE_RX_10000BPS \ ( \ - MSK_ICODE_RX_G142_G146 | \ - MSK_ICODE_RX_G002_G006 \ + MSK_ICODE_RX_G142 | \ + MSK_ICODE_RX_G002 | \ + MSK_ICODE_RX_G146 | \ + MSK_ICODE_RX_G006 \ ) /** - * @brief A mask of IRIG formats supporting 10ths of seconds + * @brief A mask of IRIG RX formats supporting 10ths of seconds */ #define MSK_ICODE_RX_HAS_SEC10THS \ ( \ MSK_ICODE_RX_A132_A133 | \ MSK_ICODE_RX_A002_A003 | \ - MSK_ICODE_RX_G142_G146 | \ - MSK_ICODE_RX_G002_G006 \ + MSK_ICODE_RX_G142 | \ + MSK_ICODE_RX_G002 | \ + MSK_ICODE_RX_A136_A137 | \ + MSK_ICODE_RX_A006_A007 | \ + MSK_ICODE_RX_G146 | \ + MSK_ICODE_RX_G006 \ ) /** - * @brief A mask of IRIG formats which support 100ths of seconds + * @brief A mask of IRIG RX formats which support 100ths of seconds */ #define MSK_ICODE_RX_HAS_SEC100THS \ ( \ - MSK_ICODE_RX_G142_G146 | \ - MSK_ICODE_RX_G002_G006 \ + MSK_ICODE_RX_G142 | \ + MSK_ICODE_RX_G002 | \ + MSK_ICODE_RX_G146 | \ + MSK_ICODE_RX_G006 \ ) /** - * @brief A mask of IRIG formats supporting a 2 digit year number + * @brief A mask of IRIG RX formats supporting a 2 digit year number after P5 + * + * Note: This macro specifies ONLY the codes where the year number + * is transmitted after position identifier P5. + * + * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 + * @see ::MSK_ICODE_RX_HAS_ANY_SHORT_YEAR */ -#define MSK_ICODE_RX_HAS_SHORT_YEAR \ -( \ - MSK_ICODE_RX_AFNOR | \ - MSK_ICODE_RX_AFNOR_DC | \ - MSK_ICODE_RX_IEEE1344 | \ - MSK_ICODE_RX_IEEE1344_DC | \ - MSK_ICODE_RX_B126_B127 | \ - MSK_ICODE_RX_B006_B007 | \ - MSK_ICODE_RX_C37118 | \ - MSK_ICODE_RX_C37118_DC \ +#define MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 \ +( \ + MSK_ICODE_RX_AFNOR | \ + MSK_ICODE_RX_AFNOR_DC | \ + MSK_ICODE_RX_IEEE1344 | \ + MSK_ICODE_RX_IEEE1344_DC | \ + MSK_ICODE_RX_B126_B127 | \ + MSK_ICODE_RX_B006_B007 | \ + MSK_ICODE_RX_C37118 | \ + MSK_ICODE_RX_C37118_DC | \ + MSK_ICODE_RX_A136_A137 | \ + MSK_ICODE_RX_A006_A007 \ ) /** - * @brief A mask of IRIG formats supporting TFOM time quality indicator + * @brief A mask of IRIG RX formats supporting a 2 digit year number after P6 + * + * Note: This macro specifies ONLY the codes where the year number + * is transmitted after position identifier P6. + * + * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 + * @see ::MSK_ICODE_RX_HAS_ANY_SHORT_YEAR + */ +#define MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 \ +( \ + MSK_ICODE_RX_G146 | \ + MSK_ICODE_RX_G006 \ +) + +/** + * @brief A mask of IRIG RX formats providing any 2 digit year number + * + * Note: Different sets of code frames may provide a year number + * in different locations of the transmitted code. + * + * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 + * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 + */ +#define MSK_ICODE_RX_HAS_ANY_SHORT_YEAR \ +( \ + MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 | \ + MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 \ +) + + + +/** + * @brief A mask of IRIG RX formats supporting TFOM time quality indicator */ #define MSK_ICODE_RX_HAS_TFOM \ ( \ @@ -3972,7 +5272,7 @@ enum ICODE_RX_CODES ) /** - * @brief A mask of IRIG formats supporting CTQ continuous time quality + * @brief A mask of IRIG RX formats supporting CTQ continuous time quality * * This has been introduced in IEEE C37.118.1-2011 */ @@ -3985,7 +5285,7 @@ enum ICODE_RX_CODES ) /** - * @brief A mask of IRIG formats supporting time zone information + * @brief A mask of IRIG RX formats supporting time zone information */ #define MSK_ICODE_RX_HAS_TZI \ ( \ @@ -3996,7 +5296,7 @@ enum ICODE_RX_CODES ) /** - * @brief IRIG formats where UTC offset must be subtracted to yield UTC + * @brief IRIG RX formats where UTC offset must be subtracted to yield UTC * * A mask of IRIG formats where the decoded UTC offset must be * subtracted from the time decoded from the IRIG signal to yield UTC, e.g.:<br> @@ -4009,7 +5309,7 @@ enum ICODE_RX_CODES ) /** - * @brief IRIG formats where UTC offset must be added to yield UTC + * @brief IRIG RX formats where UTC offset must be added to yield UTC * * A mask of IRIG formats where the decoded UTC offset must be * added to the time decoded from the IRIG signal to yield UTC, e.g.:<br> @@ -4022,7 +5322,7 @@ enum ICODE_RX_CODES ) /** - * @brief A mask of IRIG formats supporting a day of week number + * @brief A mask of IRIG RX formats supporting a day of week number */ #define MSK_ICODE_RX_HAS_AFNOR_WDAY \ ( \ @@ -4031,7 +5331,7 @@ enum ICODE_RX_CODES ) /** - * @brief A mask of IRIG formats supporting a date (day-of-month, month) + * @brief A mask of IRIG RX formats supporting a date (day-of-month, month) */ #define MSK_ICODE_RX_HAS_AFNOR_DATE \ ( \ @@ -4041,7 +5341,7 @@ enum ICODE_RX_CODES /** - * @brief The default mask of IRIG formats supported by IRIG receivers + * @brief The default mask of IRIG RX formats supported by IRIG receivers * * @note The formats which are actually supported should be retrieved * from the device @@ -4075,10 +5375,11 @@ typedef struct } IRIG_SETTINGS; #define _mbg_swab_irig_settings( _p ) \ +do \ { \ _mbg_swab16( &(_p)->icode ); \ _mbg_swab16( &(_p)->flags ); \ -} +} while ( 0 ) @@ -4129,10 +5430,11 @@ typedef struct } IRIG_INFO; #define _mbg_swab_irig_info( _p ) \ +do \ { \ _mbg_swab_irig_settings( &(_p)->settings ); \ _mbg_swab32( &(_p)->supp_codes ); \ -} +} while ( 0 ) /** @@ -4168,11 +5470,12 @@ typedef struct } IRIG_RX_COMP; #define _mbg_swab_irig_rx_comp( _p ) \ +do \ { \ int i; \ for ( i = 0; i < N_IRIG_RX_COMP_VAL; i++ ) \ _mbg_swab16( &(_p)->c[i] ); \ -} +} while ( 0 ) /** The absolute value of the maximum compensation value accepted by a device */ @@ -4191,10 +5494,11 @@ typedef struct } CAL_REC_HDR; #define _mbg_swab_cal_rec_hdr( _p ) \ +do \ { \ _mbg_swab16( &(_p)->type ); \ _mbg_swab16( &(_p)->idx ); \ -} +} while ( 0 ) /** @@ -4251,10 +5555,11 @@ typedef struct } CAL_REC_IRIG_RX_COMP; #define _mbg_swab_cal_rec_irig_rx_comp( _p ) \ +do \ { \ _mbg_swab_cal_rec_hdr( &(_p)->hdr ); \ _mbg_swab_irig_rx_comp( &(_p)->comp_data ); \ -} +} while ( 0 ) /** @} defgroup group_irig_comp */ @@ -4377,7 +5682,7 @@ typedef int16_t MBG_REF_OFFS; * (time offset from %UTC) has not yet been configured. This is usually * the case for IRIG receiver devices right after they have been shipped. */ -#define MBG_REF_OFFS_NOT_CFGD 0x8000 +#define MBG_REF_OFFS_NOT_CFGD ( (MBG_REF_OFFS) 0x8000 ) @@ -4393,9 +5698,10 @@ typedef struct } MBG_OPT_SETTINGS; #define _mbg_swab_mbg_opt_settings( _p ) \ +do \ { \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) /** @@ -4412,10 +5718,11 @@ typedef struct } MBG_OPT_INFO; #define _mbg_swab_mbg_opt_info( _p ) \ +do \ { \ _mbg_swab_mbg_opt_settings( &(_p)->settings ); \ _mbg_swab32( &(_p)->supp_flags ); \ -} +} while ( 0 ) /** @@ -4589,21 +5896,27 @@ typedef struct } MBG_TIME_SCALE_INFO; #define _mbg_swab_mbg_time_scale_info( _p ) \ +do \ { \ _mbg_swab_mbg_time_scale_settings( &(_p)->settings ); \ _mbg_swab_mbg_time_scale_settings( &(_p)->max_settings ); \ _mbg_swab32( &(_p)->supp_scales ); \ -} +} while ( 0 ) /** @} defgroup group_time_scale */ -/* - * The structures below are required to setup the programmable + +/** + * @defgroup group_pout_api Programmable Output API + * + * These structures below are used to configure the programmable * pulse outputs which are provided by some GPS receivers. * The number of programmable pulse outputs supported by a GPS - * receiver is reported in the RECEIVER_INFO::n_str_type field. - */ + * receiver is reported in the RECEIVER_INFO::n_prg_out field. + * + * @{ */ + /** * @brief A calendar date including full year number @@ -4617,9 +5930,10 @@ typedef struct } MBG_DATE; #define _mbg_swab_mbg_date( _p ) \ +do \ { \ _mbg_swab16( &(_p)->year ); \ -} +} while ( 0 ) /** @@ -4630,7 +5944,7 @@ typedef struct uint8_t hour; ///< 0..23 uint8_t min; ///< 0..59 uint8_t sec; ///< 0..59,60 - uint8_t sec100; ///< reserved, currently always 0 + uint8_t sec100; ///< 100ths of seconds } MBG_TIME; @@ -4651,14 +5965,19 @@ typedef struct } MBG_DATE_TIME; #define _mbg_swab_mbg_date_time( _p ) \ +do \ { \ _mbg_swab_mbg_date( &(_p)->d ); \ _mbg_swab_mbg_time( &(_p)->t ); \ -} +} while ( 0 ) /** * @brief A structure to define on/off cycle times + * + * @note The ::MBG_TIME::sec100 field in ::POUT_TIME:on and + * ::POUT_TIME:off is not evaluated by the firmware and thus + * should always be set to 0. */ typedef struct { @@ -4668,10 +5987,12 @@ typedef struct } POUT_TIME; #define _mbg_swab_pout_time( _p ) \ +do \ { \ _mbg_swab_mbg_date_time( &(_p)->on ); \ _mbg_swab_mbg_date_time( &(_p)->off ); \ -} +} while ( 0 ) + /** @@ -4682,78 +6003,106 @@ typedef struct #define N_POUT_TIMES 3 /** - * @brief Configuration settings for a single programmable pulse output + * @brief A Generic data field for programmable output settings */ -typedef struct +typedef union { - uint16_t mode; ///< mode of operation, see ::POUT_MODES - uint16_t mode_param; ///< depending on the mode, e.g. pulse length, or index of a signal source - uint16_t timeout; ///< timeout after which output signal is disabled [min], used with ::POUT_DCF77 and ::POUT_DCF77_M59 only, see ::MAX_POUT_DCF_TIMOUT - uint16_t flags; ///< @see ::POUT_SETTINGS_FLAGS - POUT_TIME tm[N_POUT_TIMES]; ///< switching times, or other data, see ::POUT_DATA + /// Switching times. See ::POUT_MODES_DATA_TM, ::POUT_MODES_DATA_TM_0 + POUT_TIME tm[N_POUT_TIMES]; + + uint8_t b[N_POUT_TIMES * sizeof( POUT_TIME )]; + + /// Only if ::POUT_SUPP_PULSE_SHIFT is set, this field can be used to + /// configure the time interval in [ns] by which output pulse slopes are + /// to be shifted. The configured pulse shift must be in the range + /// ::DEFAULT_POUT_PULSE_SHIFT_MIN through ::DEFAULT_POUT_PULSE_SHIFT_MAX. + /// The resolution / steps at which the pulse shift interval can be configured + /// is returned in ::POUT_INFO::pulse_shift_res. + /// @see ::POUT_MODES_DATA_PULSE_SHIFT + int32_t pulse_shift; + +} POUT_DATA; + +#define DEFAULT_POUT_PULSE_SHIFT_MIN -500000000L ///< Default minimum value for ::POUT_DATA::pulse_shift, in [ns] +#define DEFAULT_POUT_PULSE_SHIFT_MAX 499000000L ///< Default maximum value for ::POUT_DATA::pulse_shift, in [ns] -} POUT_SETTINGS; /** - * @brief A Generic data field for programmable output settings + * @brief Convert ::POUT_DATA endianess depending on the mode * - * If the mode is set to ::POUT_TIME_SLOTS then ::POUT_SETTINGS::tm must be - * interpreted as ::POUT_DATA, i.e. just an array of bytes. We can not change - * the type of the tm field to a union for compatibility reasons ... :( + * Assuming the mode is passed to the macro with correct endianess. */ -typedef union +#define _mbg_swab_pout_data( _p, _mode ) \ +do \ +{ \ + uint32_t mode_mask = 1UL << _mode; \ + \ + if ( mode_mask & POUT_MODES_DATA_TM ) \ + { \ + int i; \ + \ + for ( i = 0; i < N_POUT_TIMES; i++ ) \ + _mbg_swab_pout_time( &(_p)->tm[i] ); \ + } \ + else \ + { \ + if ( mode_mask & POUT_MODES_DATA_TM_0 ) \ + _mbg_swab_pout_time( &(_p)->tm[0] ); \ + else \ + if ( mode_mask & POUT_MODES_DATA_PULSE_SHIFT ) \ + _mbg_swab32( &(_p)->pulse_shift ); \ + } \ + \ +} while ( 0 ) + + + +/** + * @brief Configuration settings for a single programmable pulse output + */ +typedef struct { - uint8_t b[N_POUT_TIMES * sizeof( POUT_TIME )]; + uint16_t mode; ///< Mode of operation, see ::POUT_MODES + uint16_t mode_param; ///< Optional parameter depending on the mode, see @ref POUT_MODES_PARAM_MASKS -} POUT_DATA; + /// Timeout [min] which can be specified for some modes, see ::POUT_MODES_TIMEOUT, ::MAX_POUT_DCF_TIMOUT. + /// + /// If the clock looses synchronization then the output + /// - is disabled **immediately** if ::POUT_IF_SYNC_ONLY is set in ::POUT_SETTINGS::flags + /// - is disabled after ::POUT_SETTINGS::timeout, if timeout is not 0 (see ::MAX_POUT_DCF_TIMOUT) + /// - stays enabled if timeout is 0 **and** ::POUT_IF_SYNC_ONLY is **not** set + uint16_t timeout; + uint16_t flags; ///< @see ::POUT_SETTINGS_FLAGS + POUT_DATA pout_data; ///< Additional configuration data, see ::POUT_DATA + +} POUT_SETTINGS; /** * @brief Convert ::POUT_SETTINGS endianess after reading from a device - * - * When reading data from a device we first need to correct the endianess - * of the mode first, and correct the endianess of the tm field only - * if the tm field is not interpreted as ::POUT_DATA. */ -#define _mbg_swab_pout_settings_on_get( _p ) \ -{ \ - _mbg_swab16( &(_p)->mode ); \ - _mbg_swab16( &(_p)->mode_param ); \ - _mbg_swab16( &(_p)->timeout ); \ - _mbg_swab16( &(_p)->flags ); \ - \ - if ( (_p)->mode != POUT_TIME_SLOTS ) \ - { \ - int i; \ - \ - for ( i = 0; i < N_POUT_TIMES; i++ ) \ - _mbg_swab_pout_time( &(_p)->tm[i] ); \ - } \ -} +#define _mbg_swab_pout_settings_on_get( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->mode ); \ + _mbg_swab16( &(_p)->mode_param ); \ + _mbg_swab16( &(_p)->timeout ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab_pout_data( &(_p)->pout_data, (_p)->mode ); \ +} while ( 0 ) /** * @brief Convert ::POUT_SETTINGS endianess before writing to a device - * - * When writing data to a device we first need to check the mode, - * and correct the endianess of the tm field only if the tm field - * is not interpreted as ::POUT_DATA. Finally we can also correct - * the endianess of the mode field. */ -#define _mbg_swab_pout_settings_on_set( _p ) \ -{ \ - if ( (_p)->mode != POUT_TIME_SLOTS ) \ - { \ - int i; \ - \ - for ( i = 0; i < N_POUT_TIMES; i++ ) \ - _mbg_swab_pout_time( &(_p)->tm[i] ); \ - } \ - \ - _mbg_swab16( &(_p)->mode ); \ - _mbg_swab16( &(_p)->mode_param ); \ - _mbg_swab16( &(_p)->timeout ); \ - _mbg_swab16( &(_p)->flags ); \ -} +#define _mbg_swab_pout_settings_on_set( _p ) \ +do \ +{ \ + _mbg_swab_pout_data( &(_p)->pout_data, (_p)->mode ); \ + _mbg_swab16( &(_p)->mode ); \ + _mbg_swab16( &(_p)->mode_param ); \ + _mbg_swab16( &(_p)->timeout ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) @@ -4764,6 +6113,7 @@ typedef union * of time slots per minute is stored in ::POUT_SETTINGS::mode_param. * Valid numbers are all numbers n in the range ::MIN_TIME_SLOTS_PER_MINUTE * to ::MAX_TIME_SLOTS_PER_MINUTE for which the remainder of 60 / n is 0. + * @see ::POUT_MODES_MODE_PARAM_AS_SLOTS_PER_MIN * * @anchor POUT_TIME_SLOTS_MODE_DEFS @{ */ @@ -4797,7 +6147,7 @@ typedef union * * These codes are used with ::POUT_SETTINGS::mode. One or more of * the remaining fields in ::POUT_SETTINGS are evaluated depending - * on the selected mode. + * on the selected mode. Unused fields should be set to 0. * * Unless ::POUT_NOT_INVERTIBLE is set in ::POUT_INFO::flags * the output signal level can be inverted if ::POUT_INVERTED @@ -4806,30 +6156,94 @@ typedef union * @note Not every programmable pulse output supports all modes. * * @see @ref POUT_MODE_MASKS + * @see @ref POUT_MODES_PARAM_MASKS + * @see @ref ENG_POUT_NAMES + * @see @ref ENG_POUT_HINTS */ enum POUT_MODES { - POUT_IDLE, ///< always off, or on if ::POUT_INVERTED flag is set - POUT_TIMER, ///< switch on/off at times specified in ::POUT_SETTINGS::tm - POUT_SINGLE_SHOT, ///< pulse at time POUT_SETTINGS::tm[0].on, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN - POUT_CYCLIC_PULSE, ///< pulse every POUT_SETTINGS::tm[0].on.t interval, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN - POUT_PER_SEC, ///< pulse if second changes, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN - POUT_PER_MIN, ///< pulse if minute changes, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN - POUT_PER_HOUR, ///< pulse if hour changes, pulse length in ::POUT_SETTINGS::mode_param [10 ms units], see ::MAX_POUT_PULSE_LEN - POUT_DCF77, ///< emulate DCF77 signal, uses ::POUT_SETTINGS::timeout, see ::MAX_POUT_DCF_TIMOUT - POUT_POS_OK, ///< on if receiver position verified (nav_solved) - POUT_TIME_SYNC, ///< on if time synchronized (time_syn) - POUT_ALL_SYNC, ///< on if position verified and time synchronized - POUT_TIMECODE, ///< IRIG/AFNOR DCLS signal output - POUT_TIMESTR, ///< serial time string, ::POUT_SETTINGS::mode_param contains the number of the COM port, see ::MAX_POUT_TIMESTR_PORTS - POUT_10MHZ, ///< 10 MHz fixed frequency - POUT_DCF77_M59, ///< DCF77-like signal with 500 ms pulse in 59th second, uses ::POUT_SETTINGS::timeout, see ::MAX_POUT_DCF_TIMOUT - POUT_SYNTH, ///< programmable frequency synthesizer output signal - POUT_TIME_SLOTS, ///< programmable time slots during each minute, uses ::POUT_DATA, ::POUT_SETTINGS::mode_param contains time slots per minute - POUT_GPIO, ///< GPIO input or output signal, ::POUT_SETTINGS::mode_param specifies the GPIO number, see ::MBG_GPIO_CFG_LIMITS::num_io - // New modes have to be added here at the end of the enumeration, and - // the POUT_MODE_MASKS and string initializers (also in pcpslstr.h) - // have to be updated accordingly. + /// Output is normally always 'off', or always 'on', if flag ::POUT_INVERTED is set. + POUT_IDLE, + + /// Switch 'on' or 'off' at the times specified in ::POUT_DATA::tm. + POUT_TIMER, + + /// Generate a pulse at the time specified in ::POUT_SETTINGS::POUT_DATA::tm[0]::on. + /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_SINGLE_SHOT, + + /// Generate a cyclic pulse at the interval specified in ::POUT_SETTINGS::POUT_DATA::tm[0]:on::t. + /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_CYCLIC_PULSE, + + /// Generate a pulse whenever the second changes. + /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_PER_SEC, + + /// Generate a pulse whenever the minute changes. + /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_PER_MIN, + + /// Generate a pulse whenever the hour changes. + /// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_PER_HOUR, + + /// Generate DCF77-compatible second marks. + /// See ::POUT_DCF77_M59, ::POUT_SETTINGS::timeout and ::MAX_POUT_DCF_TIMOUT. + POUT_DCF77, + + /// Output switched on if receiver position verified (condition nav_solved). + POUT_POS_OK, + + /// Output switched on if time synchronized (condition time_syn). + POUT_TIME_SYNC, + + /// Output switched on if both position verified and time synchronized. + POUT_ALL_SYNC, + + /// IRIG/AFNOR DCLS time code signal mapped to this output. + POUT_TIMECODE, + + /// Serial time string of one one of the serial ports mapped to this output. + /// ::POUT_SETTINGS::mode_param contains the number of the COM port. + /// See ::MAX_POUT_TIMESTR_PORTS. + POUT_TIMESTR, + + /// 10 MHz fixed frequency output. + POUT_10MHZ, + + /// DCF77-like signal with extra 500 ms pulse in the 59th second + /// (the original DCF77 signal has no such pulse). See ::POUT_DCF77, + /// ::POUT_SETTINGS::timeout and ::MAX_POUT_DCF_TIMOUT. + POUT_DCF77_M59, + + /// Output signal generated by the programmable frequency synthesizer. + POUT_SYNTH, + + /// Programmable time slots during each minute. + /// ::POUT_SETTINGS::mode_param specifies the time slots per minute. + /// Uses ::POUT_DATA. ::TODO + POUT_TIME_SLOTS, + + /// A GPIO input or output signal is reflected at this pulse output. + /// ::POUT_SETTINGS::mode_param specifies the GPIO number which must + /// be in the range 0..::MBG_GPIO_CFG_LIMITS::num_io. + POUT_GPIO, + + /// A 1PPS signal with a fixed 20us pulse length + POUT_PTTI_PPS, + + /// A HaveQuick signal as configured in ::HAVEQUICK_SETTINGS::format + POUT_HAVEQUICK, + + // New modes have to be added here at the end of the enumeration, and the + // POUT_MODE_MASKS, the POUT_MODES_PARAM_MASKS as well as string initializers + // (also in pcpslstr.h) have to be updated accordingly. N_POUT_MODES ///< the number of known modes }; @@ -4862,14 +6276,168 @@ enum POUT_MODES #define MSK_POUT_SYNTH ( 1UL << POUT_SYNTH ) ///< see ::POUT_SYNTH #define MSK_POUT_TIME_SLOTS ( 1UL << POUT_TIME_SLOTS ) ///< see ::POUT_TIME_SLOTS #define MSK_POUT_GPIO ( 1UL << POUT_GPIO ) ///< see ::POUT_GPIO +#define MSK_POUT_PTTI_PPS ( 1UL << POUT_PTTI_PPS ) ///< see ::POUT_PTTI_PPS +#define MSK_POUT_HAVEQUICK ( 1UL << POUT_HAVEQUICK ) ///< see ::POUT_HAVEQUICK /** @} anchor POUT_MODE_MASKS */ -/* - * Default initializers for English pulse mode names. Initializers - * for multi-language strings can be found in pcpslstr.h. + +/** + * @brief Bit masks indicating which parameters relevant for which ::POUT_MODES + * + * @see ::POUT_MODES + * @see @ref POUT_MODE_MASKS + * + * @anchor POUT_MODES_PARAM_MASKS @{ */ + + +/** + * @brief POUT modes which use the full ::POUT_DATA::tm array as parameter + */ +#define POUT_MODES_DATA_TM \ +( \ + MSK_POUT_TIMER \ +) + + +/** + * @brief POUT modes which use only ::POUT_DATA::tm[0] as parameter + */ +#define POUT_MODES_DATA_TM_0 \ +( \ + MSK_POUT_SINGLE_SHOT | \ + MSK_POUT_CYCLIC_PULSE \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::mode_param as pulse length + * + * @see ::MAX_POUT_PULSE_LEN + */ +#define POUT_MODES_MODE_PARAM_AS_PULSE_LEN \ +( \ + MSK_POUT_SINGLE_SHOT | \ + MSK_POUT_CYCLIC_PULSE | \ + MSK_POUT_PER_SEC | \ + MSK_POUT_PER_MIN | \ + MSK_POUT_PER_HOUR \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::mode_param as COM port index number + */ +#define POUT_MODES_MODE_PARAM_AS_COM_IDX \ +( \ + MSK_POUT_TIMESTR \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::mode_param as time slots per minute + * + * @see @ref POUT_TIME_SLOTS_MODE_DEFS + */ +#define POUT_MODES_MODE_PARAM_AS_SLOTS_PER_MIN \ +( \ + MSK_POUT_TIME_SLOTS \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::mode_param as GPIO index number + */ +#define POUT_MODES_MODE_PARAM_AS_GPIO_IDX \ +( \ + MSK_POUT_GPIO \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::timeout + */ +#define POUT_MODES_TIMEOUT \ +( \ + MSK_POUT_DCF77 | \ + MSK_POUT_DCF77_M59 \ +) + + +/** + * @brief POUT modes which which support ::POUT_TIMEBASE_UTC + */ +#define POUT_MODES_SUPP_TIMEBASE_UTC \ +( \ + MSK_POUT_DCF77 | \ + MSK_POUT_DCF77_M59 \ +) + + +/** + * @brief POUT modes which use ::POUT_DATA::pulse_shift + * + * @note: Supported only if ::POUT_SUPP_PULSE_SHIFT is set + */ +#define POUT_MODES_DATA_PULSE_SHIFT \ +( \ + MSK_POUT_PER_SEC | \ + MSK_POUT_PER_MIN | \ + MSK_POUT_PER_HOUR \ +) + + +/** + * @brief POUT modes which support ::POUT_SUPP_IF_SYNC_ONLY + * + * Even if ::POUT_SUPP_IF_SYNC_ONLY is set in ::POUT_INFO::flags + * the associated flag ::POUT_IF_SYNC_ONLY in ::POUT_SETTINGS::flags + * may be evaluated depending on the mode. + * + * Modes ::POUT_POS_OK, ::POUT_TIME_SYNC, and ::MSK_POUT_ALL_SYNC + * are explicitly excluded. + * + * For modes ::MSK_POUT_DCF77 and ::MSK_POUT_DCF77_M59 see also + * ::POUT_SETTINGS::timeout. */ +#define POUT_MODES_SUPP_IF_SYNC_ONLY \ +( \ + MSK_POUT_IDLE | \ + MSK_POUT_TIMER | \ + MSK_POUT_SINGLE_SHOT | \ + MSK_POUT_CYCLIC_PULSE | \ + MSK_POUT_PER_SEC | \ + MSK_POUT_PER_MIN | \ + MSK_POUT_PER_HOUR | \ + MSK_POUT_DCF77 | \ + MSK_POUT_TIMECODE | \ + MSK_POUT_TIMESTR | \ + MSK_POUT_10MHZ | \ + MSK_POUT_DCF77_M59 | \ + MSK_POUT_SYNTH | \ + MSK_POUT_TIME_SLOTS | \ + MSK_POUT_GPIO | \ + MSK_POUT_PTTI_PPS | \ + MSK_POUT_HAVEQUICK \ +) + + +/** @} anchor POUT_MODES_PARAM_MASKS */ + + + +/** + * @brief Name strings associated with ::POUT_MODES + * + * Default initializers for English programmable output mode names. + * Initializers for multi-language strings can be found in pcpslstr.h. + * + * @see ::POUT_MODES + * @see ::DEFAULT_ENG_POUT_NAMES + * + * @anchor ENG_POUT_NAMES @{ */ + #define ENG_POUT_NAME_IDLE "Idle" #define ENG_POUT_NAME_TIMER "Timer" #define ENG_POUT_NAME_SINGLE_SHOT "Single Shot" @@ -4888,7 +6456,18 @@ enum POUT_MODES #define ENG_POUT_NAME_SYNTH "Synthesizer Frequency" #define ENG_POUT_NAME_TIME_SLOTS "Time Slots per Minute" #define ENG_POUT_NAME_GPIO "GPIO Signal" +#define ENG_POUT_PTTI_PPS "PTTI 1PPS" +#define ENG_POUT_HAVEQUICK "HaveQuick" + +/** @} anchor ENG_POUT_NAMES */ + + +/** + * @brief An initializer for a table of English POUT name strings + * + * @see @ref ENG_POUT_NAMES + */ #define DEFAULT_ENG_POUT_NAMES \ { \ ENG_POUT_NAME_IDLE, \ @@ -4908,10 +6487,23 @@ enum POUT_MODES ENG_POUT_NAME_DCF77_M59, \ ENG_POUT_NAME_SYNTH, \ ENG_POUT_NAME_TIME_SLOTS, \ - ENG_POUT_NAME_GPIO \ + ENG_POUT_NAME_GPIO, \ + ENG_POUT_PTTI_PPS, \ + ENG_POUT_HAVEQUICK \ } +/** + * @brief Hint strings associated with ::POUT_MODES + * + * Default initializers for English programmable output mode hints. + * Initializers for multi-language strings can be found in pcpslstr.h. + * + * @see ::POUT_MODES + * @see ::DEFAULT_ENG_POUT_HINTS + * + * @anchor ENG_POUT_HINTS @{ */ + #define ENG_POUT_HINT_IDLE "Constant output level" #define ENG_POUT_HINT_TIMER "Switch based on configured on/off times" #define ENG_POUT_HINT_SINGLE_SHOT "Generate a single pulse of determined length" @@ -4930,7 +6522,17 @@ enum POUT_MODES #define ENG_POUT_HINT_SYNTH "Frequency generated by programmable synthesizer" #define ENG_POUT_HINT_TIME_SLOTS "Output enabled during specified time slots per minute" #define ENG_POUT_HINT_GPIO "Duplicated signal of the specified GPIO input or output" +#define ENG_POUT_HINT_PTTI_PPS "Generate 20us Pulse at beginning of the second" +#define ENG_POUT_HINT_HAVEQUICK "Duplicated HaveQuick Signal" +/** @} anchor ENG_POUT_HINTS */ + + +/** + * @brief An initializer for a table of English POUT hint strings + * + * @see @ref ENG_POUT_HINTS + */ #define DEFAULT_ENG_POUT_HINTS \ { \ ENG_POUT_HINT_IDLE, \ @@ -4950,7 +6552,9 @@ enum POUT_MODES ENG_POUT_HINT_DCF77_M59, \ ENG_POUT_HINT_SYNTH, \ ENG_POUT_HINT_TIME_SLOTS, \ - ENG_POUT_HINT_GPIO \ + ENG_POUT_HINT_GPIO, \ + ENG_POUT_HINT_PTTI_PPS, \ + ENG_POUT_HINT_HAVEQUICK \ } @@ -4962,9 +6566,27 @@ enum POUT_MODES */ enum POUT_SETTINGS_FLAG_BITS { - POUT_BIT_INVERTED, ///< output level is inverted, use only if ::POUT_NOT_INVERTIBLE not set - POUT_BIT_IF_SYNC_ONLY, ///< disable output in holdover mode, use only if ::POUT_SUPP_IF_SYNC_ONLY is set - POUT_BIT_TIMEBASE_UTC, ///< output %UTC if mode is ::POUT_DCF77 or ::POUT_DCF77_M59, use only if ::POUT_SUPP_DCF77_UTC is set + /// Output level is to be inverted. Can only be used + /// if ::POUT_NOT_INVERTIBLE is **not** set, but is + /// supported by all ::POUT_MODES. + POUT_BIT_INVERTED, + + /// Enable output **only** while synchronized. This even overrides + /// the settings in ::ENABLE_FLAGS::pulses, so if this flag is set + /// the output is only enabled if the clock is synchronized, and is + /// disabled when synchronization is lost, i.e. the device enters + /// holdover mode. + /// This flag can only be used with outputs that have ::POUT_SUPP_IF_SYNC_ONLY + /// set, and is only supported for the ::POUT_MODES specified in + /// ::POUT_MODES_SUPP_IF_SYNC_ONLY. + POUT_BIT_IF_SYNC_ONLY, + + /// Output %UTC time instead of local time for DCF77 emulation. + /// This flag can only be used with outputs that have ::POUT_SUPP_DCF77_UTC + /// set, and is only supported for the ::POUT_MODES specified in + /// ::POUT_MODES_SUPP_TIMEBASE_UTC (e.g. ::POUT_DCF77 or ::POUT_DCF77_M59). + POUT_BIT_TIMEBASE_UTC, + N_POUT_SETTINGS_FLAG_BITS ///< Number of known flag bits }; @@ -5001,16 +6623,18 @@ typedef struct } POUT_SETTINGS_IDX; #define _mbg_swab_pout_settings_idx_on_set( _p ) \ +do \ { \ _mbg_swab16( &(_p)->idx ); \ _mbg_swab_pout_settings_on_set( &(_p)->pout_settings ); \ -} +} while ( 0 ) #define _mbg_swab_pout_settings_idx_on_get( _p ) \ +do \ { \ _mbg_swab16( &(_p)->idx ); \ _mbg_swab_pout_settings_on_get( &(_p)->pout_settings ); \ -} +} while ( 0 ) /** @@ -5026,21 +6650,24 @@ typedef struct typedef struct { POUT_SETTINGS pout_settings; - uint32_t supp_modes; ///< bit mask of modes supp. by this output, see @ref POUT_MODE_MASKS - uint8_t timestr_ports; ///< bit mask of COM ports supported for mode ::POUT_TIMESTR, see ::MAX_POUT_TIMESTR_PORTS - uint8_t reserved_0; ///< reserved for future use, currently unused and always 0 - uint16_t reserved_1; ///< reserved for future use, currently unused and always 0 - uint32_t flags; ///< @see ::POUT_INFO_FLAG_MASKS + uint32_t supp_modes; ///< bit mask of modes supp. by this output, see @ref POUT_MODE_MASKS + uint8_t timestr_ports; ///< bit mask of COM ports supported for mode ::POUT_TIMESTR, see ::MAX_POUT_TIMESTR_PORTS + uint8_t pulse_shift_res; ///< pulse shift resolution, in [ns], only if ::POUT_SUPP_PULSE_SHIFT, see ::POUT_DATA::pulse_shift + uint16_t reserved_1; ///< reserved for future use, currently unused and always 0 + uint32_t flags; ///< @see ::POUT_INFO_FLAG_MASKS } POUT_INFO; #define _mbg_swab_pout_info_on_get( _p ) \ +do \ { \ _mbg_swab_pout_settings_on_get( &(_p)->pout_settings ); \ _mbg_swab32( &(_p)->supp_modes ); \ + _mbg_swab8( &(_p)->timestr_ports ); \ + _mbg_swab8( &(_p)->pulse_shift_res ); \ _mbg_swab16( &(_p)->reserved_1 ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) #define MAX_POUT_TIMESTR_PORTS 8 ///< The max number of COM ports that can be handled by ::POUT_INFO::timestr_ports @@ -5058,6 +6685,7 @@ enum POUT_INFO_FLAG_BITS POUT_BIT_SUPP_DCF77_UTC, ///< ::POUT_SUPP_DCF77_UTC is supported for this output POUT_BIT_FIXED_PULSE_LEN, ///< pulse length is limited to the value ::POUT_SETTINGS::mode_param POUT_BIT_NOT_INVERTIBLE, ///< output level can't be inverted, thus ::POUT_INVERTED is not supported for this output + POUT_BIT_SUPP_PULSE_SHIFT, ///< output slopes can be shifted, see ::POUT_DATA::pulse_shift N_POUT_INFO_FLAG_BITS ///< number of known flag bits }; @@ -5072,7 +6700,8 @@ enum POUT_INFO_FLAG_MASKS POUT_SUPP_IF_SYNC_ONLY = ( 1UL << POUT_BIT_SUPP_IF_SYNC_ONLY ), ///< see ::POUT_BIT_SUPP_IF_SYNC_ONLY, ::POUT_IF_SYNC_ONLY POUT_SUPP_DCF77_UTC = ( 1UL << POUT_BIT_SUPP_DCF77_UTC ), ///< see ::POUT_BIT_SUPP_DCF77_UTC, ::POUT_SUPP_DCF77_UTC POUT_FIXED_PULSE_LEN = ( 1UL << POUT_BIT_FIXED_PULSE_LEN ), ///< see ::POUT_BIT_FIXED_PULSE_LEN - POUT_NOT_INVERTIBLE = ( 1UL << POUT_BIT_NOT_INVERTIBLE ) ///< see ::POUT_BIT_NOT_INVERTIBLE, ::POUT_INVERTED + POUT_NOT_INVERTIBLE = ( 1UL << POUT_BIT_NOT_INVERTIBLE ), ///< see ::POUT_BIT_NOT_INVERTIBLE, ::POUT_INVERTED + POUT_SUPP_PULSE_SHIFT = ( 1UL << POUT_BIT_SUPP_PULSE_SHIFT ) ///< see ::POUT_BIT_SUPP_PULSE_SHIFT, ::POUT_DATA::pulse_shift }; @@ -5096,10 +6725,13 @@ typedef struct } POUT_INFO_IDX; #define _mbg_swab_pout_info_idx_on_get( _p ) \ +do \ { \ _mbg_swab16( &(_p)->idx ); \ _mbg_swab_pout_info_on_get( &(_p)->pout_info ); \ -} +} while ( 0 ) + +/** @} defgroup group_pout_api */ @@ -5173,6 +6805,7 @@ enum MULTI_REF_TYPES MULTI_REF_GRC, ///< Glonass / GPS receiver MULTI_REF_HAVEQUICK, ///< HaveQuick input MULTI_REF_EXT_OSC, ///< external oscillator disciplined and looped back via 1 PPS I/O + MULTI_REF_SYNCE, ///< Synchronous Ethernet, needs (external) ethernet interface N_MULTI_REF ///< the number of defined sources, must not exceed ::MAX_N_MULTI_REF_TYPES }; @@ -5208,7 +6841,8 @@ enum MULTI_REF_TYPES "Long Wave Receiver", \ "GLONASS/GPS Receiver", \ "HaveQuick Input", \ - "ext. Osc." \ + "ext. Osc.", \ + "Synchronous Ethernet" \ } /** @@ -5226,17 +6860,18 @@ enum MULTI_REF_TYPES "10MHZ+PPS", \ "TCR", \ "NTP", \ - "PTP hq", \ - "PTP E1", \ - "Fixed in", \ - "STR in", \ - "GPIO in", \ + "PTP", \ + "PTP_E1", \ + "FIXED_FREQ", \ + "STRING+PPS", \ + "GPIO", \ "(reserved)", \ "PZF", \ "LWR", \ "GGR", \ "HQI", \ - "EXT" \ + "EXT", \ + "SYNCE" \ } @@ -5269,6 +6904,7 @@ enum MULTI_REF_TYPES #define HAS_MULTI_REF_HAVEQUICK ( 1UL << MULTI_REF_HAVEQUICK ) ///< see ::MULTI_REF_HAVEQUICK #define HAS_MULTI_REF_EXT_OSC ( 1UL << MULTI_REF_EXT_OSC ) ///< see ::MULTI_REF_EXT_OSC +#define HAS_MULTI_REF_SYNCE ( 1UL << MULTI_REF_SYNCE ) ///< see ::MULTI_REF_SYNCE /** @} anchor MULTI_REF_TYPE_MASKS */ @@ -5438,6 +7074,13 @@ typedef struct } XMULTI_REF_ID; +#define _mbg_swab_xmulti_ref_id( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->type ); \ + _mbg_swab8( &(_p)->instance ); \ +} while ( 0 ) + /** @@ -5453,6 +7096,16 @@ typedef struct } XMULTI_REF_SETTINGS; +#define _mbg_swab_xmulti_ref_settings( _p ) \ +do \ +{ \ + _mbg_swab_xmulti_ref_id( &(_p)->id ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab_nano_time( &(_p)->bias ); \ + _mbg_swab_nano_time( &(_p)->precision ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + /** @@ -5469,6 +7122,13 @@ typedef struct } XMULTI_REF_SETTINGS_IDX; +#define _mbg_swab_xmulti_ref_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmulti_ref_settings( &(_p)->settings ); \ +} while ( 0 ) + /** @@ -5476,10 +7136,10 @@ typedef struct */ enum XMR_SETTINGS_FLAG_BITS { - XMRSF_BIT_AUTO_BIAS_MASTER, ///< src is allowed to operate as zero asymmetry master - XMRSF_BIT_AUTO_BIAS_SLAVE, ///< accept static bias correction from zero asymmetry master - XMRSF_BIT_ASYMMETRY_STEP_DETECTION, ///< static bias auto correction in case of step - N_XMRSF_BITS ///< number of know status bits + XMRSF_BIT_AUTO_BIAS_MASTER, ///< src is allowed to operate as zero asymmetry master + XMRSF_BIT_AUTO_BIAS_SLAVE, ///< accept static bias correction from zero asymmetry master + XMRSF_BIT_ASYMMETRY_STEP_DETECTION, ///< static bias auto correction in case of step + N_XMRSF_BITS ///< number of known flag bits }; @@ -5522,6 +7182,16 @@ typedef struct } XMULTI_REF_INFO; +#define _mbg_swab_xmulti_ref_info( _p ) \ +do \ +{ \ + _mbg_swab_xmulti_ref_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_ref ); \ + _mbg_swab8( &(_p)->n_supp_ref ); \ + _mbg_swab8( &(_p)->n_prio ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + /** @@ -5534,6 +7204,13 @@ typedef struct } XMULTI_REF_INFO_IDX; +#define _mbg_swab_xmulti_ref_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmulti_ref_info( &(_p)->info ); \ +} while ( 0 ) + /** @@ -5544,12 +7221,23 @@ typedef struct XMULTI_REF_ID id; ///< time source identifier uint16_t status; ///< status bits, see @ref XMR_REF_STATUS_BIT_MASKS NANO_TIME offset; ///< time offset from main time base @todo specify sign vs. earlier/later - uint16_t flags; ///< flags, currently unused + uint16_t flags; ///< flags, see ::XMR_QL // TODO ### uint8_t ssm; ///< synchronization status message, if supported by signal source uint8_t soc; ///< signal outage counter, incremented on loss of signal } XMULTI_REF_STATUS; +#define _mbg_swab_xmulti_ref_status( _p ) \ +do \ +{ \ + _mbg_swab_xmulti_ref_id( &(_p)->id ); \ + _mbg_swab16( &(_p)->status ); \ + _mbg_swab_nano_time( &(_p)->offset ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab8( &(_p)->ssm ); \ + _mbg_swab8( &(_p)->soc ); \ +} while ( 0 ) + /** @@ -5562,6 +7250,50 @@ typedef struct } XMULTI_REF_STATUS_IDX; +#define _mbg_swab_xmulti_ref_status_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmulti_ref_status( &(_p)->status ); \ +} while ( 0 ) + + + +/** + * @brief ::TODO + * + * Used with the ::... field of ::XMULTI_REF_STATUS::flags + * + * @see ::XMULTI_REF_STATUS::flags + * @see ::XMR_QL_MASK + * @see ::_GET_XMR_QL + * @see ::_PUT_XMR_QL + */ +enum XMR_QL +{ + XMR_QL_UNKNOWN, + XMR_QL_GREEN, + XMR_QL_YELLOW, + XMR_QL_RED, + N_XMR_QL +}; + +#define XMR_QL_TDEV_MASK ( 0x03 << 0 ) +#define XMR_QL_MTIE_MASK ( 0x03 << 2 ) + +#define _GET_XMR_QL_TDEV( _x ) ( ( ( _x ) & XMR_QL_TDEV_MASK ) >> 0 ) +#define _PUT_XMR_QL_TDEV( _x, _ql ) \ +do { \ + ( _x ) = ( ( _x ) & ~XMR_QL_TDEV_MASK ) | ( ( ( _ql ) << 0 ) & XMR_QL_TDEV_MASK ); \ +} while ( 0 ) + + +#define _GET_XMR_QL_MTIE( _x ) ( ( ( _x ) & XMR_QL_MTIE_MASK ) >> 2 ) +#define _PUT_XMR_QL_MTIE( _x, _ql ) \ +do { \ + ( _x ) = ( ( _x ) & ~XMR_QL_MTIE_MASK ) | ( ( ( _ql ) << 2 ) & XMR_QL_MTIE_MASK ); \ +} while ( 0 ) + /** @@ -5569,21 +7301,23 @@ typedef struct */ enum XMR_REF_STATUS_BITS { - XMRS_BIT_NOT_SUPP, ///< ref type cfg'd for this level is not supported - XMRS_BIT_NO_CONN, ///< input signal is disconnected - XMRS_BIT_NO_SIGNAL, ///< no input signal - XMRS_BIT_IS_MASTER, ///< reference is master source - XMRS_BIT_IS_LOCKED, ///< locked to input signal - XMRS_BIT_IS_ACCURATE, ///< oscillator control has reached full accuracy - XMRS_BIT_NOT_SETTLED, ///< reference time signal not settled - XMRS_BIT_NOT_PHASE_LOCKED, ///< oscillator not phase locked to PPS - XMRS_BIT_NUM_SRC_EXC, ///< number of available sources exceeds what can be handled - XMRS_BIT_IS_EXTERNAL, ///< this ref source is on extension card - XMRS_BIT_LOW_JITTER, ///< this ref source has low jitter - N_XMRS_BITS ///< number of know status bits + XMRS_BIT_NOT_SUPP, ///< ref type cfg'd for this level is not supported + XMRS_BIT_NO_CONN, ///< input signal is disconnected + XMRS_BIT_NO_SIGNAL, ///< no input signal + XMRS_BIT_IS_MASTER, ///< reference is master source + XMRS_BIT_IS_LOCKED, ///< locked to input signal + XMRS_BIT_IS_ACCURATE, ///< oscillator control has reached full accuracy + XMRS_BIT_NOT_SETTLED, ///< reference time signal not settled + XMRS_BIT_NOT_PHASE_LOCKED, ///< oscillator not phase locked to PPS + XMRS_BIT_NUM_SRC_EXC, ///< number of available sources exceeds what can be handled + XMRS_BIT_IS_EXTERNAL, ///< this ref source is on extension card + XMRS_BIT_LOW_JITTER, ///< this ref source has low jitter + XMRS_BIT_ITU_LIMIT_VIOLATED, ///< ITU limits violated (valid if device has ::XMR_METRICS) + N_XMRS_BITS ///< number of know status bits }; + /** * @brief Bit masks associated with ::XMR_REF_STATUS_BITS * @@ -5593,21 +7327,23 @@ enum XMR_REF_STATUS_BITS * * @anchor XMR_REF_STATUS_BIT_MASKS @{ */ -#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP ) ///< see ::XMRS_BIT_NOT_SUPP -#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN ) ///< see ::XMRS_BIT_NO_CONN -#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL ) ///< see ::XMRS_BIT_NO_SIGNAL -#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER ) ///< see ::XMRS_BIT_IS_MASTER -#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED ) ///< see ::XMRS_BIT_IS_LOCKED -#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE ) ///< see ::XMRS_BIT_IS_ACCURATE -#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED ) ///< see ::XMRS_BIT_NOT_SETTLED -#define XMRS_MSK_NOT_PHASE_LOCKED ( 1UL << XMRS_BIT_NOT_PHASE_LOCKED ) ///< see ::XMRS_BIT_NOT_PHASE_LOCKED -#define XMRS_MSK_NUM_SRC_EXC ( 1UL << XMRS_BIT_NUM_SRC_EXC ) ///< see ::XMRS_BIT_NUM_SRC_EXC -#define XMRS_MSK_IS_EXTERNAL ( 1UL << XMRS_BIT_IS_EXTERNAL ) ///< see ::XMRS_BIT_IS_EXTERNAL -#define XMRS_MSK_LOW_JITTER ( 1UL << XMRS_BIT_LOW_JITTER ) ///< see ::XMRS_BIT_LOW_JITTER +#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP ) ///< see ::XMRS_BIT_NOT_SUPP +#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN ) ///< see ::XMRS_BIT_NO_CONN +#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL ) ///< see ::XMRS_BIT_NO_SIGNAL +#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER ) ///< see ::XMRS_BIT_IS_MASTER +#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED ) ///< see ::XMRS_BIT_IS_LOCKED +#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE ) ///< see ::XMRS_BIT_IS_ACCURATE +#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED ) ///< see ::XMRS_BIT_NOT_SETTLED +#define XMRS_MSK_NOT_PHASE_LOCKED ( 1UL << XMRS_BIT_NOT_PHASE_LOCKED ) ///< see ::XMRS_BIT_NOT_PHASE_LOCKED +#define XMRS_MSK_NUM_SRC_EXC ( 1UL << XMRS_BIT_NUM_SRC_EXC ) ///< see ::XMRS_BIT_NUM_SRC_EXC +#define XMRS_MSK_IS_EXTERNAL ( 1UL << XMRS_BIT_IS_EXTERNAL ) ///< see ::XMRS_BIT_IS_EXTERNAL +#define XMRS_MSK_LOW_JITTER ( 1UL << XMRS_BIT_LOW_JITTER ) ///< see ::XMRS_BIT_LOW_JITTER +#define XMRS_MSK_ITU_LIMIT_VIOLATED ( 1UL << XMRS_BIT_ITU_LIMIT_VIOLATED ) ///< see ::XMRS_BIT_ITU_LIMIT_VIOLATED /** @} anchor XMR_REF_STATUS_BIT_MASKS */ + /** * @brief XMRS status bit name strings * @@ -5625,10 +7361,12 @@ enum XMR_REF_STATUS_BITS "Phase not locked", \ "Number sources exceeds limit", \ "Is external", \ - "Low jitter" \ + "Low jitter", \ + "ITU Limit violated" \ } + /* * An initializer for a ::XMULTI_REF_STATUS variable * with status invalid / not used @@ -5642,6 +7380,7 @@ enum XMR_REF_STATUS_BITS } + /** * @brief General info on supported XMR sources and instances * @@ -5677,6 +7416,13 @@ typedef struct } XMULTI_REF_INSTANCES; +#define _mbg_swab_xmulti_ref_instances( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab16( &(_p)->n_xmr_settings ); \ +} while ( 0 ) + /** @@ -5716,13 +7462,14 @@ enum XMR_INST_FLAG_BIT_MASKS }; + /** * @brief XMR holdover interval, or elapsed holdover time, in [s] */ typedef uint32_t XMR_HOLDOVER_INTV; #define _mbg_swab_xmr_holdover_intv( _p ) \ - _mbg_swab32( _p ); + _mbg_swab32( _p ) @@ -5732,6 +7479,7 @@ typedef uint32_t XMR_HOLDOVER_INTV; #define XMR_PRIO_LVL_UNSPEC -1 + /** * @brief XMR holdover status * @@ -5765,13 +7513,28 @@ typedef struct int8_t curr_prio; ///< current priority level, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC int8_t nxt_prio; ///< next priority level after holdover, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC uint8_t remote_watchdog; ///< counts down in ::XMR_HLDOVR_PRE_AUTONOMOUS mode - uint32_t reserved; ///< reserved, don't use, currently 0 + uint32_t time_offset_ns; ///< estimated time offset in holdover operation XMR_HOLDOVER_INTV elapsed; ///< elapsed time in holdover mode, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set XMR_HOLDOVER_INTV interval; ///< current holdover interval, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set uint32_t flags; ///< holdover status flags, see ::XMR_HOLDOVER_STATUS_FLAG_MASKS } XMR_HOLDOVER_STATUS; +#define _mbg_swab_xmr_holdover_status( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->mode ); \ + _mbg_swab8( &(_p)->curr_prio ); \ + _mbg_swab8( &(_p)->nxt_prio ); \ + _mbg_swab8( &(_p)->remote_watchdog ); \ + _mbg_swab32( &(_p)->time_offset_ns ); \ + _mbg_swab_xmr_holdover_intv( &(_p)->elapsed ); \ + _mbg_swab_xmr_holdover_intv( &(_p)->interval ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + /** * @brief XMR holdover status modes @@ -5796,9 +7559,9 @@ enum XMR_HOLDOVER_STATUS_MODES */ #define XMR_HOLDOVER_STATUS_MODE_NAMES \ { \ - "autonomous", \ - "pre-autonomous", \ - "remote" \ + "Autonomous", \ + "Pre-Autonomous", \ + "Remote" \ } @@ -5813,6 +7576,7 @@ enum XMR_HOLDOVER_STATUS_FLAG_BITS XMR_HLDOVR_BIT_IN_HOLDOVER, ///< the device is currently in holdover mode XMR_HLDOVR_BIT_TRANSITION_ENBD, ///< timebase is in transition (being slewed) after sources have been switched XMR_HLDOVR_BIT_IN_TRANSITION, ///< transition is currently active, slewing in progress + XMR_HLDOVR_BIT_TIME_OFFS_VALID, ///< values in field ::XMR_HOLDOVER_STATUS::time_offset_ns are valid N_XMR_HOLDOVER_STATUS_FLAG_BITS ///< the number of known status flags }; @@ -5826,18 +7590,58 @@ enum XMR_HOLDOVER_STATUS_FLAG_MASKS { XMR_HLDOVR_MSK_IN_HOLDOVER = ( 1UL << XMR_HLDOVR_BIT_IN_HOLDOVER ), ///< see ::XMR_HLDOVR_BIT_IN_HOLDOVER XMR_HLDOVR_MSK_TRANSITION_ENBD = ( 1UL << XMR_HLDOVR_BIT_TRANSITION_ENBD ), ///< see ::XMR_HLDOVR_BIT_TRANSITION_ENBD - XMR_HLDOVR_MSK_IN_TRANSITION = ( 1UL << XMR_HLDOVR_BIT_IN_TRANSITION ) ///< see ::XMR_HLDOVR_BIT_IN_TRANSITION + XMR_HLDOVR_MSK_IN_TRANSITION = ( 1UL << XMR_HLDOVR_BIT_IN_TRANSITION ), ///< see ::XMR_HLDOVR_BIT_IN_TRANSITION + XMR_HLDOVR_MSK_TIME_OFFS_VALID = ( 1UL << XMR_HLDOVR_BIT_TIME_OFFS_VALID ) ///< see ::XMR_HLDOVR_BIT_TIME_OFFS_VALID }; + +/** + * @brief XMR source feature flag bits + * + * Used to define ::XMR_EXT_SRC_FEAT_FLAG_MSKS + */ +enum XMR_EXT_SRC_FEAT_FLAG_BITS +{ + XMR_EXT_SRC_FEAT_FLAG_BIT_STATS, ///< XMR source provides ::XMR_STATS + XMR_EXT_SRC_FEAT_FLAG_BIT_METRICS, ///< XMR source provides ::XMR_METRICS + N_XMR_EXT_SRC_FEAT_FLAG_BITS +}; + + + +/** + * @brief XMR source feature flag bit masks + * + * Used with ::XMR_EXT_SRC_INFO::feat_flags. + * + * @see ::XMR_EXT_SRC_FEAT_FLAG_BITS + */ +enum XMR_EXT_SRC_FEAT_FLAG_MSKS +{ + XMR_EXT_SRC_FEAT_FLAG_MSK_STATS = ( 1UL << XMR_EXT_SRC_FEAT_FLAG_BIT_STATS ), ///< see ::XMR_EXT_SRC_FEAT_FLAG_BIT_STATS + XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS = ( 1UL << XMR_EXT_SRC_FEAT_FLAG_BIT_METRICS ) ///< see ::XMR_EXT_SRC_FEAT_FLAG_BIT_METRICS +}; + + + typedef struct { uint16_t supp_flags; ///< indicates which flags are supported by ::XMULTI_REF_SETTINGS::flags, see ::XMR_SETTINGS_FLAG_MSKS - uint16_t reserved_0; - uint32_t reserved_1; + uint16_t feat_flags; ///< see ::XMR_EXT_SRC_FEAT_FLAG_MSKS + uint32_t reserved_0; } XMR_EXT_SRC_INFO; +#define _mbg_swab_xmr_ext_src_info( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->supp_flags ); \ + _mbg_swab16( &(_p)->feat_flags ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ +} while ( 0 ) + + typedef struct { @@ -5846,13 +7650,295 @@ typedef struct } XMR_EXT_SRC_INFO_IDX; // +#define _mbg_swab_xmr_ext_src_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmr_ext_src_info( &(_p)->info ); \ +} while ( 0 ) + + + +/** + * @brief XMR statistics for a particular source + * + * This structure is only provided by an XMR source which has + * ::XMR_EXT_SRC_FEAT_FLAG_MSK_STATS set in ::XMR_EXT_SRC_INFO::feat_flags. + * + * @see ::XMR_STATS_IDX + * @see ::XMR_EXT_SRC_INFO::feat_flags + * @see ::XMR_EXT_SRC_FEAT_FLAG_MSK_STATS + */ +typedef struct +{ + uint32_t timestamp; ///< time stamp when the record was taken, UTC, seconds since 1970 + NANO_TIME last_mue; ///< mean value (mue) of prev. interval + NANO_TIME last_sigma; ///< standard deviation (sigma) of prev. interval + NANO_TIME last_max; ///< maximum value within interval + NANO_TIME last_min; ///< minimum value within interval + NANO_TIME reserved_0; ///< currently reserved, unused, always 0 + NANO_TIME step_comp_val; ///< current step compensation value + NANO_TIME auto_bias; ///< current time automatic bias compensation + uint32_t reserved_1; ///< currently reserved, unused, always 0 + uint32_t reserved_2; ///< currently reserved, unused, always 0 + uint32_t flags; ///< see ::XMR_STATS_FLAGS_MSKS + +} XMR_STATS; + +#define _mbg_swab_xmr_stats( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->timestamp ); \ + _mbg_swab_nano_time( &(_p)->last_mue ); \ + _mbg_swab_nano_time( &(_p)->last_sigma ); \ + _mbg_swab_nano_time( &(_p)->last_max ); \ + _mbg_swab_nano_time( &(_p)->last_min ); \ + _mbg_swab_nano_time( &(_p)->reserved_0 ); \ + _mbg_swab_nano_time( &(_p)->step_comp_val ); \ + _mbg_swab_nano_time( &(_p)->auto_bias ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of bits used to define ::XMR_STATS_FLAGS_MSKS + * + * @see ::XMR_STATS_FLAGS_MSKS + */ +enum XMR_STATS_FLAGS_BITS +{ + XMR_STATS_FLAG_BIT_STEP_DETECTED, ///< A time step was detected at the input source + XMR_STATS_FLAG_BIT_STEP_COMPENSATED, ///< A time step was compensated at the input source + XMR_STATS_FLAG_BIT_AUTO_BIAS_VALID, ///< The value in ::XMR_STATS::auto_bias is valid + N_XMR_STATS_FLAGS_BITS +}; + + + +/** + * @brief Flag bit masks used with ::XMR_STATS::flags + * + * @see ::XMR_STATS_FLAGS_BITS + */ +enum XMR_STATS_FLAGS_MSKS +{ + XMR_STATS_FLAG_MSK_STEP_DETECTED = ( 1UL << XMR_STATS_FLAG_BIT_STEP_DETECTED ), ///< see ::XMR_STATS_FLAG_BIT_STEP_DETECTED + XMR_STATS_FLAG_MSK_STEP_COMPENSATED = ( 1UL << XMR_STATS_FLAG_BIT_STEP_COMPENSATED ), ///< see ::XMR_STATS_FLAG_BIT_STEP_COMPENSATED + XMR_STATS_FLAG_MSK_AUTO_BIAS_VALID = ( 1UL << XMR_STATS_FLAG_BIT_AUTO_BIAS_VALID ) ///< see ::XMR_STATS_FLAG_BIT_AUTO_BIAS_VALID +}; + + + +/** + * @brief String initializers for XMR Stats Flags + * + * @see ::XMR_STATS_FLAGS_MSKS + */ +#define DEFAULT_XMR_STATS_FLAG_NAMES \ +{ \ + "Step Detected", \ + "Step Compensated", \ + "Auto BIAS valid" \ +} + + + +/** + * @brief XMR statistics for a particular source, with index + * + * @see ::XMR_STATS + */ +typedef struct +{ + uint16_t idx; ///< the priority level index (highest == 0), 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 + XMR_STATS stats; ///< XMR statistics of the particular source + +} XMR_STATS_IDX; + +#define _mbg_swab_xmr_stats_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmr_stats( &(_p)->stats ); \ +} while ( 0 ) + + + +#define MAX_XMR_METRICS 20 + +typedef struct +{ + uint32_t timestamp; + uint32_t flags; ///< idx bit set if mtie[idx] is valid + uint8_t mtie_scale; ///< scale factors of MTIE + uint8_t tdev_scale; ///< scale factors of TDEV + uint16_t reserved_0; ///< currently unused + uint32_t reserved_1; ///< currently unused + uint32_t reserved_2; ///< currently unused + uint32_t mtie[MAX_XMR_METRICS]; ///< mtie scaled 32 bit fixed point unsigned + uint32_t tdev[MAX_XMR_METRICS]; ///< tdev scaled 32 bit fixed point unsigned + +} XMR_METRICS; + +#define _mbg_swab_xmr_metrics( _p ) \ +do \ +{ \ + int i; \ + \ + _mbg_swab32( &(_p)->timestamp ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab8( &(_p)->mtie_scale ); \ + _mbg_swab8( &(_p)->tdev_scale ); \ + _mbg_swab16( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + \ + for ( i = 0; i < MAX_XMR_METRICS; i++ ) \ + _mbg_swab32( &(_p)->mtie[i] ); \ + \ + for ( i = 0; i < MAX_XMR_METRICS; i++ ) \ + _mbg_swab32( &(_p)->tdev[i] ); \ + \ +} while ( 0 ) + + + +// conversion factor scaled FPU32 to double +#define _fpu32_to_double_fac( _x ) ( 1.0 / ( 4294967296.0 * ( _x ) ) ) + + + +/** + * @brief XMR timing metrics for a particular source, with index + * + * @see ::XMR_METRICS + */ +typedef struct +{ + uint16_t idx; + XMR_METRICS metrics; + +} XMR_METRICS_IDX; + +#define _mbg_swab_xmr_metrics_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmr_metrics( &(_p)->metrics ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of ITU limit masks + * + * Used for detection of ::XMR_METRICS mask violation. + * + * @see ::ITU_LIMIT_MASKS + * @see ::XMR_METRICS + */ +enum ITU_LIMITS +{ + ITU_LIMIT_G811_PRC, + ITU_LIMIT_G823_SSU, + ITU_LIMIT_G823_SEC, + ITU_LIMIT_G8272_PRTC, + ITU_LIMIT_G82721_EPRTC, + N_ITU_LIMITS +} ; + + + +/** + * @brief Enumeration of ITU limit masks + * + * Used for detection of ::XMR_METRICS mask violation. + * + * @see ::ITU_LIMITS + * @see ::XMR_METRICS + */ +enum ITU_LIMIT_MASKS +{ + MSK_ITU_LIMIT_G811_PRC = ( 1UL << ITU_LIMIT_G811_PRC ), + MSK_ITU_LIMIT_G823_SSU = ( 1UL << ITU_LIMIT_G823_SSU ), + MSK_ITU_LIMIT_G823_SEC = ( 1UL << ITU_LIMIT_G823_SEC ), + MSK_ITU_LIMIT_G8272_PRTC = ( 1UL << ITU_LIMIT_G8272_PRTC ), + MSK_ITU_LIMIT_G82721_EPRTC = ( 1UL << ITU_LIMIT_G82721_EPRTC ) +}; + + + +/** + * @brief String initializers for ITU limit masks + * + * Used for detection of ::XMR_METRICS mask violation. + * + * @see ::ITU_LIMITS + * @see ::XMR_METRICS + */ +#define ITU_LIMIT_SHORT_STRS \ +{ \ + "G811 (PRC)", \ + "G823 (SSU)", \ + "G823 (SEC)", \ + "G8272 (PRTC)", \ + "G82721 (ePRTC)" \ +} + + + +/** + * @brief supported limits for qualtity metrics + * + * @see ::XMR_METRICS + */ +typedef struct +{ + uint8_t ql_mask; ///< see :ITU_LIMIT_MASKS + uint8_t hysteresis; ///< hysteresis (percent) between yellow and red alarm + uint16_t reserved_0; + uint32_t reserved_1; + +} XMR_QL_SETTINGS; + + + +typedef struct +{ + uint32_t supp_ql_masks; ///< see :ITU_LIMIT_MASKS + uint32_t reserved_0; + uint32_t reserved_1; + XMR_QL_SETTINGS settings; + +} XMR_QL_INFO; + + + +typedef struct +{ + uint16_t idx; + XMR_QL_SETTINGS settings; + +} XMR_QL_SETTINGS_IDX; + + + +typedef struct +{ + uint16_t idx; + XMR_QL_INFO info; + +} XMR_QL_INFO_IDX; + /** @} defgroup group_multi_ref_ext */ /** @} defgroup group_multi_ref_all */ - /** * @defgroup group_gpio GPIO port configuration stuff * @@ -5879,11 +7965,12 @@ typedef struct } MBG_GPIO_CFG_LIMITS; #define _mbg_swab_mbg_gpio_cfg_limits( _p ) \ +do \ { \ _mbg_swab32( &(_p)->num_io ); \ _mbg_swab32( &(_p)->reserved ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) @@ -5926,22 +8013,31 @@ enum MBG_GPIO_CFG_LIMIT_FLAG_MASKS */ enum MBG_GPIO_TYPES { - MBG_GPIO_TYPE_FREQ_IN, ///< variable frequency input, freq == 0 if input not used - MBG_GPIO_TYPE_FREQ_OUT, ///< variable frequency output - MBG_GPIO_TYPE_FIXED_FREQ_OUT, ///< fixed frequency output - MBG_GPIO_TYPE_BITS_IN, ///< framed data stream input - MBG_GPIO_TYPE_BITS_OUT, ///< framed data stream output - N_MBG_GPIO_TYPES ///< number of known types + MBG_GPIO_TYPE_FREQ_IN, ///< Variable frequency input, freq == 0 if input not used + MBG_GPIO_TYPE_FREQ_OUT, ///< Variable frequency output + MBG_GPIO_TYPE_FIXED_FREQ_OUT, ///< Fixed frequency output + MBG_GPIO_TYPE_BITS_IN, ///< Framed data stream input + MBG_GPIO_TYPE_BITS_OUT, ///< Framed data stream output + MBG_GPIO_TYPE_VIDEO_OUT, ///< Video signal output (PAL, NTSC, ...) + MBG_GPIO_TYPE_VIDEO_SYNC_OUT, ///< Video sync signal output (H-Sync, V-Sync, ...) + MBG_GPIO_TYPE_STUDIO_CLOCK_OUT, ///< Studio clock output + MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT, ///< Digital Audio output (DARS, ...) + N_MBG_GPIO_TYPES ///< Number of known types }; + #define DEFAULT_GPIO_TYPES_SHORT_STRS \ { \ "Freq. In", \ "Freq. Out", \ "Fixed Freq Out", \ "BITS In", \ - "BITS Out" \ + "BITS Out", \ + "Video Out", \ + "Video Sync Out", \ + "Studio Clock Out", \ + "Digital Audio Out" \ } @@ -5964,6 +8060,7 @@ enum MBG_GPIO_SIGNAL_SHAPES }; + /** * @brief Bit masks associated with ::MBG_GPIO_SIGNAL_SHAPES * @@ -6009,10 +8106,11 @@ typedef struct } MBG_GPIO_FREQ; #define _mbg_swab_mbg_gpio_freq( _p ) \ +do \ { \ _mbg_swab32( &(_p)->hz ); \ _mbg_swab32( &(_p)->frac); \ -} +} while ( 0 ) @@ -6034,6 +8132,17 @@ typedef struct } MBG_GPIO_FREQ_IN_SETTINGS; +#define _mbg_swab_mbg_gpio_freq_in_settings( _p ) \ +do \ +{ \ + _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \ + _mbg_swab32( &(_p)->csc_limit ); \ + _mbg_swab32( &(_p)->shape ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + /** * @brief Supported options for a variable frequency GPIO input @@ -6049,11 +8158,22 @@ typedef struct uint32_t freq_max; ///< maximum output frequency [Hz] uint32_t csc_limit_max; ///< 1/1000 units of the signal period, limited due to 10 ns sampling interval, see ::MBG_GPIO_FREQ_IN_SETTINGS::csc_limit //##++++++++++++++++ uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS - uint32_t reserved; ///< reserved, currently always 0 + uint32_t supp_limits; ///< supported ITU limit masks for BITS signal see ::ITU_LIMIT_MASKS uint32_t flags; ///< reserved, currently always 0 } MBG_GPIO_FREQ_IN_SUPP; +#define _mbg_swab_mbg_gpio_freq_in_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->freq_min ); \ + _mbg_swab32( &(_p)->freq_max ); \ + _mbg_swab32( &(_p)->csc_limit_max ); \ + _mbg_swab32( &(_p)->supp_shapes ); \ + _mbg_swab32( &(_p)->supp_limits ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + /** @@ -6074,6 +8194,16 @@ typedef struct } MBG_GPIO_FREQ_OUT_SETTINGS; +#define _mbg_swab_mbg_gpio_freq_out_settings( _p ) \ +do \ +{ \ + _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \ + _mbg_swab32( &(_p)->milli_phase ); \ + _mbg_swab32( &(_p)->shape ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + /** @@ -6096,6 +8226,18 @@ typedef struct } MBG_GPIO_FREQ_OUT_SUPP; +#define _mbg_swab_mbg_gpio_freq_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->freq_min ); \ + _mbg_swab32( &(_p)->freq_max ); \ + _mbg_swab32( &(_p)->freq_resolution ); \ + _mbg_swab32( &(_p)->milli_phase_max ); \ + _mbg_swab32( &(_p)->supp_shapes ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + /** @@ -6117,6 +8259,7 @@ enum MBG_GPIO_FIXED_FREQS N_MBG_GPIO_FIXED_FREQ ///< number of predefined fixed frequencies }; + /** * @brief Bit masks associated with ::MBG_GPIO_FIXED_FREQS * @@ -6155,6 +8298,7 @@ enum MBG_GPIO_FIXED_FREQ_MASKS } + /** * @brief Configuration of a GPIO fixed frequency output * @@ -6172,6 +8316,16 @@ typedef struct } MBG_GPIO_FIXED_FREQ_OUT_SETTINGS; +#define _mbg_swab_mbg_gpio_fixed_freq_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->freq_idx ); \ + _mbg_swab32( &(_p)->shape ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + /** * @brief Supported options for a fixed frequency output @@ -6190,6 +8344,15 @@ typedef struct } MBG_GPIO_FIXED_FREQ_OUT_SUPP; +#define _mbg_swab_mbg_gpio_fixed_freq_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_freq ); \ + _mbg_swab32( &(_p)->supp_shapes ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + /** @@ -6208,6 +8371,7 @@ enum MBG_GPIO_BITS_FORMATS N_MBG_GPIO_BITS_FORMATS ///< number of defined formats }; + /** * @brief Bit masks associated with ::MBG_GPIO_BITS_FORMATS * @@ -6224,6 +8388,21 @@ enum MBG_GPIO_BITS_FORMAT_MASKS }; +/** + * @brief Initializers for an array of GPIO bit format strings + * + * @see ::MBG_GPIO_BITS_FORMATS + * @see ::MBG_GPIO_BITS_FORMAT_MASKS + */ +#define MBG_GPIO_BITS_FORMAT_STRS \ +{ \ + "E1 Framed", \ + "T1 Framed", \ + "E1 Timing", \ + "T1 Timing" \ +} + + /** * @brief Minimum and maximum known SSM values @@ -6269,6 +8448,7 @@ enum GPIO_SA_BITS_GROUPS }; + /** * @brief Configuration of a GPIO as BITS input module * @@ -6279,9 +8459,9 @@ enum GPIO_SA_BITS_GROUPS */ typedef struct { - uint32_t format; ///< signal format, see ::MBG_GPIO_BITS_FORMATS - uint32_t reserved; ///< reserved, currently always 0 - uint32_t csc_limit; ///< max. cycle slip [1/1000 cycle units] + uint32_t format; ///< signal format, see ::MBG_GPIO_BITS_FORMATS + uint32_t reserved; ///< reserved, currently always 0 + uint32_t csc_limit; ///< max. cycle slip [1/1000 cycle units] union quality { @@ -6308,6 +8488,38 @@ typedef struct } MBG_GPIO_BITS_IN_SETTINGS; +#define _mbg_swab_mbg_gpio_bits_in_settings( _p, _recv ) \ +do \ +{ \ + uint32_t f = (_p)->format; \ + if ( (_recv) ) \ + _mbg_swab32( &f); \ + _mbg_swab32( &(_p)->format ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->csc_limit ); \ + switch( f ) \ + { \ + case MBG_GPIO_BITS_E1_FRAMED : \ + case MBG_GPIO_BITS_E1_TIMING : \ + _mbg_swab8( &(_p)->quality.e1.ssm ); \ + _mbg_swab8( &(_p)->quality.e1.sa_bits ); \ + _mbg_swab16( &(_p)->quality.e1.reserved ); \ + break; \ + \ + case MBG_GPIO_BITS_T1_FRAMED : \ + case MBG_GPIO_BITS_T1_TIMING : \ + _mbg_swab8( &(_p)->quality.t1.min_boc ); \ + _mbg_swab8( &(_p)->quality.t1.reserved_0 ); \ + _mbg_swab16( &(_p)->quality.t1.reserved_1 ); \ + break; \ + \ + default: \ + break; \ + } \ + _mbg_swab32( &(_p)->err_msk ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + /** @@ -6320,6 +8532,7 @@ enum MBG_GPIO_BITS_ERRS N_MBG_GPIO_BITS_ERRS ///< number of known errors }; + /** * @brief Bit masks associated with BITS input error conditions * @@ -6334,6 +8547,7 @@ enum MBG_GPIO_BITS_ERR_MASKS }; + /** * @brief Supported options of a BITS GPIO input * @@ -6344,11 +8558,18 @@ enum MBG_GPIO_BITS_ERR_MASKS */ typedef struct { - uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS - uint32_t reserved; ///< reserved, currently always 0 + uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS + uint32_t reserved; ///< reserved, currently always 0 } MBG_GPIO_BITS_IN_SUPP; +#define _mbg_swab_mbg_gpio_bits_in_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_fmts ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + /** @@ -6373,9 +8594,27 @@ typedef struct } MBG_GPIO_BITS_OUT_SETTINGS; +#define _mbg_swab_mbg_gpio_bits_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->format ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab8( &(_p)->sa_bits ); \ + _mbg_swab8( &(_p)->ssm ); \ + _mbg_swab8( &(_p)->boc ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + /** * @brief Enumeration of flags used with BITS type GPIO outputs + * + * @see ::MBG_GPIO_BITS_OUT_FLAG_MASKS + * @see ::MBG_GPIO_BITS_OUT_FLAG_STRS */ enum MBG_GPIO_BITS_OUT_FLAGS { @@ -6384,12 +8623,14 @@ enum MBG_GPIO_BITS_OUT_FLAGS N_MBG_GPIO_BITS_OUT_FLAGS ///< number of known flags }; + /** * @brief Bit masks associated with ::MBG_GPIO_BITS_OUT_FLAGS * * Used with ::MBG_GPIO_BITS_OUT_SETTINGS::flags * * @see ::MBG_GPIO_BITS_OUT_FLAGS + * @see ::MBG_GPIO_BITS_OUT_FLAG_STRS */ enum MBG_GPIO_BITS_OUT_FLAG_MASKS { @@ -6399,6 +8640,19 @@ enum MBG_GPIO_BITS_OUT_FLAG_MASKS /** + * @brief String initializers for an array of GPIO BITS out flags + * + * @see ::MBG_GPIO_BITS_OUT_FLAGS + * @see ::MBG_GPIO_BITS_OUT_FLAG_MASKS + */ +#define MBG_GPIO_BITS_OUT_FLAG_STRS \ +{ \ + "HDB3", \ + "B8ZS" \ +} + + +/** * @brief Supported options of a BITS type GPIO output * * Used as sub-structure of ::MBG_GPIO_LIMITS. @@ -6408,11 +8662,814 @@ enum MBG_GPIO_BITS_OUT_FLAG_MASKS */ typedef struct { - uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS - uint32_t reserved; ///< reserved, currently always 0 + uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS + uint32_t supp_flags; ///< bit mask of supported flags, see ::MBG_GPIO_BITS_OUT_FLAG_MASKS } MBG_GPIO_BITS_OUT_SUPP; +#define _mbg_swab_mbg_gpio_bits_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_fmts ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of Video signal formats + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::format + * + * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS + */ +enum MBG_GPIO_VIDEO_FORMATS +{ + MBG_GPIO_VIDEO_FORMAT_OFF, ///< OFF + MBG_GPIO_VIDEO_SD_FORMAT_NTSC, ///< NTSC 525i + MBG_GPIO_VIDEO_SD_FORMAT_PAL, ///< PAL standard (Germany) 625i + MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz, ///< SMPTE296M-3 720p at 50 Hz + MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz, ///< SMPTE274M-6 1080i at 50 Hz + MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz, ///< SMPTE296M-1 720p at 59.94 Hz + MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz, ///< SMPTE274M-7 1080i at 59.94 Hz + MBG_GPIO_VIDEO_SD_FORMAT_PAL_M, ///< PAL M (Brazil) 525i + N_MBG_GPIO_VIDEO_FORMATS ///< number of defined video formats +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_FORMATS + * + * Used with ::MBG_GPIO_VIDEO_OUT_SUPP::supp_formats + * + * @see ::MBG_GPIO_VIDEO_FORMATS + */ +enum MBG_GPIO_VIDEO_FORMAT_MASKS +{ + MSK_MBG_GPIO_VIDEO_FORMAT_OFF = ( 1UL << MBG_GPIO_VIDEO_FORMAT_OFF ), ///< see ::MBG_GPIO_VIDEO_FORMAT_OFF + MSK_MBG_GPIO_VIDEO_SD_FORMAT_NTSC = ( 1UL << MBG_GPIO_VIDEO_SD_FORMAT_NTSC ), ///< see ::MBG_GPIO_VIDEO_SD_FORMAT_NTSC + MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL = ( 1UL << MBG_GPIO_VIDEO_SD_FORMAT_PAL ), ///< see ::MBG_GPIO_VIDEO_SD_FORMAT_PAL + MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz ), ///< see ::MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz + MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz ), ///< see ::MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz + MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz ), ///< see ::MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz + MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz ), ///< see ::MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz + MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL_M = ( 1UL << MBG_GPIO_VIDEO_SD_FORMAT_PAL_M ) ///< see ::MBG_GPIO_VIDEO_SD_FORMAT_PAL_M +}; + + +/** + * @brief A combination of bit masks for SD video formats + * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS + */ +#define MBG_GPIO_VIDEO_SD_FORMATS ( MSK_MBG_GPIO_VIDEO_FORMAT_OFF | MSK_MBG_GPIO_VIDEO_SD_FORMAT_NTSC | MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL | \ + MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL_M ) + +/** + * @brief A combination of bit masks for HD video formats + * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS + */ +#define MBG_GPIO_VIDEO_HD_FORMATS ( MSK_MBG_GPIO_VIDEO_FORMAT_OFF | MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz | MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz | \ + MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz | MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz ) + + + +/** + * @brief Initializers for an array of video output name strings + * + * @see ::MBG_GPIO_VIDEO_FORMATS + * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS + */ +#define MBG_GPIO_VIDEO_OUT_STRS \ +{ \ + "OFF", \ + "NTSC (525i)", \ + "PAL (625i)", \ + "720p 50 Hz", \ + "1080i 50 Hz", \ + "720p 59.94 Hz", \ + "1080i 59.94 Hz", \ + "PAL M (525i)" \ +} + + + +/** + * @brief Enumeration of flags used with video type GPIO outputs + */ +enum MBG_GPIO_VIDEO_OUT_FLAGS +{ + MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF, ///< if set, Out1: HD, Out2: SD + MBG_GPIO_VIDEO_OUT_HAS_TC_SD, ///< supports Time Code for SD Black Bursts + N_MBG_GPIO_VIDEO_OUT_FLAGS ///< number of known flags +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_OUT_FLAGS + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::flags + * + * @see ::MBG_GPIO_VIDEO_OUT_FLAGS + */ +enum MBG_GPIO_VIDEO_OUT_FLAG_MASKS +{ + MSK_MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF = ( 1UL << MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF ), ///< see ::MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF + MSK_MBG_GPIO_VIDEO_OUT_HAS_TC_SD = ( 1UL << MBG_GPIO_VIDEO_OUT_HAS_TC_SD ) ///< see ::MBG_GPIO_VIDEO_OUT_HAS_TC_SD +}; + + + +/** + * @brief Enumeration of epochs used with video type GPIO outputs + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::epoch, and used to + * define ::MBG_GPIO_VIDEO_EPOCH_MASKS + * + * @see ::MBG_GPIO_VIDEO_EPOCH_MASKS + * @see ::MBG_GPIO_VIDEO_EPOCH_STRS + */ +enum MBG_GPIO_VIDEO_EPOCHS +{ + SMPTE_TAI_EPOCH_1970, ///< 1970-01-01 00:00:00 + SMPTE_TAI_EPOCH_1958, ///< 1958-01-01 00:00:00 + SMPTE_UTC_EPOCH_1972, ///< 1972-01-01 00:00:00 + SMPTE_GPS_EPOCH_1980, ///< 1980-01-06 00:00:00 + N_MBG_GPIO_VIDEO_EPOCHS ///< number of known epochs +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_EPOCHS + * + * Used with :: MBG_GPIO_VIDEO_OUT_SUPP::supp_epochs + * + * @see ::MBG_GPIO_VIDEO_EPOCHS + */ +enum MBG_GPIO_VIDEO_EPOCH_MASKS +{ + MSK_SMPTE_TAI_EPOCH_1970 = ( 1UL << SMPTE_TAI_EPOCH_1970 ), ///< see ::SMPTE_TAI_EPOCH_1970 + MSK_SMPTE_TAI_EPOCH_1958 = ( 1UL << SMPTE_TAI_EPOCH_1958 ), ///< see ::SMPTE_TAI_EPOCH_1958 + MSK_SMPTE_UTC_EPOCH_1972 = ( 1UL << SMPTE_UTC_EPOCH_1972 ), ///< see ::SMPTE_UTC_EPOCH_1972 + MSK_SMPTE_GPS_EPOCH_1980 = ( 1UL << SMPTE_GPS_EPOCH_1980 ) ///< see ::SMPTE_GPS_EPOCH_1980 +}; + + + +/** + * @brief Initializers for an array of video epoch strings + * + * @see ::MBG_GPIO_VIDEO_EPOCHS + */ +#define MBG_GPIO_VIDEO_EPOCH_STRS \ +{ \ + "TAI D1970-01-01 T00:00:00", \ + "TAI D1958-01-01 T00:00:00", \ + "UTC D1972-01-01 T00:00:00", \ + "GPS D1980-01-06 T00:00:00" \ +} + + + +/** + * @brief Enumeration of time code modes used with video type GPIO outputs + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::tc_mode + * + */ +enum MBG_GPIO_VIDEO_TC_MODES +{ + MBG_GPIO_VIDEO_TC_MODE_NONE, ///< None + MBG_GPIO_VIDEO_TC_MODE_VITC, ///< Vertical Interval Time Code + N_MBG_GPIO_VIDEO_TC_MODES +}; + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_TC_MODES + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::tc_mode + * + */ +enum MBG_GPIO_VIDEO_TC_MODE_MASKS +{ + MSK_MBG_GPIO_VIDEO_TC_MODE_NONE = ( 1UL << MBG_GPIO_VIDEO_TC_MODE_NONE ), ///< see ::MBG_GPIO_VIDEO_TC_MODE_NONE + MSK_MBG_GPIO_VIDEO_TC_MODE_VITC = ( 1UL << MBG_GPIO_VIDEO_TC_MODE_VITC ) ///< see ::MBG_GPIO_VIDEO_TC_MODE_VITC +}; + + +/** + * @brief Initializers for an array of video time code modes + * + * @see ::MBG_GPIO_VIDEO_TC_MODES + */ +#define MBG_GPIO_VIDEO_TC_MODE_STRS \ +{ \ + "None", \ + "VITC" \ +} + + + +/** + * @brief Configuration of a GPIO as video output module + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_VIDEO_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t format; ///< video format, see ::MBG_GPIO_VIDEO_FORMATS + uint32_t flags; ///< flags, see ::MBG_GPIO_VIDEO_OUT_FLAG_MASKS + int32_t phase_offset; ///< Phase offset in [ns] + uint8_t epoch; ///< epoch, see ::MBG_GPIO_VIDEO_EPOCHS + + uint8_t tc_mode; ///< time code mode, see ::MBG_GPIO_VIDEO_TC_MODES + uint8_t tc_line0; ///< first time code line location, valid lines: 6-22 + uint8_t tc_line1; ///< second time code line location, valid lines: 6-22 + + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + +} MBG_GPIO_VIDEO_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_video_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->format ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->phase_offset ); \ + _mbg_swab8( &(_p)->epoch ); \ + _mbg_swab8( &(_p)->tc_mode ); \ + _mbg_swab8( &(_p)->tc_line0 ); \ + _mbg_swab8( &(_p)->tc_line1 ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ +} while ( 0 ) + + + +/** + * @brief Supported options of a video type GPIO output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_VIDEO_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_formats; ///< supported video formats, see ::MBG_GPIO_VIDEO_FORMAT_MASKS + uint32_t supp_flags; ///< supported flags, see ::MBG_GPIO_VIDEO_OUT_FLAG_MASKS + uint32_t supp_epochs; ///< supported epochs, see ::MBG_GPIO_VIDEO_EPOCH_MASKS + + uint8_t supp_tc_modes; ///< supported tc_modes, see ::MBG_GPIO_VIDEO_TC_MODE_MASKS + + uint8_t reserved0; ///< reserved, currently always 0 + uint8_t reserved2; ///< reserved, currently always 0 + uint16_t reserved3; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + +} MBG_GPIO_VIDEO_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_video_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_formats ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->supp_epochs ); \ + _mbg_swab8( &(_p)->supp_tc_modes ); \ + _mbg_swab8( &(_p)->reserved0 ); \ + _mbg_swab16( &(_p)->reserved2 ); \ + _mbg_swab16( &(_p)->reserved3 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of types used with video sync GPIO outputs + * Depends on configured video output + */ +enum MBG_GPIO_VIDEO_SYNC_TYPES +{ + MBG_GPIO_VIDEO_SYNC_TYPE_OFF, ///< Output Off + MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC, ///< SD horizontal sync + MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC, ///< SD vertical sync + MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME, ///< SD frame/field sync + MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK, ///< SD blanking interval + MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC, ///< HD horizontal sync + MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC, ///< HD vertical sync + MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME, ///< HD frame/field sync + MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK, ///< HD blanking interval + N_MBG_GPIO_VIDEO_SYNC_TYPES ///< number of known types +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_SYNC_TYPES + * + * Used with ::MBG_GPIO_VIDEO_SYNC_OUT_SUPP::supp_types + * + * @see ::MBG_GPIO_VIDEO_SYNC_TYPES + */ +enum MBG_GPIO_VIDEO_SYNC_TYPE_MASKS +{ + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_OFF = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_OFF ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK ) +}; + + + +/** + * @brief Initializers for an array of video sync output name strings + * + * @see ::MBG_GPIO_VIDEO_SYNC_TYPES + * @see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS + */ +#define MBG_GPIO_VIDEO_SYNC_OUT_STRS \ +{ \ + "OFF", \ + "SD H-Sync", \ + "SD V-Sync", \ + "SD Frame", \ + "SD Blank", \ + "HD H-Sync", \ + "HD V-Sync", \ + "HD Frame", \ + "HD Blank" \ +} + + + +/** + * @brief A combination of bit masks for SD video sync types + * @see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS + */ +#define MBG_GPIO_VIDEO_SYNC_SD_TYPES ( MSK_MBG_GPIO_VIDEO_SYNC_TYPE_OFF | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC | \ + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK ) + +/** + * @brief A combination of bit masks for HD video sync types + * @see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS + */ +#define MBG_GPIO_VIDEO_SYNC_HD_TYPES ( MSK_MBG_GPIO_VIDEO_SYNC_TYPE_OFF | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC | \ + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK ) + + + +/** + * @brief Configuration of a GPIO as sync output module + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t type; ///< sync type, see :: MBG_GPIO_SYNC_TYPES + uint32_t flags; ///< flags, currently always 0 + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + uint32_t reserved2; ///< reserved, currently always 0 + uint32_t reserved3; ///< reserved, currently always 0 + +} MBG_GPIO_VIDEO_SYNC_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_video_sync_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->type ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ + _mbg_swab32( &(_p)->reserved2 ); \ + _mbg_swab32( &(_p)->reserved3 ); \ +} while ( 0 ) + + + +/** + * @brief Supported options of a sync type GPIO output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_types; ///< supported types, see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS + uint32_t supp_flags; ///< supported flags, currently always 0 + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + +} MBG_GPIO_VIDEO_SYNC_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_video_sync_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_types ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of studio clock base frequencies + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS::base_freq + * + * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS + */ +enum MBG_GPIO_STUDIO_CLOCK_BASE_FREQS +{ + MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ, ///< 32 kHz base frequency + MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ, ///< 44.1 kHz base frequency + MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ, ///< 48 kHz base frequency + N_MBG_GPIO_STUDIO_CLOCK_BASE_FREQS ///< number of defined base frequencies +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SUPP::supp_base_freqs + * + * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS + */ +enum MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS +{ + MSK_MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ = ( 1UL << MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ ), ///< see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ + MSK_MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ = ( 1UL << MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ ), ///< see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ + MSK_MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ = ( 1UL << MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ ) ///< see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ +}; + + + +/** + * @brief Initializers for an array of base frequencies of studio clock output name strings + * + * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS + * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS + */ +#define MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_STRS \ +{ \ + "32 kHz", \ + "44.1 kHz", \ + "48 kHz" \ +} + + + +/** + * @brief Enumeration of studio clock scales + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS::scale + * Multiply scale with base frequency + * + * @see ::MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS + */ +enum MBG_GPIO_STUDIO_CLOCK_SCALES +{ + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32, + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16, + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8, + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4, + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2, + MBG_GPIO_STUDIO_CLOCK_SCALE_1, + MBG_GPIO_STUDIO_CLOCK_SCALE_2, + MBG_GPIO_STUDIO_CLOCK_SCALE_4, + MBG_GPIO_STUDIO_CLOCK_SCALE_8, + MBG_GPIO_STUDIO_CLOCK_SCALE_16, + MBG_GPIO_STUDIO_CLOCK_SCALE_32, + MBG_GPIO_STUDIO_CLOCK_SCALE_64, + MBG_GPIO_STUDIO_CLOCK_SCALE_128, + MBG_GPIO_STUDIO_CLOCK_SCALE_256, + MBG_GPIO_STUDIO_CLOCK_SCALE_512, + N_MBG_GPIO_STUDIO_CLOCK_SCALES ///< number of defined scales +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_STUDIO_CLOCK_SCALES + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SUPP::supp_scales[N_MBG_GPIO_STUDIO_CLOCK_BASE_FREQS] + * + * @see ::MBG_GPIO_STUDIO_CLOCK_SCALES + */ +enum MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS +{ + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_1 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_2 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_2 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_2 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_4 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_4 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_4 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_8 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_8 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_8 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_16 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_16 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_16 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_32 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_32 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_32 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_64 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_64 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_64 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_128 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_128 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_128 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_256 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_256 ), ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_256 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_512 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_512 ) ///< see ::MBG_GPIO_STUDIO_CLOCK_SCALE_512 +}; + + + +/** + * @brief Initializers for an array of scales of studio clock output name strings + * + * @see ::MBG_GPIO_STUDIO_CLOCK_SCALES + * @see ::MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS + */ +#define MBG_GPIO_STUDIO_CLOCK_SCALE_STRS \ +{ \ + "1/32", \ + "1/16", \ + "1/8", \ + "1/4", \ + "1/2", \ + "1", \ + "2", \ + "4", \ + "8", \ + "16", \ + "32", \ + "64", \ + "128", \ + "256", \ + "512" \ +} + + + +/** + * @brief Enumeration of flags used with studio clock type GPIO outputs + */ +enum MBG_GPIO_STUDIO_CLOCK_FLAGS +{ + MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED, ///< if set, enables output + N_MBG_GPIO_STUDIO_CLOCK_FLAGS ///< number of known flags +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_STUDIO_CLOCK_FLAGS + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS::flags + * + * @see ::MBG_GPIO_STUDIO_CLOCK_FLAGS + */ +enum MBG_GPIO_STUDIO_CLOCK_FLAG_MASKS +{ + MSK_MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED = ( 1UL << MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED ) ///< see ::MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED +}; + + + +/** + * @brief Configuration of a GPIO as studio clock output module + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t base_freq; ///< base frequency, see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS + uint32_t scale; ///< scale, see ::MBG_GPIO_STUDIO_CLOCK_SCALES + uint32_t flags; ///< flags, see ::MBG_GPIO_STUDIO_CLOCK_FLAGS + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + +} MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_studio_clock_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->base_freq ); \ + _mbg_swab32( &(_p)->scale ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ +} while ( 0 ) + + + +#define MAX_SUPP_BASE_FREQUENCIES 8 ///< max. supported base frequencies for studio clock outputs + +/** + * @brief Configuration of a GPIO as studio clock output module + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint8_t supp_base_freqs; ///< supported base frequencies, see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS + uint8_t reserved0; ///< reserved, currently always 0 + uint16_t reserved1; ///< reserved, currently always 0 + uint16_t supp_scales[MAX_SUPP_BASE_FREQUENCIES]; ///< supported scales for each base frequency, see ::MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS + uint32_t supp_flags; ///< supported flags, see::MBG_GPIO_STUDIO_CLOCK_FLAG_MASKS + uint32_t reserved2; ///< reserved, currently always 0 + +} MBG_GPIO_STUDIO_CLOCK_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_studio_clock_out_supp( _p ) \ +do \ +{ \ + uint8_t idx; \ + _mbg_swab8( &(_p)->supp_base_freqs ); \ + _mbg_swab8( &(_p)->reserved0 ); \ + _mbg_swab16( &(_p)->reserved1 ); \ + for( idx = 0; idx < MAX_SUPP_BASE_FREQUENCIES; idx++ ) \ + _mbg_swab16( &(_p)->supp_scales[idx] ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved2 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of types used with GPIO type digital audio outputs + * + * Used with ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT_SETTINGS::type, and used to + * define ::MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS + * + * @see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS + * @see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_STRS + */ +enum MBG_GPIO_DIGITAL_AUDIO_TYPES +{ + MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF, + MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS, ///< DARS + N_MBG_GPIO_DIGITAL_AUDIO_TYPES ///< number of known types +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_DIGITAL_AUDIO_TYPES + * + * Used with :: MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT_SUPP::supp_types + * + * @see ::MBG_GPIO_DIGITAL_AUDIO_TYPES + */ +enum MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS +{ + MSK_MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF = ( 1UL << MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF ), ///< see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF + MSK_MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS = ( 1UL << MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS ) ///< see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS +}; + + + +/** + * @brief Initializers for an array of video epoch strings + * + * @see ::MBG_GPIO_VIDEO_EPOCHS + */ +#define MBG_GPIO_DIGITAL_AUDIO_TYPE_STRS \ +{ \ + "OFF", \ + "DARS" \ +} + + + +/** + * @brief Enumeration of flags used with GPIO type digital audio outputs + */ +enum MBG_GPIO_DIGITAL_AUDIO_FLAGS +{ + MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG, ///< reserved + N_MBG_GPIO_DIGITAL_AUDIO_FLAGS ///< number of known flags +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_DIGITAL_AUDIO_FLAGS + * + * Used with ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT_SETTINGS::flags + * + * @see ::MBG_GPIO_DIGITAL_AUDIO_FLAGS + */ +enum MBG_GPIO_DIGITAL_AUDIO_FLAG_MASKS +{ + MSK_MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG = ( 1UL << MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG ) ///< see ::MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG +}; + + + +/** + * @brief Configuration of a GPIO digital audio output + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t type; ///< digital audio type, see ::MBG_GPIO_DIGITAL_AUDIO_TYPES + uint32_t flags; ///< reserved, currently always 0 + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + uint32_t reserved2; ///< reserved, currently always 0 + +} MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_digital_audio_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->type ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ + _mbg_swab32( &(_p)->reserved2 ); \ +} while ( 0 ) + + + +/** + * @brief Supported options for digital audio output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_types; ///< supported digital audio types, see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS + uint32_t supp_flags; ///< reserved, currently always 0 + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + uint32_t reserved2; ///< reserved, currently always 0 + +} MBG_GPIO_DIGITAL_AUDIO_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_digital_audio_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_types ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ + _mbg_swab32( &(_p)->reserved2 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of general flags used with a GPIO + * + * @see ::MBG_GPIO_FLAG_MASKS + */ +enum MBG_GPIO_FLAGS +{ + MBG_GPIO_DEPENDS_ON_ASS_IO_IDX, ///< indicates that this output depends on GPIO with ::MBG_GPIO_SETTINGS::ass_io_idx and may not be configured independently + N_MBG_GPIO_FLAGS ///< number of known flags +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_FLAGS + * + * Used with ::MBG_GPIO_LIMITS::flags and ::MBG_GPIO_SETTINGS::flags + * + * @see ::MBG_GPIO_FLAGS + */ +enum MBG_GPIO_FLAG_MASKS +{ + MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX = ( 1UL << MBG_GPIO_DEPENDS_ON_ASS_IO_IDX ) ///< see ::MBG_GPIO_DEPENDS_ON_ASS_IO_IDX +}; + /** @@ -6420,22 +9477,56 @@ typedef struct */ typedef struct { - uint32_t type; ///< GPIO type, see ::MBG_GPIO_TYPES - uint32_t reserved; ///< reserved, currently always 0 - uint32_t flags; ///< reserved, currently always 0 + uint32_t type; ///< GPIO type, see ::MBG_GPIO_TYPES + + uint16_t reserved_1; ///< reserved, currently always 0 + uint8_t reserved_2; ///< reserved, currently always 0 + uint8_t ass_io_idx; ///< associated GPIO index, only valid if ::MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX is set in flags field + + uint32_t flags; ///< flags, see ::MBG_GPIO_FLAG_MASKS /// settings depending on the GPIO type, see ::MBG_GPIO_TYPES union { - MBG_GPIO_FREQ_IN_SETTINGS freq_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_IN - MBG_GPIO_FREQ_OUT_SETTINGS freq_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_OUT - MBG_GPIO_FIXED_FREQ_OUT_SETTINGS ff_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT - MBG_GPIO_BITS_IN_SETTINGS bits_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_IN - MBG_GPIO_BITS_OUT_SETTINGS bits_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_OUT + MBG_GPIO_FREQ_IN_SETTINGS freq_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_IN + MBG_GPIO_FREQ_OUT_SETTINGS freq_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_OUT + MBG_GPIO_FIXED_FREQ_OUT_SETTINGS ff_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT + MBG_GPIO_BITS_IN_SETTINGS bits_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_IN + MBG_GPIO_BITS_OUT_SETTINGS bits_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_OUT + MBG_GPIO_VIDEO_OUT_SETTINGS video_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_OUT + MBG_GPIO_VIDEO_SYNC_OUT_SETTINGS video_sync_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT + MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS studio_clk_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT + MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS digital_audio_out; ///< if ::MBG_GPIO_SETTINGS::type is ::;MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT } u; } MBG_GPIO_SETTINGS; +#define _mbg_swab_mbg_gpio_settings( _p, _recv ) \ +do \ +{ \ + uint32_t t = (_p)->type; \ + if ( (_recv) ) \ + _mbg_swab32( &t ); \ + _mbg_swab32( &(_p)->type ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab8( &(_p)->reserved_2 ); \ + _mbg_swab8( &(_p)->ass_io_idx ); \ + _mbg_swab32( &(_p)->flags ); \ + switch( t ) \ + { \ + case MBG_GPIO_TYPE_FREQ_IN : _mbg_swab_mbg_gpio_freq_in_settings( &(_p)->u.freq_in ); break; \ + case MBG_GPIO_TYPE_FREQ_OUT : _mbg_swab_mbg_gpio_freq_out_settings( &(_p)->u.freq_out ); break; \ + case MBG_GPIO_TYPE_FIXED_FREQ_OUT : _mbg_swab_mbg_gpio_fixed_freq_out_settings( &(_p)->u.ff_out ); break; \ + case MBG_GPIO_TYPE_BITS_IN : _mbg_swab_mbg_gpio_bits_in_settings( &(_p)->u.bits_in, (_recv) ); break; \ + case MBG_GPIO_TYPE_BITS_OUT : _mbg_swab_mbg_gpio_bits_out_settings( &(_p)->u.bits_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_OUT : _mbg_swab_mbg_gpio_video_out_settings( &(_p)->u.video_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_SYNC_OUT : _mbg_swab_mbg_gpio_video_sync_out_settings( &(_p)->u.video_sync_out ); break; \ + case MBG_GPIO_TYPE_STUDIO_CLOCK_OUT : _mbg_swab_mbg_gpio_studio_clock_out_settings( &(_p)->u.studio_clk_out ); break; \ + case MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT : _mbg_swab_mbg_gpio_digital_audio_out_settings( &(_p)->u.digital_audio_out ); break; \ + default : break; \ + } \ +} while ( 0 ) + /** @@ -6448,6 +9539,13 @@ typedef struct } MBG_GPIO_SETTINGS_IDX; +#define _mbg_swab_mbg_gpio_settings_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_mbg_gpio_settings( &(_p)->settings, (_recv ) ); \ +} while ( 0 ) + /** @@ -6457,20 +9555,48 @@ typedef struct { uint32_t type; ///< GPIO type, see ::MBG_GPIO_TYPES uint32_t reserved; ///< reserved, currently always 0 - uint32_t supp_flags; ///< supported flags //##++++++++++++ which? + uint32_t supp_flags; ///< supported flags, see ::MBG_GPIO_FLAG_MASKS /// limits depending on the GPIO type, see ::MBG_GPIO_TYPES union { - MBG_GPIO_FREQ_IN_SUPP freq_in; ///< if type is ::MBG_GPIO_TYPE_FREQ_IN - MBG_GPIO_FREQ_OUT_SUPP freq_out; ///< if type is ::MBG_GPIO_TYPE_FREQ_OUT - MBG_GPIO_FIXED_FREQ_OUT_SUPP ff_out; ///< if type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT - MBG_GPIO_BITS_IN_SUPP bits_in; ///< if type is ::MBG_GPIO_TYPE_BITS_IN - MBG_GPIO_BITS_OUT_SUPP bits_out; ///< if type is ::MBG_GPIO_TYPE_BITS_OUT + MBG_GPIO_FREQ_IN_SUPP freq_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_IN + MBG_GPIO_FREQ_OUT_SUPP freq_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_OUT + MBG_GPIO_FIXED_FREQ_OUT_SUPP ff_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT + MBG_GPIO_BITS_IN_SUPP bits_in; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_IN + MBG_GPIO_BITS_OUT_SUPP bits_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_OUT + MBG_GPIO_VIDEO_OUT_SUPP video_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_OUT + MBG_GPIO_VIDEO_SYNC_OUT_SUPP video_sync_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT + MBG_GPIO_STUDIO_CLOCK_OUT_SUPP studio_clk_out; ///< if ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT + MBG_GPIO_DIGITAL_AUDIO_OUT_SUPP digital_audio_out; ///< if ::MBG_GPIO_SETTINGS::type is ::;MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT } u; } MBG_GPIO_LIMITS; +#define _mbg_swab_mbg_gpio_limits( _p, _recv ) \ +do \ +{ \ + uint32_t t = (_p)->type; \ + if ( (_recv) ) \ + _mbg_swab32( &t ); \ + _mbg_swab32( &(_p)->type ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + switch( t ) \ + { \ + case MBG_GPIO_TYPE_FREQ_IN : _mbg_swab_mbg_gpio_freq_in_supp( &(_p)->u.freq_in ); break; \ + case MBG_GPIO_TYPE_FREQ_OUT : _mbg_swab_mbg_gpio_freq_out_supp( &(_p)->u.freq_out ); break; \ + case MBG_GPIO_TYPE_FIXED_FREQ_OUT : _mbg_swab_mbg_gpio_fixed_freq_out_supp( &(_p)->u.ff_out ); break; \ + case MBG_GPIO_TYPE_BITS_IN : _mbg_swab_mbg_gpio_bits_in_supp( &(_p)->u.bits_in ); break; \ + case MBG_GPIO_TYPE_BITS_OUT : _mbg_swab_mbg_gpio_bits_out_supp( &(_p)->u.bits_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_OUT : _mbg_swab_mbg_gpio_video_out_supp( &(_p)->u.video_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_SYNC_OUT : _mbg_swab_mbg_gpio_video_sync_out_supp( &(_p)->u.video_sync_out ); break; \ + case MBG_GPIO_TYPE_STUDIO_CLOCK_OUT : _mbg_swab_mbg_gpio_studio_clock_out_supp( &(_p)->u.studio_clk_out ); break; \ + case MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT : _mbg_swab_mbg_gpio_digital_audio_out_supp( &(_p)->u.digital_audio_out ); break; \ + default : break; \ + } \ +} while ( 0 ) + /** @@ -6484,6 +9610,13 @@ typedef struct } MBG_GPIO_INFO; +#define _mbg_swab_mbg_gpio_info( _p, _recv ) \ +do \ +{ \ + _mbg_swab_mbg_gpio_settings( &(_p)->settings, (_recv) ); \ + _mbg_swab_mbg_gpio_limits( &(_p)->limits, (_recv) ); \ +} while ( 0 ) + /** * @brief A GPIO port's current settings and limits, plus port index @@ -6495,6 +9628,13 @@ typedef struct } MBG_GPIO_INFO_IDX; +#define _mbg_swab_mbg_gpio_info_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_mbg_gpio_info( &(_p)->info, (_recv) ); \ +} while ( 0 ) + /** @@ -6510,6 +9650,16 @@ typedef struct } MBG_GPIO_STATUS; +#define _mbg_swab_mbg_gpio_status( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->port_state ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + /** @@ -6522,6 +9672,13 @@ typedef struct } MBG_GPIO_STATUS_IDX; +#define _mbg_swab_mbg_gpio_status_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_gpio_status( &(_p)->status ); \ +} while ( 0 ) + /** @@ -6658,13 +9815,14 @@ typedef struct } HAVEQUICK_SETTINGS; #define _mbg_swab_havequick_settings( _p ) \ +do \ { \ _mbg_swab16( &(_p)->format ); \ _mbg_swab16( &(_p)->flags ); \ _mbg_swab32( &(_p)->offset ); \ _mbg_swab32( &(_p)->reserved_0 ); \ _mbg_swab32( &(_p)->reserved_1 ); \ -} +} while ( 0 ) /** * @brief Current settings and capabilities of a HaveQuick input or output @@ -6679,12 +9837,13 @@ typedef struct } HAVEQUICK_INFO; #define _mbg_swab_havequick_info( _p ) \ +do \ { \ _mbg_swab_havequick_settings( &(_p)->settings ); \ _mbg_swab32( &(_p)->supp_formats ); \ _mbg_swab16( &(_p)->supp_flags ); \ _mbg_swab16( &(_p)->reserved ); \ -} +} while ( 0 ) /** @@ -6737,17 +9896,18 @@ typedef struct } MBG_NUM_EVT_LOG_ENTRIES; #define _mbg_swab_mbg_num_evt_log_entries( _p ) \ +do \ { \ _mbg_swab32( &(_p)->used ); \ _mbg_swab32( &(_p)->max ); \ -} +} while ( 0 ) typedef uint16_t MBG_EVT_CODE; -#define _mbg_swab_evt_code( _p ) _mbg_swab16( _p ); +#define _mbg_swab_evt_code( _p ) _mbg_swab16( _p ) typedef uint16_t MBG_EVT_INFO; -#define _mbg_swab_evt_info( _p ) _mbg_swab16( _p ); +#define _mbg_swab_evt_info( _p ) _mbg_swab16( _p ) /** * @brief An event log entry @@ -6761,11 +9921,12 @@ typedef struct } MBG_EVT_LOG_ENTRY; #define _mbg_swab_mbg_evt_log_entry( _p ) \ +do \ { \ _mbg_swab32( &(_p)->time ); \ _mbg_swab_evt_code( &(_p)->code ); \ _mbg_swab_evt_info( &(_p)->info ); \ -} +} while ( 0 ) // ::MBG_EVT_LOG_ENTRY::code is a combination of some bits used for the ID, @@ -6928,11 +10089,12 @@ typedef struct } MBG_IMS_STATE; #define _mbg_swab_mbg_ims_state( _p ) \ +do \ { \ _mbg_swab16( &(_p)->num_sensors ); \ _mbg_swab32( &(_p)->reserved ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) @@ -6955,7 +10117,7 @@ enum MBG_IMS_STATE_FLAG_BITS */ enum MBG_IMS_STATE_FLAG_MASKS { - MBG_IMS_STATE_FLAG_MSK_HAS_FDM = ( 1UL << MBG_IMS_STATE_FLAG_BIT_HAS_FDM ) ///< see ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM + MBG_IMS_STATE_FLAG_MSK_HAS_FDM = ( 1UL << MBG_IMS_STATE_FLAG_BIT_HAS_FDM ) ///< see ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM }; @@ -6975,6 +10137,7 @@ typedef struct } MBG_IMS_SENSOR_STATE; #define _mbg_swab_mbg_ims_sensor_state( _p ) \ +do \ { \ _mbg_swab16( &(_p)->type ); \ _mbg_swab16( &(_p)->idx ); \ @@ -6982,7 +10145,7 @@ typedef struct _mbg_swab16( &(_p)->exp ); \ _mbg_swab16( &(_p)->reserved ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) /** @@ -6996,10 +10159,11 @@ typedef struct } MBG_IMS_SENSOR_STATE_IDX; #define _mbg_swab_mbg_ims_sensor_state_idx( _p ) \ +do \ { \ _mbg_swab32( &(_p)->idx ); \ _mbg_swab_mbg_ims_sensor_state( &(_p)->state ); \ -} +} while ( 0 ) @@ -7052,8 +10216,8 @@ typedef struct int32_t dac_val_min; ///< min. possible DAC Value, positive or negative int32_t dac_val_max; ///< max. possible DAC Value, positive or negative - int32_t u_min; ///< min. possible real voltage range, positive or negative, depending on ::MBG_DAC_SPECS::dac_val_min - int32_t u_max; ///< max. possible real voltage range, positive or negative, depending on ::MBG_DAC_SPECS::dac_val_max + int32_t u_min; ///< min. possible real voltage range [mV], positive or negative, depending on ::MBG_DAC_SPECS::dac_val_min + int32_t u_max; ///< max. possible real voltage range [mV], positive or negative, depending on ::MBG_DAC_SPECS::dac_val_max uint32_t reserved_0; ///< reserved, currently always 0 uint32_t reserved_1; ///< reserved, currently always 0 @@ -7061,14 +10225,15 @@ typedef struct } MBG_DAC_SPECS; #define _mbg_swab_mbg_dac_specs( _p ) \ +do \ { \ _mbg_swab32( &(_p)->dac_val_min ); \ - _mbg_swab32( &(-p)->dac_val_max ); \ - _mbg_swab32( &(_P)->u_min ); \ + _mbg_swab32( &(_p)->dac_val_max ); \ + _mbg_swab32( &(_p)->u_min ); \ _mbg_swab32( &(_p)->u_max ); \ _mbg_swab32( &(_p)->reserved_0 ); \ _mbg_swab32( &(_p)->reserved_1 ); \ -} +} while ( 0 ) @@ -7090,13 +10255,15 @@ typedef struct } MBG_IMS_FDM_OUTPUT_STATE; #define _mbg_swab_mbg_ims_fdm_output_state( _p ) \ +do \ { \ _mbg_swab32( &(_p)->dac_val ); \ _mbg_swab32( &(_p)->mode ); \ _mbg_swab_mbg_dac_specs( &(_p)->dac_specs ); \ _mbg_swab32( &(_p)->reserved_0 ); \ _mbg_swab32( &(_p)->reserved_1 ); \ -} +} while ( 0 ) + /** @@ -7110,10 +10277,11 @@ typedef struct } MBG_IMS_FDM_OUTPUT_STATE_IDX; #define _mbg_swab_mbg_ims_fdm_output_state_idx( _p ) \ +do \ { \ _mbg_swab32( &(_p)->idx ); \ _mbg_swab_mbg_ims_fdm_output_state( &(_p)->state ); \ -} +} while ( 0 ) @@ -7130,10 +10298,11 @@ typedef struct } MBG_IMS_FDM_OUTPUT_SETTINGS; #define _mbg_swab_mbg_ims_fdm_output_settings( _p ) \ +do \ { \ _mbg_swab32( &(_p)->mode ); \ _mbg_swab32( &(_p)->reserved ); \ -} +} while ( 0 ) /** @@ -7147,10 +10316,11 @@ typedef struct } MBG_IMS_FDM_OUTPUT_SETTINGS_IDX; #define _mbg_swab_mbg_ims_fdm_output_settings_idx( _p ) \ +do \ { \ _mbg_swab32( &(_p)->idx ); \ _mbg_swab_mbg_ims_fdm_output_settings( &(_p)->settings ); \ -} +} while ( 0 ) @@ -7166,11 +10336,13 @@ typedef struct } MBG_IMS_FDM_OUTPUT_INFO; #define _mbg_swab_mbg_ims_fdm_output_info( _p ) \ +do \ { \ _mbg_swab_mbg_ims_fdm_output_settings( &(_p)->settings ); \ _mbg_swab32( &(_p)->supp_modes ); \ _mbg_swab_mbg_dac_specs( &(_p)->dac_specs ); \ -} +} while ( 0 ) + /** @@ -7184,10 +10356,11 @@ typedef struct } MBG_IMS_FDM_OUTPUT_INFO_IDX; #define _mbg_swab_mbg_ims_fdm_output_info_idx( _p ) \ +do \ { \ _mbg_swab32( &(_p)->idx ); \ _mbg_swab_mbg_ims_fdm_output_info( &(_p)->info ); \ -} +} while ( 0 ) @@ -7206,6 +10379,7 @@ enum MBG_IMS_FDM_OUTPUT_MODES }; + /** * @brief Bit masks used with ::MBG_IMS_FDM_OUTPUT_STATE::mode * @@ -7228,29 +10402,35 @@ typedef struct uint8_t reserved_0; ///< reserved, currently always 0 uint16_t reserved_1; ///< reserved, currently always 0 - uint32_t fd_min; ///< min. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units - uint32_t fd_max; ///< max. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units - uint32_t fd_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::fd_min and ::MBG_IMS_FDM_LIMITS::fd_max + uint32_t fd_neg_limit; ///< min. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units + uint32_t fd_pos_limit; ///< max. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units + uint32_t fd_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::fd_neg_limit and ::MBG_IMS_FDM_LIMITS::fd_pos_limit - uint32_t td_min; ///< min. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units - uint32_t td_max; ///< max. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units - uint32_t td_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::td_min and ::MBG_IMS_FDM_LIMITS::td_max + uint32_t td_neg_limit; ///< min. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units + uint32_t td_pos_limit; ///< max. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units + uint32_t td_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::td_neg_limit and ::MBG_IMS_FDM_LIMITS::td_pos_limit uint32_t reserved_2; ///< reserved, currently always 0 } MBG_IMS_FDM_LIMITS; #define _mbg_swab_mbg_ims_fdm_limits( _p ) \ +do \ { \ _mbg_swab8( &(_p)->n_outputs ); \ _mbg_swab8( &(_p)->reserved_0 ); \ _mbg_swab16( &(_p)->reserved_1 ); \ - _mbg_swab32( &(_p)->fd_min ); \ - _mbg_swab32( &(_p)->fd_max ); \ - _mbg_swab32( &(_p)->td_min ); \ - _mbg_swab32( &(_p)->td_max ); \ + \ + _mbg_swab32( &(_p)->fd_neg_limit ); \ + _mbg_swab32( &(_p)->fd_pos_limit ); \ + _mbg_swab32( &(_p)->fd_scale ); \ + \ + _mbg_swab32( &(_p)->td_neg_limit ); \ + _mbg_swab32( &(_p)->td_pos_limit ); \ + _mbg_swab32( &(_p)->td_scale ); \ + \ _mbg_swab32( &(_p)->reserved_2 ); \ -} +} while ( 0 ) @@ -7274,16 +10454,17 @@ typedef struct } MBG_IMS_FDM_STATE; -#define _mbg_swab_mbg_ims_fdm_state( _p ) \ -{ \ - _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \ - _mbg_swab_nano_time_64( &(_p)->t_ref ); \ - _mbg_swab_nano_time_64( &(_p)->t_plt ); \ - _mbg_swab_nano_time_64( &(_p)->t_sync ); \ - _mbg_swab32( &(_p)->line_freq ); \ - _mbg_swab32( &(_p)->flags ); \ - _mbg_swab32( &(_p)->reserved ); \ -} +#define _mbg_swab_mbg_ims_fdm_state( _p ) \ +do \ +{ \ + _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \ + _mbg_swab_nano_time_64( &(_p)->t_ref ); \ + _mbg_swab_nano_time_64( &(_p)->t_plt ); \ + _mbg_swab_nano_time_64( &(_p)->t_sync ); \ + _mbg_swab32( &(_p)->line_freq ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) @@ -7316,6 +10497,18 @@ enum MBG_IMS_FDM_LINE_FREQ_MASKS }; +/** + * @brief Initializers for an array of line freq. name strings + * + * @see ::MBG_IMS_FDM_LINE_FREQS + */ +#define MBG_IMS_FDM_LINE_FREQ_STRS \ +{ \ + "Auto", \ + "50 Hz", \ + "60 Hz", \ +} + /** * @brief Enumeration of flag bits used to define ::MBG_IMS_FDM_STATE_FLAG_MASKS @@ -7353,11 +10546,11 @@ enum MBG_IMS_FDM_STATE_FLAG_MASKS */ typedef struct { - uint32_t fd_min; ///< min. frequency deviation limit in 100 uHz steps - uint32_t fd_max; ///< max. frequency deviation limit in 100 uHz steps + uint32_t fd_neg_limit; ///< min. frequency deviation limit in 1 mHz steps + uint32_t fd_pos_limit; ///< max. frequency deviation limit in 1 mHz steps - uint32_t td_min; ///< min. time deviation limit in 100 us steps - uint32_t td_max; ///< max. time deviation limit in 100 us steps + uint32_t td_neg_limit; ///< min. time deviation limit in 1 ms steps + uint32_t td_pos_limit; ///< max. time deviation limit in 1 ms steps uint32_t line_freq; ///< nominal line frequency, see ::MBG_IMS_FDM_LINE_FREQS uint32_t reserved; ///< reserved, currently always 0 @@ -7365,35 +10558,63 @@ typedef struct } MBG_IMS_FDM_SETTINGS; #define _mbg_swab_mbg_ims_fdm_settings( _p ) \ +do \ { \ - _mbg_swab32( &(_p)->fd_min ); \ - _mbg_swab32( &(_p)->fd_max ); \ - _mbg_swab32( &(_p)->td_min ); \ - _mbg_swab32( &(_p)->td_max ); \ - _mbg_swab32( &(_p)->mode ); \ + _mbg_swab32( &(_p)->fd_neg_limit ); \ + _mbg_swab32( &(_p)->fd_pos_limit ); \ + _mbg_swab32( &(_p)->td_neg_limit ); \ + _mbg_swab32( &(_p)->td_pos_limit ); \ + _mbg_swab32( &(_p)->line_freq ); \ _mbg_swab32( &(_p)->reserved ); \ -} +} while ( 0 ) + /** -* @brief Specific FDM settings and limits. -*/ + * @brief IMS FDM flags + * + * @see ::MBG_IMS_FDM_FLAG_MASKS + */ +enum MBG_IMS_FDM_FLAGS +{ + MBG_IMS_FDM_FLAG_CAN_SET_TDEV, ///< Device supports command GPS_FDM_SET_TD + N_MBG_IMS_FDM_FLAGS ///< Number of known FDM flags +}; + + + +/** + * @brief IMS FDM flag masks + * + * @see ::MBG_IMS_FDM_FLAGS + */ +enum MBG_IMS_FDM_FLAG_MASKS +{ + MBG_IMS_FDM_FLAG_MASK_CAN_SET_TDEV = ( 1UL << MBG_IMS_FDM_FLAG_CAN_SET_TDEV ) ///< see ::MBG_IMS_FDM_FLAG_CAN_SET_TDEV +}; + + + +/** + * @brief Specific FDM settings and limits. + */ typedef struct { MBG_IMS_FDM_SETTINGS settings; uint32_t supp_line_freqs; ///< Bit mask of supported line frequencies, see ::MBG_IMS_FDM_LINE_FREQ_MASKS uint32_t reserved; ///< Reserved, currently always 0 - uint32_t flags; ///< Flags, currently always 0 + uint32_t flags; ///< Flags, see ::MBG_IMS_FDM_FLAG_MASKS } MBG_IMS_FDM_INFO; #define _mbg_swab_mbg_ims_fdm_info( _p ) \ +do \ { \ _mbg_swab_mbg_ims_fdm_settings( &(_p)->settings ); \ _mbg_swab32( &(_p)->supp_line_freqs ); \ _mbg_swab32( &(_p)->reserved ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) /** @} defgroup group_ims */ @@ -7433,10 +10654,11 @@ typedef struct } GEN_IO_INFO; #define _mbg_swab_gen_io_info( _p ) \ +do \ { \ _mbg_swab_gen_io_info_type( &(_p)->type ); \ _mbg_swab16( &(_p)->num ); \ -} +} while ( 0 ) @@ -7516,6 +10738,19 @@ typedef struct } SCU_STAT_INFO; +#define _mbg_swab_scu_stat_info( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->hw_id ); \ + _mbg_swab32( &(_p)->fw_id ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab8( &(_p)->clk0_info ); \ + _mbg_swab8( &(_p)->clk1_info ); \ + _mbg_swab16( &(_p)->epld_status ); \ + _mbg_swab16( &(_p)->epld_control ); \ +} while ( 0 ) + + typedef struct { @@ -7525,6 +10760,15 @@ typedef struct } SCU_STAT_SETTINGS; +#define _mbg_swab_scu_stat_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->epld_control_mask ); \ + _mbg_swab16( &(_p)->epld_control_value ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + /** * @brief Bit masks used to check the SCU EPLD status @@ -7533,17 +10777,22 @@ typedef struct */ enum SCU_STAT_MASKS { - MSK_EPLD_STAT_TS1 = 0x0001, ///< state of time sync signal clk_1 - MSK_EPLD_STAT_TS2 = 0x0002, ///< state of time sync signal clk_2 - MSK_EPLD_STAT_TL_ERROR = 0x0004, ///< state of time limit error input - MSK_EPLD_STAT_PSU1_OK = 0x0008, ///< state of power supply 1 monitoring input - MSK_EPLD_STAT_PSU2_OK = 0x0010, ///< state of power supply 2 monitoring input - MSK_EPLD_STAT_AUTO = 0x0020, ///< AUTOMATIC/REMOTE or MANUAL Mode - MSK_EPLD_STAT_SEL = 0x0040, ///< select bit for output MUX, ( clk_1 = 0 ) - MSK_EPLD_STAT_ENA = 0x0080, ///< enable Bit for output MUX, set if enabled - - MSK_EPLD_STAT_ACO = 0x4000, ///< Access control override bit - MSK_EPLD_STAT_WDOG_OK = 0x8000 ///< WDT_OK set to zero if watchdog expired + MSK_EPLD_STAT_TS1 = 0x0001, ///< state of time sync signal clk_1 + MSK_EPLD_STAT_TS2 = 0x0002, ///< state of time sync signal clk_2 + MSK_EPLD_STAT_TL_ERROR = 0x0004, ///< state of time limit error input + MSK_EPLD_STAT_PSU1_OK = 0x0008, ///< state of power supply 1 monitoring input + MSK_EPLD_STAT_PSU2_OK = 0x0010, ///< state of power supply 2 monitoring input + MSK_EPLD_STAT_AUTO = 0x0020, ///< AUTOMATIC/REMOTE or MANUAL Mode + MSK_EPLD_STAT_SEL = 0x0040, ///< select bit for output MUX, ( clk_1 = 0 ) + MSK_EPLD_STAT_ENA = 0x0080, ///< enable Bit for output MUX, set if enabled + MSK_EPLD_STAT_HAS_LAN = 0x0100, ///< indicates that the device has a network interface + MSK_EPLD_STAT_RESERVED0 = 0x0200, ///< reserved, DO NOT USE! + MSK_EPLD_STAT_RESERVED1 = 0x0400, ///< reserved, DO NOT USE! + MSK_EPLD_STAT_HAS_4_PSUS = 0x0800, ///< indicates 4 power supplies instead of 2 + MSK_EPLD_STAT_PSU3_OK = 0x1000, ///< state of power supply 3 monitoring input + MSK_EPLD_STAT_PSU4_OK = 0x2000, ///< state of power supply 4 monitoring input + MSK_EPLD_STAT_ACO = 0x4000, ///< Access control override bit + MSK_EPLD_STAT_WDOG_OK = 0x8000 ///< WDT_OK set to zero if watchdog expired }; @@ -7617,7 +10866,7 @@ enum RECEIVER_MODES typedef int16_t DAC_VAL; #define _mbg_swab_dac_val( _p ) \ - _mbg_swab16( _p ); + _mbg_swab16( _p ) @@ -7635,13 +10884,14 @@ typedef struct } STAT_INFO; #define _mbg_swab_stat_info( _p ) \ +do \ { \ _mbg_swab16( &(_p)->mode ); \ _mbg_swab16( &(_p)->good_svs ); \ _mbg_swab16( &(_p)->svs_in_view ); \ _mbg_swab_dac_val( &(_p)->dac_val ); \ _mbg_swab_dac_val( &(_p)->dac_cal ); \ -} +} while ( 0 ) #define OSC_DAC_RANGE 4096UL @@ -7663,6 +10913,7 @@ enum MBG_GNSS_TYPES GNSS_TYPE_GALILEO, ///< GALILEO, Europe GNSS_TYPE_WAAS, ///< WAAS, Wide Area Augmentation System GNSS_TYPE_EGNOS, ///< EGNOS, European Geostationary Navigation Overlay Service + GNSS_TYPE_QZSS, ///< QZSS, Quasi Zenit Satellite System N_GNSS_TYPES ///< Number of defined codes }; @@ -7679,7 +10930,8 @@ enum MBG_GNSS_TYPE_MASKS MBG_GNSS_TYPE_MSK_BEIDOU = ( 1UL << GNSS_TYPE_BEIDOU ), ///< see ::GNSS_TYPE_BEIDOU MBG_GNSS_TYPE_MSK_GALILEO = ( 1UL << GNSS_TYPE_GALILEO ), ///< see ::GNSS_TYPE_GALILEO MBG_GNSS_TYPE_MSK_WAAS = ( 1UL << GNSS_TYPE_WAAS ), ///< see ::GNSS_TYPE_WAAS - MBG_GNSS_TYPE_MSK_EGNOS = ( 1UL << GNSS_TYPE_EGNOS ) ///< see ::GNSS_TYPE_EGNOS + MBG_GNSS_TYPE_MSK_EGNOS = ( 1UL << GNSS_TYPE_EGNOS ), ///< see ::GNSS_TYPE_EGNOS + MBG_GNSS_TYPE_MSK_QZSS = ( 1UL << GNSS_TYPE_QZSS ) ///< see ::GNSS_TYPE_QZSS }; @@ -7695,7 +10947,8 @@ enum MBG_GNSS_TYPE_MASKS "BEIDOU", \ "GALILEO", \ "WAAS", \ - "EGNOS" \ + "EGNOS", \ + "QZSS" \ } @@ -7710,63 +10963,69 @@ typedef struct { uint32_t gnss_set; ///< bit mask of currently used GNSS systems, see ::MBG_GNSS_TYPE_MASKS uint8_t prio[N_GNSS_MODE_PRIO]; ///< see ::MBG_GNSS_TYPES, unused fields set to 0xFF, idx 0 is highest prio - uint32_t flags; ///< see ::MBG_GNSS_MODE_FLAG_MASKS + uint32_t flags; ///< unused, currently always 0 (should be named MBG_GNSS_MODE_SETTINGS_FLAG_MASKS) } MBG_GNSS_MODE_SETTINGS; #define _mbg_swab_mbg_gnss_mode_settings( _p ) \ +do \ { \ _mbg_swab32( &(_p)->gnss_set ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) typedef struct { - MBG_GNSS_MODE_SETTINGS settings; ///< current GNSS mode settings - uint32_t supp_gnss_types; ///< bit masks of supported GNSS types, see ::MBG_GNSS_TYPE_MASKS - uint32_t flags; ///< indicates which flags are supported for settings::flags, see ::MBG_GNSS_MODE_FLAG_MASKS + MBG_GNSS_MODE_SETTINGS settings; ///< Current GNSS mode settings + uint32_t supp_gnss_types; ///< Bit masks of supported GNSS types, see ::MBG_GNSS_TYPE_MASKS + uint16_t flags; ///< See ::MBG_GNSS_MODE_INFO_FLAG_MASKS + uint16_t n_sv_status; ///< Number of ::GNSS_SV_STATUS_IDX structures that can be read (only if ::MBG_GNSS_FLAG_MSK_HAS_SV_STATUS) } MBG_GNSS_MODE_INFO; #define _mbg_swab_mbg_gnss_mode_info( _p ) \ +do \ { \ _mbg_swab_mbg_gnss_mode_settings( &(_p)->settings ); \ _mbg_swab32( &(_p)->supp_gnss_types ); \ - _mbg_swab32( &(_p)->flags ); \ -} + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab16( &(_p)->n_sv_status ); \ +} while ( 0 ) + /** - * @brief Flag bits used with ::MBG_GNSS_MODE_SETTINGS and ::MBG_GNSS_MODE_INFO + * @brief Flag bits used to define ::MBG_GNSS_MODE_INFO_FLAG_MASKS * - * @see ::MBG_GNSS_MODE_FLAG_MASKS + * @see ::MBG_GNSS_MODE_INFO_MASKS */ -enum MBG_GNSS_MODE_FLAG_BITS +enum MBG_GNSS_MODE_INFO_FLAG_BITS { - MBG_GNSS_FLAG_EXCLUSIVE, ///< (read only) only one of the supported GNSS systems can be used at the same time - MBG_GNSS_FLAG_HAS_PRIORITY, ///< (read only) priority can be configured using the MBG_GNSS_MODE_SETTINGS::prio field - MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER, ///< (read only) + MBG_GNSS_FLAG_EXCLUSIVE, ///< Only one of the supported GNSS systems can be used at the same time + MBG_GNSS_FLAG_HAS_PRIORITY, ///< Priority can be configured using the ::MBG_GNSS_MODE_SETTINGS::prio field + MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER, ///< The ::GNSS_SAT_INFO_IDX structure is supported by the device + MBG_GNSS_FLAG_HAS_SV_STATUS, ///< The ::GNSS_SV_STATUS_IDX structure is supported by the device N_MBG_GNSS_FLAGS }; /** - * @brief Flag masks used with MBG_GNSS_MODE_SETTINGS::flags and MBG_GNSS_MODE_INFO::flags + * @brief Flag masks used with MBG_GNSS_MODE_INFO::flags * * @see ::MBG_GNSS_MODE_FLAG_BITS */ -enum MBG_GNSS_MODE_FLAG_MASKS +enum MBG_GNSS_MODE_INFO_FLAG_MASKS { - MBG_GNSS_FLAG_MSK_EXCLUSIVE = ( 1UL << MBG_GNSS_FLAG_EXCLUSIVE ), ///< see ::MBG_GNSS_FLAG_EXCLUSIVE - MBG_GNSS_FLAG_MSK_HAS_PRIORITY = ( 1UL << MBG_GNSS_FLAG_HAS_PRIORITY ), ///< see ::MBG_GNSS_FLAG_HAS_PRIORITY - MBG_GNSS_FLAG_MSK_SAT_INFO_IDX_SUPP_SER = ( 1UL << MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER ) ///< see ::MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER + MBG_GNSS_FLAG_MSK_EXCLUSIVE = ( 1UL << MBG_GNSS_FLAG_EXCLUSIVE ), ///< see ::MBG_GNSS_FLAG_EXCLUSIVE + MBG_GNSS_FLAG_MSK_HAS_PRIORITY = ( 1UL << MBG_GNSS_FLAG_HAS_PRIORITY ), ///< see ::MBG_GNSS_FLAG_HAS_PRIORITY + MBG_GNSS_FLAG_MSK_SAT_INFO_IDX_SUPP_SER = ( 1UL << MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER ), ///< see ::MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER + MBG_GNSS_FLAG_MSK_HAS_SV_STATUS = ( 1UL << MBG_GNSS_FLAG_HAS_SV_STATUS ) ///< see ::MBG_GNSS_FLAG_HAS_SV_STATUS }; - #define MAX_USED_SATS 32 /** @@ -7783,10 +11042,11 @@ typedef struct } GNSS_SAT_INFO; #define _mbg_swab_gnss_sat_info( _p ) \ +do \ { \ _mbg_swab16( &(_p)->good_svs ); \ _mbg_swab16( &(_p)->svs_in_view ); \ -} +} while ( 0 ) @@ -7797,17 +11057,215 @@ typedef struct */ typedef struct { - uint16_t idx; ///< GNSS system type index + /// GNSS system type index according to ::MBG_GNSS_MODE_INFO::supp_gnss_types. + /// I.e., idx 0 corresponds to the GNSS system for which the least significant + /// bit is set in ::MBG_GNSS_MODE_INFO::supp_gnss_types, idx 1 corresponds to + /// GNSS system for which the next higher bit is set, etc. This must *not* + /// necessarily match the sequence of the ::MBG_GNSS_TYPES enumeration. + uint16_t idx; + GNSS_SAT_INFO gnss_sat_info; ///< see ::GNSS_SAT_INFO } GNSS_SAT_INFO_IDX; -#define _mbg_swab_gnss_sat_info_idx( _p ) \ -{ \ - _mbg_swab16( &(_p)->idx ); \ +#define _mbg_swab_gnss_sat_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ _mbg_swab_gnss_sat_info( &(_p)->gnss_sat_info ); \ -} +} while ( 0 ) + + + +/** + * @defgroup group_gnss_sv_status GNSS Satellite Status + * + * @note These structures and associated types are only supported by a device + * if ::MBG_XFEATURE_GNSS_SV_INFO is set in the extended device features. // FIXME + * + * @{ */ + +/** + * @brief Detailed GNSS satellite status + * + * @see ::GNSS_SV_STATUS_IDX + * @see @ref group_gnss_sv_stat_flags + */ +typedef struct +{ + uint8_t gnss_type; ///< GNSS type as enumerated in ::MBG_GNSS_TYPES + uint8_t svno; ///< Satellite number, see ::TODO + uint8_t cn_ratio; ///< Carrier-to-noise ratio [dbHz] + int8_t elev; ///< Elevation [deg], range: -90..90 deg + + int16_t azim; ///< Azimuth [deg], range: 0..360 deg + int16_t pr_residual; ///< Pseudo range residual [m] + + uint32_t stat_flags; ///< see @ref group_gnss_sv_stat_flags + +} GNSS_SV_STATUS; + +#define _mbg_swab_gnss_sv_status( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->gnss_type ); \ + _mbg_swab8( &(_p)->svno ); \ + _mbg_swab8( &(_p)->cn_ratio ); \ + _mbg_swab8( &(_p)->elev ); \ + _mbg_swab16( &(_p)->azim ); \ + _mbg_swab16( &(_p)->pr_residual ); \ + _mbg_swab32( &(_p)->stat_flags ); \ +} while ( 0 ) + + + +/** + * @defgroup group_gnss_sv_stat_flags GNSS status flags encoding + * + * Used with ::GNSS_SV_STATUS::stat_flags. + * + * @{ */ + +/// Bits 0 to 2 are a 3 bit quality indicator, see ::GNSS_SV_STAT_QUALITY_INDS +#define _gnss_sv_stat_quality_ind( __stat_flags ) \ + ( (uint8_t) ( (__stat_flags) & 0x00000007UL ) ) + +/// Bit 3 is set if the SV is actually used for navigation +#define _gnss_sv_stat_sv_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00000008UL ) != 0 ) + +/// Bits 4 and 5 are a 2 bit health code, see ::GNSS_SV_STAT_HEALTH_CODES +#define _gnss_sv_stat_health_code( __stat_flags ) \ + ( (uint8_t) ( ( (__stat_flags) & 0x00000030UL ) >> 4 ) ) + +/// Bit 6 is set if differential correction is available for this SV +#define _gnss_sv_stat_diff_corr( __stat_flags ) \ + ( ( (__stat_flags) & 0x00000040UL ) != 0 ) + +/// Bit 7 is set if carrier smoothed pseudorange is used for this SV +#define _gnss_sv_stat_smoothed( __stat_flags ) \ + ( ( (__stat_flags) & 0x00000080UL ) != 0 ) + +/// Bits 8 to 10 are a 3 bit code indicating the orbit source, see ::GNSS_SV_STAT_ORBIT_SOURCES +#define _gnss_sv_stat_orbit_src( __stat_flags ) \ + ( (uint8_t) ( ( (__stat_flags) & 0x00000700UL ) >> 8 ) ) + +/// Bit 11 is set if ephemeris parameters are available for this SV +#define _gnss_sv_stat_eph_avail( __stat_flags ) \ + ( ( (__stat_flags) & 0x00000800UL ) != 0 ) + +/// Bit 12 is set if almanac parameters are available for this SV +#define _gnss_sv_stat_alm_avail( __stat_flags ) \ + ( ( (__stat_flags) & 0x00001000UL ) != 0 ) + +/// Bit 13 is set if AssistNow Offline data is available for this SV +#define _gnss_sv_stat_ano_avail( __stat_flags ) \ + ( ( (__stat_flags) & 0x00002000UL ) != 0 ) + +/// Bit 14 is set if AssistNow Autonomous data is available for this SV +#define _gnss_sv_stat_aop_avail( __stat_flags ) \ + ( ( (__stat_flags) & 0x00004000UL ) != 0 ) + +/// Bit 15 is reserved. + +/// Bit 16 is set if SBAS corrections have been used for this SV +#define _gnss_sv_stat_sbas_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00010000UL ) != 0 ) + +/// Bit 17 is set if RTCM corrections have been used for this SV +#define _gnss_sv_stat_rtcm_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00020000UL ) != 0 ) + +/// Bits 18 and 19 are reserved. + +/// Bit 20 is set if pseudorange corrections have been used for this SV +#define _gnss_sv_stat_pr_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00100000UL ) != 0 ) + +/// Bit 21 is set if carrier range corrections have been used for this SV +#define _gnss_sv_stat_cr_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00200000UL ) != 0 ) + +/// Bit 22 is set if range rate (doppler) corrections have been used for this SV +#define _gnss_sv_stat_do_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00400000UL ) != 0 ) +/// Bits 23 to 31 are reserved. + +/** @} defgroup group_gnss_sv_stat_flags */ + + +/** + * @brief Quality indicators used with ::GNSS_SV_STATUS::sv_stat + * + * @see ::_gnss_sv_stat_quality_ind + */ +enum GNSS_SV_STAT_QUALITY_INDS +{ + GNSS_SV_STAT_NO_SIGNAL, ///< No signal + GNSS_SV_STAT_SEARCHING, ///< Searching signal + GNSS_SV_STAT_ACQUIRED, ///< Signal acquired + GNSS_SV_STAT_UNUSABLE, ///< Signal detected but unusable + GNSS_SV_STAT_CODE_LOCKED, ///< Code locked and time synchronized + GNSS_SV_STAT_CODE_CARRIER_LOCKED, ///< Code and carrier locked, and time synchronized + GNSS_SV_STAT_CODE_CARRIER_LOCKED_2, ///< Code and carrier locked, and time synchronized + GNSS_SV_STAT_CODE_CARRIER_LOCKED_3 ///< Code and carrier locked, and time synchronized +}; + + +/** + * @brief Health indicators used with ::GNSS_SV_STATUS::sv_stat + * + * @see ::_gnss_sv_stat_health_code + */ +enum GNSS_SV_STAT_HEALTH_CODES +{ + GNSS_SV_STAT_HEALTH_UNKNOWN, ///< Health status unknown + GNSS_SV_STAT_HEALTH_OK, ///< Healthy + GNSS_SV_STAT_HEALTH_NOT_OK ///< Unhealthy +}; + + +/** + * @brief Orbit source codes used with ::GNSS_SV_STATUS::sv_stat + * + * @see ::_gnss_sv_stat_orbit_src + */ +enum GNSS_SV_STAT_ORBIT_SOURCES +{ + GNSS_SV_STAT_ORBIT_SRC_UNKNOWN, ///< Orbit source unknown + GNSS_SV_STAT_ORBIT_SRC_EPH, ///< Ephemeris data used for orbit + GNSS_SV_STAT_ORBIT_SRC_ALM, ///< Almanac data used for orbit + GNSS_SV_STAT_ORBIT_SRC_ASSN_OFFL, ///< AssistNow Offline orbit is used + GNSS_SV_STAT_ORBIT_SRC_ASSN_AUTO, ///< AssistNow Autonomous orbit is used + GNSS_SV_STAT_ORBIT_OTHER_1, ///< Other orbit information is used + GNSS_SV_STAT_ORBIT_OTHER_2, ///< Other orbit information is used + GNSS_SV_STAT_ORBIT_OTHER_3 ///< Other orbit information is used +}; + + + +/** + * @brief Detailed GNSS satellite status, plus index + * + * @see ::GNSS_SV_STATUS + */ +typedef struct +{ + uint32_t idx; ///< Range 0..::MBG_GNSS_MODE_INFO::n_sv_status-1 + GNSS_SV_STATUS gnss_sv_status; + +} GNSS_SV_STATUS_IDX; + +#define _mbg_swab_gnss_sv_status_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_gnss_sv_status( &(_p)->gnss_sv_status ); \ +} while ( 0 ) + + +/** @} defgroup group_gnss_sv_status */ @@ -7824,11 +11282,14 @@ typedef struct #endif #define _mbg_swab_ident( _p ) \ +do \ { \ int i; \ for ( i = 0; i < 4; i++ ) \ _mbg_swab32( &(_p)->lw[i] ); \ -} +} while ( 0 ) + + /** * @brief A data type used to configure the length of an antenna cable [m] @@ -7858,6 +11319,9 @@ typedef struct } MBG_MAC_ADDR; +#define _mbg_swab_mbg_mac_addr( _p ) \ + _nop_macro_fnc() + /** @@ -7866,7 +11330,7 @@ typedef struct typedef uint32_t IP4_ADDR; #define _mbg_swab_ip4_addr( _p ) \ - _mbg_swab32( _p ); + _mbg_swab32( _p ) @@ -7885,6 +11349,8 @@ typedef struct } IP6_ADDR; +#define _mbg_swab_ip6_addr( _p ) _nop_macro_fnc() + /** @@ -7956,19 +11422,47 @@ enum IPV6_MULTICAST_SCOPES /** - * @brief A host's fully qualified domain name (FQDN), or a numeric IP address string + * @brief The maximum length of a fully qualified host/domain domain name (FQDN) * * In theory each single component (host name, domain name, top level domain name) * of a FQDN can have up to 63 characters, but the overall length is limited to - * 255 characters. We specify one more character for the trailing 0. + * 255 characters (see RFC-1123). We specify one more character for the trailing 0. + */ +#define MBG_MAX_HOSTNAME_LEN 256 + + +/** + * @brief A buffer for a fully qualified domain name (FQDN) or a numeric IP address string */ -typedef char MBG_HOSTNAME[256]; ///< ASCIIZ format +typedef char MBG_HOSTNAME[MBG_MAX_HOSTNAME_LEN]; ///< ASCIIZ format + +#define _mbg_swab_mbg_host_name( _p ) _nop_macro_fnc() + /** @} defgroup group_net_basic_types */ /** + * @brief The maximum length of an interface name + * + * We use an extra name here for the Meinberg-specific structures + * to avoid a name clash with system definitions, e.g. Linux systems + * define IFNAMSIZ usually as 16 in linux/if.h. + */ +#define MBG_IFNAMSIZ 16 + + +/** + * @brief Hardware type for identification of physical interfaces + * + * Use own definition for use under Windows, + * original ARPHRD_ETHER comes from linux/if_arp.h + */ +#define MBG_ARPHRD_ETHER 1 + + +/** * @defgroup group_vlan_cfg Definitions used with VLAN configuration * * @{ */ @@ -7980,7 +11474,7 @@ typedef char MBG_HOSTNAME[256]; ///< ASCIIZ format */ typedef uint16_t MBG_VLAN_CFG; -#define _mbg_swab_mbg_vlan_cfg( _p ) _mbg_swab16( _p ); +#define _mbg_swab_mbg_vlan_cfg( _p ) _mbg_swab16( _p ) #define VLAN_ID_BITS 12 ///< number of bits to hold the ID #define N_VLAN_ID ( 1 << VLAN_ID_BITS ) ///< number of ID values @@ -8036,6 +11530,7 @@ typedef struct } IP4_SETTINGS; #define _mbg_swab_ip4_settings( _p ) \ +do \ { \ _mbg_swab_ip4_addr( &(_p)->ip_addr ); \ _mbg_swab_ip4_addr( &(_p)->netmask ); \ @@ -8043,7 +11538,7 @@ typedef struct _mbg_swab_ip4_addr( &(_p)->gateway ); \ _mbg_swab16( &(_p)->flags ); \ _mbg_swab_mbg_vlan_cfg( &(_p)->vlan_cfg ); \ -} +} while ( 0 ) @@ -8072,13 +11567,14 @@ typedef struct } LAN_IF_INFO; #define _mbg_swab_lan_if_info( _p ) \ +do \ { \ _mbg_swab16( &(_p)->type ); \ _mbg_swab16( &(_p)->ver_code ); \ _mbg_swab32( &(_p)->rsvd_0 ); \ _mbg_swab16( &(_p)->flags ); \ _mbg_swab16( &(_p)->rsvd_1 ); \ -} +} while ( 0 ) /** @@ -8145,7 +11641,8 @@ enum MBG_IP_ADDR_TYPES { MBG_IP_ADDR_TYPE_UNKNOWN, MBG_IP_ADDR_TYPE_IP4, - MBG_IP_ADDR_TYPE_IP6 + MBG_IP_ADDR_TYPE_IP6, + N_MBG_IP_ADDR_TYPES }; /* @@ -8165,83 +11662,202 @@ enum MBG_IP_ADDR_TYPES /** - * @brief Network link speed modes + * @brief Feature flag bits used to define ::MBG_NET_GLB_CFG_INFO_MASKS + * + * @see ::MBG_NET_GLB_CFG_INFO_MASKS + */ +enum MBG_NET_GLB_CFG_INFO_FLAGS +{ + MBG_NET_GLB_SUPP_STAGE_2, ///< Supports commands which have been added in stage 2 + MBG_NET_GLB_SUPP_BONDING, ///< Supports bonding + N_MBG_NET_GLB_INFO_FLAGS +}; + + +/** + * @brief Flag masks used with ::MBG_NET_GLB_CFG_INFO::feat_flags * - * @see ::MBG_NET_LINK_MODE_MASKS + * @see ::MBG_NET_GLB_CFG_INFO_FLAGS + */ +enum MBG_NET_GLB_CFG_INFO_MASKS +{ + MBG_NET_GLB_SUPP_STAGE_2_MASK = (1UL << MBG_NET_GLB_SUPP_STAGE_2), ///< see ::MBG_NET_GLB_SUPP_STAGE_2 + MBG_NET_GLB_SUPP_BONDING_MASK = (1UL << MBG_NET_GLB_SUPP_BONDING) ///< see ::MBG_NET_GLB_SUPP_BONDING +}; + + + +/** + * @brief Network interface link speed mode enumeration * - * Note: Half duplex is not supported for 10GBit + * @see @ref MBG_NET_INTF_LINK_SPEED_MODE_MASKS */ -enum MBG_NET_LINK_MODES +enum MBG_NET_INTF_LINK_SPEED_MODES { - MBG_NET_LINK_MODE_AUTONEG, ///< auto negotiation - MBG_NET_LINK_MODE_10_BT_H, ///< 10 MBit half duplex - MBG_NET_LINK_MODE_10_BT_F, ///< 10 MBit full duplex - MBG_NET_LINK_MODE_100_BT_H, ///< 100 MBit half duplex - MBG_NET_LINK_MODE_100_BT_F, ///< 100 MBit full duplex - MBG_NET_LINK_MODE_1000_BT_H, ///< 1 GBit half duplex - MBG_NET_LINK_MODE_1000_BT_F, ///< 1 GBit full duplex - MBG_NET_LINK_MODE_10000_BT_F, ///< 10 GBit Full Duplex - N_MBG_NET_LINK_MODES + MBG_NET_INTF_LINK_SPEED_MODE_UNKNOWN, ///< Unknown speed mode + MBG_NET_INTF_LINK_SPEED_MODE_10_T_HALF, ///< 10baseT Half Duplex (10 MBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10_T_FULL, ///< 10baseT Full Duplex (10 MBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_100_T_HALF, ///< 100baseT Half Duplex (100 MBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_100_T_FULL, ///< 100baseT Full Duplex (100 MBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_1000_T_HALF, ///< 1000baseT Half Duplex (1 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_1000_T_FULL, ///< 1000baseT Full Duplex (1 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_1000_KX_FULL, ///< 1000baseKX Full Duplex (1 GBit/s) + + MBG_NET_INTF_LINK_SPEED_MODE_2500_X_FULL, ///< 2500baseX Full Duplex (2.5 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10000_T_FULL, ///< 10000baseT Full Duplex (10 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10000_KX4_FULL, ///< 10000baseKX4 Full Duplex (10 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10000_KR_FULL, ///< 10000baseKR Full Duplex (10 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10000_R_FEC, ///< 10000baseR FEC (forward error correction) (10 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_20000_MLD2_FULL, ///< 20000baseMLD2 Full Duplex (20 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_20000_KR2_FULL, ///< 20000baseKR2 Full Duplex (20 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_40000_KR4_FULL, ///< 40000baseKR4 Full Duplex (40 GBit/s) + + MBG_NET_INTF_LINK_SPEED_MODE_40000_CR4_FULL, ///< 40000baseCR4 Full Duplex (40 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_40000_SR4_FULL, ///< 40000baseSR4 Full Duplex (40 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_40000_LR4_FULL, ///< 40000baseLR4 Full Duplex (40 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_56000_KR4_FULL, ///< 56000baseKR4 Full Duplex (56 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_56000_CR4_FULL, ///< 56000baseCR4 Full Duplex (56 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_56000_SR4_FULL, ///< 56000baseSR4 Full Duplex (56 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_56000_LR4_FULL, ///< 56000baseLR4 Full Duplex (56 GBit/s) + + N_MBG_NET_INTF_LINK_SPEED_MODES }; + /** - * @brief Network link speed mode masks + * @brief Network interface link speed mode masks * - * @see ::MBG_NET_LINK_MODES + * @see ::MBG_NET_INTF_LINK_SPEED_MODES + * + * @anchor MBG_NET_INTF_LINK_SPEED_MODE_MASKS @{ */ + +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_UNKNOWN ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_UNKNOWN ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_UNKNOWN +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10_T_HALF ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10_T_HALF +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10_T_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10_T_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_100_T_HALF ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_100_T_HALF +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_100_T_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_100_T_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_1000_T_HALF ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_1000_T_HALF ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_1000_T_HALF +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_1000_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_1000_T_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_1000_T_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_1000_KX_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_1000_KX_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_1000_KX_FULL + +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_2500_X_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_2500_X_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_2500_X_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_T_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10000_T_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_KX4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_KX4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10000_KX4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_KR_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_KR_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10000_KR_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_R_FEC ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_R_FEC ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_10000_R_FEC +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_20000_MLD2_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_20000_MLD2_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_20000_MLD2_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_20000_KR2_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_20000_KR2_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_20000_KR2_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_KR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_KR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_40000_KR4_FULL + +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_CR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_CR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_40000_CR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_SR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_SR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_40000_SR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_LR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_LR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_40000_LR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_KR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_KR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_56000_KR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_CR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_CR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_56000_CR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_SR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_SR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_56000_SR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_LR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_LR4_FULL ) ///< see ::MBG_NET_INTF_LINK_SPEED_MODE_56000_LR4_FULL + +/** @} anchor MBG_NET_INTF_LINK_SPEED_MODE_MASKS */ + + + +/** + * @brief Network interface link speeds [Mb/s] + * + * @see @ref MBG_NET_INTF_LINK_SPEED_MODE_MASKS */ -enum MBG_NET_LINK_MODE_MASKS +enum MBG_NET_INTF_LINK_SPEEDS { - MBG_NET_LINK_MODE_MASK_AUTONEG = ( 1UL << MBG_NET_LINK_MODE_AUTONEG ), ///< see ::MBG_NET_LINK_MODE_AUTONEG - MBG_NET_LINK_MODE_MASK_10_BT_H = ( 1UL << MBG_NET_LINK_MODE_10_BT_H ), ///< see ::MBG_NET_LINK_MODE_10_BT_H - MBG_NET_LINK_MODE_MASK_10_BT_F = ( 1UL << MBG_NET_LINK_MODE_10_BT_F ), ///< see ::MBG_NET_LINK_MODE_10_BT_F - MBG_NET_LINK_MODE_MASK_100_BT_H = ( 1UL << MBG_NET_LINK_MODE_100_BT_H ), ///< see ::MBG_NET_LINK_MODE_100_BT_H - MBG_NET_LINK_MODE_MASK_100_BT_F = ( 1UL << MBG_NET_LINK_MODE_100_BT_F ), ///< see ::MBG_NET_LINK_MODE_100_BT_F - MBG_NET_LINK_MODE_MASK_1000_BT_H = ( 1UL << MBG_NET_LINK_MODE_1000_BT_H ), ///< see ::MBG_NET_LINK_MODE_1000_BT_H - MBG_NET_LINK_MODE_MASK_1000_BT_F = ( 1UL << MBG_NET_LINK_MODE_1000_BT_F ), ///< see ::MBG_NET_LINK_MODE_1000_BT_F - MBG_NET_LINK_MODE_MASK_10000_BT_F = ( 1UL << MBG_NET_LINK_MODE_10000_BT_F ) ///< see ::MBG_NET_LINK_MODE_10000_BT_F + MBG_NET_INTF_LINK_SPEED_UNKNOWN = 0UL, + MBG_NET_INTF_LINK_SPEED_10 = 10UL, + MBG_NET_INTF_LINK_SPEED_100 = 100UL, + MBG_NET_INTF_LINK_SPEED_1000 = 1000UL, + MBG_NET_INTF_LINK_SPEED_2500 = 2500UL, + MBG_NET_INTF_LINK_SPEED_10000 = 10000UL, + MBG_NET_INTF_LINK_SPEED_20000 = 20000UL, + MBG_NET_INTF_LINK_SPEED_40000 = 40000UL, + MBG_NET_INTF_LINK_SPEED_56000 = 56000UL }; /** - * @brief Network link port types + * @brief Network interface link port types * - * @see ::MBG_NET_LINK_PORT_MASKS + * @see ::MBG_NET_INTF_LINK_PORT_TYPE_MASKS */ -enum MBG_NET_LINK_PORTS +enum MBG_NET_INTF_LINK_PORT_TYPES { - MBG_NET_LINK_PORT_AUTO, ///< auto detection - MBG_NET_LINK_PORT_TP, ///< Twisted Pair (TP) - MBG_NET_LINK_PORT_AUI, ///< Attachment Unit Interface (AUI), externel transceiver - MBG_NET_LINK_PORT_MII, ///< Media Independent Interface (MII), external receiver - MBG_NET_LINK_PORT_FIBRE, ///< fibre optic - MBG_NET_LINK_PORT_BNC, ///< coaxial cable - N_MBG_NET_LINK_PORTS + MBG_NET_INTF_LINK_PORT_TYPE_UNKNOWN, ///< Unknown port type + MBG_NET_INTF_LINK_PORT_TYPE_TP, ///< Twisted Pair (TP) copper cable + MBG_NET_INTF_LINK_PORT_TYPE_FIBRE, ///< Fibre Optic (FO) cable + MBG_NET_INTF_LINK_PORT_TYPE_BNC, ///< Coaxial BNC cable + MBG_NET_INTF_LINK_PORT_TYPE_AUI, ///< Attachment Unit Interface (AUI), externel transceiver + MBG_NET_INTF_LINK_PORT_TYPE_MII, ///< Media Independent Interface (MII), external receiver + MBG_NET_INTF_LINK_PORT_TYPE_DA, ///< Direct attach SFP+ connection + N_MBG_NET_INTF_LINK_PORT_TYPES }; + /** - * @brief Network link port type masks + * @brief Network interface link port masks * - * @see ::MBG_NET_LINK_PORTS + * @see ::MBG_NET_INTF_LINK_PORT_TYPES */ -enum MBG_NET_LINK_PORT_MASKS +enum MBG_NET_INTF_LINK_PORT_TYPE_MASKS { - MBG_NET_LINK_PORT_MASK_AUTO = ( 1UL << MBG_NET_LINK_PORT_AUTO ), ///< see ::MBG_NET_LINK_PORT_AUTO - MBG_NET_LINK_PORT_MASK_TP = ( 1UL << MBG_NET_LINK_PORT_TP ), ///< see ::MBG_NET_LINK_PORT_TP - MBG_NET_LINK_PORT_MASK_AUI = ( 1UL << MBG_NET_LINK_PORT_AUI ), ///< see ::MBG_NET_LINK_PORT_AUI - MBG_NET_LINK_PORT_MASK_MII = ( 1UL << MBG_NET_LINK_PORT_MII ), ///< see ::MBG_NET_LINK_PORT_MII - MBG_NET_LINK_PORT_MASK_FIBRE = ( 1UL << MBG_NET_LINK_PORT_FIBRE ), ///< see ::MBG_NET_LINK_PORT_FIBRE - MBG_NET_LINK_PORT_MASK_BNC = ( 1UL << MBG_NET_LINK_PORT_BNC ) ///< see ::MBG_NET_LINK_PORT_BNC + MBG_NET_INTF_LINK_PORT_TYPE_MASK_UNKNOWN = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_UNKNOWN ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_UNKNOWN + MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_TP ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_TP + MBG_NET_INTF_LINK_PORT_TYPE_MASK_FIBRE = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_FIBRE ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_FIBRE + MBG_NET_INTF_LINK_PORT_TYPE_MASK_BNC = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_BNC ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_BNC + MBG_NET_INTF_LINK_PORT_TYPE_MASK_AUI = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_AUI ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_AUI + MBG_NET_INTF_LINK_PORT_TYPE_MASK_MII = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_MII ), ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_MII + MBG_NET_INTF_LINK_PORT_TYPE_MASK_DA = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_DA ) ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_DA }; /** - * @brief Network link state bits + * @brief Initializers for network interface link port type long strings * - * @see ::MBG_NET_LINK_STATE_MASKS + * @see ::MBG_NET_INTF_LINK_PORT_TYPE + */ +#define MBG_NET_INTF_LINK_PORT_TYPE_LONG_STRS \ +{ \ + "Unknown", \ + "Twisted Pair", \ + "Fibre Optic", \ + "Coaxial BNC", \ + "Attachment Unit Interface", \ + "Media Independent Interface", \ + "Direct Attach SFP+" \ +} + + +/** + * @brief Initializers for network interface link port type short strings + * + * @see ::MBG_NET_INTF_LINK_PORT_TYPE + */ +#define MBG_NET_INTF_LINK_PORT_TYPE_SHORT_STRS \ +{ \ + "Unknown", \ + "TP", \ + "FO", \ + "BNC", \ + "AUI", \ + "MII", \ + "DA" \ +} + + + +/** + * @brief Network interface link state bits + * + * @see @ref MBG_NET_INTF_LINK_STATE_MASKS * * @note See official Linux kernel documentation * https://www.kernel.org/doc/Documentation/networking/operstates.txt @@ -8249,201 +11865,241 @@ enum MBG_NET_LINK_PORT_MASKS * using similar names struct IP_ADAPTER_ADDRESSES which is explained at * http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058%28v=vs.85%29.aspx */ -enum MBG_NET_LINK_STATE_BITS -{ - MBG_NET_LINK_STATE_BIT_UP, - MBG_NET_LINK_STATE_BIT_BROADCAST, - MBG_NET_LINK_STATE_BIT_LOOPBACK, - MBG_NET_LINK_STATE_BIT_P2P, - MBG_NET_LINK_STATE_BIT_RUNNING, - MBG_NET_LINK_STATE_BIT_NO_ARP, - MBG_NET_LINK_STATE_BIT_PROMISC, - MBG_NET_LINK_STATE_BIT_MASTER, - MBG_NET_LINK_STATE_BIT_SLAVE, - MBG_NET_LINK_STATE_BIT_MULTICAST, - MBG_NET_LINK_STATE_BIT_LOWER_UP, - MBG_NET_LINK_STATE_BIT_DORMANT, - MBG_NET_LINK_STATE_BIT_ECHO, - N_MBG_NET_LINK_STATE_BITS +enum MBG_NET_INTF_LINK_STATE_BITS +{ + MBG_NET_INTF_LINK_STATE_BIT_UP, + MBG_NET_INTF_LINK_STATE_BIT_RUNNING, + MBG_NET_INTF_LINK_STATE_BIT_LOWER_UP, + MBG_NET_INTF_LINK_STATE_BIT_DORMANT, + MBG_NET_INTF_LINK_STATE_BIT_BROADCAST, + MBG_NET_INTF_LINK_STATE_BIT_MULTICAST, + MBG_NET_INTF_LINK_STATE_BIT_ALL_MULTI, + MBG_NET_INTF_LINK_STATE_BIT_DEBUG, + + MBG_NET_INTF_LINK_STATE_BIT_LOOPBACK, + MBG_NET_INTF_LINK_STATE_BIT_POINT_TO_POINT, + MBG_NET_INTF_LINK_STATE_BIT_NO_ARP, + MBG_NET_INTF_LINK_STATE_BIT_PROMISC, + MBG_NET_INTF_LINK_STATE_BIT_MASTER, + MBG_NET_INTF_LINK_STATE_BIT_SLAVE, + MBG_NET_INTF_LINK_STATE_BIT_PORT_SEL, + MBG_NET_INTF_LINK_STATE_BIT_AUTO_MEDIA, + + MBG_NET_INTF_LINK_STATE_BIT_ECHO, + MBG_NET_INTF_LINK_STATE_BIT_DYNAMIC, + MBG_NET_INTF_LINK_STATE_BIT_NO_TRAILERS, + + N_MBG_NET_INTF_LINK_STATE_BITS }; + /** - * @brief Network link state masks + * @brief Network interface link state masks * - * @see ::MBG_NET_LINK_STATE_BITS (reclined to Linux' if.h, Windows is similiar) - */ -enum MBG_NET_LINK_STATE_MASKS -{ - MBG_NET_LINK_STATE_MASK_UP = ( 1UL << MBG_NET_LINK_STATE_BIT_UP ), ///< see ::MBG_NET_LINK_STATE_BIT_UP - MBG_NET_LINK_STATE_MASK_BROADCAST = ( 1UL << MBG_NET_LINK_STATE_BIT_BROADCAST ), ///< see ::MBG_NET_LINK_STATE_BIT_BROADCAST - MBG_NET_LINK_STATE_MASK_LOOPBACK = ( 1UL << MBG_NET_LINK_STATE_BIT_LOOPBACK ), ///< see ::MBG_NET_LINK_STATE_BIT_LOOPBACK - MBG_NET_LINK_STATE_MASK_P2P = ( 1UL << MBG_NET_LINK_STATE_BIT_P2P ), ///< see ::MBG_NET_LINK_STATE_BIT_P2P - MBG_NET_LINK_STATE_MASK_RUNNING = ( 1UL << MBG_NET_LINK_STATE_BIT_RUNNING ), ///< see ::MBG_NET_LINK_STATE_BIT_RUNNING - MBG_NET_LINK_STATE_MASK_NO_ARP = ( 1UL << MBG_NET_LINK_STATE_BIT_NO_ARP ), ///< see ::MBG_NET_LINK_STATE_BIT_NO_ARP - MBG_NET_LINK_STATE_MASK_PROMISC = ( 1UL << MBG_NET_LINK_STATE_BIT_PROMISC ), ///< see ::MBG_NET_LINK_STATE_BIT_PROMISC - MBG_NET_LINK_STATE_MASK_MASTER = ( 1UL << MBG_NET_LINK_STATE_BIT_MASTER ), ///< see ::MBG_NET_LINK_STATE_BIT_MASTER - MBG_NET_LINK_STATE_MASK_SLAVE = ( 1UL << MBG_NET_LINK_STATE_BIT_SLAVE ), ///< see ::MBG_NET_LINK_STATE_BIT_SLAVE - MBG_NET_LINK_STATE_MASK_MULTICAST = ( 1UL << MBG_NET_LINK_STATE_BIT_MULTICAST ), ///< see ::MBG_NET_LINK_STATE_BIT_MULTICAST - MBG_NET_LINK_STATE_MASK_LOWER_UP = ( 1UL << MBG_NET_LINK_STATE_BIT_LOWER_UP ), ///< see ::MBG_NET_LINK_STATE_BIT_LOWER_UP - MBG_NET_LINK_STATE_MASK_DORMANT = ( 1UL << MBG_NET_LINK_STATE_BIT_DORMANT ), ///< see ::MBG_NET_LINK_STATE_BIT_DORMANT - MBG_NET_LINK_STATE_MASK_ECHO = ( 1UL << MBG_NET_LINK_STATE_BIT_ECHO ) ///< see ::MBG_NET_LINK_STATE_BIT_ECHO -}; + * @see ::MBG_NET_INTF_LINK_STATE_BITS (reclined to Linux' if.h, Windows is similiar) + * + * @anchor MBG_NET_INTF_LINK_STATE_MASKS @{ */ + +#define MBG_NET_INTF_LINK_STATE_MASK_UP ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_UP ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_UP +#define MBG_NET_INTF_LINK_STATE_MASK_RUNNING ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_RUNNING ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_RUNNING +#define MBG_NET_INTF_LINK_STATE_MASK_LOWER_UP ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_LOWER_UP ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_LOWER_UP +#define MBG_NET_INTF_LINK_STATE_MASK_DORMANT ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_DORMANT ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_DORMANT +#define MBG_NET_INTF_LINK_STATE_MASK_BROADCAST ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_BROADCAST ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_BROADCAST +#define MBG_NET_INTF_LINK_STATE_MASK_MULTICAST ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_MULTICAST ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_MULTICAST +#define MBG_NET_INTF_LINK_STATE_MASK_ALL_MULTI ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_ALL_MULTI ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_ALL_MULTI +#define MBG_NET_INTF_LINK_STATE_MASK_DEBUG ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_DEBUG ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_DEBUG + +#define MBG_NET_INTF_LINK_STATE_MASK_LOOPBACK ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_LOOPBACK ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_LOOPBACK +#define MBG_NET_INTF_LINK_STATE_MASK_POINT_TO_POINT ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_POINT_TO_POINT ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_POINT_TO_POINT +#define MBG_NET_INTF_LINK_STATE_MASK_NO_ARP ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_NO_ARP ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_NO_ARP +#define MBG_NET_INTF_LINK_STATE_MASK_PROMISC ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_PROMISC ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_PROMISC +#define MBG_NET_INTF_LINK_STATE_MASK_MASTER ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_MASTER ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_MASTER +#define MBG_NET_INTF_LINK_STATE_MASK_SLAVE ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_SLAVE ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_SLAVE +#define MBG_NET_INTF_LINK_STATE_MASK_PORT_SEL ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_PORT_SEL ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_PORT_SEL +#define MBG_NET_INTF_LINK_STATE_MASK_AUTO_MEDIA ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_AUTO_MEDIA ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_AUTO_MEDIA + +#define MBG_NET_INTF_LINK_STATE_MASK_ECHO ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_ECHO ) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_ECHO +#define MBG_NET_INTF_LINK_STATE_MASK_DYNAMIC ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_DYNAMIC) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_DYNAMIC +#define MBG_NET_INTF_LINK_STATE_MASK_NO_TRAILERS ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_NO_TRAILERS) ///< see ::MBG_NET_INTF_LINK_STATE_BIT_NO_TRAILERS + +/** @} anchor MBG_NET_INTF_LINK_STATE_MASKS */ /** - * @brief Network link option bits + * @brief Network interface link option bits * - * @see ::MBG_NET_LINK_OPT_MASKS + * @see ::MBG_NET_INTF_LINK_OPT_MASKS */ -enum MBG_NET_LINK_OPTS +enum MBG_NET_INTF_LINK_OPTS { - MBG_NET_LINK_OPT_CAN_SET_MAC, - MBG_NET_LINK_OPT_CAN_BOND, - MBG_NET_LINK_OPT_CAN_SYNCE, - N_MBG_NET_LINK_OPTS + MBG_NET_INTF_LINK_OPT_CAN_SET_MAC, + MBG_NET_INTF_LINK_OPT_CAN_SYNCE_IN, + MBG_NET_INTF_LINK_OPT_CAN_SYNCE_OUT, + MBG_NET_INTF_LINK_OPT_CAN_AUTONEG, + MBG_NET_INTF_LINK_OPT_CAN_NTP_HW_TS, + MBG_NET_INTF_LINK_OPT_CAN_PTP_HW_TS, + N_MBG_NET_INTF_LINK_OPTS }; + /** - * @brief Network link option masks + * @brief Network interface link option masks * - * @see ::MBG_NET_LINK_OPTS + * @see ::MBG_NET_INTF_LINK_OPTS */ -enum MBG_NET_LINK_OPT_MASKS +enum MBG_NET_INTF_LINK_OPT_MASKS { - MBG_NET_LINK_OPT_MASK_CAN_SET_MAC = ( 1UL << MBG_NET_LINK_OPT_CAN_SET_MAC ), ///< see ::MBG_NET_LINK_OPT_CAN_SET_MAC - MBG_NET_LINK_OPT_MASK_CAN_BOND = ( 1UL << MBG_NET_LINK_OPT_CAN_BOND ), ///< see ::MBG_NET_LINK_OPT_CAN_BOND - MBG_NET_LINK_OPT_MASK_CAN_SYNCE = ( 1UL << MBG_NET_LINK_OPT_CAN_SYNCE ) ///< see ::MBG_NET_LINK_OPT_CAN_SYNCE + MBG_NET_INTF_LINK_OPT_MASK_CAN_SET_MAC = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_SET_MAC ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_SET_MAC + MBG_NET_INTF_LINK_OPT_MASK_CAN_SYNCE_IN = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_SYNCE_IN ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_SYNCE_IN + MBG_NET_INTF_LINK_OPT_MASK_CAN_SYNCE_OUT = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_SYNCE_OUT ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_SYNCE_OUT + MBG_NET_INTF_LINK_OPT_MASK_CAN_AUTONEG = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_AUTONEG ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_AUTONEG + MBG_NET_INTF_LINK_OPT_MASK_CAN_NTP_HW_TS = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_NTP_HW_TS ), ///< see ::MBG_NET_INTF_LINK_OPT_CAN_NTP_HW_TS + MBG_NET_INTF_LINK_OPT_MASK_CAN_PTP_HW_TS = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_PTP_HW_TS ) ///< see ::MBG_NET_INTF_LINK_OPT_CAN_PTP_HW_TS }; /** - * @brief Network link roles + * @brief Network interface link bonding mode + * + * Used with ::MBG_NET_INTF_LINK_SETTINGS::bond_mode * - * Used with ::MBG_NET_LINK_SETTINGS::role to determine - * if a network link operates in normal mode, or in - * a special mode, e.g. as part of a higher level pseudo - * interface (bonding, etc.) + * @note if_bonding.h contains bonding modes under Linux, found no hint under Windows. + * BUT: Something similiar (concerning naming) can be configured under Windows + * via GUI in device manager, if supported. */ -enum MBG_NET_LINK_ROLES +enum MBG_NET_INTF_LINK_BOND_MODES { - MBG_NET_LINK_ROLE_UNKNOWN, ///< role can't be determined - MBG_NET_LINK_ROLE_NORMAL, ///< link is normal physical interface - MBG_NET_LINK_ROLE_MASTER, ///< link is master (e.g. bonding) - MBG_NET_LINK_ROLE_SLAVE, ///< link is slave (e.g. bonding) - N_MBG_NET_LINK_ROLES + MBG_NET_INTF_LINK_BOND_MODE_ROUNDROBIN, + MBG_NET_INTF_LINK_BOND_MODE_ACTIVEBACKUP, + MBG_NET_INTF_LINK_BOND_MODE_XOR, + MBG_NET_INTF_LINK_BOND_MODE_BROADCAST, + MBG_NET_INTF_LINK_BOND_MODE_8023AD, + MBG_NET_INTF_LINK_BOND_MODE_TLB, + MBG_NET_INTF_LINK_BOND_MODE_ALB, + N_MBG_NET_INTF_LINK_BOND_MODES }; -//##++++++++++++++++ TODO define masks? /** - * @brief Network link bonding bits + * @brief Network interface link bonding mode masks * - * @see SIOCGIFPFLAGS under Linux, found no hint under Windows + * @see ::MBG_NET_INTF_LINK_BOND_MODES */ -enum MBG_NET_LINK_ROLE_BITS +enum MBG_NET_INTF_LINK_BOND_MODE_MASKS { - MBG_NET_LINK_ROLE_BIT_BONDING, ///< Bonding master - MBG_NET_LINK_ROLE_BIT_BOND_SLAVE_INACTIVE, ///< Bonding slave is not active - MBG_NET_LINK_ROLE_BIT_BOND_MASTER_8023AD, ///< 802.3ad bonding master - MBG_NET_LINK_ROLE_BIT_BOND_MASTER_ALB, ///< Balanced-alb bonding master - N_MBG_NET_LINK_ROLE_BITS + MBG_NET_INTF_LINK_BOND_MODE_MASK_ROUNDROBIN = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_ROUNDROBIN ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_ROUNDROBIN + MBG_NET_INTF_LINK_BOND_MODE_MASK_ACTIVEBACKUP = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_ACTIVEBACKUP ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_ACTIVEBACKUP + MBG_NET_INTF_LINK_BOND_MODE_MASK_XOR = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_XOR ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_XOR + MBG_NET_INTF_LINK_BOND_MODE_MASK_BROADCAST = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_BROADCAST ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_BROADCAST + MBG_NET_INTF_LINK_BOND_MODE_MASK_8023AD = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_8023AD ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_8023AD + MBG_NET_INTF_LINK_BOND_MODE_MASK_TLB = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_TLB ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_TLB + MBG_NET_INTF_LINK_BOND_MODE_MASK_ALB = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_ALB ), ///< see ::MBG_NET_INTF_LINK_BOND_MODE_ALB }; + /** - * @brief Network link role masks + * @brief Network interface link bonding mode name strings * - * @see ::MBG_NET_LINK_ROLE_BITS + * @see ::MBG_NET_INTF_LINK_BOND_MODES */ -enum MBG_NET_LINK_ROLE_MASKS -{ - MBG_NET_LINK_ROLE_MASK_BONDING = ( 1UL << MBG_NET_LINK_ROLE_BIT_BONDING ), ///< see ::MBG_NET_LINK_ROLE_BIT_BONDING - MBG_NET_LINK_ROLE_MASK_BOND_SLAVE_INACTIVE = ( 1UL << MBG_NET_LINK_ROLE_BIT_BOND_SLAVE_INACTIVE ), ///< see ::MBG_NET_LINK_ROLE_BIT_BOND_SLAVE_INACTIVE - MBG_NET_LINK_ROLE_MASK_BOND_MASTER_8023AD = ( 1UL << MBG_NET_LINK_ROLE_BIT_BOND_MASTER_8023AD ), ///< see ::MBG_NET_LINK_ROLE_BIT_BOND_MASTER_8023AD - MBG_NET_LINK_ROLE_MASK_BOND_MASTER_ALB = ( 1UL << MBG_NET_LINK_ROLE_BIT_BOND_MASTER_ALB ), ///< see ::MBG_NET_LINK_ROLE_BIT_BOND_MASTER_ALB - N_MBG_NET_LINK_ROLE_MASKS -}; +#define MBG_NET_INTF_LINK_BOND_MODE_STRS \ +{ \ + "Round Robin", \ + "Active Backup", \ + "XOR", \ + "Broadcast", \ + "802.3ad (LACP)", \ + "TLB", \ + "ALB" \ +} /** - * @brief Network link bonding mode - * - * Used with ::MBG_NET_LINK_SETTINGS::role_value + * @brief Network interface link bonding states * - * @note if_bonding.h contains bonding modes under Linux, found no hint under Windows. - * BUT: Something similiar (concerning naming) can be configured under Windows - * via GUI in device manager, if supported. + * Used with ::MBG_NET_INTF_LINK_SETTINGS::bond_state */ -enum MBG_NET_LINK_BOND_MODES +enum MBG_NET_INTF_LINK_BOND_STATES { - MBG_NET_LINK_BOND_MODE_UNKNOWN, - MBG_NET_LINK_BOND_MODE_ROUNDROBIN, - MBG_NET_LINK_BOND_MODE_ACTIVEBACKUP, - MBG_NET_LINK_BOND_MODE_XOR, - MBG_NET_LINK_BOND_MODE_BROADCAST, - MBG_NET_LINK_BOND_MODE_8023AD, - MBG_NET_LINK_BOND_MODE_TLB, - MBG_NET_LINK_BOND_MODE_ALB, - N_MBG_NET_LINK_BOND_MODES + MBG_NET_INTF_LINK_BOND_STATE_ACTIVE, + MBG_NET_INTF_LINK_BOND_STATE_BACKUP, + N_MBG_NET_INTF_LINK_BOND_STATES }; /** - * @brief Network logical interface commands + * @brief Network interface link type bits + * + * Used with ::MBG_NET_INTF_LINK_SETTINGS::type * - * Used with ::MBG_NET_INTF_SETTINGS::cmd + * @see ::MBG_NET_INTF_LINK_TYPE_MASKS */ -enum MBG_NET_LOG_INTF_CMDS +enum MBG_NET_INTF_LINK_TYPES { - MBG_NET_LOG_CMD_NONE, - MBG_NET_LOG_CMD_ADD_UPDATE, - MBG_NET_LOG_CMD_REMOVE, - N_MBG_NET_LOG_CMDS + MBG_NET_INTF_LINK_TYPE_PHYS, ///< Real physical network interface + MBG_NET_INTF_LINK_TYPE_VLAN, ///< VLAN interface, assigned to physical interface + MBG_NET_INTF_LINK_TYPE_BOND, ///< Bonding interface, which acts as bonding master + N_MBG_NET_INTF_LINK_TYPE_BITS }; /** - * @brief Network logical interface roles + * @brief Network interface link type masks * - * Used with ::MBG_NET_INTF_SETTINGS::role + * Used with ::MBG_NET_INTF_LINK_INFO::supp_types + * + * @see ::MBG_NET_INTF_LINK_TYPES */ -enum MBG_NET_LOG_INTF_ROLES +enum MBG_NET_INTF_LINK_TYPE_MASKS { - MBG_NET_LOG_ROLE_STANDARD, - MBG_NET_LOG_ROLE_BOND, - MBG_NET_LOG_ROLE_VLAN, - N_MBG_NET_INTF_ROLE + MBG_NET_INTF_LINK_TYPE_MASK_PHYS = ( 1UL << MBG_NET_INTF_LINK_TYPE_PHYS ), ///< see ::MBG_NET_INTF_LINK_TYPE_PHYS + MBG_NET_INTF_LINK_TYPE_MASK_VLAN = ( 1UL << MBG_NET_INTF_LINK_TYPE_VLAN ), ///< see ::MBG_NET_INTF_LINK_TYPE_VLAN + MBG_NET_INTF_LINK_TYPE_MASK_BOND = ( 1UL << MBG_NET_INTF_LINK_TYPE_BOND ) ///< see ::MBG_NET_INTF_LINK_TYPE_BOND }; /** - * @brief Network interface bits + * @brief Network interface address bits * - * @see ::MBG_NET_INTF_MASKS + * @see ::MBG_NET_INTF_ADDR_MASKS * - * Used with ::MBG_NET_INTF_INFO::supp_flags + * Used with ::MBG_NET_INTF_ADDR_INFO::supp_flags and ::MBG_NET_INTF_ADDR_SETTINGS::flags */ -enum MBG_NET_INTF_BITS +enum MBG_NET_INTF_ADDR_BITS { - MBG_NET_INTF_BIT_EXT_ROUTING, - N_MBG_NET_INTF_BITS + MBG_NET_INTF_ADDR_BIT_DHCP4, ///< Address has been automatically assigned by DHCP via IPv4 + MBG_NET_INTF_ADDR_BIT_DHCP6, ///< Address has been automatically assigned by DHCP via IPv6 + N_MBG_NET_INTF_ADDR_FLAGS }; + /** - * @brief Network interface masks + * @brief Network interface address masks * - * @see ::MBG_NET_INTF_BITS + * @see ::MBG_NET_INTF_ADDR_BITS */ -enum MBG_NET_INTF_MASKS +enum MBG_NET_INTF_ADDR_MASKS +{ + MBG_NET_INTF_ADDR_MASK_DHCP4 = ( 1UL << MBG_NET_INTF_ADDR_BIT_DHCP4 ), ///< see ::MBG_NET_INTF_ADDR_BIT_DHCP4 + MBG_NET_INTF_ADDR_MASK_DHCP6 = ( 1UL << MBG_NET_INTF_ADDR_BIT_DHCP6 ) ///< see ::MBG_NET_INTF_ADDR_BIT_DHCP6 +}; + + +enum MBG_NET_INTF_ROUTE_TYPES { - MBG_NET_INTF_MASK_EXT_ROUTING = ( 1UL << MBG_NET_INTF_BIT_EXT_ROUTING ) ///< see ::MBG_NET_INTF_BIT_EXT_ROUTING + MBG_NET_INTF_ROUTE_TYPE_UNKNOWN, + MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY, + MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY, + MBG_NET_INTF_ROUTE_TYPE_DEST_ADDR, + N_MBG_NET_INTF_ROUTE_TYPES }; /** @} defgroup group_ext_net_cfg_types */ @@ -8463,18 +12119,24 @@ enum MBG_NET_INTF_MASKS */ typedef struct { - MBG_HOSTNAME hostname; ///< hostname, eventually FQDN including domain name - uint32_t reserved; ///< currently reserved, always 0 - uint32_t flags; ///< currently reserved, always 0 - //##++++ TODO: flags could control IPv6, enable forwarding, etc. + MBG_HOSTNAME hostname; ///< hostname, eventually FQDN including domain name + + uint8_t num_intf_link; ///< number of detected/configured physical network interfaces (links), see ::MBG_NET_INTF_LINK_INFO_IDX + uint8_t num_intf_addr; ///< number of configured interface addresses, see ::MBG_NET_INTF_ADDR_INFO_IDX + uint8_t num_dns_srvr; ///< number of configured DNS servers, see ::MBG_IP_ADDR_IDX + uint8_t num_dns_srch_dom; ///< number of configured DNS search domains, see ::MBG_NET_NAME_IDX + uint8_t num_intf_route; ///< number of configured interface routes, see ::MBG_NET_INTF_ROUTE_INFO_IDX + + uint8_t reserved; ///< currently reserved, always 0 + uint16_t flags; ///< currently reserved, always 0 } MBG_NET_GLB_CFG_SETTINGS; -#define _mbg_swab_net_glb_cfg_settings( _p ) \ -{ \ - _mbg_swab32( &(_p)->reserved ); \ - _mbg_swab32( &(_p)->flags ); \ -} +#define _mbg_swab_net_glb_cfg_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) /** @@ -8483,33 +12145,35 @@ typedef struct typedef struct { MBG_NET_GLB_CFG_SETTINGS glb_settings; - uint16_t num_link; ///< max. supported links (physical interfaces), see ::MBG_NET_LINK_SETTINGS_IDX, ::MBG_NET_LINK_INFO_IDX - uint16_t num_intf; ///< max. logical (including virtual) interfaces, see ::MBG_NET_INTF_SETTINGS_IDX, ::MBG_NET_INTF_INFO_IDX - uint16_t num_dns_srvr; ///< max. configurable DNS server addresses, using ::MBG_IP_ADDR_IDX records - uint16_t num_dns_srch_dom; ///< max. configurable DNS search domain records, using ::MBG_NET_NAME_IDX records - uint16_t num_static_routes; ///< max. configurable static routes - uint16_t max_hostname_len; ///< max. length of hostname including trailing 0; if set to 0, max. length is 256 (see rfc1123) - uint32_t reserved_1; ///< currently reserved, always 0 - uint32_t reserved_2; ///< currently reserved, always 0 - uint32_t flags_1; ///< currently reserved, always 0 - uint32_t flags_2; ///< currently reserved, always 0 + uint16_t n_supp_intf_link; ///< max. number of supported physical network interfaces (links), see ::MBG_NET_INTF_LINK_SETTINGS_IDX, ::MBG_NET_INTF_LINK_INFO_IDX + uint16_t n_supp_intf_addr; ///< max. number of supported interface addresses, see ::MBG_NET_INTF_ADDR_SETTINGS_IDX, ::MBG_NET_INTF_ADDR_INFO_IDX + uint16_t n_supp_dns_srvr; ///< max. number of supported DNS server addresses, using ::MBG_IP_ADDR_IDX records + uint16_t n_supp_dns_srch_dom; ///< max. number of supported DNS search domain records, using ::MBG_NET_NAME_IDX records + uint16_t n_supp_intf_route; ///< max. number of supported interface routes, see ::MBG_NET_INTF_ROUTE_SETTINGS_IDX, ::MBG_NET_INTF_ROUTE_INFO_IDX + uint16_t max_hostname_len; ///< max. length of hostname including trailing 0; if set to 0, max. length is 256 (see rfc1123) + uint32_t reserved_1; ///< currently reserved, always 0 + uint32_t reserved_2; ///< currently reserved, always 0 + uint32_t feat_flags; ///< Feature flags, see ::MBG_NET_GLB_CFG_INFO_MASKS + uint32_t flags_2; ///< currently reserved, always 0 } MBG_NET_GLB_CFG_INFO; #define _mbg_swab_net_glb_cfg_info( _p ) \ +do \ { \ _mbg_swab_net_glb_cfg_settings( &(_p)->glb_settings ); \ - _mbg_swab16( &(_p)->num_link ); \ - _mbg_swab16( &(_p)->num_intf ); \ - _mbg_swab16( &(_p)->num_dns_srvr ); \ - _mbg_swab16( &(_p)->num_dns_srch_dom ); \ - _mbg_swab16( &(_p)->num_static_routes ); \ + _mbg_swab16( &(_p)->n_supp_intf_link ); \ + _mbg_swab16( &(_p)->n_supp_intf_addr ); \ + _mbg_swab16( &(_p)->n_supp_dns_srvr ); \ + _mbg_swab16( &(_p)->n_supp_dns_srch_dom ); \ + _mbg_swab16( &(_p)->n_supp_intf_route ); \ _mbg_swab16( &(_p)->max_hostname_len ); \ _mbg_swab32( &(_p)->reserved_1 ); \ _mbg_swab32( &(_p)->reserved_2 ); \ - _mbg_swab32( &(_p)->flags_1 ); \ + _mbg_swab32( &(_p)->feat_flags ); \ _mbg_swab32( &(_p)->flags_2 ); \ -} +} while ( 0 ) + /** @@ -8521,7 +12185,7 @@ typedef struct uint8_t reserved_1; ///< reserved, currently always 0 @todo Do we need this as scope indicator? uint16_t reserved_2; ///< reserved, currently always 0 - union + union u_addr { IP4_ADDR ip4_addr; ///< IPv4 address if ::MBG_IP_ADDR::type == MBG_IP_ADDR_TYPE_IP4 IP6_ADDR ip6_addr; ///< IPv6 address if ::MBG_IP_ADDR::type == MBG_IP_ADDR_TYPE_IP6 @@ -8529,6 +12193,27 @@ typedef struct } MBG_IP_ADDR; +#define _mbg_swab_ip_addr( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->type ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + \ + switch ( (_p)->type ) \ + { \ + case MBG_IP_ADDR_TYPE_IP4: \ + _mbg_swab_ip4_addr( &(_p)->u_addr.ip4_addr ); \ + break; \ + \ + case MBG_IP_ADDR_TYPE_IP6: \ + _mbg_swab_ip6_addr( &(_p)->u_addr.ip6_addr ); \ + break; \ + } \ + \ +} while ( 0 ) + + /** * @brief An IPv4 or IPv6 network address, plus index @@ -8540,6 +12225,36 @@ typedef struct } MBG_IP_ADDR_IDX; +#define _mbg_swab_ip_addr_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ip_addr( &(_p)->addr ); \ +} while ( 0 ) + + +/** + * @brief An IPv4 or IPv6 network address plus UDP or TCP port number + */ +typedef struct +{ + MBG_IP_ADDR addr; ///< see ::MBG_IP_ADDR + + uint16_t port; ///< UDP or TCP port + uint16_t flags; ///< currently always 0 + //##+++++ TODO should the flags field indicate if the port is UDP and/or TCP? + +} MBG_IP_ADDR_PORT; + +#define _mbg_swab_ip_addr_port( _p ) \ +do \ +{ \ + _mbg_swab_ip_addr( &(_p)->addr ); \ + _mbg_swab16( &(_p)->port ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + + /** * @brief Network host or domain name @@ -8550,6 +12265,13 @@ typedef struct } MBG_NET_NAME; +#define _mbg_swab_net_name( _p ) \ +do \ +{ \ + _mbg_swab_mbg_host_name( &(_p)->name ); \ +} while ( 0 ) + + /** * @brief Network host or domain name, plus index @@ -8561,55 +12283,97 @@ typedef struct } MBG_NET_NAME_IDX; +#define _mbg_swab_net_name_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_name( &(_p)->net_name ); \ +} while ( 0 ) + /** - * @brief Link (physical interface) specific settings + * @brief Physical network interface link specific settings */ typedef struct { - MBG_MAC_ADDR mac_addr; ///< Physical hardware address - MBG_MAC_ADDR broadcast; ///< Physical broadcast address - uint32_t mtu; ///< Max. packet size in bytes - uint32_t states; ///< see ::MBG_NET_LINK_STATE_BITS - uint32_t flags; ///< Reserved, currently 0 - uint32_t reserved_1; ///< Reserved, currently 0 - uint32_t reserved_2; ///< Reserved, currently 0 - uint16_t bond_idx; ///< Current primary slave link index in ::MBG_NET_LINK_ROLE_MASTER role, - ///< current bonding master link index in ::MBG_NET_LINK_ROLE_SLAVE role, - ///< otherwise reserved and usually 0. - uint8_t speed_mode; ///< see ::MBG_NET_LINK_MODES - uint8_t port; ///< see ::MBG_NET_LINK_PORTS - uint8_t role; ///< see ::MBG_NET_LINK_ROLES - uint8_t reserved[3]; ///< Alignment. Can be used in future for usefull stuff. -//##+++++ TODO check reserved above - uint32_t role_flags; ///< see ::MBG_NET_LINK_ROLE_BITS - uint32_t role_value; ///< Additional role parameters depending on role and role_flags, - ///< e.g. if role is master and flags contain bonding. - ///< See ::MBG_NET_LINK_BOND_MODES. -} MBG_NET_LINK_SETTINGS; + char name[MBG_IFNAMSIZ]; ///< Interface name + MBG_MAC_ADDR mac_addr; ///< Physical hardware address + MBG_MAC_ADDR broadcast; ///< Physical broadcast address -#define _mbg_swab_net_link_settings( _p ) \ + uint32_t if_index; ///< Interface index assigned by the kernel + uint32_t common_if_index; ///< Common interface index assigned by the lib (associated with the MAC address), + ///< Valid if ::MBG_NET_INTF_LINK_SETTINGS::type is ::MBG_NET_INTF_LINK_TYPE_PHYS + uint32_t ass_if_index; ///< Interface index of the associated physical interface link, + ///< Valid if ::MBG_NET_INTF_LINK_SETTINGS::type is ::MBG_NET_INTF_LINK_TYPE_VLAN + + uint32_t flags; ///< Reserved, currently 0 + uint32_t states; ///< see @ref MBG_NET_INTF_LINK_STATE_MASKS + + uint32_t hw_type; ///< Hardware type of interface (see linux/if_arp.h, i.e. ARPHRD_ETHER) ::TODO + uint32_t mtu; ///< Max. packet size in bytes + uint32_t txqlen; ///< Transmission queue length (number of packets) + uint32_t speed; ///< Link speed in MBit/s + + uint8_t type; ///< see ::MBG_NET_INTF_LINK_TYPES + uint8_t duplex; ///< Duplex mode, half (0) or full (1) + uint8_t autoneg; ///< Indicates, whether autonegotiation is enabled or disabled + uint8_t port_type; ///< see ::MBG_NET_INTF_LINK_PORT_TYPES + + uint8_t bond_mode; ///< Bonding mode, see ::MBG_NET_INTF_LINK_BOND_MODES + ///< Valid if ::MBG_NET_INTF_LINK_STATE_MASK_MASTER is set in ::MBG_NET_INTF_LINK_SETTINGS::states + uint8_t bond_state; ///< Status of this interface in the bonding group, see ::MBG_NET_INTF_LINK_BOND_STATES + ///< Valid if MBG_NET_INTF_LINK_STATE_MASK_SLAVE is set in ::MBG_NET_INTF_LINK_SETTINGS::states + uint16_t bond_idx; ///< Interface index of the bonding master link, see ::MBG_NET_INTF_LINK_SETTINGS::if_index + ///< Valid, if MBG_NET_INTF_LINK_STATE_MASK_SLAVE is set in ::MBG_NET_INTF_LINK_SETTINGS::states + + uint16_t vlan_cfg; ///< VLAN configuration options, see ::MBG_VLAN_CFG + ///< Valid if ::MBG_NET_INTF_LINK_SETTINGS::type is ::MBG_NET_INTF_LINK_TYPE_VLAN + uint16_t reserved_1; ///< Reserved, currently 0 + + uint32_t reserved_2; ///< Reserved, currently 0 + uint32_t reserved_3; ///< Reserved, currently 0 + +} MBG_NET_INTF_LINK_SETTINGS; + +#define _mbg_swab_net_intf_link_settings( _p ) \ +do \ { \ - _mbg_swab32( &(_p)->mtu ); \ - _mbg_swab32( &(_p)->states ); \ + _mbg_swab32( &(_p)->if_index ); \ + _mbg_swab32( &(_p)->common_if_index ); \ + _mbg_swab32( &(_p)->ass_if_index ); \ _mbg_swab32( &(_p)->flags ); \ - _mbg_swab32( &(_p)->reserved_1 ); \ - _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->states ); \ + _mbg_swab32( &(_p)->hw_type ); \ + _mbg_swab32( &(_p)->mtu ); \ + _mbg_swab32( &(_p)->txqlen ); \ + _mbg_swab32( &(_p)->speed ); \ _mbg_swab16( &(_p)->bond_idx ); \ - _mbg_swab32( &(_p)->role_flags ); \ - _mbg_swab32( &(_p)->role_value ); \ -} + _mbg_swab16( &(_p)->vlan_cfg ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + /** * @brief Link (physical interface) specific settings, plus index */ typedef struct { - uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::num_link-1 - MBG_NET_LINK_SETTINGS settings; + uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::n_supp_intf_link-1 + MBG_NET_INTF_LINK_SETTINGS settings; + +} MBG_NET_INTF_LINK_SETTINGS_IDX; + +#define _mbg_swab_net_intf_link_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_link_settings( &(_p)->settings ); \ +} while ( 0 ) -} MBG_NET_LINK_SETTINGS_IDX; /** @@ -8617,142 +12381,256 @@ typedef struct */ typedef struct { - MBG_NET_LINK_SETTINGS link_settings; ///< see ::MBG_NET_LINK_SETTINGS - uint32_t supp_opts; ///< see ::MBG_NET_LINK_OPT_MASKS - uint32_t supp_speed_modes; ///< see ::MBG_NET_LINK_MODE_MASKS - uint32_t supp_link_ports; ///< see ::MBG_NET_LINK_PORT_MASKS - uint32_t supp_states; ///< see ::MBG_NET_LINK_STATE_MASKS + MBG_NET_INTF_LINK_SETTINGS link_settings; ///< see ::MBG_NET_INTF_LINK_SETTINGS + uint32_t supp_flags; ///< Reserved, currently 0 + uint32_t supp_states; ///< see @ref MBG_NET_INTF_LINK_STATE_MASKS + uint32_t supp_types; ///< see ::MBG_NET_INTF_LINK_TYPE_MASKS + uint32_t supp_speed_modes; ///< see @ref MBG_NET_INTF_LINK_SPEED_MODE_MASKS + uint32_t supp_port_types; ///< see ::MBG_NET_INTF_LINK_PORT_TYPE_MASKS + uint32_t supp_opts; ///< see ::MBG_NET_INTF_LINK_OPT_MASKS + uint32_t supp_bond_modes; ///< see ::MBG_NET_INTF_LINK_BOND_MODE_MASKS + uint32_t reserved_1; uint32_t reserved_2; uint32_t reserved_3; + uint32_t reserved_4; +} MBG_NET_INTF_LINK_INFO; -} MBG_NET_LINK_INFO; +#define _mbg_swab_net_intf_link_info( _p ) \ +do \ +{ \ + _mbg_swab_net_intf_link_settings( &(_p)->link_settings ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->supp_states ); \ + _mbg_swab32( &(_p)->supp_types ); \ + _mbg_swab32( &(_p)->supp_speed_modes ); \ + _mbg_swab32( &(_p)->supp_port_types ); \ + _mbg_swab32( &(_p)->supp_opts ); \ + _mbg_swab32( &(_p)->supp_bond_modes ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ +} while ( 0 ) -#define _mbg_swab_net_link_info( _p ) \ -{ \ - _mbg_swab_net_link_settings( &(_p)->link_settings ); \ - _mbg_swab32( &(_p)->supp_opts ); \ - _mbg_swab32( &(_p)->supp_speed_modes ); \ - _mbg_swab32( &(_p)->supp_link_ports ); \ - _mbg_swab32( &(_p)->supp_states ); \ - _mbg_swab32( &(_p)->reserved_2 ); \ - _mbg_swab32( &(_p)->reserved_3 ); \ -} /** - * @brief Query MBG_NET_LINK_INFO by its index + * @brief Query MBG_NET_INTF_LINK_INFO by its index */ typedef struct { - uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::num_link-1 - MBG_NET_LINK_INFO info; + uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_link-1 + MBG_NET_INTF_LINK_INFO info; ///< see ::MBG_NET_INTF_LINK_INFO -} MBG_NET_LINK_INFO_IDX; +} MBG_NET_INTF_LINK_INFO_IDX; + +#define _mbg_swab_net_intf_link_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_link_info( &(_p)->info ); \ +} while ( 0 ) /** - * @brief Interface specific settings, flags and supported features + * @brief Network interface address specific settings, flags and supported features * - * @note Use link_mac and role to identify uniquely its associated network link. + * @note Use if_index to identify uniquely its associated network link. */ typedef struct { - uint8_t cmd; ///< see ::MBG_NET_LOG_INTF_CMDS - uint8_t role; ///< see ::MBG_NET_LOG_INTF_ROLES - uint16_t reserved_1; ///< Reserved, currently 0 - uint32_t role_value; ///< Role specific value. E.g. VLAN ID - uint32_t flags; ///< Reserved, currently 0 - uint32_t reserved_2; ///< Reserved, currently 0 - MBG_IP_ADDR ip; ///< IP address associated with this interface - MBG_IP_ADDR gateway; ///< Interface specific. Reserved for future use. see ::MBG_IP_ADDR and ::MBG_NET_INTF_BIT_EXT_ROUTING - MBG_MAC_ADDR link_mac; ///< Unique identifier for related link (physical) interface - uint8_t prefix; ///< Number of subnet mask bits for CIDR notation, e.g. 24 for /24 - uint8_t reserved_3; ///< Reserved, currently 0 + char label[MBG_IFNAMSIZ]; ///< Interface label + + uint32_t addr_index; ///< Index of the address on the physical interface it is assigned to + uint32_t ass_if_index; ///< Index of the associated interface link, see ::MBG_NET_INTF_LINK_SETTINGS::if_index + + uint32_t flags; ///< see ::MBG_NET_INTF_ADDR_MASKS + + MBG_IP_ADDR ip; ///< IP address associated with this interface + MBG_IP_ADDR broadcast; ///< Broadcast address associated with this interface + + uint8_t prefix_bits; ///< Number of subnet mask bits for CIDR notation, e.g. 24 for /24 + uint8_t reserved_1; ///< Reserved, currently 0 + uint16_t reserved_2; ///< Reserved, currently 0 -} MBG_NET_INTF_SETTINGS; + uint32_t reserved_3; ///< Reserved, currently 0 + uint32_t reserved_4; ///< Reserved, currently 0 + uint32_t reserved_5; ///< Reserved, currently 0 + +} MBG_NET_INTF_ADDR_SETTINGS; + +#define _mbg_swab_net_intf_addr_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->addr_index ); \ + _mbg_swab32( &(_p)->ass_if_index ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab_ip_addr( &(_p)->ip ); \ + _mbg_swab_ip_addr( &(_p)->broadcast ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->reserved_5 ); \ +} while ( 0 ) /** - * @brief Query MBG_NET_INTF_INFO by its index + * @brief Query MBG_NET_INTF_ADDR_SETTINGS by its index */ typedef struct { - uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::num_intf-1 - MBG_NET_INTF_SETTINGS settings; + uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_addr-1 + MBG_NET_INTF_ADDR_SETTINGS settings; ///< see ::MBG_NET_INTF_ADDR_SETTINGS -} MBG_NET_INTF_SETTINGS_IDX; +} MBG_NET_INTF_ADDR_SETTINGS_IDX; + +#define _mbg_swab_net_intf_addr_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_addr_settings( &(_p)->settings ); \ +} while ( 0 ) /** - * @brief Interface specific settings, flags and supported features + * @brief Network interface address specific settings, flags and supported features */ typedef struct { - MBG_NET_INTF_SETTINGS intf_settings; - uint32_t supp_flags; ///< see ::MBG_NET_INTF_MASKS - uint32_t reserved_1; ///< Reserved, currently 0 - uint32_t reserved_2; ///< Reserved, currently 0 + MBG_NET_INTF_ADDR_SETTINGS addr_settings; ///< see ::MBG_NET_INTF_ADDR_SETTINGS + uint32_t supp_flags; ///< see ::MBG_NET_INTF_ADDR_MASKS + uint32_t reserved_1; ///< Reserved, currently 0 + uint32_t reserved_2; ///< Reserved, currently 0 -} MBG_NET_INTF_INFO; +} MBG_NET_INTF_ADDR_INFO; + +#define _mbg_swab_net_intf_addr_info( _p ) \ +do \ +{ \ + _mbg_swab_net_intf_addr_settings( &(_p)->addr_settings ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) /** - * @brief Query MBG_NET_INTF_INFO by its index + * @brief Query MBG_NET_INTF_ADDR_INFO by its index */ typedef struct { - uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_INFO::num_intf-1 - MBG_NET_INTF_INFO info; + uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_addr-1 + MBG_NET_INTF_ADDR_INFO info; ///< see ::MBG_NET_INTF_ADDR_INFO + +} MBG_NET_INTF_ADDR_INFO_IDX; -} MBG_NET_INTF_INFO_IDX; +#define _mbg_swab_net_intf_addr_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_addr_info( &(_p)->info ); \ +} while ( 0 ) /** - * @brief An IPv4 or IPv6 network address plus UDP or TCP port number + * @brief Network interface route specific settings + * + * @note Use link_mac and ass_addr_idx to identify the associated network address and network link (via address) */ typedef struct { - MBG_IP_ADDR addr; ///< see ::MBG_IP_ADDR + uint8_t type; ///< Type of the route entry, see ::MBG_NET_INTF_ROUTE_TYPES + uint8_t reserved_1; ///< Reserved, currently 0 + uint16_t reserved_2; ///< Reserved, currently 0 - uint16_t port; ///< UDP or TCP port - uint16_t flags; ///< currently always 0 - //##+++++ TODO should the flags field indicate if the port is UDP and/or TCP? + MBG_IP_ADDR gateway; ///< Gateway IP address, only used if type is + ///< ::MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY or ::MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY + MBG_IP_ADDR dst; ///< Destination IP address, only used if ::MBG_NET_INTF_ROUTE_SETTINGS::type is + ///< ::MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY or ::MBG_NET_INTF_ROUTE_TYPE_DEST_ADDR + uint8_t dst_prefix_bits; ///< Prefix Bits for the destination address -} MBG_IP_ADDR_PORT; + uint32_t ass_if_index; ///< Index of the associated interface link, see ::MBG_NET_INTF_LINK_SETTINGS::if_index + uint32_t ass_addr_index; ///< Index of the associated interface address, see ::MBG_NET_INTF_ADDR_SETTINGS::addr_index, + ///< Valid if ::MBG_NET_INTF_ROUTE_SETTINGS::type is ::MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY or ::MBG_NET_INTF_ROUTE_TYPE_DEST_ADDR + uint32_t reserved_3; ///< Reserved, currently 0 + uint32_t reserved_4; ///< Reserved, currently 0 + uint32_t reserved_5; ///< Reserved, currently 0 +} MBG_NET_INTF_ROUTE_SETTINGS; + +#define _mbg_swab_net_intf_route_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab_ip_addr( &(_p)->gateway ); \ + _mbg_swab_ip_addr( &(_p)->dst ); \ + _mbg_swab32( &(_p)->ass_if_index ); \ + _mbg_swab32( &(_p)->ass_addr_index ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->reserved_5 ); \ +} while ( 0 ) -#if 0 //##++++++++++++++++++++++ /** - * @brief Network service configuration - * - * Used to configure known services, e.g SSH, FTP, etc. + * @brief Query MBG_NET_INTF_ROUTE_SETTINGS by its index */ typedef struct { - uint16_t svc_type; ///< see ::MBG_NET_SVC_TYPES - uint16_t reserved; ///< reserved, currently always 0 - MBG_IP_ADDR_PORT settings; ///< The network address and port a service listens on - uint32_t flags; ///< reserved, currently always 0 + uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_route-1 + MBG_NET_INTF_ROUTE_SETTINGS settings; ///< see ::MBG_NET_INTF_ROUTE_SETTINGS -} MBG_NET_INTF_CFG; +} MBG_NET_INTF_ROUTE_SETTINGS_IDX; +#define _mbg_swab_net_intf_route_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_route_settings( &(_p)->settings ); \ +} while ( 0 ) /** - * @brief + * @brief Network interface address specific settings */ typedef struct { - uint8_t b[IP6_ADDR_BYTES]; ///< bytes holding the address bits, b[0] == LSBs -//##+++ uint8_t cidr_net_mask; ///< number of CIDR net mask bits, 0..::IP6_ADDR_BITS -// uint8_t reserved; ///< not yet used, always 0 -// uint16_t flags; ///< not yet used, always 0 + MBG_NET_INTF_ROUTE_SETTINGS route_settings; ///< see ::MBG_NET_INTF_ROUTE_SETTINGS + uint32_t reserved_1; ///< Reserved, currently 0 + uint32_t reserved_2; ///< Reserved, currently 0 + uint32_t reserved_3; ///< Reserved, currently 0 + uint32_t reserved_4; ///< Reserved, currently 0 +} MBG_NET_INTF_ROUTE_INFO; -} MBG_NET_INTF_CFG; +#define _mbg_swab_net_intf_route_info( _p ) \ +do \ +{ \ + _mbg_swab_net_intf_route_settings( &(_p)->route_settings ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ +} while ( 0 ) + + +/** + * @brief Query MBG_NET_INTF_ROUTE_INFO by its index + */ +typedef struct +{ + uint16_t idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_route-1 + MBG_NET_INTF_ROUTE_INFO info; ///< see ::MBG_NET_INTF_ROUTE_INFO + +} MBG_NET_INTF_ROUTE_INFO_IDX; + +#define _mbg_swab_net_intf_route_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_route_info( &(_p)->info ); \ +} while ( 0 ) -#endif /** @} defgroup group_ext_net_cfg */ @@ -8760,6 +12638,273 @@ typedef struct + + +/** + * @defgroup group_ucap_net User Captures via Network + * + * @note Group for the user capture via network feature + * Only supported if ::MBG_XFEATURE_UCAP_NET is set in extended features + * Corresponding GPS commands are ::GPS_UCAP_NET_GLB_INFO and ::GPS_UCAP_NET_RECV_INFO_IDX + * + * @{ */ + + +#define MBG_UCAP_NET_DEFAULT_UDP_PORT 50815 + +/** + * @brief Transfer mode for user captures via network + * + * @see ::MBG_UCAP_NET_TRANSF_MODE_MASKS + * + * Used with ::MBG_UCAP_NET_RECV_SETTINGS::mode + */ +enum MBG_UCAP_NET_TRANSF_MODE +{ + MBG_UCAP_NET_TRANSF_MODE_UNKNOWN, ///< Unknown transfer mode + MBG_UCAP_NET_TRANSF_MODE_ON_REQ, ///< User captures will be transferred on request only + MBG_UCAP_NET_TRANSF_MODE_AUTO, ///< User captures are being transferred automatically + N_MBG_UCAP_NET_TRANSF_MODES +}; + + +/** + * @brief Masks for transfer mode used with ::MBG_UCAP_NET_GLB_INFO::supp_modes + * + * @see ::MBG_UCAP_NET_TRANSF_MODE + */ +enum MBG_UCAP_NET_TRANSF_MODE_MASKS +{ + MBG_UCAP_NET_TRANSF_MODE_MASK_UNKNOWN = ( 1UL << MBG_UCAP_NET_TRANSF_MODE_UNKNOWN ), ///< see ::MBG_UCAP_NET_TRANSF_MODE_UNKNOWN + MBG_UCAP_NET_TRANSF_MODE_MASK_ON_REQ = ( 1UL << MBG_UCAP_NET_TRANSF_MODE_ON_REQ ), ///< see ::MBG_UCAP_NET_TRANSF_MODE_ON_REQ + MBG_UCAP_NET_TRANSF_MODE_MASK_AUTO = ( 1UL << MBG_UCAP_NET_TRANSF_MODE_AUTO ) ///< see ::MBG_UCAP_NET_TRANSF_MODE_AUTO +}; + + + +/** + * @brief Transfer protocol for user captures via network + * + * @see ::MBG_UCAP_NET_TRANSF_PROTO_MASKS + * + * Used with ::MBG_UCAP_NET_RECV_SETTINGS::proto + */ +enum MBG_UCAP_NET_TRANSF_PROTO +{ + MBG_UCAP_NET_TRANSF_PROTO_UNKNOWN, ///< Unknown transfer mode + MBG_UCAP_NET_TRANSF_PROTO_UDP, ///< User captures are transferred via UDP + N_MBG_UCAP_NET_TRANSF_PROTOS +}; + + +/** + * @brief Masks for transfer protocol used with ::MBG_UCAP_NET_GLB_INFO::supp_protos + * + * @see ::MBG_UCAP_NET_TRANSF_PROTO + */ +enum MBG_UCAP_NET_TRANSF_PROTO_MASKS +{ + MBG_UCAP_NET_TRANSF_PROTO_MASK_UNKNOWN = ( 1UL << MBG_UCAP_NET_TRANSF_PROTO_UNKNOWN ), ///< see ::MBG_UCAP_NET_TRANSF_PROTO_UNKNOWN + MBG_UCAP_NET_TRANSF_PROTO_MASK_UDP = ( 1UL << MBG_UCAP_NET_TRANSF_PROTO_UDP ) ///< see ::MBG_UCAP_NET_TRANSF_PROTO_UDP +}; + + + +/** + * @brief Supported flags for user captures via network + * + * @see ::MBG_UCAP_NET_SUPP_FLAG_MASKS + */ +enum MBG_UCAP_NET_SUPP_FLAGS +{ + MBG_UCAP_NET_SUPP_FLAG_IPV6, + N_MBG_UCAP_NET_SUPP_FLAGS +}; + + +/** + * @brief Masks for supported flags used with ::MBG_UCAP_NET_GLB_INFO::supp_flags + * + * @see ::MBG_UCAP_NET_TRANSF_PROTO + */ +enum MBG_UCAP_NET_SUPP_FLAG_MASKS +{ + MBG_UCAP_NET_SUPP_FLAG_MASK_IPV6 = ( 1UL << MBG_UCAP_NET_SUPP_FLAG_IPV6 ) ///< see ::MBG_UCAP_NET_SUPP_FLAG_IPV6 +}; + + +/** + * @brief Global settings for user captures via network + * + * @note This structure shall be used to set the current global settings of a device + * with GPS command ::GPS_UCAP_NET_GLB_INFO. + */ +typedef struct +{ + uint32_t num_recvs; ///< Number of configured network receivers, see ::MBG_UCAP_NET_RECV_INFO_IDX + uint32_t reserved_0; ///< Reserved, currently always 0 + uint32_t reserved_1; ///< Reserved, currently always 0 + uint32_t reserved_2; ///< Reserved, currently always 0 + +} MBG_UCAP_NET_GLB_SETTINGS; + + +#define _mbg_swab_ucap_net_glb_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->num_recvs ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +/** + * @brief Global settings, features and flags for user captures via network + * + * @note This structure shall be used to read the current global settings from a device + * with GPS command ::GPS_UCAP_NET_GLB_INFO. + */ +typedef struct +{ + MBG_UCAP_NET_GLB_SETTINGS settings; ///< see ::MBG_UCAP_NET_GLB_SETTINGS + + uint32_t n_supp_recvs; ///< Number of supported network receivers, see ::MBG_UCAP_NET_RECV_INFO_IDX + uint32_t supp_modes; ///< Supported transfer modes, see ::MBG_UCAP_NET_TRANSF_MODE_MASKS + uint32_t supp_protos; ///< Supported transfer protocols, see ::MBG_UCAP_NET_TRANSF_PROTO_MASKS + uint32_t reserved_0; ///< Reserved, currently always 0 + uint32_t reserved_1; ///< Reserved, currently always 0 + uint32_t supp_flags; ///< Supported flags, see ::MBG_UCAP_NET_SUPP_FLAG_MASKS + +} MBG_UCAP_NET_GLB_INFO; + + +#define _mbg_swab_ucap_net_glb_info( _p ) \ +do \ +{ \ + _mbg_swab_ucap_net_glb_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->n_supp_recvs ); \ + _mbg_swab32( &(_p)->supp_modes ); \ + _mbg_swab32( &(_p)->supp_protos ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + + +/** + * @brief Settings for receivers of user captures via network + */ +typedef struct +{ + uint8_t mode; ///< Transfer mode, see ::MBG_UCAP_NET_TRANSF_MODE + uint8_t proto; ///< Transfer protocol, see ::MBG_UCAP_NET_TRANSF_PROTO + uint16_t reserved_1; ///< Reserved, currently always 0 + + uint32_t reserved_2; ///< Reserved, currently always 0 + uint32_t reserved_3; ///< Reserved, currently always 0 + uint32_t ucaps; ///< Bit mask for active user captures + + MBG_IP_ADDR_PORT addr; ///< Destination IP and port address of the network receiver, see ::MBG_IP_ADDR_PORT + +} MBG_UCAP_NET_RECV_SETTINGS; + + +#define _mbg_swab_ucap_net_recv_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->ucaps ); \ + _mbg_swab_ip_addr_port( &(_p)->addr ); \ +} while ( 0 ) + + + +/** + * @brief Settings for receivers of user captures via network + * + * @note This structure shall be used to write the settings to the device + * with GPS command ::GPS_UCAP_NET_RECV_INFO_IDX. + * This can be done for index 0 to ::MBG_UCAP_NET_GLB_SETTINGS::num_recvs-1. + * + * @see ::MBG_UCAP_NET_RECV_SETTINGS + */ +typedef struct +{ + uint16_t idx; ///< 0..::MBG_UCAP_NET_GLB_SETTINGS::num_recvs-1 + MBG_UCAP_NET_RECV_SETTINGS settings; ///< see ::MBG_UCAP_NET_RECV_SETTINGS + +} MBG_UCAP_NET_RECV_SETTINGS_IDX; + + +#define _mbg_swab_ucap_net_recv_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ucap_net_recv_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Settings, features and flags for receivers of user captures via network + */ +typedef struct +{ + MBG_UCAP_NET_RECV_SETTINGS settings; ///< see ::MBG_UCAP_NET_RECV_SETTINGS + + uint32_t reserved_0; ///< Reserved, currently always 0 + uint32_t reserved_1; ///< Reserved, currently always 0 + uint32_t reserved_2; ///< Reserved, currently always 0 + uint32_t reserved_3; ///< Reserved, currently always 0 + +} MBG_UCAP_NET_RECV_INFO; + + +#define _mbg_swab_ucap_net_recv_info( _p ) \ +do \ +{ \ + _mbg_swab_ucap_net_recv_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief Settings, features and flags for receivers of user captures via network + * + * @note This structure shall be used to read the current settings from the device + * with GPS command ::GPS_UCAP_NET_RECV_INFO_IDX. + * This can be done for index 0 to ::MBG_UCAP_NET_GLB_SETTINGS::num_recvs-1. + * + * @see ::MBG_UCAP_NET_RECV_INFO + */ +typedef struct +{ + uint16_t idx; ///< 0..::MBG_UCAP_NET_GLB_INFO::n_supp_recvs-1 + MBG_UCAP_NET_RECV_INFO info; ///< see ::MBG_UCAP_NET_RECV_INFO + +} MBG_UCAP_NET_RECV_INFO_IDX; + + +#define _mbg_swab_ucap_net_recv_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ucap_net_recv_info( &(_p)->info ); \ +} while ( 0 ) + +/** @} defgroup ext_ucap */ + + + /** * @defgroup group_ptp Definitions used with PTP/IEEE1588 * @@ -9069,6 +13214,9 @@ enum PTP_ROLES PTP_ROLE_BOTH_MASTER, ///< simultanous multicast and unicast master PTP_ROLE_NTP_SERVER, ///< NTP Unicast Server PTP_ROLE_NTP_CLIENT, ///< NTP Unicast Client + PTP_ROLE_TIME_MONITOR, ///< Time Monitor for external PTP or NTP devices + PTP_ROLE_V1_MASTER, ///< PTPv1 Master in Multicast mode + PTP_ROLE_V1_SLAVE, ///< PTPv1 Slave in Multicast mode N_PTP_ROLES ///< number of defined roles }; @@ -9096,7 +13244,10 @@ enum PTP_ROLE_MASKS PTP_ROLE_MSK_MULTICAST_AUTO = ( 1UL << PTP_ROLE_MULTICAST_AUTO ), ///< see ::PTP_ROLE_MULTICAST_AUTO PTP_ROLE_MSK_BOTH_MASTER = ( 1UL << PTP_ROLE_BOTH_MASTER ), ///< see ::PTP_ROLE_BOTH_MASTER PTP_ROLE_MSK_NTP_SERVER = ( 1UL << PTP_ROLE_NTP_SERVER ), ///< see ::PTP_ROLE_NTP_SERVER - PTP_ROLE_MSK_NTP_CLIENT = ( 1UL << PTP_ROLE_NTP_CLIENT ) ///< see ::PTP_ROLE_NTP_CLIENT + PTP_ROLE_MSK_NTP_CLIENT = ( 1UL << PTP_ROLE_NTP_CLIENT ), ///< see ::PTP_ROLE_NTP_CLIENT + PTP_ROLE_MSK_TIME_MONITOR = ( 1UL << PTP_ROLE_TIME_MONITOR ), ///< see ::PTP_ROLE_TIME_MONITOR + PTP_ROLE_MSK_V1_MASTER = ( 1UL << PTP_ROLE_V1_MASTER ), ///< see ::PTP_ROLE_MULTICAST_MASTER + PTP_ROLE_MSK_V1_SLAVE = ( 1UL << PTP_ROLE_V1_SLAVE ) ///< see ::PTP_ROLE_UNICAST_SLAVE }; @@ -9125,7 +13276,10 @@ enum PTP_ROLE_MASKS "Multicast (Auto)", \ "UC+MC Master", \ "NTP Server", \ - "NTP Client" \ + "NTP Client", \ + "Time Monitor", \ + "V1 Master", \ + "V1 Slave" \ } @@ -9144,7 +13298,10 @@ enum PTP_ROLE_MASKS "MCA", \ "UMM", \ "NSV", \ - "NCL" \ + "NCL", \ + "MON", \ + "V1M", \ + "V1S" \ } @@ -9176,6 +13333,70 @@ typedef uint16_t PTP_PORT_ID; /** + * @brief A PTP port identity + * + * @note For further information, see IEEE 1588-2008, chapter 5.3.5 + * + * @see ::PTP_CLOCK_ID + * @see ::PTP_PORT_ID + */ +typedef struct +{ + PTP_CLOCK_ID clock_identity; + PTP_PORT_ID port_number; + +} PTP_PORT_IDENTITY; + + +#define _mbg_swab_ptp_port_identity( _p ) \ +{ \ + _mbg_swab_ptp_clock_id( &(_p)->clock_identity ); \ + _mbg_swab_ptp_port_id( &(_p)->port_number ); \ +} + + +/** + * @brief PTP clock quality + * + * @note For further information, see IEEE 1588-2008, chapter 5.3.7 + */ +typedef struct +{ + uint8_t clock_class; ///< PTP clock class representing the current sync status + int8_t clock_accuracy; ///< see ::PTP_CLOCK_ACCURACIES + uint16_t log_variance; ///< PTP offset scaled log variance representing the time stability + +} PTP_CLOCK_QUALITY; + + +#define _mbg_swab_ptp_clock_quality( _p ) \ +{ \ + _mbg_swab8( &(_p)->clock_class ); \ + _mbg_swab8( &(_p)->clock_accuracy ); \ + _mbg_swab16( &(_p)->log_variance ); \ +} + + +/** + * @brief PTP time interval + * + * @note For further information, see IEEE 1588-2008, chapter 5.3.2 + * + */ +typedef struct +{ + int64_t scaled_nanoseconds; + +} PTP_TIME_INTERVAL; + + +#define _mbg_swab_ptp_time_interval( _p ) \ +{ \ + _mbg_swab64( &(_p)->scaled_nanoseconds ); \ +} + + +/** * @brief An enumeration of time scales used with PTP * * @note The standard time scale used by PTP is TAI, which is a linear time scale. @@ -9253,7 +13474,7 @@ typedef struct uint8_t clock_class; uint8_t clock_accuracy; ///< see ::PTP_CLOCK_ACCURACIES - uint32_t reserved_1; ///< reserved, currently always 0 + uint32_t tsu_secs; ///< current seconds value of time stamp unit uint32_t reserved_2; ///< reserved, currently always 0 uint8_t domain_number; ///< the PTP clock domain number, 0:3 @@ -9272,6 +13493,7 @@ typedef struct } PTP_STATE; #define _mbg_swab_ptp_state( _p ) \ +do \ { \ _mbg_swab16( &(_p)->nw_prot ); \ _mbg_swab32( &(_p)->flags ); \ @@ -9281,12 +13503,12 @@ typedef struct _mbg_swab_nano_time( &(_p)->delay_asymmetry ); \ _mbg_swab_ptp_clock_id( &(_p)->gm_id ); \ _mbg_swab16( &(_p)->clock_offset_scaled_log_variance ); \ - _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->tsu_secs ); \ _mbg_swab32( &(_p)->reserved_2 ); \ _mbg_swab16( &(_p)->utc_offset ); \ _mbg_swab_dac_val( &(_p)->osc_dac_cal ); \ _mbg_swab16( &(_p)->reserved_3 ); \ -} +} while ( 0 ) /** @@ -9360,17 +13582,18 @@ typedef struct } PTP_CFG_SETTINGS; -#define _mbg_swab_ptp_cfg_settings( _p ) \ -{ \ - _mbg_swab16( &(_p)->nw_prot ); \ - _mbg_swab16( &(_p)->sync_intv ); \ - _mbg_swab16( &(_p)->ann_intv ); \ - _mbg_swab16( &(_p)->delay_req_intv ); \ - _mbg_swab32( &(_p)->upper_bound ); \ - _mbg_swab32( &(_p)->lower_bound ); \ - _mbg_swab32( &(_p)->reserved ); \ - _mbg_swab32( &(_p)->flags ); \ -} +#define _mbg_swab_ptp_cfg_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->nw_prot ); \ + _mbg_swab16( &(_p)->sync_intv ); \ + _mbg_swab16( &(_p)->ann_intv ); \ + _mbg_swab16( &(_p)->delay_req_intv ); \ + _mbg_swab32( &(_p)->upper_bound ); \ + _mbg_swab32( &(_p)->lower_bound ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) @@ -9380,7 +13603,7 @@ typedef struct enum PTP_ANN_RCPT_TIMEOUT_LIMITS { PTP_ANN_RCPT_TIMEOUT_MIN = 2, - PTP_ANN_RCPT_TIMEOUT_MAX = 255, + PTP_ANN_RCPT_TIMEOUT_MAX = 8, DEFAULT_PTP_ANN_RCPT_TIMEOUT = 3 }; @@ -9412,6 +13635,7 @@ typedef struct } PTP_CFG_INFO; #define _mbg_swab_ptp_cfg_info( _p ) \ +do \ { \ _mbg_swab_ptp_cfg_settings( &(_p)->settings ); \ _mbg_swab16( &(_p)->reserved_2 ); \ @@ -9425,7 +13649,7 @@ typedef struct _mbg_swab32( &(_p)->supp_nw_prot ); \ _mbg_swab32( &(_p)->supp_opt_ext ); \ _mbg_swab32( &(_p)->supp_delay_mech ); \ -} +} while ( 0 ) @@ -9477,14 +13701,23 @@ enum PTP_CFG_FLAGS PTP_CFG_SYNCE_MASTER, ///< [R/-] Hardware supports Synchronous Ethernet Out PTP_CFG_SYNCE_SLAVE, ///< [R/-] Hardware supports Synchronous Ethernet In PTP_CFG_HAS_MUX, ///< [R/-] Hardware supports multiplexed signal outputs + PTP_CFG_CAN_BE_TIME_MONITOR, ///< [R/-] can be Monitoring device for external PTP or NTP devices //### TODO Shouldn't this be an XFEATURE flag? + PTP_CFG_HAS_STATISTICS, ///< [R/-] ::MBG_PTP_STATISTICS_INFO can be queried + + PTP_CFG_CAN_BE_V1_MASTER, ///< [R/-] supports PTPv1 MASTER role + PTP_CFG_CAN_BE_V1_SLAVE, ///< [R/-] supports PTPv1 SLAVE role + PTP_CFG_HAS_V2_COMMON_DATASETS, ///< [R/-] PTPv2 common dataset structures (see IEEE1588-2008, chapter 8.2) can be queried + PTP_CFG_HAS_V1_COMMON_DATASETS, ///< [R/-] PTPv1 common dataset structures can be queried N_PTP_CFG_FLAGS ///< the number of defined flags }; /** - * @defgroup group_PTP_CFG_FLAG_MASKS Bit masks used with ::PTP_CFG_INFO::supp_flags and ::PTP_CFG_SETTINGS::flags + * @defgroup group_PTP_CFG_FLAG_MASKS Bit masks used with PTP_CFG_INFO::supp_flags and PTP_CFG_SETTINGS::flags * + * @see ::PTP_CFG_INFO::supp_flags + * @see ::PTP_CFG_SETTINGS::flags * @see ::PTP_CFG_FLAGS * * @anchor PTP_CFG_FLAG_MASKS @@ -9515,6 +13748,13 @@ enum PTP_CFG_FLAGS #define PTP_CFG_MSK_SYNCE_MASTER ( 1UL << PTP_CFG_SYNCE_MASTER ) ///< see ::PTP_CFG_SYNCE_MASTER #define PTP_CFG_MSK_SYNCE_SLAVE ( 1UL << PTP_CFG_SYNCE_SLAVE ) ///< see ::PTP_CFG_SYNCE_SLAVE #define PTP_CFG_MSK_HAS_MUX ( 1UL << PTP_CFG_HAS_MUX ) ///< see ::PTP_CFG_HAS_MUX +#define PTP_CFG_MSK_CAN_BE_TIME_MONITOR ( 1UL << PTP_CFG_CAN_BE_TIME_MONITOR ) ///< see ::PTP_CFG_CAN_BE_TIME_MONITOR +#define PTP_CFG_MSK_HAS_STATISTICS ( 1UL << PTP_CFG_HAS_STATISTICS ) ///< see ::PTP_CFG_HAS_STATISTICS + +#define PTP_CFG_MSK_CAN_BE_V1_MASTER ( 1UL << PTP_CFG_CAN_BE_V1_MASTER ) ///< see ::PTP_CFG_CAN_BE_V1_MASTER +#define PTP_CFG_MSK_CAN_BE_V1_SLAVE ( 1UL << PTP_CFG_CAN_BE_V1_SLAVE ) ///< see ::PTP_CFG_CAN_BE_V1_SLAVE +#define PTP_CFG_MSK_HAS_V2_COMMON_DATASETS ( 1UL << PTP_CFG_HAS_V2_COMMON_DATASETS ) ///< see ::PTP_CFG_HAS_V2_COMMON_DATASETS +#define PTP_CFG_MSK_HAS_V1_COMMON_DATASETS ( 1UL << PTP_CFG_HAS_V1_COMMON_DATASETS ) ///< see ::PTP_CFG_HAS_V1_COMMON_DATASETS /** @} defgroup group_PTP_CFG_FLAG_MASKS */ @@ -9564,10 +13804,13 @@ enum PTP_HW_FEAT_MASKS enum PTP_OPT_EXTS { PTP_OPT_EXT_NONE, ///< no extension used - PTP_OPT_EXT_POWER, ///< IEEE C37.238 profile extension + PTP_OPT_EXT_POWER, ///< IEEE C37.238-2011 profile extension PTP_OPT_EXT_TELECOM, ///< ITU-T G.8265.1 profile extension PTP_OPT_EXT_TELECOM_PHASE, ///< ITU-T G.8275.1 profile extension PTP_OPT_EXT_SMPTE, ///< SMPTE ST 2059-2 profile extension + PTP_OPT_EXT_8021AS, ///< IEEE 802.1AS profile extension + PTP_OPT_EXT_6185093, ///< IEC/IEEE FDIS 61850-9-3 Power Utility profile extension + PTP_OPT_EXT_TELECOM_PTS, ///< ITU-T G.8275.2 profile extension N_PTP_OPT_EXT ///< number of known optional extensions }; @@ -9583,7 +13826,10 @@ enum PTP_OPT_EXT_MASKS PTP_MSK_OPT_EXT_POWER = ( 1UL << PTP_OPT_EXT_POWER ), ///< see ::PTP_OPT_EXT_POWER PTP_MSK_OPT_EXT_TELECOM = ( 1UL << PTP_OPT_EXT_TELECOM ), ///< see ::PTP_OPT_EXT_TELECOM PTP_MSK_OPT_EXT_TELECOM_PHASE = ( 1UL << PTP_OPT_EXT_TELECOM_PHASE ), ///< see ::PTP_OPT_EXT_TELECOM_PHASE - PTP_MSK_OPT_EXT_SMPTE = ( 1UL << PTP_OPT_EXT_SMPTE ) ///< see ::PTP_OPT_EXT_SMPTE + PTP_MSK_OPT_EXT_SMPTE = ( 1UL << PTP_OPT_EXT_SMPTE ), ///< see ::PTP_OPT_EXT_SMPTE + PTP_MSK_OPT_EXT_8021AS = ( 1UL << PTP_OPT_EXT_8021AS ), ///< see ::PTP_OPT_EXT_8021AS + PTP_MSK_OPT_EXT_6185093 = ( 1UL << PTP_OPT_EXT_6185093 ), ///< see ::PTP_OPT_EXT_6185093 + PTP_MSK_OPT_EXT_TELECOM_PTS = ( 1UL << PTP_OPT_EXT_TELECOM_PTS ) ///< see ::PTP_OPT_EXT_TELECOM_PTS }; @@ -9606,6 +13852,11 @@ enum PTP_PRESETS PTP_PRESETS_TELECOM, ///< ITU-T G.8265.1 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM is set PTP_PRESETS_TELECOM_PHASE, ///< ITU-T G.8275.1 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM_PHASE is set PTP_PRESETS_SMPTE, ///< SMPTE ST 2059-2 profile extension, only if ::PTP_MSK_OPT_EXT_SMPTE is set + PTP_PRESETS_AES67, ///< AES67 media profile + PTP_PRESETS_8021AS, ///< IEEE 802.1AS -like profile, only if ::PTP_MSK_OPT_EXT_8021AS is set + PTP_PRESETS_6185093, ///< IEC/IEEE FDIS 61850-9-3, only if ::PTP_MSK_OPT_EXT_6185093 is set + PTP_PRESETS_TELECOM_PTS, ///< ITU-T G.8275.2 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM_PTS is set + PTP_PRESETS_DOCSIS_31, ///< only if ::PTP_MSK_OPT_EXT_TELECOM_PHASE is set N_PTP_PRESETS ///< number of supported presets }; @@ -9623,7 +13874,12 @@ enum PTP_PRESETS_MASKS PTP_MSK_PRESETS_POWER = ( 1UL << PTP_PRESETS_POWER ), ///< see ::PTP_PRESETS_POWER PTP_MSK_PRESETS_TELECOM = ( 1UL << PTP_PRESETS_TELECOM ), ///< see ::PTP_PRESETS_TELECOM PTP_MSK_PRESETS_TELECOM_PHASE = ( 1UL << PTP_PRESETS_TELECOM_PHASE ), ///< see ::PTP_PRESETS_TELECOM_PHASE - PTP_MSK_PRESETS_SMPTE = ( 1UL << PTP_PRESETS_SMPTE ) ///< see ::PTP_PRESETS_SMPTE + PTP_MSK_PRESETS_SMPTE = ( 1UL << PTP_PRESETS_SMPTE ), ///< see ::PTP_PRESETS_SMPTE + PTP_MSK_PRESETS_AES67 = ( 1UL << PTP_PRESETS_AES67 ), ///< see ::PTP_PRESETS_AES67 + PTP_MSK_PRESETS_8021AS = ( 1UL << PTP_PRESETS_8021AS ), ///< see ::PTP_PRESETS_8021AS + PTP_MSK_PRESETS_6185093 = ( 1UL << PTP_PRESETS_6185093), ///< see ::PTP_PRESETS_6185093 + PTP_MSK_PRESETS_TELECOM_PTS = ( 1UL << PTP_PRESETS_TELECOM_PTS), ///< see ::PTP_PRESETS_TELECOM_PTS + PTP_MSK_PRESETS_DOCSIS_31 = ( 1UL << PTP_PRESETS_DOCSIS_31) ///< see ::PTP_PRESETS_DOCSIS_31 }; @@ -9640,7 +13896,12 @@ enum PTP_PRESETS_MASKS "Power IEEE C37.238", \ "Telecom ITU-T G.8265.1", \ "Telecom ITU-T G.8275.1", \ - "SMPTE ST 2059-2" \ + "SMPTE ST 2059-2", \ + "AES67 Media Profile", \ + "IEEE 802.1AS", \ + "Utility IEC 61850-9-3", \ + "Telecom ITU-T G.8275.2", \ + "DOCSIS 3.1" \ } @@ -9662,6 +13923,7 @@ typedef struct } PTP_POWER_PROFILE_CFG; #define _mbg_swab_ptp_power_profile_cfg( _p ) \ +do \ { \ _mbg_swab32( &(_p)->network_incaccuracy ); \ _mbg_swab8( &(_p)->grandmaster_id ); \ @@ -9669,20 +13931,18 @@ typedef struct _mbg_swab16( &(_p)->reserved_2 ); \ _mbg_swab_tzdl( &(_p)->tzdl ); \ _mbg_swab32( &(_p)->flags ); \ -} - +} while ( 0 ) -#if 1 // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +#if defined( _PRELIMINARY_CODE ) // TODO: These definitions are preliminary and maybe subject to changes. - /** * @brief SMPTE System Frame Rates according to SMPTE ST 2059-2 * - * @see ::XXX + * @see ::TODO */ enum SMPTE_SYSTEM_FRAME_RATES { @@ -9743,68 +14003,78 @@ typedef struct /// The data type shall be composed of a pair of unsigned Int32 values coded /// in big-endian form where the first shall be the numerator and the second /// shall be the denominator. The denominator shall be the smallest value - /// that represents the frame rate denominator. + /// that represents the frame rate denominator /// For example, 29.97 Hz: (30000/1001) or 25 Hz: (25/1). uint32_t defaultSystemFrameRateNum; uint32_t defaultSystemFrameRateDenum; - /// Master locking status /// Complementary information to clockClass (0: Not in use, 1: Free Run, /// 2: Cold Locking, 3: Warm Locking, 4: Locked) uint8_t masterLockingStatus; - /// Time Address Flags /// Indicates the intended ST 12-1 flags. /// Bit 0: Drop frame (0: Non-drop-frame, 1: Drop-frame) /// Bit 1: Color Frame Identification (0: Not in use, 1: In use) /// Bits 2-7: Reserved uint8_t timeAddressFlags; - /// Current local offset - /// Offset in seconds of Local Time from PTP time. For example, if Local - /// Time is Eastern Standard Time (North America) UTC-5 and the number of - /// leap seconds is 35, the value will be -18035 (decimal). - int32_t currentLocalOffset; + /// Offset in seconds of Local Time from grandmaster PTP time. For example, + /// if Local Time is Eastern Standard Time (North America) UTC-5 and the + /// number of leap seconds is 35, the value will be -18035 (decimal). + + uint8_t reserved_1; + uint8_t reserved_2; + int32_t currentLocalOffset; /// Jump seconds /// The size of the next discontinuity, in seconds, of Local Time. A value /// of zero indicates that no discontinuity is expected. A positive value /// indicates that the discontinuity will cause the currentLocalOffset to increase. int32_t jumpSeconds; - /// Time of next jump - /// The value of the seconds portion of the master PTP time at the time + /// The value of the seconds portion of the grandmastermaster PTP time at the time /// that the next discontinuity of the currentLocalOffset will occur. The /// discontinuity occurs at the start of the second indicated uint8_t timeOfNextJump[6]; - - /// Daily jam - /// Daily point in Local Time (in ten-minute intervals since midnight) for - /// jamming ST 12-1 time address to Local Time. 255: Daily jam not in use - /// 1-143: Daily Jam Time offset since midnight in number of ten-minute - /// intervals since midnight. A value 0 indicated midnight; 143 indicates - /// ten minutes to next midnight. 144 and 254: Reserved - uint8_t dailyJamTime; - - /// Previous daily jam - /// Point in Local Time (in ten-minute intervals since midnight) of previous - /// jam of ST 12-1 time address to Local Time. This item shall be updated in - /// the message immediately following a jam event. Value definition as daily - /// Jam Time - uint8_t previousDailyJamTime; - + /// Time of next jam + /// The value of the seconds portion of the PTP time corresponding to the next + /// scheduled occurrence of the Daily Jam. If no Daily Jam is scheduled, the + /// value of timeOfNextJam shall be zero. + uint8_t timeOfNextJam[6]; + /// Time of previous jam + /// The value of the seconds portion of the PTP time corresponding to the + /// previous occurrence of the Daily Jam. + uint8_t timeOfPreviousJam[6]; /// Previous jam local offset /// The value of currentLocalOffset at the previous daily jam time. /// If a discontinuity of Local Time occurs at the jam time, this parameter - /// reflects the offset after the discontinuity - int32_t previousJamLocalOffset; + /// reflects the offset after the discontinuity. + uint8_t reserved_3; + uint8_t reserved_4; + uint32_t reserved_5; + int32_t previousJamLocalOffset; /// Daylight saving /// Bit 0: Current Daylight Saving (0: Not in effect, 1: In effect) /// Bit 1: Daylight Saving at next discontinuity (0: Not in effect, 1: In effect) /// Bit 2: Daylight Saving at previous daily jam time (0: Not in effect, 1: In effect) /// Bits 3-7: Reserved uint8_t daylightSaving; + /// Leap second jump + /// The reason for the forthcoming discontinuity of currentLocalOffset indicated by + /// timeOfNextJump + /// Bit 0: + /// 0: Other than a change in the number of leap seconds (default) + /// 1: A change in number of leap seconds + /// Bits 1-7: Reserved + uint8_t leapSecondJump; + + uint8_t reserved_6; + uint8_t reserved_7; + + uint32_t reserved_8; + uint32_t reserved_9; + uint32_t reserved_10; } PTP_SMPTE_PROFILE_CFG; @@ -9816,13 +14086,22 @@ typedef struct typedef struct { uint8_t use_alternate_multicast_address; + uint8_t reserved_1; + uint8_t reserved_2; + uint8_t reserved_3; + uint32_t reserved_4; } PTP_TELECOMG8275_PROFILE_CFG; -#define _mbg_swab_ptp_telecom8275_profile_cfg( _p ) \ -{ \ - _mbg_swab8( &(_p)->use_alternate_multicast_mac_address ); \ -} +#define _mbg_swab_ptp_telecom8275_profile_cfg( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->use_alternate_multicast_mac_address ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab8( &(_p)->reserved_2 ); \ + _mbg_swab8( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ +} while ( 0 ) @@ -9946,12 +14225,87 @@ enum ITU_SSM_CODES } + +/** + * @brief Maximum T1 SSM only quality levels + * + * @see ::T1_SSM_QLVL + * @see ::T1_SSM_QLVL_STRS + * @see ::T1_SSM_QLVL_ARRAY + */ +#define MAX_T1_SSM_QLVL 8 + + + +/** + * @brief T1 SSM only quality level (6 bit encoded) + * + * @see ::MAX_T1_SSM_QLVL + * @see ::T1_SSM_QLVL_STRS + * @see ::T1_SSM_QLVL_ARRAY + */ +enum T1_SSM_QLVL +{ + T1_SSM_QLVL_ST1_TRACE = 2, + T1_SSM_QLVL_SYNC_TRACE_UNKNOWN = 4, + T1_SSM_QLVL_ST2_TRACE = 6, + T1_SSM_QLVL_ST3_TRACE = 8, + T1_SSM_QLVL_SONET_MIN_CLOCK_TRACE = 17, + T1_SSM_QLVL_ST4_TRACE = 20, + T1_SSM_QLVL_DNU_FOR_SYNC = 24, + T1_SSM_QLVL_RESERVED = 32 +}; + + + +/** + * @brief T1 SSM only quality level array + * + * @see ::MAX_T1_SSM_QLVL + * @see ::T1_SSM_QLVL_STRS + * @see ::T1_SSM_QLVL + */ +#define T1_SSM_QLVL_ARRAY \ +{ \ + T1_SSM_QLVL_ST1_TRACE, \ + T1_SSM_QLVL_SYNC_TRACE_UNKNOWN, \ + T1_SSM_QLVL_ST2_TRACE, \ + T1_SSM_QLVL_ST3_TRACE, \ + T1_SSM_QLVL_SONET_MIN_CLOCK_TRACE, \ + T1_SSM_QLVL_ST4_TRACE, \ + T1_SSM_QLVL_DNU_FOR_SYNC, \ + T1_SSM_QLVL_RESERVED \ +} + + + +/** + * @brief Name strings for T1 SSM quality levels + * + * @see ::MAX_T1_SSM_QLVL + * @see ::T1_SSM_QLVL + * @see ::T1_SSM_QLVL_ARRAY + */ +#define T1_SSM_QLVL_STRS \ +{ \ + "Stratum 1 traceable", \ + "Synchronized traceability unknown", \ + "Stratum 2 traceable", \ + "Stratum 3 traceable", \ + "SONET minimum clock traceable", \ + "Stratum 4 traceable", \ + "Do not use for sync", \ + "Reserved for network sync" \ +} + + + /** * @brief SDH network options * * @see ::SDH_NETWORK_OPTION_MASKS */ -enum SDH_NETWORK_OPTION +enum SDH_NETWORK_OPTIONS { SDH_NETWORK_OPTION_1, SDH_NETWORK_OPTION_2, @@ -9964,12 +14318,12 @@ enum SDH_NETWORK_OPTION /** * @brief Flag masks used with ::MBG_SYNC_E_INFO::supp_sdh_network_opts * - * @see ::SDH_NETWORK_OPTION + * @see ::SDH_NETWORK_OPTIONS */ enum SDH_NETWORK_OPTION_MASKS { - SDH_NETWORK_OPTION_1_MSK = ( 1UL << SDH_NETWORK_OPTION_1 ), ///< see ::SDH_NETWORK_OPTION_1_MSK - SDH_NETWORK_OPTION_2_MSK = ( 1UL << SDH_NETWORK_OPTION_2 ), ///< see ::SDH_NETWORK_OPTION_2_MSK + SDH_NETWORK_OPTION_1_MSK = ( 1UL << SDH_NETWORK_OPTION_1 ), ///< see ::SDH_NETWORK_OPTION_1 + SDH_NETWORK_OPTION_2_MSK = ( 1UL << SDH_NETWORK_OPTION_2 ), ///< see ::SDH_NETWORK_OPTION_2 }; @@ -9993,7 +14347,7 @@ enum SDH_NETWORK_OPTION_MASKS * * @see ::GBIT_LINK_COPPER_MODE_MASKS */ -enum GBIT_LINK_COPPER_MODE +enum GBIT_LINK_COPPER_MODES { GBIT_LINK_COPPER_AUTO, // valid if synce is disabled GBIT_LINK_COPPER_FORCE_SYNCE_AUTO, @@ -10009,7 +14363,7 @@ enum GBIT_LINK_COPPER_MODE /** * @brief Flag masks used with ::MBG_SYNC_E_INFO::supp_gbit_link_copper_modes * - * @see ::GBIT_LINK_COPPER_MODE + * @see ::GBIT_LINK_COPPER_MODES */ enum GBIT_LINK_COPPER_MODE_MASKS { @@ -10027,7 +14381,7 @@ enum GBIT_LINK_COPPER_MODE_MASKS /** * @brief Link status for SyncE on a 1000BASE-T interface * - * @see ::XXX + * @see ::TODO */ enum GBIT_LINK_STATUS { @@ -10051,80 +14405,13 @@ enum GBIT_LINK_STATUS "AUTO (SFP LINK UP)", \ } +#else // !defined( _PRELIMINARY_CODE ), dummy declarations -/** - * @brief Bits used to define ::MBG_SYNCE_FLAG_MASKS - */ -enum MBG_SYNCE_FLAGS -{ - SYNCE_FLAG_ACTIVE_SYNC_MASTER, - N_SYNCE_FLAGS // number of defined bits -}; - - - -/** - * @brief Flag masks used with ::MBG_SYNC_E_SETTINGS::flags - * - * @see ::MBG_SYNCE_FLAGS - */ -enum MBG_SYNCE_FLAG_MASKS -{ - SYNCE_FLAG_ACTIVE_SYNC_MASTER_MSK = ( 1UL << SYNCE_FLAG_ACTIVE_SYNC_MASTER ) ///< see ::SYNCE_FLAG_ACTIVE_SYNC_MASTER -}; - - - -/** - * @brief Settings for a Synchronous Ethernet interface - * - * @see ::XXX - */ -typedef struct -{ - uint8_t synce_enabled; ///< SyncE is activated for the specific interface - uint8_t ql_selection_enabled; ///< Quality Level is determined automatically - uint8_t sdh_network_option; ///< see ::SDH_NETWORK_OPTION - uint8_t local_priority; ///< user defined priority value for selected port - uint8_t local_network_sync_level_ssm; ///< automatically assigend quality level for SyncE output - uint8_t fixed_output_ssm; ///< Fixed SSM output override - uint8_t fixed_input_ssm; ///< Assumed SSM value for SyncE Input (0xFF if taken from network) - uint8_t gbit_link_copper_mode; ///< see ::GBIT_LINK_COPPER_MODE - uint8_t reserved_1; - uint8_t reserved_2; - uint32_t reserved_3; - uint32_t flags; ///< see ::MBG_SYNCE_FLAG_MASKS - -} MBG_SYNC_E_SETTINGS; - - - -typedef struct -{ - MBG_SYNC_E_SETTINGS settings; - uint32_t supp_sdh_network_opts; - uint32_t supp_gbit_link_copper_modes; - uint32_t supp_flags; - uint32_t reserved; - -} MBG_SYNC_E_INFO; - - - -typedef struct -{ - uint8_t synce_enabled; - uint8_t output_ssm; - uint8_t input_ssm; - uint8_t gbit_link_status; ///< see ::GBIT_LINK_STATUS - uint8_t reserved_1; - uint8_t reserved_2; - uint32_t reserved_3; - uint32_t flags; ///< MBG_SYNCE_FLAG_MASKS - -} MBG_SYNC_E_STATUS; +typedef int PTP_SMPTE_PROFILE_CFG; +typedef int PTP_TELECOMG8275_PROFILE_CFG; +typedef int ITU_SSM_CODE; -#endif // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +#endif // defined( _PRELIMINARY_CODE ) @@ -10147,6 +14434,7 @@ typedef struct } PTP_UC_MASTER_CFG_LIMITS; #define _mbg_swab_ptp_uc_master_cfg_limits( _p ) \ +do \ { \ _mbg_swab16( &(_p)->n_supp_master ); \ _mbg_swab16( &(_p)->sync_intv_min ); \ @@ -10158,7 +14446,8 @@ typedef struct _mbg_swab16( &(_p)->reserved_0 ); \ _mbg_swab32( &(_p)->supp_flags ); \ _mbg_swab32( &(_p)->reserved_1 ); \ -} +} while ( 0 ) + /** @@ -10189,6 +14478,7 @@ typedef struct } PTP_UC_MASTER_SETTINGS; #define _mbg_swab_ptp_uc_master_settings( _p ) \ +do \ { \ _mbg_swab_ptp_clock_id( &(_p)->gm_clock_id ); \ _mbg_swab_ptp_port_id( &(_p)->gm_port_id ); \ @@ -10200,7 +14490,8 @@ typedef struct _mbg_swab16( &(_p)->reserved_0 ); \ _mbg_swab32( &(_p)->reserved_1 ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) + /** @@ -10233,10 +14524,12 @@ typedef struct } PTP_UC_MASTER_SETTINGS_IDX; #define _mbg_swab_ptp_uc_master_settings_idx( _p ) \ +do \ { \ _mbg_swab32( &(_p)->idx ); \ _mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \ -} +} while ( 0 ) + /** @@ -10254,11 +14547,13 @@ typedef struct } PTP_UC_MASTER_INFO; #define _mbg_swab_ptp_uc_master_info( _p ) \ +do \ { \ _mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \ _mbg_swab32( &(_p)->reserved ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) + /** @@ -10282,11 +14577,700 @@ typedef struct } PTP_UC_MASTER_INFO_IDX; #define _mbg_swab_ptp_uc_master_info_idx( _p ) \ +do \ { \ _mbg_swab32( &(_p)->idx ); \ _mbg_swab_ptp_uc_master_info( &(_p)->info ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t counter_cfg; + uint32_t flags; + uint32_t reserved_1; + uint32_t reserved_2; + +} MBG_PTP_STATISTICS_SETTINGS; + + + +typedef struct +{ + MBG_PTP_STATISTICS_SETTINGS settings; + uint32_t supp_flags; ///< Supported settings, currently 0 + uint32_t reserved_1; + +} MBG_PTP_STATISTICS_INFO; + + + +typedef struct +{ + uint32_t status; ///< status word flags (use PacketCounterStat_e) + uint32_t rx; ///< overall Rx packet counter + uint32_t rxPerSec; ///< overall Rx packet counter + uint32_t tx; ///< overall Tx packet counter + uint32_t txPerSec; ///< overall Tx packet counter + /// invalid Rx packet counter + /// Indicates one of the following issues: wrong PTP version, wrong domain number, + /// message from self, message from other BC port, multicast message in unicast mode + /// or message extraction error (size error or inconsistent format). + uint32_t errorRx; + uint32_t announceMsgRx; ///< Accepted Announce message Rx counter + uint32_t announceMsgPerSecRx; ///< Accepted Announce message Rx counter + uint32_t announceMsgTx; ///< Announce message Tx counter + uint32_t announceMsgPerSecTx; ///< Announce message Tx counter + uint32_t syncMsgRx; ///< Accepted Sync message Rx counter + uint32_t syncMsgPerSecRx; ///< Accepted Sync message Rx counter + uint32_t syncMsgTx; ///< Sync message Tx counter + uint32_t syncMsgPerSecTx; ///< Sync message Tx counter + uint32_t followUpMsgRx; ///< Accepted Follow-up message Rx counter + uint32_t followUpMsgPerSecRx; ///< Accepted Follow-up message Rx counter + uint32_t followUpMsgTx; ///< Follow-up message Tx counter + uint32_t followUpMsgPerSecTx; ///< Follow-up message Tx counter + uint32_t dlyReqMsgRx; ///< Accepted Delay request message Rx counter + uint32_t dlyReqMsgPerSecRx; ///< Accepted Delay request message Rx counter + uint32_t dlyReqMsgTx; ///< Delay request message Tx counter + uint32_t dlyReqMsgPerSecTx; ///< Delay request message Tx counter + uint32_t dlyRespMsgRx; ///< Accepted Delay response message Rx counter + uint32_t dlyRespMsgPerSecRx; ///< Accepted Delay response message Rx counter + uint32_t dlyRespMsgTx; ///< Delay response message Tx counter + uint32_t dlyRespMsgPerSecTx; ///< Delay response message Tx counter + uint32_t pDlyReqMsgRx; ///< Accepted PDelay Request message Rx counter + uint32_t pDlyReqMsgPerSecRx; ///< Accepted PDelay Request message Rx counter + uint32_t pDlyReqMsgTx; ///< PDelay Request message Tx counter + uint32_t pDlyReqMsgPerSecTx; ///< PDelay Request message Tx counter + uint32_t pDlyRespMsgRx; ///< Accepted PDelay Response message Rx counter + uint32_t pDlyRespMsgPerSecRx; ///< Accepted PDelay Response message Rx counter + uint32_t pDlyRespMsgTx; ///< PDelay Response message Tx counter + uint32_t pDlyRespMsgPerSecTx; ///< PDelay Response message Tx counter + uint32_t pDlyFollowUpRx; ///< Accepted PDelay Follow-Up message Rx counter + uint32_t pDlyFollowUpPerSecRx; ///< Accepted PDelay Follow-Up message Rx counter + uint32_t pDlyFollowUpTx; ///< PDelay Follow-Up message Tx counter + uint32_t pDlyFollowUpPerSecTx; ///< PDelay Follow-Up message Tx counter + uint32_t signallingRx; ///< Accepted Signalling message Rx counter + uint32_t signallingPerSecRx; ///< Accepted Signalling message Rx counter + uint32_t signallingTx; ///< Signalling message Tx counter + uint32_t signallingPerSecTx; ///< Signalling message Tx counter + uint32_t mgmtRx; ///< Accepted Management message Rx counter + uint32_t mgmtPerSecRx; ///< Accepted Management message Rx counter + uint32_t mgmtTx; ///< Management message Tx counter + uint32_t mgmtPerSecTx; ///< Management message Tx counter + uint32_t mgmtErr; ///< Management error counter (rx) + uint32_t annReceptTout; ///< Announce recept timeout count + + uint32_t numUcConn; ///< Number of current Unicast client connections + uint32_t maxNumUcConn; ///< Maximum Number of Unicast client connections (due to licence or CPU performance) + uint32_t numMsgPerSec; ///< Number of all messages per second (TX/RX) + uint32_t maxMsgPerSec; ///< max allowed number of all messages per second in Multicast/Hybrid mode (due to licence or CPU performance) + +} MBG_PTP_STATISTICS_STATUS; + + + +enum PTP_V1_COMM_IDS +{ + V1_PTP_CLOSED, + V1_PTP_ETHER, + /* reserved */ + V1_PTP_FFBUS = 4, + V1_PTP_PROFIBUS, + V1_PTP_LON, + V1_PTP_DNET, + V1_PTP_SDS, + V1_PTP_CONTROLNET, + V1_PTP_CANOPEN, + /* reserved */ + V1_PTP_IEEE1394 = 243, + V1_PTP_IEEE802_11A, + V1_PTP_IEEE_WIRELESS, + V1_PTP_INFINIBAND, + V1_PTP_BLUETOOTH, + V1_PTP_IEEE802_15_1, + V1_PTP_IEEE1451_3, + V1_PTP_IEEE1451_5, + V1_PTP_USB, + V1_PTP_ISA, + V1_PTP_PCI, + V1_PTP_VXI, + V1_PTP_DEFAULT +}; + + + +#define PTP_CODE_STRING_LENGTH 4 +#define PTP_SUBDOMAIN_NAME_LENGTH 16 + + +/** + * @brief PTPv1 UUID structure used in ::MBG_PTP_V1_DEFAULT_DATASET + * + * @see ::MBG_PTP_V1_DEFAULT_DATASET + */ +typedef struct +{ + uint8_t communication_technology; + uint8_t reserved_1; + uint16_t reserved_2; + PTP_CLOCK_ID clock_uuid; + PTP_PORT_ID port_id; + uint16_t reserved_3; +} PTP_V1_UUID; + + +#define _mbg_swab_ptp_v1_uuid( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab_ptp_clock_id( &(_p)->clock_uuid ); \ + _mbg_swab_ptp_port_id( &(_p)->port_id ); \ + _mbg_swab16( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 default dataset flags + * + * @see ::PTP_V1_DEFAULT_DATASET_FLAGS_MASKS + */ +enum PTP_V1_DEFAULT_DATASET_FLAGS +{ + V1_DFLT_CLK_FOLLOWUP_CAPABLE, + V1_DFLT_PREFERRED, + V1_DFLT_INITIALIZABLE, + V1_DFLT_EXT_TIMING, + V1_DFLT_IS_BC +}; + + + +/** + * @brief PTPv1 default dataset flag masks used with ::MBG_PTP_V1_DEFAULT_DATASET::flags + * + * @see ::PTP_V1_DEFAULT_DATASET_FLAGS + */ +enum PTP_V1_DEFAULT_DATASET_FLAGS_MASKS +{ + V1_DFLT_MSK_CLK_FOLLOWUP_CAPABLE = ( 1UL << V1_DFLT_CLK_FOLLOWUP_CAPABLE ), ///< see ::V1_DFLT_CLK_FOLLOWUP_CAPABLE + V1_DFLT_MSK_PREFERRED = ( 1UL << V1_DFLT_PREFERRED ), ///< see ::V1_DFLT_PREFERRED + V1_DFLT_MSK_INITIALIZABLE = ( 1UL << V1_DFLT_INITIALIZABLE ), ///< see ::V1_DFLT_INITIALIZABLE + V1_DFLT_MSK_EXT_TIMING = ( 1UL << V1_DFLT_EXT_TIMING), ///< see ::V1_DFLT_EXT_TIMING + V1_DFLT_MSK_IS_BC = ( 1UL << V1_DFLT_IS_BC ) ///< see ::V1_DFLT_IS_BC +}; + + + +/** + * @brief PTPv1 default dataset containing global information about the device + * + * @see ::PTP_V1_UUID + */ +typedef struct { + PTP_V1_UUID uuid; + uint8_t clock_stratum; + uint8_t clock_identifier[PTP_CODE_STRING_LENGTH]; + uint16_t clock_variance; + int8_t sync_interval; + uint8_t subdomain_name[PTP_SUBDOMAIN_NAME_LENGTH]; + uint16_t number_ports; + uint16_t number_foreign_records; + uint32_t flags; +} MBG_PTP_V1_DEFAULT_DATASET; + + +#define _mbg_swab_ptp_v1_default_dataset( _p ) \ +do \ +{ \ + _mbg_swab_ptp_v1_uuid( &(_p)->uuid ); \ + _mbg_swab16( &(_p)->clock_variance ); \ + _mbg_swab16( &(_p)->number_ports ); \ + _mbg_swab16( &(_p)->number_foreign_records ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 current dataset containing information about the synchronization status of the device + * + * @see ::NANO_TIME + */ +typedef struct +{ + uint16_t steps_removed; + uint16_t reserved_1; + NANO_TIME offset_from_master; + NANO_TIME one_way_delay; +} MBG_PTP_V1_CURRENT_DATASET; + + +#define _mbg_swab_ptp_v1_current_dataset( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->steps_removed ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab_nano_time( &(_p)->offset_from_master ); \ + _mbg_swab_nano_time( &(_p)->one_way_delay ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 parent dataset flags + * + * @see ::PTP_V1_PARENT_DATASET_FLAGS_MASKS + */ +enum PTP_V1_PARENT_DATASET_FLAGS +{ + V1_PARENT_FOLLOWUP_CAPABLE, + V1_PARENT_EXT_TIMING, + V1_PARENT_STATS, + V1_PARENT_UTC_REASONABLE, + V1_PARENT_GM_PREFERRED, + V1_PARENT_GM_IS_BC +}; + + + +/** + * @brief PTPv1 parent dataset flag masks used with ::MBG_PTP_V1_PARENT_DATASET::flags + * + * @see ::PTP_V1_PARENT_DATASET_FLAGS + */ +enum PTP_V1_PARENT_DATASET_FLAGS_MASKS +{ + V1_PARENT_MSK_FOLLOWUP_CAPABLE = ( 1UL << V1_PARENT_FOLLOWUP_CAPABLE ), ///< see ::V1_PARENT_FOLLOWUP_CAPABLE + V1_PARENT_MSK_EXT_TIMING = ( 1UL << V1_PARENT_EXT_TIMING ), ///< see ::V1_PARENT_EXT_TIMING + V1_PARENT_MSK_STATS = ( 1UL << V1_PARENT_STATS ), ///< see ::V1_PARENT_STATS + V1_PARENT_MSK_UTC_REASONABLE = ( 1UL << V1_PARENT_UTC_REASONABLE ), ///< see ::V1_PARENT_UTC_REASONABLE + V1_PARENT_MSK_GM_PREFERRED = ( 1UL << V1_PARENT_GM_PREFERRED ), ///< see ::V1_PARENT_GM_PREFERRED + V1_PARENT_MSK_GM_IS_BC = ( 1UL << V1_PARENT_GM_IS_BC ) ///< see ::V1_PARENT_GM_IS_BC +}; + + + +/** + * @brief PTPv1 parent dataset containing information about the master (parent) of the device + * + * @see ::PTP_V1_UUID + */ +typedef struct +{ + PTP_V1_UUID uuid; + uint16_t parent_last_sync_sequence_number; + int16_t parent_variance; + int16_t observed_variance; + uint16_t reserved_1; + int32_t observed_drift; + PTP_V1_UUID grandmaster_uuid; + uint8_t grandmaster_stratum; + uint8_t grandmaster_identifier[PTP_CODE_STRING_LENGTH]; + int16_t grandmaster_variance; + uint16_t grandmaster_sequence_number; + uint16_t reserved_2; + uint32_t flags; +} MBG_PTP_V1_PARENT_DATASET; + + +#define _mbg_swab_ptp_v1_parent_dataset( _p ) \ +do \ +{ \ + _mbg_swab_ptp_v1_uuid( &(_p)->uuid ); \ + _mbg_swab16( &(_p)->parent_last_sync_sequence_number ); \ + _mbg_swab16( &(_p)->parent_variance ); \ + _mbg_swab16( &(_p)->observed_variance ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->observed_drift ); \ + _mbg_swab_ptp_v1_uuid( &(_p)->grandmaster_uuid ); \ + _mbg_swab16( &(_p)->grandmaster_variance ); \ + _mbg_swab16( &(_p)->grandmaster_sequence_number ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 time drop dataset flags + * + * @see ::PTP_V1_TIME_PROP_DATASET_FLAGS_MASKS + */ +enum PTP_V1_TIME_PROP_DATASET_DATASET_FLAGS +{ + V1_TPROP_LEAP_59, + V1_TPROP_LEAP_61, +}; + + + +/** + * @brief PTPv1 time drop dataset flag masks used with ::MBG_PTP_V1_TIME_PROP_DATASET::flags + * + * @see ::PTP_V1_TIME_PROP_DATASET_DATASET_FLAGS + */ +enum PTP_V1_TIME_PROP_DATASET_FLAGS_MASKS +{ + V1_TPROP_MSK_LEAP_59 = ( 1UL << V1_TPROP_LEAP_59 ), ///< see ::V1_TPROP_LEAP_59 + V1_TPROP_MSK_LEAP_61 = ( 1UL << V1_TPROP_LEAP_61 ), ///< see ::V1_TPROP_LEAP_61 +}; + + + +/** + * @brief PTPv1 time drop dataset + * + */ +typedef struct +{ + int16_t current_utc_offset; + uint16_t epoch_number; + uint32_t flags; +} MBG_PTP_V1_TIME_PROPERTIES_DATASET; + + +#define _mbg_swab_ptp_v1_time_properties_dataset( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->current_utc_offset ); \ + _mbg_swab16( &(_p)->epoch_number ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 port dataset flags + * + * @see ::PTP_V1_PORT_DATASET_FLAGS_MASKS + */ +enum PTP_V1_PORT_DATASET_DATASET_FLAGS +{ + V1_PORT_DATASET_BURST_ENB, +}; + + + +/** + * @brief PTPv1 port dataset flag masks used with ::MBG_PTP_V1_PORT_DATASET::flags + * + * @see ::PTP_V1_PORT_DATASET_DATASET_FLAGS + */ +enum PTP_V1_PORT_DATASET_FLAGS_MASKS +{ + V1_PORT_DATASET_MSK_BURST_ENB = ( 1UL << V1_PORT_DATASET_BURST_ENB ), ///< see ::V1_PORT_DATASET_BURST_ENB +}; + + + +/** + * @brief PTPv1 port dataset containing information about the appropriate port of the device + * + * @see ::PTP_V1_UUID + */ +typedef struct +{ + uint8_t port_state; + uint8_t reserved_1; + uint16_t last_sync_event_sequence_number; + uint16_t last_general_event_sequence_number; + uint16_t reserved_2; + uint32_t subdomain_address; + uint16_t event_port_address; + uint16_t general_port_address; + PTP_V1_UUID uuid; + uint32_t flags; +} MBG_PTP_V1_PORT_DATASET; + + +#define _mbg_swab_ptp_v1_port_dataset( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->last_sync_event_sequence_number ); \ + _mbg_swab16( &(_p)->last_general_event_sequence_number ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->subdomain_address ); \ + _mbg_swab16( &(_p)->event_port_address ); \ + _mbg_swab16( &(_p)->general_port_address ); \ + _mbg_swab_ptp_v1_uuid( &(_p)->uuid ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Index structure for PTPv1 port dataset + * + * @note Port dataset with index 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports - 1 can be queried from a device + * + * @see ::MBG_PTP_V1_PORT_DATASET + */ +typedef struct +{ + uint16_t idx; ///< Index of the port dataset, 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports - 1 + MBG_PTP_V1_PORT_DATASET port_dataset; ///< see ::MBG_PTP_V1_PORT_DATASET + +} MBG_PTP_V1_PORT_DATASET_IDX; + + +#define _mbg_swab_ptp_v1_port_dataset_idx( _p ) \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ptp_v1_port_dataset( &(_p)->port_dataset ); \ +} + + +/** + * @brief Flags structure for the PTPv2 default dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.1 and 15.5.3.3.1 + * + * @see ::MBG_PTP_V2_DEFAULT_DATASET + */ +typedef struct +{ + uint8_t two_step : 1; ///< indicates, whether the clock is a two-step clock + uint8_t slave_only : 1; ///< indicates, whether the clock is a slave-only clock + uint8_t reserved : 6; ///< reserved, currently always 0 + +} MBG_PTP_V2_DEFAULT_DATASET_FLAGS; + +#define _mbg_swab_ptp_v2_default_dataset_flags( _p ) \ + _nop_macro_fnc() + + +/** + * @brief PTPv2 default dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.1 and 15.5.3.3.1 + * + * @see ::MBG_PTP_V2_DEFAULT_DATASET_FLAGS + * @see ::PTP_CLOCK_QUALITY + * @see ::PTP_CLOCK_ID + */ +typedef struct +{ + MBG_PTP_V2_DEFAULT_DATASET_FLAGS flags; ///< flags field, see ::MBG_PTP_V2_DEFAULT_DATASET_FLAGS + uint8_t reserved_1; ///< reserved, currently always 0 + uint16_t number_ports; ///< number of PTP ports on the device + uint8_t priority_1; ///< priority 1 attribute for the local clock + PTP_CLOCK_QUALITY clock_quality; ///< quality of the local clock, see ::PTP_CLOCK_QUALITY + uint8_t priority_2; ///< priority 2 attribute for the local clock + PTP_CLOCK_ID clock_identity; ///< identity of the local clock, see ::PTP_CLOCK_ID + uint8_t domain_number; ///< domain attribute of the local clock + uint8_t reserved_2; ///< reserved, currently always 0 + +} MBG_PTP_V2_DEFAULT_DATASET; + + +#define _mbg_swab_ptp_v2_default_dataset( _p ) \ +{ \ + _mbg_swab_ptp_v2_default_dataset_flags( &(_p)->flags ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab16( &(_p)->number_ports ); \ + _mbg_swab8( &(_p)->priority_1 ); \ + _mbg_swab_ptp_clock_quality( &(_p)->clock_quality ); \ + _mbg_swab8( &(_p)->priority_2 ); \ + _mbg_swab_ptp_clock_id( &(_p)->clock_identity ); \ + _mbg_swab8( &(_p)->domain_number ); \ + _mbg_swab8( &(_p)->reserved_2 ); \ +} + + +/** + * @brief PTPv2 current dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.2 and 15.5.3.4.1 + * + * @see ::PTP_TIME_INTERVAL + */ +typedef struct +{ + uint16_t steps_removed; ///< number of communication paths between local clock and grandmaster + PTP_TIME_INTERVAL offset_from_master; ///< current time difference between master and slave, see ::PTP_TIME_INTERVAL + PTP_TIME_INTERVAL mean_path_delay; ///< current mean propagation time between master and slave, see ::PTP_TIME_INTERVAL + +} MBG_PTP_V2_CURRENT_DATASET; + + +#define _mbg_swab_ptp_v2_current_dataset( _p ) \ +{ \ + _mbg_swab16( &(_p)->steps_removed ); \ + _mbg_swab_ptp_time_interval( &(_p)->offset_from_master ); \ + _mbg_swab_ptp_time_interval( &(_p)->mean_path_delay ); \ +} + + +/** + * @brief Flags structure for the PTPv2 parent dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.3.3 and 15.5.3.5.1.2 + * + * @see ::MBG_PTP_V2_PARENT_DATASET + */ +typedef struct +{ + uint8_t parent_stats : 1; ///< indicates, whether the variance and change rate values are valid + uint8_t reserved : 7; ///< reserved, currently always 0 + +} MBG_PTP_V2_PARENT_DATASET_FLAGS; + +#define _mbg_swab_ptp_v2_parent_dataset_flags( _p )\ + _nop_macro_fnc() + + + +/** + * @brief PTPv2 parent dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.3 and 15.5.3.5.1 + * + * @see ::PTP_PORT_IDENTITY + * @see ::MBG_PTP_V2_PARENT_DATASET_FLAGS + * @see ::PTP_CLOCK_QUALITY + * @see ::PTP_CLOCK_ID + */ +typedef struct +{ + PTP_PORT_IDENTITY parent_port_identity; ///< identity of the master port, that issues the sync messages, see ::PTP_PORT_IDENTITY + MBG_PTP_V2_PARENT_DATASET_FLAGS flags; ///< flags field, see ::MBG_PTP_V2_PARENT_DATASET_FLAGS + uint8_t reserved; ///< reserved, currently always 0 + uint16_t parent_log_variance; ///< estimate of the parent clock's PTP variance, only valid if ::flags::parent_stats is set + int32_t parent_phase_change_rate; ///< estimate of the parent clock's phase change rate, only valid if ::flags::parent_stats is set + uint8_t grandmaster_priority_1; ///< priority 1 attribute of the grandmaster clock + PTP_CLOCK_QUALITY grandmaster_clock_quality; ///< quality of the grandmaster clock, see ::PTP_CLOCK_QUALITY + uint8_t grandmaster_priority_2; ///< priority 2 attribute of the grandmaster clock + PTP_CLOCK_ID grandmaster_identity; ///< identity of the grandmaster clock, see ::PTP_CLOCK_ID + +} MBG_PTP_V2_PARENT_DATASET; + + +#define _mbg_swab_ptp_v2_parent_dataset( _p ) \ +{ \ + _mbg_swab_ptp_port_identity( &(_p)->parent_port_identity ); \ + _mbg_swab_ptp_v2_parent_dataset_flags( &(_p)->flags ); \ + _mbg_swab8( &(_p)->reserved ); \ + _mbg_swab16( &(_p)->parent_log_variance ); \ + _mbg_swab32( &(_p)->parent_phase_change_rate ); \ + _mbg_swab8( &(_p)->grandmaster_priority_1 ); \ + _mbg_swab_ptp_clock_quality( &(_p)->grandmaster_clock_quality ); \ + _mbg_swab8( &(_p)->grandmaster_priority_2 ); \ + _mbg_swab_ptp_clock_id( &(_p)->grandmaster_identity ); \ +} + + +/** + * @brief Flags structure for the PTPv2 time properties dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.4 and 15.5.3.6.1 + * + * @see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET + */ +typedef struct +{ + uint8_t leap_61 : 1; ///< set, if the last minute of the current UTC day containts 61 seconds + uint8_t leap_59 : 1; ///< set, if the last minute of the current UTC day containts 59 seconds + uint8_t utc_offset_valid : 1; ///< set, if the current UTC offset is known to be correct + uint8_t ptp_timescale : 1; ///< set, if the timescale of the grandmaster clock is PTP + uint8_t time_traceable : 1; ///< set, if timescale and utc offset are traceable to a primary reference + uint8_t frequency_traceable : 1; ///< set, if the frequency determining the timescale is traceable to a primary reference + uint8_t reserved : 2; ///< reserved, currently always 0 + +} MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS; + + +#define _mbg_swab_ptp_v2_time_properties_dataset_flags( _p ) \ + _nop_macro_fnc() + + +/** + * @brief PTPv2 time properties dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.4 and 15.5.3.6.1 + * + * @see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS + */ +typedef struct +{ + int16_t current_utc_offset; ///< offset between TAI and UTC in seconds + MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS flags; ///< flags field, see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS + uint8_t time_source; ///< source of time used by the grandmaster clock, see ::PTP_TIME_SOURCES + +} MBG_PTP_V2_TIME_PROPERTIES_DATASET; + + +#define _mbg_swab_ptp_v2_time_properties_dataset( _p ) \ +{ \ + _mbg_swab16( &(_p)->current_utc_offset ); \ + _mbg_swab_ptp_v2_time_properties_dataset_flags( &(_p)->flags ); \ + _mbg_swab8( &(_p)->time_source ); \ +} + + +/** + * @brief PTPv2 port dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.5 and 15.5.3.7.1 + * + * @see ::PTP_PORT_IDENTITY + * @see ::PTP_TIME_INTERVAL + * @see ::MBG_PTP_V2_PORT_DATASET_IDX + */ +typedef struct +{ + PTP_PORT_IDENTITY port_identity; ///< identity of the local port, see ::PTP_PORT_IDENTITY + uint8_t port_state; ///< state of the protocol engine associated with this port, see ::PTP_PORT_STATES + int8_t log_min_delay_req_interval; ///< minimum delay request interval for this port + PTP_TIME_INTERVAL peer_mean_path_delay; ///< estimate of the current one-way propagation delay on the link, only valid if P2P is used, see ::PTP_TIME_INTERVAL + int8_t log_announce_interval; ///< announce interval to be used by this port + uint8_t announce_receipt_timeout; ///< shall be an integral multiple of ::announce_interval + int8_t log_sync_interval; ///< mean sync interval to be used for multicast messages + uint8_t delay_mechanism; ///< propagation delay measuring option, see ::PTP_DELAY_MECHS + int8_t log_min_pdelay_req_interval; ///< minimum peer delay request interval for this port + uint8_t version_number : 4; ///< PTP version in use on the port + uint8_t reserved : 4; ///< reserved, currently always 0 + +} MBG_PTP_V2_PORT_DATASET; + + +#define _mbg_swab_ptp_v2_port_dataset( _p ) \ +{ \ + _mbg_swab_ptp_port_identity( &(_p)->port_identity ); \ + _mbg_swab8( &(_p)->port_state ); \ + _mbg_swab8( &(_p)->log_min_delay_req_interval ); \ + _mbg_swab_ptp_time_interval( &(_p)->peer_mean_path_delay ); \ + _mbg_swab8( &(_p)->log_announce_interval ); \ + _mbg_swab8( &(_p)->announce_receipt_timeout ); \ + _mbg_swab8( &(_p)->log_sync_interval ); \ + _mbg_swab8( &(_p)->delay_mechanism ); \ + _mbg_swab8( &(_p)->log_min_pdelay_req_interval ); \ +} + + +/** + * @brief Index structure for PTPv2 port dataset + * + * @note Port dataset with index 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1 can be queried from a device + * + * @see ::MBG_PTP_V2_PORT_DATASET + */ +typedef struct +{ + uint16_t idx; ///< Index of the port dataset, 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1 + MBG_PTP_V2_PORT_DATASET port_dataset; ///< see ::MBG_PTP_V2_PORT_DATASET + +} MBG_PTP_V2_PORT_DATASET_IDX; + + +#define _mbg_swab_ptp_v2_port_dataset_idx( _p ) \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ptp_v2_port_dataset( &(_p)->port_dataset ); \ } + /** @} defgroup group_ptp */ @@ -10329,7 +15313,7 @@ enum NTP_ROLE_MASKS /** * @brief Enumeration of global NTP flags * - * @see ::NTP_FLAG_MASKS + * @see @ref NTP_FLAG_MASKS */ enum NTP_FLAGS { @@ -10347,10 +15331,23 @@ enum NTP_FLAGS NTP_MULTICAST, ///< transmission via multicast, point to multipoint NTP_MANYCAST, ///< transmission via manycast, point to multipoint NTP_POOL, ///< peer shall be treated as a pool server + NTP_PEER, ///< specifies a symmetric-active association should be used with this server + NTP_BROADCASTCLIENT, ///< receive broadcast messages on all interfaces + NTP_MULTICASTCLIENT, ///< receive messages from the given multicast group + NTP_MANYCASTCLIENT, ///< manycast shall be used on the given multicast address to discover peers + NTP_RESTRICTIONS, ///< NTP supports restrictions + NTP_DISCARD, ///< NTP supports "discard" rate limiting + NTP_REFCLOCKS, ///< NTP supports refclocks + NTP_STATISTICS, ///< NTP supports statistics (e.g. clockstats, loopstats, etc...) + NTP_MISCELLANEOUS, ///< NTP supports misc options (e.g. tinker, driftfile, orphan mode, etc...) + NTP_TRUSTED_KEYS, ///< NTP supports specifying trusted symmetric keys + NTP_FIXED_REFCLOCKS, ///< NTP refclocks not configurable + N_NTP_FLAGS }; + /** * @brief Flag masks associated with ::NTP_FLAGS * @@ -10361,24 +15358,38 @@ enum NTP_FLAGS * @todo We may need structures to configure symmetric keys, and autokey certificates. * * @see ::NTP_FLAGS - */ -enum NTP_FLAG_MASKS -{ - NTP_MSK_IPV4 = ( 1UL << NTP_IPV4 ), ///< see ::NTP_IPV4 - NTP_MSK_IPV6 = ( 1UL << NTP_IPV6 ), ///< see ::NTP_IPV6 - NTP_MSK_SYMM_KEYS = ( 1UL << NTP_SYMM_KEYS ), ///< see ::NTP_SYMM_KEYS - NTP_MSK_AUTOKEY = ( 1UL << NTP_AUTOKEY ), ///< see ::NTP_AUTOKEY - NTP_MSK_BURST = ( 1UL << NTP_BURST ), ///< see ::NTP_BURST - NTP_MSK_IBURST = ( 1UL << NTP_IBURST ), ///< see ::NTP_IBURST - NTP_MSK_NO_SELECT = ( 1UL << NTP_NO_SELECT ), ///< see ::NTP_NO_SELECT - NTP_MSK_PREEMPT = ( 1UL << NTP_PREEMPT ), ///< see ::NTP_PREEMPT - NTP_MSK_PREFER = ( 1UL << NTP_PREFER ), ///< see ::NTP_PREFER - NTP_MSK_TRUE = ( 1UL << NTP_TRUE ), ///< see ::NTP_TRUE - NTP_MSK_BROADCAST = ( 1UL << NTP_BROADCAST ), ///< see ::NTP_BROADCAST - NTP_MSK_MULTICAST = ( 1UL << NTP_MULTICAST ), ///< see ::NTP_MULTICAST - NTP_MSK_MANYCAST = ( 1UL << NTP_MANYCAST ), ///< see ::NTP_MANYCAST - NTP_MSK_POOL = ( 1UL << NTP_POOL ) ///< see ::NTP_POOL -}; + * + * @anchor NTP_FLAG_MASKS @{ */ + +#define NTP_MSK_IPV4 ( 1UL << NTP_IPV4 ) ///< see ::NTP_IPV4 +#define NTP_MSK_IPV6 ( 1UL << NTP_IPV6 ) ///< see ::NTP_IPV6 +#define NTP_MSK_SYMM_KEYS ( 1UL << NTP_SYMM_KEYS ) ///< see ::NTP_SYMM_KEYS; if set, ::NTP_SYMM_KEY_LIMITS can be queried +#define NTP_MSK_AUTOKEY ( 1UL << NTP_AUTOKEY ) ///< see ::NTP_AUTOKEY +#define NTP_MSK_BURST ( 1UL << NTP_BURST ) ///< see ::NTP_BURST +#define NTP_MSK_IBURST ( 1UL << NTP_IBURST ) ///< see ::NTP_IBURST +#define NTP_MSK_NO_SELECT ( 1UL << NTP_NO_SELECT ) ///< see ::NTP_NO_SELECT +#define NTP_MSK_PREEMPT ( 1UL << NTP_PREEMPT ) ///< see ::NTP_PREEMPT +#define NTP_MSK_PREFER ( 1UL << NTP_PREFER ) ///< see ::NTP_PREFER +#define NTP_MSK_TRUE ( 1UL << NTP_TRUE ) ///< see ::NTP_TRUE +#define NTP_MSK_BROADCAST ( 1UL << NTP_BROADCAST ) ///< see ::NTP_BROADCAST +#define NTP_MSK_MULTICAST ( 1UL << NTP_MULTICAST ) ///< see ::NTP_MULTICAST +#define NTP_MSK_MANYCAST ( 1UL << NTP_MANYCAST ) ///< see ::NTP_MANYCAST +#define NTP_MSK_POOL ( 1UL << NTP_POOL ) ///< see ::NTP_POOL +#define NTP_MSK_PEER ( 1UL << NTP_PEER ) ///< see ::NTP_PEER +#define NTP_MSK_BROADCASTCLIENT ( 1UL << NTP_BROADCASTCLIENT) ///< see ::NTP_BROADCASTCLIENT +#define NTP_MSK_MULTICASTCLIENT ( 1UL << NTP_MULTICASTCLIENT) ///< see ::NTP_MULTICASTCLIENT +#define NTP_MSK_MANYCASTCLIENT ( 1UL << NTP_MANYCASTCLIENT) ///< see ::NTP_MANYCASTCLIENT +#define NTP_MSK_RESTRICTIONS ( 1UL << NTP_RESTRICTIONS ) ///< see ::NTP_RESTRICTIONS +#define NTP_MSK_DISCARD ( 1UL << NTP_DISCARD ) ///< see ::NTP_DISCARD +#define NTP_MSK_REFCLOCKS ( 1UL << NTP_REFCLOCKS ) ///< see ::NTP_REFCLOCKS +#define NTP_MSK_STATISTICS ( 1UL << NTP_STATISTICS ) ///< see ::NTP_STATISTICS; if set, ::NTP_STATS_GLB_INFO can be queried +#define NTP_MSK_MISCELLANEOUS ( 1UL << NTP_MISCELLANEOUS ) ///< see ::NTP_MISCELLANEOUS +#define NTP_MSK_TRUSTED_KEYS ( 1UL << NTP_TRUSTED_KEYS ) ///< see ::NTP_TRUSTED_KEYS +#define NTP_MSK_FIXED_REFCLOCKS ( 1UL << NTP_FIXED_REFCLOCKS ) ///< see ::NTP_FIXED_REFCLOCKS + + +/** @} anchor NTP_FLAG_MASKS */ + /** @@ -10388,25 +15399,23 @@ enum NTP_FLAG_MASKS */ typedef struct { - uint8_t ntp_role; ///< one of the supported NTP roles, see ::NTP_ROLES - uint8_t reserved_1; ///< reserved, currently 0 - uint16_t reserved_2; ///< reserved, currently 0 + uint8_t ntp_role; ///< one of the supported NTP roles, see ::NTP_ROLES + uint8_t num_symm_keys; ///< number of configured symm keys + uint8_t num_trusted_keys; ///< number of activated symm keys + uint8_t reserved_1; ///< reserved, currently 0 - uint32_t reserved_3; ///< reserved, currently 0 - uint32_t reserved_4; ///< reserved, currently 0 + uint32_t reserved_2; ///< reserved, currently 0 + uint32_t reserved_3; ///< reserved, currently 0 - uint32_t flags; ///< NTP flags, see ::NTP_FLAG_MASKS + uint32_t flags; ///< NTP flags, see @ref NTP_FLAG_MASKS } NTP_GLB_SETTINGS; #define _mbg_swab_ntp_glb_settings( _p ) \ +do \ { \ - _mbg_swab16( &(_p)->reserved_2 ); \ - _mbg_swab32( &(_p)->reserved_3 ); \ - _mbg_swab32( &(_p)->reserved_4 ); \ - _mbg_swab32( &(_p)->flags ); \ -} - + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) /** @@ -10418,24 +15427,966 @@ typedef struct { NTP_GLB_SETTINGS settings; ///< current configuration settings - uint32_t reserved_1; ///< reserved, currently 0 - uint32_t reserved_2; ///< reserved, currently 0 + uint8_t max_symm_keys; ///< number of available symm keys that can be generated, see ::NTP_SYMM_KEY_INFO_IDX + uint8_t max_trusted_keys; ///< number of available trusted keys, see ::NTP_TRUSTED_KEY_INFO_IDX + + uint16_t reserved_2; ///< reserved, currently 0 + uint32_t reserved_3; ///< reserved, currently 0 uint32_t supp_ntp_roles; ///< supported NTP roles, see ::NTP_ROLE_MASKS - uint32_t supp_flags; ///< supported NTP flags, see ::NTP_FLAG_MASKS + uint32_t supp_flags; ///< supported NTP flags, see @ref NTP_FLAG_MASKS } NTP_GLB_INFO; #define _mbg_swab_ntp_glb_info( _p ) \ +do \ { \ _mbg_swab_ntp_glb_settings( &(_p)->settings ); \ - _mbg_swab32( &(_p)->reserved_1 ); \ - _mbg_swab32( &(_p)->reserved_2 ); \ _mbg_swab32( &(_p)->supp_ntp_roles ); \ _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + +#if defined( _PRELIMINARY_CODE ) + +/** + * @brief Enumeration of supported NTP restriction types/keywords + * + * Used with ::NTP_RESTR::type + * + * @see https://www.eecis.udel.edu/~mills/ntp/html/accopt.html#restrict + * @see ::NTP_RESTR_TYPE_MSKS + */ +enum NTP_RESTR_TYPES +{ + NTP_RESTR_TYPE_DEFAULT, + NTP_RESTR_TYPE_SOURCE, + NTP_RESTR_TYPE_ADDRESS, + N_NTP_RESTR_TYPES +}; + + + +/** + * @brief Bit masks associated with ::NTP_RESTR_TYPES + * + * Used with ::NTP_RESTR_LIMITS::supp_types + * + * @see ::NTP_RESTR_TYPES + */ +enum NTP_RESTR_TYPE_MSKS +{ + NTP_RESTR_TYPE_MSK_DEFAULT = ( 1UL << NTP_RESTR_TYPE_DEFAULT ), ///< see ::NTP_RESTR_TYPE_DEFAULT + NTP_RESTR_TYPE_MSK_SOURCE = ( 1UL << NTP_RESTR_TYPE_SOURCE ), ///< see ::NTP_RESTR_TYPE_SOURCE + NTP_RESTR_TYPE_MSK_ADDRESS = ( 1UL << NTP_RESTR_TYPE_ADDRESS ) ///< see ::NTP_RESTR_TYPE_ADDRESS +}; + + + +/** + * @brief Enumeration of supported NTP restriction flags + * + * Used to define ::NTP_RESTR_FLAG_MSKS + * + * @see https://www.eecis.udel.edu/~mills/ntp/html/accopt.html#restrict + * @see ::NTP_RESTR_FLAG_MSKS + */ +enum NTP_RESTR_FLAGS +{ + NTP_RESTR_FLAG_FLAKE, + NTP_RESTR_FLAG_IGNORE, + NTP_RESTR_FLAG_KOD, + NTP_RESTR_FLAG_LIMITED, + NTP_RESTR_FLAG_LOWPRIOTRAP, + NTP_RESTR_FLAG_MSSNTP, + NTP_RESTR_FLAG_NOMODIFY, + NTP_RESTR_FLAG_NOQUERY, + NTP_RESTR_FLAG_NOPEER, + NTP_RESTR_FLAG_NOSERVE, + NTP_RESTR_FLAG_NOTRAP, + NTP_RESTR_FLAG_NOTRUST, + NTP_RESTR_FLAG_NTPPORT, + NTP_RESTR_FLAG_VERSION, + NTP_RESTR_FLAG_IPV4, ///< This default restriction only applies to IPv4 + NTP_RESTR_FLAG_IPV6, ///< This default restriction only applies to IPv6 + N_NTP_RESTR_FLAGS +}; + + + +/** + * @brief Flag masks associated with ::NTP_RESTR_FLAGS + * + * Used with ::NTP_RESTR::flags and ::NTP_RESTR_LIMITS::supp_flags + * + * @see ::NTP_RESTR_FLAGS + */ +enum NTP_RESTR_FLAG_MSKS +{ + NTP_RESTR_FLAG_MSK_FLAKE = ( 1UL << NTP_RESTR_FLAG_FLAKE ), ///< see ::NTP_RESTR_FLAG_FLAKE + NTP_RESTR_FLAG_MSK_IGNORE = ( 1UL << NTP_RESTR_FLAG_IGNORE ), ///< see ::NTP_RESTR_FLAG_IGNORE + NTP_RESTR_FLAG_MSK_KOD = ( 1UL << NTP_RESTR_FLAG_KOD ), ///< see ::NTP_RESTR_FLAG_KOD + NTP_RESTR_FLAG_MSK_LIMITED = ( 1UL << NTP_RESTR_FLAG_LIMITED ), ///< see ::NTP_RESTR_FLAG_LIMITED + NTP_RESTR_FLAG_MSK_LOWPRIOTRAP = ( 1UL << NTP_RESTR_FLAG_LOWPRIOTRAP ),///< see ::NTP_RESTR_FLAG_LOWPRIOTRAP + NTP_RESTR_FLAG_MSK_MSSNTP = ( 1UL << NTP_RESTR_FLAG_MSSNTP ), ///< see ::NTP_RESTR_FLAG_MSSNTP + NTP_RESTR_FLAG_MSK_NOMODIFY = ( 1UL << NTP_RESTR_FLAG_NOMODIFY ), ///< see ::NTP_RESTR_FLAG_NOMODIFY + NTP_RESTR_FLAG_MSK_NOQUERY = ( 1UL << NTP_RESTR_FLAG_NOQUERY ), ///< see ::NTP_RESTR_FLAG_NOQUERY + NTP_RESTR_FLAG_MSK_NOPEER = ( 1UL << NTP_RESTR_FLAG_NOPEER ), ///< see ::NTP_RESTR_FLAG_NOPEER + NTP_RESTR_FLAG_MSK_NOSERVE = ( 1UL << NTP_RESTR_FLAG_NOSERVE ), ///< see ::NTP_RESTR_FLAG_NOSERVE + NTP_RESTR_FLAG_MSK_NOTRAP = ( 1UL << NTP_RESTR_FLAG_NOTRAP ), ///< see ::NTP_RESTR_FLAG_NOTRAP + NTP_RESTR_FLAG_MSK_NOTRUST = ( 1UL << NTP_RESTR_FLAG_NOTRUST ), ///< see ::NTP_RESTR_FLAG_NOTRUST + NTP_RESTR_FLAG_MSK_NTPPORT = ( 1UL << NTP_RESTR_FLAG_NTPPORT ), ///< see ::NTP_RESTR_FLAG_NTPPORT + NTP_RESTR_FLAG_MSK_VERSION = ( 1UL << NTP_RESTR_FLAG_VERSION ), ///< see ::NTP_RESTR_FLAG_VERSION + NTP_RESTR_FLAG_MSK_IPV4 = ( 1UL << NTP_RESTR_FLAG_IPV4 ), ///< see ::NTP_RESTR_FLAG_IPV4 + NTP_RESTR_FLAG_MSK_IPV6 = ( 1UL << NTP_RESTR_FLAG_IPV6 ) ///< see ::NTP_RESTR_FLAG_IPV6 +}; + + + +/** + * @brief General NTP restriction limits to be read from a device + * + * Used to query from a device how many NTP restrictions are supported + * by the device, then index 0..::NTP_RESTR_LIMITS::cur_restrs-1 + * restriction records can be read from a device. A maximum of + * ::NTP_RESTR_LIMITS::max_restrs can be configured at all. + */ +typedef struct +{ + uint16_t max_restrs; ///< Number of maximum supported restrictions + uint16_t cur_restrs; ///< Number of currently configured restrictions + uint32_t supp_types; ///< Supported restriction types, see ::NTP_RESTR_TYPE_MSKS + uint32_t supp_flags; ///< Supported restriction flags, see ::NTP_RESTR_FLAG_MSKS + uint32_t reserved; ///< Future use + +} NTP_RESTR_LIMITS; + +#define _mbg_swab_ntp_restr_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->max_restrs ); \ + _mbg_swab16( &(_p)->cur_restrs ); \ + _mbg_swab32( &(_p)->supp_types ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + +/** + * @brief NTP restriction + * + * Structure contains all flags and information needed for a valid NTP restriction + * as described at ntp.org's manual page. + */ +typedef struct +{ + uint8_t type; ///< Restriction type, see ::NTP_RESTR_TYPES + uint8_t reserved_1; ///< Future use + uint16_t reserved_2; ///< Future use + uint32_t flags; ///< Restriction flags, see ::NTP_RESTR_FLAG_MSKS + + MBG_HOSTNAME addr; ///< used if ::NTP_RESTR::type == ::NTP_RESTR_TYPE_ADDRESS + ///< can contain a hostname, or an IPv4 or IPv6 address + ///< with or without CIDR extension (eg. 172.16.0.0/16). +} NTP_RESTR; + +#define _mbg_swab_ntp_restr( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab_ntp_restr_discard( &(_p)->u.discard ); \ +} while ( 0 ) + + + +/** + * @brief NTP restriction, plus index + * + * @see ::NTP_RESTR + */ +typedef struct +{ + uint16_t idx; + NTP_RESTR restr; + +} NTP_RESTR_IDX; + +#define _mbg_swab_ntp_restr_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ntp_restr( &(_p)->restr ); \ +} while ( 0 ) + + + +/** + * @brief General NTP "discard" rate limiting limits to be read from a device + * + * Used to query from a device what range of values is supported + * for the NTP "discard" rate limiting configuration. + */ +typedef struct +{ + uint8_t avg_min; ///< Minimum value for avg + uint8_t avg_max; ///< Maximum value for avg + uint8_t min_min; ///< Minimum value for min + uint8_t min_max; ///< Maximum value for min + uint16_t monitor_min; ///< Maximum value for min + uint16_t monitor_max; ///< Maximum value for min + + uint32_t reserved; ///< Future use + +} NTP_DISCARD_LIMITS; + +#define _mbg_swab_ntp_discard_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->monitor_min ); \ + _mbg_swab16( &(_p)->monitor_max ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + + + +/** + * @brief NTP "discard" rate limiting settings as described at ntp.org's manual + */ +typedef struct +{ + uint8_t avg; ///< Specify the minimum average interpacket spacing in log2 s. + uint8_t min; ///< Specify the minimum interpacket spacing (guard time) in seconds. + uint16_t monitor; ///< ### TODO Which is the unit of this field? + uint32_t reserved; ///< Possible future use + +} NTP_DISCARD_SETTINGS; + +#define _mbg_swab_ntp_discard_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->monitor ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of supported refclock types + * + * Used with ::NTP_REFCLK_CFG_SETTINGS::type + * + * @see https://www.eecis.udel.edu/~mills/ntp/html/refclock.html + * @see ::NTP_REFCLK_TYPE_MSKS + */ +enum NTP_REFCLK_TYPES +{ + NTP_REFCLK_TYPE_LOCAL, ///< NTP local clock + NTP_REFCLK_TYPE_TRUETIME, ///< NTP Truetime driver + NTP_REFCLK_TYPE_PARSE, ///< NTP parse driver + NTP_REFCLK_TYPE_NMEA, ///< NTP NMEA driver + NTP_REFCLK_TYPE_PPS, ///< NTP atom driver (standalone PPS) + NTP_REFCLK_TYPE_SHM, ///< NTP shared memory driver + N_NTP_REFCLK_TYPES +}; + + + +/** + * @brief Bit masks associated with ::NTP_REFCLK_TYPES + * + * Used with ::NTP_REFCLK_CFG_INFO::supp_refclk_types + * + * @see ::NTP_REFCLK_TYPES + */ +enum NTP_REFCLK_TYPE_MSKS +{ + NTP_REFCLK_TYPE_MSK_LOCAL = ( 1UL << NTP_REFCLK_TYPE_LOCAL ), ///< see ::NTP_REFCLK_TYPE_LOCAL + NTP_REFCLK_TYPE_MSK_TRUETIME = ( 1UL << NTP_REFCLK_TYPE_TRUETIME ), ///< see ::NTP_REFCLK_TYPE_TRUETIME + NTP_REFCLK_TYPE_MSK_PARSE = ( 1UL << NTP_REFCLK_TYPE_PARSE ), ///< see ::NTP_REFCLK_TYPE_PARSE + NTP_REFCLK_TYPE_MSK_NMEA = ( 1UL << NTP_REFCLK_TYPE_NMEA ), ///< see ::NTP_REFCLK_TYPE_NMEA + NTP_REFCLK_TYPE_MSK_PPS = ( 1UL << NTP_REFCLK_TYPE_PPS ), ///< see ::NTP_REFCLK_TYPE_PPS + NTP_REFCLK_TYPE_MSK_SHM = ( 1UL << NTP_REFCLK_TYPE_SHM ) ///< see ::NTP_REFCLK_TYPE_SHM +}; + + + + + +/** + * @brief Numbers related to the "fudge" flags used with ntpd's refclock interface + * + * Used with ::NTP_REFCLK_CFG_SETTINGS::drv_flags_enable + * and ::NTP_REFCLK_CFG_SETTINGS::drv_flags_value + * + * The refclock interface provided by ntpd supports a number of flags + * (flag1..flag4) which can be "fudged" in ntp.conf to control specific + * features of a particular refclock driver, e.g.: + * "fudge 127.127.8.0 flag1 1" + * + * Which feature is controlled by which flag depends on the refclock + * driver type, so usually each flag has a different meaning for + * different refclock types. + * + * There are different cases to be distinguished: + * + * - if a flag is not specified at all in ntp.conf then + * the controlled feature is enabled or disabled + * according to the driver's default settings + * + * - if a flag is specified as '0' or '1' in ntp.conf then + * the controlled feature is enabled or disabled + * according to the flag's setting. + * + * Thus, the bit mask in ::NTP_REFCLK_CFG_SETTINGS::drv_flags_enable + * controls if the associated fudge flag should be specified in ntp.conf, + * and if it is specified then the associated bit in + * ::NTP_REFCLK_CFG_SETTINGS::drv_flags_value controls if the fudge flag + * is set to 0 or 1. + * + * @anchor NTP_FUDGE_FLAG_NUMBERS @{ */ + +#define NTP_MIN_REFCLOCK_FUDGE_FLAG 1 ///< minimum refclock fudge flag number, associated with bit 0 +#define N_NTP_REFCLOCK_FUDGE_FLAGS 4 ///< the number of supported fudge flags + +/** @} anchor NTP_FUDGE_FLAG_NUMBERS */ + + + +/** + * @brief NTP refclock specific settings + * + * Used to configure a NTP refclock. + */ +typedef struct +{ + uint8_t type; ///< See ::NTP_REFCLK_TYPES + uint8_t instance; ///< Refclock instance of the specified type. Usually up to 4 instances of the same type are supported by ntpd. + uint8_t mode; ///< Driver specific "mode" //### TODO Flag to enable "mode"? + int8_t stratum; ///< Stratum number to be fudged; -1 if unspecified and thus default is to be used + + int8_t refid[4]; ///< Reference id used by driver //### TODO Flag to enable "refid"? + + uint8_t minpoll; ///< Minimum polling interval, [log2 seconds], 0 if unused/unspecified + uint8_t maxpoll; ///< Maximum polling interval, [log2 seconds], 0 if unused/unspecified + uint8_t reserved_1; ///< Reserved for future use + uint8_t reserved_2; ///< Future use + + NANO_TIME_64 time1; ///< Driver specific + NANO_TIME_64 time2; ///< Driver specific + + uint16_t drv_flags_enable; ///< Enable/disable driver specific flags, see @ref NTP_FUDGE_FLAG_NUMBERS + uint16_t drv_flags_value; ///< 0 or 1, if (drv_flags_enable & x) == 1, see @ref NTP_FUDGE_FLAG_NUMBERS + + uint32_t flags; ///< See @ref NTP_FLAG_MASKS. Only flags specified in ::TODO can be used here. + + uint32_t reserved_3; ///< Future use + +} NTP_REFCLK_CFG_SETTINGS; + +#define _mbg_swab_ntp_refclk_cfg_settings( _p ) \ +do \ +{ \ + _mbg_swab_nano_time_64( &(_p)->time1 ); \ + _mbg_swab_nano_time_64( &(_p)->time2 ); \ + _mbg_swab16( &(_p)->drv_flags_enable ); \ + _mbg_swab16( &(_p)->drv_flags_value ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief NTP refclock settings index + * + * @see ::NTP_REFCLK_CFG_SETTINGS + */ +typedef struct +{ + uint16_t idx; + NTP_REFCLK_CFG_SETTINGS settings; ///< See ::NTP_REFCLK_CFG_SETTINGS + +} NTP_REFCLK_CFG_SETTINGS_IDX; + +#define _mbg_swab_ntp_refclk_cfg_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ntp_refclk_cfg_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief NTP refclock configuration and supported refclock types + * + * This structure can be used to set a NTP refclock's configuration + * and get to know its overall supported refclocks. + */ +typedef struct +{ + NTP_REFCLK_CFG_SETTINGS settings; ///< See ::NTP_REFCLK_CFG_SETTINGS + + uint32_t supp_refclk_types; ///< See ::NTP_REFCLK_TYPE_MSKS + +} NTP_REFCLK_CFG_INFO; + +#define _mbg_swab_ntp_refclk_cfg_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_refclk_cfg_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_refclk_types ); \ +} while ( 0 ) + + + +/** + * @brief NTP refclock info, with index + * + * @see ::NTP_REFCLK_CFG_INFO + */ +typedef struct +{ + uint16_t idx; + NTP_REFCLK_CFG_INFO info; + +} NTP_REFCLK_CFG_INFO_IDX; + +#define _mbg_swab_ntp_refclk_cfg_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ntp_refclk_cfg_info( &(_p)->info ); \ +} while ( 0 ) + + +/** + * @brief Enumeration of NTP supported symmetric key hashing algorithms + * + * @see ::NTP_SYMM_KEY_HASH_MASKS + * + * @note Support of external libraries (e.g.: OpenSSL) may be needed for + * some hashing algorithms. + */ +enum NTP_SYMM_KEY_HASHES +{ + NTP_SYMM_KEY_HASH_MD5, ///< NTP supports MD5 as key hashing algorithm + NTP_SYMM_KEY_HASH_SHA1, ///< NTP supports SHA1 as key hashing algorithm + N_NTP_SYMM_KEY_HASHES +}; + + + +/** + * @brief Flag masks associated with ::NTP_SYMM_KEY_HASHES + * + * @see ::NTP_SYMM_KEY_HASHES + */ +enum NTP_SYMM_KEY_HASH_MASKS +{ + NTP_SYMM_KEY_HASH_MSK_MD5 = ( 1UL << NTP_SYMM_KEY_HASH_MD5 ), ///< see ::NTP_SYMM_KEY_HASH_MD5 + NTP_SYMM_KEY_HASH_MSK_SHA1 = ( 1UL << NTP_SYMM_KEY_HASH_SHA1 ), ///< see ::NTP_SYMM_KEY_HASH_SHA1 +}; + + +/** + * @brief Name strings for defined NTP symm key hashes + * + * @see ::NTP_SYMM_KEY_HASHES + */ +#define NTP_SYMM_KEY_HASHES_STRS \ +{ \ + "MD5", \ + "SHA1" \ } + +/** + * @brief General NTP symmetric key limits to be read from a device + * + * ::NTP_SYMM_KEY_LIMITS::supp_hashes specifies supported hashing algorithms + * to create keys with. See ::NTP_SYMM_KEY_HASH_MASKS. Structure can be queried + * if ::NTP_MSK_SYMM_KEYS is set in ::NTP_GLB_INFO::supp_flags + */ +typedef struct +{ + uint16_t supp_hashes; ///< See ::NTP_SYMM_KEY_HASH_MASKS + uint16_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + uint32_t reserved_4; ///< Future use + +} NTP_SYMM_KEY_LIMITS; + +#define _mbg_swab_ntp_symm_key_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->supp_hashes ); \ +} while ( 0 ) + + + +/// Maximum length of a symmetric key. 128 byte was chosen to be +/// prepared for hash algorithms like SHA256, SH384, up to SHA512. +#define N_NTP_SYMM_KEY_LEN 128 + + +/** + * @brief NTP symmetric key specific settings + * + * This structure is used to configure a symmetric key for NTP. + */ +typedef struct +{ + uint16_t id; ///< Configurable key id (1..65534) + uint8_t hash; ///< See ::NTP_SYMM_KEY_HASHES + uint8_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint8_t key[N_NTP_SYMM_KEY_LEN]; ///< Hashed phrase, see ::N_NTP_SYMM_KEY_LEN + +} NTP_SYMM_KEY_SETTINGS; + +#define _mbg_swab_ntp_symm_key_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->id ); \ +} while ( 0 ) + + + +/** + * @brief NTP symmetric key settings, with index + * + * @see ::NTP_SYMM_KEY_SETTINGS + */ +typedef struct +{ + uint16_t idx; + NTP_SYMM_KEY_SETTINGS settings; + +} NTP_SYMM_KEY_SETTINGS_IDX; + +#define _mbg_swab_ntp_symm_key_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ntp_symm_key_settings( &(_p)->settings ); \ +} while ( 0 ) + + +/** + * @brief NTP symmkey info + * + * This structure is used to query a symmetric key for NTP. + */ +typedef struct +{ + NTP_SYMM_KEY_SETTINGS settings; + + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + uint32_t reserved_4; ///< Future use + +} NTP_SYMM_KEY_INFO; + +#define _mbg_swab_ntp_symm_key_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_symm_key_settings( &(_p)->settings ); \ +} while ( 0 ) + + +/** + * @brief NTP symm key info, with index + * + * @see ::NTP_SYMM_KEY_INFO + */ +typedef struct +{ + uint16_t idx; + NTP_SYMM_KEY_INFO info; + +} NTP_SYMM_KEY_INFO_IDX; + +#define _mbg_swab_ntp_symm_key_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ntp_symm_key_info( &(_p)->info ); \ +} while ( 0 ) + + +/** + * @brief NTP trusted key settings + * + * This structure is used to configure a trusted symmetric key for NTP. + */ +typedef struct +{ + uint16_t id; ///< Configurable key id (1..65534) + uint16_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + +} NTP_TRUSTED_KEY_SETTINGS; + +#define _mbg_swab_ntp_trusted_key_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->id ); \ +} while ( 0 ) + + +/** + * @brief NTP trusted key settings, with index + * + * @see ::NTP_TRUSTED_KEY_SETTINGS + */ +typedef struct +{ + uint16_t idx; + NTP_TRUSTED_KEY_SETTINGS settings; + +} NTP_TRUSTED_KEY_SETTINGS_IDX; + +#define _mbg_swab_ntp_trusted_key_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ntp_trusted_key_settings( &(_p)->settings ); \ +} while ( 0 ) + +/** + * @brief NTP trusted key info + * + * This structure is used to query a trusted symmetric key for NTP. + */ +typedef struct +{ + NTP_TRUSTED_KEY_SETTINGS settings; + + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + uint32_t reserved_4; ///< Future use + +} NTP_TRUSTED_KEY_INFO; + +#define _mbg_swab_ntp_trusted_key_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_trusted_key_settings( &(_p)->settings ); \ +} while ( 0 ) + + +/** + * @brief NTP trusted key info, with index + * + * @see ::NTP_TRUSTED_KEY_INFO + */ +typedef struct +{ + uint16_t idx; + NTP_TRUSTED_KEY_INFO info; + +} NTP_TRUSTED_KEY_INFO_IDX; + +#define _mbg_swab_ntp_trusted_key_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ntp_trusted_key_info( &(_p)->info ); \ +} while ( 0 ) + + +/** + * @brief Enumeration of NTP supported statistics + * + * @see ::NTP_GLB_STATS_MASKS + */ +enum NTP_GLB_STATS_FLAGS +{ + NTP_GLB_STATS_FLAG_ENABLE, ///< NTP stats can generally be enabled or disabled + NTP_GLB_STATS_FLAG_CLOCKSTATS, ///< NTP supports clockstats + NTP_GLB_STATS_FLAG_CRYPTOSTATS, ///< NTP supports cryptostats + NTP_GLB_STATS_FLAG_LOOPSTATS, ///< NTP supports loopstats + NTP_GLB_STATS_FLAG_PEERSTATS, ///< NTP supports peerstats + NTP_GLB_STATS_FLAG_RAWSTATS, ///< NTP supports rawstats + NTP_GLB_STATS_FLAG_SYSSTATS, ///< NTP supports sysstats + NTP_GLB_STATS_FLAG_FILEGEN, ///< NTP supports sets of files + ///< If flag is set there are structures needed + ///< that are not avail right now. Future use + N_NTP_GLB_STATS_FLAGS +}; + + + +/** + * @brief Flag masks associated with ::NTP_GLB_STATS_FLAGS + * + * @see ::NTP_GLB_STATS_FLAGS + */ +enum NTP_GLB_STATS_MASKS +{ + NTP_GLB_STATS_MSK_ENABLE = ( 1UL << NTP_GLB_STATS_FLAG_ENABLE ), ///< See ::NTP_GLB_STATS_FLAG_ENABLE + NTP_GLB_STATS_MSK_CLOCKSTATS = ( 1UL << NTP_GLB_STATS_FLAG_CLOCKSTATS ), ///< See ::NTP_GLB_STATS_FLAG_CLOCKSTATS + NTP_GLB_STATS_MSK_CRYPTOSTATS = ( 1UL << NTP_GLB_STATS_FLAG_CRYPTOSTATS ), ///< See ::NTP_GLB_STATS_FLAG_CRYPTOSTATS + NTP_GLB_STATS_MSK_LOOPSTATS = ( 1UL << NTP_GLB_STATS_FLAG_LOOPSTATS ), ///< See ::NTP_GLB_STATS_FLAG_LOOPSTATS + NTP_GLB_STATS_MSK_PEERSTATS = ( 1UL << NTP_GLB_STATS_FLAG_PEERSTATS ), ///< See ::NTP_GLB_STATS_FLAG_PEERSTATS + NTP_GLB_STATS_MSK_RAWSTATS = ( 1UL << NTP_GLB_STATS_FLAG_RAWSTATS ), ///< See ::NTP_GLB_STATS_FLAG_RAWSTATS + NTP_GLB_STATS_MSK_SYSSTATS = ( 1UL << NTP_GLB_STATS_FLAG_SYSSTATS ), ///< See ::NTP_GLB_STATS_FLAG_SYSSTATS + NTP_GLB_STATS_MSK_FILEGEN = ( 1UL << NTP_GLB_STATS_FLAG_FILEGEN ) ///< See ::NTP_GLB_STATS_FLAG_FILEGEN +}; + + + +/** + * @brief Global NTP statistics settings to be read from / written to a device + * + * ::NTP_GLB_STATS_MSK_ENABLE is the switch to enable / disable statistics in + * general. In case the bit is set all other bits stand for special statistic + * types that can be enabled or disabled by setting or deleting its specific bit. + */ +typedef struct +{ + uint32_t flags; ///< See ::NTP_GLB_STATS_MASKS + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + +} NTP_STATS_GLB_SETTINGS; + +#define _mbg_swab_ntp_stats_glb_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +/** + * @brief NTP statistics settings + * + * This structure can be used to determine possible NTP statistic options + * and can be queried if ::NTP_MSK_STATISTICS bit is set in ::NTP_GLB_INFO::supp_flags. + */ +typedef struct +{ + NTP_STATS_GLB_SETTINGS settings; ///< See ::NTP_STATS_GLB_SETTINGS + + uint32_t supp_stats; ///< See ::NTP_GLB_STATS_MASKS + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + +} NTP_STATS_GLB_INFO; + +#define _mbg_swab_ntp_stats_glb_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_stats_glb_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_stats ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of NTP supported (various) misc options + * + * @see ::NTP_MISC_MSKS + */ +enum NTP_MISC_FLAGS +{ + NTP_MISC_FLAG_DRIFTFILE, ///< NTP supports driftfile + NTP_MISC_FLAG_ORPHAN_MODE, ///< NTP supports orphan mode + NTP_MISC_FLAG_LEAPFILE, ///< NTP supports leapfile + N_NTP_MISC_FLAGS +}; + + + +/** + * @brief Flag masks associated with ::NTP_MISC_FLAGS + * + * @see ::NTP_MISC_FLAGS + */ +enum NTP_MISC_MSKS +{ + NTP_MISC_MSK_DRIFTFILE = ( 1UL << NTP_MISC_FLAG_DRIFTFILE ), ///< See ::NTP_MISC_FLAG_DRIFTFILE + NTP_MISC_MSK_ORPHAN_MODE = ( 1UL << NTP_MISC_FLAG_ORPHAN_MODE ), ///< See ::NTP_MISC_FLAG_ORPHAN_MODE + NTP_MISC_MSK_LEAPFILE = ( 1UL << NTP_MISC_FLAG_LEAPFILE ) ///< See ::NTP_MISC_FLAG_LEAPFILE +}; + + + +/** + * @brief General NTP misc limits to be read from a device + * + * This structure can be used to determine various NTP options + * and can be queried if ::NTP_MSK_MISCELLANEOUS bit is set in ::NTP_GLB_INFO::supp_flags. + */ +typedef struct +{ + uint32_t supp_flags; ///< See ::NTP_MISC_MSKS + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + +} NTP_MISC_LIMITS; + +#define _mbg_swab_ntp_misc_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + + +/** + * @brief NTP driftfile settings to be read from / written to a device + * + * If ::NTP_MISC_MSK_DRIFTFILE is set in ::NTP_MISC_LIMITS::supp_flags + * ::NTP_MISC_DRIFTFILE_SETTINGS can be read / written. + */ +typedef struct +{ + uint8_t enable; ///< Enable / disable writing a driftfile + uint8_t reserved_1; ///< Future use + uint16_t reserved_2; ///< Future use + +} NTP_MISC_DRIFTFILE_SETTINGS; + +#define _mbg_swab_ntp_misc_driftfile_settings( _p ) \ +do \ +{ \ +} while ( 0 ) + + +/** + * @brief Enumeration of NTP supported (various) misc options + * + * @see ::NTP_ORPHAN_MODE_MSK + */ +enum NTP_ORPHAN_MODE_FLAGS +{ + NTP_ORPHAN_MODE_FLAG_SUPP_DISABLE, ///< Orphan Mode support disabling + + N_NTP_ORPHAN_MODE_FLAGS +}; + + + +/** + * @brief Flag masks associated with ::NTP_ORPHAN_MODE_FLAGS + * + * @see ::NTP_ORPHAN_MODE_FLAGS + */ +enum NTP_ORPHAN_MODE_MSK +{ + NTP_ORPHAN_MODE_MSK_SUPP_DISABLE = ( 1UL << NTP_ORPHAN_MODE_FLAG_SUPP_DISABLE ) ///< See ::NTP_ORPHAN_MODE_FLAG_SUPP_DISABLE +}; + + +/** + * @brief NTP orphan mode settings to be read from / written to a device + * + * If ::NTP_MISC_MSK_ORPHAN_MODE is set in ::NTP_MISC_LIMITS::supp_flags + * ::NTP_MISC_ORPHAN_MODE_SETTINGS can be read / written. + */ +typedef struct +{ + uint8_t enable; ///< Generally enable / disable orphan mode + uint8_t mode; ///< Stratum level when no ref source available + uint16_t reserved_1; ///< Future use + + uint32_t reserved_2; ///< Future use + +} NTP_MISC_ORPHAN_MODE_SETTINGS; + +#define _mbg_swab_ntp_misc_orphan_mode_settings( _p ) \ +do \ +{ \ +} while ( 0 ) + + +/** + * @brief NTP orphan mode info + * + */ +typedef struct +{ + NTP_MISC_ORPHAN_MODE_SETTINGS settings; ///< See ::NTP_MISC_ORPHAN_MODE_SETTINGS + + uint32_t supp_flags; ///< See ::NTP_ORPHAN_MODE_MSK + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + +} NTP_MISC_ORPHAN_MODE_INFO; + +#define _mbg_swab_ntp_misc_orphan_mode_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_misc_orphan_mode_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + +/** + * @brief NTP leapfile settings to be read from / written to a device + * + * If ::NTP_MISC_MSK_LEAPFILE is set in ::NTP_MISC_LIMITS::supp_flags + * ::NTP_MISC_LEAPFILE_SETTINGS can be read / written. + */ +typedef struct +{ + uint8_t enable; ///< Generally enable / disable leapfile + uint8_t reserved_1; ///< Stratum level when no ref source available + uint16_t reserved_2; ///< Future use + +} NTP_MISC_LEAPFILE_SETTINGS; + +#define _mbg_swab_ntp_misc_leapfile_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_2 ); \ +} while ( 0 ) + + +#else // !defined( _PRELIMINARY_CODE ), dummy declarations + + typedef int NTP_RESTR_LIMITS; + typedef int NTP_RESTR; + typedef int NTP_RESTR_IDX; + typedef int NTP_DISCARD_LIMITS; + typedef int NTP_DISCARD_SETTINGS; + typedef int NTP_REFCLK_CFG_SETTINGS; + typedef int NTP_REFCLK_CFG_SETTINGS_IDX; + typedef int NTP_REFCLK_CFG_INFO; + typedef int NTP_REFCLK_CFG_INFO_IDX; + typedef int NTP_SYMM_KEY_LIMITS; + typedef int NTP_SYMM_KEY_SETTINGS; + typedef int NTP_SYMM_KEY_SETTINGS_IDX; + typedef int NTP_SYMM_KEY_INFO; + typedef int NTP_SYMM_KEY_INFO_IDX; + typedef int NTP_TRUSTED_KEY_SETTINGS; + typedef int NTP_TRUSTED_KEY_SETTINGS_IDX; + typedef int NTP_TRUSTED_KEY_INFO; + typedef int NTP_TRUSTED_KEY_INFO_IDX; + typedef int NTP_STATS_GLB_SETTINGS; + typedef int NTP_STATS_GLB_INFO; + typedef int NTP_MISC_LIMITS; + typedef int NTP_MISC_DRIFTFILE_SETTINGS; + typedef int NTP_MISC_ORPHAN_MODE_SETTINGS; + typedef int NTP_MISC_ORPHAN_MODE_INFO; + typedef int NTP_MISC_LEAPFILE_SETTINGS; + +#endif // defined( _PRELIMINARY_CODE ) + + /** * @brief Client settings of an NTP device * @@ -10443,19 +16394,24 @@ typedef struct */ typedef struct { - uint32_t reserved_1; ///< reserved, currently 0 - uint32_t reserved_2; ///< reserved, currently 0 + uint8_t num_peers; ///< number available peers + uint8_t reserved_1; ///< reserved, currently 0 + uint16_t reserved_2; ///< reserved, currently 0 - uint32_t flags; ///< NTP flags, see ::NTP_FLAG_MASKS + uint32_t reserved_3; ///< reserved, currently 0 + + uint32_t flags; ///< NTP flags, see @ref NTP_FLAG_MASKS } NTP_CLNT_MODE_SETTINGS; #define _mbg_swab_ntp_clnt_mode_settings( _p ) \ +do \ { \ _mbg_swab32( &(_p)->reserved_1 ); \ _mbg_swab32( &(_p)->reserved_2 ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) + /** @@ -10475,19 +16431,80 @@ typedef struct uint32_t reserved_1; ///< reserved, currently 0 uint32_t reserved_2; ///< reserved, currently 0 - uint32_t supp_flags; ///< supported NTP flags, see ::NTP_FLAG_MASKS - uint32_t supp_peer_flags; ///< supported NTP flags for peers, see ::NTP_FLAG_MASKS + uint32_t supp_flags; ///< supported NTP flags, see @ref NTP_FLAG_MASKS + uint32_t supp_peer_flags; ///< supported NTP flags for peers, see @ref NTP_FLAG_MASKS } NTP_CLNT_MODE_INFO; #define _mbg_swab_ntp_clnt_mode_info( _p ) \ +do \ { \ _mbg_swab_ntp_clnt_mode_settings( &(_p)->settings ); \ _mbg_swab32( &(_p)->reserved_1 ); \ _mbg_swab32( &(_p)->reserved_2 ); \ _mbg_swab32( &(_p)->supp_flags ); \ _mbg_swab32( &(_p)->supp_peer_flags ); \ -} +} while ( 0 ) + + + +/** + * @brief General NTP peer settings limits to be read from a device + * + * Used to query from a device how many NTP associations are supported + * by the device, then index 0..::NTP_PEER_LIMITS::n_cur_peers-1 + * peer records can be read from a device. A maximum of + * ::NTP_PEER_LIMITS::n_supp_peers can be configured at all. + */ +typedef struct +{ + uint16_t n_supp_peers; ///< maximum number of configurable peers + uint16_t n_cur_peers; ///< current number of configured peers + + uint8_t poll_intv_min; ///< minimum supported NTP polling interval + uint8_t poll_intv_max; ///< maximum supported NTP polling interval + uint8_t reserved_1; ///< reserved, currently 0 + uint8_t reserved_2; ///< reserved, currently 0 + + uint32_t supp_assoc_types; ///< supported types of NTP associations + uint32_t reserved_3; ///< reserved, currently 0 + + uint32_t supp_flags_server; ///< supported flags for unicast associations + uint32_t supp_flags_peer; ///< supported flags for unicast symmetric-active assocations + uint32_t supp_flags_pool; ///< supported flags for unicast pool associations + uint32_t supp_flags_broadcast; ///< supported flags for broadcast associations + uint32_t supp_flags_multicast; ///< supported flags for multicast associations + uint32_t supp_flags_manycast; ///< supported flags for manycast associations + uint32_t supp_flags_broadcastclient; ///< supported flags for broadcast client associations + uint32_t supp_flags_multicastclient; ///< supported flags for multicast client associations + uint32_t supp_flags_manycastclient; ///< supported flags for manycast client associations + uint32_t reserved_4; ///< reserved, currently 0 + uint32_t reserved_5; ///< reserved, currently 0 + uint32_t reserved_6; ///< reserved, currently 0 + +} NTP_PEER_LIMITS; + +#define _mbg_swab_ntp_peer_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->n_supp_peers ); \ + _mbg_swab16( &(_p)->n_cur_peers ); \ + _mbg_swab32( &(_p)->supp_assoc_types ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->supp_flags_server ); \ + _mbg_swab32( &(_p)->supp_flags_peer ); \ + _mbg_swab32( &(_p)->supp_flags_pool ); \ + _mbg_swab32( &(_p)->supp_flags_broadcast ); \ + _mbg_swab32( &(_p)->supp_flags_multicast ); \ + _mbg_swab32( &(_p)->supp_flags_manycast ); \ + _mbg_swab32( &(_p)->supp_flags_broadcastclient ); \ + _mbg_swab32( &(_p)->supp_flags_multicastclient ); \ + _mbg_swab32( &(_p)->supp_flags_manycastclient ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->reserved_5 ); \ + _mbg_swab32( &(_p)->reserved_6 ); \ +} while ( 0 ) + /** @@ -10502,28 +16519,33 @@ typedef struct */ typedef struct { - MBG_HOSTNAME hostname; ///< hostname or IP address of the peer + MBG_HOSTNAME hostname; ///< hostname or IP address of the peer, not used + ///< when the NTP_BROADCASTCLIENT flag is set uint8_t min_poll; ///< minimal configurable NTP polling interval uint8_t max_poll; ///< maximal configurable NTP polling interval uint8_t ttl; ///< time-to-live to use with broadcast/multicast/manycast uint8_t reserved_1; ///< reserved, currently 0 - uint32_t reserved_2; ///< reserved, currently 0 + uint32_t key; ///< ID of the symmetric key used with this association, + ///< this must be in the range 1-65534, 0 = disabled uint32_t reserved_3; ///< reserved, currently 0 uint32_t reserved_4; ///< reserved, currently 0 - uint32_t flags; ///< additional options configured, see ::NTP_FLAG_MASKS + uint32_t flags; ///< additional options configured, see @ref NTP_FLAG_MASKS } NTP_PEER_SETTINGS; #define _mbg_swab_ntp_peer_settings( _p ) \ +do \ { \ - _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->key ); \ _mbg_swab32( &(_p)->reserved_3 ); \ _mbg_swab32( &(_p)->reserved_4 ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) + + /** * @brief Peer settings for NTP devices @@ -10538,54 +16560,62 @@ typedef struct } NTP_PEER_SETTINGS_IDX; #define _mbg_swab_ntp_peer_settings_idx( _p ) \ +do \ { \ _mbg_swab32( &(_p)->idx ); \ _mbg_swab_ntp_peer_settings( &(_p)->peer_settings ); \ -} +} while ( 0 ) + -#ifdef DEBUG /** - * @brief Dummy structure for later NTP server implementations, not used, yet + * @brief Server settings of an NTP device + * + * This structure should be sent to an NTP server to configure server parameters */ typedef struct { - uint32_t reserved_1; ///< reserved, currently 0 - uint32_t reserved_2; ///< reserved, currently 0 + uint8_t num_refclks; ///< number of available refclks @ref NTP_REFCLK_CFG_INFO + uint8_t reserved_1; ///< reserved, currently 0 + uint16_t reserved_2; ///< reserved, currently 0 + + uint32_t reserved_3; ///< reserved, currently 0 - uint32_t flags; ///< NTP flags, see ::NTP_FLAG_MASKS + uint32_t flags; ///< NTP flags, see @ref NTP_FLAG_MASKS } NTP_SRV_MODE_SETTINGS; #define _mbg_swab_ntp_srv_mode_settings( _p ) \ +do \ { \ - _mbg_swab32( &(_p)->reserved_1 ); \ - _mbg_swab32( &(_p)->reserved_2 ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) /** - * @brief Dummy structure for later NTP server implementations + * @brief Server settings info of an NTP device + * + * This structure should be used to query an NTP server configuration from a device */ typedef struct { NTP_SRV_MODE_SETTINGS settings; - uint32_t reserved_1; ///< reserved, currently 0 - uint32_t reserved_2; ///< reserved, currently 0 + uint8_t max_refclks; ///< number of supported refclks @ref NTP_REFCLK_CFG_INFO + uint8_t reserved_1; ///< reserved, currently 0 + uint16_t reserved_2; ///< reserved, currently 0 - uint32_t supp_flags; ///< supported NTP flags, see ::NTP_FLAG_MASKS + uint32_t reserved_3; ///< reserved, currently 0 + + uint32_t supp_flags; ///< supported NTP flags, see @ref NTP_FLAG_MASKS } NTP_SRV_MODE_INFO; #define _mbg_swab_ntp_srv_mode_info( _p ) \ +do \ { \ _mbg_swab_ntp_srv_mode_settings( &(_p)->settings ); \ - _mbg_swab32( &(_p)->reserved_1 ); \ - _mbg_swab32( &(_p)->reserved_2 ); \ _mbg_swab32( &(_p)->supp_flags ); \ -} -#endif // DEBUG +} while ( 0 ) /** @@ -10602,12 +16632,14 @@ typedef struct } NTP_SHORT_TSTAMP; #define _mbg_swab_ntp_short_tstamp( _p ) \ +do \ { \ _mbg_swab16( &(_p)->seconds ); \ _mbg_swab16( &(_p)->fractions ); \ } + /** * @brief Structure that represents a timestamp in NTP Timestamp Format */ @@ -10619,10 +16651,12 @@ typedef struct } NTP_TSTAMP; #define _mbg_swab_ntp_tstamp( _p ) \ +do \ { \ _mbg_swab32( &(_p)->seconds ); \ _mbg_swab32( &(_p)->fractions ); \ -} +} while ( 0 ) + /** @@ -10646,6 +16680,7 @@ enum NTP_IMPL * for multi-language strings can be found in tmonlstr.h. */ #define MBG_NTP_IMPL_STR_ENG "Implemetation Type:" + #define MBG_NTP_IMPL_STR_ENG_UNKNOWN "Unknown NTP implementation" #define MBG_NTP_IMPL_STR_ENG_NTPD "Network Time Protocol daemon (ntpd)" #define MBG_NTP_IMPL_STR_ENG_NTPDATE "NTP client only (ntpdate)" @@ -10665,6 +16700,7 @@ enum NTP_IMPL } + /** * @brief Enumeration of CPU types using NTP * @@ -10687,6 +16723,7 @@ enum NTP_CPU_TYPES }; + /** * @brief Name strings for known CPU types using NTP * @@ -10708,6 +16745,7 @@ enum NTP_CPU_TYPES } + /** * @brief Enumeration of operating systems using NTP * @@ -10725,6 +16763,7 @@ enum NTP_SYSTEMS }; + /** * @brief Name strings for operating systens using NTP * @@ -10741,6 +16780,7 @@ enum NTP_SYSTEMS } + /** * @brief Enumeration of NTP leap indication bits * @@ -10756,11 +16796,14 @@ enum NTP_LI_BITS N_NTP_LI_BITS }; + + /* * Default initializers for English leapsecond string names. Initializers * for multi-language strings can be found in tmonlstr.h. */ #define MBG_NTP_LEAP_STR_ENG "Leapsecond indication:" + #define MBG_NTP_LEAP_STR_ENG_NONE "None" #define MBG_NTP_LEAP_STR_ENG_ADD_SEC "Insert second" #define MBG_NTP_LEAP_STR_ENG_DEL_SEC "Delete second" @@ -10775,6 +16818,7 @@ enum NTP_LI_BITS } + /** * @brief Enumeration of NTP synchronization source bits * @@ -10796,11 +16840,14 @@ enum NTP_SYNC_SRC_BITS N_NTP_SYNC_SRC_BITS }; + + /* * Default initializers for English sync source string names. Initializers * for multi-language strings can be found in tmonlstr.h. */ #define MBG_NTP_SYNC_SRC_STR_ENG_LABEL "Sync Source:" + #define MBG_NTP_SYNC_SRC_STR_ENG_UNSPEC "Not yet synchronized" #define MBG_NTP_SYNC_SRC_STR_ENG_PPS "Pulse per second signal" #define MBG_NTP_SYNC_SRC_STR_ENG_LF_RADIO "VLF/LF radio" @@ -10827,6 +16874,7 @@ enum NTP_SYNC_SRC_BITS } + /** * @brief Enumeration of NTP system event message bits * @@ -10854,12 +16902,15 @@ enum NTP_SYS_EVT_BITS N_NTP_SYS_EVT_BITS }; + + /* * Default initializers for English sync source string names. Initializers * for multi-language strings can be found in tmonlstr.h. */ #define MBG_NTP_SYS_EVT_STR_ENG_CNT_LABEL "System Event Counter:" #define MBG_NTP_SYS_EVT_STR_ENG_MSG_LABEL "System Event Message:" + #define MBG_NTP_SYS_EVT_STR_ENG_UNSPEC "Unspecified NTP event" #define MBG_NTP_SYS_EVT_STR_ENG_FREQ_NOT_SET "Frequency file not available" #define MBG_NTP_SYS_EVT_STR_ENG_FREQ_SET "Frequency set from frequency file" @@ -10898,6 +16949,8 @@ enum NTP_SYS_EVT_BITS MBG_NTP_SYS_EVT_STR_ENG_STALE_LS_VALUES \ } + + /** * @brief Enumeration of supported NTP system state values * @@ -10918,6 +16971,7 @@ enum NTP_SYS_STATE_SUPP_FLAGS }; + /** * @brief Flag masks for NTP_SYS_STATE_SUPP_FLAGS * @@ -10939,6 +16993,7 @@ enum NTP_SYS_STATE_SUPP_FLAG_MASKS }; + /** * @brief Structure that represents the current system status of an NTP device * @@ -10969,7 +17024,7 @@ typedef struct int32_t root_delay; ///< [us] Total roundtrip delay to the system peer int32_t root_disp; ///< [us] Total dispersion to the system peer - MBG_IP_ADDR ref_id; ///< Reference ID of the current system peer, see ::MBG_IP_ADDR + MBG_IP_ADDR ref_id; ///< Reference ID of the current system peer, see ::MBG_IP_ADDR NTP_TSTAMP ref_time; ///< Last time the system time has been adjusted, see ::NTP_TSTAMP NTP_TSTAMP sys_time; ///< Current system time, see ::NTP_TSTAMP @@ -10990,6 +17045,54 @@ typedef struct } NTP_SYS_STATE; +#define _mbg_swab_ntp_sys_state( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_flags ); \ + \ + _mbg_swab8( &(_p)->leap_ind ); \ + _mbg_swab8( &(_p)->sys_sync_src ); \ + _mbg_swab8( &(_p)->sys_evt_cnt ); \ + _mbg_swab8( &(_p)->sys_rec_evt ); \ + \ + _mbg_swab8( &(_p)->impl_type ); \ + _mbg_swab8( &(_p)->major_version ); \ + _mbg_swab8( &(_p)->minor_version ); \ + _mbg_swab8( &(_p)->micro_version ); \ + \ + _mbg_swab16( &(_p)->patch_lvl ); \ + _mbg_swab8( &(_p)->cpu_type ); \ + _mbg_swab8( &(_p)->system ); \ + \ + _mbg_swab8( &(_p)->stratum ); \ + _mbg_swab8( &(_p)->precision ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + \ + _mbg_swab32( &(_p)->root_delay ); \ + _mbg_swab32( &(_p)->root_disp ); \ + \ + _mbg_swab_ip_addr( &(_p)->ref_id ); \ + \ + _mbg_swab_ntp_tstamp( &(_p)->ref_time ); \ + _mbg_swab_ntp_tstamp( &(_p)->sys_time ); \ + \ + _mbg_swab16( &(_p)->sys_peer ); \ + _mbg_swab8( &(_p)->poll ); \ + _mbg_swab8( &(_p)->minpoll ); \ + \ + _mbg_swab64( &(_p)->offset ); \ + \ + _mbg_swab32( &(_p)->freq ); \ + _mbg_swab32( &(_p)->sys_jitter ); \ + _mbg_swab32( &(_p)->clk_jitter ); \ + _mbg_swab32( &(_p)->clk_wander ); \ + \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + \ +} while ( 0 ) + + /** * @brief Enumeration of NTP mode bits @@ -11010,6 +17113,8 @@ enum NTP_MODE_BITS N_NTP_MODE_BITS }; + + /* * Default initializers for English NTP peer mode string names. Initializers * for multi-language strings can be found in tmonlstr.h. @@ -11039,6 +17144,7 @@ enum NTP_MODE_BITS } + /** * @brief Enumeration of NTP peer reach status * @@ -11057,6 +17163,8 @@ enum NTP_REACH_STAT_BITS N_NTP_REACH_STAT_BITS }; + + /* * Default initializers for English reach status string names. Initializers * for multi-language strings can be found in tmonlstr.h. @@ -11085,6 +17193,7 @@ enum NTP_REACH_STAT_BITS } + /** * @brief Enumeration of NTP peer selection status * @@ -11104,6 +17213,8 @@ enum NTP_PEER_SEL_STATUS_BITS N_NTP_PEER_SEL_STATUS_BITS }; + + /* * Default initializers for English peer select status string names. Initializers * for multi-language strings can be found in tmonlstr.h. @@ -11132,6 +17243,7 @@ enum NTP_PEER_SEL_STATUS_BITS } + /** * @brief Enumeration of NTP peer status codes * @@ -11171,6 +17283,7 @@ enum NTP_PEER_STATUS_FLAG_MASKS * for multi-language strings can be found in tmonlstr.h. */ #define MBG_NTP_PEER_STATUS_STR_ENG_LABEL "Peer Status:" + #define MBG_NTP_PEER_STATUS_STR_ENG_BCST "Broadcast association" #define MBG_NTP_PEER_STATUS_STR_ENG_REACH "Host reachable" #define MBG_NTP_PEER_STATUS_STR_ENG_AUTHENB "Authentication enabled" @@ -11186,6 +17299,7 @@ enum NTP_PEER_STATUS_FLAG_MASKS } + /** * @brief Enumeration of NTP peer event message codes * @@ -11213,12 +17327,15 @@ enum NTP_PEER_EVT_BITS N_NTP_PEER_EVT_BITS }; + + /* * Default initializers for English event message codes. Initializers * for multi-language strings can be found in tmonlstr.h. */ #define MBG_NTP_PEER_EVT_STR_ENG_CNT_LABEL "Peer Event Counter:" #define MBG_NTP_PEER_EVT_STR_ENG_MSG_LABEL "Peer Event Message:" + #define MBG_NTP_PEER_EVT_STR_ENG_UNSPEC "Unspecified NTP event" #define MBG_NTP_PEER_EVT_STR_ENG_MOBILIZE "Association mobilized" #define MBG_NTP_PEER_EVT_STR_ENG_DEMOBILIZE "Association demobilized" @@ -11283,6 +17400,7 @@ enum NTP_FLASH_STAT_FLAGS }; + /** * @brief Flag masks for ::NTP_FLASH_STAT_FLAGS * @@ -11307,12 +17425,14 @@ enum NTP_FLASH_STAT_FLAG_MASKS NTP_FLASH_STAT_PEER_UNREACH_MSK = ( 1UL << NTP_FLASH_STAT_PEER_UNREACH ), ///< see ::NTP_FLASH_STAT_PEER_UNREACH }; + + /* * Default initializers for English ntp flash state mask. Initializers * for multi-language strings can be found in tmonlstr.h. */ - #define MBG_NTP_FLASH_STR_ENG_LABEL "Flash Status:" + #define MBG_NTP_FLASH_STR_ENG_PKT_DUP "Duplicate packet" #define MBG_NTP_FLASH_STR_ENG_PKT_BOGUS "Bogus packet" #define MBG_NTP_FLASH_STR_ENG_PKT_UNSYNC "Server not synchronized" @@ -11346,6 +17466,7 @@ enum NTP_FLASH_STAT_FLAG_MASKS } + /** * @brief Enumeration of supported NTP peer state values * @@ -11353,7 +17474,7 @@ enum NTP_FLASH_STAT_FLAG_MASKS */ enum NTP_PEER_STATE_SUPP_FLAGS { - NTP_PEER_STATE_SUPP_STD = 0, ///< supports standard values of ::NTP_PEER_STATE, all fields except below and reserved + NTP_PEER_STATE_SUPP_STD, ///< supports standard values of ::NTP_PEER_STATE, all fields except below and reserved NTP_PEER_STATE_SUPP_ASS_ID, ///< supports association ID, see ::NTP_PEER_STATE::ass_id NTP_PEER_STATE_SUPP_EVENTS, ///< supports peer state events (NTP_PEER_STATE::peer_evt_cnt, NTP_PEER_STATE::peer_rec_evt) NTP_PEER_STATE_SUPP_REACH_STAT, ///< supports peer reach status, see ::NTP_PEER_STATE::peer_reach_stat @@ -11395,6 +17516,7 @@ enum NTP_PEER_STATE_SUPP_FLAG_MASKS }; + /** * @brief Structure that represents the status of an NTP peer * @@ -11418,8 +17540,8 @@ typedef struct uint8_t reserved_1; ///< Reserved, currently always 0 uint16_t reserved_2; ///< Reserved, currently always 0 - MBG_IP_ADDR_PORT src_addr; ///< Source address of the NTP peer, see ::MBG_IP_ADDR_PORT - MBG_IP_ADDR_PORT dst_addr; ///< Destination address of the NTP peer, see ::MBG_IP_ADDR_PORT + MBG_IP_ADDR_PORT src_addr; ///< Source address of the NTP peer, see ::MBG_IP_ADDR_PORT + MBG_IP_ADDR_PORT dst_addr; ///< Destination address of the NTP peer, see ::MBG_IP_ADDR_PORT uint8_t stratum; ///< Current stratum level of the NTP peer int8_t precision; ///< Precision of the peer clock (2^precision) @@ -11428,7 +17550,7 @@ typedef struct int32_t root_delay; ///< [us] Total roundtrip delay to the system peer of the NTP peer int32_t root_disp; ///< [us] Total dispersion to the system peer of the NTP peer - MBG_IP_ADDR ref_id; ///< Reference ID of the NTP peer, see ::MBG_IP_ADDR + MBG_IP_ADDR ref_id; ///< Reference ID of the NTP peer, see ::MBG_IP_ADDR NTP_TSTAMP ref_time; ///< Last time the NTP peers time has been adjusted, see ::NTP_TSTAMP NTP_TSTAMP rec_time; ///< Current system time of the NTP peer, see ::NTP_TSTAMP @@ -11466,6 +17588,73 @@ typedef struct } NTP_PEER_STATE; + +#define _mbg_swab_ntp_peer_state( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_flags ); \ + \ + _mbg_swab16( &(_p)->ass_id ); \ + _mbg_swab16( &(_p)->peer_status_flags ); \ + \ + _mbg_swab8( &(_p)->leap_ind ); \ + _mbg_swab8( &(_p)->peer_sel_stat ); \ + _mbg_swab8( &(_p)->peer_evt_cnt ); \ + _mbg_swab8( &(_p)->peer_rec_evt ); \ + \ + _mbg_swab8( &(_p)->peer_reach_stat ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + \ + _mbg_swab_ip_addr_port( &(_p)->src_addr ); \ + _mbg_swab_ip_addr_port( &(_p)->dst_addr ); \ + \ + _mbg_swab8( &(_p)->stratum ); \ + _mbg_swab8( &(_p)->precision ); \ + _mbg_swab16( &(_p)->reserved_3 ); \ + \ + _mbg_swab32( &(_p)->root_delay ); \ + _mbg_swab32( &(_p)->root_disp ); \ + \ + _mbg_swab_ip_addr( &(_p)->ref_id ); \ + \ + _mbg_swab_ntp_tstamp( &(_p)->ref_time ); \ + _mbg_swab_ntp_tstamp( &(_p)->rec_time ); \ + \ + _mbg_swab8( &(_p)->reach ); \ + _mbg_swab8( &(_p)->reserved_4 ); \ + _mbg_swab16( &(_p)->unreach ); \ + \ + _mbg_swab8( &(_p)->host_mode ); \ + _mbg_swab8( &(_p)->peer_mode ); \ + _mbg_swab8( &(_p)->host_poll ); \ + _mbg_swab8( &(_p)->peer_poll ); \ + \ + _mbg_swab8( &(_p)->headway ); \ + _mbg_swab8( &(_p)->reserved_5 ); \ + _mbg_swab16( &(_p)->flash_stat_flags ); \ + \ + _mbg_swab16( &(_p)->key_id ); \ + _mbg_swab16( &(_p)->reserved_6 ); \ + \ + _mbg_swab64( &(_p)->offset ); \ + _mbg_swab64( &(_p)->delay ); \ + \ + _mbg_swab32( &(_p)->disp ); \ + _mbg_swab32( &(_p)->jitter ); \ + \ + _mbg_swab32( &(_p)->xleave ); \ + \ + _mbg_swab8( &(_p)->n_filter_values ); \ + _mbg_swab8( &(_p)->reserved_7 ); \ + _mbg_swab16( &(_p)->reserved_8 ); \ + \ + _mbg_swab32( &(_p)->reserved_9 ); \ + \ +} while ( 0 ) + + + /** * @brief Structure that contains an index value and the NTP peer state * @@ -11480,6 +17669,14 @@ typedef struct } NTP_PEER_STATE_IDX; +#define _mbg_swab_ntp_peer_state_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ntp_peer_state( &(_p)->peer_state ); \ +} while ( 0 ) + + /** @} defgroup group_ntp */ @@ -11508,6 +17705,7 @@ typedef struct } LNO_STATE; #define _mbg_swab_lno_state( _p ) \ +do \ { \ int i; \ \ @@ -11517,7 +17715,7 @@ typedef struct _mbg_swab_16( &(_p)->max_sine_lvl ); \ _mbg_swab_16( &(_p)->reserved_0 ); \ _mbg_swab_16( &(_p)->flags ); \ -} +} while ( 0 ) /** @@ -11570,12 +17768,13 @@ typedef struct } VST_HEADER; #define _mbg_swab_vst_header( _p ) \ +do \ { \ _mbg_swab16( &(_p)->data_type ); \ _mbg_swab16( &(_p)->idx ); \ _mbg_swab16( &(_p)->data_len ); \ _mbg_swab16( &(_p)->reserved ); \ -} +} while ( 0 ) /** @} defgroup group_vst */ @@ -11628,12 +17827,13 @@ typedef struct } SHS_SETTINGS; #define _mbg_swab_shs_settings( _p ) \ +do \ { \ _mbg_swab_nano_time( &(_p)->err_limit ); \ _mbg_swab_nano_time( &(_p)->warn_limit ); \ _mbg_swab32( &(_p)->reserved ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) @@ -11653,12 +17853,13 @@ typedef struct } SHS_INFO; #define _mbg_swab_shs_info( _p ) \ +do \ { \ _mbg_swab_shs_settings( &(_p)->settings ); \ _mbg_swab_nano_time( &(_p)->max_limit ); \ _mbg_swab32( &(_p)->reserved ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) @@ -11678,13 +17879,14 @@ typedef struct } SHS_STATUS; #define _mbg_swab_shs_status( _p ) \ +do \ { \ _mbg_swab_nano_time( &(_p)->time_diff ); \ _mbg_swab32( &(_p)->clk_status_1 ); \ _mbg_swab32( &(_p)->clk_status_2 ); \ _mbg_swab16( &(_p)->reserved_2 ); \ _mbg_swab32( &(_p)->flags ); \ -} +} while ( 0 ) @@ -11751,11 +17953,6 @@ enum SHS_FLAG_MASKS * @{ */ /** - * @brief An identifier used to mark an XBP port unused - */ -#define XBP_PORT_RESERVED ( (uint8_t) 255 ) - -/** * @brief An XBP port specifier * * Each controller can provide up to 255 ports with numbers 0..254. @@ -11765,6 +17962,12 @@ typedef uint8_t XBP_PORT; /** + * @brief An identifier used to mark an XBP port unused + */ +#define XBP_PORT_RESERVED ( (XBP_PORT) -1 ) + + +/** * @brief Maximum XBP bus/controller cascading level * * Should be 7 so the total size of ::XBP_ADDR is 8 bytes. @@ -11784,6 +17987,8 @@ typedef struct } XBP_ADDR; +#define _mbg_swab_xbp_addr( _p ) _nop_macro_fnc() // only single bytes + /** @@ -11793,10 +17998,24 @@ typedef struct { uint32_t features; ///< Mask of XBP features, see ::XBP_FEAT_MASKS uint32_t flags; ///< XBP flags, currently not used - uint32_t reserved[4]; ///< reserved, currently not used + uint32_t reserved_0; ///< reserved, currently not used + uint32_t reserved_1; ///< reserved, currently not used + uint32_t reserved_2; ///< reserved, currently not used + uint32_t reserved_3; ///< reserved, currently not used } XBP_LIMITS; +#define _mbg_swab_xbp_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->features ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + /** @@ -11835,6 +18054,14 @@ typedef struct } XBP_NODE_LIMITS; +#define _mbg_swab_xbp_node_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->node_count ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ +} while ( 0 ) + /** @@ -11876,6 +18103,17 @@ typedef struct } XBP_NODE_INFO; +#define _mbg_swab_xbp_node_info( _p ) \ +do \ +{ \ + _mbg_swab_xbp_addr( &(_p)->addr ); \ + _mbg_swab_receiver_info( &(_p)->ri ); \ + _mbg_swab8( &(_p)->state ); \ + _mbg_swab8( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + /** * @brief Information on an XBP node with specific index @@ -11889,11 +18127,375 @@ typedef struct } XBP_NODE_INFO_IDX; +#define _mbg_swab_xbp_node_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_xbp_node_info( &(_p)->node_info ); \ +} while ( 0 ) + + /** @} defgroup group_xbp */ -/*------------------------------------------------------------------------*/ +/** + * @defgroup group_tlv_api Meinberg TLV API definitions + * + * @note These structures and definitions are only supported by a device + * if ::MBG_XFEATURE_TLV_API is set in the extended device features. + * + * @{ */ + + +/** + * @brief A data type used to hold a unique ID (UID) for a TLV transaction + */ +typedef uint32_t MBG_TLV_UID; + +#define _mbg_swab_tlv_uid( _p ) \ + _mbg_swab32( _p ) + + + +/** + * @brief A data type to hold one of the ::MBG_TLV_TYPES or ::MBG_TLV_FEAT_TYPES + * + * @see ::MBG_TLV_TYPES + * @see ::MBG_TLV_FEAT_TYPES + */ +typedef uint32_t MBG_TLV_TYPE; + +#define _mbg_swab_tlv_type( _p ) \ + _mbg_swab32( _p ) + + + +/** + * @defgroup group_tlv_feat Meinberg TLV feature definitions + * + * @{ */ + + +/** + * @brief The maximum number of TLV feature types. + * + * Warning: Changing this number breaks API compatibility! + * + * @see ::MBG_TLV_FEAT_TYPES + */ +#define MAX_MBG_TLV_FEAT_TYPES 128 //### TODO Is this sufficient? + + +/** + * @brief Enumeration of known TLV feature types. + * + * TLV feature types are used to specify the content of a binary TLV message + * so that the receiver knows how to interpret the content. + * + * Used with ::MBG_TLV_INFO::supp_tlv_feat and ::MBG_TLV_DATA::type. ### TODO + * + * @see ::MBG_TLV_FEAT_BUFFER + * @see ::MBG_TLV_FEAT_TYPE_NAMES + * @see ::MBG_TLV_TYPES + * @see ::MBG_TLV_TYPE + */ +enum MBG_TLV_FEAT_TYPES +{ + /// Expects two TLV types in order: + /// 1) ::MBG_TLV_TYPE_STR => Firmware version as string + /// 2) ::MBG_TLV_TYPE_FILE => Firmware file as data blob + MBG_TLV_FEAT_TYPE_FW_UPDATE, + + /// If announce message's total bytes are 0, it is a diagnostics file + /// request. If its total bytes are not 0, TLV type ::MBG_TLV_TYPE_FILE + /// is expected and it should contain a file as data blob. + MBG_TLV_FEAT_TYPE_DIAG_FILE, + + /// Only used as action trigger on a remote site, expects no data. + MBG_TLV_FEAT_TYPE_FW_ROLLBACK, + + /// Expects two TLV types in order: + /// 1) ::MBG_TLV_TYPE_STR => Full qualified path including filename on target system + /// 2) ::MBG_TLV_TYPE_FILE => File as data blob + MBG_TLV_FEAT_TYPE_FILE_TRANSFER, + + /// 1) ::MBG_TLV_TYPE_STR => Command line call as string + MBG_TLV_FEAT_TYPE_EXEC_CMD, + + /// 1) ::MBG_TLV_TYPE_FILE => Encrypted license file as data blob + MBG_TLV_FEAT_TYPE_LICENSE_UPGRADE, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_LIMITS, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_LIMITS, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_PTPV2_IDX, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_PTPV2_IDX, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_NTP_IDX, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_NTP_IDX, + + /// Expects two TLV types in order: + /// 1) ::MBG_TLV_TYPE_STR => Full qualified path including filename on target system + MBG_TLV_FEAT_TYPE_FILE_REQUEST, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_PTPV1_IDX, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_PTPV1_IDX, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_TIME_MONITOR_IDX, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_TIME_MONITOR_IDX, + + N_MBG_TLV_FEAT_TYPES + // NOTE If new TLV feature types are appended here then an appropriate + // name string has to be appended to ::MBG_TLV_FEAT_TYPE_NAMES, and care must + // be taken that ::N_MBG_TLV_FEAT_TYPES doesn't exceed ::MAX_MBG_TLV_FEAT_TYPES. +}; + + +/** + * @brief Names of TLV API features + * + * Can be used to initialize a string array of ::N_MBG_TLV_FEAT_TYPES entries, + * so the number of strings must correspond to ::N_MBG_TLV_FEAT_TYPES. + * + * @see ::MBG_TLV_FEAT_TYPES + */ +#define MBG_TLV_FEAT_TYPE_NAMES \ +{ \ + "TLV Firmware Update", \ + "TLV Diagnostics File", \ + "TLV Firmware Rollback", \ + "TLV File Transfer", \ + "TLV Execute Command", \ + "TLV License Upgrade", \ + "TLV License Limits", \ + "TLV License PTPV2", \ + "TLV License NTP", \ + "TLV File Request", \ + "TLV License PTPV1 IDX", \ + "TLV License Time Monitor" \ +} + + + +/** + * @brief Array size required to store up to ::MAX_MBG_TLV_FEAT_TYPES bits + * + * The number of bytes required to store up to ::MAX_MBG_TLV_FEAT_TYPES + * feature bits in a byte array. + */ +#define MAX_MBG_TLV_FEAT_BYTES ( MAX_MBG_TLV_FEAT_TYPES / 8 ) + + +/** + * @brief A structure used to store a bit mask of supported TLV context types. + * + * Bit masks for up to ::MAX_MBG_TLV_FEAT_TYPES totally can be stored, + * but only ::N_MBG_TLV_FEAT_TYPES types are currently defined. + * The ::_set_tlv_feat_bit macro should be used by the firmware + * to set a bit mask in the buffer, and the ::check_tlv_feat_supp + * function should be used to implement API calls which test if an + * extended TLV context type is supported. + * + * @see ::_set_tlv_feat_bit + * @see ::check_tlv_feat_supp + */ +typedef struct +{ + uint8_t b[MAX_MBG_TLV_FEAT_BYTES]; + +} MBG_TLV_FEAT_BUFFER; + + + +/** + * @brief Set a TLV context type bit in a ::MBG_TLV_FEAT_BUFFER + * + * Should be used by the firmware only to set one of the ::MBG_TLV_FEAT_TYPES + * bits in an ::MBG_TLV_FEAT_BUFFER after power-up. + * + * @param[in] _tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] _tlv_feat_buffp Pointer to a ::MBG_TLV_FEAT_BUFFER + */ +#define _set_tlv_feat_bit( _tlv_feat_type, _tlv_feat_buffp ) \ + _set_array_bit( _tlv_feat_type, (_tlv_feat_buffp)->b, MAX_MBG_TLV_FEAT_BYTES ) + + +/** @} defgroup group_tlv_feat */ + + + +/** + * @brief A structure used to query current TLV capabilities + * + * This is only supported by a device if the ::MBG_XFEATURE_TLV_API bit + * is set in the extended device features. + */ +typedef struct +{ + uint32_t reserved; ///< Future use + uint32_t flags; ///< Future use + MBG_TLV_FEAT_BUFFER supp_tlv_feat; ///< A byte array of supported TLV feature bits, see ::MBG_TLV_FEAT_TYPES + +} MBG_TLV_INFO; + +#define _mbg_swab_tlv_info( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of known TLV types + * + * Used with ::MBG_TLV_TYPE types, e.g. in ::MBG_TLV_HDR::tlv_type + * or ::MBG_TLV_DATA::type. + * + * @see ::MBG_TLV_FEAT_TYPES + * @see ::MBG_TLV_TYPE + */ +enum MBG_TLV_TYPES +{ + MBG_TLV_TYPE_STR, + MBG_TLV_TYPE_FILE, + MBG_TLV_TYPE_BLOB, ///< In fact, a file is also a blob but + ///< give the child a different name to avoid confusion. + ///< Use this for getting/setting fixed structures! + N_MBG_TLV_TYPES +}; + + + +/** + * @brief General TLV data structure + * + * Structure containing common, additional data required to send + * an announce message for following TLVs. + */ +typedef struct +{ + MBG_TLV_UID uid; ///< Unique ID identifying following TLVs, 0 if empty/not set. + MBG_TLV_TYPE type; ///< One of the ::MBG_TLV_TYPES or ::MBG_TLV_FEAT_TYPES depending on the type of message. + uint32_t total_bytes; ///< Number of all bytes including header(s) that are related to a TLV block transaction. + uint32_t reserved_1; ///< Reserved for future use + +} MBG_TLV_DATA; + +#define _mbg_swab_tlv_data( _p ) \ +do \ +{ \ + _mbg_swab_tlv_uid( &(_p)->uid ); \ + _mbg_swab_tlv_type( &(_p)->type ); \ + _mbg_swab32( &(_p)->total_bytes ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ +} while ( 0 ) + + + +/** + * @brief Structure containing state information while reading TLV data. + */ +typedef struct +{ + MBG_TLV_DATA data; ///< See ::MBG_TLV_DATA + uint32_t read_bytes; ///< Number of bytes read + uint32_t reserved_1; ///< Future use + +} MBG_TLV_RCV_STATE; + + + +/** + * @brief A structure initiating a TLV transfer + * + * ::MBG_TLV_ANNOUNCE should be sent first, before starting a + * TLV transfer, to inform the remote site about following TLVs. + * Following sequence of TLVs is not fixed and implementation + * dependent. + */ +typedef struct +{ + MBG_TLV_DATA data; ///< See ::MBG_TLV_DATA + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + +} MBG_TLV_ANNOUNCE; + +#define _mbg_swab_tlv_announce( _p ) \ +do \ +{ \ + _mbg_swab_tlv_data( &(_p)->data ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +#define MSG_TLV_MAX_VALUE_SIZE 480 + +/** + * @brief TLV header structure containing information on current TLV transaction + */ +typedef struct +{ + MBG_TLV_UID uid; ///< Unique source ID. See ::MBG_TLV_DATA::uid + MBG_TLV_UID tlv_type; ///< "Subtype" identifying current TLV, see ::MBG_TLV_TYPES + uint32_t cur_bytes; ///< Number of bytes in ::MBG_TLV::value + uint32_t trans_bytes; ///< Number of bytes transferred so far related to this TLV type. + uint32_t total_bytes; ///< Number of total bytes (size) of this TLV type without header. + ///< It is fixed and must not be changed during a TLV transaction. + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + +} MBG_TLV_HDR; + +#define _mbg_swab_tlv_header( _p ) \ +do \ +{ \ + _mbg_swab_tlv_uid( &(_p)->uid ); \ + _mbg_swab_tlv_type( &(_p)->tlv_type ); \ + _mbg_swab32( &(_p)->cur_bytes ); \ + _mbg_swab32( &(_p)->trans_bytes ); \ + _mbg_swab32( &(_p)->total_bytes ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief TLV structure containing information on current TLV transaction and its current data. + */ +typedef struct +{ + MBG_TLV_HDR hdr; ///< See ::MBG_TLV_HDR + uint8_t value[MSG_TLV_MAX_VALUE_SIZE]; ///< See ::MSG_TLV_MAX_VALUE_SIZE + +} MBG_TLV; + +#define _mbg_swab_tlv( _p ) \ +do \ +{ \ + _mbg_swab_tlv_header( &(_p)->hdr ); \ +} while ( 0 ) + +/** @} defgroup group_tlv_api */ + + + +/** + * @defgroup group_gps_nav_data Definitions used with navigational data received from GPS satellites + * + * @note These structures and definitions are only supported by a device + * if ::GPS_MODEL_IS_GPS is set in the @ref GPS_BUILTIN_FEATURE_MASKS + * + * @{ */ + /** * @brief Ephemeris parameters of one specific satellite @@ -12047,6 +18649,7 @@ typedef struct } UTC; #define _mbg_swab_utc_parm( _p ) \ +do \ { \ _mbg_swab_csum( &(_p)->csum ); \ _mbg_swab16( &(_p)->valid ); \ @@ -12055,7 +18658,7 @@ typedef struct _mbg_swab_double( &(_p)->A1 ); \ _mbg_swab16( &(_p)->WNlsf ); \ _mbg_swab16( &(_p)->DNt ); \ -} +} while ( 0 ) @@ -12092,6 +18695,8 @@ typedef struct } ASCII_MSG; +/** @} defgroup group_gps_nav_data */ + enum GPS_PLATFORMS @@ -12149,6 +18754,7 @@ typedef struct } NAV_TIME_MODE_SETTINGS; + /** * Navigation Engine settings to set configuration * parameters of a dynamic platform model. @@ -12168,6 +18774,2906 @@ typedef struct } NAV_ENGINE_SETTINGS; + +/** + * @defgroup group_led_api Meinberg TLV API definitions + * + * @note These structures and definitions are only supported by a device + * if ::MBG_XFEATURE_LED_API is set in the extended device features. + * + * @{ */ + + +/** + * @brief General LED info to be read from a device + * + * Used to query from a device how many LEDs are supported + * by the device, then index 0..::MBG_LED_LIMITS::num_leds-1 + * ::MBG_LED_INFO_IDX or ::MBG_LED_SETTINGS_IDX structures + * can be read from or written to the device. + * + * @see ::MBG_LED_SETTINGS_IDX + * @see ::MBG_LED_INFO_IDX + */ +typedef struct +{ + uint8_t num_leds; ///< Number of supported LEDs, see ::MBG_LED_SETTINGS_IDX::idx and ::MBG_LED_INFO_IDX::idx + uint8_t reserved_0; ///< Currently reserved, unused, always 0 + uint16_t reserved_1; ///< Currently reserved, unused, always 0 + uint32_t reserved_2; ///< Currently reserved, unused, always 0 + +} MBG_LED_LIMITS; + +#define _mbg_swab_mbg_led_limits( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->num_leds ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +/** + * @brief Possible modes of LEDs + * + * Used with ::MBG_LED_SETTINGS::mode + * + * @see ::MBG_LED_MODE_MASKS + */ +enum MBG_LED_MODES +{ + MBG_LED_MODE_OFF, + MBG_LED_MODE_ON, + MBG_LED_MODE_FLASH, + MBG_LED_MODE_FLASH_5S, + N_MBG_LED_MODES +}; + + + +/** + * @brief Bit masks associated with LED modes + * + * Used with ::MBG_LED_INFO::supp_modes + * + * @see ::MBG_LED_MODES + */ +enum MBG_LED_MODE_MASKS +{ + MBG_LED_MODE_MASK_OFF = ( 1UL << MBG_LED_MODE_OFF ), ///< see ::MBG_LED_MODE_OFF + MBG_LED_MODE_MASK_ON = ( 1UL << MBG_LED_MODE_ON ), ///< see ::MBG_LED_MODE_ON + MBG_LED_MODE_MASK_FLASH = ( 1UL << MBG_LED_MODE_FLASH ), ///< see ::MBG_LED_MODE_FLASH + MBG_LED_MODE_MASK_FLASH_5S = ( 1UL << MBG_LED_MODE_FLASH_5S ) ///< see ::MBG_LED_MODE_FLASH_5S +}; + + +/** + * @brief Names of LED modes + * + * Can be used to initialize a string array of ::N_MBG_LED_MODES entries, + * so the number of strings must correspond to ::N_MBG_LED_MODES. + * + * @see ::MBG_LED_MODES + * @see ::MBG_LED_MODE_MASKS + */ +#define MBG_LED_MODE_STRS \ +{ \ + "Off", \ + "On", \ + "Flash", \ + "Flash 5s" \ +} + + + +/** + * @brief Possible colors of LEDs + * + * Used with ::MBG_LED_SETTINGS::color + * + * @see ::MBG_LED_COLOR_MASKS + */ +enum MBG_LED_COLORS +{ + MBG_LED_COLOR_GREEN, + MBG_LED_COLOR_RED, + MBG_LED_COLOR_YELLOW, + MBG_LED_COLOR_BLUE, + N_MBG_LED_COLORS +}; + + + +/** + * @brief Bit masks of possible LED colors + * + * Used with ::MBG_LED_INFO::supp_colors + * + * @see ::MBG_LED_COLORS + */ +enum MBG_LED_COLOR_MASKS +{ + MBG_LED_COLOR_MASK_GREEN = ( 1UL << MBG_LED_COLOR_GREEN ), ///< see ::MBG_LED_COLOR_GREEN + MBG_LED_COLOR_MASK_RED = ( 1UL << MBG_LED_COLOR_RED ), ///< see ::MBG_LED_COLOR_RED + MBG_LED_COLOR_MASK_YELLOW = ( 1UL << MBG_LED_COLOR_YELLOW ), ///< see ::MBG_LED_COLOR_YELLOW + MBG_LED_COLOR_MASK_BLUE = ( 1UL << MBG_LED_COLOR_BLUE ) ///< see ::MBG_LED_COLOR_BLUE +}; + + + +/** + * @brief Names of LED colors + * + * Can be used to initialize a string array of ::N_MBG_LED_COLORS entries, + * so the number of strings must correspond to ::N_MBG_LED_COLORS. + * + * @see ::MBG_LED_COLORS + * @see ::MBG_LED_COLOR_MASKS + */ +#define MBG_LED_COLOR_STRS \ +{ \ + "Green", \ + "Red", \ + "Yellow", \ + "Blue" \ +} + + + +/** + * @brief Configuration settings for a single LED + * + * @see ::MBG_LED_SETTINGS_IDX + */ +typedef struct +{ + uint8_t mode; ///< LED mode, see ::MBG_LED_MODES + uint8_t color; ///< LED color, see ::MBG_LED_COLORS + uint16_t reserved; ///< Currently reserved, unused, always 0 + +} MBG_LED_SETTINGS; + +#define _mbg_swab_mbg_led_settings( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->mode ); \ + _mbg_swab8( &(_p)->color ); \ + _mbg_swab16( &(_p)->reserved ); \ +} while ( 0 ) + + + +/** + * @brief Configuration settings for a single LED, plus index + * + * @see ::MBG_LED_SETTINGS + * @see ::MBG_LED_LIMITS + */ +typedef struct +{ + uint16_t idx; ///< 0..::MBG_LED_LIMITS::num_leds-1 + MBG_LED_SETTINGS settings; ///< LED settings + +} MBG_LED_SETTINGS_IDX; + +#define _mbg_swab_mbg_led_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_led_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of an LED + * + * This structure should be read from the device to retrieve the + * current settings of an LED plus its capabilities, e.g. the + * supported modes, colors, etc. + * + * @see ::MBG_LED_INFO_IDX + */ +typedef struct +{ + MBG_LED_SETTINGS settings; ///< Current LED settings + uint32_t supp_modes; ///< Supported modes, see ::MBG_LED_MODE_MASKS + uint32_t supp_colors; ///< Supported colors, see ::MBG_LED_COLOR_MASKS + uint32_t reserved; ///< Currently reserved, unused, always 0 + uint32_t flags; ///< Currently reserved, unused, always 0 + +} MBG_LED_INFO; + +#define _mbg_swab_mbg_led_info( _p ) \ +do \ +{ \ + _mbg_swab_mbg_led_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_modes ); \ + _mbg_swab32( &(_p)->supp_colors ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of an LED, plus index + * + * @see ::MBG_LED_INFO + * @see ::MBG_LED_LIMITS + */ +typedef struct +{ + uint16_t idx; ///< 0..::MBG_LED_LIMITS::num_leds-1 + MBG_LED_INFO info; ///< LED info + +} MBG_LED_INFO_IDX; + +#define _mbg_swab_mbg_led_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_led_info( &(_p)->info ); \ +} while ( 0 ) + +/** @} defgroup group_led_api */ + + + +/** + * @defgroup group_lne_api Definitions specific to LNE devices + * + * @note These structures and definitions are only supported by a device + * if ::MBG_XFEATURE_LNE_API is set in the extended device features. + * + * @{ */ + + +/** + * @brief General info to be read from an LNE device + * + * Used to query from a device e.g. how many LNE ports are provided + * by the device, then index 0..::MBG_LNE_LIMITS::num_ports-1 + * ::MBG_LNE_PORT_INFO_IDX or ::MBG_LNE_PORT_SETTINGS_IDX structures + * can be read from or written to the device. + * + * @see ::MBG_LNE_PORT_SETTINGS_IDX + * @see ::MBG_LNE_PORT_INFO_IDX + */ +typedef struct +{ + uint8_t num_ports; ///< Number of supported ports, see ::MBG_LNE_PORT_SETTINGS_IDX::idx and ::MBG_LNE_PORT_INFO_IDX::idx + uint8_t reserved_0; ///< Currently reserved, unused, always 0 + uint16_t reserved_1; ///< Currently reserved, unused, always 0 + uint32_t features; // ### TODO Mask of supported features, see ::MBG_LNE_FEAT_MASKS + ///< Currently reserved, unused, always 0 + uint32_t reserved_2; ///< Currently reserved, unused, always 0 + +} MBG_LNE_LIMITS; + +#define _mbg_swab_mbg_lne_limits( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->num_ports ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->features ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +#if 0 //### TODO //################# + +/** + * @brief LNE feature bits + * + * Used to define ::MBG_LNE_FEAT_MASKS + * + * @see ::MBG_LNE_FEAT_MASKS + */ +enum MBG_LNE_FEAT_BITS +{ + MBG_LNE_FEAT_BIT_SWITCH_PWR, ///< Power switching off all LNE ports at once supported, see ::MBG_LNE_PWR_STATE + N_MBG_LNE_FEAT_BITS +}; + + + +/** + * @brief LNE feature bit masks + * + * Used with ::MBG_LNE_LIMITS::features + * + * @see ::MBG_LNE_FEAT_BITS + */ +enum MBG_LNE_FEAT_MASKS +{ + MBG_LNE_FEAT_MASK_SWITCH_PWR = ( 1UL << MBG_LNE_FEAT_BIT_SWITCH_PWR ) ///< see ::MBG_LNE_FEAT_BIT_SWITCH_PWR +}; + +#endif + + + +/** + * @brief Configuration settings for a single LNE port + * + * @see ::MBG_LNE_PORT_SETTINGS_IDX + */ +typedef struct +{ + uint32_t reserved_0; ///< currently reserved, unused, always 0 + uint32_t reserved_1; ///< currently reserved, unused, always 0 + uint32_t reserved_2; ///< currently reserved, unused, always 0 + uint32_t flags; ///< currently reserved, unused, always 0 + +} MBG_LNE_PORT_SETTINGS; + +#define _mbg_swab_mbg_lne_port_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Configuration settings for a single LNE port, plus index + * + * @see ::MBG_LNE_PORT_SETTINGS + * @see ::MBG_LNE_LIMITS + */ +typedef struct +{ + uint16_t idx; ///< 0..::MBG_LNE_LIMITS::num_ports-1 + MBG_LNE_PORT_SETTINGS settings; ///< LNE settings + +} MBG_LNE_PORT_SETTINGS_IDX; + +#define _mbg_swab_mbg_lne_port_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_lne_port_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of an LNE port + * + * This structure should be read from the device to retrieve the + * current settings of an LNE port plus its capabilities, ### e.g. the + * supported modes, colors, etc. + * + * @see ::MBG_LNE_PORT_INFO_IDX + */ +typedef struct +{ + MBG_LNE_PORT_SETTINGS settings; ///< Current LNE port settings + MBG_MAC_ADDR mac_addr; ///< The MAC address assigned to this port + uint32_t reserved_0; ///< currently reserved, unused, always 0 + uint32_t reserved_1; ///< currently reserved, unused, always 0 + uint32_t reserved_2; ///< currently reserved, unused, always 0 + uint32_t flags; ///< see ::LNE_PORT_FLAG_MASKS + +} MBG_LNE_PORT_INFO; + +#define _mbg_swab_mbg_lne_port_info( _p ) \ +do \ +{ \ + _mbg_swab_mbg_lne_port_settings( &(_p)->settings ); \ + _mbg_swab_mbg_mac_addr( &(_p)->mac_addr ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of an LNE port, plus index + * + * @see ::MBG_LNE_PORT_INFO + * @see ::MBG_LNE_LIMITS + */ +typedef struct +{ + uint16_t idx; ///< 0..::MBG_LED_LIMITS::num_leds-1 + MBG_LNE_PORT_INFO info; ///< LNE port info + +} MBG_LNE_PORT_INFO_IDX; + +#define _mbg_swab_mbg_lne_port_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_lne_port_info( &(_p)->info ); \ +} while ( 0 ) + + + +/** + * @brief LNE port flag bits + * + * Used to define ::LNE_PORT_FLAG_MASKS + * + * @see ::LNE_PORT_FLAG_MASKS + */ +enum LNE_PORT_FLAG_BITS +{ + LNE_PORT_FLAG_BIT_IS_SFP, + N_LNE_PORT_FLAG_BITS +}; + + + +/** + * @brief LNE port flag bit masks + * + * Used with ::MBG_LNE_PORT_INFO::flags + * + * @see ::LNE_PORT_FLAG_BITS + */ +enum LNE_PORT_FLAG_MASKS +{ + LNE_PORT_FLAG_MASK_IS_SFP = ( 1UL << LNE_PORT_FLAG_BIT_IS_SFP ) ///< see ::LNE_PORT_FLAG_BIT_IS_SFP +}; + + +/** @} defgroup group_lne_api */ + + + +/** + * @defgroup group_pwr_ctl_api Definitions for power control API + * + * @note These structures and definitions are only supported by a device + * if ::MBG_XFEATURE_PWR_CTL_API is set in the extended device features. + * + * @{ */ + + +/** + * @brief Device power states + * + * Used with ::MBG_PWR_CTL::state. + */ +enum MBG_PWR_STATES +{ + MBG_PWR_STATE_OFF, + MBG_PWR_STATE_ON, + N_MBG_PWR_STATES +}; + + + +/** + * @brief Device power control + * + * Used to change or retrieve a device's power state + */ +typedef struct +{ + uint8_t state; ///< see ::MBG_PWR_STATES + uint8_t reserved_0; ///< Currently reserved, unused, always 0 + uint16_t reserved_1; ///< Currently reserved, unused, always 0 + +} MBG_PWR_CTL; + +#define _mbg_swab_mbg_pwr_ctl( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->state ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ +} while ( 0 ) + +/** @} defgroup group_pwr_ctl_api */ + + + + +/** + * @defgroup group_ext_sys_info Extended system information + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_EXT_SYS_INFO is set in the extended device features. + * + * @{ */ + + +/** + * @brief Bits used to define ::MBG_EXT_SYS_INFO_MSKS + * + * @see ::MBG_EXT_SYS_INFO_MSKS + */ +enum MBG_EXT_SYS_INFO_BITS +{ + MBG_EXT_SYS_INFO_BIT_SW_REV, + MBG_EXT_SYS_INFO_BIT_HW_REV, + MBG_EXT_SYS_INFO_BIT_OS_REV, + MBG_EXT_SYS_INFO_BIT_FPGA_REV, + MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV, + N_MBG_EXT_SYS_INFO_BITS +}; + + + +/** + * @brief Bit masks of supported revision numbers + * + * Used with ::MBG_EXT_SYS_INFO::supp_members + * + * @see ::MBG_EXT_SYS_INFO_BITS + */ +enum MBG_EXT_SYS_INFO_MSKS +{ + MBG_EXT_SYS_INFO_MSK_SW_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_SW_REV ), ///< see ::MBG_EXT_SYS_INFO_BIT_SW_REV + MBG_EXT_SYS_INFO_MSK_HW_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_HW_REV ), ///< see ::MBG_EXT_SYS_INFO_BIT_HW_REV + MBG_EXT_SYS_INFO_MSK_OS_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_OS_REV ), ///< see ::MBG_EXT_SYS_INFO_BIT_OS_REV + MBG_EXT_SYS_INFO_MSK_FPGA_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_FPGA_REV ), ///< see ::MBG_EXT_SYS_INFO_BIT_FPGA_REV + MBG_EXT_SYS_INFO_MSK_CORE_MOD_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV ) ///< see ::MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV +}; + + +enum MBG_EXT_SYS_INFO_PROC_TYPES +{ + MBG_EXT_SYS_INFO_PROC_TYPE_NONE, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_A9, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_SAM3u, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_SAM3s, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_STM32F4, + N_MBG_EXT_SYS_INFO_PROC_TYPES +}; + +#define MBG_EXT_SYS_INFO_PROC_STRS \ +{ \ + "None", \ + "Cortex A9", \ + "Cortex SAM3u", \ + "Cortex SAM3s", \ + "Cortex STM32F4" \ +} + +enum MBG_EXT_SYS_INFO_FPGA_TYPES +{ + MBG_EXT_SYS_INFO_FPGA_TYPE_NONE, + MBG_EXT_SYS_INFO_FPGA_TYPE_CYCLONE5_SOC, ///< System on chip + MBG_EXT_SYS_INFO_FPGA_TYPE_CYCLONE5, ///< Stand alone FPGA + MBG_EXT_SYS_INFO_FPGA_TYPE_CYCLONE4GX15, + MBG_EXT_SYS_INFO_FPGA_TYPE_CYLCONE4CE22, + N_MBG_EXT_SYS_INFO_FPGA_TYPES +}; + +#define MBG_EXT_SYS_INFO_FPGA_STRS \ +{ \ + "None", \ + "Cyclone5 SoC", \ + "Cyclone5", \ + "Cyclone4GX15", \ + "Cyclone4CE22" \ +} + +enum MBG_EXT_SYS_INFO_CORE_MOD_TYPES +{ + MBG_EXT_SYS_INFO_CORE_MOD_TYPE_NONE, + MBG_EXT_SYS_INFO_CORE_MOD_TYPE_UBX_LEA_M8F, ///< u-blox GNSS module without Galileo support + MBG_EXT_SYS_INFO_CORE_MOD_TYPE_UBX_LEA_M8T, ///< u-blox GNSS module with Galileo support + N_MBG_EXT_SYS_INFO_CORE_MOD_TYPES +}; + +#define MBG_EXT_SYS_INFO_CORE_MOD_STRS \ +{ \ + "None", \ + "u-blox LEA-M8F", \ + "u-blox LEA-M8T" \ +} + +typedef struct +{ + uint32_t supp_members; ///< ::MBG_EXT_SYS_INFO_MSKS + + uint32_t sw_rev; + uint32_t hw_rev; + uint32_t os_rev; + uint32_t fpga_rev; + + uint16_t proc_type; ///< See ::MBG_EXT_SYS_INFO_PROC_TYPES + uint16_t fpga_type; ///< See ::MBG_EXT_SYS_INFO_FPGA_TYPES + uint16_t core_mod_type; ///< See ::MBG_EXT_SYS_INFO_CORE_MOD_TYPES + uint16_t reserved; + + uint32_t core_mod_rev; + + /* Reserved for future use, currently 0 */ + uint32_t reserved_rev_3; + uint32_t reserved_rev_4; + uint32_t reserved_rev_5; + uint32_t reserved_rev_6; + uint32_t reserved_rev_7; + uint32_t reserved_rev_8; + uint32_t reserved_rev_9; + uint32_t reserved_rev_10; + uint32_t reserved_rev_11; + +} MBG_EXT_SYS_INFO; + +#define _mbg_swab_ext_sys_info( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab32( &(_p)->sw_rev ); \ + _mbg_swab32( &(_p)->hw_rev ); \ + _mbg_swab32( &(_p)->os_rev ); \ + _mbg_swab32( &(_p)->fpga_rev ); \ + _mbg_swab16( &(_p)->proc_type ); \ + _mbg_swab16( &(_p)->fpga_type ); \ + _mbg_swab16( &(_p)->core_mod_type ); \ + _mbg_swab16( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->core_mod_rev ); \ +} while ( 0 ) + + +#define _mbg_encode_revision( _major, _minor, _patch ) \ + ( ( (_major) << 24) | ( (_minor) << 16 ) | (_patch) ) + + +#define _mbg_decode_revision( _rev, _major, _minor, _patch ) \ +{ \ + (_major) = ( (_rev) >> 24 ) & 0xff; \ + (_minor) = ( (_rev) >> 16 ) & 0xff; \ + (_patch) = (_rev) & 0xffff; \ +} + + +/** @} defgroup group_ext_sys_info */ + + +/** + * @defgroup group_license_limits License information + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_LICENSE_LIMITS is set in the extended device features. + * + * @{ */ + + +#define MBG_MAX_LICENSES 32 + + +/** + * @brief General license information to be read from a device + * + * Used to query from a device how many and which different license types + * are supported. If a special type is supported (licenses[MBG_LICENSE_BASE_TYPES] > 0), its + * license specific information can be queried from 0..licenses[MBG_LICENSE_BASE_TYPES]-1 via + * its license specific [...]_IDX structures and TLV API command codes. + * See ::MBG_XFEATURE_TLV_API and ::MBG_TLV_FEAT_TYPES. + */ +typedef struct +{ + uint8_t licenses[MBG_MAX_LICENSES]; ///< To get the number of supported licenses + ///< of a specific type you need to access the array + ///< with the specififc license index defined at ::MBG_LICENSE_BASE_TYPES. +} MBG_LICENSE_LIMITS; + + +enum MBG_LICENSE_BASE_TYPES +{ + MBG_LICENSE_BASE_TYPE_PTPV2, + MBG_LICENSE_BASE_TYPE_NTP, + MBG_LICENSE_BASE_TYPE_PTPV1, + MBG_LICENSE_BASE_TYPE_TIME_MONITOR, + N_MBG_LICENSE_BASE_TYPES +}; + + +/** + * @brief Bits used to define ::MBG_LICENSE_BASE_MSKS + * + * @see ::MBG_LICENSE_BASE_MSKS + */ +enum MBG_LICENSE_BASE_FLAGS +{ + MBG_LICENSE_BASE_FLAG_SUPP_UPGRADE, ///< License supports upgrading / modifying + N_MBG_LICENSE_BASE_FLAGS +}; + + +/** + * @brief Bit masks of common supported base license flags + * + * Used with ::MBG_LICENSE_BASE::supp_flags + * + * @see ::MBG_LICENSE_BASE_FLAGS + */ +enum MBG_LICENSE_BASE_MSKS +{ + MBG_LICENSE_BASE_MSK_SUPP_UPGRADE = ( 1UL << MBG_LICENSE_BASE_FLAG_SUPP_UPGRADE ) ///< See ::MBG_LICENSE_BASE_FLAG_SUPP_UPGRADE +}; + + +/** + * @brief Common license information + * + * Should be part of each individual license type. + */ +typedef struct +{ + uint8_t type; ///< See ::MBG_LICENSE_BASE_TYPES + uint8_t reserved_1; ///< Reserved for future use, currently 0 + uint16_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t supp_flags; ///< See ::MBG_LICENSE_BASE_MSKS + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_BASE; + +#define _mbg_swab_license_base( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + +/** + * @brief Bits used to define ::MBG_LICENSE_PTPV2_MEMBER_MSKS + * + * @see ::MBG_LICENSE_PTPV2_MEMBER_MSKS + */ +enum MBG_LICENSE_PTPV2_MEMBERS +{ + MBG_LICENSE_PTPV2_MEMBER_MAX_UCLIENTS, + MBG_LICENSE_PTPV2_MEMBER_MAX_MTRANS, + N_MBG_LICENSE_PTPV2_MEMBERS +}; + + +/** + * @brief Bit masks of PTPV2 license specific members + * + * Used with ::MBG_LICENSE_PTPV2::supp_members + * + * @see ::MBG_LICENSE_PTPV2_MEMBERS + */ +enum MBG_LICENSE_PTPV2_MEMBER_MSKS +{ + MBG_LICENSE_PTPV2_MEMBER_MSK_MAX_UCLIENTS = ( 1UL << MBG_LICENSE_PTPV2_MEMBER_MAX_UCLIENTS ), ///< See ::MBG_LICENSE_PTPV2_MEMBER_MAX_UCLIENTS + MBG_LICENSE_PTPV2_MEMBER_MSK_MAX_MTRANS = ( 1UL << MBG_LICENSE_PTPV2_MEMBER_MAX_MTRANS ) ///< See ::MBG_LICENSE_PTPV2_MEMBER_MAX_MTRANS +}; + + +/** + * @brief PTPV2 specific license information + * + */ +typedef struct +{ + MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE + uint32_t supp_members; ///< See ::MBG_LICENSE_PTPV2_MEMBER_MSKS + uint32_t reserved_1; ///< Reserved for future use, currently 0 + uint16_t max_uclients; ///< Maximal number of supported unicast clients. + uint16_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t max_mtrans; ///< Maximal number of supported multicast transactions per second. + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + uint32_t reserved_5; ///< Reserved for future use, currently 0 + uint32_t reserved_6; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_PTPV2; + +#define _mbg_swab_license_ptpv2( _p ) \ +do \ +{ \ + _mbg_swab_license_base( &(_p)->base ); \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab16( &(_p)->max_uclients ); \ + _mbg_swab32( &(_p)->max_mtrans ); \ +} while ( 0 ) + + +typedef struct +{ + uint32_t idx; + MBG_LICENSE_PTPV2 license; + +} MBG_LICENSE_PTPV2_IDX; + +#define _mbg_swab_license_ptpv2_idx( _p ) \ +do \ +{ \ + _mbg_swab_license_ptpv2( &(_p)->license ); \ + _mbg_swab32( &(_p)->idx ); \ +} while ( 0 ) + + +/** + * @brief Bits used to define ::MBG_LICENSE_NTP_MEMBER_MSKS + * + * @see ::MBG_LICENSE_NTP_MEMBER_MSKS + */ +enum MBG_LICENSE_NTP_MEMBERS +{ + MBG_LICENSE_NTP_MEMBER_MAX_RPS, + N_MBG_LICENSE_NTP_MEMBERS +}; + + +/** + * @brief Bit masks of NTP license specific members + * + * Used with ::MBG_LICENSE_NTP::supp_members + * + * @see ::MBG_LICENSE_PTPV2_MEMBERS + */ +enum MBG_LICENSE_NTP_MEMBER_MSKS +{ + MBG_LICENSE_NTP_MEMBER_MSK_MAX_RPS = ( 1UL << MBG_LICENSE_NTP_MEMBER_MAX_RPS ) ///< See ::MBG_LICENSE_NTP_MEMBER_MAX_RPS +}; + + +/** + * @brief NTP specific license information + */ +typedef struct +{ + MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE + uint32_t supp_members; ///< See ::MBG_LICENSE_NTP_MEMBER_MSKS + uint32_t max_rps; ///< Maximum number of supported NTP requests per second + uint32_t reserved_1; ///< Reserved for future use, currently 0 + uint32_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + uint32_t reserved_5; ///< Reserved for future use, currently 0 + uint32_t reserved_6; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_NTP; + +#define _mbg_swab_license_ntp( _p ) \ +do \ +{ \ + _mbg_swab_license_base( &(_p)->base ); \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab32( &(_p)->max_rps ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + MBG_LICENSE_NTP license; + +} MBG_LICENSE_NTP_IDX; + +#define _mbg_swab_license_ntp_idx( _p ) \ +do \ +{ \ + _mbg_swab_license_ntp( &(_p)->license ); \ + _mbg_swab32( &(_p)->idx ); \ +} while ( 0 ) + +/** + * @brief Bits used to define ::MBG_LICENSE_PTPV1_MEMBER_MSKS + * + * @see ::MBG_LICENSE_PTPV1_MEMBER_MSKS + */ +enum MBG_LICENSE_PTPV1_MEMBERS +{ + MBG_LICENSE_PTPV1_MEMBER_MAX_RPS, + N_MBG_LICENSE_PTPV1_MEMBERS +}; + + +/** + * @brief Bit masks of PTPV1 license specific members + * + * Used with ::MBG_LICENSE_PTPV1::supp_members + * + * @see ::MBG_LICENSE_PTPV2_MEMBERS + */ +enum MBG_LICENSE_PTPV1_MEMBER_MSKS +{ + MBG_LICENSE_PTPV1_MEMBER_MSK_MAX_RPS = ( 1UL << MBG_LICENSE_PTPV1_MEMBER_MAX_RPS ) ///< See ::MBG_LICENSE_PTPV1_MEMBER_MAX_RPS +}; + + +/** + * @brief NTP specific license information + */ +typedef struct +{ + MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE + uint32_t supp_members; ///< See ::MBG_LICENSE_PTPV1_MEMBER_MSKS + uint32_t max_rps; ///< Maximum number of supported PTPv1 delay requests per second + uint32_t reserved_1; ///< Reserved for future use, currently 0 + uint32_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + uint32_t reserved_5; ///< Reserved for future use, currently 0 + uint32_t reserved_6; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_PTPV1; + +#define _mbg_swab_license_ptpv1( _p ) \ +do \ +{ \ + _mbg_swab_license_base( &(_p)->base ); \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab32( &(_p)->max_rps ); \ +} while ( 0 ) + + +typedef struct +{ + uint32_t idx; + MBG_LICENSE_PTPV1 license; + +} MBG_LICENSE_PTPV1_IDX; + +#define _mbg_swab_license_ptpv1_idx( _p ) \ +do \ +{ \ + _mbg_swab_license_ptpv1( &(_p)->license ); \ + _mbg_swab32( &(_p)->idx ); \ +} while ( 0 ) + +/** + * @brief Bits used to define ::MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS + * + * @see ::MBG_LICENSE_TIME:MONITOR_MEMBER_MSKS + */ +enum MBG_LICENSE_TIME_MONITOR_MEMBERS +{ + MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_PTPV2_CLIENTS, + MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_NTP_CLIENTS, + N_MBG_LICENSE_TIME_MONITOR_MEMBERS +}; + + +/** + * @brief Bit masks of Time Monitor license specific members + * + * Used with ::MBG_LICENSE_TIME_MONITOR::supp_members + * + * @see ::MBG_LICENSE_TIME_MONITOR_MEMBERS + */ +enum MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS +{ + MBG_LICENSE_TIME_MONITOR_MEMBER_MSK_MAX_PTPV2_CLIENTS = ( 1UL << MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_PTPV2_CLIENTS ), ///< See ::MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_PTPV2_CLIENTS + MBG_LICENSE_TIME_MONITOR_MEMBER_MSK_MAX_NTP_CLIENTS = ( 1UL << MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_NTP_CLIENTS ) ///< See ::MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_NTP_CLIENTS +}; + + +/** + * @brief Time Monitor specific license information + * + */ +typedef struct +{ + MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE + uint32_t supp_members; ///< See ::MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS + uint32_t reserved_1; ///< Reserved for future use, currently 0 + uint16_t max_ptpv2_clients; ///< Maximum number of supported PTPv2 clients to be monitored + uint16_t max_ntp_clients; ///< Maximum number of supported NTP clients to be monitored + uint32_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + uint32_t reserved_5; ///< Reserved for future use, currently 0 + uint32_t reserved_6; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_TIME_MONITOR; + +#define _mbg_swab_license_time_monitor( _p ) \ +do \ +{ \ + _mbg_swab_license_base( &(_p)->base ); \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab16( &(_p)->max_ptpv2_clients ); \ + _mbg_swab16( &(_p)->max_ntp_clients ); \ +} while ( 0 ) + + +typedef struct +{ + uint32_t idx; + MBG_LICENSE_TIME_MONITOR license; + +} MBG_LICENSE_TIME_MONITOR_IDX; + +#define _mbg_swab_license_time_monitor_idx( _p ) \ +do \ +{ \ + _mbg_swab_license_time_monitor( &(_p)->license ); \ + _mbg_swab32( &(_p)->idx ); \ +} while ( 0 ) + +/** @} defgroup group_license_limits */ + + + +/** + * @defgroup group_clk_res_info Clock resolution info + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_CLK_RES_INFO is set in the extended device features. + * + * @{ */ + +/** + * @brief Clock resolution information + * + * @see @ref group_clk_res_info + */ +typedef struct +{ + uint32_t base_clk; ///< Base clock of the internal time base [MHz] + uint32_t num_clk_phase; ///< Number of multi-phase clock signals + uint32_t reserved_9; + uint32_t reserved_8; + uint32_t reserved_7; + uint32_t reserved_6; + uint32_t reserved_5; + uint32_t reserved_4; + uint32_t reserved_3; + uint32_t reserved_2; + uint32_t reserved_1; + uint32_t reserved_0; + +} MBG_CLK_RES_INFO; + +#define _mbg_swab_mbg_clk_res_info( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->base_clk ); \ + _mbg_swab32( &(_p)->num_clk_phase ); \ + _mbg_swab32( &(_p)->reserved_9 ); \ + _mbg_swab32( &(_p)->reserved_8 ); \ + _mbg_swab32( &(_p)->reserved_7 ); \ + _mbg_swab32( &(_p)->reserved_6 ); \ + _mbg_swab32( &(_p)->reserved_5 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ +} while ( 0 ) + +/** @} defgroup group_clk_res_info */ + + + +/** + * @brief Type of upcoming transaction sequence + * + * Used in combination with ::GPS_BEGIN_TRANSACTION and ::GPS_END_TRANSACTION + * to announce which type of transaction is going to be started. Thus the receiver + * can prepare for following actions. + */ +enum MBG_TRANSACTION_TYPES +{ + MBG_TRANSACTION_TYPE_NONE, + /* ### TODO FIXME + * Network transaction requires at least and as first command: + * - ::GPS_NET_GLB_CFG (::MBG_NET_GLB_CFG_INFO) + * Depending on ::MBG_NET_GLB_CFG_INFO::glb_settings and its num_[...] + * members there are a couple of index commands which should be handled in any order: + * - ::GPS_NET_DNS_SRVR (::MBG_IP_ADDR_IDX) + * - ::GPS_NET_DNS_SRCH_DOM (::MBG_NET_NAME_IDX) + * - ::GPS_NET_INTF_LINK_IDX (::MBG_NET_INTF_LINK_INFO_IDX) + * - ::GPS_NET_INTF_ADDR_IDX (::MBG_NET_INTF_ADDR_INFO_IDX) + * - ::GPS_NET_INTF_ROUTE_IDX (::MBG_NET_INTF_ROUTE_INFO_IDX) + */ + MBG_TRANSACTION_TYPE_NETWORK, + MBG_TRANSACTION_TYPE_PTP, + /* + * Commands in any order if supp. by ::MBG_SNMP_GLB_INFO::max_[...] + * and ::MBG_SNMP_GLB_INFO::supp_versions + * + * Should be used within ::MBG_TRANSACTION_TYPE_MONITORING but may also be + * used stand-alone. + * + * - ::GPS_SNMP_GLB_SETTINGS + * - ::GPS_SNMP_V12_SETTINGS_IDX + * - ::GPS_SNMP_V12_TRAP_SETTINGS_IDX + * - ::GPS_SNMP_V3_SETTINGS_IDX + * - ::GPS_SNMP_V3_TRAP_SETTINGS_IDX + */ + MBG_TRANSACTION_TYPE_MONITORING_SNMP, + /* + * NTP transaction requires at least and as first command: + * ::GPS_NTP_GLB_CFG + * Commands in any order if supp. by ::MBG_NTP_GLB_INFO + * and ::MBG_SNMP_GLB_INFO::supp_versions + * + * - ::GPS_NTP_REFCLK_CFG + * - ::GPS_NTP_MISC_LIMITS + * - ::GPS_NTP_MISC_ORPHAN_MODE + * - ::GPS_NTP_SYMM_KEY_LIMITS + * - ::GPS_NTP_SYMM_KEY_CFG + * - ::GPS_NTP_TRUSTED_KEY_CFG + * - ::GPS_NTP_CLNT_MODE_CFG + * - ::GPS_NTP_SRV_MODE_CFG + * - ::GPS_NTP_PEER_SETTINGS_IDX + * - ::GPS_NTP_SYS_STATE + * - ::GPS_NTP_PEER_STATE_IDX + */ + MBG_TRANSACTION_TYPE_NTP, + /* + * IO Port transaction used to read or write ALL_IO_PORT_INFO + * Commands related to this transaction: + * + * - ::GPS_IO_PORT_LIMITS + * - ::GPS_IO_PORT_SETTINGS_IDX + * - ::GPS_IO_PORT_INFO_IDX + * - ::GPS_IO_PORT_TYPE_INFO_IDX + * - ::GPS_IO_PORT_STATUS_IDX + */ + MBG_TRANSACTION_TYPE_IO_PORT, + /* + * Commands in any order if ::MBG_XFEATURE_MONITORING is set in + * ::MBG_XFEATURE_BUFFER. + * + * Transactions ::MBG_TRANSACTION_TYPE_MONITORING_SNMP and + * ::MBG_TRANSACTION_TYPE_EVENTS may also be opened within + * ::MBG_TRANSACTION_TYPE_MONITORING transaction. + * + * - ::GPS_MONITORING_LIMITS + * - ::GPS_MONITORING_STATUS + */ + MBG_TRANSACTION_TYPE_MONITORING, + /* + * Commands in any order if ::MBG_XFEATURE_MONITORING is set in + * ::MBG_XFEATURE_BUFFER. + * + * Should be used within ::MBG_TRANSACTION_TYPE_MONITORING but may also be + * used stand-alone. + * + * - ::GPS_EVENT_IDX + * - ::GPS_EVENT_STAT_IDX + */ + MBG_TRANSACTION_TYPE_EVENTS, + + MAX_MBG_TRANSACTION_TYPES +}; + + +#define MBG_TRANSACTION_MSK_SET 0x8000 +#define _mbg_is_set_transaction( _type ) ( ( _type ) & MBG_TRANSACTION_MSK_SET ) +#define _mbg_transaction_type_set( _type ) ( ( _type ) |= MBG_TRANSACTION_MSK_SET ) + + +/** + * @defgroup group_io_ports IO Port API + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_IO_PORTS is set in the extended device features. + * + * @{ */ + +/** + * @brief Port types + * + * Used with ::MBG_IO_PORT_TYPE_INFO::type and + * :: MBG_IO_PORT_SETTINGS::type + */ +enum MBG_IO_PORT_TYPES +{ + MBG_IO_PORT_TYPE_NONE = -1, ///< Only use this for ::MBG_IO_PORT_SETTINGS::type if ::MBG_IO_PORT_SETTINGS::op_mode is ::MBG_IO_PORT_OP_MODE_NONE + MBG_IO_PORT_TYPE_PPS, + MBG_IO_PORT_TYPE_10MHz, + MBG_IO_PORT_TYPE_2048KHz, + MBG_IO_PORT_TYPE_GPIO, + MBG_IO_PORT_TYPE_ETHERNET, + MBG_IO_PORT_TYPE_TERMINAL, + MBG_IO_PORT_TYPE_MULTI, + MBG_IO_PORT_TYPE_POUT, + N_MBG_IO_PORT_TYPES +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_TYPES + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_TYPES entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_TYPES. + * + * @see ::MBG_IO_PORT_TYPES + */ +#define MBG_IO_PORT_TYPE_STRS \ +{ \ + "PPS", \ + "10 MHz", \ + "2048 KHz", \ + "GPIO", \ + "Ethernet", \ + "Terminal", \ + "Multi", \ + "Prog. Output" \ +} + + +/** + * @brief Port directions (input or output) + * + * @see ::MBG_IO_PORT_DIR_MSKS + */ +enum MBG_IO_PORT_DIRS +{ + MBG_IO_PORT_DIR_NONE = -1, ///< Only use this for ::MBG_IO_PORT_SETTINGS::direction if ::MBG_IO_PORT_SETTINGS::op_mode is ::MBG_IO_PORT_OP_MODE_NONE + MBG_IO_PORT_DIR_IN, ///< Port is input like PPS In + MBG_IO_PORT_DIR_OUT, ///< Port is output like 10Mhz + MBG_IO_PORT_DIR_IN_OUT, ///< Port can be in- & output in parallel like network port + N_MBG_IO_PORT_DIRS +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_DIRS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_DIRS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_DIRS. + * + * @see ::MBG_IO_PORT_DIRS + */ +#define MBG_IO_PORT_DIR_STRS \ +{ \ + "Input", \ + "Output", \ + "Input/Output" \ +} + + +/** + * @brief Bit masks of Meinberg I/O port directions + * + * Used with ::MBG_IO_PORT_TYPE_INFO::supp_dirs + * + * @see ::MBG_IO_PORT_DIRS + */ +enum MBG_IO_PORT_DIR_MSKS +{ + MBG_IO_PORT_MSK_DIR_IN = ( 1UL << MBG_IO_PORT_DIR_IN ), ///< See ::MBG_IO_PORT_DIR_IN + MBG_IO_PORT_MSK_DIR_OUT = ( 1UL << MBG_IO_PORT_DIR_OUT ), ///< See ::MBG_IO_PORT_DIR_OUT + MBG_IO_PORT_MSK_DIR_IN_OUT = ( 1UL << MBG_IO_PORT_DIR_IN_OUT ) ///< See ::MBG_IO_PORT_DIR_IN_OUT +}; + + +/** + * @brief Port type sources + * + * Configurable sources for an I/O port type + * + * @see ::MBG_IO_PORT_SRC_MSKS + */ +enum MBG_IO_PORT_SRCS +{ + MBG_IO_PORT_SRC_NONE = -1, ///< Only use this for ::MBG_IO_PORT_SETTINGS::source if ::MBG_IO_PORT_SETTINGS::op_mode is ::MBG_IO_PORT_OP_MODE_NONE + MBG_IO_PORT_SRC_STATIC, ///< Static, not configurable + MBG_IO_PORT_SRC_LOCAL, ///< Locally generated, e.g. on (carrier) board + MBG_IO_PORT_SRC_ASSOC_CLOCK, ///< Fixed (wired) clock from back plane (e.g. refclock 1 in M500 IMS) + MBG_IO_PORT_SRC_ACTIVE_CLOCK, ///< Switched clock from back plane (e.g. selected by RSC) + MBG_IO_PORT_SRC_CLK1, ///< Clock 1 fixed (CPU board only) + MBG_IO_PORT_SRC_CLK2, ///< Clock 2 fixed (CPU board only) + MBG_IO_PORT_SRC_ARC, ///< Any rate converter + MBG_IO_PORT_SRC_OSC, ///< Oscillator + MBG_IO_PORT_SRC_SYNCE, ///< SyncE + N_MBG_IO_PORT_SRCS +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_SRCS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_SRCS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_SRCS. + * + * @see ::MBG_IO_PORT_SRCS + */ +#define MBG_IO_PORT_SRC_STRS \ +{ \ + "Static", \ + "Locally generated", \ + "Associated clock", \ + "Active clock", \ + "Clock 1 fixed", \ + "Clock 2 fixed", \ + "Any rate converter", \ + "Oscillator", \ + "SyncE" \ +} + + +/** + * @brief Bit masks of Meinberg I/O port attitudes + * + * Used with ::MBG_IO_PORT_TYPE_INFO::supp_srcs + * + * @see ::MBG_IO_PORT_SRCS + */ +enum MBG_IO_PORT_SRC_MSKS +{ + MBG_IO_PORT_SRC_MSK_STATIC = (1UL << MBG_IO_PORT_SRC_STATIC), ///< See ::MBG_IO_PORT_SRC_STATIC + MBG_IO_PORT_SRC_MSK_LOCAL = (1UL << MBG_IO_PORT_SRC_LOCAL), ///< See ::MBG_IO_PORT_SRC_LOCAL + MBG_IO_PORT_SRC_MSK_ASSOC_CLOCK = (1UL << MBG_IO_PORT_SRC_ASSOC_CLOCK), ///< See ::MBG_IO_PORT_SRC_ASSOC_CLOCK + MBG_IO_PORT_SRC_MSK_ACTIVE_CLOCK = (1UL << MBG_IO_PORT_SRC_ACTIVE_CLOCK), ///< See ::MBG_IO_PORT_SRC_ACTIVE_CLOCK + MBG_IO_PORT_SRC_MSK_CLK1 = (1UL << MBG_IO_PORT_SRC_CLK1), ///< See ::MBG_IO_PORT_SRC_CLK1 + MBG_IO_PORT_SRC_MSK_CLK2 = (1UL << MBG_IO_PORT_SRC_CLK2), ///< See ::MBG_IO_PORT_SRC_CLK2 + MBG_IO_PORT_SRC_MSK_ARC = (1UL << MBG_IO_PORT_SRC_ARC), ///< See ::MBG_IO_PORT_SRC_ARC + MBG_IO_PORT_SRC_MSK_OSC = (1UL << MBG_IO_PORT_SRC_OSC), ///< See ::MBG_IO_PORT_SRC_OSC + MBG_IO_PORT_SRC_MSK_SYNCE = (1UL << MBG_IO_PORT_SRC_SYNCE) ///< See ::MBG_IO_PORT_SRC_SYNCE +}; + + +/** + * @brief Port connector types + * + * Used with ::MBG_IO_PORT_TYPE_INFO::conn_type + * + */ +enum MBG_IO_PORT_CONN_TYPES +{ + MBG_IO_PORT_CONN_TYPE_SMA, + MBG_IO_PORT_CONN_TYPE_BNC, + MBG_IO_PORT_CONN_TYPE_DSUB25, + MBG_IO_PORT_CONN_TYPE_RJ45, + MBG_IO_PORT_CONN_TYPE_SFP, + MBG_IO_PORT_CONN_TYPE_USB_MICRO_B, + MBG_IO_PORT_CONN_TYPE_USB_A, + MBG_IO_PORT_CONN_TYPE_USB_B, + MBG_IO_PORT_CONN_TYPE_SMA_ANT, + MBG_IO_PORT_CONN_TYPE_RJ45_ETH, + MBG_IO_PORT_CONN_TYPE_2_PIN_DFK, + MBG_IO_PORT_CONN_TYPE_3_PIN_DFK, + MBG_IO_PORT_CONN_TYPE_16_PIN_DFK, + MBG_IO_PORT_CONN_TYPE_BNC_ISO, + MBG_IO_PORT_CONN_TYPE_DSUB9, + MBG_IO_PORT_CONN_TYPE_FIBRE_ST, + MBG_IO_PORT_CONN_TYPE_XHE_SPI, + N_MBG_IO_PORT_CONN_TYPES +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_CONN_TYPES + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_CONN_TYPES entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_CONN_TYPES. + * + * @see ::MBG_IO_PORT_CONN_TYPES + */ +#define MBG_IO_PORT_CONN_TYPE_STRS \ +{ \ + "SMA", \ + "BNC", \ + "D-Sub 25", \ + "RJ45", \ + "SFP", \ + "USB Micro B", \ + "USB A", \ + "USB B", \ + "SMA Antenna", \ + "RJ45 Ethernet", \ + "DFK 2-Pin", \ + "DFK 3-Pin", \ + "DFK 16-Pin", \ + "BNC isolated", \ + "D-Sub 9", \ + "Fibre ST", \ + "XHE SPI" \ +} + + +/** + * @brief Position of a port on a card + * + * Used with ::MBG_IO_PORT_INFO::position + * + */ +enum MBG_IO_PORT_POS +{ + MBG_IO_PORT_POS_FRONT_COL_1, ///> Connector column 1, front + MBG_IO_PORT_POS_REAR_COL_1, ///> Connector column 1, rear + MBG_IO_PORT_POS_FRONT_COL_2, ///> Connector column 2, front + MBG_IO_PORT_POS_REAR_COL_2, ///> Connector column 2, rear + MBG_IO_PORT_POS_FRONT_COL_3, ///> Connector column 3, front + MBG_IO_PORT_POS_REAR_COL_3, ///> Connector column 3, rear + MBG_IO_PORT_POS_FRONT_COL_4, ///> Connector column 4, front + MBG_IO_PORT_POS_REAR_COL_4, ///> Connector column 4, rear + N_MBG_IO_PORT_POS +}; + + +/** + * @brief Bit masks of Meinberg I/O port attitudes + * + * Used with ::MBG_IO_PORT_TYPE_INFO::supp_srcs + * + * @see ::MBG_IO_PORT_POS + */ +enum MBG_IO_PORT_POS_MSKS +{ + MBG_IO_PORT_POS_MSK_FRONT_COL_1 = (1UL << MBG_IO_PORT_POS_FRONT_COL_1), ///< See ::MBG_IO_PORT_POS_FRONT_COL_1 + MBG_IO_PORT_POS_MSK_REAR_COL_1 = (1UL << MBG_IO_PORT_POS_REAR_COL_1), ///< See ::MBG_IO_PORT_POS_REAR_COL_1 + MBG_IO_PORT_POS_MSK_FRONT_COL_2 = (1UL << MBG_IO_PORT_POS_FRONT_COL_2), ///< See ::MBG_IO_PORT_POS_FRONT_COL_2 + MBG_IO_PORT_POS_MSK_REAR_COL_2 = (1UL << MBG_IO_PORT_POS_REAR_COL_2), ///< See ::MBG_IO_PORT_POS_REAR_COL_2 + MBG_IO_PORT_POS_MSK_FRONT_COL_3 = (1UL << MBG_IO_PORT_POS_FRONT_COL_3), ///< See ::MBG_IO_PORT_POS_FRONT_COL_3 + MBG_IO_PORT_POS_MSK_REAR_COL_3 = (1UL << MBG_IO_PORT_POS_REAR_COL_3), ///< See ::MBG_IO_PORT_POS_REAR_COL_3 + MBG_IO_PORT_POS_MSK_FRONT_COL_4 = (1UL << MBG_IO_PORT_POS_FRONT_COL_4), ///< See ::MBG_IO_PORT_POS_FRONT_COL_4 + MBG_IO_PORT_POS_MSK_REAR_COL_4 = (1UL << MBG_IO_PORT_POS_REAR_COL_4) ///< See ::MBG_IO_PORT_POS_REAR_COL_4 +}; + + +/** + * @brief IO Port Limits + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_U + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef struct +{ + uint8_t num_ports; + uint8_t reserved_1[3]; ///< Reserved, currently 0 + uint32_t supp_positions; ///< Determines the size of the card (i.e. 2 rows, front/rear) See ::MBG_IO_PORT_POS_MSKS + uint32_t reserved_2[10]; ///< Reserved, currently 0 + +} MBG_IO_PORT_LIMITS; + +#define _mbg_swab_io_port_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_positions ); \ +} while ( 0 ) + + + +/** + * @brief Port Operation Bits + * + * Used with ::MBG_IO_PORT_SETTINGS::op_mode + * + * For now, there is a per port operation mode setting which + * is quite equal to ::ENABLE_FLAGS. + * + * @see ::MBG_IO_PORT_OP_MODE_MSKS + */ +enum MBG_IO_PORT_OP_MODE_BITS +{ + MBG_IO_PORT_OP_MODE_NONE = -1, ///< Current mode cannot be determined + MBG_IO_PORT_OP_MODE_DISABLED, ///< Disabled port + MBG_IO_PORT_OP_MODE_ALWAYS, ///< Always enable port + MBG_IO_PORT_OP_MODE_IF_SYNC_ONLY, ///< Enable port if sync only + MBG_IO_PORT_OP_MODE_AFTER_SYNC, ///< Always enable port after being sync once + N_MBG_IO_PORT_OP_MODE_BITS +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_OP_MODE_BITS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_OP_MODE_BITS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_OP_MODE_BITS. + * + * @see ::MBG_IO_PORT_OP_MODE_BITS + */ +#define MBG_IO_PORT_OP_MODE_STRS \ +{ \ + "Disabled", \ + "Always enabled", \ + "If sync only", \ + "Always after sync" \ +} + + + +/** + * @brief Masks for ::MBG_IO_PORT_OP_MODE_BITS + * + * Used with ::MBG_IO_PORT_INFO::supp_op_modes + * + * @see ::MBG_IO_PORT_OP_MODE_BITS + */ +enum MBG_IO_PORT_OP_MODE_MSKS +{ + MBG_IO_PORT_OP_MODE_MSK_DISABLED = (1UL << MBG_IO_PORT_OP_MODE_DISABLED), ///< See ::MBG_IO_PORT_OP_MODE_DISABLED + MBG_IO_PORT_OP_MODE_MSK_ALWAYS = (1UL << MBG_IO_PORT_OP_MODE_ALWAYS), ///< See ::MBG_IO_PORT_OP_MODE_ALWAYS + MBG_IO_PORT_OP_MODE_MSK_IF_SYNC_ONLY = (1UL << MBG_IO_PORT_OP_MODE_IF_SYNC_ONLY), ///< See ::MBG_IO_PORT_OP_MODE_IF_SYNC_ONLY + MBG_IO_PORT_OP_MODE_MSK_AFTER_SYNC = (1UL << MBG_IO_PORT_OP_MODE_AFTER_SYNC) ///< See ::MBG_IO_PORT_OP_MODE_AFTER_SYNC +}; + + +/** + * @brief Physical or logical group role bits + * + * Used with ::MBG_IO_PORT_STATUS::phys_grp_role, ::MBG_IO_PORT_STATUS::log_grp_role + * + * @see ::MBG_IO_PORT_GRP_ROLE_MSKS + */ +enum MBG_IO_PORT_GRP_ROLE_BITS +{ + MBG_IO_PORT_GRP_ROLE_NONE, ///< No group role, only possible if port is not assigned to any group + MBG_IO_PORT_GRP_ROLE_MASTER, ///< Master port in group, i.e. configurable port of LIU + MBG_IO_PORT_GRP_ROLE_SLAVE, ///< Slave port in group, i.e. non-configurable port of LIU + MBG_IO_PORT_GRP_ROLE_PASSIVE, ///< Passive port in group, i.e. passive port of network group (i.e. SFP or RJ45) + N_MBG_IO_PORT_GRP_ROLE_BITS +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_GRP_ROLE_BITS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_GRP_ROLE_BITS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_GRP_ROLE_BITS. + * + * @see ::MBG_IO_PORT_GRP_ROLE_BITS + */ +#define MBG_IO_PORT_GRP_ROLE_STRS \ +{ \ + "None", \ + "Master", \ + "Slave", \ + "Passive" \ +} + + +/** + * @brief Masks for ::MBG_IO_PORT_GRP_ROLE_BITS + * + * Used with ::MBG_IO_PORT_INFO::supp_phys_grp_roles + * + * @see ::MBG_IO_PORT_GRP_ROLE_BITS + */ +enum MBG_IO_PORT_GRP_ROLE_MSKS +{ + MBG_IO_PORT_GRP_ROLE_MSK_NONE = (1UL << MBG_IO_PORT_GRP_ROLE_NONE), ///< See ::MBG_IO_PORT_GRP_ROLE_NONE + MBG_IO_PORT_GRP_ROLE_MSK_MASTER = (1UL << MBG_IO_PORT_GRP_ROLE_MASTER), ///< See ::MBG_IO_PORT_GRP_ROLE_MASTER + MBG_IO_PORT_GRP_ROLE_MSK_SLAVE = (1UL << MBG_IO_PORT_GRP_ROLE_SLAVE), ///< See ::MBG_IO_PORT_GRP_ROLE_SLAVE + MBG_IO_PORT_GRP_ROLE_MSK_PASSIVE = (1UL << MBG_IO_PORT_GRP_ROLE_PASSIVE) ///< See ::MBG_IO_PORT_GRP_ROLE_PASSIVE +}; + + +/** + * @brief IO Port Settings Union + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_U + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef union +{ + MBG_GPIO_SETTINGS gpio_settings; + POUT_SETTINGS pout_settings; + +} MBG_IO_PORT_SETTINGS_U; + +#define _mbg_swab_io_port_settings_u( _type, _p, _recv ) \ +do \ +{ \ + switch ( (_type) ) \ + { \ + case MBG_IO_PORT_TYPE_GPIO: \ + _mbg_swab_mbg_gpio_settings( &(_p)->gpio_settings, (_recv) ); \ + break; \ + \ + case MBG_IO_PORT_TYPE_POUT: \ + if ( _recv ) \ + _mbg_swab_pout_settings_on_get( &(_p)->pout_settings ); \ + else _mbg_swab_pout_settings_on_set( &(_p)->pout_settings ); \ + break; \ + \ + default: break; \ + } \ +} while ( 0 ) + + +#define MBG_IO_PORT_SETTINGS_MIN_SIZE 32 + + +/** + * @brief IO Port Settings + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_U + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef struct +{ + uint16_t type; ///< ::MBG_IO_PORT_TYPES + uint8_t direction; ///< ::MBG_IO_PORT_DIRS + uint8_t source; ///< ::MBG_IO_PORT_SRCS + uint8_t op_mode; ///< ::MBG_IO_PORT_OP_MODE_BITS + uint8_t reserved_1[3]; ///< Future use and padding, currently 0 + uint32_t reserved_2[6]; ///< Future use and padding, currently 0 + + /* + * Struct members above represent minimum amount of data to be sent. + * See ::MBG_IO_PORT_SETTINGS_MIN_SIZE + */ + + MBG_IO_PORT_SETTINGS_U data; ///< Data union for setting's type + +} MBG_IO_PORT_SETTINGS; + +#define _mbg_swab_io_port_settings( _p, _recv ) \ +do \ +{ \ + uint16_t t = (_p)->type; \ + if ( (_recv) ) \ + _mbg_swab16( &t ); \ + _mbg_swab16( &(_p)->type ); \ + _mbg_swab_io_port_settings_u( t, &(_p)->data, (_recv) ); \ +} while ( 0 ) + + + + +/** + * @brief IO Port Settings Index + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_U + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + * + * Indexes from 0..::MBG_IO_PORT_LIMITS::num_ports - 1 are used + * to set ::MBG_IO_PORT_SETTINGS wrapped in ::MBG_IO_PORT_SETTINGS_IDX. + */ +typedef struct +{ + uint32_t idx; + MBG_IO_PORT_SETTINGS settings; + +} MBG_IO_PORT_SETTINGS_IDX; + +#define _mbg_swab_io_port_settings_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_io_port_settings( &(_p)->settings, (_recv) ); \ +} while ( 0 ) + + +#define MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE (MBG_IO_PORT_SETTINGS_MIN_SIZE + sizeof( uint32_t )) + + +#define MBG_IO_PORT_SETTINGS_IDX_SIZES \ +{ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_PPS */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_10MHz */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_2048KHz */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( MBG_GPIO_SETTINGS ), /* MBG_IO_PORT_TYPE_GPIO */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_ETHERNET */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_TERMINAL */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_MULTI */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( POUT_SETTINGS ) /* MBG_IO_PORT_TYPE_POUT */ \ +} + + +#define MBG_NO_PHYS_GROUP 0xFF +#define MBG_NO_LOG_GROUP 0xFF + +/** + * @brief IO Port Info + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO_U + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef struct +{ + uint8_t num_types; ///< See ::MBG_IO_PORT_TYPE_INFO + uint8_t conn_type; ///< See ::MBG_IO_PORT_CONN_TYPES + uint8_t position; ///< See ::MBG_IO_PORT_POS + uint8_t reserved_1; ///< Future use and padding, currently 0 + uint16_t supp_op_modes; ///< See ::MBG_IO_PORT_OP_MODE_MSKS + uint16_t supp_phys_grp_roles; ///< Supported roles in ::MBG_IO_PORT_STATUS::phys_grp_role, see ::MBG_IO_PORT_GRP_ROLE_MSKS + uint8_t phys_grp; ///< Physical group number (i.e. SFP/RJ45 on HPS100), or ::MBG_NO_PHYS_GROUP + uint8_t reserved_2[3]; ///< Future use and padding, currently 0 + uint32_t reserved_3[8]; ///< Future use and padding, currently 0 + char rel_str[16]; ///< Indicates internal relation, i.e. "lan0", "fpga0" or "/dev/ttyS0" + MBG_IO_PORT_SETTINGS settings; ///< See ::MBG_IO_PORT_SETTINGS + +} MBG_IO_PORT_INFO; + +#define _mbg_port_has_phys_group( _p ) ( ( _p )->phys_grp != MBG_NO_PHYS_GROUP ) + +#define _mbg_swab_io_port_info( _p, _recv ) \ +do \ +{ \ + _mbg_swab16( &(_p)->supp_op_modes ); \ + _mbg_swab16( &(_p)->supp_phys_grp_roles ); \ + _mbg_swab_io_port_settings( &(_p)->settings, (_recv) ); \ +} while ( 0 ) + + + +#define MBG_IO_PORT_INFO_MIN_SIZE ( 60 + MBG_IO_PORT_SETTINGS_MIN_SIZE ) + + +/** + * @brief IO Port Info Index + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + * + * Indexes from 0..::MBG_IO_PORT_LIMITS::num_ports - 1 are used + * to query ::MBG_IO_PORT_INFO wrapped in ::MBG_IO_PORT_INFO_IDX. + */ +typedef struct +{ + uint32_t idx; + MBG_IO_PORT_INFO info; + +} MBG_IO_PORT_INFO_IDX; + +#define _mbg_swab_io_port_info_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_io_port_info( &(_p)->info, (_recv) ); \ +} while ( 0 ) + + + +#define MBG_IO_PORT_INFO_IDX_MIN_SIZE (MBG_IO_PORT_INFO_MIN_SIZE + sizeof( uint32_t )) + + +#define MBG_IO_PORT_INFO_IDX_SIZES \ +{ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_PPS */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_10MHz */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_2048KHz */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( MBG_GPIO_SETTINGS ), /* MBG_IO_PORT_TYPE_GPIO */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_ETHERNET */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_TERMINAL */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_MULTI */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( POUT_SETTINGS ) /* MBG_IO_PORT_TYPE_POUT */ \ +} + + +/** + * @brief IO Port Type Info Union + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef union +{ + MBG_GPIO_LIMITS gpio_limits; + POUT_INFO pout_info; + +} MBG_IO_PORT_TYPE_INFO_U; + +#define _mbg_swab_io_port_type_info_u( _type, _p, _recv ) \ +do \ +{ \ + switch ( (_type) ) \ + { \ + case MBG_IO_PORT_TYPE_GPIO: \ + _mbg_swab_mbg_gpio_limits( &(_p)->gpio_limits, (_recv) ); \ + break; \ + \ + case MBG_IO_PORT_TYPE_POUT: \ + _mbg_swab_pout_info_on_get( &(_p)->pout_info ); \ + break; \ + \ + default: break; \ + } \ +} while ( 0 ) + + + +#define MBG_IO_PORT_TYPE_INFO_MIN_SIZE 32 + + +/** + * @brief IO Port Type Info + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef struct +{ + uint16_t port_type; ///< See ::MBG_IO_PORT_TYPES + uint16_t reserved_1; ///< Future use and padding, currently 0 + uint8_t supp_dirs; ///< See ::MBG_IO_PORT_DIR_MSKS + uint8_t reserved_2[3]; ///< Future use and padding, currently 0 + uint32_t supp_srcs; ///< See ::MBG_IO_PORT_SRC_MSKS + uint32_t reserved_3[5]; ///< Future use and padding, currently 0 + + /* + * Struct members above represent minimum amount of data to be sent. + * See ::MBG_IO_PORT_TYPE_INFO_MIN_SIZE + */ + + MBG_IO_PORT_TYPE_INFO_U data; ///< Port type specific data + +} MBG_IO_PORT_TYPE_INFO; + +#define _mbg_swab_io_port_type_info( _p, _recv ) \ +do \ +{ \ + uint16_t t = (_p)->port_type; \ + if ( (_recv) ) \ + _mbg_swab16( &t ); \ + _mbg_swab16( &(_p)->port_type ); \ + _mbg_swab_io_port_type_info_u( t, &(_p)->data, (_recv) ); \ + _mbg_swab32( &(_p)->supp_srcs ); \ +} while ( 0 ) + + +#define MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE (MBG_IO_PORT_TYPE_INFO_MIN_SIZE + 2 * sizeof( uint32_t )) + + +#define MBG_IO_PORT_TYPE_INFO_IDX_SIZES \ +{ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_PPS */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_10MHz */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_2048KHz */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( MBG_GPIO_LIMITS ), /* MBG_IO_PORT_TYPE_GPIO */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_ETHERNET */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_TERMINAL */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_MULTI */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( POUT_INFO ) /* MBG_IO_PORT_TYPE_POUT */ \ +} + + +/** + * @brief IO Port Type Info Index + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + * + * Indexes from 0..::MBG_IO_PORT_INFO::num_types - 1 are used + * to query ::MBG_IO_PORT_TYPE_INFO wrapped in ::MBG_IO_PORT_TYPE_INFO_IDX. + * + */ +typedef struct +{ + uint32_t port_idx; + uint32_t port_type_idx; + MBG_IO_PORT_TYPE_INFO info; + +} MBG_IO_PORT_TYPE_INFO_IDX; + +#define _mbg_swab_io_port_type_info_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->port_idx ); \ + _mbg_swab32( &(_p)->port_type_idx ); \ + _mbg_swab_io_port_type_info( &(_p)->info, (_recv) ); \ +} while ( 0 ) + + + +#define MAX_IO_PORT_STATUS_BITS 64 + + +/** + * @brief Port Type Status Bits + * + */ +enum MBG_IO_PORT_STATUS_BITS +{ + MBG_IO_PORT_STATUS_BIT_DISABLED, ///< See ::MBG_IO_PORT_OP_MODE_DISABLED. Other bits should be 0 in this case + MBG_IO_PORT_STATUS_BIT_CARRIER_DETECTED, ///< Port has physical carrier connection (e.g. BNC cable in BPE's case) + MBG_IO_PORT_STATUS_BIT_INPUT_SIGNAL_NEVER_AVAIL, ///< Input signal has NEVER been avail + MBG_IO_PORT_STATUS_BIT_INPUT_SIGNAL_AVAIL, ///< Input signal is avail right now + MBG_IO_PORT_STATUS_BIT_INPUT_SIGNAL_LOST, ///< Input signal is currently not avail, but has been avail before + MBG_IO_PORT_STATUS_BIT_SHORT_CIRCUIT, ///< Short circuit + N_MBG_IO_PORT_STATUS_BITS +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_STATUS_BITS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_STATUS_BITS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_STATUS_BITS. + * + * @see ::MBG_IO_PORT_STATUS_BITS + */ +#define MBG_IO_PORT_STATUS_STRS \ +{ \ + "Disabled", \ + "Carrier detected", \ + "Input signal has never been avail", \ + "Input signal is avail", \ + "Input signal is currently lost", \ + "Short circuit" \ +} + + +/** + * @brief Array size required to store all status bits + * + * The number of bytes required to store up to ::MAX_IO_PORT_STATUS_BITS + * feature bits in a byte array. + */ +#define MAX_IO_PORT_STATUS_BYTES ( MAX_IO_PORT_STATUS_BITS / 8 ) + + +/** + * @brief A structure used to store port status bits + * + * Up to ::MAX_IO_PORT_STATUS_BITS totally can be stored, but only + * ::N_MBG_IO_PORT_STATUS_BITS are currently defined. + * + * The ::_set_io_port_status_bit macro should be used by the firmware + * to set a status bit in the buffer, and the ::check_byte_array_bit + * to check if a bit is set + * + * @see ::_set_io_port_status_bit + * @see ::check_byte_array_bit + */ +typedef struct +{ + uint8_t b[MAX_IO_PORT_STATUS_BYTES]; + +} MBG_IO_PORT_STATUS_BUFFER; + +#define _mbg_swab_io_port_status_buffer( _p ) \ + _nop_macro_fnc() + + + +/** + * @brief Set an port status bit in a ::MBG_IO_PORT_STATUS_BUFFER + * + * Should be used by the firmware only to set one of the ::N_MBG_IO_PORT_STATUS_BITS + * in an ::MBG_IO_PORT_STATUS_BUFFER after power-up. + * + * @param[in] _status_bit One of the ::MBG_IO_PORT_STATUS_BITS + * @param[in] _status_buffp Pointer to an ::MBG_IO_PORT_STATUS_BUFFER + */ +#define _set_io_port_status_bit( _status_bit, _status_buffp ) \ + _set_array_bit( _status_bit, (_status_buffp)->b, MAX_IO_PORT_STATUS_BYTES ) + + +/** + * @brief IO Port Type Status + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS_IDX + * + */ +typedef struct +{ + MBG_IO_PORT_STATUS_BUFFER supp_stati; ///< Supported ::MBG_IO_PORT_STATUS_BITS in ::MBG_IO_PORT_STATUS_BUFFER + MBG_IO_PORT_STATUS_BUFFER status; ///< See ::MBG_IO_PORT_STATUS_BUFFER + + uint8_t cfg_counter; ///< Updated (increased) when config changes + uint8_t phys_grp_role; ///< Physical group role state, see ::MBG_IO_PORT_GRP_ROLE_BITS + uint8_t log_grp; ///< Logical group number (i.e. bond0), or ::MBG_NO_LOG_GROUP + uint8_t log_grp_role; ///< Logical group role (i.e. bond master, bond slave), see ::MBG_IO_PORT_GRP_ROLE_BITS + + uint32_t reserved_2[4]; ///< Future use, currently 0 + +} MBG_IO_PORT_STATUS; + +#define _mbg_port_has_log_group( _p ) ( ( _p )->log_grp != MBG_NO_LOG_GROUP ) + +#define _mbg_swab_io_port_status( _p ) \ +do \ +{ \ + _mbg_swab_io_port_status_buffer( &(_p)->supp_stati ); \ + _mbg_swab_io_port_status_buffer( &(_p)->status ); \ +} while ( 0 ) + + + +/** + * @brief IO Port Type Status + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * + * Indexes from 0..::MBG_IO_PORT_INFO::num_types - 1 are used + * to query ::MBG_IO_PORT_TYPE_INFO wrapped in ::MBG_IO_PORT_TYPE_INFO_IDX. + * + */ +typedef struct +{ + uint32_t idx; + MBG_IO_PORT_STATUS status; + +} MBG_IO_PORT_STATUS_IDX; + +#define _mbg_swab_io_port_status_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_io_port_status( &(_p)->status ); \ +} while ( 0 ) + + +/** @} defgroup group_io_ports */ + + + +/** + * @defgroup group_monitoring Monitoring / notification + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_MONITORING is set in the extended device features. + * + * TODO: Add proper Doxygen documentation + * + * @{ */ + + +#define MBG_MONITORING_STR_SIZE 32 + +enum MBG_MONITORING_TYPES +{ + MBG_MONITORING_TYPE_SNMP, + MBG_MONITORING_TYPE_EMAIL, + MBG_MONITORING_TYPE_SYSLOG, + N_MBG_MONITORING_TYPES +}; + +#define MBG_MONITORING_TYPE_STRS \ +{ \ + "SNMP", \ + "Email", \ + "Syslog" \ +} + +enum MBG_MONITORING_TYPE_MSKS +{ + MBG_MONITORING_TYPE_MSK_SNMP = (1UL << MBG_MONITORING_TYPE_SNMP), + MBG_MONITORING_TYPE_MSK_EMAIL = (1UL << MBG_MONITORING_TYPE_EMAIL), + MBG_MONITORING_TYPE_MSK_SYSLOG = (1UL << MBG_MONITORING_TYPE_SYSLOG) +}; + + + +typedef struct +{ + uint16_t supp_types; ///< See ::MBG_MONITORING_TYPE_MSKS + uint16_t supp_num_events; ///< Supported number of events. See ::MBG_EVENT_TYPES + uint32_t reserved_2[3]; + +} MBG_MONITORING_LIMITS; + +#define _mbg_swab_monitoring_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->supp_types ); \ + _mbg_swab16( &(_p)->supp_num_events ); \ +} while ( 0 ) + + + +/* If ::MBG_MONITORING_TYPE_MSK_SNMP is set in ::MBG_MONITORING_LIMITS::supp_types */ + +enum MBG_SNMP_VERSIONS +{ + MBG_SNMP_VERSION_V1, + MBG_SNMP_VERSION_V2c, + MBG_SNMP_VERSION_V3, + N_MBG_SNMP_VERSIONS +}; + +#define MBG_SNMP_VERSION_STRS \ +{ \ + "Version 1", \ + "Version 2c", \ + "Version 3" \ +} + +enum MBG_SNMP_VERSION_MSKS +{ + MBG_SNMP_VERSION_MSK_V1 = (1UL << MBG_SNMP_VERSION_V1), + MBG_SNMP_VERSION_MSK_V2c = (1UL << MBG_SNMP_VERSION_V2c), + MBG_SNMP_VERSION_MSK_V3 = (1UL << MBG_SNMP_VERSION_V3) +}; + + + +typedef struct +{ + uint8_t num_v12_settings; ///< Number of configured v1/v2 settings, see ::MBG_SNMP_V12_INFO_IDX + uint8_t num_v3_settings; ///< Number of configured v1/v2 trap receivers, see ::MBG_SNMP_V12_TRAP_INFO_IDX + uint8_t num_v12_trap_receivers; ///< Number of configured v3 settings, see ::MBG_SNMP_V3_INFO_IDX + uint8_t num_v3_trap_receivers; ///< Number of configured v3 trap receivers, see ::MBG_SNMP_V3_TRAP_INFO_IDX + uint16_t listening_port; ///< snmpd listening port, 161 by default + uint16_t reserved_1; + uint32_t reserved_2[3]; + char location[MBG_MONITORING_STR_SIZE]; + char contact[MBG_MONITORING_STR_SIZE]; + char name[MBG_MONITORING_STR_SIZE]; + char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use + char reserved_4[MBG_MONITORING_STR_SIZE]; ///< Future use + +} MBG_SNMP_GLB_SETTINGS; + +#define _mbg_swab_snmp_glb_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->listening_port ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_SNMP_GLB_SETTINGS settings; + uint8_t supp_versions; ///< See ::MBG_SNMP_VERSION_MSKS + uint8_t max_v12_settings; ///< Only valid if ::supp_versions contains ::MBG_SNMP_VERSION_MSK_V1 or ::MBG_SNMP_VERSION_MSK_V2c + uint8_t max_v3_settings; ///< Only valid if ::supp_versions contains ::MBG_SNMP_VERSION_MSK_V3 + uint8_t max_v12_trap_receivers; ///< Only valid if ::supp_versions contains ::MBG_SNMP_VERSION_MSK_V1 or ::MBG_SNMP_VERSION_MSK_V2c + uint8_t max_v3_trap_receivers; ///< Only valid if ::supp_versions contains ::MBG_SNMP_VERSION_MSK_V3 + uint8_t reserved_1[3]; + uint32_t reserved_2[2]; + +} MBG_SNMP_GLB_INFO; + +#define _mbg_swab_snmp_glb_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_glb_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +enum MBG_SNMP_ACCESS_TYPES +{ + MBG_SNMP_ACCESS_TYPE_RO, + MBG_SNMP_ACCESS_TYPE_RW, + N_MBG_SNMP_ACCESS_TYPES +}; + + +#define MBG_SNMP_ACCESS_TYPE_STRS \ +{ \ + "Read-only", \ + "Read-write" \ +} + + + +typedef struct +{ + uint8_t version; ///< See ::MBG_MONITORING_SNMP_VERSIONS (1 or 2) + uint8_t access_type; ///< See ::MBG_SNMP_ACCESS_TYPES, ignore in trap settings + uint8_t reserved_1[2]; + uint32_t reserved_2[3]; + char community[MBG_MONITORING_STR_SIZE]; + +} MBG_SNMP_V12_SETTINGS; + +#define _mbg_swab_snmp_v12_settings( _p ) \ +do \ +{ \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + MBG_SNMP_V12_SETTINGS settings; + +} MBG_SNMP_V12_SETTINGS_IDX; + +#define _mbg_swab_snmp_v12_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v12_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_SNMP_V12_SETTINGS settings; + uint32_t reserved_1[4]; + +} MBG_SNMP_V12_INFO; + +#define _mbg_swab_snmp_v12_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v12_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + MBG_SNMP_V12_INFO info; + +} MBG_SNMP_V12_INFO_IDX; + +#define _mbg_swab_snmp_v12_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v12_info( &(_p)->info ); \ +} while ( 0 ) + + + +typedef struct +{ + uint8_t timeout; ///< In seconds + uint8_t retries; + uint16_t reserved_1; + uint32_t reserved_2[3]; + char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use + char reserved_4[MBG_MONITORING_STR_SIZE]; ///< Future use + MBG_SNMP_V12_SETTINGS v12_settings; + MBG_HOSTNAME receiver_addr; + uint16_t dest_port; ///< receiver destination port, 162 by default + uint16_t reserved_5; + +} MBG_SNMP_V12_TRAP_SETTINGS; + +#define _mbg_swab_snmp_v12_trap_settings( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v12_settings( &(_p)->v12_settings ); \ + _mbg_swab16( &(_p)->dest_port ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + MBG_SNMP_V12_TRAP_SETTINGS settings; + +} MBG_SNMP_V12_TRAP_SETTINGS_IDX; + +#define _mbg_swab_snmp_v12_trap_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v12_trap_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_SNMP_V12_TRAP_SETTINGS settings; + uint32_t reserved_1[4]; + +} MBG_SNMP_V12_TRAP_INFO; + +#define _mbg_swab_snmp_v12_trap_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v12_trap_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + MBG_SNMP_V12_TRAP_INFO info; + +} MBG_SNMP_V12_TRAP_INFO_IDX; + +#define _mbg_swab_snmp_v12_trap_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v12_trap_info( &(_p)->info ); \ +} while ( 0 ) + + + +enum MBG_SNMP_V3_SEC_LEVELS +{ + MBG_SNMP_V3_SEC_LEVEL_NO_AUTH_NO_PRIV, + MBG_SNMP_V3_SEC_LEVEL_AUTH_NO_PRIV, + MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV, + N_MBG_SNMP_V3_SEC_LEVELS +}; + +#define MBG_SNMP_V3_SEC_LEVEL_STRS \ +{ \ + "No auth no priv", \ + "Auth no priv", \ + "Auth priv" \ +} + + +enum MBG_SNMP_V3_AUTH_PROTOCOLS +{ + MBG_SNMP_V3_AUTH_PROTOCOL_NONE, + MBG_SNMP_V3_AUTH_PROTOCOL_MD5, + MBG_SNMP_V3_AUTH_PROTOCOL_SHA, + N_MBG_SNMP_V3_AUTH_PROTOCOLS +}; + +#define MBG_SNMP_V3_AUTH_PROTOCOL_STRS \ +{ \ + "None", \ + "MD5", \ + "SHA" \ +} + + +enum MBG_SNMP_V3_PRIV_PROTOCOLS +{ + MBG_SNMP_V3_PRIV_PROTOCOL_NONE, + MBG_SNMP_V3_PRIV_PROTOCOL_DES, + MBG_SNMP_V3_PRIV_PROTOCOL_AES, + N_MBG_SNMP_V3_PRIV_PROTOCOLS +}; + + +#define MBG_SNMP_V3_PRIV_PROTOCOL_STRS \ +{ \ + "None", \ + "DES", \ + "AES" \ +} + + + +typedef struct +{ + uint8_t access_type; ///< See ::MBG_SNMP_ACCESS_TYPES, ignore in trap settings + uint8_t sec_level; ///< See ::MBG_SNMP_V3_SEC_LEVEL + uint8_t auth_protocol; ///< See ::MBG_SNMP_V3_AUTH_PROTOCOLS if ::sec_level is + ///< ::MBG_SNMP_V3_SEC_LEVEL_AUTH_NO_PRIV or ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV + uint8_t priv_protocol; ///< See ::MBG_SNMP_V3_PRIV_PROTOCOLS if ::sec_level is + ///< ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV + uint32_t reserved_1[3]; + char user_name[MBG_MONITORING_STR_SIZE]; ///< Must be set + char auth_passwd[MBG_MONITORING_STR_SIZE]; ///< Passwd is for user if ::auth_protocol is ::MBG_SNMP_V3_SEC_LEVEL_AUTH_NO_PRIV or ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV + char sec_engine_id[MBG_MONITORING_STR_SIZE]; ///< Mandatory + char context_engine_id[MBG_MONITORING_STR_SIZE]; ///< Ignore + char context_name[MBG_MONITORING_STR_SIZE]; ///< Ignore + char reserved_2[MBG_MONITORING_STR_SIZE]; ///< Future use + char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use + char priv_passwd[MBG_MONITORING_STR_SIZE]; /// Encryption passwd if ::auth_protocol is ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV + uint32_t boots; ///< Number of system/deamon restarts -> Ignore + uint32_t time; ///< Timeticks since last "boots" event -> Ignore + uint32_t reserved_4[2]; + +} MBG_SNMP_V3_SETTINGS; + +#define _mbg_swab_snmp_v3_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->boots ); \ + _mbg_swab32( &(_p)->time ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + MBG_SNMP_V3_SETTINGS settings; + +} MBG_SNMP_V3_SETTINGS_IDX; + +#define _mbg_swab_snmp_v3_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v3_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_SNMP_V3_SETTINGS settings; + uint32_t reserved_1[4]; + +} MBG_SNMP_V3_INFO; + +#define _mbg_swab_snmp_v3_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v3_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + MBG_SNMP_V3_INFO info; + +} MBG_SNMP_V3_INFO_IDX; + +#define _mbg_swab_snmp_v3_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v3_info( &(_p)->info ); \ +} while ( 0 ) + + + +typedef struct +{ + uint8_t timeout; ///< In seconds + uint8_t retries; + uint8_t reserved_1[2]; + uint32_t reserved_2[3]; + MBG_SNMP_V3_SETTINGS v3_settings; + MBG_HOSTNAME receiver_addr; + uint16_t dest_port; ///< receiver destination port, 162 by default + uint16_t reserved_3; + +} MBG_SNMP_V3_TRAP_SETTINGS; + +#define _mbg_swab_snmp_v3_trap_settings( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v3_settings( &(_p)->v3_settings ); \ + _mbg_swab16( &(_p)->dest_port ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + MBG_SNMP_V3_TRAP_SETTINGS settings; + +} MBG_SNMP_V3_TRAP_SETTINGS_IDX; + +#define _mbg_swab_snmp_v3_trap_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v3_trap_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_SNMP_V3_TRAP_SETTINGS settings; + uint32_t reserved_1[4]; + +} MBG_SNMP_V3_TRAP_INFO; + +#define _mbg_swab_snmp_v3_trap_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v3_trap_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + MBG_SNMP_V3_TRAP_INFO info; + +} MBG_SNMP_V3_TRAP_INFO_IDX; + +#define _mbg_swab_snmp_v3_trap_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v3_trap_info( &(_p)->info ); \ +} while ( 0 ) + + + +enum MBG_EVENT_TYPES +{ + MBG_EVENT_TYPE_NTP_STOPPED, + MBG_EVENT_TYPE_NTP_NOT_SYNC, + MBG_EVENT_TYPE_NTP_SYNC, + MBG_EVENT_TYPE_LINK_DOWN, + MBG_EVENT_TYPE_LINK_UP, + MBG_EVENT_TYPE_HEARTBEAT, + N_MBG_EVENT_TYPES +}; + +#define MBG_EVENT_TYPE_STRS \ +{ \ + "NTP stopped", \ + "NTP not synchronized", \ + "NTP synchronized", \ + "Network link down", \ + "Network link up", \ + "Heartbeat" \ +} + +enum MBG_EVENT_SEVERITIES +{ + MBG_EVENT_SEVERITY_CRITICAL, + MBG_EVENT_SEVERITY_ERROR, + MBG_EVENT_SEVERITY_WARNING, + MBG_EVENT_SEVERITY_INFO, + MBG_EVENT_SEVERITY_SUCCESS, + N_MBG_EVENT_SEVERITIES +}; + +#define MBG_EVENT_SEVERITY_STRS \ +{ \ + "Critical", \ + "Error", \ + "Warning", \ + "Info", \ + "Success" \ +} + +enum MBG_EVENT_SEVERITY_MSKS +{ + MBG_EVENT_SEVERITY_MSK_CRITICAL = (1UL << MBG_EVENT_SEVERITY_CRITICAL), + MBG_EVENT_SEVERITY_MSK_ERROR = (1UL << MBG_EVENT_SEVERITY_ERROR), + MBG_EVENT_SEVERITY_MSK_WARNING = (1UL << MBG_EVENT_SEVERITY_WARNING), + MBG_EVENT_SEVERITY_MSK_INFO = (1UL << MBG_EVENT_SEVERITY_INFO), + MBG_EVENT_SEVERITY_MSK_SUCCESS = (1UL << MBG_EVENT_SEVERITY_SUCCESS) +}; + +typedef struct +{ + uint8_t severity; ///< See ::MBG_EVENT_SEVERITIES + uint8_t reserved_1; + uint16_t triggers; ///< See ::MBG_MONITORING_TYPE_MSKS if set in ::MBG_MONITORING_LIMITS::supp_types + uint16_t interval; ///< In seconds if ::MBG_EVENT_FLAG_MSK_INTERVAL is set in ::MBG_EVENT_INFO::supp_flags. 0 otherwise + uint16_t reserved_2; + uint32_t reserved_3[6]; + +} MBG_EVENT_SETTINGS; + +#define _mbg_swab_event_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->triggers ); \ + _mbg_swab16( &(_p)->interval ); \ +} while ( 0 ) + + + +/** + * @brief Structure for monitoring event settings + * + * @see ::MBG_EVENT_INFO_IDX + */ +typedef struct +{ + uint32_t idx; + MBG_EVENT_SETTINGS settings; + +} MBG_EVENT_SETTINGS_IDX; + +#define _mbg_swab_event_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_event_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +enum MBG_EVENT_SUPP_FLAGS +{ + MBG_EVENT_SUPP_FLAG_INTERVAL, ///< Event can be sent cyclical + N_MBG_EVENT_SUPP_FLAGS +}; + + +enum MBG_EVENT_SUPP_FLAG_MSKS +{ + MBG_EVENT_SUPP_FLAG_MSK_INTERVAL = ( 1UL << MBG_EVENT_SUPP_FLAG_INTERVAL ) +}; + + + +enum MBG_EVENT_FLAGS +{ + MBG_EVENT_FLAG_NOT_AVAIL, ///< Event is currently not available, i.e. card in slot has been removed + N_MBG_EVENT_FLAGS +}; + + +enum MBG_EVENT_FLAG_MSKS +{ + MBG_EVENT_FLAG_MSK_NOT_AVAIL = ( 1UL << MBG_EVENT_FLAG_NOT_AVAIL ) +}; + +#define MBG_OWN_EVENT_CHASSIS 0xFF +#define MBG_OWN_EVENT_SLOT 0xFF +#define MBG_INV_EVENT_PORT 0xFF + + + +typedef struct +{ + MBG_EVENT_SETTINGS settings; + uint16_t type; ///< See ::MBG_EVENT_TYPES + uint8_t chassis_idx; ///< Index of the associated IMS chassis + uint8_t slot_idx; ///< Index of the associated IMS slot + uint8_t port_idx; ///< Index of the associated IO port + uint8_t reserved_1; ///< Reserved, currently 0 + uint16_t reserved_2; ///< Reserved, currently 0 + + uint16_t supp_severities; ///< See ::MBG_EVENT_SEVERITY_MSKS + uint16_t supp_flags; ///< See ::MBG_EVENT_SUPP_FLAG_MSKS + uint16_t supp_triggers; ///< See ::MBG_MONITORING_TYPE_MSKS + uint16_t flags; ///< See ::MBG_EVENT_FLAG_MSKS + + uint32_t reserved_3[4]; + +} MBG_EVENT_INFO; + +#define _mbg_swab_event_info( _p ) \ +do \ +{ \ + _mbg_swab_event_settings( &(_p)->settings ); \ + _mbg_swab16( &(_p)->type ); \ + _mbg_swab16( &(_p)->supp_severities ); \ + _mbg_swab16( &(_p)->supp_flags ); \ + _mbg_swab16( &(_p)->supp_triggers ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Structure for monitoring event info + * + * @note idx represents the event type, see ::MBG_EVENT_TYPES + * Before requesting the struct, its availability should be checked + * in ::MBG_MONITORING_LIMITS::supp_events. + * + * @see ::MBG_EVENT_TYPES + * @see ::MBG_MONITORING_LIMITS + */ +typedef struct +{ + uint32_t idx; + MBG_EVENT_INFO info; + +} MBG_EVENT_INFO_IDX; + +#define _mbg_swab_event_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_event_info( &(_p)->info ); \ +} while ( 0 ) + + + +typedef struct +{ + uint8_t snmp_cfg_counter; ///< Updated (increased) when SNMP config changes + uint8_t email_cfg_counter; ///< Updated (increased) when Email config changes + uint8_t syslog_cfg_counter; ///< Updated (increased) when Syslog config changes + uint8_t event_cfg_counter; ///< Updated (increased) when event config changes + uint32_t reserved_2[3]; + +} MBG_MONITORING_STATUS; + +#define _mbg_swab_monitoring_status( _p ) \ +do \ +{ \ +} while ( 0 ) + + + +enum MBG_EVENT_STATUS_FLAGS +{ + MBG_EVENT_STATUS_FLAG_ACTIVE, ///< Event is currently active + N_MBG_EVENT_STATUS_FLAGS +}; + + +enum MBG_EVENT_STATUS_FLAG_MSKS +{ + MBG_EVENT_STATUS_FLAG_MSK_ACTIVE = (1UL << MBG_EVENT_STATUS_FLAG_ACTIVE) +}; + + + +typedef struct +{ + uint16_t flags; ///< See ::MBG_EVENT_STATUS_FLAGS + uint16_t reserved_1; + uint32_t last_triggered; ///< Unix timestamp when this event has been triggered + uint32_t reserved_2[6]; + +} MBG_EVENT_STATUS; + +#define _mbg_swab_event_status( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab32( &(_p)->last_triggered ); \ +} while ( 0 ) + + + +typedef struct +{ + uint16_t idx; + MBG_EVENT_STATUS status; + +} MBG_EVENT_STATUS_IDX; + +#define _mbg_swab_event_status_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_event_status( &(_p)->status ); \ +} while ( 0 ) + +/** @} defgroup group_monitoring */ + + +/** + * @defgroup group_usb_lock + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_USB_LOCK is set in the extended device features. + * Feature can electrically disconnect an USB slave device from + * the USB host bus. It cannot be reset via software, it's a one way action only. + * + * TODO: Add proper Doxygen documentation + * + * @{ */ + + +enum MBG_USB_LOCK_FLAGS +{ + MBG_USB_LOCK_FLAG_ACTIVE, ///< USB Connection is interrupted + N_MBG_USB_LOCK_FLAGS +}; + + +enum MBG_USB_LOCK_FLAG_MSKS +{ + MBG_USB_LOCK_FLAG_MSK_ACTIVE = (1UL << MBG_USB_LOCK_FLAG_ACTIVE) ///< See ::MBG_USB_LOCK_FLAG_ACTIVE +}; + + +typedef struct +{ + uint8_t flags; ///< ::MBG_USB_LOCK_FLAG_MSKS + uint8_t reserved_1[3]; + uint32_t reserved_2[3]; + +} MBG_USB_LOCK_SETTINGS; + +#define _mbg_swab_usb_lock_settings( _p ) do {} while ( 0 ) + + +typedef struct +{ + MBG_USB_LOCK_SETTINGS settings; + uint8_t supp_flags; ///< ::MBG_USB_LOCK_FLAG_MSKS + uint8_t reserved_1[3]; + uint32_t reserved_2[3]; + +} MBG_USB_LOCK_INFO; + +#define _mbg_swab_usb_lock_info( _p ) \ +do \ +{ \ + _mbg_swab_usb_lock_settings( _p ); \ +} while ( 0 ) + + +typedef struct +{ + uint8_t flags; ///< ::MBG_USB_LOCK_FLAG_MSKS + uint8_t reserved_1[3]; + uint32_t reserved_2[3]; + +} MBG_USB_LOCK_STATUS; + +#define _mbg_swab_usb_lock_status( _p ) do {} while ( 0 ) + + +/** @} defgroup group_usb_lock */ + + #if defined( _USING_BYTE_ALIGNMENT ) #pragma pack() // set default alignment #undef _USING_BYTE_ALIGNMENT diff --git a/mbglib/common/gpsserio.c b/mbglib/common/gpsserio.c index d0381aa..66ed43b 100644 --- a/mbglib/common/gpsserio.c +++ b/mbglib/common/gpsserio.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: gpsserio.c 1.13.1.3 2015/07/24 11:07:17Z martin TEST $ + * $Id: gpsserio.c 1.13.1.16 2016/11/15 15:43:44Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -11,7 +11,33 @@ * * ----------------------------------------------------------------------- * $Log: gpsserio.c $ - * Revision 1.13.1.3 2015/07/24 11:07:17Z martin + * Revision 1.13.1.16 2016/11/15 15:43:44Z martin + * Account for modified mbgserio functions. + * Revision 1.13.1.15 2016/06/29 11:59:03 philipp + * Extended socket API by TCP client + * Revision 1.13.1.14 2016/06/03 11:10:28 thomas-b + * Fixed Windows compatibility issues in xmt_tbuff + * Revision 1.13.1.13 2016/03/23 13:45:47 thomas-b + * Fixed check for buffer overflow and return appropriate rc + * Revision 1.13.1.12 2016/03/21 13:27:32 martin + * *** empty log message *** + * Revision 1.13.1.11 2016/03/18 06:15:30 thomas-b + * Fixed call of mbg_memcpy_reversed + * Revision 1.13.1.10 2016/03/17 15:54:59 martin + * Use mbg_memcpy..() functions. + * Revision 1.13.1.9 2016/03/11 10:16:38 thomas-b + * Added function chk_hdr_rcvd + * Revision 1.13.1.8 2015/12/10 16:30:15 martin + * *** empty log message *** + * Revision 1.13.1.7 2015/12/09 10:21:22 martin + * *** empty log message *** + * Revision 1.13.1.6 2015/11/02 10:12:26 martin + * *** empty log message *** + * Revision 1.13.1.5 2015/09/15 15:31:52 martin + * Include sys/time.h to fix a compiler warning. + * Revision 1.13.1.4 2015/09/08 14:51:59 martin + * Added some comments regarding mutex support. + * Revision 1.13.1.3 2015/07/24 11:07:17 martin * Revision 1.13.1.2 2015/05/20 12:21:23 martin * Revision 1.13.1.1 2015/05/19 13:20:21 daniel * Preliminary support for USB_DIRECT_IO @@ -65,6 +91,7 @@ #undef _GPSSERIO #include <mbgerror.h> +#include <str_util.h> #include <string.h> #include <stdlib.h> @@ -72,6 +99,7 @@ #if defined( MBG_TGT_POSIX ) #include <unistd.h> + #include <sys/time.h> #endif #if _USE_ENCRYPTION @@ -230,6 +258,28 @@ int chk_data_csum( const MBG_MSG_BUFF *pmb ) +/*HDR*/ +/** + * @brief Checks if a binary message header has been completely received + * + * @param[in] prctl ::MBG_MSG_RCV_CTL that shall be checked + * + * @return One of the @ref MBG_RETURN_CODES + */ +int chk_hdr_rcvd( const MBG_MSG_RCV_CTL *prctl ) +{ + if ( prctl->rcv_state.cnt == 0 ) + return MBG_ERR_GENERIC; //### TODO different return code? + + if ( ( prctl->rcv_state.flags & MBG_MSG_RCV_CTL_RCVD_HDR ) == 0 ) + return MBG_ERR_BUSY; + + return MBG_SUCCESS; + +} // chk_hdr_rcvd + + + #if _USE_ENCRYPTION #ifdef MBG_TGT_WIN32 @@ -292,7 +342,7 @@ int encrypt_message( MBG_MSG_CTL *pmctl, CRYPT_MSG_PREFIX *pcmp, MBG_MSG_BUFF *p // copy AES init vector into encrypted message //##++ check types of aes_initvect fields - memcpy( pcmp->aes_initvect, pmctl->aes_initvect, sizeof( pcmp->aes_initvect ) ); + mbg_memcpy( pcmp->aes_initvect, pmctl->aes_initvect, sizeof( pcmp->aes_initvect ) ); pcmp->hdr.cmd = GPS_CRYPTED_PACKET; pcmp->hdr.len = (uint16_t) ( n_bytes + sizeof( pcmp->aes_initvect ) ); @@ -323,7 +373,7 @@ int decrypt_message( MBG_MSG_CTL *pmctl ) MBG_MSG_BUFF *pmb = prctl->pmb; CRYPT_MSG_DATA *pcmd = &pmb->u.crypt_msg_data; int rc; - int len; + size_t len; if ( pmb->hdr.len < AES_BLOCK_SIZE ) return 0; @@ -336,12 +386,12 @@ int decrypt_message( MBG_MSG_CTL *pmctl ) if ( rc < 0 ) // decryption error { - prctl->flags |= MBG_MSG_RCV_CTL_DECRYPT_ERR; + prctl->rcv_state.flags |= MBG_MSG_RCV_CTL_DECRYPT_ERR; return MBG_ERR_DECRYPT; } // packet decrypted successfully. - prctl->flags |= MBG_MSG_RCV_CTL_DECRYPTED; + prctl->rcv_state.flags |= MBG_MSG_RCV_CTL_DECRYPTED; // If the wrong password has been used for decryption // then decryption may have been formally successful, @@ -362,7 +412,7 @@ int decrypt_message( MBG_MSG_CTL *pmctl ) len = sizeof( MBG_STD_MSG ); // copy the decrypted message to the head of the buffer - memcpy( pmb, &pcmd->std_msg, len ); + mbg_memcpy( pmb, &pcmd->std_msg, len ); // now check the CSUMs of the decrypted packet @@ -408,42 +458,17 @@ void set_encryption_mode( MBG_MSG_CTL *pmctl, int mode, const char *key ) -static /*HDR*/ -/** - * @brief Copy array of bytes in reverse order - * - * Can be used if the destination address is in the same buffer - * behind the source address, so the source address would be - * overwritten by a normal memcpy(). - * - * @param[out] dst Destination address behind the source address - * @param[in] src Source address - * @param[in] n_bytes Number of bytes to copy - */ -void memcpy_reverse( void *dst, const void *src, int n_bytes ) -{ - if ( n_bytes ) // just to be sure it isn't 0 - { - uint8_t *dstp = ( (uint8_t *) dst ) + n_bytes; - uint8_t *srcp = ( (uint8_t *) src ) + n_bytes; - - while ( --n_bytes ) - *(--dstp) = *(--srcp); - } - -} // memcpy_reverse - - - /*HDR*/ /** * @brief Complete message header and transmit message * - * Compute checksums and complete the message header, - * then transmit both header and data. The caller must - * have copied the data to be sent to the data field - * of the transmit buffer and have set up the cmd and - * len fields of the message header. + * Compute checksums and complete the message header, then + * transmit both header and data. The caller must have copied + * the data to be sent to the data field of the transmit buffer + * and have set up the cmd and len fields of the message header. + * + * This function doesn't protect access to the device by a mutex, + * so the calling function has to take care of the mutex handling. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to XBP address specifier @@ -469,10 +494,9 @@ int xmt_tbuff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) // the original msg into an XBP msg. if ( p_addr ) { - // Move the original msg to the data part of an XBP msg - // don't just use memcpy here since the destination memory area + // Move the original msg to the data part of an XBP msg which // overlaps the source memory area. - memcpy_reverse( &pmb->u.xbp_msg_data.std_msg.hdr, &pmb->hdr, msg_len ); + mbg_memcpy_reversed( &pmb->u.xbp_msg_data.std_msg.hdr, &pmb->hdr, msg_len ); // Fill in the specified XBP address. pmb->u.xbp_msg_data.xbp_addr = *p_addr; @@ -511,11 +535,11 @@ int xmt_tbuff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) #if _USE_SERIAL_IO case MBG_CONN_TYPE_SERIAL: { - MBG_PORT_HANDLE port_handle = pmctl->st.serio.port_handle; + MBGSERIO_DEV *mdev = pmctl->st.p_serio; // Note: encrypted msgs over serial are not yet supported. - rc = mbgserio_write( port_handle, &soh, sizeof( soh ) ); + rc = mbgserio_write( mdev, &soh, sizeof( soh ) ); if ( rc < 0 ) // error goto out; @@ -523,7 +547,7 @@ int xmt_tbuff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) if ( rc != sizeof( soh ) ) goto out_write_failed; - rc = mbgserio_write( port_handle, pmb, msg_len ); + rc = mbgserio_write( mdev, pmb, msg_len ); if ( rc < 0 ) // error goto out; @@ -540,7 +564,7 @@ int xmt_tbuff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) // Yet this is anyway supported under Windows only, so we can // safely use Windows-specific types as expected by the FTDI API. DWORD bytes_written; - FT_HANDLE port_handle = pmctl->st.ftdiio.port_handle; + FT_HANDLE port_handle = pmctl->st.ftdi.port_handle; FT_STATUS status; // Note: encrypted msgs over serial are not yet supported. @@ -586,20 +610,20 @@ int xmt_tbuff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) #if _USE_ENCRYPTION if ( pmctl->xmt.xfer_mode == MBG_XFER_MODE_ENCRYPTED ) { - memcpy( p, &cm_pfx, sizeof( cm_pfx ) ); + mbg_memcpy( p, &cm_pfx, sizeof( cm_pfx ) ); p += sizeof( cm_pfx ); msg_len += sizeof( cm_pfx ); } #endif - memcpy( p, pmb, rc ); + mbg_memcpy( p, pmb, rc ); p += rc; msg_len += sizeof( soh ); // also account for SOH - rc = sendto( pmctl->st.sockio.sockfd, sock_xmt_buffer, msg_len, 0, - (const struct sockaddr *) &pmctl->st.sockio.addr, - sizeof( pmctl->st.sockio.addr ) ); + rc = sendto( pmctl->st.sockio.sockfd, (const char*)sock_xmt_buffer, msg_len, 0, + (const struct sockaddr *) pmctl->st.sockio.p_addr, + pmctl->st.sockio.addrlen ); if ( rc < 0 ) // on error: -1 on Linux, SOCKET_ERROR == -1 on Windows { @@ -624,11 +648,11 @@ int xmt_tbuff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) #endif *p = soh; - memcpy( p + 1, pmb, msg_len ); + mbg_memcpy( p + 1, pmb, msg_len ); msg_len++; // also account for SOH // Note: encrypted msgs over USB are not yet supported. - rc = mbgusbio_write( &pmctl->st.usbio, p, msg_len, 1000 ); + rc = mbgusbio_write( &pmctl->st.usbio, p, msg_len ); if ( rc < 0 ) // error goto out; @@ -651,7 +675,7 @@ int xmt_tbuff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) #endif *p = soh; - memcpy( p + 1, pmb, msg_len ); + mbg_memcpy( p + 1, pmb, msg_len ); msg_len++; // also account for SOH // Note: encrypted msgs over direct USB I/O are not yet supported. @@ -692,12 +716,19 @@ out: /** * @brief Send a binary command message without parameters * + * This function doesn't protect access to the device by a mutex, + * so the calling function has to take care of the mutex handling, + * or ::mbgextio_xmt_cmd which does so should be called preferably + * from applications. + * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to XBP address specifier * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES * * @return One of the @ref MBG_RETURN_CODES * + * @see ::mbgextio_xmt_cmd + * @see ::mbgextio_xmt_cmd_us * @see ::xmt_cmd_us */ int xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) @@ -717,6 +748,11 @@ int xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) /** * @brief Send a binary command message with ushort (16 bit) parameter * + * This function doesn't protect access to the device by a mutex, + * so the calling function has to take care of the mutex handling, + * or ::mbgextio_xmt_cmd_us which does so should be called preferably + * from applications. + * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to XBP address specifier * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES @@ -724,6 +760,8 @@ int xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) * * @return One of the @ref MBG_RETURN_CODES * + * @see ::mbgextio_xmt_cmd_us + * @see ::mbgextio_xmt_cmd * @see ::xmt_cmd */ int xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t us ) @@ -742,6 +780,23 @@ int xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_ /*HDR*/ /** + * @brief Init reception of a binary message + * + * @param[in,out] prctl Pointer to a valid receive control structure + * + * @see ::check_transfer + */ +void init_transfer( MBG_MSG_RCV_CTL *prctl ) +{ + memset( &prctl->rcv_state, 0, sizeof( prctl->rcv_state ) ); + prctl->rcv_state.cur = (uint8_t *) prctl->pmb; // point to start of buffer + +} // init_transfer + + + +/*HDR*/ +/** * @brief Check an incoming data stream for a binary message * * Check the sequence of incoming characters for blocks of @@ -749,6 +804,9 @@ int xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_ * which is part of the ::MBG_MSG_RCV_CTL structure and the * caller checks the return value to get the receive status. * + * This function doesn't protect access to the device by a mutex, + * so the calling function has to take care of the mutex handling. + * * @param[in,out] prctl Pointer to a valid receive control structure * @param[in] c A byte from the incoming data stream * @@ -759,16 +817,15 @@ int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c ) MBG_MSG_BUFF *pmb = prctl->pmb; MSG_HDR *pmh = &pmb->hdr; - if ( prctl->cnt == 0 ) /* not receiving yet */ + if ( prctl->rcv_state.cnt == 0 ) /* not receiving yet */ { if ( c != START_OF_HEADER ) return TR_WAITING; /* ignore this character */ /* initialize receiving */ - mbg_tmo_get_time( &prctl->tstamp ); - prctl->cur = (uint8_t *) pmb; /* first byte of buffer */ - prctl->cnt = sizeof( *pmh ); /* prepare to rcv msg header */ - prctl->flags = 0; + init_transfer( prctl ); + mbg_tmo_get_time( &prctl->rcv_state.tstamp ); + prctl->rcv_state.cnt = sizeof( *pmh ); /* prepare to rcv msg header */ return TR_RECEIVING; } @@ -776,30 +833,30 @@ int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c ) /* SOH has already been received */ - if ( prctl->cur < &prctl->pmb->u.bytes[prctl->buf_size] ) + if ( prctl->rcv_state.cur < ( (uint8_t *) prctl->pmb + sizeof( *prctl->pmb ) ) ) { - *prctl->cur = c; /* save incoming character */ - prctl->cur++; + *prctl->rcv_state.cur = c; /* save incoming character */ + prctl->rcv_state.cur++; } else /* don't write beyond buffer */ - prctl->flags |= MBG_MSG_RCV_CTL_OVERFLOW; + prctl->rcv_state.flags |= MBG_MSG_RCV_CTL_OVERFLOW; - prctl->cnt--; + prctl->rcv_state.cnt--; - if ( prctl->cnt ) /* transfer not complete */ + if ( prctl->rcv_state.cnt ) /* transfer not complete */ return TR_RECEIVING; /* cnt == 0, so the header or the whole message is complete */ - if ( !( prctl->flags & MBG_MSG_RCV_CTL_RCVD_HDR ) ) /* header complete now */ + if ( !( prctl->rcv_state.flags & MBG_MSG_RCV_CTL_RCVD_HDR ) ) /* header complete now */ { unsigned int data_len; if ( chk_hdr_csum( pmh ) < 0 ) /* error */ { - prctl->cnt = 0; /* restart receiving */ + init_transfer( prctl ); /* restart receiving */ return TR_CSUM_HDR; /* invalid header checksum received */ } @@ -808,26 +865,27 @@ int check_transfer( MBG_MSG_RCV_CTL *prctl, uint8_t c ) data_len = pmh->len; - prctl->cnt = data_len; /* save number of bytes to wait for */ - prctl->flags |= MBG_MSG_RCV_CTL_RCVD_HDR; /* flag header complete */ + prctl->rcv_state.cnt = data_len; /* save number of bytes to wait for */ + prctl->rcv_state.flags |= MBG_MSG_RCV_CTL_RCVD_HDR; /* flag header complete */ if ( data_len > ( prctl->buf_size - sizeof( *pmh ) ) ) - prctl->flags |= MBG_MSG_RCV_CTL_MSG_TOO_LONG; + prctl->rcv_state.flags |= MBG_MSG_RCV_CTL_MSG_TOO_LONG; return TR_RECEIVING; } + if ( prctl->rcv_state.flags & MBG_MSG_RCV_CTL_OVERFLOW ) + return TR_OVERFLOW; /* Header and data have been received. The header checksum has been */ /* checked, now recompute and compare data checksum. */ if ( chk_data_csum( pmb ) < 0 ) /* error */ { - prctl->cnt = 0; /* restart receiving */ + init_transfer( prctl ); /* restart receiving */ return TR_CSUM_DATA; /* invalid header checksum received */ } - msg_complete: return TR_COMPLETE; /* message complete, must be evaluated */ diff --git a/mbglib/common/gpsserio.h b/mbglib/common/gpsserio.h index d1d4d26..7154559 100644 --- a/mbglib/common/gpsserio.h +++ b/mbglib/common/gpsserio.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: gpsserio.h 1.48.1.1 2015/07/24 11:07:39Z martin TEST $ + * $Id: gpsserio.h 1.48.1.90 2017/04/11 06:42:42Z philipp TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -31,7 +31,190 @@ * * ----------------------------------------------------------------------- * $Log: gpsserio.h $ - * Revision 1.48.1.1 2015/07/24 11:07:39Z martin + * Revision 1.48.1.90 2017/04/11 06:42:42Z philipp + * Renamed MBG_USB_INTR structures to MBG_USB_LOCK + * Revision 1.48.1.89 2017/04/11 05:29:57 philipp + * Added commands, structures and defines for feature USB interrupt + * Revision 1.48.1.88 2017/03/27 10:38:26 thomas-b + * Added GPS command to read and write PTPv1 common datasets + * Revision 1.48.1.87 2017/03/03 06:43:48 thomas-b + * Removed DEBUG restriction for NTP server mode structures, added several new NTP structures + * Revision 1.48.1.86 2017/03/02 14:04:56 gregoire + * Support of new NTP structures added + * Revision 1.48.1.85 2017/03/02 08:34:53 gregoire + * New cmds for NTP strucutres added + * Revision 1.48.1.84 2017/02/21 15:54:55 thomas-b + * Added GPS commands for monitoring events and status and extended MSG_BUF + * Revision 1.48.1.83 2017/02/16 13:01:23 thomas-b + * Renamed command GPS_PTP_V2_PORT_DS to GPS_PTP_V2_PORT_DS_IDX + * Revision 1.48.1.82 2017/02/16 12:10:08 martin + * *** empty log message *** + * Revision 1.48.1.81 2017/02/16 08:13:22 thomas-b + * Added GPS commands to query and send PTPv2 common datasets + * Revision 1.48.1.80 2017/02/15 16:15:15 martin + * Renamed GNSS_SV_INFO to GNSS_SV_STATUS. + * Revision 1.48.1.79 2017/02/10 14:41:36 martin + * New extended feature MBG_XFEATURE_GNSS_SV_INFO + * and associated structures. + * Revision 1.48.1.78 2017/02/08 07:12:41 thomas-b + * Removed one more unnecessary GPS command for SNMP + * Revision 1.48.1.77 2017/02/08 07:05:37 philipp + * Use less GPS command codes for SNMP monitoring + * Revision 1.48.1.76 2017/02/06 15:42:29 philipp + * Added SNMP monitoring structures to MBG_MSG_CTL + * Revision 1.48.1.75 2017/02/06 13:09:53 philipp + * Added GPS monitoring commands + * Revision 1.48.1.74 2017/01/27 08:17:40 martin + * Fixed macro syntax. + * Revision 1.48.1.73 2016/11/22 10:33:16 philipp + * Implemented I/O ports + * Revision 1.48.1.72 2016/11/15 15:43:57 martin + * Account for modified mbgserio functions. + * Revision 1.48.1.71 2016/10/27 07:59:33 martin + * *** empty log message *** + * Revision 1.48.1.70 2016/10/25 07:48:28 martin + * Doxygen fixes. + * Revision 1.48.1.69 2016/10/14 08:18:52 thomas-b + * Decreased poll timeout + * Revision 1.48.1.68 2016/10/10 10:17:52 thomas-b + * Added new commands for MBG_XFEATURE_UCAP_NETWORK + * Revision 1.48.1.67 2016/09/30 05:36:43 thomas-b + * Decreased socket poll timeout + * Revision 1.48.1.66 2016/09/29 07:22:10 thomas-b + * Improved comments for new commands + * Revision 1.48.1.65 2016/09/28 13:44:08 thomas-b + * Added commands and structures for MBG_NET_CFG_API stage 2 + * Revision 1.48.1.64 2016/08/23 09:18:33 udo + * changed Time Mon Inst Info structure for both read/write + * Revision 1.48.1.63 2016/08/16 12:48:30 gregoire.diehl + * Fixed default build. + * Revision 1.48.1.62 2016/08/15 09:30:55 udo + * added TIME_MON_TARGET_EXT_DATA_SET + * Revision 1.48.1.61 2016/08/11 11:30:43 martin + * Conditionally support time monitoring API. + * Revision 1.48.1.60 2016/08/11 10:25:37 martin + * Started to support time_mon. + * Revision 1.48.1.59 2016/08/09 07:10:07 martin + * *** empty log message *** + * Revision 1.48.1.58 2016/08/04 14:51:25 martin + * Moved some compatibility definitions from gpsserio.h to mbg_tgt.h. + * Revision 1.48.1.57 2016/07/07 14:22:05 martin + * *** empty log message *** + * Revision 1.48.1.56 2016/07/07 13:08:44 andre.hartmann + * added support for mbg_clock_res_info + * Revision 1.48.1.55 2016/06/29 11:59:11Z philipp + * Extended socket API by TCP client + * Revision 1.48.1.54 2016/06/13 15:02:13 andre + * Revision 1.48.1.53 2016/06/02 10:15:38Z philipp + * Renaming all MBG_EXT_REV_INFO related stuff to MBG_EXT_SYS_INFO. + * Revision 1.48.1.52 2016/05/18 07:35:05 andre + * added command for XMR_METRICS_IDX + * Revision 1.48.1.51 2016/04/25 14:45:21Z martin + * Moved TLV, transaction, and boot stuff from _PRELIMINARY_CODE + * to standard section. + * Revision 1.48.1.50 2016/04/20 09:26:10 philipp + * Moved all HPS-PTP related structures to gpspriv.h and removed related extended feature bit from gpsdefs.h. + * Also removed functions from mbgextio and xdevfeat since HPS-PTP handling needs a redesign concerning structures. + * Thus, handle everything explicitly for now! + * -> Redesing this A.S.A.P.!!! + * Revision 1.48.1.49 2016/04/07 13:50:08 martin + * New command GPS_EXT_REV_INFO. + * Revision 1.48.1.48 2016/03/24 14:08:49 martin + * *** empty log message *** + * Revision 1.48.1.47 2016/03/24 09:16:19 martin + * Reworked device power control definitions. + * Revision 1.48.1.46 2016/03/23 13:45:47 thomas-b + * Fixed check for buffer overflow and return appropriate rc + * Revision 1.48.1.45 2016/03/21 13:27:32 martin + * *** empty log message *** + * Revision 1.48.1.44 2016/03/16 16:07:03 martin + * *** empty log message *** + * Revision 1.48.1.43 2016/03/15 14:55:07 martin + * Modified LNE and LED API. + * Revision 1.48.1.42 2016/03/11 10:16:38 thomas-b + * Added function chk_hdr_rcvd + * Revision 1.48.1.41 2016/03/01 09:18:57 udo + * added LNE_PWR_STATE + * Revision 1.48.1.40 2016/02/22 08:51:51 udo + * added LNE_INFO_EXT + * Revision 1.48.1.39 2016/02/18 11:26:21 udo + * added MBG_LNE_LED_STATUS to data types of binary protocol + * Revision 1.48.1.38 2016/02/18 08:58:45 udo + * added LNE_LED_STATE in GPS_CMD_CODES + * Revision 1.48.1.37 2016/02/17 14:35:22 udo + * used MBG_TIME_MON_TARGET_STATUS_IDX + * Revision 1.48.1.36 2016/02/11 09:57:41 paul + * withdraw rename in MSG_DATA + * updated comment + * Revision 1.48.1.35 2016/02/09 13:21:20Z paul + * renamd GPS_FDM_SET_PLT to GPS_FDM_SET_TD + * changed NANO_TIME_64 field to int32_t in MSG_DATA union + * Revision 1.48.1.34 2016/02/08 10:59:45Z martin + * *** empty log message *** + * Revision 1.48.1.33 2016/02/08 10:43:56 martin + * Added command GPS_FDM_SET_PLT. + * Revision 1.48.1.32 2016/01/19 14:12:29 udo + * improve time monitor structures + * Revision 1.48.1.31 2016/01/18 08:42:44 udo + * added support for PTP Time Monitoring on TSU/HPS100 + * Revision 1.48.1.30 2016/01/15 08:54:41 martin + * *** empty log message *** + * Revision 1.48.1.29 2016/01/14 08:35:48 martin + * *** empty log message *** + * Revision 1.48.1.28 2016/01/14 08:28:53 martin + * Fixed a typo. + * Revision 1.48.1.27 2016/01/13 15:09:19 martin + * Support XMR_STATS. + * Revision 1.48.1.26 2015/12/10 16:30:15 martin + * *** empty log message *** + * Revision 1.48.1.25 2015/12/10 11:52:10 martin + * *** empty log message *** + * Revision 1.48.1.24 2015/12/01 11:54:26 martin + * Support TLV features. + * Revision 1.48.1.23 2015/11/30 16:51:03 martin + * New command GPS_SAVE_CFG. + * Revision 1.48.1.22 2015/11/26 09:57:32 martin + * *** empty log message *** + * Revision 1.48.1.21 2015/11/25 16:56:01 martin + * Started to implement extended features. + * Merged Philipp's changes from the 1.48.1.19.1.x branch. + * Revision 1.48.1.20 2015/10/09 11:09:16 martin + * *** empty log message *** + * Revision 1.48.1.19 2015/10/06 14:11:23 martin + * Account for library module chk_tstr renamed to mbg_tstr. + * Revision 1.48.1.18 2015/10/01 07:34:34 martin + * Fixed a typo. + * Revision 1.48.1.17 2015/09/24 13:31:01 philipp + * Removed duplicate GPS_GET_DIAG_FILE command + * Revision 1.48.1.16 2015/09/24 13:12:54 philipp + * Changed naming to be more common + * Revision 1.48.1.15 2015/09/23 12:34:07 daniel + * Added two new HPS commands for reboot and diag file + * Revision 1.48.1.14 2015/09/15 13:25:58 martin + * *** empty log message *** + * Revision 1.48.1.13 2015/09/14 07:51:40 werner + * Revision 1.48.1.12 2015/09/14 07:48:32Z martin + * *** empty log message *** + * Revision 1.48.1.11 2015/09/14 07:22:26 martin + * *** empty log message *** + * Revision 1.48.1.10 2015/09/11 12:04:51 martin + * *** empty log message *** + * Revision 1.48.1.9 2015/09/10 12:49:11 martin + * New code GPS_FDM_FREQ. + * Revision 1.48.1.8 2015/09/10 07:42:37 daniel + * Added preliminary commands GPS_BEGIN_TRANSACTION, GPS_END_TRANSACTION + * Revision 1.48.1.7 2015/09/08 14:22:44 martin + * Revision 1.48.1.6 2015/09/08 12:13:46 martin + * Revision 1.48.1.5 2015/09/07 08:33:03 philipp + * Added GPS commands GPS_GET_DIAG_FILE and GPS_DO_FW_UPDATE to _PRELIMINARY_CODE section + * Revision 1.48.1.4 2015/09/04 09:19:49 daniel + * Added GPS_REFCLOCK_STATE and GPS_TSU_VERSION to _PREMININARY_CODE + * Revision 1.48.1.3 2015/09/02 16:42:20 martin + * Preliminary code which is only included if a preprocessor symbol + * _PRELIMINARY_CODE is defined in the project Makefile. + * Revision 1.48.1.2 2015/08/20 14:50:39 martin + * Account for renamed symbol in a different module. + * Revision 1.48.1.1 2015/07/24 11:07:39 martin * Revision 1.48 2015/07/06 15:23:51 martin * Updated function prototypes. * Revision 1.47 2015/05/13 13:52:57 martin @@ -231,11 +414,12 @@ * overridden by global definitions, if required. */ -#if _IS_MBG_FIRMWARE +#if !_IS_MBG_FIRMWARE + #include <xdevfeat.h> +#else // This handle type in not used by the firmware. // However, we define it to avoid build errors. typedef int MBG_HANDLE; - #endif @@ -324,6 +508,11 @@ #endif #endif +/* Control inclusion of time_mon.h */ +#ifndef _USE_TIME_MON + #define _USE_TIME_MON 0 +#endif + /* Control inclusion of non-public declarations */ #ifndef _USE_GPSPRIV /* by default do include if building a GPS firmware */ @@ -375,11 +564,26 @@ #include <pcpsdefs.h> #endif +#if _USE_TIME_MON && defined( _PRELIMINARY_CODE ) + #include <time_mon.h> +#else // dummy declarations to avoid compiler errors with function prototypes + typedef int MBG_TIME_MON_LIMITS; + typedef int MBG_TIME_MON_INST_SETTINGS; + typedef int MBG_TIME_MON_INST_SETTINGS_IDX; + typedef int MBG_TIME_MON_INST_INFO; + typedef int MBG_TIME_MON_INST_INFO_IDX; + typedef int MBG_TIME_MON_TARGET_SETTINGS; + typedef int MBG_TIME_MON_TARGET_SETTINGS_IDX; + typedef int MBG_TIME_MON_TARGET_STATUS; + typedef int MBG_TIME_MON_TARGET_STATUS_IDX; + typedef int MBG_TIME_MON_TARGET_EXT_DATA_SET_IDX; +#endif + #if _USE_GPSPRIV #include <gpspriv.h> #endif -#if _USE_RCV_TSTAMP +#if _USE_RCV_TSTAMP || defined( _DEBUG_MSG_TIMING ) #include <mbg_tmo.h> #endif @@ -405,7 +609,6 @@ extern "C" { */ enum TR_STATUS_CODES { - TR_COMPLETE_TSTR = 3, ///< The optional time string check has detected a valid time string TR_COMPLETE = 2, ///< A binary message has been received successfully TR_RECEIVING = 1, ///< Binary reception in progress, i.e. after START_OF_HEADER received TR_WAITING = 0, ///< Waiting for a binary message, i.e. no START_OF_HEADER received, yet @@ -416,7 +619,8 @@ enum TR_STATUS_CODES TR_OPEN_ERR = -5, ///< Failed to open connection. TR_IO_ERR = -6, ///< I/O error for the specified connection TR_AUTH_ERR = -7, ///< Authentication error for the specified LAN connection - TR_RCVD_NACK = -8 ///< Received Negative Acknowledge from a device (prev. msg not accepted or not supported) + TR_RCVD_NACK = -8, ///< Received Negative Acknowledge from a device (prev. msg not accepted or not supported) + TR_OVERFLOW = -9 ///< Received message was too long for the message receive buffer }; @@ -493,7 +697,7 @@ enum GPS_CMD_CODES GPS_STAT_INFO, ///< (r--) ::STAT_INFO, satellite info, mode of operation, and DAC info, only if ::GPS_MODEL_HAS_STAT_INFO GPS_SWITCH_PARMS, ///< (rw-) deprecated, use ::GPS_POUT_INFO_IDX/::GPS_POUT_SETTINGS_IDX GPS_STRING_PARMS, ///< (rw-) deprecated, use ::GPS_PORT_INFO_IDX/::GPS_PORT_SETTINGS_IDX - GPS_ANT_CABLE_LENGTH, ///< (rw-) ::ANT_CABLE_LEN, length of antenna cable, only if ::GPS_MODEL_HAS_ANT_CABLE_LENGTH + GPS_ANT_CABLE_LENGTH, ///< (rw-) ::ANT_CABLE_LEN, length of antenna cable, only if ::GPS_MODEL_HAS_ANT_CABLE_LEN GPS_SYNC_OUTAGE_DELAY, ///< (rw-) (customized firmware only) GPS_PULSE_INFO, ///< (rw-) (customized firmware only) GPS_OPT_FEATURES, ///< (r--) deprecated, use ::GPS_RECEIVER_INFO @@ -547,17 +751,17 @@ enum GPS_CMD_CODES GPS_NTP_GLB_CFG, ///< (rw-) ::NTP_GLB_INFO/::NTP_GLB_SETTINGS, only if ::GPS_HAS_NTP GPS_NTP_CLNT_MODE_CFG, ///< (rw-) ::NTP_CLNT_MODE_INFO/::NTP_CLNT_MODE_SETTINGS, only if ::NTP_MSK_ROLE_CLIENT GPS_NTP_SRV_MODE_CFG, ///< (rw-) ::NTP_SRV_MODE_INFO/::NTP_SRV_MODE_SETTINGS, only if ::NTP_MSK_ROLE_SERVER - GPS_NTP_PEER_SETTINGS_IDX, ///< (rw-) ::NTP_PEER_SETTINGS_IDX, only if ??? - GPS_NTP_SYS_STATE, ///< (r--) ::NTP_SYS_STATE, only if ??? - GPS_NTP_PEER_STATE_IDX, ///< (r--) ::NTP_PEER_STATE_IDX, only if ??? + GPS_NTP_PEER_SETTINGS_IDX, ///< (rw-) ::NTP_PEER_SETTINGS_IDX, only if ??? //### TODO + GPS_NTP_SYS_STATE, ///< (r--) ::NTP_SYS_STATE, only if ??? //### TODO + GPS_NTP_PEER_STATE_IDX, ///< (r--) ::NTP_PEER_STATE_IDX, only if ??? //### TODO GPS_SHS, ///< (rw-) ::SHS_INFO/::SHS_SETTINGS, only if ::GPS_HAS_SHS GPS_SHS_STATUS, ///< (r--) ::SHS_STATUS, only if ::GPS_HAS_SHS GPS_NET_GLB_CFG, ///< (rw-) ::MBG_NET_GLB_CFG_INFO/::MBG_NET_GLB_CFG_SETTINGS, only if ::GPS_HAS_NET_CFG - GPS_NET_DNS_SRVR, ///< (rw-) ::MBG_IP_ADDR_IDX, DNS cfg., only if ::MBG_NET_GLB_CFG_INFO::num_dns_srvr > 0 - GPS_NET_DNS_SRCH_DOM, ///< (rw-) ::MBG_NET_NAME_IDX, DNS cfg., only if ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom > 0 - GPS_NET_STAT_DNS_SRVR, ///< (r--) ::MBG_IP_ADDR_IDX, DNS status, only if ::MBG_NET_GLB_CFG_INFO::num_dns_srvr > 0 - GPS_NET_STAT_DNS_SRCH_DOM, ///< (r--) ::MBG_NET_NAME_IDX, DNS status, only if ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom > 0 - GPS_GNSS_SAT_INFO_IDX, ///< (r--) ::GNSS_SAT_INFO_IDX, only if ::MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER, deprecates ::GPS_GNSS_SAT_INFO + GPS_NET_DNS_SRVR, ///< (rw-) ::MBG_IP_ADDR_IDX, DNS cfg., only if ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr > 0 + GPS_NET_DNS_SRCH_DOM, ///< (rw-) ::MBG_NET_NAME_IDX, DNS cfg., only if ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom > 0 + GPS_NET_STAT_DNS_SRVR, ///< (r--) ::MBG_IP_ADDR_IDX, DNS status, only if ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr > 0 + GPS_NET_STAT_DNS_SRCH_DOM, ///< (r--) ::MBG_NET_NAME_IDX, DNS status, only if ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom > 0 + GPS_GNSS_SAT_INFO_IDX, ///< (r--) ::GNSS_SAT_INFO_IDX, only if ::MBG_GNSS_FLAG_MSK_SAT_INFO_IDX_SUPP_SER, deprecates ::GPS_GNSS_SAT_INFO GPS_XMR_HOLDOVER_ELAPSED, ///< (r--) ::XMR_HOLDOVER_INTV, elapsed time in holdover mode, only if ::GPS_MODEL_HAS_XMR_HOLDOVER_INTV, deprecated by ::GPS_XMR_HOLDOVER_STATUS GPS_GPIO_STATUS_IDX, ///< (r--) ::MBG_GPIO_STATUS_IDX, only if ::MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP GPS_XMR_HOLDOVER_STATUS, ///< (r--) ::XMR_HOLDOVER_STATUS, only if ::XMRIF_MSK_HOLDOVER_STATUS_SUPP, deprecates ::GPS_XMR_HOLDOVER_ELAPSED and partially ::GPS_XMR_HOLDOVER_INTV @@ -572,6 +776,75 @@ enum GPS_CMD_CODES GPS_FDM_SETTINGS, ///< (rw-) ::MBG_IMS_FDM_SETTINGS, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags GPS_FDM_INFO, ///< (r--) ::MBG_IMS_FDM_INFO, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags GPS_XMR_EXT_SRC_INFO_IDX, ///< (r--) ::XMR_EXT_SRC_INFO_IDX, only if ::XMRIF_MSK_EXT_SRC_INFO_SUPP + GPS_FDM_FREQ, ///< (r--) ::MBG_GPIO_FREQ, only if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags + GPS_XFEATURES, ///< (r--) ::MBG_XFEATURE_BUFFER, only if ::GPS_HAS_XFEATURE + GPS_SAVE_CFG, ///< (-w-) no data, save current config as default, only if ::MBG_XFEATURE_SAVE_CFG + GPS_XMR_STATS_IDX, ///< (r--) ::XMR_STATS_IDX, only if ::XMR_EXT_SRC_FEAT_FLAG_MSK_STATS + GPS_FDM_SET_TD, ///< (-w-) ::NANO_TIME_64, set time deviation, only if ::MBG_IMS_FDM_FLAG_MASK_CAN_SET_TDEV + GPS_LNE_LIMITS, ///< (r--) ::MBG_LNE_LIMITS, LNE API capabilities, only if ::MBG_XFEATURE_LNE_API + GPS_LNE_PORT_INFO_IDX, ///< (r--) ::MBG_LNE_PORT_INFO_IDX, settings and capabilities of an LED, only if ::MBG_XFEATURE_LNE_API + GPS_LNE_PORT_SETTINGS_IDX, ///< (rw-) ::MBG_LNE_PORT_SETTINGS_IDX, settings of a specific LED, only if ::MBG_XFEATURE_LNE_API + GPS_PWR_CTL, ///< (rw-) ::MBG_PWR_CTL, set or retrieve device power state, only if ::MBG_XFEATURE_PWR_CTL_API + GPS_LED_LIMITS, ///< (r--) ::MBG_LED_LIMITS, LED API capabilities, only if ::MBG_XFEATURE_LED_API + GPS_LED_INFO_IDX, ///< (r--) ::MBG_LED_INFO_IDX, settings and capabilities of an LED, only if ::MBG_XFEATURE_LED_API + GPS_LED_SETTINGS_IDX, ///< (rw-) ::MBG_LED_SETTINGS_IDX, settings of a specific LED, only if ::MBG_XFEATURE_LED_API + GPS_EXT_SYS_INFO, ///< (r--) ::MBG_EXT_SYS_INFO, extended revision information, only if ::MBG_XFEATURE_EXT_SYS_INFO + GPS_TLV_INFO, ///< (r--) ::MBG_TLV_INFO, query information on which TLV stuff is supported, only if ::MBG_XFEATURE_TLV_API + GPS_TLV_ANNOUNCE, ///< (-w-) ::MBG_TLV_ANNOUNCE, send and announcement for a subsequent TLV, only if ::MBG_XFEATURE_TLV_API + GPS_TLV_DATA, ///< (rw-) a binary data bufer to be sent/received, according to the previous announce msg, only if ::MBG_XFEATURE_TLV_API + GPS_BEGIN_TRANSACTION, ///< (-w-) no data, begin transaction and apply changes after ::GPS_END_TRANSACTION, only supp. if ::MBG_XFEATURE_TRANSACTIONS + GPS_END_TRANSACTION, ///< (-w-) no data, end transaction and apply changes, only supp. if ::MBG_XFEATURE_TRANSACTIONS + GPS_REBOOT, ///< (-w-) no data, let the device reboot itself, only supp. if ::MBG_XFEATURE_REBOOT + GPS_XMR_METRICS_IDX, ///< (r--) ::GPS_XMR_METRICS_IDX, only if ::XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS + GPS_XMR_QL_INFO_IDX, ///< (r--) ::XMR_QL_INFO, only if ::XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS + GPS_XMR_QL_SETTINGS_IDX, ///< (-w-) ::XMR_QL_SETTINGS, only if ::XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS + GPS_CLK_RES_INFO, ///< (r--) ::MBG_CLK_RES_INFO, only if ::MBG_XFEATURE_CLK_RES_INFO + GPS_NET_INTF_LINK_IDX, ///< (rw-) ::MBG_NET_INTF_LINK_INFO_IDX/::MBG_NET_INTF_LINK_SETTINGS_IDX, only if ::MBG_NET_GLB_SUPP_STAGE_2_MASK is set in ::MBG_NET_GLB_CFG_INFO::feat_flags + GPS_NET_INTF_ADDR_IDX, ///< (rw-) ::MBG_NET_INTF_ADDR_INFO_IDX/::MBG_NET_INTF_ADDR_SETTINGS_IDX, only if ::MBG_NET_GLB_SUPP_STAGE_2_MASK is set in ::MBG_NET_GLB_CFG_INFO::feat_flags + GPS_NET_INTF_ROUTE_IDX, ///< (rw-) ::MBG_NET_INTF_ROUTE_INFO_IDX/::MBG_NET_INTF_ROUTE_SETTINGS_IDX, only if ::MBG_NET_GLB_SUPP_STAGE_2_MASK is set in ::MBG_NET_GLB_CFG_INFO::feat_flags + GPS_NET_STAT_GLB_CFG, ///< (r--) ::MBG_NET_GLB_CFG_INFO, network status, only if ::MBG_NET_GLB_SUPP_STAGE_2_MASK is set in ::MBG_NET_GLB_CFG_INFO::feat_flags + GPS_NET_STAT_INTF_LINK_IDX, ///< (r--) ::MBG_NET_INTF_LINK_INFO_IDX, link status, only if ::MBG_NET_GLB_SUPP_STAGE_2_MASK is set in ::MBG_NET_GLB_CFG_INFO::feat_flags + GPS_NET_STAT_INTF_ADDR_IDX, ///< (r--) ::MBG_NET_INTF_ADDR_INFO_IDX, addr status, only if ::MBG_NET_GLB_SUPP_STAGE_2_MASK is set in ::MBG_NET_GLB_CFG_INFO::feat_flags + GPS_NET_STAT_INTF_ROUTE_IDX, ///< (r--) ::MBG_NET_INTF_ROUTE_INFO_IDX, route status, only if ::MBG_NET_GLB_SUPP_STAGE_2_MASK is set in ::MBG_NET_GLB_CFG_INFO::feat_flags + GPS_UCAP_NET_GLB_INFO, ///< (rw-) ::MBG_UCAP_NET_GLB_INFO/::MBG_UCAP_NET_GLB_SETTINGS, only supp. if ::MBG_XFEATURE_UCAP_NET is set in extended features + GPS_UCAP_NET_RECV_INFO_IDX, ///< (rw-) ::MBG_UCAP_NET_RECV_INFO_IDX/::MBG_UCAP_NET_RECV_SETTINGS_IDX, only supp. if ::MBG_XFEATURE_UCAP_NET is set in extended features + GPS_IO_PORT_LIMITS, ///< (r--) ::MBG_IO_PORT_LIMITS, only supp. if ::MBG_XFEATURE_IO_PORTS is set in extended features + GPS_IO_PORT_SETTINGS_IDX, ///< (-w-) ::MBG_IO_PORT_SETTINGS_IDX, only supp. if ::MBG_XFEATURE_IO_PORTS is set in extended features + GPS_IO_PORT_INFO_IDX, ///< (r--) ::MBG_IO_PORT_INFO_IDX, only supp. if ::MBG_XFEATURE_IO_PORTS is set in extended features and from 0..MBG_IO_PORT_LIMITS::num_ports - 1 + GPS_IO_PORT_TYPE_INFO_IDX, ///< (r--) ::MBG_IO_PORT_TYPE_INFO_IDX, only supp. if ::MBG_XFEATURE_IO_PORTS is set in extended features and from 0..MMBG_IO_PORT_INFO::num_types - 1 + GPS_IO_PORT_STATUS_IDX, ///< (r--) ::MBG_IO_PORT_STATUS_IDX, only supp. if ::MBG_XFEATURE_IO_PORTS is set in extended features and from 0..MBG_IO_PORT_LIMITS::num_ports - 1 + GPS_MONITORING_LIMITS, ///< (r--) ::MBG_MONITORING_LIMITS, only supp. if ::MBG_XFEATURE_MONITORING is set in extended features + GPS_SNMP_GLB, ///< (rw-) ::MBG_SNMP_GLB_INFO / ::MBG_SNMP_GLB_SETTINGS, only supp. if ::MBG_MONITORING_TYPE_MSK_SNMP is set in ::MBG_MONITORING_LIMITS::supp_types + GPS_SNMP_V12_IDX, ///< (rw-) ::MBG_SNMP_V12_INFO_IDX / ::MBG_SNMP_V12_SETTINGS_IDX, only supp. if ::MBG_SNMP_VERSION_MSK_V1 or :: MBG_SNMP_VERSION_MSK_V2 is set + ///< in ::MBG_SNMP_GLB_INFO::supp_versions and from 0..::MBG_SNMP_GLB_INFO::num_v12_settings - 1 + GPS_SNMP_V12_TRAP_IDX, ///< (rw-) ::MBG_SNMP_V12_TRAP_INFO_IDX / ::MBG_SNMP_V12_TRAP_SETTINGS_IDX, only supp. if ::MBG_SNMP_VERSION_MSK_V1 or :: MBG_SNMP_VERSION_MSK_V2c is set + ///< in ::MBG_SNMP_GLB_INFO::supp_versions and from 0..::MBG_SNMP_GLB_INFO::num_v12_trap_receivers - 1 + GPS_SNMP_V3_IDX, ///< (rw-) ::MBG_SNMP_V3_INFO_IDX / ::MBG_SNMP_V3_SETTINGS_IDX, only supp. if ::MBG_SNMP_VERSION_MSK_V3 is set in ::MBG_SNMP_GLB_INFO::supp_versions and from + ///< 0..::MBG_SNMP_GLB_INFO::num_v3_settings - 1 + GPS_SNMP_V3_TRAP_IDX, ///< (rw-) ::MBG_SNMP_V3_TRAP_INFO_IDX / ::MBG_SNMP_V3_TRAP_SETTINGS_IDX, only supp. if ::MBG_SNMP_VERSION_MSK_V3 in ::MBG_SNMP_GLB_INFO::supp_versions and from + ///< 0..::MBG_SNMP_GLB_INFO::num_v3_trap_receivers - 1 + GPS_GNSS_SV_STATUS_IDX, ///< (r--) ::GNSS_SV_STATUS_IDX, only supp. if ::MBG_GNSS_FLAG_MSK_HAS_SV_STATUS is set + GPS_PTP_V2_DEFAULT_DS, ///< (rw-) ::MBG_PTP_V2_DEFAULT_DATASET, only supp. if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_PTP_V2_CURRENT_DS, ///< (rw-) ::MBG_PTP_V2_CURRENT_DATASET, only supp. if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_PTP_V2_PARENT_DS, ///< (rw-) ::MBG_PTP_V2_PARENT_DATASET, only supp. if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_PTP_V2_TIME_PROP_DS, ///< (rw-) ::MBG_PTP_V2_TIME_PROPERTIES_DATASET, only supp. if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_PTP_V2_PORT_DS_IDX, ///< (rw-) ::MBG_PTP_V2_PORT_DATASET_IDX, only supp. if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_MONITORING_STATUS, ///< (r--) ::MBG_MONITORING_STATUS, only supp. if ::MBG_MONITORING_TYPE_MSK_SNMP is set in ::MBG_MONITORING_LIMITS::supp_types + GPS_EVENT_IDX, ///< (rw-) ::MBG_EVENT_INFO_IDX / ::MBG_EVENT_SETTINGS_IDX, only supp. if ::MBG_XFEATURE_MONITORING is set in extended features + GPS_EVENT_STAT_IDX, ///< (r--) ::MBG_EVENT_STATUS_IDX, only supp. if ::MBG_XFEATURE_MONITORING is set in extended features + GPS_NTP_REFCLK_CFG, ///< (rw-) ::MBG_NTP_REFCLK_CFG_INFO_IDX only if NTP_SRV_MODE_SETTINGS::num_refclks > 0 + GPS_NTP_MISC_LIMITS, ///< (r--) ::MBG_NTP_MISC_LIMITS ONLY if NTP_MSK_MISCELLANEOUS IS SET IN GPS_NTP_GLB_CFG::supp_flags + GPS_NTP_MISC_ORPHAN_MODE, ///< (rw-) ::MBG_NTP_MISC_ORPHAN_MODE_SETTINGS only if NTP_MISC_MSK_ORPHAN_MODE is set in GPS_NTP_MISC_LIMITS::supp_flags + GPS_NTP_SYMM_KEY_LIMITS, ///< (r--) ::MBG_GPS_NTP_SYMM_KEY_LIMITS only if NTP_MSK_SYMM_KEY is set in ::NTP_SRV_MODE_SETTINGS::supp_flags + GPS_NTP_SYMM_KEY_CFG, ///< (rw-) ::MBG_GPS_NTP_SYMM_KEY_CFG only if NTP_MSK_SYMM_KEY is set in ::NTP_SRV_MODE_SETTINGS::supp_flags + GPS_NTP_TRUSTED_KEY_CFG, ///< (rw-) ::MBG_GPS_NTP_TRUSTED_KEY_CFG only if GPS_NTP_GLB_CFG::max_trusted_keys > 0 + GPS_PTP_V1_DEFAULT_DS, ///< (rw-) ::MBG_PTP_V1_DEFAULT_DATASET, only supp. if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_PTP_V1_CURRENT_DS, ///< (rw-) ::GPS_PTP_V1_CURRENT_DS, only supp. if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_PTP_V1_PARENT_DS, ///< (rw-) ::GPS_PTP_V1_PARENT_DS, only supp. if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_PTP_V1_TIME_PROP_DS, ///< (rw-) ::GPS_PTP_V1_TIME_PROP_DS, only supp. if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_PTP_V1_PORT_DS_IDX, ///< (rw-) ::GPS_PTP_V1_PORT_DS_IDX, only supp. if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + GPS_USB_LOCK_INFO, ///< (rw-) ::MBG_USB_LOCK_INFO / ::MBG_USB_LOCK_SETTINGS, only supp. if ::MBG_XFEATURE_USB_LOCK is set in ::MBG_XFEATURE_BUFFER + GPS_USB_LOCK_STATUS, ///< (r--) ::MBG_USB_LOCK_STATUS, only supp. if ::MBG_XFEATURE_USB_LOCK is set in ::MBG_XFEATURE_BUFFER /* GPS data */ GPS_CFGH = 0x100, ///< (rw-) ::CFGH, SVs' configuration and health codes @@ -583,8 +856,8 @@ enum GPS_CMD_CODES /* Glonass data */ GPS_GLNS_ALM = 0x200, ///< (rw-) ** preliminary ** //##++ - GPS_GNSS_SAT_INFO, ///< (r--) ::GNSS_SAT_INFO, Glonass-only sat. info (deprecated by ::GPS_GNSS_SAT_INFO_IDX) - GPS_GNSS_MODE, ///< (rw-) ::MBG_GNSS_MODE_SETTINGS/::MBG_GNSS_MODE_INFO}, GNSS operation mode + GPS_GNSS_SAT_INFO, ///< (r--) ::GNSS_SAT_INFO, GLONASS-only satellite info (deprecated by ::GPS_GNSS_SAT_INFO_IDX) + GPS_GNSS_MODE, ///< (rw-) ::MBG_GNSS_MODE_INFO/::MBG_GNSS_MODE_SETTINGS, GNSS operation mode // Warning: // The next numbers in range 0x200 are reserved @@ -593,6 +866,7 @@ enum GPS_CMD_CODES GPS_LAN_IF_INFO, ///< (r--) ::LAN_IF_INFO, only if ::GPS_HAS_LAN_IP4 GPS_IP4_STATE, ///< (r--) ::IP4_SETTINGS, only if ::GPS_HAS_LAN_IP4 + /* misc data (SCU) */ GPS_SCU_STAT = 0x820, ///< (rwa) ::SCU_STAT_SETTINGS/::SCU_STAT_INFO, SCU board control, only if ::GPS_MODEL_IS_SCU @@ -608,9 +882,20 @@ enum GPS_CMD_CODES PZF_PCPS_TIME = 0xA00, ///< (rw-) ::PCPS_TIME, date/time/status, only if ::GPS_MODEL_IS_DCF_PZF PZF_TR_DISTANCE, ///< (rw-) ::TR_DISTANCE, dist. from transmitter [km], only if ::GPS_MODEL_IS_DCF_PZF PZF_TZCODE, ///< (rw-) ::TZCODE, time zone code, only if ::GPS_MODEL_IS_DCF_PZF - PZF_CORR_INFO ///< (r--) ::CORR_INFO, correlation info, only if ::GPS_MODEL_IS_DCF_PZF -}; + PZF_CORR_INFO, ///< (r--) ::CORR_INFO, correlation info, only if ::GPS_MODEL_IS_DCF_PZF + +#if defined( _PRELIMINARY_CODE ) + // Temp. test codes, not for release!!! + // Code still need to be added to GPS_CMD_CODES_TABLE + // *Don't* make these codes #if _USE_TIME_MON only!! + GPS_TIME_MON_INST_INFO, ///< (rw-) ::MBG_TIME_MON_INST_INFO + GPS_TIME_MON_TARGET_SETTINGS, ///< (-w-) ::MBG_TIME_MON_TARGET_SETTINGS + GPS_TIME_MON_TARGET_STATUS_IDX, ///< (r--) ::MBG_TIME_MON_TARGET_STATUS_IDX + GPS_TIME_MON_TARGET_EXT_DATA_SET_IDX, ///< (r--) ::MBG_TIME_MON_TARGET_EXT_DATA_SET_IDX +#endif // defined( _PRELIMINARY_CODE ) + +}; #if !defined( MBG_TGT_DOS ) @@ -721,6 +1006,71 @@ enum GPS_CMD_CODES _mbg_cn_table_entry( GPS_FDM_SETTINGS ), \ _mbg_cn_table_entry( GPS_FDM_INFO ), \ _mbg_cn_table_entry( GPS_XMR_EXT_SRC_INFO_IDX ), \ + _mbg_cn_table_entry( GPS_FDM_FREQ ), \ + _mbg_cn_table_entry( GPS_XFEATURES ), \ + _mbg_cn_table_entry( GPS_SAVE_CFG ), \ + _mbg_cn_table_entry( GPS_XMR_STATS_IDX ), \ + _mbg_cn_table_entry( GPS_FDM_SET_TD ), \ + _mbg_cn_table_entry( GPS_LNE_LIMITS ), \ + _mbg_cn_table_entry( GPS_LNE_PORT_INFO_IDX ), \ + _mbg_cn_table_entry( GPS_LNE_PORT_SETTINGS_IDX ), \ + _mbg_cn_table_entry( GPS_PWR_CTL ), \ + _mbg_cn_table_entry( GPS_LED_LIMITS ), \ + _mbg_cn_table_entry( GPS_LED_INFO_IDX ), \ + _mbg_cn_table_entry( GPS_LED_SETTINGS_IDX ), \ + _mbg_cn_table_entry( GPS_EXT_SYS_INFO ), \ + _mbg_cn_table_entry( GPS_TLV_INFO ), \ + _mbg_cn_table_entry( GPS_TLV_ANNOUNCE ), \ + _mbg_cn_table_entry( GPS_TLV_DATA ), \ + _mbg_cn_table_entry( GPS_BEGIN_TRANSACTION ), \ + _mbg_cn_table_entry( GPS_END_TRANSACTION ), \ + _mbg_cn_table_entry( GPS_REBOOT ), \ + _mbg_cn_table_entry( GPS_XMR_METRICS_IDX ), \ + _mbg_cn_table_entry( GPS_XMR_QL_INFO_IDX ), \ + _mbg_cn_table_entry( GPS_XMR_QL_SETTINGS_IDX ), \ + _mbg_cn_table_entry( GPS_CLK_RES_INFO ), \ + _mbg_cn_table_entry( GPS_NET_INTF_LINK_IDX ), \ + _mbg_cn_table_entry( GPS_NET_INTF_ADDR_IDX ), \ + _mbg_cn_table_entry( GPS_NET_INTF_ROUTE_IDX), \ + _mbg_cn_table_entry( GPS_NET_STAT_GLB_CFG ), \ + _mbg_cn_table_entry( GPS_NET_STAT_INTF_LINK_IDX ), \ + _mbg_cn_table_entry( GPS_NET_STAT_INTF_ADDR_IDX), \ + _mbg_cn_table_entry( GPS_NET_STAT_INTF_ROUTE_IDX), \ + _mbg_cn_table_entry( GPS_UCAP_NET_GLB_INFO ), \ + _mbg_cn_table_entry( GPS_UCAP_NET_RECV_INFO_IDX ), \ + _mbg_cn_table_entry( GPS_IO_PORT_LIMITS ), \ + _mbg_cn_table_entry( GPS_IO_PORT_SETTINGS_IDX ), \ + _mbg_cn_table_entry( GPS_IO_PORT_INFO_IDX ), \ + _mbg_cn_table_entry( GPS_IO_PORT_TYPE_INFO_IDX ), \ + _mbg_cn_table_entry( GPS_IO_PORT_STATUS_IDX ), \ + _mbg_cn_table_entry( GPS_MONITORING_LIMITS ), \ + _mbg_cn_table_entry( GPS_SNMP_GLB ), \ + _mbg_cn_table_entry( GPS_SNMP_V12_IDX ), \ + _mbg_cn_table_entry( GPS_SNMP_V12_TRAP_IDX ), \ + _mbg_cn_table_entry( GPS_SNMP_V3_IDX ), \ + _mbg_cn_table_entry( GPS_SNMP_V3_TRAP_IDX ), \ + _mbg_cn_table_entry( GPS_GNSS_SV_STATUS_IDX ), \ + _mbg_cn_table_entry( GPS_PTP_V2_DEFAULT_DS ), \ + _mbg_cn_table_entry( GPS_PTP_V2_CURRENT_DS ), \ + _mbg_cn_table_entry( GPS_PTP_V2_PARENT_DS ), \ + _mbg_cn_table_entry( GPS_PTP_V2_TIME_PROP_DS ), \ + _mbg_cn_table_entry( GPS_PTP_V2_PORT_DS_IDX ), \ + _mbg_cn_table_entry( GPS_MONITORING_STATUS ), \ + _mbg_cn_table_entry( GPS_EVENT_IDX ), \ + _mbg_cn_table_entry( GPS_EVENT_STAT_IDX ), \ + _mbg_cn_table_entry( GPS_NTP_REFCLK_CFG ), \ + _mbg_cn_table_entry( GPS_NTP_MISC_LIMITS ), \ + _mbg_cn_table_entry( GPS_NTP_MISC_ORPHAN_MODE ), \ + _mbg_cn_table_entry( GPS_NTP_SYMM_KEY_LIMITS ), \ + _mbg_cn_table_entry( GPS_NTP_SYMM_KEY_CFG ), \ + _mbg_cn_table_entry( GPS_NTP_TRUSTED_KEY_CFG ), \ + _mbg_cn_table_entry( GPS_PTP_V1_DEFAULT_DS ), \ + _mbg_cn_table_entry( GPS_PTP_V1_CURRENT_DS ), \ + _mbg_cn_table_entry( GPS_PTP_V1_PARENT_DS ), \ + _mbg_cn_table_entry( GPS_PTP_V1_TIME_PROP_DS ), \ + _mbg_cn_table_entry( GPS_PTP_V1_PORT_DS_IDX ), \ + _mbg_cn_table_entry( GPS_USB_LOCK_INFO ), \ + _mbg_cn_table_entry( GPS_USB_LOCK_STATUS ), \ \ /* GPS data */ \ _mbg_cn_table_entry( GPS_CFGH ), \ @@ -756,6 +1106,7 @@ enum GPS_CMD_CODES _mbg_cn_table_entry( PZF_TR_DISTANCE ), \ _mbg_cn_table_entry( PZF_TZCODE ), \ _mbg_cn_table_entry( PZF_CORR_INFO ), \ + \ _mbg_cn_table_end() \ } @@ -797,7 +1148,7 @@ typedef struct typedef uint16_t TZCODE; #define _mbg_swab_tzcode( _p ) \ - _mbg_swab16( _p ); + _mbg_swab16( _p ) /** @@ -839,6 +1190,8 @@ typedef struct */ typedef union { + uint16_t u16; + int16_t i16; uint16_t us; double d; SVNO svno; @@ -907,10 +1260,8 @@ typedef union NTP_GLB_SETTINGS ntp_glb_settings; NTP_CLNT_MODE_INFO ntp_clnt_mode_info; NTP_CLNT_MODE_SETTINGS ntp_clnt_mode_settings; - #if defined( DEBUG ) - NTP_SRV_MODE_INFO ntp_srv_mode_info; - NTP_SRV_MODE_INFO ntp_srv_mode_settings; - #endif + NTP_SRV_MODE_INFO ntp_srv_mode_info; + NTP_SRV_MODE_SETTINGS ntp_srv_mode_settings; NTP_PEER_SETTINGS_IDX ntp_peer_settings_idx; NTP_SYS_STATE ntp_sys_state; NTP_PEER_STATE_IDX ntp_peer_state_idx; @@ -921,6 +1272,12 @@ typedef union MBG_NET_GLB_CFG_SETTINGS net_glb_cfg_settings; MBG_IP_ADDR_IDX ip_addr_idx; MBG_NET_NAME_IDX net_name_idx; + MBG_NET_INTF_LINK_INFO_IDX net_intf_link_info_idx; + MBG_NET_INTF_LINK_SETTINGS_IDX net_intf_link_settings_idx; + MBG_NET_INTF_ADDR_INFO_IDX net_intf_addr_info_idx; + MBG_NET_INTF_ADDR_SETTINGS_IDX net_intf_addr_settings_idx; + MBG_NET_INTF_ROUTE_INFO_IDX net_intf_route_info_idx; + MBG_NET_INTF_ROUTE_SETTINGS_IDX net_intf_route_settings_idx; GNSS_SAT_INFO_IDX gnss_sat_info_idx; MBG_GPIO_STATUS_IDX gpio_status_idx; XMR_HOLDOVER_STATUS xmr_holdover_status; @@ -935,6 +1292,84 @@ typedef union MBG_IMS_FDM_SETTINGS fdm_settings; MBG_IMS_FDM_INFO fdm_info; XMR_EXT_SRC_INFO_IDX xmr_ext_src_info_idx; + MBG_GPIO_FREQ fdm_freq; + MBG_XFEATURE_BUFFER xfeature_buffer; + XMR_STATS_IDX xmr_stats_idx; + NANO_TIME_64 nano_time_64; + MBG_LNE_LIMITS lne_limits; + MBG_LNE_PORT_INFO_IDX lne_port_info_idx; + MBG_LNE_PORT_SETTINGS_IDX lne_port_settings_idx; + MBG_PWR_CTL pwr_ctl; + MBG_LED_LIMITS led_limits; + MBG_LED_INFO_IDX led_info_idx; + MBG_LED_SETTINGS_IDX led_settings_idx; + MBG_EXT_SYS_INFO ext_sys_info; + MBG_TLV_INFO tlv_info; + MBG_TLV_ANNOUNCE tlv_announce; + MBG_TLV tlv; + + XMR_METRICS_IDX xmr_metrics_idx; + XMR_QL_INFO_IDX xmr_ql_info_idx; + XMR_QL_SETTINGS_IDX xmr_ql_settings_idx; + + MBG_CLK_RES_INFO mbg_clk_res_info; + + MBG_UCAP_NET_GLB_INFO ucap_net_glb_info; + MBG_UCAP_NET_GLB_SETTINGS ucap_net_glb_settings; + MBG_UCAP_NET_RECV_INFO_IDX ucap_net_recv_info_idx; + MBG_UCAP_NET_RECV_SETTINGS_IDX ucap_net_recv_settings_idx; + + MBG_IO_PORT_LIMITS iop_limits; + MBG_IO_PORT_SETTINGS_IDX iop_settings_idx; + MBG_IO_PORT_INFO_IDX iop_info_idx; + MBG_IO_PORT_TYPE_INFO_IDX iop_type_info_idx; + MBG_IO_PORT_STATUS_IDX iop_status_idx; + + MBG_MONITORING_LIMITS monitoring_limits; + MBG_SNMP_GLB_SETTINGS snmp_glb_settings; + MBG_SNMP_GLB_INFO snmp_glb_info; + MBG_SNMP_V12_SETTINGS_IDX snmp_v12_settings_idx; + MBG_SNMP_V12_INFO_IDX snmp_v12_info_idx; + MBG_SNMP_V12_TRAP_SETTINGS_IDX snmp_v12_trap_settings_idx; + MBG_SNMP_V12_TRAP_INFO_IDX snmp_v12_trap_info_idx; + MBG_SNMP_V3_SETTINGS_IDX snmp_v3_settings_idx; + MBG_SNMP_V3_INFO_IDX snmp_v3_info_idx; + MBG_SNMP_V3_TRAP_SETTINGS_IDX snmp_v3_trap_settings_idx; + MBG_SNMP_V3_TRAP_INFO_IDX snmp_v3_trap_info_idx; + + GNSS_SV_STATUS_IDX gnss_sv_status_idx; + + MBG_PTP_V2_DEFAULT_DATASET ptp_v2_default_dataset; + MBG_PTP_V2_CURRENT_DATASET ptp_v2_current_dataset; + MBG_PTP_V2_PARENT_DATASET ptp_v2_parent_dataset; + MBG_PTP_V2_TIME_PROPERTIES_DATASET ptp_v2_time_properties_dataset; + MBG_PTP_V2_PORT_DATASET_IDX ptp_v2_port_dataset_idx; + + MBG_MONITORING_STATUS monitoring_status; + MBG_EVENT_INFO_IDX event_info_idx; + MBG_EVENT_SETTINGS_IDX event_settings_idx; + MBG_EVENT_STATUS_IDX event_status_idx; + + NTP_SYMM_KEY_LIMITS ntp_symm_key_limits; + NTP_SYMM_KEY_INFO_IDX ntp_symm_key_info_idx; + NTP_SYMM_KEY_SETTINGS_IDX ntp_symm_key_settings_idx; + NTP_TRUSTED_KEY_INFO_IDX ntp_trusted_key_info_idx; + NTP_TRUSTED_KEY_SETTINGS_IDX ntp_trusted_key_settings_idx; + NTP_REFCLK_CFG_INFO_IDX ntp_refclk_cfg_info_idx; + NTP_REFCLK_CFG_SETTINGS_IDX ntp_refclk_cfg_settings_idx; + NTP_MISC_LIMITS ntp_misc_limits; + NTP_MISC_ORPHAN_MODE_INFO ntp_misc_orphan_mode_info; + NTP_MISC_ORPHAN_MODE_SETTINGS ntp_misc_orphan_mode_settings; + + MBG_PTP_V1_DEFAULT_DATASET ptp_v1_default_dataset; + MBG_PTP_V1_CURRENT_DATASET ptp_v1_current_dataset; + MBG_PTP_V1_PARENT_DATASET ptp_v1_parent_dataset; + MBG_PTP_V1_TIME_PROPERTIES_DATASET ptp_v1_time_properties_dataset; + MBG_PTP_V1_PORT_DATASET_IDX ptp_v1_port_dataset_idx; + + MBG_USB_LOCK_INFO usb_lock_info; + MBG_USB_LOCK_SETTINGS usb_lock_settings; + MBG_USB_LOCK_STATUS usb_lock_status; //##++ PTP_POWER_PROFILE_CFG ptp_power_profile_cfg; // no cmd code, yet. @@ -962,13 +1397,19 @@ typedef union SECU_SETTINGS secu_settings; #endif +#if _USE_TIME_MON && defined( _PRELIMINARY_CODE ) + MBG_TIME_MON_INST_INFO time_mon_inst_info; + MBG_TIME_MON_TARGET_SETTINGS time_mon_target_settings; + MBG_TIME_MON_TARGET_STATUS_IDX time_mon_target_status_idx; + MBG_TIME_MON_TARGET_EXT_DATA_SET_IDX time_mon_target_ext_data_set_idx; +#endif + #if _USE_GPSPRIV _mbg_gps_types_priv #endif } MSG_DATA; - /// The maximum number of bytes required for a ::MSG_DATA buffer #ifndef MAX_MSG_DATA_SIZE #ifndef ADD_MSG_DATA_SIZE @@ -1108,15 +1549,20 @@ typedef struct { MBG_MSG_BUFF *pmb; ///< points to unencrypted message buffer int buf_size; ///< size of buffer, including header - uint8_t *cur; ///< points to current pos inside receive buffer - int cnt; ///< the number of bytes to be received - ulong flags; ///< flags if header already completed, etc., see ::MBG_MSG_RCV_CTL_MASKS - #if _USE_RCV_TSTAMP - MBG_TMO_TIME tstamp; ///< time when the first byte of the packet was received - #endif - #if _USE_CHK_TSTR - CHK_TSTR_FNC chk_tstr_fnc; ///< optional handler for normal, non-protocol data - CHK_TSTR_ARG *chk_tstr_arg; ///< arguments for the non-protocol data handler + + struct rcv_state + { + uint8_t *cur; ///< points to current pos inside receive buffer + int cnt; ///< the number of bytes to be received + ulong flags; ///< flags if header already completed, etc., see ::MBG_MSG_RCV_CTL_MASKS + #if _USE_RCV_TSTAMP + MBG_TMO_TIME tstamp; ///< time when the first byte of the packet was received + #endif + } rcv_state; + + #if _USE_MBG_TSTR + MBG_TSTR_RCV_FNC *tstr_rcv_fnc; ///< optional handler for normal, non-protocol data + MBG_TSTR_RCV_ARG *tstr_rcv_arg; ///< arguments for the non-protocol data handler #endif } MBG_MSG_RCV_CTL; @@ -1141,7 +1587,7 @@ enum MBG_MSG_RCV_CTL_BITS /** * @brief Receive control bit masks * - * Used with ::MBG_MSG_RCV_CTL::flags + * Used with ::MBG_MSG_RCV_CTL::rcv_state::flags * * @see ::MBG_MSG_RCV_CTL_BITS */ @@ -1165,10 +1611,6 @@ typedef struct int buf_size; ///< size of buffer, including header int xfer_mode; ///< transfer mode, see ::MBG_XFER_MODES - #if _USE_MUTEX - MBG_MUTEX xmt_mutex; ///< mutex to serialize transmission - #endif - } MBG_MSG_XMT_CTL; @@ -1189,54 +1631,25 @@ enum MBG_XFER_MODES #if _USE_SOCKET_IO -#if !defined ( MBGEXTIO_RCV_TIMEOUT_SOCKET ) - #define MBGEXTIO_RCV_TIMEOUT_SOCKET 2000 // [ms] -#endif - -#define LAN_XPT_PORT 10001 - - -/** - * @brief A socket file descriptor type - */ -#if defined( MBG_TGT_WIN32 ) - typedef SOCKET MBG_SOCK_FD; // usually evaluates to (unsigned int), or (unsigned __int64) -#elif defined( MBG_TGT_POSIX ) - typedef int MBG_SOCK_FD; -#endif - - -/** - * @brief A value to mark an ::MBG_SOCK_FD as invalid - */ -#if defined( MBG_TGT_WIN32 ) - #define MBG_INVALID_SOCK_FD INVALID_SOCKET // usually evaluates to (SOCKET)(~0) since SOCKET is unsigned -#elif defined( MBG_TGT_POSIX ) - #define MBG_INVALID_SOCK_FD -1 +#if !defined( MBGEXTIO_MSG_TIMEOUT_SOCKET ) + #define MBGEXTIO_MSG_TIMEOUT_SOCKET 1000 // [ms] #endif -#if defined( MBG_TGT_WIN32 ) - #define socklen_t int -#elif defined( MBG_TGT_POSIX ) - #define socklen_t socklen_t +#if !defined( MBGEXTIO_POLL_TIMEOUT_SOCKET ) + #define MBGEXTIO_POLL_TIMEOUT_SOCKET 200 // [ms] #endif - -/** - * @brief The return code of socket functions in case of error - */ -#if defined( MBG_TGT_WIN32 ) - #define MBG_SOCKET_ERR_RETVAL SOCKET_ERROR // usually evaluates to -1 -#elif defined( MBG_TGT_POSIX ) - #define MBG_SOCKET_ERR_RETVAL -1 -#endif +#define LAN_XPT_PORT 10001 typedef struct { MBG_SOCK_FD sockfd; - struct sockaddr_in addr; + struct sockaddr_in _addr; + struct sockaddr_in *p_addr; + socklen_t addrlen; + ulong poll_timeout; } SOCKET_IO_STATUS; @@ -1248,8 +1661,9 @@ typedef struct typedef struct { FT_HANDLE port_handle; + ulong poll_timeout; -} FTDI_IO_STATUS; +} FTDI_DEV; #endif // _USE_SERIAL_IO_FTDI @@ -1259,34 +1673,71 @@ typedef struct typedef int MBG_USB_DIRECT_IO_FD; -#if !defined (MBG_USB_DIRECT_IO_INVALID_FD) +#if !defined(MBG_USB_DIRECT_IO_INVALID_FD) #define MBG_USB_DIRECT_IO_INVALID_FD -1 #endif -#if !defined ( MBGEXTIO_RCV_TIMEOUT_USB_DIRECT_IO ) - #define MBGEXTIO_RCV_TIMEOUT_USB_DIRECT_IO 1000 // [ms] +#if !defined( MBGEXTIO_POLL_TIMEOUT_USB_DIRECT_IO ) + #define MBGEXTIO_POLL_TIMEOUT_USB_DIRECT_IO 1000 // [ms] +#endif + +#if !defined( MBGEXTIO_MSG_TIMEOUT_USB_DIRECT_IO ) + #define MBGEXTIO_MSG_TIMEOUT_USB_DIRECT_IO 1000 // [ms] #endif typedef struct { MBG_USB_DIRECT_IO_FD usbdiofd; -}USB_DIRECT_IO_STATUS; + ulong poll_timeout; + +} USB_DIRECT_IO_STATUS; #endif // _USE_USB_DIRECT_IO +#if !_IS_MBG_FIRMWARE + +struct MBG_MSG_CTL_s; + +/** + * @brief Message handler callback function pointer + */ +typedef int _MBG_API MBG_MSG_HANDLER( struct MBG_MSG_CTL_s *pmctl ); + +#endif // !_IS_MBG_FIRMWARE + + + /** * @brief A generic message send and receive control structure */ -typedef struct +typedef struct MBG_MSG_CTL_s { MBG_MSG_RCV_CTL rcv; MBG_MSG_XMT_CTL xmt; - int conn_type; - ulong msg_rcv_timeout; ///< binary message receive timeout [ms] - ulong char_rcv_timeout; ///< serial character receive timeout [ms] + ///< An optional error code received from a device with a NACK message + ///< Use ::mbgextio_get_last_nack_err_code to retrieve the code + ///< @todo This is probably not thread-safe. + int nack_err_code; + + #if _USE_MUTEX + MBG_MUTEX dev_mutex; ///< Mutex to serialize device access + #endif + + int conn_type; ///< One of the ::MBG_CONN_TYPES + uint32_t device_flags; ///< See ::MSG_CTL_DEVICE_FLAG_MSKS + ulong msg_rcv_timeout; ///< Binary message receive timeout [ms] + + #if !_IS_MBG_FIRMWARE + MBG_XDEV_FEATURES xdev_features; ///< Receiver info plus extended device features + MBG_MSG_HANDLER *msg_handler_fnc; ///< See ::mbgextio_register_msg_callback + + /// While TLV messages are handled, this structure is used temporarily + /// by some API functions to track the state of the TLV messages. + MBG_TLV_RCV_STATE tlv_rcv_state; + #endif #if _USE_ENCRYPTION uint8_t aes_initvect[AES_BLOCK_SIZE]; @@ -1302,22 +1753,22 @@ typedef struct _USE_SOCKET_IO || \ _USE_USB_IO || \ _USE_USB_DIRECT_IO - union + union st { #if _USE_SOCKET_IO SOCKET_IO_STATUS sockio; #endif #if _USE_SERIAL_IO - SERIAL_IO_STATUS serio; + MBGSERIO_DEV *p_serio; #endif #if _USE_SERIAL_IO_FTDI - FTDI_IO_STATUS ftdiio; + FTDI_DEV ftdi; #endif #if _USE_USB_IO - USB_IO_STATUS usbio; + MBGUSBIO_DEV usbio; #endif #if _USE_USB_DIRECT_IO @@ -1326,9 +1777,14 @@ typedef struct } st; #endif + #if defined( _DEBUG_MSG_TIMING ) + MBG_MSG_TIMES mt; + #endif + } MBG_MSG_CTL; + /** * @brief Binary message connection types * @@ -1419,6 +1875,15 @@ enum MBG_CONN_TYPES int chk_data_csum( const MBG_MSG_BUFF *pmb ) ; /** + * @brief Checks if a binary message header has been completely received + * + * @param[in] prctl ::MBG_MSG_RCV_CTL that shall be checked + * + * @return One of the @ref MBG_RETURN_CODES + */ + int chk_hdr_rcvd( const MBG_MSG_RCV_CTL *prctl ) ; + + /** * @brief Encrypt a binary message * * In encryption mode the original packet is encrypted and put @@ -1453,11 +1918,13 @@ enum MBG_CONN_TYPES /** * @brief Complete message header and transmit message * - * Compute checksums and complete the message header, - * then transmit both header and data. The caller must - * have copied the data to be sent to the data field - * of the transmit buffer and have set up the cmd and - * len fields of the message header. + * Compute checksums and complete the message header, then + * transmit both header and data. The caller must have copied + * the data to be sent to the data field of the transmit buffer + * and have set up the cmd and len fields of the message header. + * + * This function doesn't protect access to the device by a mutex, + * so the calling function has to take care of the mutex handling. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to XBP address specifier @@ -1469,18 +1936,30 @@ enum MBG_CONN_TYPES /** * @brief Send a binary command message without parameters * + * This function doesn't protect access to the device by a mutex, + * so the calling function has to take care of the mutex handling, + * or ::mbgextio_xmt_cmd which does so should be called preferably + * from applications. + * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to XBP address specifier * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES * * @return One of the @ref MBG_RETURN_CODES * + * @see ::mbgextio_xmt_cmd + * @see ::mbgextio_xmt_cmd_us * @see ::xmt_cmd_us */ int xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) ; /** - * @brief Send a binary command message with ushort ( 16 bit) parameter + * @brief Send a binary command message with ushort (16 bit) parameter + * + * This function doesn't protect access to the device by a mutex, + * so the calling function has to take care of the mutex handling, + * or ::mbgextio_xmt_cmd_us which does so should be called preferably + * from applications. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to XBP address specifier @@ -1489,11 +1968,22 @@ enum MBG_CONN_TYPES * * @return One of the @ref MBG_RETURN_CODES * + * @see ::mbgextio_xmt_cmd_us + * @see ::mbgextio_xmt_cmd * @see ::xmt_cmd */ int xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t us ) ; /** + * @brief Init reception of a binary message + * + * @param[in,out] prctl Pointer to a valid receive control structure + * + * @see ::check_transfer + */ + void init_transfer( MBG_MSG_RCV_CTL *prctl ) ; + + /** * @brief Check an incoming data stream for a binary message * * Check the sequence of incoming characters for blocks of @@ -1501,6 +1991,9 @@ enum MBG_CONN_TYPES * which is part of the ::MBG_MSG_RCV_CTL structure and the * caller checks the return value to get the receive status. * + * This function doesn't protect access to the device by a mutex, + * so the calling function has to take care of the mutex handling. + * * @param[in,out] prctl Pointer to a valid receive control structure * @param[in] c A byte from the incoming data stream * diff --git a/mbglib/common/gpsutils.c b/mbglib/common/gpsutils.c index caa885b..f7e98f8 100644 --- a/mbglib/common/gpsutils.c +++ b/mbglib/common/gpsutils.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: gpsutils.c 1.9 2013/01/30 16:10:08Z martin REL_M $ + * $Id: gpsutils.c 1.9.1.7 2016/08/11 12:45:54Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,17 @@ * * ----------------------------------------------------------------------- * $Log: gpsutils.c $ - * Revision 1.9 2013/01/30 16:10:08Z martin + * Revision 1.9.1.7 2016/08/11 12:45:54Z martin + * Revision 1.9.1.6 2016/08/09 15:56:50Z martin + * Fixed format bug. + * Revision 1.9.1.5 2016/07/22 09:57:11 martin + * Quieted some compiler warninges. + * Revision 1.9.1.4 2015/09/07 09:19:58 martin + * Revision 1.9.1.3 2015/08/27 16:24:41 martin + * Revision 1.9.1.2 2015/08/25 15:34:48 martin + * Use save string functions from str_util.c. + * Revision 1.9.1.1 2015/08/21 14:21:57 martin + * Revision 1.9 2013/01/30 16:10:08 martin * Exclude some code from compiling by default, and * thus don't require pcpslstr.h by default. * Revision 1.8 2012/10/15 14:27:05Z martin @@ -38,32 +48,71 @@ #include <gpsutils.h> #undef _GPSUTILS -#if !defined( USE_SPRINTF ) - #define USE_SPRINTF 0 +#if defined( USE_SPRINTF ) + #error USE_SPRINTF was obsoleted by USE_SNPRINTF. Please update project settings. #endif -#if USE_SPRINTF - #include <pcpslstr.h> +#if !defined( USE_SNPRINTF ) + #define USE_SNPRINTF 0 +#endif + +#if !defined( _USE_GPSUTILS_FULL ) + #if defined( MBG_TGT_WIN32 ) && defined( __BORLANDC__ ) + #define _USE_GPSUTILS_FULL 1 + #else + #define _USE_GPSUTILS_FULL 0 + #endif +#endif + +#if USE_SNPRINTF + #include <str_util.h> +// #include <pcpslstr.h> +#define DEG "deg" +#endif + +#if _USE_GPSUTILS_FULL + #include <str_util.h> + #include <math.h> #endif #include <stdio.h> #include <string.h> -#include <math.h> -#define _eos( _s ) ( &(_s)[strlen( _s )] ) +#if USE_SNPRINTF || _USE_GPSUTILS_FULL + +static const char str_na[] = "N/A"; + +#endif + /*HDR*/ -void swap_double( double *d ) +/** + * @brief Swap the bytes of a single variable of type "double" + * + * The memory layout of a "double" on Meinberg bus level devices + * and computers usually differs. This function can be used to + * fix this and is usually called from inside API functions, + * if required. + * + * @param[in,out] p Pointer to a "double" to be swapped + * + * @see ::swap_eph_doubles + * @see ::swap_alm_doubles + * @see ::swap_utc_doubles + * @see ::swap_iono_doubles + * @see ::swap_pos_doubles + */ +void swap_double( double *p ) { uint16_t *wp1; uint16_t *wp2; uint16_t w; int i; - wp1 = (uint16_t *) d; - wp2 = ( (uint16_t *) d ) + 3; + wp1 = (uint16_t *) p; + wp2 = ( (uint16_t *) p ) + 3; for ( i = 0; i < 2; i++ ) { @@ -74,158 +123,284 @@ void swap_double( double *d ) wp2--; } -} /* swap_double */ +} // swap_double /*HDR*/ -void swap_eph_doubles( EPH *ephp ) +/** + * @brief Swap the "double" fields in an ::EPH structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to an ::EPH structure to be converted + * + * @see ::swap_double + * @see ::swap_alm_doubles + * @see ::swap_utc_doubles + * @see ::swap_iono_doubles + * @see ::swap_pos_doubles + */ +void swap_eph_doubles( EPH *p ) { - swap_double( &ephp->sqrt_A ); - swap_double( &ephp->e ); - swap_double( &ephp->M0 ); - swap_double( &ephp->omega ); - swap_double( &ephp->i0 ); - swap_double( &ephp->OMEGA0 ); - swap_double( &ephp->OMEGADOT ); - - swap_double( &ephp->deltan ); - swap_double( &ephp->idot ); - - swap_double( &ephp->crc ); - swap_double( &ephp->crs ); - swap_double( &ephp->cuc ); - swap_double( &ephp->cus ); - swap_double( &ephp->cic ); - swap_double( &ephp->cis ); - - swap_double( &ephp->af0 ); - swap_double( &ephp->af1 ); - swap_double( &ephp->af2 ); - - swap_double( &ephp->tgd ); + swap_double( &p->sqrt_A ); + swap_double( &p->e ); + swap_double( &p->M0 ); + swap_double( &p->omega ); + swap_double( &p->i0 ); + swap_double( &p->OMEGA0 ); + swap_double( &p->OMEGADOT ); + + swap_double( &p->deltan ); + swap_double( &p->idot ); + + swap_double( &p->crc ); + swap_double( &p->crs ); + swap_double( &p->cuc ); + swap_double( &p->cus ); + swap_double( &p->cic ); + swap_double( &p->cis ); + + swap_double( &p->af0 ); + swap_double( &p->af1 ); + swap_double( &p->af2 ); + + swap_double( &p->tgd ); } /* swap_eph_doubles */ /*HDR*/ -void swap_alm_doubles( ALM *almp ) +/** + * @brief Swap the "double" fields in an ::ALM structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to an ::ALM structure to be converted + * + * @see ::swap_double + * @see ::swap_eph_doubles + * @see ::swap_utc_doubles + * @see ::swap_iono_doubles + * @see ::swap_pos_doubles + */ +void swap_alm_doubles( ALM *p ) { - swap_double( &almp->sqrt_A ); - swap_double( &almp->e ); - swap_double( &almp->deltai ); - swap_double( &almp->OMEGA0 ); - swap_double( &almp->OMEGADOT ); - swap_double( &almp->omega ); - swap_double( &almp->M0 ); - swap_double( &almp->af0 ); - swap_double( &almp->af1 ); + swap_double( &p->sqrt_A ); + swap_double( &p->e ); + swap_double( &p->deltai ); + swap_double( &p->OMEGA0 ); + swap_double( &p->OMEGADOT ); + swap_double( &p->omega ); + swap_double( &p->M0 ); + swap_double( &p->af0 ); + swap_double( &p->af1 ); } /* swap_alm_doubles */ /*HDR*/ -void swap_utc_doubles( UTC *utcp ) +/** + * @brief Swap the "double" fields in a ::UTC structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to a ::UTC structure to be converted + * + * @see ::swap_double + * @see ::swap_eph_doubles + * @see ::swap_alm_doubles + * @see ::swap_iono_doubles + * @see ::swap_pos_doubles + */ +void swap_utc_doubles( UTC *p ) { - swap_double( &utcp->A0 ); - swap_double( &utcp->A1 ); + swap_double( &p->A0 ); + swap_double( &p->A1 ); } /* swap_utc_doubles */ /*HDR*/ -void swap_iono_doubles( IONO *ionop ) +/** + * @brief Swap the "double" fields in a ::IONO structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to a ::IONO structure to be converted + * + * @see ::swap_double + * @see ::swap_eph_doubles + * @see ::swap_alm_doubles + * @see ::swap_utc_doubles + * @see ::swap_pos_doubles + */ +void swap_iono_doubles( IONO *p ) { - swap_double( &ionop->alpha_0 ); - swap_double( &ionop->alpha_1 ); - swap_double( &ionop->alpha_2 ); - swap_double( &ionop->alpha_3 ); + swap_double( &p->alpha_0 ); + swap_double( &p->alpha_1 ); + swap_double( &p->alpha_2 ); + swap_double( &p->alpha_3 ); - swap_double( &ionop->beta_0 ); - swap_double( &ionop->beta_1 ); - swap_double( &ionop->beta_2 ); - swap_double( &ionop->beta_3 ); + swap_double( &p->beta_0 ); + swap_double( &p->beta_1 ); + swap_double( &p->beta_2 ); + swap_double( &p->beta_3 ); } /* swap_iono_doubles */ /*HDR*/ -void swap_pos_doubles( POS *posp ) +/** + * @brief Swap the "double" fields in a ::POS structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to a ::POS structure to be converted + * + * @see ::swap_double + * @see ::swap_eph_doubles + * @see ::swap_alm_doubles + * @see ::swap_utc_doubles + * @see ::swap_iono_doubles + */ +void swap_pos_doubles( POS *p ) { int i; for ( i = 0; i < N_XYZ; i++ ) - swap_double( &posp->xyz[i] ); + swap_double( &p->xyz[i] ); for ( i = 0; i < N_LLA; i++ ) - swap_double( &posp->lla[i] ); + swap_double( &p->lla[i] ); - swap_double( &posp->longitude.sec ); - swap_double( &posp->latitude.sec ); + swap_double( &p->longitude.sec ); + swap_double( &p->latitude.sec ); } /* swap_pos_doubles */ -#if USE_SPRINTF +#if USE_SNPRINTF /*HDR*/ -void sprint_dms( char *s, DMS *pdms, int prec ) +/** + * @brief Print the ::DMS part of a geo position into a string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p Pointer to a ::DMS structure to be printed + * @param[in] prec Precision, i.e. number of fractions of the seconds + * + * @return Length of the string in the buffer + * + * @see snprint_dms + * @see snprint_alt + * @see snprint_pos_geo + * @see snprint_fixed_freq + */ +size_t snprint_dms( char *s, size_t max_len, const DMS *p, int prec ) { - sprintf( s, "%c %i" DEG "%02i'%02.*f\"", - pdms->prefix, - pdms->deg, - pdms->min, - prec, - pdms->sec - ); + size_t n = snprintf_safe( s, max_len, "%c %i" DEG "%02i'%02.*f\"", + p->prefix, p->deg, p->min, + prec, p->sec ); + + return n; -} /* sprint_dms */ +} // snprint_dms /*HDR*/ -void sprint_alt( char *s, double alt ) +/** + * @brief Print the altitude part of a geo position into a string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] alt The altitude value to be printed, in [m] + * + * @return Length of the string in the buffer + * + * @see snprint_dms + * @see snprint_pos_geo + * @see snprint_fixed_freq + */ +size_t snprint_alt( char *s, size_t max_len, double alt ) { - sprintf( s, "%.0fm", alt ); + size_t n = snprintf_safe( s, max_len, "%.0fm", alt ); -} /* sprint_dms */ + return n; + +} // snprint_alt /*HDR*/ -void sprint_pos_geo( char *s, POS *ppos, const char *sep, int prec ) +/** + * @brief Print a geo position in ::POS format into a string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p Pointer to a ::POS structure to be printed + * @param[in] sep Separator character for the ::DMS part + * @param[in] prec Precision, i.e. number of fractions of the seconds of the ::DMS part + * + * @return Length of the string in the buffer + * + * @see snprint_dms + * @see snprint_alt + * @see snprint_fixed_freq + */ +size_t snprint_pos_geo( char *s, size_t max_len, const POS *p, char sep, int prec ) { - if ( ppos->lla[LON] && ppos->lla[LAT] && ppos->lla[ALT] ) + size_t n = 0; + + if ( p->lla[LON] && p->lla[LAT] && p->lla[ALT] ) { - sprint_dms( s, &ppos->latitude, prec ); - strcat( s, sep ); - sprint_dms( _eos( s ), &ppos->longitude, prec ); - strcat( s, sep ); - sprint_alt( _eos( s ), ppos->lla[ALT] ); + n += snprint_dms( &s[n], max_len - n, &p->latitude, prec ); + n += snprintf_safe( &s[n], max_len - n, "%c", sep ); + n += snprint_dms( &s[n], max_len - n, &p->longitude, prec ); + n += snprintf_safe( &s[n], max_len - n, "%c", sep ); + n += snprint_alt( &s[n], max_len - n, p->lla[ALT] ); } else - strcpy( s, "N/A" ); + n = sn_cpy_str_safe( s, max_len, str_na ); -} /* sprint_pos_geo */ + return n; -#endif +} // sprint_pos_geo +#endif // USE_SNPRINTF -#if defined( MBG_TGT_WIN32 ) && defined( __BORLANDC__ ) + +#if _USE_GPSUTILS_FULL /*HDR*/ -void sprint_fixed_freq( char *s, FIXED_FREQ_INFO *p_ff ) +/** + * @brief Print a formatted ::FIXED_FREQ_INFO into a string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_ff Pointer to a ::FIXED_FREQ_INFO structure to be printed + * + * @return Length of the string in the buffer + * + * @see snprint_dms + * @see snprint_alt + * @see snprint_pos_geo + */ +size_t snprint_fixed_freq( char *s, size_t max_len, FIXED_FREQ_INFO *p_ff ) { double freq; int range; ushort unit; ushort format; + size_t n = 0; // Before re-calculating frequency, range is the base 10 exponent // to the frequency value which is represented in kHz. @@ -298,19 +473,20 @@ void sprint_fixed_freq( char *s, FIXED_FREQ_INFO *p_ff ) // calculate display value freq = freq / pow( 10, ( ( 3 * unit ) - 3 ) ); - sprintf( s, fmt_str[format], freq, unit_str[unit] ); - return; + n = snprintf_safe( s, max_len, fmt_str[format], freq, unit_str[unit] ); } else { // out of range display fequency in Hz - sprintf( s, "%lfHz", freq ); + n = snprintf_safe( s, max_len, "%fHz", freq ); } } else - strcpy( s, "N/A" ); + n = sn_cpy_str_safe( s, max_len, str_na ); + + return n; -} /* sprint_fixed_freq */ +} // snprint_fixed_freq -#endif // defined( MBG_TGT_WIN32 ) && defined( __BORLANDC__ ) +#endif // _USE_GPSUTILS_FULL diff --git a/mbglib/common/gpsutils.h b/mbglib/common/gpsutils.h index c2143ca..7e9b713 100644 --- a/mbglib/common/gpsutils.h +++ b/mbglib/common/gpsutils.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: gpsutils.h 1.7 2010/07/15 09:32:09Z martin REL_M $ + * $Id: gpsutils.h 1.7.1.4 2016/08/11 13:50:01Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,13 @@ * * ----------------------------------------------------------------------- * $Log: gpsutils.h $ - * Revision 1.7 2010/07/15 09:32:09Z martin + * Revision 1.7.1.4 2016/08/11 13:50:01Z martin + * Include stddef.h. + * Revision 1.7.1.3 2015/08/27 16:24:41Z martin + * Revision 1.7.1.2 2015/08/25 15:34:48 martin + * Use save string functions from str_util.c. + * Revision 1.7.1.1 2015/08/21 14:22:06 martin + * Revision 1.7 2010/07/15 09:32:09 martin * Use DEG character definition from pcpslstr.h. * Revision 1.6 2005/02/18 10:32:33Z martin * Check more predefined macros to determine if compiling for Windows. @@ -34,6 +40,8 @@ #include <mbggeo.h> +#include <stddef.h> + #ifdef _GPSUTILS #define _ext @@ -57,16 +65,163 @@ extern "C" { /* This section was generated automatically */ /* by MAKEHDR, do not remove the comments. */ - void swap_double( double *d ) ; - void swap_eph_doubles( EPH *ephp ) ; - void swap_alm_doubles( ALM *almp ) ; - void swap_utc_doubles( UTC *utcp ) ; - void swap_iono_doubles( IONO *ionop ) ; - void swap_pos_doubles( POS *posp ) ; - void sprint_dms( char *s, DMS *pdms, int prec ) ; - void sprint_alt( char *s, double alt ) ; - void sprint_pos_geo( char *s, POS *ppos, const char *sep, int prec ) ; - void sprint_fixed_freq( char *s, FIXED_FREQ_INFO *p_ff ) ; + /** + * @brief Swap the bytes of a single variable of type "double" + * + * The memory layout of a "double" on Meinberg bus level devices + * and computers usually differs. This function can be used to + * fix this and is usually called from inside API functions, + * if required. + * + * @param[in,out] p Pointer to a "double" to be swapped + * + * @see ::swap_eph_doubles + * @see ::swap_alm_doubles + * @see ::swap_utc_doubles + * @see ::swap_iono_doubles + * @see ::swap_pos_doubles + */ + void swap_double( double *p ) ; + + /** + * @brief Swap the "double" fields in an ::EPH structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to an ::EPH structure to be converted + * + * @see ::swap_double + * @see ::swap_alm_doubles + * @see ::swap_utc_doubles + * @see ::swap_iono_doubles + * @see ::swap_pos_doubles + */ + void swap_eph_doubles( EPH *p ) ; + + /** + * @brief Swap the "double" fields in an ::ALM structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to an ::ALM structure to be converted + * + * @see ::swap_double + * @see ::swap_eph_doubles + * @see ::swap_utc_doubles + * @see ::swap_iono_doubles + * @see ::swap_pos_doubles + */ + void swap_alm_doubles( ALM *p ) ; + + /** + * @brief Swap the "double" fields in a ::UTC structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to a ::UTC structure to be converted + * + * @see ::swap_double + * @see ::swap_eph_doubles + * @see ::swap_alm_doubles + * @see ::swap_iono_doubles + * @see ::swap_pos_doubles + */ + void swap_utc_doubles( UTC *p ) ; + + /** + * @brief Swap the "double" fields in a ::IONO structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to a ::IONO structure to be converted + * + * @see ::swap_double + * @see ::swap_eph_doubles + * @see ::swap_alm_doubles + * @see ::swap_utc_doubles + * @see ::swap_pos_doubles + */ + void swap_iono_doubles( IONO *p ) ; + + /** + * @brief Swap the "double" fields in a ::POS structure + * + * See comments for ::swap_double + * + * @param[in,out] p Pointer to a ::POS structure to be converted + * + * @see ::swap_double + * @see ::swap_eph_doubles + * @see ::swap_alm_doubles + * @see ::swap_utc_doubles + * @see ::swap_iono_doubles + */ + void swap_pos_doubles( POS *p ) ; + + /** + * @brief Print the ::DMS part of a geo position into a string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p Pointer to a ::DMS structure to be printed + * @param[in] prec Precision, i.e. number of fractions of the seconds + * + * @return Length of the string in the buffer + * + * @see snprint_dms + * @see snprint_alt + * @see snprint_pos_geo + * @see snprint_fixed_freq + */ + size_t snprint_dms( char *s, size_t max_len, const DMS *p, int prec ) ; + + /** + * @brief Print the altitude part of a geo position into a string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] alt The altitude value to be printed, in [m] + * + * @return Length of the string in the buffer + * + * @see snprint_dms + * @see snprint_pos_geo + * @see snprint_fixed_freq + */ + size_t snprint_alt( char *s, size_t max_len, double alt ) ; + + /** + * @brief Print a geo position in ::POS format into a string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p Pointer to a ::POS structure to be printed + * @param[in] sep Separator character for the ::DMS part + * @param[in] prec Precision, i.e. number of fractions of the seconds of the ::DMS part + * + * @return Length of the string in the buffer + * + * @see snprint_dms + * @see snprint_alt + * @see snprint_fixed_freq + */ + size_t snprint_pos_geo( char *s, size_t max_len, const POS *p, char sep, int prec ) ; + + /** + * @brief Print a formatted ::FIXED_FREQ_INFO into a string buffer + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_ff Pointer to a ::FIXED_FREQ_INFO structure to be printed + * + * @return Length of the string in the buffer + * + * @see snprint_dms + * @see snprint_alt + * @see snprint_pos_geo + */ + size_t snprint_fixed_freq( char *s, size_t max_len, FIXED_FREQ_INFO *p_ff ) ; + /* ----- function prototypes end ----- */ diff --git a/mbglib/common/lan_util.c b/mbglib/common/lan_util.c new file mode 100644 index 0000000..8aea36e --- /dev/null +++ b/mbglib/common/lan_util.c @@ -0,0 +1,1938 @@ + +/************************************************************************** + * + * $Id: lan_util.c 1.11.1.14 2017/04/10 13:05:16Z martin TEST $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Utility functions useful for network programming. + * + * ----------------------------------------------------------------------- + * $Log: lan_util.c $ + * Revision 1.11.1.14 2017/04/10 13:05:16Z martin + * Fixed some compiler warnings. + * Revision 1.11.1.13 2017/02/23 15:24:22Z martin + * Fixed macro definition syntax to avoid clang compiler warnings. + * Revision 1.11.1.12 2016/10/31 17:39:47 martin + * Only return standard MBG_RETURN_CODES. + * Removed definitions of old MBG_LU_... return codes. + * Renamed check_octets_not_all_zero() to octets_are_all_zero(), which returns a bool now. + * Renamed check_mac_addr_not_all_zero() to mac_addr_all_zero(), which returns a bool now. + * Removed get_port_mac_addr_check(). + * Updated doxygen comments. + * Revision 1.11.1.11 2016/09/22 12:25:26 thomas-b + * Fixed compiler warning for uninitialized vars + * Revision 1.11.1.10 2016/08/10 12:25:54 martin + * Check for MBG_TGT_POSIX instead of MBG_TGT_UNIX. + * Revision 1.11.1.9 2016/08/09 07:10:22 martin + * *** empty log message *** + * Revision 1.11.1.8 2015/12/01 11:35:31 martin + * Doxygen fixes. + * Revision 1.11.1.7 2015/11/11 18:16:08 martin + * New function snprint_ptp_clock_id(). + * Revision 1.11.1.6 2015/11/04 17:06:35Z martin + * *** empty log message *** + * Revision 1.11.1.5 2015/09/17 10:06:30 martin + * Revision 1.11.1.4 2015/08/31 10:26:26Z martin + * Revision 1.11.1.3 2015/08/27 16:23:16Z martin + * Use safe string functions from str_util.c. + * Cleanup. + * Revision 1.11.1.2 2015/04/13 15:26:50 hannes + * Added all function defintions for IP6. + * FIX: Fixed snprint_ip4_cidr_mask to behave as expected. + * It will concatenate the cidr mask bits to the ip address now. + * Revision 1.11.1.1 2015/04/02 15:28:31 hannes + * Started adding the ipv4 functions for ipv6. + * Revision 1.11 2015/04/01 14:31:14 hannes + * Fix: cidr_str_to_ip4_addr_and_net_mask: Defaults correctly to + * netmask 0.0.0.0 (/0) for no CIDR extension in cidr_str. + * Revision 1.10 2014/10/17 12:45:48 martin + * Let str_to_ip4_addr() return 0 if an empty string has been passed. + * Revision 1.9 2014/09/24 08:31:00 martin + * Exclude get_ip4_gateway() from build if USE_MBG_TSU is defined. + * Fixed some compiler warnings. + * Added and modified some comments. + * Revision 1.8 2013/10/02 07:19:13 martin + * New function get_port_intf_idx. + * Fixed naming.of local netlink support functions. + * Revision 1.7 2013/05/22 16:49:42 martin + * Fixed some return codes. + * Revision 1.6 2013/03/19 10:24:51 martin + * Fixed bugs in get_ip4_gateway(): A skipped routing entry was + * taken as default route, and thus a wrong default route 0.0.0.0 + * could be returned erraneously. Also, malloc() was used without + * checking the result. + * Added conditional debug code. + * Revision 1.5 2013/02/19 15:13:10 martin + * Added some new functions. + * Updated doxygen comments. + * Revision 1.4 2012/11/02 09:16:57 martin + * Fixed build under Windows. + * Revision 1.3 2012/10/02 18:23:28Z martin + * Removed obsolete code to avoid compiler warning. + * Revision 1.2 2012/03/09 08:49:19 martin + * Added some commonly used functions. + * Revision 1.1 2011/03/04 10:01:32Z martin + * Initial revision. + * + **************************************************************************/ + +#define _LAN_UTIL + #include <lan_util.h> +#undef _LAN_UTIL + +#include <words.h> +#include <str_util.h> +#include <mbgerror.h> + +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +#if defined( MBG_TGT_POSIX ) + + #if defined( MBG_TGT_LINUX ) + + #include <linux/types.h> + + // Some older versions of linux/types.h don't define u8..u64 + // for user space applications. However, if they do they also + // define BITS_PER_LONG, so we use this symbol to figure out + // if we need to define u8..u64 by ourselves. + #if !defined( BITS_PER_LONG ) + typedef uint8_t u8; + typedef uint16_t u16; + typedef uint32_t u32; + typedef uint64_t u64; + #endif + + #include <linux/sockios.h> + #include <linux/ethtool.h> + #include <linux/rtnetlink.h> + #endif + + #include <unistd.h> + #include <syslog.h> + #include <sys/ioctl.h> + #include <arpa/inet.h> + #include <netinet/in.h> + +#else + + // dummy codes, the functions will report an error ... + #define SIOCGIFADDR 0 + #define SIOCGIFNETMASK 0 + #define SIOCGIFBRDADDR 0 + + #if defined( MBG_TGT_WIN32 ) + #define snprintf _snprintf + #endif + +#endif + + +#if !defined( DEBUG_NETLINK ) + #if ( 0 && defined( DEBUG ) && defined( MBG_TGT_LINUX ) ) + #define DEBUG_NETLINK 1 + #else + #define DEBUG_NETLINK 0 + #endif +#endif + + +#if DEBUG_NETLINK + // we need a function to output debugging information + #if !defined STANDALONE + #include <ptp2_cnf.h> // for mbglog() from the ARM PTP projects + #else + // to be provided by the application + extern __attribute__( ( format( printf, 2, 3 ) ) ) void mbglog( int priority, const char *fmt, ... ); + #endif +#endif // DEBUG_NETLINK + + + +// Maximum size of an IPv4 address string in dotted quad format, +// including a terminating 0, and thus the required minimum size +// for a buffer to take such a string. i.e. "aaa.bbb.ccc.ddd\0". +#define MAX_IP4_ADDR_STR_SIZE 16 + + +#if defined( MBG_TGT_LINUX ) + +struct route_info +{ + struct in_addr dstAddr; + struct in_addr srcAddr; + struct in_addr gateWay; + char ifName[IF_NAMESIZE]; +}; + +#endif + + + +/*HDR*/ +/** + * @brief Count the number of sequential bits in an IPv4 net mask + * + * Counting starts from MSB, i.e. for 0xC0 and 0xC1 the results + * are both 2 since only the 2 MSBs are sequentially set. + * + * @param[in] p_mask The IPv4 net mask to be evaluated + * + * @return The number of sequential MSB bits set in *p_mask + * + * @see ::ip4_net_mask_from_cidr + */ +int get_ip4_net_mask_bits( const IP4_ADDR *p_mask ) +{ + IP4_ADDR msb_mask = IP4_MSB_MASK; + int i; + + for ( i = 0; i < MAX_IP4_BITS; i++ ) + { + if ( ( *p_mask & msb_mask ) == 0 ) + break; + + msb_mask >>= 1; + } + + return i; + +} // get_ip4_net_mask_bits + + + +/*HDR*/ +/** + * @brief Print an IPv4 address to a dotted quad formatted string + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv4 address to be evaluated + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip4_cidr_addr + * @see ::str_to_ip4_addr + * @see ::cidr_str_to_ip4_addr_and_net_mask + */ +size_t snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *p_addr, const char *info ) +{ + size_t n = 0; + ulong ul = *p_addr; + + if ( info ) + n += snprintf_safe( s, max_len, "%s", info ); + + // Don't use byte pointers here since this is not safe + // for both little and big endian targets. + n += snprintf_safe( &s[n], max_len - n, "%u.%u.%u.%u", + BYTE_3( ul ), BYTE_2( ul ), + BYTE_1( ul ), BYTE_0( ul ) + ); + return n; + +} // snprint_ip4_addr + + + +/*HDR*/ +/** + * @brief Print an IPv4 address plus net mask in CIDR notation to a string + * + * The printed CIDR string is something like "172.16.3.250/24" + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv4 address to be evaluated + * @param[in] p_mask The associated IPv4 net mask + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip4_addr + * @see ::str_to_ip4_addr + * @see ::cidr_str_to_ip4_addr_and_net_mask + */ +size_t snprint_ip4_cidr_addr( char *s, size_t max_len, const IP4_ADDR *p_addr, + const IP4_ADDR *p_mask, const char *info ) +{ + int cidr_mask_bits; + size_t n = snprint_ip4_addr( s, max_len, p_addr, info ); + + cidr_mask_bits = get_ip4_net_mask_bits( p_mask ); + + if ( ( cidr_mask_bits >= MIN_IP4_CIDR_NETMASK_BITS ) && + ( cidr_mask_bits <= MAX_IP4_CIDR_NETMASK_BITS ) ) + n += snprintf_safe( &s[n], max_len - n, "/%i", cidr_mask_bits ); + + return n; + +} // snprint_ip4_cidr_addr + + + +/*HDR*/ +/** + * @brief Convert a string to an ::IP4_ADDR + * + * If output parameter is specified as NULL then this function + * can be used to check if the IPv4 address string is formally correct. + * + * @param[out] p_addr Pointer to an ::IP4_ADDR variable to be filled, or NULL + * @param[in] s An IPv4 address string to be converted + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip4_addr + * @see ::snprint_ip4_cidr_addr + * @see ::cidr_str_to_ip4_addr_and_net_mask + */ +int str_to_ip4_addr( IP4_ADDR *p_addr, const char *s ) +{ + IP4_ADDR tmp_ip4_addr = 0; + const char *cp = s; + int i; + + if ( strlen( s ) ) + { + for ( i = 0; ; ) + { + unsigned long ul = strtoul( (char *) cp, (char **) &cp, 10 ); + + if ( ul > 0xFFUL ) // invalid number + return MBG_ERR_INV_PARM; + + tmp_ip4_addr |= ul << ( 8 * (3 - i) ); + + if ( ++i >= 4 ) + break; // done + + if ( *cp != '.' ) + return MBG_ERR_INV_PARM; // invalid string format, dot expected + + cp++; // skip dot + } + } + + if ( p_addr ) + *p_addr = tmp_ip4_addr; + + // success: return the number of evaluated chars + return (int) ( cp - s ); + +} // str_to_ip4_addr + + + +/*HDR*/ +/** + * @brief Convert a string in CIDR notation to an ::IP4_ADDR and net mask + * + * If output parameters are specified as NULL then this function + * can be used to check if the CIDR string is formally correct. + * + * @param[out] p_addr Pointer to an ::IP4_ADDR variable to be filled with + * the IPv4 address, or NULL + * @param[out] p_mask Pointer to an ::IP4_ADDR variable to be filled with + * the IPv4 net mask, or NULL + * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "172.16.3.250/24" + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip4_addr + * @see ::snprint_ip4_cidr_addr + * @see ::str_to_ip4_addr + */ +int cidr_str_to_ip4_addr_and_net_mask( IP4_ADDR *p_addr, IP4_ADDR *p_mask, + const char *cidr_str ) +{ + IP4_ADDR mask; + long cidr_mask_bits; + const char *cp; + int l; + int rc = str_to_ip4_addr( p_addr, cidr_str ); + + if ( mbg_rc_is_error( rc ) ) + return rc; + + + l = (int) strlen( cidr_str ); + + if ( l < rc ) // input string too short + return MBG_ERR_INV_PARM; + + + cp = &cidr_str[rc]; + + if ( *cp == 0 ) // end of string + { + // The string has no CIDR extension, so + // assume "/0", i.e. host mask 0.0.0.0; + mask = (IP4_ADDR) 0; + goto done; + } + + + if ( *cp != '/' ) + return MBG_ERR_INV_PARM; + + + cp++; + cidr_mask_bits = strtol( (char *) cp, (char **) &cp, 10 ); + + if ( ( cidr_mask_bits < MIN_IP4_CIDR_NETMASK_BITS ) || + ( cidr_mask_bits > MAX_IP4_CIDR_NETMASK_BITS ) ) + return MBG_ERR_RANGE; + + + mask = ip4_net_mask_from_cidr( (int) cidr_mask_bits ); + +done: + if ( p_mask ) + *p_mask = mask; + + // success: return the number of evaluated chars + return (int) ( cp - cidr_str ); + +} // cidr_str_to_ip4_addr_and_net_mask + + + +/*HDR*/ +/** + * @brief Count the number of sequential bits in an IPv6 net mask + * + * Counting starts from MSB, i.e. for 0xC0 and 0xC1 the results + * are both 2 since only the 2 MSBs are sequentially set. + * + * @param[in] p_mask The IPv6 net mask to be evaluated + * + * @return The number of sequential MSB bits set in *p_mask + * + * @see ::ip6_net_mask_from_cidr + */ +int get_ip6_net_mask_bits( const IP6_ADDR *p_mask ) +{ + int i; + int cnt = 0; + uint8_t msb_mask = IP6_MSB_MASK; + + for ( i = IP6_ADDR_BYTES - 1 ; i >= 0; i-- ) + { + if ( p_mask->b[i] == 0xff ) + cnt += 8; + else + { + for ( ; cnt < MAX_IP6_CIDR_NETMASK_BITS; cnt++ ) + { + if ( ( p_mask->b[i] & msb_mask ) == 0 ) + break; + + msb_mask >>= 1; + } + break; + } + } + + return cnt; + +} // get_ip6_net_mask_bits + + + +/*HDR*/ +/** + * @brief Print an IPv6 address in optimized format to a string + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv6 address to be evaluated + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip6_cidr_addr + * @see ::snprint_ip6_cidr_mask_addr + * @see ::str_to_ip6_addr + * @see ::cidr_str_to_ip6_addr_and_cidr_bits + * @see ::cidr_str_to_ip6_addr_and_net_mask + */ +size_t snprint_ip6_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, const char *info ) +{ + // Copied from inet_ntop.c, and reversed byte order + + IP6_ADDR_STR tmp; + char *tp; + #define NUM_WORDS ( (int) ( sizeof( IP6_ADDR_STR ) / sizeof( uint16_t ) ) ) + uint16_t words[NUM_WORDS] = { 0 }; + int i; + size_t n = 0; + struct + { + int base; + int len; + } best = { 0 }, cur = { 0 }; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in p_addr->b[] for :: shorthanding. + */ + for ( i = IP6_ADDR_BYTES - 1; i >= 0; i-- ) + words[(IP6_ADDR_BYTES - 1 - i) / 2] |= (p_addr->b[i] << ((1 - ((IP6_ADDR_BYTES - 1 - i) % 2)) << 3)); + + best.base = -1; + cur.base = -1; + + for ( i = 0; i < NUM_WORDS; i++ ) + { + if ( words[i] == 0 ) + { + if ( cur.base == -1 ) + cur.base = i, cur.len = 1; + else + cur.len++; + } + else + { + if ( cur.base != -1 ) + { + if ( best.base == -1 || cur.len > best.len ) + best = cur; + + cur.base = -1; + } + } + } + + if ( cur.base != -1 ) + { + if ( best.base == -1 || cur.len > best.len ) + best = cur; + } + + if ( best.base != -1 && best.len < 2 ) + best.base = -1; + + // Format the result. + + tp = tmp; + + for ( i = 0; i < NUM_WORDS; i++ ) + { + /* Are we inside the best run of 0x00's? */ + if ( best.base != -1 && i >= best.base && i < ( best.base + best.len ) ) + { + if (i == best.base) + *tp++ = ':'; + + continue; + } + + /* Are we following an initial run of 0x00s or any real hex? */ + if ( i != 0 ) + *tp++ = ':'; + + /* Is this address an encapsulated IPv4? */ + if ( i == 6 && best.base == 0 && ( best.len == 6 || ( best.len == 5 && words[5] == 0xffff ) ) ) + return MBG_ERR_INV_PARM; // we don't support ecapsulated IPv4 + + sprintf( tp, "%x", words[i] ); + tp += strlen( tp ); + } + + /* Was it a trailing run of 0x00's? */ + if ( best.base != -1 && ( best.base + best.len ) == NUM_WORDS ) + *tp++ = ':'; + + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ( ( tp - tmp ) > (int) max_len ) + return MBG_ERR_OVERFLOW; + + if ( info ) + n += snprintf_safe( s, max_len, "%s", info ); + + n += snprintf_safe( &s[n], max_len - n, "%s", tmp ); + + return n; + + #undef NUM_WORDS + +} // snprint_ip6_addr + + + +/*HDR*/ +/** + * @brief Print an IPv6 address plus net mask to string in CIDR notation + * + * The printed CIDR string is something like "2001:0DB8:0:CD30:EF45::/64" + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv6 address to be evaluated + * @param[in] p_mask The associated IPv6 net mask + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip6_addr + * @see ::snprint_ip6_cidr_mask_addr + * @see ::str_to_ip6_addr + * @see ::cidr_str_to_ip6_addr_and_cidr_bits + * @see ::cidr_str_to_ip6_addr_and_net_mask + */ +size_t snprint_ip6_cidr_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, + const IP6_ADDR *p_mask, const char *info ) +{ + size_t n = snprint_ip6_addr( s, max_len, p_addr, info ); + + int cidr_mask_bits = get_ip6_net_mask_bits( p_mask ); + + if ( ( cidr_mask_bits >= MIN_IP6_CIDR_NETMASK_BITS ) && + ( cidr_mask_bits <= MAX_IP6_CIDR_NETMASK_BITS ) ) + n += snprintf_safe( &s[n], max_len - n, "/%i", cidr_mask_bits ); + + return n; + +} // snprint_ip6_cidr_addr + + + +/*HDR*/ +/** + * @brief Print an IPv6 address plus number of net mask bits to string in CIDR notation + * + * The printed CIDR string is something like "2001:0DB8:0:CD30:EF45::/64" + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv6 address to be evaluated + * @param[in] cidr_mask_bits The CIDR number of bits specifying the IPv6 net mask + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip6_addr + * @see ::snprint_ip6_cidr_addr + * @see ::str_to_ip6_addr + * @see ::cidr_str_to_ip6_addr_and_cidr_bits + * @see ::cidr_str_to_ip6_addr_and_net_mask + */ +size_t snprint_ip6_cidr_mask_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, + const int cidr_mask_bits, const char* info ) +{ + size_t n; + IP6_ADDR mask; + + ip6_net_mask_from_cidr( &mask, cidr_mask_bits ); + + n = snprint_ip6_addr( s, max_len, p_addr, info ); + + if ( ( cidr_mask_bits >= MIN_IP6_CIDR_NETMASK_BITS ) && + ( cidr_mask_bits <= MAX_IP6_CIDR_NETMASK_BITS ) ) + n += snprintf_safe( &s[n], max_len - n, "/%i", cidr_mask_bits ); + + return n; + +} // snprint_ip6_cidr_mask_addr + + + +/*HDR*/ +/** + * @brief Convert a string to an ::IP6_ADDR + * + * If the output parameter is specified as NULL then this function + * can be used to check if the string is formally correct. + * + * On success ::IP6_ADDR variable contains the IPv6 address + * in little endian byte order. + * + * @param[out] p_addr Pointer to the ::IP6_ADDR variable, or NULL + * @param[in] s A string containing an IPv6 address + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip6_addr + * @see ::snprint_ip6_cidr_addr + * @see ::snprint_ip6_cidr_mask_addr + * @see ::str_to_ip6_addr + * @see ::cidr_str_to_ip6_addr_and_cidr_bits + * @see ::cidr_str_to_ip6_addr_and_net_mask + */ +int str_to_ip6_addr( IP6_ADDR *p_addr, const char *s ) +{ + // copied from inet_pton.c and reversed byte order + IP6_ADDR tmp = { { 0 } }; + static const char xdigits[] = "0123456789abcdef"; + uint8_t *tp; + uint8_t *startp; + uint8_t *colonp; + int ch; + int saw_xdigit; + int read_cnt = 0; + unsigned int val; + + if ( p_addr ) + memset( p_addr, 0, sizeof( *p_addr ) ); // set IP address to :: + + startp = tmp.b - 1; + tp = startp + sizeof( tmp ); + + colonp = NULL; + + /* Leading :: requires some special handling. */ + if ( *s == ':' ) + { + read_cnt++; + + if ( *++s != ':' ) + return MBG_ERR_INV_PARM; + } + + saw_xdigit = 0; + val = 0; + + while ( ( ch = tolower( *s++ ) ) != '\0' ) + { + const char *pch; + + read_cnt++; + + pch = strchr( xdigits, ch ); + + if ( pch != NULL ) + { + val <<= 4; + val |= ( pch - xdigits ); + + if ( val > 0xffff ) //### TODO signed? unsigned? + return MBG_ERR_INV_PARM; + + saw_xdigit = 1; + continue; + } + + if ( ch == ':' ) + { + if ( !saw_xdigit ) + { + if ( colonp ) + return MBG_ERR_INV_PARM; + + colonp = tp; + continue; + + } + else + if ( *s == '\0' ) + return MBG_ERR_INV_PARM; + + if ( tp - sizeof( uint16_t ) < startp ) + return MBG_ERR_INV_PARM; + + *tp-- = (uint8_t) ( val >> 8 ) & 0xff; + *tp-- = (uint8_t) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + + if ( ch == '/' ) // cidr notation. we reached the end + { + read_cnt--; + break; + } + + return MBG_ERR_INV_PARM; + } + + if ( saw_xdigit ) + { + if ( tp - sizeof( uint16_t ) < startp ) + return MBG_ERR_INV_PARM; + + *tp-- = (uint8_t) (val >> 8) & 0xff; + *tp-- = (uint8_t) val & 0xff; + } + + if ( colonp != NULL ) + { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const size_t n = colonp - tp; + size_t i; + + if ( tp == startp ) + return MBG_ERR_INV_PARM; + + for ( i = 0; i <= n; i++ ) + { + startp[i] = colonp[i - n]; + colonp[i - n] = 0; + } + + tp = startp; + } + + if ( tp != startp ) + return MBG_ERR_INV_PARM; + + if ( p_addr ) + *p_addr = tmp; + + return read_cnt; + +} // str_to_ip6_addr + + + +/*HDR*/ +/** + * @brief Convert a string in CIDR notation to an ::IP6_ADDR and net mask + * + * If output parameters are specified as NULL then this function + * can be used to check if the CIDR string is formally correct. + * + * @param[out] p_addr Pointer to an ::IP6_ADDR variable to be filled up + * with the IPv6 address, or NULL + * @param[out] p_mask Pointer to an ::IP6_ADDR variable to be filled up + with the net mask bits, or NULL + * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "2001:0DB8:0:CD30::/64" + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip4_addr + * @see ::snprint_ip4_cidr_addr + * @see ::str_to_ip4_addr + */ +int cidr_str_to_ip6_addr_and_net_mask( IP6_ADDR *p_addr, IP6_ADDR *p_mask, const char *cidr_str ) +{ + int mask = 0; + int rc = cidr_str_to_ip6_addr_and_cidr_bits( p_addr, &mask, cidr_str ); + + if ( mbg_rc_is_error( rc ) ) + return rc; + + if ( p_mask ) + ip6_net_mask_from_cidr( p_mask, mask ); + + return rc; + +} // cidr_str_to_ip6_addr_and_net_mask + + + +/*HDR*/ +/** + * @brief Convert a string in CIDR notation to an ::IP6_ADDR and net mask bits + * + * If output parameters are specified as NULL then this function + * can be used to check if the CIDR string is formally correct. + * + * @param[out] p_addr Pointer to an ::IP6_ADDR variable for the IPv6 address, or NULL + * @param[out] p_cidr Pointer to an int variable for the net mask bits, or NULL + * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "2001:0DB8:0:CD30::/64" + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip6_addr + * @see ::snprint_ip6_cidr_addr + * @see ::str_to_ip6_addr + */ +int cidr_str_to_ip6_addr_and_cidr_bits( IP6_ADDR *p_addr, int *p_cidr, + const char *cidr_str ) +{ + long cidr_mask_bits; + const char *cp; + ssize_t l; + int rc = str_to_ip6_addr( p_addr, cidr_str ); + + if ( mbg_rc_is_error( rc ) ) + return rc; + + l = strlen( cidr_str ); + + if ( l < rc ) // input string too short + return MBG_ERR_INV_PARM; + + cp = &cidr_str[rc]; + + if ( *cp == 0 ) // end of string + { + // The string has no CIDR extension, so + // assume "/0", i.e. host mask :: + cidr_mask_bits = 0; + goto done; + } + + if ( *cp != '/' ) + return MBG_ERR_INV_PARM; + + cp++; + cidr_mask_bits = strtol( (char *) cp, (char **) &cp, 10 ); + + if ( ( cidr_mask_bits < MIN_IP6_CIDR_NETMASK_BITS ) || + ( cidr_mask_bits > MAX_IP6_CIDR_NETMASK_BITS ) ) + return MBG_ERR_RANGE; + +done: + if ( p_cidr ) + *p_cidr = (int) cidr_mask_bits; + + // success: return the number of evaluated chars + return (int) ( cp - cidr_str ); + +} // cidr_str_to_ip6_addr_and_cidr_bits + + + +/*HDR*/ +/** + * @brief Compute an IPv6 net mask according to the number of CIDR netmask bits + * + * E.g. the 64 bits mentioned in "2001:0DB8:0:CD30::/64" result in 2^64, + * corresponding to FFFF:FFFF:FFFF:FFFF:: in IPv6 notation. + * + * @param[out] p_mask Pointer to an ::IP6_ADDR variable for the IPv6 netmask + * @param[in] netmask_bits Number of netmask bits from CIDR notation + * + * @see ::get_ip6_net_mask_bits + */ +void ip6_net_mask_from_cidr( IP6_ADDR *p_mask, int netmask_bits ) +{ + int i = 0; + + if ( p_mask ) + { + memset( p_mask, 0, sizeof( *p_mask ) ); + + if ( netmask_bits < 0 ) + netmask_bits = 0; + else + if ( netmask_bits >= IP6_ADDR_BITS ) + netmask_bits = IP6_ADDR_BITS; + + for ( i = IP6_ADDR_BYTES - 1; i >= 0; i-- ) + { + if ( netmask_bits > 8 ) + { + p_mask->b[i] = 0xff; + netmask_bits -= 8; + } + else + { + p_mask->b[i] = (0xff << ( 8 - netmask_bits ) ) & 0xff; + netmask_bits = 0; + } + } + } + +} // ip6_net_mask_from_cidr + + + +/*HDR*/ +/** + * @brief Determine the network part of an IPv6 address based on the net mask + * + * E.g. IP "2001:0DB8:0:CD30::", net mask "FFFF:FFFF::" yields network part "2001:0DB8::". + * + * @param[out] p_net_part The extracted network part of the IPv6 address + * @param[in] p_addr The IPv6 address to be evaluated + * @param[in] p_mask The associated IPv6 net mask + */ +void ip6_net_part_from_addr( IP6_ADDR *p_net_part, const IP6_ADDR *p_addr, + const IP6_ADDR *p_mask ) +{ + int i; + + for ( i = IP6_ADDR_BYTES; i-- > 0; ) + p_net_part->b[i] = p_addr->b[i] & p_mask->b[i]; + +} // ip6_net_part_from_addr + + + +/*HDR*/ +/** + * @brief Print a MAC ID or similar array of octets to a string + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Maximum length of the string, i.e. size of the buffer + * @param[in] octets An array of octets + * @param[in] num_octets The number of octets to be printed from the array + * @param[in] sep The separator printed between the bytes, or 0 + * @param[in] info An optional string which is prepended to the output, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_mac_addr + * @see ::str_to_octets + * @see ::octets_are_all_zero + */ +size_t snprint_octets( char *s, size_t max_len, const uint8_t *octets, + int num_octets, char sep, const char *info ) +{ + size_t n = 0; + int i; + + if ( info ) + n += snprintf_safe( s, max_len, "%s", info ); + + for ( i = 0; i < num_octets; i++ ) + { + if ( i && sep ) + n += snprintf_safe( &s[n], max_len - n, "%c", sep ); + + n += snprintf_safe( &s[n], max_len - n, "%02X", octets[i] ); + } + + return n; + +} // snprint_octets + + + +/*HDR*/ +/** + * @brief Print a ::PTP_CLOCK_ID to a string + * + * @todo Eventually this function should be moved to a different module. + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Maximum length of the string, i.e. size of the buffer + * @param[in] p The ::PTP_CLOCK_ID to be printed + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_octets + */ +size_t snprint_ptp_clock_id( char *s, size_t max_len, const PTP_CLOCK_ID *p ) +{ + return snprint_octets( s, max_len, p->b, sizeof( *p ), ':', NULL ); + +} // snprint_ptp_clock_id + + + +/*HDR*/ +/** + * @brief Print a MAC address to a string + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Maximum length of the string, i.e. size of the buffer + * @param[in] p_mac_addr The MAC address to be printed + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_octets + * @see ::str_to_octets + * @see ::octets_are_all_zero + */ +size_t snprint_mac_addr( char *s, size_t max_len, const MBG_MAC_ADDR *p_mac_addr ) +{ + return snprint_octets( s, max_len, p_mac_addr->b, sizeof( *p_mac_addr ), MAC_SEP_CHAR, NULL ); + +} // snprint_mac_addr + + + +/*HDR*/ +/** + * @brief Set a MAC ID or a similar array of octets from a string + * + * @param[out] octets An array of octets to be set up + * @param[in] num_octets The number of octets which can be stored + * @param[in] s The string to be converted + * + * @return The overall number of octets decoded from the string + * + * @see ::snprint_octets + * @see ::snprint_mac_addr + * @see ::octets_are_all_zero + */ +int str_to_octets( uint8_t *octets, int num_octets, const char *s ) +{ + char *cp = (char *) s; + int i; + + // don't use strtok() since that functions modifies the original string + for ( i = 0; i < num_octets; ) + { + octets[i] = (uint8_t) strtoul( cp, &cp, 16 ); + i++; + + if ( *cp == 0 ) + break; // end of string + + if ( ( *cp != MAC_SEP_CHAR ) && ( *cp != MAC_SEP_CHAR_ALT ) ) + break; // invalid character + + cp++; + } + + return i; + +} // str_to_octets + + + +/*HDR*/ +/** + * @brief Check if an array of octets is all zero + * + * @param[in] octets Pointer to the array of octets + * @param[in] num_octets Number of octets + * + * @return true if all bytes are 0, else false + * + * @see ::snprint_octets + * @see ::snprint_mac_addr + * @see ::str_to_octets + */ +bool octets_are_all_zero( const uint8_t *octets, int num_octets ) +{ + int i; + + // check if any of the bytes is != 0 + for ( i = 0; i < num_octets; i++ ) + if ( octets[i] != 0 ) + break; + + return i == num_octets; // true if *all* bytes are 0 + +} // octets_are_all_zero + + + +/*HDR*/ +/** + * @brief Check if a MAC address is all zero + * + * @param[in] p_addr Pointer to a MAC address to be checked + * + * @return true if all bytes of the MAC address are 0, else false + * + * @see ::octets_are_all_zero + */ +bool mac_addr_is_all_zero( const MBG_MAC_ADDR *p_addr ) +{ + return octets_are_all_zero( p_addr->b, sizeof( p_addr->b ) ); + +} // mac_addr_is_all_zero + + + +#if defined( MBG_TGT_POSIX ) + +/*HDR*/ +/** + * @brief Do a SIOCGxxx IOCTL call to read specific information from a LAN interface + * + * @param[in] if_name Name of the interface + * @param[in] ioctl_code One of the predefined system SIOCGxxx IOCTL codes + * @param[out] p_ifreq Pointer to a request buffer + * + * @return One of the @ref MBG_RETURN_CODES + */ +int do_siocg_ioctl( const char *if_name, int ioctl_code, struct ifreq *p_ifreq ) +{ + int sock_fd; + int rc; + + if ( strlen( if_name ) > ( IFNAMSIZ - 1 ) ) + return MBG_ERR_INV_PARM; + + sock_fd = socket( AF_INET, SOCK_DGRAM, 0 ); //### TODO: or AF_INET6/PF_INET6 for IPv6 + + if ( sock_fd == -1 ) // failed to open socket + return mbg_get_last_socket_error( "failed to open socket in do_siocg_ioctl" ); + + strncpy_safe( p_ifreq->ifr_name, if_name, sizeof( p_ifreq->ifr_name ) ); + + rc = ioctl( sock_fd, ioctl_code, p_ifreq ); + + if ( rc == -1 ) // ioctl failed, errno has been set appropriately + rc = mbg_get_last_socket_error( "ioctl failed in do_siocg_ioctl" ); + else + rc = MBG_SUCCESS; + + close( sock_fd ); + + return rc; + +} // do_siocg_ioctl + +#endif // defined( MBG_TGT_POSIX ) + + + +/*HDR*/ +/** + * @brief Retrieve the index of a specific network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_intf_idx Pointer to a variable to be filled up + * + * @return One of the @ref MBG_RETURN_CODES. + * On error, *p_intf_idx is set to -1. + */ +int get_port_intf_idx( const char *if_name, int *p_intf_idx ) +{ + int rc = MBG_ERR_NOT_SUPP_ON_OS; + + #if defined( MBG_TGT_LINUX ) + struct ifreq ifr = { { { 0 } } }; + + rc = do_siocg_ioctl( if_name, SIOCGIFINDEX, &ifr ); + + if ( mbg_rc_is_success( rc ) ) + { + *p_intf_idx = ifr.ifr_ifindex; + return rc; + } + #endif + + // we get here on error only + *p_intf_idx = -1; + + return rc; + +} // get_port_intf_idx + + + +/*HDR*/ +/** + * @brief Retrieve the MAC address of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_mac_addr Pointer to the MAC address buffer to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, the MAC address is set to all 0 + */ +int get_port_mac_addr( const char *if_name, MBG_MAC_ADDR *p_mac_addr ) +{ + int rc = MBG_ERR_NOT_SUPP_ON_OS; + + #if defined( MBG_TGT_LINUX ) + struct ifreq ifr = { { { 0 } } }; + + rc = do_siocg_ioctl( if_name, SIOCGIFHWADDR, &ifr ); + + if ( mbg_rc_is_success( rc ) ) + { + memcpy( p_mac_addr, ifr.ifr_hwaddr.sa_data, sizeof( *p_mac_addr ) ); + return rc; + } + #endif + + // we get here on error only + memset( p_mac_addr, 0, sizeof( *p_mac_addr ) ); + + return rc; + +} // get_port_mac_addr + + + +/*HDR*/ +/** + * @brief Check the link state of a network interface + * + * @param[in] if_name Name of the interface + * + * @return 1 if link detected on port, + * 0 if no link detected on port, + * one of the @ref MBG_ERROR_CODES in case of an error + */ +int check_port_link( const char *if_name ) +{ + int rc = MBG_ERR_NOT_SUPP_ON_OS; + + #if defined( MBG_TGT_LINUX ) + struct ifreq ifr = { { { 0 } } }; + struct ethtool_value edata = { 0 }; + + edata.cmd = ETHTOOL_GLINK; // defined in ethtool.h + ifr.ifr_data = (caddr_t) &edata; + + rc = do_siocg_ioctl( if_name, SIOCETHTOOL, &ifr ); + + if ( mbg_rc_is_success( rc ) ) + rc = ( edata.data == 0 ) ? 0 : 1; + #endif + + return rc; + +} // check_port_link + + + +static /*HDR*/ +/** + * @brief Retrieve some IPv4 address-like info from a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_addr Pointer to address field to be filled up + * @param[in] sigioc_code The IOCTL code associated with the address + * + * @return One of the @ref MBG_RETURN_CODES + * On error, *p_addr is set to all 0. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + */ +int get_specific_port_ip4_addr( const char *if_name, IP4_ADDR *p_addr, int sigioc_code ) +{ + int rc = MBG_ERR_NOT_SUPP_ON_OS; + + #if defined( MBG_TGT_LINUX ) + struct ifreq ifr = { { { 0 } } }; + + rc = do_siocg_ioctl( if_name, sigioc_code, &ifr ); + + if ( mbg_rc_is_success( rc ) ) + { + *p_addr = ntohl( ( (struct sockaddr_in *) &ifr.ifr_addr )->sin_addr.s_addr ); + return rc; + } + #endif + + // we get here on error only + *p_addr = 0; // make empty address + + return rc; + +} // get_specific_port_ip4_addr + + + +/*HDR*/ +/** + * @brief Retrieve the IPv4 address of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_addr Pointer to address field to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, *p_addr is set to all 0. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ +int get_port_ip4_addr( const char *if_name, IP4_ADDR *p_addr ) +{ + return get_specific_port_ip4_addr( if_name, p_addr, SIOCGIFADDR ); + +} // get_port_ip4_addr + + + +/*HDR*/ +/** + * @brief Retrieve the IPv4 net mask of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_addr Pointer to address field to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, *p_addr is set to all 0. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ +int get_port_ip4_netmask( const char *if_name, IP4_ADDR *p_addr ) +{ + return get_specific_port_ip4_addr( if_name, p_addr, SIOCGIFNETMASK ); + +} // get_port_ip4_netmask + + + +/*HDR*/ +/** + * @brief Retrieve the IPv4 broadcast address of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_addr Pointer to address field to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, *p_addr is set to all 0. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ +int get_port_ip4_broad_addr( const char *if_name, IP4_ADDR *p_addr ) +{ + return get_specific_port_ip4_addr( if_name, p_addr, SIOCGIFBRDADDR ); + +} // get_port_ip4_broad_addr + + + +#if defined( MBG_TGT_LINUX ) + +static /*HDR*/ +/** + * @brief Read a requested message from the netlink socket + * + * @return Message length (>= 0) on success, or of the @ref MBG_ERROR_CODES + */ +int nl_read( int sock_fd, char *buf_ptr, size_t buf_size, int seq_num, int pid ) +{ + struct nlmsghdr *nl_hdr; + int read_len = 0; + int msg_len = 0; + + do + { + // receive response from the kernel, can be several chunks + if ( ( read_len = recv( sock_fd, buf_ptr, buf_size - msg_len, 0 ) ) == -1 ) + { + int rc = mbg_get_last_socket_error( NULL ); + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Failed to receive netlink packet: %s", + __func__, mbg_strerror( rc ) ); + #endif + return rc; + } + + nl_hdr = (struct nlmsghdr *) buf_ptr; + + // check if the header is valid + if ( ( NLMSG_OK( nl_hdr, read_len ) == 0 ) || ( nl_hdr->nlmsg_type == NLMSG_ERROR ) ) + { + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Invalid header in received netlink packet", + __func__ ); + #endif + return MBG_ERR_DATA_FMT; + } + + // check if the its the last message + if ( nl_hdr->nlmsg_type == NLMSG_DONE ) + { + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Reached last message in received packet", + __func__ ); + #endif + break; + } + + // move the pointer to buffer appropriately + buf_ptr += read_len; + msg_len += read_len; + + // check if its a multi part message + if ( ( nl_hdr->nlmsg_flags & NLM_F_MULTI ) == 0 ) + { + // return if it's not a multi part message + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Received packet is not a multi part message", + __func__ ); + #endif + break; + } + + } while ( ( nl_hdr->nlmsg_seq != seq_num ) || ( nl_hdr->nlmsg_pid != pid ) ); + + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Received packet has len %i", + __func__, msg_len ); + #endif + + return msg_len; + +} // nl_read + + + +#if DEBUG_NETLINK + +static /*HDR*/ +void nl_log_bytes( const char *fnc, const char *info, const void *p, int n_bytes ) +{ + char ws[80]; + size_t n = 0; + int i; + + for ( i = 0; i < n_bytes; i++ ) + n += snprintf_safe( &ws[n], sizeof( ws ) - n, " %i", BYTE_OF( * (uint8_t *) p, i ) ); + + mbglog( LOG_INFO, "%s: attibute %s, copying %i bytes:%s", + fnc, info, n_bytes, ws ); + +} // nl_log_bytes + +#endif + + + +static /*HDR*/ +int nl_parse_routes( struct nlmsghdr *nl_hdr, struct route_info *rt_info ) +{ + // parse the route info returned + struct rtmsg *rt_msg; + struct rtattr *rt_attr; + int rt_len; + + rt_msg = (struct rtmsg *) NLMSG_DATA( nl_hdr ); + + // If the route is not for AF_INET then return. + // This could be also IPv6 routes. + if ( rt_msg->rtm_family != AF_INET ) //##++ TODO: PF_INET6 for IPv6 + { + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Route is not AF_INET (%li), but %li", + __func__, (long) AF_INET, (long) rt_msg->rtm_family ); + #endif + return -1; + } + + // If the route does not belong to main routing table then return. + if ( rt_msg->rtm_table != RT_TABLE_MAIN ) + { + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Route does not belong to main table (%li), but %li", + __func__, (long) RT_TABLE_MAIN, (long) rt_msg->rtm_table ); + #endif + return -1; + } + + + // get the rtattr field + rt_attr = (struct rtattr *) RTM_RTA( rt_msg ); + rt_len = RTM_PAYLOAD( nl_hdr ); + + for ( ; RTA_OK( rt_attr, rt_len ); rt_attr = RTA_NEXT( rt_attr, rt_len ) ) + { + #if DEBUG_NETLINK + mbglog( LOG_ERR, "rt_attr at %p, %i bytes left", rt_attr, rt_len ); + #endif + + switch ( rt_attr->rta_type ) + { + case RTA_OIF: + if_indextoname( *(int *)RTA_DATA( rt_attr ), rt_info->ifName ); + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: attibute RTA_OIF, IF name: %s", + __func__, rt_info->ifName ); + #endif + break; + + case RTA_GATEWAY: + memcpy( &rt_info->gateWay, RTA_DATA( rt_attr ), sizeof( rt_info->gateWay ) ); + #if DEBUG_NETLINK + nl_log_bytes( __func__, "RTA_GATEWAY", &rt_info->gateWay, sizeof( rt_info->gateWay ) ); + #endif + break; + + case RTA_PREFSRC: + memcpy( &rt_info->srcAddr , RTA_DATA( rt_attr ), sizeof( rt_info->srcAddr ) ); + #if DEBUG_NETLINK + nl_log_bytes( __func__, "RTA_PREFSRC", &rt_info->srcAddr, sizeof( rt_info->srcAddr ) ); + #endif + break; + + case RTA_DST: + memcpy( &rt_info->dstAddr, RTA_DATA( rt_attr ), sizeof( rt_info->dstAddr ) ); + #if DEBUG_NETLINK + nl_log_bytes( __func__, "RTA_DST", &rt_info->dstAddr, sizeof( rt_info->dstAddr ) ); + #endif + break; + + #if DEBUG_NETLINK + case RTA_TABLE: + { + // The RTA_TABLE attribute was added to the kernel source in 2006 to support + // more than 255 routing tables. Originally the number of the routing table + // to which an entry belongs had been passed only in struct rtmsg::rtm_table, + // which is only 8 bits wide and should still hold the 8 LSBs of the full + // routing table number for compatibility, so this should still work for the + // standard routing tables, including the main table we are inspecting here. + // + // Whether this can be compiled in depends on the version of linux/rtnetlink.h + // used by the compiler. Unfortunately RTA_TABLE is part of an enum, so you + // can't simply use #ifdef RTA_TABLE to include this code conditionally. + uint32_t rta_table; + memcpy( &rta_table, RTA_DATA( rt_attr ), sizeof( rta_table ) ); + mbglog( LOG_ERR, "%s: attibute RTA_TABLE %i (%i)", + __func__, rta_table, rt_msg->rtm_table ); + } + break; + + default: + mbglog( LOG_ERR, "%s: Found unknown route type %li", + __func__, (long) rt_attr->rta_type ); + #endif + } + } + + return 0; + +} // nl_parse_routes + +#endif // defined( MBG_TGT_LINUX ) + + + +/*HDR*/ +/** + * @brief Retrieve the IPv4 gateway (default route) + * + * @param[out] p_addr Pointer to address field to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, *p_addr is set to all 0. + */ +int get_ip4_gateway( IP4_ADDR *p_addr ) +{ + int rc = MBG_ERR_NOT_SUPP_ON_OS; + +#if defined( MBG_TGT_LINUX ) + struct nlmsghdr *nlmsg; + struct route_info route_info; + char msg_buf[8192]; // pretty large buffer, why 8192 ? + int sock_fd; + int len; + int msg_seq = 0; + int idx; + + // create socket + if ( ( sock_fd = socket( PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE ) ) == -1 ) + { + rc = mbg_get_last_socket_error( NULL ); + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Failed to create netlink socket: %s", + __func__, mbg_strerror( rc ) ); + #endif + goto out; + } + + + // initialize buffer with request message + memset( msg_buf, 0, sizeof( msg_buf ) ); + + // point the header and the msg structure pointers into the buffer + nlmsg = (struct nlmsghdr *) msg_buf; + + // fill in the nlmsg header + nlmsg->nlmsg_len = NLMSG_LENGTH( sizeof( struct rtmsg ) ); // length of message + nlmsg->nlmsg_type = RTM_GETROUTE; // get the routes from kernel routing table + + nlmsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // the message is a request for dump + nlmsg->nlmsg_seq = msg_seq++; // sequence of the message packet + nlmsg->nlmsg_pid = getpid(); // PID of process sending the request + + // send the request + if ( send( sock_fd, nlmsg, nlmsg->nlmsg_len, 0 ) == -1 ) + { + rc = mbg_get_last_socket_error( NULL ); + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Failed to write to netlink socket: %s", + __func__, mbg_strerror( rc ) ); + #endif + goto out; + } + + // read the response + if ( ( len = nl_read( sock_fd, msg_buf, sizeof( msg_buf ), msg_seq, getpid() ) ) < 0 ) + { + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Failed to read from netlink socket", + __func__ ); + #endif + rc = len; + goto out; + } + + #if DEBUG_NETLINK + mbglog( LOG_ERR, "%s: Read %i bytes from netlink socket", __func__, len ); + #endif + + // parse and print the response + for ( idx = 0; NLMSG_OK( nlmsg, len ); nlmsg = NLMSG_NEXT( nlmsg, len ), idx++ ) + { + memset( &route_info, 0, sizeof( route_info ) ); + + #if DEBUG_NETLINK + mbglog( LOG_ERR, "\nnl_msg at %p, %i bytes left", nlmsg, len ); + #endif + + + if ( nl_parse_routes( nlmsg, &route_info ) < 0 ) + continue; // don't check route_info if it has not been set up + + #if DEBUG_NETLINK + { + char ws[100]; + int l = sizeof( ws ); + int n = 0; + + // inet_ntoa() uses a static buffer which is overwritten on every call + //##++ TODO: rather than inet_ntoa use inet_ntop which can also handle IPv6 + n += snprintf_safe( &ws[n], l - n, "src %s", (char *) inet_ntoa( route_info.srcAddr ) ); + n += snprintf_safe( &ws[n], l - n, ", dst %s", (char *) inet_ntoa( route_info.dstAddr ) ); + n += snprintf_safe( &ws[n], l - n, ", gw %s", (char *) inet_ntoa( route_info.gateWay ) ); + + mbglog( LOG_ERR, "%s: route %i: %s, if \"%s\"", + __func__, idx, ws, route_info.ifName ); + } + #endif + + // check if default IPv4 gateway + //##++ TODO: rather than inet_ntoa use inet_ntop which can also handle IPv6 + if ( strstr( (char *) inet_ntoa( route_info.dstAddr ), "0.0.0.0" ) ) + { + *p_addr = ntohl( route_info.gateWay.s_addr ); + rc = MBG_SUCCESS; + // Actually we could stop searching now. However, in case of debug + // we'll continue to examine the rest of the routing message. + #if DEBUG_NETLINK + //##++ TODO: rather than inet_ntoa use inet_ntop which can also handle IPv6 + mbglog( LOG_ERR, "%s: Default gateway found: %s", + __func__, (char *) inet_ntoa( route_info.gateWay ) ); + #else + break; + #endif + } + } + +out: + if ( sock_fd >= 0 ) + close( sock_fd ); + +#endif // defined( MBG_TGT_LINUX ) + + if ( mbg_rc_is_error( rc ) ) + *p_addr = 0; + + return rc; + +} // get_ip4_gateway + + + +/*HDR*/ +/** + * @brief Retrieve the IPv4 address of a network interface as string + * + * @param[in] if_name Name of the interface + * @param[out] p_addr_buf Pointer to the string buffer to be filled up + * @param[in] buf_size size of the string buffer + * + * @return One of the @ref MBG_RETURN_CODES + * On error, a string according to "0.0.0.0" is generated. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ +int get_port_ip4_addr_str( const char *if_name, char *p_addr_buf, int buf_size ) +{ + IP4_ADDR addr; + + int rc = get_port_ip4_addr( if_name, &addr ); + + snprint_ip4_addr( p_addr_buf, buf_size, &addr, NULL ); + + return rc; + +} // get_port_ip4_addr_str + + + +/*HDR*/ +/** + * @brief Retrieve the IPv4 net mask of a network interface as string + * + * @param[in] if_name Name of the interface + * @param[out] p_addr_buf Pointer to the string buffer to be filled up + * @param[in] buf_size size of the string buffer + * + * @return One of the @ref MBG_RETURN_CODES + * On error, a string according to "0.0.0.0" is generated. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ +int get_port_ip4_netmask_str( const char *if_name, char *p_addr_buf, int buf_size ) +{ + IP4_ADDR addr; + + int rc = get_port_ip4_netmask( if_name, &addr ); + + snprint_ip4_addr( p_addr_buf, buf_size, &addr, NULL ); + + return rc; + +} // get_port_ip4_netmask_str + + + +/*HDR*/ +/** + * @brief Retrieve the IPv4 broadcast address of a network interface as string + * + * @param[in] if_name Name of the interface + * @param[out] p_addr_buf Pointer to the string buffer to be filled up + * @param[in] buf_size size of the string buffer + * + * @return One of the @ref MBG_RETURN_CODES + * On error, a string according to "0.0.0.0" is generated. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_specific_port_ip4_addr + */ +int get_port_ip4_broad_addr_str( const char *if_name, char *p_addr_buf, int buf_size ) +{ + IP4_ADDR addr; + + int rc = get_port_ip4_broad_addr( if_name, &addr ); + + snprint_ip4_addr( p_addr_buf, buf_size, &addr, NULL ); + + return rc; + +} // get_port_ip4_broad_addr_str + + + +/*HDR*/ +/** + * @brief Retrieve the current IPv4 settings of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p Pointer to a IP4_SETTINGS structure to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ +int get_port_ip4_settings( const char *if_name, IP4_SETTINGS *p ) +{ + int link_up; + int rc; + + memset( p, 0, sizeof( *p ) ); + + rc = get_port_ip4_addr( if_name, &p->ip_addr ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + + rc = get_port_ip4_netmask( if_name, &p->netmask ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + + rc = get_port_ip4_broad_addr( if_name, &p->broad_addr ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + +#ifndef USE_MBG_TSU + rc = get_ip4_gateway( &p->gateway ); + + if ( mbg_rc_is_error( rc ) ) + goto out; +#endif + + link_up = check_port_link( if_name ); + + if ( mbg_rc_is_success( rc ) ) + if ( link_up ) + p->flags |= IP4_MSK_LINK; + +#if 0 //### TODO + // We could also try to check VLAN and DHCP settings here, + // but as of now, this is specific to an application. + + // ##++++ The VLAN and DHCP status info collected below + // just return what has been configured previously by this program, + // however, it does not reflect any changes which have been made + // manually, e.g. via the command line. + if ( vlan_enabled ) + { + p->flags |= IP4_MSK_VLAN; + p->vlan_cfg = vlan_cfg; + } + + if ( dhcp_enabled ) + p->flags |= IP4_MSK_DHCP; +#endif + +out: + return rc; + +} // get_port_ip4_settings + + diff --git a/mbglib/common/lan_util.h b/mbglib/common/lan_util.h new file mode 100644 index 0000000..31f37e8 --- /dev/null +++ b/mbglib/common/lan_util.h @@ -0,0 +1,775 @@ + +/************************************************************************** + * + * $Id: lan_util.h 1.6.1.7 2016/10/31 17:39:47Z martin TEST martin $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Definitions and prototypes for lan_util.c. + * + * ----------------------------------------------------------------------- + * $Log: lan_util.h $ + * Revision 1.6.1.7 2016/10/31 17:39:47Z martin + * Only return standard MBG_RETURN_CODES. + * Removed definitions of old MBG_LU_... return codes. + * Renamed check_octets_not_all_zero() to octets_are_all_zero(), which returns a bool now. + * Renamed check_mac_addr_not_all_zero() to mac_addr_all_zero(), which returns a bool now. + * Removed get_port_mac_addr_check(). + * Updated doxygen comments. + * Revision 1.6.1.6 2015/12/01 11:35:32 martin + * Doxygen fixes. + * Revision 1.6.1.5 2015/11/11 17:58:13 martin + * Revision 1.6.1.4 2015/11/04 17:06:36Z martin + * *** empty log message *** + * Revision 1.6.1.3 2015/08/27 16:23:23 martin + * Revision 1.6.1.2 2015/04/13 15:25:06 hannes + * Added defines for IP6 CIDR mask bits. + * Revision 1.6.1.1 2015/04/02 15:28:03 hannes + * Added most of the ipv4 functions for ipv6. + * Revision 1.6 2014/09/24 08:32:58 martin + * Fixed a POSIX header file dependency. + * Revision 1.5 2013/10/02 07:20:36 martin + * Updated function prototypes. + * Revision 1.4 2013/02/19 15:15:53 martin + * Added some inline functions. + * Redefined return codes as named enum. + * Updated function prototypes. + * Revision 1.3 2012/10/02 18:24:29 martin + * Added some macros to simpliy conversion to string. + * Revision 1.2 2012/03/09 08:51:44 martin + * Updated function prototypes. + * Revision 1.1 2011/03/04 10:01:32 martin + * Initial revision. + * + **************************************************************************/ + +#ifndef _LAN_UTIL_H +#define _LAN_UTIL_H + + +/* Other headers to be included */ + +#include <mbg_tgt.h> +#include <gpsdefs.h> // for some Meinberg data structures + +#include <stdlib.h> + +#if defined( MBG_TGT_POSIX ) + #include <sys/types.h> + #include <sys/socket.h> + #include <net/if.h> + #include <ifaddrs.h> // *must* be included *after* net/if.h +#else + // A dummy declaration to prevent from warnings due to usage + // of this type with function prototypes. + struct ifreq + { + int dummy; + }; +#endif + + +#if defined( IFHWADDRLEN ) // usually defined in net/if.h + #if ( IFHWADDRLEN != 6 ) + #error Warning: IFHWADDRLEN is not 6! + #endif +#endif + + + +#ifdef _LAN_UTIL + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +#if defined( _USE_PACK ) + #pragma pack( 1 ) // set byte alignment + #define _USING_BYTE_ALIGNMENT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#if !defined( MAC_SEP_CHAR ) + #define MAC_SEP_CHAR ':' // character used to separate octets of a MAC ID +#endif + +#if !defined( MAC_SEP_CHAR_ALT ) + #define MAC_SEP_CHAR_ALT '-' // alternate character +#endif + + +#define MAX_IP4_BITS ( 8 * (int) sizeof( IP4_ADDR ) ) + +#define IP4_MSB_MASK ( 1UL << ( MAX_IP4_BITS - 1 ) ) + +#define MIN_IP4_CIDR_NETMASK_BITS 0 +#define MAX_IP4_CIDR_NETMASK_BITS MAX_IP4_BITS + + +#define IP6_MSB_MASK ( 1UL << ( 8 - 1 ) ) + +#define MIN_IP6_CIDR_NETMASK_BITS 0 +#define MAX_IP6_CIDR_NETMASK_BITS IP6_ADDR_BITS + + + +/** + * @brief Compute an IP4 net mask according to the number of CIDR netmask bits + * + * E.g. the 24 bits mentioned in "172.16.3.250/24" result in 0xFFFFFF00, + * corresponding to 255.255.255.0 in dotted quad notation. + * + * @param netmask_bits Number of netmask bits from CIDR notation + * + * @return The IPv4 net mask + * + * @see get_ip4_net_mask_bits() + */ +static __mbg_inline +IP4_ADDR ip4_net_mask_from_cidr( int netmask_bits ) +{ + return (IP4_ADDR) ~( ( 1UL << ( MAX_IP4_BITS - netmask_bits ) ) - 1 ); + +} // ip4_net_mask_from_cidr + + + +/** + * @brief Determine the broadcast address for an IP4 address plus net mask + * + * E.g. IP 0xAC1003FA, net mask 0xFFFFFF00 yields broadcast addr 0xAC1003FF. + * In dotted quad notation, IP 172.16.3.250 with net mask 255.255.255.0 + * result in broadcast address 172.16.3.255. + * + * @param p_addr The full IP4 address + * @param p_mask The IP4 net mask + * + * @return The determined IP4 broadcast address + */ +static __mbg_inline +IP4_ADDR ip4_broad_addr_from_addr( const IP4_ADDR *p_addr, const IP4_ADDR *p_mask ) +{ + return *p_addr | ~(*p_mask); + +} // ip4_broad_addr_from_addr + + + +/** + * @brief Determine the network part of an IP4 address based on the net mask + * + * E.g. IP 0xAC1003FA, net mask 0xFFFFFF00 yields network part 0xAC100300. + * In dotted quad notation, IP 172.16.3.250 with net mask 255.255.255.0 + * results in network part 172.16.3.0. + * + * @param p_addr The full IP4 address + * @param p_mask The IP4 net mask + * + * @return The network part of the IP4 address + */ +static __mbg_inline +IP4_ADDR ip4_net_part_from_addr( const IP4_ADDR *p_addr, const IP4_ADDR *p_mask ) +{ + return *p_addr & *p_mask; + +} // ip4_net_part_from_addr + + + +/** + * @brief Check if two IP4 addresses have the same network part. + * + * @param p_addr1 The first IP4 address to check + * @param p_addr2 The second IP4 address to check + * @param p_mask The IP4 net mask + * + * @return true, if the network parts are matching + */ +static __mbg_inline +int ip4_net_part_matches( const IP4_ADDR *p_addr1, const IP4_ADDR *p_addr2, + const IP4_ADDR *p_mask ) +{ + return ip4_net_part_from_addr( p_addr1, p_mask ) + == ip4_net_part_from_addr( p_addr2, p_mask ); + +} // ip4_net_part_matches + + + +#define _ip4_addr_to_str( _s, _a ) \ + snprint_ip4_addr( _s, sizeof( _s ), _a, NULL ) + +#define _mac_addr_to_str( _s, _a ) \ + snprint_mac_addr( _s, sizeof( _s ), _a ) + + + +/* function prototypes: */ + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + + /** + * @brief Count the number of sequential bits in an IPv4 net mask + * + * Counting starts from MSB, i.e. for 0xC0 and 0xC1 the results + * are both 2 since only the 2 MSBs are sequentially set. + * + * @param[in] p_mask The IPv4 net mask to be evaluated + * + * @return The number of sequential MSB bits set in *p_mask + * + * @see ::ip4_net_mask_from_cidr + */ + int get_ip4_net_mask_bits( const IP4_ADDR *p_mask ) ; + + /** + * @brief Print an IPv4 address to a dotted quad formatted string + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv4 address to be evaluated + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip4_cidr_addr + * @see ::str_to_ip4_addr + * @see ::cidr_str_to_ip4_addr_and_net_mask + */ + size_t snprint_ip4_addr( char *s, size_t max_len, const IP4_ADDR *p_addr, const char *info ) ; + + /** + * @brief Print an IPv4 address plus net mask in CIDR notation to a string + * + * The printed CIDR string is something like "172.16.3.250/24" + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv4 address to be evaluated + * @param[in] p_mask The associated IPv4 net mask + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip4_addr + * @see ::str_to_ip4_addr + * @see ::cidr_str_to_ip4_addr_and_net_mask + */ + size_t snprint_ip4_cidr_addr( char *s, size_t max_len, const IP4_ADDR *p_addr, const IP4_ADDR *p_mask, const char *info ) ; + + /** + * @brief Convert a string to an ::IP4_ADDR + * + * If output parameter is specified as NULL then this function + * can be used to check if the IPv4 address string is formally correct. + * + * @param[out] p_addr Pointer to an ::IP4_ADDR variable to be filled, or NULL + * @param[in] s An IPv4 address string to be converted + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip4_addr + * @see ::snprint_ip4_cidr_addr + * @see ::cidr_str_to_ip4_addr_and_net_mask + */ + int str_to_ip4_addr( IP4_ADDR *p_addr, const char *s ) ; + + /** + * @brief Convert a string in CIDR notation to an ::IP4_ADDR and net mask + * + * If output parameters are specified as NULL then this function + * can be used to check if the CIDR string is formally correct. + * + * @param[out] p_addr Pointer to an ::IP4_ADDR variable to be filled with + * the IPv4 address, or NULL + * @param[out] p_mask Pointer to an ::IP4_ADDR variable to be filled with + * the IPv4 net mask, or NULL + * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "172.16.3.250/24" + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip4_addr + * @see ::snprint_ip4_cidr_addr + * @see ::str_to_ip4_addr + */ + int cidr_str_to_ip4_addr_and_net_mask( IP4_ADDR *p_addr, IP4_ADDR *p_mask, const char *cidr_str ) ; + + /** + * @brief Count the number of sequential bits in an IPv6 net mask + * + * Counting starts from MSB, i.e. for 0xC0 and 0xC1 the results + * are both 2 since only the 2 MSBs are sequentially set. + * + * @param[in] p_mask The IPv6 net mask to be evaluated + * + * @return The number of sequential MSB bits set in *p_mask + * + * @see ::ip6_net_mask_from_cidr + */ + int get_ip6_net_mask_bits( const IP6_ADDR *p_mask ) ; + + /** + * @brief Print an IPv6 address in optimized format to a string + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv6 address to be evaluated + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip6_cidr_addr + * @see ::snprint_ip6_cidr_mask_addr + * @see ::str_to_ip6_addr + * @see ::cidr_str_to_ip6_addr_and_cidr_bits + * @see ::cidr_str_to_ip6_addr_and_net_mask + */ + size_t snprint_ip6_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, const char *info ) ; + + /** + * @brief Print an IPv6 address plus net mask to string in CIDR notation + * + * The printed CIDR string is something like "2001:0DB8:0:CD30:EF45::/64" + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv6 address to be evaluated + * @param[in] p_mask The associated IPv6 net mask + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip6_addr + * @see ::snprint_ip6_cidr_mask_addr + * @see ::str_to_ip6_addr + * @see ::cidr_str_to_ip6_addr_and_cidr_bits + * @see ::cidr_str_to_ip6_addr_and_net_mask + */ + size_t snprint_ip6_cidr_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, const IP6_ADDR *p_mask, const char *info ) ; + + /** + * @brief Print an IPv6 address plus number of net mask bits to string in CIDR notation + * + * The printed CIDR string is something like "2001:0DB8:0:CD30:EF45::/64" + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] p_addr The IPv6 address to be evaluated + * @param[in] cidr_mask_bits The CIDR number of bits specifying the IPv6 net mask + * @param[in] info An optional string which is prepended to the string, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_ip6_addr + * @see ::snprint_ip6_cidr_addr + * @see ::str_to_ip6_addr + * @see ::cidr_str_to_ip6_addr_and_cidr_bits + * @see ::cidr_str_to_ip6_addr_and_net_mask + */ + size_t snprint_ip6_cidr_mask_addr( char *s, size_t max_len, const IP6_ADDR *p_addr, const int cidr_mask_bits, const char* info ) ; + + /** + * @brief Convert a string to an ::IP6_ADDR + * + * If the output parameter is specified as NULL then this function + * can be used to check if the string is formally correct. + * + * On success ::IP6_ADDR variable contains the IPv6 address + * in little endian byte order. + * + * @param[out] p_addr Pointer to the ::IP6_ADDR variable, or NULL + * @param[in] s A string containing an IPv6 address + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip6_addr + * @see ::snprint_ip6_cidr_addr + * @see ::snprint_ip6_cidr_mask_addr + * @see ::str_to_ip6_addr + * @see ::cidr_str_to_ip6_addr_and_cidr_bits + * @see ::cidr_str_to_ip6_addr_and_net_mask + */ + int str_to_ip6_addr( IP6_ADDR *p_addr, const char *s ) ; + + /** + * @brief Convert a string in CIDR notation to an ::IP6_ADDR and net mask + * + * If output parameters are specified as NULL then this function + * can be used to check if the CIDR string is formally correct. + * + * @param[out] p_addr Pointer to an ::IP6_ADDR variable to be filled up + * with the IPv6 address, or NULL + * @param[out] p_mask Pointer to an ::IP6_ADDR variable to be filled up + with the net mask bits, or NULL + * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "2001:0DB8:0:CD30::/64" + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip4_addr + * @see ::snprint_ip4_cidr_addr + * @see ::str_to_ip4_addr + */ + int cidr_str_to_ip6_addr_and_net_mask( IP6_ADDR *p_addr, IP6_ADDR *p_mask, const char *cidr_str ) ; + + /** + * @brief Convert a string in CIDR notation to an ::IP6_ADDR and net mask bits + * + * If output parameters are specified as NULL then this function + * can be used to check if the CIDR string is formally correct. + * + * @param[out] p_addr Pointer to an ::IP6_ADDR variable for the IPv6 address, or NULL + * @param[out] p_cidr Pointer to an int variable for the net mask bits, or NULL + * @param[in] cidr_str The string to be converted, in CIDR format, e.g. "2001:0DB8:0:CD30::/64" + * + * @return A number >= 0 (::MBG_SUCCESS) according to the number of characters evaluated + * from the input string, or one of the @ref MBG_ERROR_CODES on error, + * specifically ::MBG_ERR_INV_PARM if an invalid number or character was found in the string. + * + * @see ::snprint_ip6_addr + * @see ::snprint_ip6_cidr_addr + * @see ::str_to_ip6_addr + */ + int cidr_str_to_ip6_addr_and_cidr_bits( IP6_ADDR *p_addr, int *p_cidr, const char *cidr_str ) ; + + /** + * @brief Compute an IPv6 net mask according to the number of CIDR netmask bits + * + * E.g. the 64 bits mentioned in "2001:0DB8:0:CD30::/64" result in 2^64, + * corresponding to FFFF:FFFF:FFFF:FFFF:: in IPv6 notation. + * + * @param[out] p_mask Pointer to an ::IP6_ADDR variable for the IPv6 netmask + * @param[in] netmask_bits Number of netmask bits from CIDR notation + * + * @see ::get_ip6_net_mask_bits + */ + void ip6_net_mask_from_cidr( IP6_ADDR *p_mask, int netmask_bits ) ; + + /** + * @brief Determine the network part of an IPv6 address based on the net mask + * + * E.g. IP "2001:0DB8:0:CD30::", net mask "FFFF:FFFF::" yields network part "2001:0DB8::". + * + * @param[out] p_net_part The extracted network part of the IPv6 address + * @param[in] p_addr The IPv6 address to be evaluated + * @param[in] p_mask The associated IPv6 net mask + */ + void ip6_net_part_from_addr( IP6_ADDR *p_net_part, const IP6_ADDR *p_addr, const IP6_ADDR *p_mask ) ; + + /** + * @brief Print a MAC ID or similar array of octets to a string + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Maximum length of the string, i.e. size of the buffer + * @param[in] octets An array of octets + * @param[in] num_octets The number of octets to be printed from the array + * @param[in] sep The separator printed between the bytes, or 0 + * @param[in] info An optional string which is prepended to the output, or NULL + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_mac_addr + * @see ::str_to_octets + * @see ::octets_are_all_zero + */ + size_t snprint_octets( char *s, size_t max_len, const uint8_t *octets, int num_octets, char sep, const char *info ) ; + + /** + * @brief Print a ::PTP_CLOCK_ID to a string + * + * @todo Eventually this function should be moved to a different module. + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Maximum length of the string, i.e. size of the buffer + * @param[in] p The ::PTP_CLOCK_ID to be printed + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_octets + */ + size_t snprint_ptp_clock_id( char *s, size_t max_len, const PTP_CLOCK_ID *p ) ; + + /** + * @brief Print a MAC address to a string + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Maximum length of the string, i.e. size of the buffer + * @param[in] p_mac_addr The MAC address to be printed + * + * @return The overall number of characters printed to the string + * + * @see ::snprint_octets + * @see ::str_to_octets + * @see ::octets_are_all_zero + */ + size_t snprint_mac_addr( char *s, size_t max_len, const MBG_MAC_ADDR *p_mac_addr ) ; + + /** + * @brief Set a MAC ID or a similar array of octets from a string + * + * @param[out] octets An array of octets to be set up + * @param[in] num_octets The number of octets which can be stored + * @param[in] s The string to be converted + * + * @return The overall number of octets decoded from the string + * + * @see ::snprint_octets + * @see ::snprint_mac_addr + * @see ::octets_are_all_zero + */ + int str_to_octets( uint8_t *octets, int num_octets, const char *s ) ; + + /** + * @brief Check if an array of octets is all zero + * + * @param[in] octets Pointer to the array of octets + * @param[in] num_octets Number of octets + * + * @return true if all bytes are 0, else false + * + * @see ::snprint_octets + * @see ::snprint_mac_addr + * @see ::str_to_octets + */ + bool octets_are_all_zero( const uint8_t *octets, int num_octets ) ; + + /** + * @brief Check if a MAC address is all zero + * + * @param[in] p_addr Pointer to a MAC address to be checked + * + * @return true if all bytes of the MAC address are 0, else false + * + * @see ::octets_are_all_zero + */ + bool mac_addr_is_all_zero( const MBG_MAC_ADDR *p_addr ) ; + + /** + * @brief Do a SIOCGxxx IOCTL call to read specific information from a LAN interface + * + * @param[in] if_name Name of the interface + * @param[in] ioctl_code One of the predefined system SIOCGxxx IOCTL codes + * @param[out] p_ifreq Pointer to a request buffer + * + * @return One of the @ref MBG_RETURN_CODES + */ + int do_siocg_ioctl( const char *if_name, int ioctl_code, struct ifreq *p_ifreq ) ; + + /** + * @brief Retrieve the index of a specific network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_intf_idx Pointer to a variable to be filled up + * + * @return One of the @ref MBG_RETURN_CODES. + * On error, *p_intf_idx is set to -1. + */ + int get_port_intf_idx( const char *if_name, int *p_intf_idx ) ; + + /** + * @brief Retrieve the MAC address of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_mac_addr Pointer to the MAC address buffer to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, the MAC address is set to all 0 + */ + int get_port_mac_addr( const char *if_name, MBG_MAC_ADDR *p_mac_addr ) ; + + /** + * @brief Check the link state of a network interface + * + * @param[in] if_name Name of the interface + * + * @return 1 if link detected on port, + * 0 if no link detected on port, + * one of the @ref MBG_ERROR_CODES in case of an error + */ + int check_port_link( const char *if_name ) ; + + /** + * @brief Retrieve the IPv4 address of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_addr Pointer to address field to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, *p_addr is set to all 0. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ + int get_port_ip4_addr( const char *if_name, IP4_ADDR *p_addr ) ; + + /** + * @brief Retrieve the IPv4 net mask of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_addr Pointer to address field to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, *p_addr is set to all 0. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ + int get_port_ip4_netmask( const char *if_name, IP4_ADDR *p_addr ) ; + + /** + * @brief Retrieve the IPv4 broadcast address of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p_addr Pointer to address field to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, *p_addr is set to all 0. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ + int get_port_ip4_broad_addr( const char *if_name, IP4_ADDR *p_addr ) ; + + /** + * @brief Retrieve the IPv4 gateway (default route) + * + * @param[out] p_addr Pointer to address field to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * On error, *p_addr is set to all 0. + */ + int get_ip4_gateway( IP4_ADDR *p_addr ) ; + + /** + * @brief Retrieve the IPv4 address of a network interface as string + * + * @param[in] if_name Name of the interface + * @param[out] p_addr_buf Pointer to the string buffer to be filled up + * @param[in] buf_size size of the string buffer + * + * @return One of the @ref MBG_RETURN_CODES + * On error, a string according to "0.0.0.0" is generated. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ + int get_port_ip4_addr_str( const char *if_name, char *p_addr_buf, int buf_size ) ; + + /** + * @brief Retrieve the IPv4 net mask of a network interface as string + * + * @param[in] if_name Name of the interface + * @param[out] p_addr_buf Pointer to the string buffer to be filled up + * @param[in] buf_size size of the string buffer + * + * @return One of the @ref MBG_RETURN_CODES + * On error, a string according to "0.0.0.0" is generated. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ + int get_port_ip4_netmask_str( const char *if_name, char *p_addr_buf, int buf_size ) ; + + /** + * @brief Retrieve the IPv4 broadcast address of a network interface as string + * + * @param[in] if_name Name of the interface + * @param[out] p_addr_buf Pointer to the string buffer to be filled up + * @param[in] buf_size size of the string buffer + * + * @return One of the @ref MBG_RETURN_CODES + * On error, a string according to "0.0.0.0" is generated. + * + * @see ::get_port_ip4_settings + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_specific_port_ip4_addr + */ + int get_port_ip4_broad_addr_str( const char *if_name, char *p_addr_buf, int buf_size ) ; + + /** + * @brief Retrieve the current IPv4 settings of a network interface + * + * @param[in] if_name Name of the interface + * @param[out] p Pointer to a IP4_SETTINGS structure to be filled up + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::get_port_ip4_addr + * @see ::get_port_ip4_addr_str + * @see ::get_port_ip4_netmask + * @see ::get_port_ip4_netmask_str + * @see ::get_port_ip4_broad_addr + * @see ::get_port_ip4_broad_addr_str + * @see ::get_specific_port_ip4_addr + */ + int get_port_ip4_settings( const char *if_name, IP4_SETTINGS *p ) ; + + +/* ----- function prototypes end ----- */ + +#ifdef __cplusplus +} +#endif + + +#if defined( _USING_BYTE_ALIGNMENT ) + #pragma pack() // set default alignment + #undef _USING_BYTE_ALIGNMENT +#endif + +/* End of header body */ + + +#undef _ext +#undef _DO_INIT + +#endif /* _LAN_UTIL_H */ + diff --git a/mbglib/common/mbg_arch.h b/mbglib/common/mbg_arch.h index 37357be..f803e1d 100644 --- a/mbglib/common/mbg_arch.h +++ b/mbglib/common/mbg_arch.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbg_arch.h 1.5.1.1 2014/10/29 14:21:17Z martin TEST $ + * $Id: mbg_arch.h 1.6 2017/01/27 09:03:16Z martin REL_M $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -14,7 +14,10 @@ * * ----------------------------------------------------------------------- * $Log: mbg_arch.h $ - * Revision 1.5.1.1 2014/10/29 14:21:17Z martin + * Revision 1.6 2017/01/27 09:03:16Z martin + * Added macros _mbg_swab8() and _mbg_swab64(). + * Fixed macro syntax. + * Modified _swab_dummy() to avoid compiler warnings due to unused variables. * Revision 1.5 2014/03/11 16:01:55 martin * Added a comment. * Revision 1.4 2012/10/02 18:32:00 martin @@ -71,7 +74,7 @@ // to access unaligned data. #if !defined( _mbg_put_unaligned ) - #define _mbg_put_unaligned( _v, _p ) ((void)( *(_p) = (_v) )) + #define _mbg_put_unaligned( _v, _p ) do { ((void)( *(_p) = (_v) )); } while ( 0 ) #endif #if !defined( _mbg_get_unaligned ) @@ -124,8 +127,9 @@ -// swap a double type variable bytewise e.g. to convert the endianess - +/** + * @brief Swap a 'double' type variable bytewise e.g. to convert the endianess + */ static __mbg_inline void mbg_swab_double( double *p ) { @@ -148,22 +152,27 @@ void mbg_swab_double( double *p ) #if defined( MBG_ARCH_BIG_ENDIAN ) - #define _mbg_swab16( _p ) *(_p) = __swab16( *(_p) ) - #define _mbg_swab32( _p ) *(_p) = __swab32( *(_p) ) + #define _mbg_swab8( _p ) _nop_macro_fnc() // always a dummy, but for completeness ... + #define _mbg_swab16( _p ) do { *(_p) = __swab16( *(_p) ); } while ( 0 ) + #define _mbg_swab32( _p ) do { *(_p) = __swab32( *(_p) ); } while ( 0 ) + #define _mbg_swab64( _p ) do { *(_p) = __swab64( *(_p) ); } while ( 0 ) #define _mbg_swab_double( _p ) mbg_swab_double( _p ) #define _mbg_swab_doubles( _p, _n ) \ + do \ { \ int i; \ for ( i = 0; i < (_n); i++ ) \ _mbg_swab_double( &_p[i] ); \ - } + } while ( 0 ) #else + #define _mbg_swab8( _p ) _nop_macro_fnc() #define _mbg_swab16( _p ) _nop_macro_fnc() #define _mbg_swab32( _p ) _nop_macro_fnc() + #define _mbg_swab64( _p ) _nop_macro_fnc() #define _mbg_swab_double( _p ) _nop_macro_fnc() @@ -173,9 +182,14 @@ void mbg_swab_double( double *p ) -//##++++++++++++ -/// @brief A placeholder for yet missing _mbg_swab_..() macros -#define _mbg_swab_dummy( _x ) _nop_macro_fnc() + +/** + * @brief A placeholder for yet missing _mbg_swab_..() macros + * + * We don't just use the _nop_macro_fnc() macros here to avoid + * compiler warnings 'unused variable'. + */ +#define _mbg_swab_dummy( _x ) do { (void) _x; } while ( 0 ) #endif /* _MBG_ARCH_H */ diff --git a/mbglib/common/mbg_cof.h b/mbglib/common/mbg_cof.h new file mode 100644 index 0000000..24b253b --- /dev/null +++ b/mbglib/common/mbg_cof.h @@ -0,0 +1,88 @@ + +/************************************************************************** + * + * $Id: mbg_cof.h 1.1.1.3 2016/08/10 14:19:00Z martin TEST $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Container macros (see Linux Kernel) + * + * ----------------------------------------------------------------------- + * $Log: mbg_cof.h $ + * Revision 1.1.1.3 2016/08/10 14:19:00Z martin + * *** empty log message *** + * Revision 1.1.1.2 2016/08/10 14:15:14 martin + * *** empty log message *** + * Revision 1.1.1.1 2016/08/09 15:59:01 martin + * Preliminary compatibility changes. + * Revision 1.1 2015/09/09 10:42:27 martin + * Initial revision by philipp. + * + **************************************************************************/ + +#ifndef _MBG_COF_H +#define _MBG_COF_H + +/* Other headers to be included */ + +#include <mbg_tgt.h> + +#if !defined( MBG_TGT_KERNEL ) + #include <stddef.h> // for offsetof() +#endif + + +#ifdef _MBG_COF + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined( MBG_TGT_POSIX ) + + // A special construct supported by gcc/clang and and implemented + // e.g. in the Linux kernel, which is said to be very type-safe: + #define mbg_container_of( _ptr, _type, _member ) ({ \ + const typeof( ((_type *)0)->_member ) *__mptr = (_ptr); \ + (_type *)((char *)__mptr - offsetof(_type,_member));}) + +#else + + // A different implementation in ANSI C, which supports type-checking anyway: + #define mbg_container_of( _ptr, _type, _member ) \ + ( (_type *)( (char *)(1 ? (_ptr) : &((_type *)0)->_member) - offsetof( _type, _member ))) + +#endif + + +/* function prototypes: */ + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + +/* (no header definitions found) */ + +/* ----- function prototypes end ----- */ + +#ifdef __cplusplus +} +#endif + +/* End of header body */ + +#undef _ext +#undef _DO_INIT + +#endif /* _MBG_COF_H */ diff --git a/mbglib/common/mbg_tgt.h b/mbglib/common/mbg_tgt.h index 8cff80e..79be489 100644 --- a/mbglib/common/mbg_tgt.h +++ b/mbglib/common/mbg_tgt.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbg_tgt.h 1.34 2015/03/03 13:32:49Z martin REL_M $ + * $Id: mbg_tgt.h 1.35.1.11 2017/04/12 07:50:31Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -11,7 +11,91 @@ * * ----------------------------------------------------------------------- * $Log: mbg_tgt.h $ - * Revision 1.34 2015/03/03 13:32:49Z martin + * Revision 1.35.1.11 2017/04/12 07:50:31Z martin + * Fixed missing struct timespec for DOS. + * Revision 1.35.1.10 2017/04/10 13:37:16Z martin + * Fixed some compiler warnings. + * Revision 1.35.1.9 2017/02/09 12:38:51Z martin + * Fixed missing brace. + * Revision 1.35.1.8 2017/02/09 12:31:17 martin + * Updated bool handling with Linux kernel. + * Revision 1.35.1.7 2017/02/09 10:41:24 martin + * Fixed missing 'bool' type for old Linux kernels. + * Revision 1.35.1.6 2016/09/27 15:33:30 martin + * Added definition for _NO_MBG_API. + * Revision 1.35.1.5 2016/09/26 16:17:36 martin + * Fixed definitions for Windows kernel mode build. + * Revision 1.35.1.4 2016/08/31 08:17:51Z thomas-b + * Do not typedef ssize_t if HAVE_SSIZE_T is defined already + * Revision 1.35.1.3 2016/08/11 08:27:17 martin + * Fixed build for Windows kernel space. + * Revision 1.35.1.2 2016/08/10 12:26:49Z martin + * *** empty log message *** + * Revision 1.35.1.1 2016/08/09 15:59:25 martin + * *** empty log message *** + * Revision 1.35 2016/08/05 12:21:34 martin + * Conditionally define a macro _DEPRECATED_BY which can be used to + * tag functions as deprecated, so compilers can emit appropriate warnings. + * New symbol MBG_TGT_HAS_ABS64. + * Moved some compatibility definitions from gpsserio.h here. + * Define ssize_t for Windows, if required. + * Conditionally provided struct timespec for Windows. + * Added compatible 64 bit type print format specifiers. + * Include inttypes.h for all targets providing also stdint.h. + * Added some MSVC version code information. + * Fixes for FreeBSD. + * Fixed some spelling. + * Tmp workaround for 2.6.32-5-sparc64. + * Proper fix required. + * Revision 1.34.1.26 2016/08/05 10:38:10 martin + * Revision 1.34.1.25 2016/08/04 14:51:25Z martin + * Moved some compatibility definitions from gpsserio.h to mbg_tgt.h. + * Revision 1.34.1.24 2016/08/02 13:10:58 martin + * Define ssize_t for Windows, if required. + * Revision 1.34.1.23 2016/07/18 14:41:27Z martin + * New symbol MBG_TGT_HAS_ABS64. + * Revision 1.34.1.22 2016/07/14 09:00:58Z martin + * Conditionally provided struct timespec for Windows. + * Revision 1.34.1.21 2016/07/07 10:01:28Z martin + * Modified inclusion of Windows header files. + * Revision 1.34.1.20 2016/06/06 12:59:03 thomas-b + * Include all necessary Windows headers in the needed sequence + * Revision 1.34.1.19 2016/04/26 14:53:06 martin + * Revision 1.34.1.18 2016/04/26 13:31:08Z martin + * Added compatible 64 bit type print format specifiers. + * Revision 1.34.1.17 2016/04/25 14:46:20Z martin + * Include inttypes.h for all targets providing also stdint.h. + * Revision 1.34.1.16 2016/03/02 12:26:15 martin + * *** empty log message *** + * Revision 1.34.1.15 2016/02/26 09:12:11 paul + * Revision 1.34.1.14 2015/12/10 12:34:14Z martin + * *** empty log message *** + * Revision 1.34.1.13 2015/12/01 14:55:52 martin + * Revision 1.34.1.12 2015/12/01 14:54:08Z martin + * *** empty log message *** + * Revision 1.34.1.11 2015/12/01 14:52:20 martin + * *** empty log message *** + * Revision 1.34.1.10 2015/12/01 14:43:44 martin + * *** empty log message *** + * Revision 1.34.1.9 2015/12/01 13:55:09 martin + * Conditionally define a macro _DEPRECATED_BY which can be used to + * tag functions as deprecated, so compilers can emit appropriate warnings. + * Revision 1.34.1.8 2015/10/28 13:45:25 martin + * Added some MSVC version code information. + * Revision 1.34.1.7 2015/10/19 09:34:56 martin + * Fixed some spelling. + * Revision 1.34.1.6 2015/10/15 12:49:10 marvin + * Revision 1.34.1.5 2015/10/08 08:55:16Z martin + * Revision 1.34.1.4 2015/10/05 15:07:23Z marvin + * Unicode support. + * Revision 1.34.1.3 2015/09/21 08:58:27Z martin + * *** empty log message *** + * Revision 1.34.1.2 2015/09/18 14:53:25 martin + * Fixes for FreeBSD. + * Revision 1.34.1.1 2015/04/07 15:40:59 martin + * Tmp workaround for 2.6.32-5-sparc64. + * Proper fix required. + * Revision 1.34 2015/03/03 13:32:49 martin * Provide __func__ for MS Visual Studio. * Revision 1.33 2015/03/02 11:27:59Z martin * Windows only: @@ -78,9 +162,9 @@ * Recognize DOS target under Watcom compilers. * Flag Watcom C always supports wchar_t. * Revision 1.12 2008/01/17 09:38:50Z daniel - * Added macros to determine whether C language extensions + * Added macros to determine whether C language extensions * (e.g. C94, C99) are supported by the target environment. - * Added macro to check whether wchar_t and friends are + * Added macro to check whether wchar_t and friends are * supported, and some compatibility stuff. * Revision 1.11 2007/10/31 16:58:03 martin * Fixed __mbg_inline for Borland C (DOS). @@ -89,7 +173,7 @@ * Added MBG_PORT_HANDLE type for serial ports. * Added macros for unified inline code syntax. * Revision 1.9 2006/12/08 12:45:54Z martin - * Under Windows include ntddk.h rather than windows.h + * Under Windows include ntddk.h rather than windows.h * if building kernel driver . * Revision 1.8 2006/10/25 12:20:45Z martin * Initial support for FreeBSD, NetBSD, and OpenBSD. @@ -106,7 +190,7 @@ * Revision 1.3 2003/04/09 13:37:20Z martin * Added definition for _MBG_API. * Revision 1.2 2003/02/24 16:08:45Z martin - * Don't setup for Win32 PNP if explicitely configured non-PNP. + * Don't setup for Win32 PNP if explicitly configured non-PNP. * Revision 1.1 2002/02/19 13:46:20Z MARTIN * Initial revision * @@ -146,7 +230,7 @@ #if ( _WIN32_WINNT >= 0x0500 ) // Win2k and above #if !defined( MBG_TGT_WIN32_NON_PNP ) - // only if not explicitely disabled + // only if not explicitly disabled #define MBG_TGT_WIN32_PNP #endif #endif @@ -217,23 +301,17 @@ // GCC for target OpenBSD #define MBG_TGT_OPENBSD -#elif defined( __sun ) // Oracle Solaris or other SunOS derived operating system +#elif defined( __sun ) // Oracle Solaris or other SunOS derived operating system // __SUNPRO_C Oracle Solaris Studio C compiler, __SUNPRO_C value is the version number // __SUNPRO_CC Oracle Solaris Studio C++ compiler, __SUNPRO_CC value is the version number // __sparc generate code for SPARC (R) architecture (32-bit or 64-bit) - // __sparcv9 generate code for 64-bit SPARC architecture - // __i386 generate code for 32-bit x86 architecture - // __amd64 generate code for 64-bit x64 architecture + // __sparcv9 generate code for 64-bit SPARC architecture + // __i386 generate code for 32-bit x86 architecture + // __amd64 generate code for 64-bit x64 architecture #define MBG_TGT_SUNOS - #define __mbg_inline __inline__ - - #include <stdint.h> - #include <stdbool.h> - #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1 - #elif defined( __QNX__ ) // any compiler for target QNX @@ -260,7 +338,7 @@ #if defined( MBG_TGT_FREEBSD ) \ - || defined( MBG_TGT_NETBSD ) \ + || defined( MBG_TGT_NETBSD ) \ || defined( MBG_TGT_OPENBSD ) #define MBG_TGT_BSD @@ -270,18 +348,35 @@ #endif -#if defined( MBG_TGT_LINUX ) \ - || defined( MBG_TGT_BSD ) \ +#if defined( MBG_TGT_LINUX ) \ + || defined( MBG_TGT_BSD ) \ + || defined( MBG_TGT_QNX_NTO ) \ || defined( MBG_TGT_SUNOS ) + #define MBG_TGT_POSIX #define MBG_TGT_UNIX #endif +#if defined( MBG_TGT_WIN32 ) + + #define _CRT_SECURE_NO_WARNINGS 1 + +#endif // Some definitions depending on the build environment ... -#if defined( __GNUC__ ) +#if defined( __GNUC__ ) || defined( __clang__ ) + + #if defined( __clang__ ) + #define _CLANG_VERSION ( __clang_major__ * 10000 \ + + __clang_minor__ * 100 \ + + __clang_patchlevel__ ) + #endif // defined( __clang__ ) + + #define _GCC_VERSION ( __GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__ ) #if defined( __i386__ ) @@ -314,21 +409,32 @@ #if defined( MBG_TGT_LINUX ) - #if defined( __KERNEL__ ) + #if defined( MBG_TGT_KERNEL ) #include <linux/types.h> #include <linux/version.h> - #if ( LINUX_VERSION_CODE <= KERNEL_VERSION( 2, 6, 4 ) ) + #if ( LINUX_VERSION_CODE <= KERNEL_VERSION( 2, 6, 4 ) ) || \ + ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2, 6, 4 ) ) // must be true for 2.6.32-5-sparc64 #define _ULONG_DEFINED 1 #define _USHORT_DEFINED 1 #define _UINT_DEFINED 1 #endif + // The Linux kernel provides the bool type + #if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2, 6, 19 ) ) + typedef _Bool bool; + #define bool bool + #endif + + // 'true' and 'false' are also defined by newer kernel versions + // as enum in linux/stddef.h, but may not be defined by + // older kernels. + #else - #include <sys/types.h> #include <stdint.h> + #include <inttypes.h> #include <stdbool.h> #if defined( __u_char_defined ) @@ -341,16 +447,25 @@ #elif defined( MBG_TGT_BSD ) - #include <sys/types.h> + #if defined( MBG_TGT_KERNEL ) + #include <sys/types.h> + #else + #include <stdint.h> + #include <inttypes.h> + #include <stdbool.h> + #endif #elif defined( MBG_TGT_QNX_NTO ) // QNX 6.x (Neutrino) + #include <unistd.h> #include <stdint.h> + #include <inttypes.h> #include <stdbool.h> #else #include <stdint.h> + #include <inttypes.h> #include <stdbool.h> #endif @@ -359,38 +474,111 @@ #define MBG_TGT_HAS_WCHAR_T 1 - #define __mbg_inline __inline__ + + #if defined( __clang__ ) + #define _DEPRECATED_BY( _s ) __attribute__((deprecated("use \"" _s "\" instead"))) // works with clang 3.4.1 + #elif ( _GCC_VERSION > 40500 ) // gcc 4.5.0 and newer + #define _DEPRECATED_BY( _s ) __attribute__((deprecated("use \"" _s "\" instead"))) + #elif ( _GCC_VERSION > 30100 ) // gcc 3.1 and newer + #define _DEPRECATED_BY( _s ) __attribute__((deprecated)) + #else + // Not supported at all, use empty default definiton below. + #endif + + #if ( _GCC_VERSION > 30100 ) // gcc 3.1 and newer + #define __mbg_inline __inline__ __attribute__((always_inline)) + #else + // Not supported at all, use empty default definiton below. + #define __mbg_inline __inline__ + #endif #elif defined( _MSC_VER ) // Known predifined MS compiler version codes: + // 1900: MSVC++ 14.0 (Visual Studio 2015) + // 1800: MSVC++ 12.0 (Visual Studio 2013) // 1700: MSVC++ 11.0 (Visual Studio 2012) // 1600: MSVC++ 10.0 (Visual Studio 2010) // 1500: MSVC++ 9.0 (Visual Studio 2008) - // 1400: MSVC++ 8.0 (Visual Studio 2005) - // 1310: MSVC++ 7.1 (Visual Studio 2003) - // 1300: MSVC++ 7.0 + // 1400: MSVC++ 8.0 (Visual Studio 2005, Windows Server 2003 SP1 DDK - AMD64) + // 1310: MSVC++ 7.1 (Visual Studio .NET 2003, Windows Server 2003 DDK) + // 1300: MSVC++ 7.0 (Visual Studio .NET 2002, Windows XP SP1 DDK) // 1200: MSVC++ 6.0 // 1100: MSVC++ 5.0 + // "struct timespec" is supported only since VS2015 + // If it is then also the symbol TIME_UTC should be defined. + // Functions to read the current time as struct timespec + // are timespec_get() and friends, which are also only provided + // by VS2015 and later. + // As of VS2015, only TIME_UTC is supported to read + // the UTC system time, there is no equivalent for + // the POSIX CLOCK_MONOTONIC. However, QPC can be used + // to get monotonic time stamps and intervals. + #if ( _MSC_VER < 1900 ) + #if !defined( HAVE_STRUCT_TIMESPEC ) + #define MBG_TGT_MISSING_STRUCT_TIMESPEC 1 + #endif + #endif + #if ( _MSC_VER >= 1600 ) #include <stdint.h> - #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1 + #include <inttypes.h> + #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1 #else - #define MBG_TGT_HAS_INT_8_16_32 1 + #define MBG_TGT_HAS_INT_8_16_32 1 + #define MBG_PRE64_PREFIX "I64" #endif - // no bool support anyway - #define MBG_TGT_MISSING_BOOL_TYPE 1 + #if !defined( __cplusplus ) + // no bool support anyway + #define MBG_TGT_MISSING_BOOL_TYPE 1 + #endif - #define MBG_TGT_HAS_WCHAR_T 1 + #define MBG_TGT_HAS_WCHAR_T 1 #define __mbg_inline __forceinline - // At least up to VS2008 the builtin symbol __func__ - // is not supported, but __FUNCTION__ returns the name + // At least up to VS2008 the C99 builtin symbol __func__ + // is not supported. Some VS versions support __FUNCTION__ + // instead, but at least VC6 doesn't support this, either. // of the current function instead. - #define __func__ __FUNCTION__ + #if ( _MSC_VER >= 1300 ) + #define __func__ __FUNCTION__ + #else + #define __func__ "func_???" + #endif + + // "deprecated" attribute + #if ( _MSC_VER >= 1400 ) + // This is supported since Visual Studio 2005 + #define _DEPRECATED_BY( _s ) __declspec(deprecated("deprecated, use \"" _s "\"")) + #endif + + // availability of _abs64() + #if ( _MSC_VER >= 1310 ) + // This is supported at least since Visual Studio 2008 + // and Windows Server 2003 SP1 DDK. + #define MBG_TGT_HAS_ABS64 1 + #endif + + #if !defined ( HAVE_SSIZE_T ) + + // ssize_t support + #if ( _MSC_VER >= 1500 ) + // ssize_t may not be defined, but SSIZE_T is + #include <basetsd.h> + typedef SSIZE_T ssize_t; + #else + // At least VC6 hasn't SIZE_T, either, but size_t + // is typedef'ed as unsigned int, so we just typedef + // the signed variant here. + typedef int ssize_t; + #endif + + #define HAVE_SSIZE_T 1 + + #endif #elif defined( _CVI_ ) @@ -404,6 +592,7 @@ #if ( _CVI_ >= 910 ) // LabWindows/CVI 2009 is the first version providing stdint.h. #include <stdint.h> + #include <inttypes.h> #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1 #else #define USE_LONG_FOR_INT32 1 @@ -443,21 +632,31 @@ #if ( __BORLANDC__ >= 0x630 ) // C++Builder XE starts to provide stdbool.h #include <stdint.h> + #include <inttypes.h> #include <stdbool.h> - #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1 + #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1 #elif ( __BORLANDC__ >= 0x570 ) - // at least BDS 2006 starts to provide stdint.h + // BDS/Borland C++ Builder 2006 starts to provide at least stdint.h #include <stdint.h> - #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1 - #define MBG_TGT_MISSING_BOOL_TYPE 1 + #include <inttypes.h> + #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1 + #if !defined( __cplusplus ) + #define MBG_TGT_MISSING_BOOL_TYPE 1 + #endif #elif ( __BORLANDC__ >= 0x0550 ) - #define MBG_TGT_HAS_INT_8_16_32 1 - #define MBG_TGT_MISSING_BOOL_TYPE 1 + #define MBG_TGT_HAS_INT_8_16_32 1 + #define MBG_PRE64_PREFIX "I64" + #if !defined( __cplusplus ) + #define MBG_TGT_MISSING_BOOL_TYPE 1 + #endif #else // e.g. BC 3.1 or earlier #if ( __BORLANDC__ <= 0x410 ) - #define MBG_TGT_MISSING_64_BIT_TYPES 1 - #define MBG_TGT_MISSING_BOOL_TYPE 1 - #define USE_LONG_FOR_INT32 1 + #define MBG_TGT_MISSING_64_BIT_TYPES 1 + #define MBG_TGT_MISSING_BOOL_TYPE 1 + #define USE_LONG_FOR_INT32 1 + #define MBG_TGT_MISSING_STRUCT_TIMESPEC 1 + + typedef int ssize_t; #endif #endif @@ -483,15 +682,16 @@ #include <sys/types.h> - #define MBG_TGT_MISSING_64_BIT_TYPES 1 + #define MBG_TGT_MISSING_64_BIT_TYPES 1 #elif ( __WATCOMC__ > 1230 ) // Open Watcom C 1.3 and above #include <stdint.h> + #include <inttypes.h> #elif !defined( __WATCOM_INT64__ ) // Watcom C 11 - #define MBG_TGT_MISSING_64_BIT_TYPES 1 + #define MBG_TGT_MISSING_64_BIT_TYPES 1 #endif @@ -502,17 +702,34 @@ #endif +// If the build environment doesn't provide a inttypes.h file +// with print format specifiers for 64 bit fixed size types +// then MBG_PRE64_PREFIX should be defined which is used +// to define our own C99 compatible format specifiers. +// Eventually, similar definitions are required for 32, 16, +// and 8 bit fixed size types. +#if defined( MBG_PRE64_PREFIX ) + #define PRIi64 MBG_PRE64_PREFIX "i" + #define PRId64 MBG_PRE64_PREFIX "d" + #define PRIo64 MBG_PRE64_PREFIX "o" + #define PRIu64 MBG_PRE64_PREFIX "u" + #define PRIx64 MBG_PRE64_PREFIX "x" + #define PRIX64 MBG_PRE64_PREFIX "X" +#endif + #if !defined( __GNUC__ ) && !defined( __attribute__ ) #define __attribute__( _x ) #endif +#if !defined( _DEPRECATED_BY ) + #define _DEPRECATED_BY( _s ) // empty definition +#endif -#if defined( MBG_TGT_WIN32 ) - #define _CRT_SECURE_NO_WARNINGS +#if defined( MBG_TGT_WIN32 ) #if defined( _AMD64_ ) - // This is used for AMD64 architecture and for + // This is used for AMD64 architecture and for // Intel XEON CPUs with 64 bit extension. #define MBG_TGT_WIN32_PNP_X64 #define WIN32_FLAVOR "x64" @@ -524,15 +741,22 @@ #if defined( _KDD_ ) #define MBG_TGT_KERNEL #include <ntddk.h> + + #define _MBG_API #else // This must not be used for kernel drivers. + + // Prevent inclusion of obsolete winsock.h in windows.h #if !defined( WIN32_LEAN_AND_MEAN ) #define WIN32_LEAN_AND_MEAN 1 #endif - - #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ - #include <winsock2.h> + #if !defined( _WINSOCKAPI_ ) + #define _WINSOCKAPI_ + #endif + #include <windows.h> + #include <winsock2.h> + #include <ws2tcpip.h> typedef HANDLE MBG_HANDLE; @@ -554,9 +778,15 @@ typedef DWORD DWORD_PTR; #endif - #endif + // socklen_t support + #if ( _MSC_VER < 1500 ) + // At least VS2008 has a socklen_t type + typedef int socklen_t; + #endif - #define _MBG_API WINAPI + #define _MBG_API WINAPI + + #endif #if defined( MBG_LIB_EXPORT ) #define _MBG_API_ATTR __declspec( dllexport ) @@ -585,6 +815,44 @@ #endif +/** + * @brief A socket file descriptor type + */ +#if defined( MBG_TGT_WIN32 ) + #if !defined( MBG_TGT_KERNEL ) // we don't need this in kernel space + // usually evaluates to UINT_PTR, which in turn evaluates + // to (unsigned int), or (unsigned __int64). + typedef SOCKET MBG_SOCK_FD; + #endif +#elif defined( MBG_TGT_POSIX ) + typedef int MBG_SOCK_FD; //### TODO + //### TODO typedef int SOCKET; +#endif + + + +/** + * @brief A value to mark an ::MBG_SOCK_FD as invalid + */ +#if defined( MBG_TGT_WIN32 ) + #define MBG_INVALID_SOCK_FD INVALID_SOCKET // usually evaluates to (SOCKET)(~0) since SOCKET is unsigned +#elif defined( MBG_TGT_POSIX ) + #define MBG_INVALID_SOCK_FD -1 +#endif + + + +/** + * @brief The return code of socket functions in case of error + */ +#if defined( MBG_TGT_WIN32 ) + #define MBG_SOCKET_ERR_RETVAL SOCKET_ERROR // usually evaluates to -1 +#elif defined( MBG_TGT_POSIX ) + #define MBG_SOCKET_ERR_RETVAL -1 +#endif + + + #if !defined( _MBG_API ) #define _MBG_API #endif @@ -593,6 +861,10 @@ #define _MBG_API_ATTR #endif +#if !defined( _NO_MBG_API ) + #define _NO_MBG_API +#endif + #if !defined( _NO_MBG_API_ATTR ) #define _NO_MBG_API_ATTR #endif @@ -605,6 +877,18 @@ #define MBG_USE_MM_IO_FOR_PCI 0 #endif +#if defined( MBG_TGT_MISSING_STRUCT_TIMESPEC ) + +#include <time.h> + + struct timespec + { + time_t tv_sec; + long tv_nsec; + }; + +#endif // defined( MBG_TGT_MISSING_STRUCT_TIMESPEC ) + // The macros below are defined in order to be able to check if // certain C language extensions are available on the target system: diff --git a/mbglib/common/mbg_tmo.h b/mbglib/common/mbg_tmo.h index 3035d60..57b5cda 100644 --- a/mbglib/common/mbg_tmo.h +++ b/mbglib/common/mbg_tmo.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbg_tmo.h 1.8.1.3 2014/03/06 13:51:39Z martin TEST $ + * $Id: mbg_tmo.h 1.8.1.3.1.5 2017/04/10 13:21:18Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,18 @@ * * ----------------------------------------------------------------------- * $Log: mbg_tmo.h $ - * Revision 1.8.1.3 2014/03/06 13:51:39Z martin + * Revision 1.8.1.3.1.5 2017/04/10 13:21:18Z martin + * Fixed some compiler warnings. + * Revision 1.8.1.3.1.4 2015/10/05 15:07:24Z marvin + * Unicode support. + * Revision 1.8.1.3.1.3 2015/10/02 14:08:10Z martin + * *** empty log message *** + * Revision 1.8.1.3.1.2 2015/09/15 13:25:57 martin + * *** empty log message *** + * Revision 1.8.1.3.1.1 2015/09/10 14:12:12 martin + * Use clock_gettime( CLOCK_MONOTONIC, ... ) for timeouts. + * New function mbg_tmo_add_ms(). + * Revision 1.8.1.3 2014/03/06 13:51:39 martin * Renamed mbgserio_msec_to_timeval to mbg_msec_to_timeval. * Revision 1.8.1.2 2014/03/04 12:08:11 martin * Revision 1.8.1.1 2014/01/08 17:20:51Z martin @@ -43,6 +54,12 @@ #include <mbg_tgt.h> #include <words.h> +#include <stdlib.h> + +#if !defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_DOS ) + #include <sys/time.h> +#endif + #ifdef _MBG_TMO #define _ext #define _DO_INIT @@ -55,11 +72,9 @@ #if defined( MBG_TGT_POSIX ) - // TODO: eventually use timespec, if available - #include <stdlib.h> - #include <sys/time.h> + #include <time.h> - typedef struct timeval MBG_TMO_TIME; + typedef struct timespec MBG_TMO_TIME; #elif defined( MBG_TGT_WIN32 ) @@ -80,6 +95,16 @@ +typedef struct +{ + MBG_TMO_TIME t_start; + MBG_TMO_TIME t_tmo; + MBG_TMO_TIME t_now; + +} MBG_MSG_TIMES; + + + #if defined( __mbg_inline ) static __mbg_inline @@ -87,7 +112,7 @@ void mbg_tmo_get_time( MBG_TMO_TIME *t ) { #if defined( MBG_TGT_POSIX ) - gettimeofday( t, NULL ); + clock_gettime( CLOCK_MONOTONIC, t ); #elif defined( MBG_TGT_WIN32 ) @@ -122,7 +147,7 @@ int mbg_tmo_time_is_set( const MBG_TMO_TIME *t ) { #if defined( MBG_TGT_POSIX ) - return ( t->tv_sec != 0 ) || ( t->tv_usec != 0 ); + return ( t->tv_sec != 0 ) || ( t->tv_nsec != 0 ); #elif defined( MBG_TGT_WIN32 ) @@ -149,24 +174,30 @@ int mbg_tmo_time_is_set( const MBG_TMO_TIME *t ) #endif - #if defined( __mbg_inline ) static __mbg_inline -void mbg_tmo_set_timeout_ms( MBG_TMO_TIME *t_tmo, ulong msec ) +void mbg_tmo_add_ms( MBG_TMO_TIME *t_tmo, long msec ) { - mbg_tmo_get_time( t_tmo ); - #if defined( MBG_TGT_POSIX ) - t_tmo->tv_usec += msec * 1000; + ldiv_t ldt = ldiv( msec, 1000 ); - while ( t_tmo->tv_usec > 1000000L ) + t_tmo->tv_sec += ldt.quot; + t_tmo->tv_nsec += ldt.rem * 1000000L; + + while ( t_tmo->tv_nsec > 1000000000L ) { - t_tmo->tv_usec -= 1000000L; + t_tmo->tv_nsec -= 1000000000L; t_tmo->tv_sec++; } + while ( t_tmo->tv_nsec < 0L ) + { + t_tmo->tv_nsec += 1000000000L; + t_tmo->tv_sec--; + } + #elif defined( MBG_TGT_WIN32 ) t_tmo->u64 += ( (uint64_t) msec ) * 10000; @@ -177,19 +208,47 @@ void mbg_tmo_set_timeout_ms( MBG_TMO_TIME *t_tmo, ulong msec ) #endif -} // mbg_tmo_set_timeout +} // mbg_tmo_add_ms #elif defined( MBG_TGT_CVI ) - #define mbg_tmo_set_timeout_ms( _t, _msec ) \ - mbg_tmo_get_time( (_t) ); \ + #error FIXME + + #define mbg_tmo_add_ms( _t, _msec ) \ + mbg_tmo_get_time( (_t) ); \ (_t)->u64 += ( (uint64_t) (_msec) ) * 10000 #else // DOS, ... - #define mbg_tmo_set_timeout_ms( _t, _msec ) \ - mbg_tmo_get_time( (_t) ); \ + #error FIXME + + #define mbg_tmo_add_ms( _t, _msec ) \ + mbg_tmo_get_time( (_t) ); \ *(_t) += (clock_t) ( ( (double) (_msec) * CLOCKS_PER_SEC ) / 1000 ); + +#endif + + + +#if defined( __mbg_inline ) + +static __mbg_inline +void mbg_tmo_set_timeout_ms( MBG_TMO_TIME *t_tmo, ulong msec ) +{ + mbg_tmo_get_time( t_tmo ); + mbg_tmo_add_ms( t_tmo, msec ); + +} // mbg_tmo_set_timeout + +#else + + #define mbg_tmo_set_timeout_ms( _t, _msec ) \ + do \ + { \ + mbg_tmo_get_time( (_t) ); \ + mbg_tmo_add_ms( (_t), (_msec) ); \ + } while 0 + #endif @@ -202,7 +261,7 @@ long mbg_tmo_time_diff_ms( const MBG_TMO_TIME *t, const MBG_TMO_TIME *t0 ) #if defined( MBG_TGT_POSIX ) return ( t->tv_sec - t0->tv_sec ) * 1000 - + ( t->tv_usec - t0->tv_usec ) / 1000; + + ( t->tv_nsec - t0->tv_nsec ) / 1000000L; #elif defined( MBG_TGT_WIN32 ) @@ -238,7 +297,7 @@ double mbg_tmo_delta_t( const MBG_TMO_TIME *t, const MBG_TMO_TIME *t0 ) #if defined( MBG_TGT_POSIX ) return (double) ( t->tv_sec - t0->tv_sec ) - + (double) ( t->tv_usec - t0->tv_usec ) / 1e6; + + (double) ( t->tv_nsec - t0->tv_nsec ) / 1e9; #elif defined( MBG_TGT_WIN32 ) @@ -274,7 +333,7 @@ int mbg_tmo_time_is_after( const MBG_TMO_TIME *t_now, const MBG_TMO_TIME *tmo ) #if defined( MBG_TGT_POSIX ) return ( ( t_now->tv_sec > tmo->tv_sec ) || - ( ( t_now->tv_sec == tmo->tv_sec ) && ( t_now->tv_usec > tmo->tv_usec ) ) ); + ( ( t_now->tv_sec == tmo->tv_sec ) && ( t_now->tv_nsec > tmo->tv_nsec ) ) ); #elif defined( MBG_TGT_WIN32 ) @@ -331,11 +390,12 @@ int mbg_tmo_curr_time_is_after( const MBG_TMO_TIME *tmo ) // needs to be implemented as non-inline function in mbg_tmo.c void mbg_msec_to_timeval( ulong msec, struct timeval *tv ); -#elif defined( MBG_TGT_POSIX ) || defined( MBG_TGT_WIN32 ) +#elif defined( MBG_TGT_POSIX ) || defined( MBG_TGT_WIN32 ) static __mbg_inline void mbg_msec_to_timeval( ulong msec, struct timeval *tv ) { + tv->tv_sec = msec / 1000; tv->tv_usec = ( msec % 1000 ) * 1000; diff --git a/mbglib/common/mbgerror.c b/mbglib/common/mbgerror.c index 576cae7..31fd9b5 100644 --- a/mbglib/common/mbgerror.c +++ b/mbglib/common/mbgerror.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgerror.c 1.1.1.10 2015/05/20 12:34:03Z martin TEST $ + * $Id: mbgerror.c 1.2.1.5 2017/02/22 11:53:24Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,24 +10,23 @@ * * ----------------------------------------------------------------------- * $Log: mbgerror.c $ - * Revision 1.1.1.10 2015/05/20 12:34:03Z martin - * Revision 1.1.1.9 2014/10/28 15:19:17 martin - * Revision 1.1.1.8 2014/05/27 12:44:33Z martin - * Revision 1.1.1.7 2014/05/09 11:39:17 marvin - * Added access denied error to win32_to_mbg error handling. - * Revision 1.1.1.6 2014/03/18 11:25:54Z gregoire - * Fixed build errors fopr CVI, but this needs - * to be tested / improved. - * Revision 1.1.1.5 2014/03/12 09:01:56Z martin - * Revision 1.1.1.4 2014/03/11 14:12:29 martin - * Revision 1.1.1.3 2014/03/11 14:08:55Z martin - * Revision 1.1.1.2 2014/03/10 16:57:15Z martin - * Revision 1.1.1.1 2014/03/07 13:20:26 martin - * Tmp. saved changes. + * Revision 1.2.1.5 2017/02/22 11:53:24Z martin + * Removed type cast.which is now obsolete + * due to changed library type. + * Revision 1.2.1.4 2016/12/16 12:40:25Z thomas-b + * Added table entry for posix errors for ENOSPC (MBG_ERR_NO_SPACE) + * Revision 1.2.1.3 2016/09/13 10:24:02 martin + * Fixed some compiler warnings. + * Revision 1.2.1.2 2016/08/16 12:48:30Z gregoire.diehl + * CVI fixes + * Revision 1.2.1.1 2016/08/11 07:58:15 martin + * Fixed a compiler warning. + * Revision 1.2 2016/08/05 12:25:44Z martin + * Added some functions. * Revision 1.1 2014/03/07 12:08:14 martin * Initial revision. * -**************************************************************************/ + **************************************************************************/ #define _MBGERROR #include <mbgerror.h> @@ -38,65 +37,396 @@ #include <stdio.h> #include <string.h> -#if defined( MBG_TGT_POSIX ) +#if defined( MBG_TGT_POSIX ) || \ + defined( MBG_TGT_WIN32 ) || \ + defined( MBG_TGT_DOS ) + #define _MBG_TGT_HAS_POSIX_ERRNO 1 +#else + #define _MBG_TGT_HAS_POSIX_ERRNO 0 +#endif + +#if _MBG_TGT_HAS_POSIX_ERRNO #include <errno.h> +#endif + +#if defined( MBG_TGT_DOS ) + #include <stddef.h> +#endif + +#if defined( MBG_TGT_POSIX ) #include <netdb.h> #endif +#if defined(USE_MBG_ZLIB) + #include <zlib.h> +#endif + + +typedef struct +{ + int orig_errno; + int mbg_errno; + +} ERRNO_CNV_ENTRY; + + + +#if _MBG_TGT_HAS_POSIX_ERRNO + +static ERRNO_CNV_ENTRY posix_errno_table[] = +{ + // POSIX codes taken from Linux asm-generic/errno.h + { EPERM, MBG_ERR_PERM }, // 1, Operation not permitted + { ENOENT, MBG_ERR_NO_ENTITY }, // 2, No such file or directory + // { ESRCH, }, // 3, No such process + { EINTR, MBG_ERR_INTR }, // 4, Interrupted system call + { EIO, MBG_ERR_IO }, // 5, I/O error + { ENXIO, MBG_ERR_NOT_FOUND }, // 6, No such device or address + // { E2BIG, }, // 7, Argument list too long + // { ENOEXEC, }, // 8, Exec format error + // { EBADF, }, // 9, Bad file number + // { ECHILD, }, // 10, No child processes + // { EAGAIN, }, // 11, Try again + { ENOMEM, MBG_ERR_NO_MEM }, // 12, Out of memory + { EACCES, MBG_ERR_ACCESS }, // 13, Permission denied + // { EFAULT, }, // 14, Bad address + // { ENOTBLK, }, // 15, Block device required + { EBUSY, MBG_ERR_BUSY }, // 16, Device or resource busy + { EEXIST, MBG_ERR_EXIST }, // 17, File exists + { EXDEV, MBG_ERR_NO_DEV }, // 18, Cross-device link + // { ENODEV, }, // 19, No such device + // { ENOTDIR, }, // 20, Not a directory + // { EISDIR, }, // 21, Is a directory + { EINVAL, MBG_ERR_INV_PARM }, // 22, Invalid argument + // { ENFILE, }, // 23, File table overflow + // { EMFILE, }, // 24, Too many open files + // { ENOTTY, }, // 25, Not a typewriter + // { ETXTBSY, }, // 26, Text file busy + // { EFBIG, }, // 27, File too large + { ENOSPC, MBG_ERR_NO_SPACE }, // 28, No space left on device + { ESPIPE, MBG_ERR_PIPE }, // 29, Illegal seek + // { EROFS, }, // 30, Read-only file system + // { EMLINK, }, // 31, Too many links + // { EPIPE, }, // 32, Broken pipe + // { EDOM, }, // 33, Math argument out of domain of func + { ERANGE, MBG_ERR_RANGE }, // 34, Math result not representable +#if defined( EOVERFLOW ) + { EOVERFLOW, MBG_ERR_OVERFLOW }, // 75, Value too large for defined data type +#endif +#if defined( ENOTSOCK ) + { ENOTSOCK, MBG_ERR_NOT_A_SOCKET }, // 88, Socket operation on non-socket +#endif +#if defined( ECONNRESET ) + { ECONNRESET, MBG_ERR_CONN_RESET }, // 104, Connection reset by peer +#endif + { 0, 0 } // end-of-table identifier + +}; // posix_errno_table + +#endif // _MBG_TGT_HAS_POSIX_ERRNO + + + +#if defined( MBG_TGT_POSIX ) + +static ERRNO_CNV_ENTRY posix_h_errno_table[] = +{ + // POSIX codes taken from Linux netdb.h + { HOST_NOT_FOUND, MBG_ERR_HOST_NOT_FOUND }, // The specified host is unknown + // { NO_ADDRESS, }, // Usually same numeric value as NO_DATA + // { NO_DATA, }, // The requested name is valid but does not have an IP address + // { NO_RECOVERY, }, // A nonrecoverable name server error occurred + // { TRY_AGAIN, }, // A temporary error occurred on an authoritative name server. Try again later. + { 0, 0 } // end-of-table identifier + +}; // posix_h_errno_table + +#endif // defined( MBG_TGT_POSIX ) + + + +#if defined( MBG_TGT_CVI ) + +static ERRNO_CNV_ENTRY cvi_rs232_error_table[] = +{ + // { kRS_UnknownSysError, }, // Unknown system error. + // { kRS_InvalidPortNum, }, // In valid port number. + // { kRS_PortNotOpen, }, // Port is not open. + // { kRS_UnknownIOError, }, // Unknown I/O error. + // { kRS_InternalError, }, // Unexpected internal error. + // { kRS_NoPortFound, }, // No serial port found. + // { kRS_CanNotOpenPort, }, // Cannot open port. + // { kRS_NullPointerPassed, }, // A NULL pointer was passed when a non-NULL pointer was expected. + // { kRS_OutOfMemory, }, // Out of memory. + // { kRS_OutOfSystemResources, }, // Unable to allocate system resources. + // { kRS_InvalidParameter, }, // Invalid parameter. + // { kRS_InvalidBaudRate, }, // Invalid baud rate. + // { kRS_InvalidParity, }, // Invalid parity. + // { kRS_InvalidDataBits, }, // Invalid number of data bits. + // { kRS_InvalidStopBits, }, // Invalid number of stop bits. + // { kRS_BadFileHandle, }, // Bad file handle. + // { kRS_FileIOError, }, // File I/O error. + // { kRS_InvalidCount, }, // Invalid count; must be greater than or equal to 0. + // { kRS_InvalidIntLevel, }, // Invalid interrupt level. + // { kRS_IOTimeOut, }, // I/O operation timed out. + // { kRS_InvalidBreakTime, }, // Break time must be a positive value. + // { kRS_InvalidInQSize, }, // Requested input queue size must be 0 or greater. + // { kRS_InvalidOutQSize, }, // Requested output queue size must be 0 or greater. + // { kRS_GeneralIOFailure, }, // General I/O error. + // { kRS_InvalidBufferPointer, }, // Buffer parameter is NULL. + // { kRS_VISALibrariesMissing, }, // A necessary run-time library could not be found or loaded. + // { kRS_NoAckReceived, }, // Packet was sent, but no acknowledgment was received. + // { kRS_MaxRetriesBeforeSend, }, // Packet was not sent within retry limit. + // { kRS_MaxRetriesBeforeReceived, }, // Packet was not received within retry limit. + // { kRS_UnexpectedEOT, }, // End of transmission character encountered when start of data character expected. + // { kRS_CanNotReadPackNum, }, // Unable to read packet number. + // { kRS_InconsistentPackNum, }, // Inconsistent packet number. + // { kRS_CanNotReadPackData, }, // Unable to read packet data. + // { kRS_CanNotReadCheckSum, }, // Unable to read checksum. + // { kRS_CheckSumError, }, // Checksum received did not match computed checksum. + // { kRS_PackSizeGTInQ, }, // Packet size exceeds input queue size. + // { kRS_OpenFileError, }, // Error opening file. + // { kRS_ReadFileError, }, // Error reading file. + // { kRS_NoInitNegAck, }, // Did not receive initial negative acknowledgment character. + // { kRS_NoAckAfterEOT, }, // Did not receive acknowledgment after end of transmission character was sent. + // { kRS_WriteFileError, }, // Error writing to file. + // { kRS_NoSOHorEOT, }, // Did not receive either a start of data or end of transmission character when expected. + // { kRS_TransferCancelled, }, // Transfer was canceled because CAN ASCII character was received. + // { kRS_InvalidStartDelay, }, // Invalid start delay. + // { kRS_InvalidMaxTries, }, // Invalid maximum number of retries. + // { kRS_InvalidWaitPeriod, }, // Invalid wait period. + // { kRS_InvalidPacketSize, }, // Invalid packet size. + // { kRS_CanNotReadCRC, }, // Unable to read Cyclical Redundancy Check. + // { kRS_CRCError, }, // Cyclical Redundancy Check error. + { 0, 0 } // end-of-table identifier + +}; // cvi_rs232_error_table + +#endif // defined( MBG_TGT_CVI ) + #if defined( MBG_TGT_WIN32 ) +static ERRNO_CNV_ENTRY win32_error_table[] = +{ + // System Error Codes (1300-1699) + { ERROR_ACCESS_DENIED, MBG_ERR_ACCESS }, // + { ERROR_PRIVILEGE_NOT_HELD, MBG_ERR_PERM }, // + { ERROR_INVALID_HANDLE, MBG_ERR_INV_HANDLE }, // + { ERROR_NOT_ENOUGH_MEMORY, MBG_ERR_NO_MEM }, // + { ERROR_OUTOFMEMORY, MBG_ERR_NO_MEM }, // + // { ERROR_WRITE_PROTECT, }, // + // { ERROR_BAD_UNIT, }, // + // { ERROR_NOT_READY, }, // + // { ERROR_WRITE_FAULT, }, // + // { ERROR_READ_FAULT, }, // + // { ERROR_GEN_FAILURE, }, // + // { ERROR_SHARING_VIOLATION, }, // + // { ERROR_LOCK_VIOLATION, }, // + // { ERROR_NOT_SUPPORTED, }, // + // { ERROR_DUP_NAME, }, // + // { ERROR_BAD_DEV_TYPE, }, // + // { ERROR_BUFFER_OVERFLOW, }, // + { ERROR_BUSY, MBG_ERR_BUSY }, // + // { ERROR_NOACCESS, }, // + { 0, 0 } // end-of-table identifier + +}; // win32_error_table + + + +static ERRNO_CNV_ENTRY win32_wsa_err_table[] = +{ + { WSAEINTR, MBG_ERR_INTR }, // 10004L A blocking operation was interrupted by a call to WSACancelBlockingCall. + // { WSAEBADF // 10009L The file handle supplied is not valid. + // { WSAEACCES // 10013L An attempt was made to access a socket in a way forbidden by its access permissions. + // { WSAEFAULT // 10014L The system detected an invalid pointer address in attempting to use a pointer argument in a call. + // { WSAEINVAL // 10022L An invalid argument was supplied. + // { WSAEMFILE // 10024L Too many open sockets. + // { WSAEWOULDBLOCK // 10035L A non-blocking socket operation could not be completed immediately. + // { WSAEINPROGRESS // 10036L A blocking operation is currently executing. + // { WSAEALREADY // 10037L An operation was attempted on a non-blocking socket that already had an operation in progress. + { WSAENOTSOCK, MBG_ERR_NOT_A_SOCKET }, // 10038L An operation was attempted on something that is not a socket. + // { WSAEDESTADDRREQ // 10039L A required address was omitted from an operation on a socket. + // { WSAEMSGSIZE // 10040L A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself. + // { WSAEPROTOTYPE // 10041L A protocol was specified in the socket function call that does not support the semantics of the socket type requested. + // { WSAENOPROTOOPT // 10042L An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call. + // { WSAEPROTONOSUPPORT // 10043L The requested protocol has not been configured into the system, or no implementation for it exists. + // { WSAESOCKTNOSUPPORT // 10044L The support for the specified socket type does not exist in this address family. + // { WSAEOPNOTSUPP // 10045L The attempted operation is not supported for the type of object referenced. + // { WSAEPFNOSUPPORT // 10046L The protocol family has not been configured into the system or no implementation for it exists. + // { WSAEAFNOSUPPORT // 10047L An address incompatible with the requested protocol was used. + // { WSAEADDRINUSE // 10048L Only one usage of each socket address (protocol/network address/port) is normally permitted. + // { WSAEADDRNOTAVAIL // 10049L The requested address is not valid in its context. + // { WSAENETDOWN // 10050L A socket operation encountered a dead network. + // { WSAENETUNREACH // 10051L A socket operation was attempted to an unreachable network. + // { WSAENETRESET // 10052L The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress. + // { WSAECONNABORTED // 10053L An established connection was aborted by the software in your host machine. + { WSAECONNRESET, MBG_ERR_CONN_RESET }, // 10054L An existing connection was forcibly closed by the remote host. + // { WSAENOBUFS // 10055L An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. + // { WSAEISCONN // 10056L A connect request was made on an already connected socket. + // { WSAENOTCONN // 10057L A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. + // { WSAESHUTDOWN // 10058L A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call. + // { WSAETOOMANYREFS // 10059L Too many references to some kernel object. + // { WSAETIMEDOUT // 10060L A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. + // { WSAECONNREFUSED // 10061L No connection could be made because the target machine actively refused it. + // { WSAELOOP // 10062L Cannot translate name. + // { WSAENAMETOOLONG // 10063L Name component or name was too long. + // { WSAEHOSTDOWN // 10064L A socket operation failed because the destination host was down. + // { WSAEHOSTUNREACH // 10065L A socket operation was attempted to an unreachable host. + // { WSAENOTEMPTY // 10066L Cannot remove a directory that is not empty. + // { WSAEPROCLIM // 10067L A Windows Sockets implementation may have a limit on the number of applications that may use it simultaneously. + // { WSAEUSERS // 10068L Ran out of quota. + // { WSAEDQUOT // 10069L Ran out of disk quota. + // { WSAESTALE // 10070L File handle reference is no longer available. + // { WSAEREMOTE // 10071L Item is not available locally. + // { WSASYSNOTREADY // 10091L WSAStartup cannot function at this time because the underlying system it uses to provide network services is currently unavailable. + // { WSAVERNOTSUPPORTED // 10092L The Windows Sockets version requested is not supported. + { WSANOTINITIALISED, MBG_ERR_SOCK_INIT }, // 10093L Either the application has not called WSAStartup, or WSAStartup failed. + // { WSAEDISCON // 10101L Returned by WSARecv or WSARecvFrom to indicate the remote party has initiated a graceful shutdown sequence. + // { WSAENOMORE // 10102L No more results can be returned by WSALookupServiceNext. + // { WSAECANCELLED // 10103L A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. + // { WSAEINVALIDPROCTABLE // 10104L The procedure call table is invalid. + // { WSAEINVALIDPROVIDER // 10105L The requested service provider is invalid. + // { WSAEPROVIDERFAILEDINIT // 10106L The requested service provider could not be loaded or initialized. + // { WSASYSCALLFAILURE // 10107L A system call that should never fail has failed. + // { WSASERVICE_NOT_FOUND // 10108L No such service is known. The service cannot be found in the specified name space. + // { WSATYPE_NOT_FOUND // 10109L The specified class was not found. + // { WSA_E_NO_MORE // 10110L No more results can be returned by WSALookupServiceNext. + // { WSA_E_CANCELLED // 10111L A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. + // { WSAEREFUSED // 10112L A database query failed because it was actively refused. + { WSAHOST_NOT_FOUND, MBG_ERR_HOST_NOT_FOUND }, // 11001L No such host is known. + // { WSATRY_AGAIN // 11002L This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. + // { WSANO_RECOVERY // 11003L A non-recoverable error occurred during a database lookup. + // { WSANO_DATA // 11004L The requested name is valid, but no data of the requested type was found. + { 0, 0 } // end-of-table identifier + +}; // win32_wsa_err_table + +#endif // defined( MBG_TGT_WIN32 ) + + + +/** + * @brief Lookup some error code in a conversion table + * + * @param[in] orig_errno + * @param[in] tbl + * + * @return @ref MBG_ERROR_CODES associated with the original error code, + * or ::MBG_ERR_UNSPEC if origianl code not found in table. + */ +static /*HDR*/ +int lookup_mbg_errno( int orig_errno, const ERRNO_CNV_ENTRY tbl[] ) +{ + const ERRNO_CNV_ENTRY *p; + + for ( p = tbl; p->orig_errno || p->mbg_errno; p++ ) + if ( p->orig_errno == orig_errno ) + return p->mbg_errno; + + return MBG_ERR_UNSPEC; + +} // lookup_mbg_errno + + + /*HDR*/ /** - * @brief Translate a Windows non-socket API error code to one of the @ref MBG_ERROR_CODES + * @brief Return an error string associated with the @ref MBG_ERROR_CODES * - * @param last_err A Windows non-socket API error code as returned by GetLastError() - * @param info An optional informational text string, or NULL + * @param[in] mbg_errno One of the @ref MBG_ERROR_CODES + * + * @return A constant string describing the error, or NULL for unknown error codes + */ +const char *mbg_strerror( int mbg_errno ) +{ + static const MBG_CODE_NAME_TABLE_ENTRY tbl[] = MBG_ERR_NAMES_ENG; + + const MBG_CODE_NAME_TABLE_ENTRY *p; + + for ( p = tbl; p->name; p++ ) + { + if ( mbg_errno == p->code ) + return p->name; + } + + + return "Unknown error"; + +} // mbg_strerror + + + +// test if ioctl error and print msg if true +//### TODO check if this should be renamed +/*HDR*/ +int mbg_ioctl_err( int rc, const char *descr ) +{ + if ( mbg_rc_is_error( rc ) ) + { + fprintf( stderr, "** %s: %s (rc: %i)\n", descr, mbg_strerror( rc ), rc ); + return -1; + } + + return 0; + +} // mbg_ioctl_err + + + +#if defined( MBG_TGT_CVI ) + +/*HDR*/ +/** + * @brief Translate an error code from the Labwindows/CVI RS-232 library to one of the @ref MBG_ERROR_CODES + * + * @param[in] cvi_rc An error code returned by a CVI RS-232 library function + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES + * + * @see http://zone.ni.com/reference/en-XX/help/370051V-01/cvi/libref/cvirs232_error_conditions/ */ -int mbg_win32_last_err_to_mbg( DWORD last_err, const char *info ) +int mbg_cvi_rs232_error_to_mbg( int cvi_rc, const char *info ) { #if DEBUG if ( info ) - fprintf( stderr, "%s, wsa_err: 0x%08lX\n", info, (long) last_err ); + fprintf( stderr, "%s, CVI RS-232 rc: %i\n", info, cvi_rc ); + #else + (void) info; // avoid compiler warning #endif - //##++++++++++++++++ TODO check codes - switch ( last_err ) // codes usually defined in winerror.h - { - case ERROR_SUCCESS: return MBG_SUCCESS; - case ERROR_ACCESS_DENIED: return MBG_ERR_ACCESS; + return ( cvi_rc < 0 ) ? lookup_mbg_errno( cvi_rc, cvi_rs232_error_table ) : MBG_SUCCESS; - case ERROR_PRIVILEGE_NOT_HELD: return MBG_ERR_PERM; +} // mbg_cvi_rs232_error_to_mbg - #if 0 - case ERROR_INVALID_HANDLE: +#endif - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_OUTOFMEMORY: - case ERROR_WRITE_PROTECT: - case ERROR_BAD_UNIT: - case ERROR_NOT_READY: - case ERROR_WRITE_FAULT: - case ERROR_READ_FAULT: - case ERROR_GEN_FAILURE: - case ERROR_SHARING_VIOLATION: - case ERROR_LOCK_VIOLATION: - case ERROR_NOT_SUPPORTED: - case ERROR_DUP_NAME: - case ERROR_BAD_DEV_TYPE: - case ERROR_BUFFER_OVERFLOW: +#if defined( MBG_TGT_WIN32 ) - case ERROR_BUSY: - case ERROR_NOACCESS: +/*HDR*/ +/** + * @brief Translate a Windows non-socket API error code to one of the @ref MBG_ERROR_CODES + * + * @param[in] last_err A Windows non-socket API error code as returned by GetLastError() + * @param[in] info An optional informational text string, or NULL + * + * @return One of the @ref MBG_ERROR_CODES + */ +int mbg_win32_last_err_to_mbg( DWORD last_err, const char *info ) +{ + #if DEBUG + if ( info ) + fprintf( stderr, "%s, wsa_err: 0x%08lX\n", info, (long) last_err ); + #else + (void) info; // avoid compiler warning #endif - } - return MBG_ERR_UNSPEC; + return ( last_err == ERROR_SUCCESS ) ? MBG_SUCCESS : lookup_mbg_errno( last_err, win32_error_table ); } // mbg_win32_last_err_to_mbg @@ -106,8 +436,8 @@ int mbg_win32_last_err_to_mbg( DWORD last_err, const char *info ) /** * @brief Translate a Windows socket API error code to one of the @ref MBG_ERROR_CODES * - * @param wsa_err A Windows socket API error code as returned by WSAGetLastError() - * @param info An optional informational text string, or NULL + * @param[in] wsa_err A Windows socket API error code as returned by WSAGetLastError() + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -116,45 +446,13 @@ int mbg_win32_wsa_err_to_mbg( DWORD wsa_err, const char *info ) #if DEBUG if ( info ) fprintf( stderr, "%s, wsa_err: 0x%08lX\n", info, (long) wsa_err ); + #else + (void) info; // avoid compiler warning #endif - //##++++++++++++++++ TODO check codes - switch ( wsa_err ) - { - case WSAENOTSOCK: - return MBG_ERR_NOT_A_SOCKET; - - case WSANOTINITIALISED: - return MBG_ERR_SOCK_INIT; - - case WSAEFAULT: - case WSAENETDOWN: - case WSAEINVAL: - case WSAEINTR: - case WSAEINPROGRESS: - return MBG_ERR_SOCK_INIT; - - case WSAEAFNOSUPPORT: - case WSAEMFILE: - case WSAEINVALIDPROVIDER: - case WSAEINVALIDPROCTABLE: - case WSAENOBUFS: - case WSAEPROTONOSUPPORT: - case WSAEPROTOTYPE: - case WSAEPROVIDERFAILEDINIT: - case WSAESOCKTNOSUPPORT: - return MBG_ERR_INV_SOCK_FD; //##++++++++++++++++ - -#if 0 - case WSAEALREADY: - case WSAEISCONN: - case WSAENETUNREACH: - return MBG_ERR_SOCKET_CFG; //##+++++ - break; -#endif - } - - return MBG_ERR_UNSPEC; + // The WSA error code is only retrieved after an error has occurred, so + // we don't need care for the success case here. + return lookup_mbg_errno( wsa_err, win32_wsa_err_table ); } // mbg_win32_wsa_err_to_mbg @@ -162,14 +460,14 @@ int mbg_win32_wsa_err_to_mbg( DWORD wsa_err, const char *info ) -#if defined( MBG_TGT_POSIX ) +#if _MBG_TGT_HAS_POSIX_ERRNO /*HDR*/ /** * @brief Translate a POSIX errno error code to one of the @ref MBG_ERROR_CODES * - * @param posix_errno A POSIX error code as usually defined in errno.h - * @param info An optional informational text string, or NULL + * @param[in] posix_errno A POSIX error code as usually defined in errno.h + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -179,29 +477,19 @@ int mbg_posix_errno_to_mbg( int posix_errno, const char *info ) if ( info ) fprintf( stderr, "%s: %s (errno: %i)\n", info, strerror( posix_errno ), posix_errno ); + #else + (void) info; // avoid compiler warning #endif - switch ( posix_errno ) - { - case EPERM: return MBG_ERR_PERM; - case EINTR: return MBG_ERR_INTR; - case EIO: return MBG_ERR_IO; - case ENXIO: return MBG_ERR_NOT_FOUND; - case ENOMEM: return MBG_ERR_NO_MEM; - case EACCES: return MBG_ERR_ACCESS; - case EBUSY: return MBG_ERR_BUSY; - case ENODEV: return MBG_ERR_NO_DEV; - case EINVAL: return MBG_ERR_INV_PARM; - case EPIPE: return MBG_ERR_PIPE; - case EOVERFLOW: return MBG_ERR_OVERFLOW; - case ENOTSOCK: return MBG_ERR_NOT_A_SOCKET; - default: break; - } - - return MBG_ERR_UNSPEC; + return lookup_mbg_errno( posix_errno, posix_errno_table ); } // mbg_posix_errno_to_mbg +#endif // _MBG_TGT_HAS_POSIX_ERRNO + + + +#if defined( MBG_TGT_POSIX ) /*HDR*/ /** @@ -214,8 +502,8 @@ int mbg_posix_errno_to_mbg( int posix_errno, const char *info ) * The functions gethostbyname() and gethostbyaddr() are obsolete, * and getaddressinfo() should be used preferably. * - * @param posix_h_errno An error code as usually defined in netdb.h - * @param info An optional informational text string, or NULL + * @param[in] posix_h_errno An error code as usually defined in netdb.h + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -225,22 +513,11 @@ int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info ) if ( info ) fprintf( stderr, "%s: %s (h_errno: %i)\n", info, hstrerror( posix_h_errno ), posix_h_errno ); + #else + (void) info; // avoid compiler warning #endif - switch ( posix_h_errno ) - { - case HOST_NOT_FOUND: // The specified host is unknown - - // case NO_ADDRESS: // Usually same numeric value as NO_DATA - case NO_DATA: // The requested name is valid but does not have an IP address - - case NO_RECOVERY: // A nonrecoverable name server error occurred - - case TRY_AGAIN: // A temporary error occurred on an authoritative name server. Try again later. - return MBG_ERR_UNSPEC; //##++++++++++++++++++++++++ - } - - return MBG_ERR_UNSPEC; + return lookup_mbg_errno( posix_h_errno, posix_h_errno_table ); } // mbg_posix_h_errno_to_mbg @@ -261,7 +538,7 @@ int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info ) * code from non-socket POSIX-like functions has to be retrieved * by calling GetLastError(). * - * @param info An optional informational text string, or NULL + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -273,7 +550,7 @@ int mbg_get_last_error( const char *info ) // has to be retrieved by calling GetLastError(), whereas // the "last error" code from POSIX-like socket functions // is retrieved by calling WSAGetLastError(). - return mbg_win32_wsa_err_to_mbg( GetLastError(), info ); + return mbg_win32_last_err_to_mbg( GetLastError(), info ); #elif defined( MBG_TGT_POSIX ) @@ -282,7 +559,8 @@ int mbg_get_last_error( const char *info ) #else - #error This function is not supported for this target. + // ### TODO #error This function is not supported for this target. + return mbg_posix_errno_to_mbg( errno, info ); #endif @@ -290,6 +568,8 @@ int mbg_get_last_error( const char *info ) +#if !defined( MBG_TGT_DOS ) + /*HDR*/ /** * @brief Get and translate last error after socket function call @@ -302,7 +582,7 @@ int mbg_get_last_error( const char *info ) * has to be retrieved by calling WSAGetLastError, whereas the "last error" * code from non-socket POSIX-like functions is stored in errno as usual. * - * @param info An optional informational text string, or NULL + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -349,7 +629,7 @@ int mbg_get_last_socket_error( const char *info ) * The functions gethostbyname() and gethostbyaddr() are obsolete, * and getaddressinfo() should be used preferably. * - * @param info An optional informational text string, or NULL + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -376,6 +656,8 @@ int mbg_get_gethostbyname_error( const char *info ) } // mbg_get_gethostbyname_error +#endif // !defined( MBG_TGT_DOS ) + #if 0 // not yet finished @@ -411,3 +693,41 @@ int mbg_gai_error( int rc, const char *info ) +#if defined( USE_MBG_ZLIB ) + +/*HDR*/ +/** + * @brief Retrieve and convert last zlib internal error code + * + * @param[in] zlib_error zlib internal error code + * @param[in] info An optional informational text string, or NULL + * @param[in] msg An optional zlib specific error msg, or NULL. + * Struct z_stream contains member msg. + * + * @return One of the @ref MBG_ERROR_CODES + */ +int mbg_zlib_error_to_mbg( int zlib_error, const char *info, const char *msg ) +{ + #if DEBUG + if ( info && msg ) + fprintf( stderr, "%s: %s (zlib_error: %d)\n", info, + msg, zlib_error ); + #endif + + switch ( zlib_error ) + { + case Z_ERRNO: return mbg_get_last_error( info ); + case Z_MEM_ERROR: return MBG_ERR_NO_MEM; + /* + * All other zlib error codes are not specified any further. + * So, it's hard to guess what they mean and we return MBG_UNSPEC so far. + */ + default: + return MBG_ERR_UNSPEC; + } + +} // mbg_zlib_error_to_mbg + +#endif // defined(USE_MBG_ZLIB) + + diff --git a/mbglib/common/mbgerror.h b/mbglib/common/mbgerror.h index 2db8649..32b8020 100644 --- a/mbglib/common/mbgerror.h +++ b/mbglib/common/mbgerror.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgerror.h 1.7.1.6 2015/05/20 12:33:17Z martin TEST $ + * $Id: mbgerror.h 1.13 2017/02/28 15:23:14Z gregoire TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -11,13 +11,21 @@ * * ----------------------------------------------------------------------- * $Log: mbgerror.h $ - * Revision 1.7.1.6 2015/05/20 12:33:17Z martin - * Revision 1.7.1.5 2015/05/13 13:53:23 martin - * Revision 1.7.1.4 2014/10/30 11:15:36 martin - * Revision 1.7.1.3 2014/10/28 15:19:17 martin - * Revision 1.7.1.2 2014/09/26 11:45:34Z martin - * Revision 1.7.1.1 2014/06/25 08:52:50 martin - * Re-enabled some symbols which have been commented out.. + * Revision 1.13 2017/02/28 15:23:14Z gregoire + * error code MBG_ERR_INV_IDX added + * Revision 1.12 2017/01/10 15:54:56 philipp + * Fixed syntax error + * Revision 1.11 2017/01/10 14:26:31 philipp + * Added error MBG_ERR_NOT_CONFIGURED + * Revision 1.10 2016/12/16 12:40:33 thomas-b + * Added MBG_ERR_NO_SPACE + * Revision 1.9 2016/10/31 17:41:55 martin + * New error code MBG_ERR_DATA_FMT. + * Revision 1.8 2016/08/05 12:29:20 martin + * Re-enabled some symbols which have been commented out. + * Added new codes, and initializers for code/string conversion tables. + * Updated doxygen comments. + * Updated function prorotypes. * Revision 1.7 2014/05/27 13:32:47Z martin * Defined additional common error codes which can be * translated from OS specific codes. @@ -50,6 +58,7 @@ /* Other headers to be included */ #include <mbg_tgt.h> +#include <words.h> #ifdef _MBGERROR #define _ext @@ -62,38 +71,41 @@ /* Start of header body */ #if !defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_KERNEL ) - //##++++ Surprisingly we need this also for Windows + //### TODO Surprisingly we need this also for Windows // in kernel mode. This should be fixed. #define DWORD uint32_t // just to avoid compiler errors #endif + /** * @brief Error codes used with Meinberg devices and drivers * - * Some of the codes have to match codes which are defined in pcpsdefs.h - * and returned by the firmware of bus-level devices. - * - * The codes will be translated into an OS dependent error code - * when returned to the calling function. + * Appropriate error strings can be retrieved via the ::mbg_strerror function. * - * For Windows, these codes are made positive and or'ed with 0xE0000000 afterwards. + * Under Windows, some message strings are provided as resources appended + * to the mbgctrl DLL, but the codes specified here have to be translated + * to Windows-specific error codes before the appropriate resource string + * can be retrieved. Actually this is done by taking the absolute number + * of an error code and have it or'ed with 0xE0000000 afterwards, e.g. + * ::MBG_ERR_GENERIC (-19) will yield Windows code 0xE0000013. + * * See ::_mbg_err_to_os * - * Example: Code -19 (#MBG_ERR_GENERIC) will be converted to 0xE0000013 under Windows. - * - * @note Attention: - * The error codes below must match exactly the corresponding codes that are evaluated in user space. - * For Windows, they are located in messages.mc/.h in mbgsvctl.dll + * @see ::MBG_ERR_NAMES_ENG * * @anchor MBG_RETURN_CODES @{ */ -#define MBG_SUCCESS 0 ///< no error, must match ::PCPS_SUCCESS +// NOTE: Some of these codes have to match codes which are defined in pcpsdefs.h +// and returned by the firmware of bus-level devices, so the definitions +// must *not* be renumbered. + +#define MBG_SUCCESS 0 ///< no error, has to match ::PCPS_SUCCESS /** @anchor MBG_ERROR_CODES @{ */ // Other codes which have to match codes defined in pcpsdefs.h returned by bus-level devices -#define MBG_ERR_STIME -1 ///< invalid date/time/status passed, must match ::PCPS_ERR_STIME -#define MBG_ERR_CFG -2 ///< invalid params with a configuration cmd, must match ::PCPS_ERR_CFG +#define MBG_ERR_STIME -1 ///< tried to write invalid date/time/status to device, has to match ::PCPS_ERR_STIME +#define MBG_ERR_CFG -2 ///< tried to write invalid configuration parameters to device, has to match ::PCPS_ERR_CFG (see also ::MBG_ERR_INV_CFG) // Codes returned by low level functions of the bus-level device driver @@ -145,7 +157,7 @@ #define MBG_ERR_HDR_CSUM -61 ///< binary protocol header checksum error #define MBG_ERR_DATA_CSUM -62 ///< binary protocol data checksum error #define MBG_ERR_RCVD_NACK -63 ///< binary protocol received reply msg with a NACK code -#define MBG_ERR_RCVD_NO_ACK -64 ///< binary protocol received reply msg without expected ACK code +#define MBG_ERR_RCVD_NO_ACK -64 ///< binary protocol received reply msg without expected ACK code //### TODO #define MBG_ERR_CONN_TYPE -65 ///< binary protocol no valid/supported connection type specified #define MBG_ERR_BYTES_WRITTEN -66 ///< binary protocol failed to write all bytes #define MBG_ERR_AUTH -67 ///< binary protocol failed authentication @@ -161,7 +173,7 @@ #define MBG_ERR_NO_DEV -75 ///< specified device not found #define MBG_ERR_NOT_FOUND -76 ///< specified item not found -#define MBG_ERR_OVERFLOW -77 ///< buffer overflow +#define MBG_ERR_OVERFLOW -77 ///< range or buffer overflow #define MBG_ERR_PIPE -78 ///< pipe error #define MBG_ERR_INTR -79 ///< interrupted system call #define MBG_ERR_ACCESS -80 ///< access denied, e.g. when trying to access a device @@ -173,28 +185,186 @@ #define MBG_ERR_ENCRYPT -85 ///< encryption failed #define MBG_ERR_DECRYPT -86 ///< decryption failed +#define MBG_ERR_DISCONN -87 ///< connection closed by remote site / host +#define MBG_ERR_INV_CFG -88 ///< invalid/inconsistent configuration parameters read from device, see also ::MBG_ERR_CFG +#define MBG_ERR_RANGE -89 ///< input parameter was out of range + +#define MBG_ERR_INV_TLV_ANN_BYTES -90 ///< number of announced TLV bytes doesn't match number of transferred bytes +#define MBG_ERR_INV_TLV_SIZE -91 ///< ### TODO +#define MBG_ERR_INV_TLV_UID -92 ///< ### TODO + +#define MBG_ERR_EXIST -93 ///< file exists +#define MBG_ERR_DATA_SIZE -94 ///< the received data size toesn't match the expected data size +#define MBG_ERR_NO_ENTITY -95 ///< no such entity //### TODO or use MBG_ERR_NO_DEV / MBG_ERR_NOT_FOUND ? +#define MBG_ERR_ALREADY_ALLOC -96 ///< pointer already allocated when trying to allocate memory +#define MBG_ERR_HOST_NOT_FOUND -97 ///< host not found +#define MBG_ERR_CONN_RESET -98 ///< connection reset by peer +#define MBG_ERR_DATA_FMT -99 ///< invalid data format + +#define MBG_ERR_NO_SPACE -100 ///< insufficient disk space left on the device +#define MBG_ERR_NOT_CONFIGURED -101 ///< configuration option is not active/configured +#define MBG_ERR_INV_IDX -102 ///< invalid index value used + +// NOTE: New codes have to be appended to this list, and the sequence of codes must not +// be changed. Whenever new codes have been defined, appropriate entries have to be added +// to the ::MBG_ERR_NAMES_ENG table initializer below, and the Windows-specific message +// texts specified in messages.mc/.h from which the resources appended to mbgsvctl.dll +// are generated have to be updated accordingly. + /** @} anchor MBG_ERROR_CODES */ /** @} anchor MBG_RETURN_CODES */ +/** + * @brief Strings associated with @ref MBG_RETURN_CODES + * + * @see @ref MBG_RETURN_CODES + */ +#define MBG_ERR_NAMES_ENG \ +{ \ + { MBG_SUCCESS, "Success, no error" }, \ + { MBG_ERR_STIME, "Invalid date/time for device" }, \ + { MBG_ERR_CFG, "Invalid configuration parameters for device" }, \ + { MBG_ERR_GENERIC, "Generic error" }, \ + { MBG_ERR_TIMEOUT, "Timeout" }, \ + { MBG_ERR_FW_ID, "Invalid firmware ID" }, \ + { MBG_ERR_NBYTES, "Unexpected number of data bytes for this API" }, \ + { MBG_ERR_INV_TIME, "Invalid time passed to device" }, \ + { MBG_ERR_FIFO, "FIFO unexpectedly empty" }, \ + { MBG_ERR_NOT_READY, "Device not ready" }, \ + { MBG_ERR_INV_TYPE, "Unsupported data type" }, \ + { MBG_ERR_NO_MEM, "Memory allocation error" }, \ + { MBG_ERR_CLAIM_RSRC, "Faild to claim resources" }, \ + { MBG_ERR_DEV_NOT_SUPP, "Device not supported" }, \ + { MBG_ERR_INV_DEV_REQUEST, "Request not supported" }, \ + { MBG_ERR_NOT_SUPP_BY_DEV, "Not supported by device" }, \ + { MBG_ERR_USB_ACCESS, "USB access failed" }, \ + { MBG_ERR_CYCLIC_TIMEOUT, "Cyclic message timeout" }, \ + { MBG_ERR_NOT_SUPP_ON_OS, "Not supported by OS" }, \ + { MBG_ERR_LIB_NOT_COMPATIBLE, "Shared lib not compatible" }, \ + { MBG_ERR_N_COM_EXCEEDS_SUPP, "Num. COM ports exceeds supported" }, \ + { MBG_ERR_N_STR_EXCEEDS_SUPP, "Num. string formats exceeds supported" }, \ + { MBG_ERR_IRQ_UNSAFE, "Unsafe IRQ support" }, \ + { MBG_ERR_N_POUT_EXCEEDS_SUPP, "Num prog. outputs exceeds supported" }, \ + { MBG_ERR_INV_INTNO, "Invalid interrupt number" }, \ + { MBG_ERR_NO_DRIVER, "Driver not found" }, \ + { MBG_ERR_DRV_VERSION, "Driver too old" }, \ + { MBG_ERR_COPY_TO_USER, "Error copying to user space" }, \ + { MBG_ERR_COPY_FROM_USER, "Error copying from user space" }, \ + { MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP, "Num. PTP Unicast masters exceeds supported" }, \ + { MBG_ERR_N_GNSS_EXCEEDS_SUPP, "Num. GNSS systems exceeds supported" }, \ + { MBG_ERR_N_GPIO_EXCEEDS_SUPP, "Num. GPIO ports exceeds supported" }, \ + { MBG_ERR_N_XMR_EXCEEDS_SUPP, "Num. XMR sources exceeds supported" }, \ + { MBG_ERR_UNSPEC, "Unspecified error" }, \ + { MBG_ERR_HDR_CSUM, "Header checksum error" }, \ + { MBG_ERR_DATA_CSUM, "Data checksum error" }, \ + { MBG_ERR_RCVD_NACK, "Received NACK message" }, \ + { MBG_ERR_RCVD_NO_ACK, "Didn't receive ACK message" }, \ + { MBG_ERR_CONN_TYPE, "Invalid I/O connection type" }, \ + { MBG_ERR_BYTES_WRITTEN, "Failed to write all bytes" }, \ + { MBG_ERR_AUTH, "Authentication failed" }, \ + { MBG_ERR_SOCK_INIT, "Failed to initialize socket" }, \ + { MBG_ERR_INV_SOCK_FD, "Invalid socket descriptor" }, \ + { MBG_ERR_NOT_A_SOCKET, "Not a socket descriptor" }, \ + { MBG_ERR_NBLOCK_WAIT_SLCT, "Select timed out waiting for port ready" }, \ + { MBG_ERR_NBLOCK_WAIT_WR_FD, "Write file descriptor not ready after waiting for port ready" }, \ + { MBG_ERR_IO, "Generic I/O error" }, \ + { MBG_ERR_INV_PARM, "Invalid parameter" }, \ + { MBG_ERR_NO_DEV, "Specified device not found" }, \ + { MBG_ERR_NOT_FOUND, "Specified item not found" }, \ + { MBG_ERR_OVERFLOW, "Buffer overflow" }, \ + { MBG_ERR_PIPE, "Pipe error" }, \ + { MBG_ERR_INTR, "Interrupted system call" }, \ + { MBG_ERR_ACCESS, "Access denied" }, \ + { MBG_ERR_PERM, "Operation not permitted" }, \ + { MBG_ERR_BUSY, "Device busy" }, \ + { MBG_ERR_INV_HANDLE, "Invalid handle" }, \ + { MBG_ERR_XBP_CASC_LVL, "Too many XBP cascading levels" }, \ + { MBG_ERR_ENCRYPT, "Encryption failed" }, \ + { MBG_ERR_DECRYPT, "Decryption failed" }, \ + { MBG_ERR_DISCONN, "Connection closed by remote site/host" }, \ + { MBG_ERR_INV_CFG, "Invalid/inconsistent configuration read from device" }, \ + { MBG_ERR_RANGE, "Input parameter was out of range" }, \ + { MBG_ERR_INV_TLV_ANN_BYTES, "TLV num of transferred bytes differs from num of announced bytes" }, \ + { MBG_ERR_INV_TLV_SIZE, "MBG_ERR_INV_TLV_SIZE" }, /* ### TODO */ \ + { MBG_ERR_INV_TLV_UID, "MBG_ERR_INV_TLV_UID" }, /* ### TODO */ \ + { MBG_ERR_EXIST, "File exists" }, \ + { MBG_ERR_DATA_SIZE, "Received data size mismatch" }, \ + { MBG_ERR_NO_ENTITY, "No such entity" }, \ + { MBG_ERR_ALREADY_ALLOC, "Memory already allocated" }, \ + { MBG_ERR_HOST_NOT_FOUND, "Host not found" }, \ + { MBG_ERR_CONN_RESET, "Connection reset by peer" }, \ + { MBG_ERR_DATA_FMT, "Invalid data format" }, \ + { MBG_ERR_NO_SPACE, "Insufficient disk space" }, \ + { MBG_ERR_NOT_CONFIGURED, "Configuration is not active and/or configured" }, \ + { MBG_ERR_INV_IDX, "Invalid or unsupported index value used"}, \ + { 0, NULL } /* end of table */ \ +} + + + +#if defined( __mbg_inline ) + +static __mbg_inline +/** + * @brief Check if the code returned by a function indicates an error + * + * @param[in] rc One of the @ref MBG_RETURN_CODES + * + * @see ::mbg_rc_is_success + * @see @ref MBG_RETURN_CODES + */ +bool mbg_rc_is_error( int rc ) +{ + // Meinberg error codes are all < 0. + return rc < MBG_SUCCESS; + +} // mbg_rc_is_error + + +static __mbg_inline +/** + * @brief Check if the code returned by a function indicates success + * + * @param[in] rc One of the @ref MBG_RETURN_CODES + * + * @see ::mbg_rc_is_error + * @see @ref MBG_RETURN_CODES + */ +bool mbg_rc_is_success( int rc ) +{ + // There are functions which don't only return MBG_SUCCESS + // on success but some arbitrary positive number, e.g. the + // number of bytes sent. So success just means "not an error". + return !mbg_rc_is_error( rc ); + +} // mbg_rc_is_success + +#else + + #define mbg_rc_is_error( _rc ) ( (_rc) < MBG_SUCCESS ) + #define mbg_rc_is_success( _rc ) ( !mbg_rc_is_error( _rc ) ) + +#endif + + -// Depending on the operating system, the codes above have to be converted before -// they are sent up to user space #if defined( MBG_TGT_WIN32 ) + + // Windows-specific codes and code conversion + #if !defined( STATUS_SUCCESS ) // not in kernel mode #define STATUS_SUCCESS 0 #endif #define _mbg_err_to_os( _c ) \ - ( ( _c == MBG_SUCCESS ) ? STATUS_SUCCESS : ( abs( _c ) | 0xE0000000 ) ) -#endif + ( ( (_c) == MBG_SUCCESS ) ? STATUS_SUCCESS : ( abs( _c ) | 0xE0000000 ) ) + +#else + #define _mbg_err_to_os( _c ) (_c ) //### TODO remove this -// If no specific conversion has been defined -// then use the original codes. -#if !defined( _mbg_err_to_os ) - #define _mbg_err_to_os( _c ) ( _c ) #endif @@ -211,20 +381,42 @@ extern "C" { /* by MAKEHDR, do not remove the comments. */ /** + * @brief Return an error string associated with the @ref MBG_ERROR_CODES + * + * @param[in] mbg_errno One of the @ref MBG_ERROR_CODES + * + * @return A constant string describing the error, or NULL for unknown error codes + */ + const char *mbg_strerror( int mbg_errno ) ; + + int mbg_ioctl_err( int rc, const char *descr ) ; + /** + * @brief Translate an error code from the Labwindows/CVI RS-232 library to one of the @ref MBG_ERROR_CODES + * + * @param[in] cvi_rc An error code returned by a CVI RS-232 library function + * @param[in] info An optional informational text string, or NULL + * + * @return One of the @ref MBG_ERROR_CODES + * + * @see http://zone.ni.com/reference/en-XX/help/370051V-01/cvi/libref/cvirs232_error_conditions/ + */ + int mbg_cvi_rs232_error_to_mbg( int cvi_rc, const char *info ) ; + + /** * @brief Translate a Windows non-socket API error code to one of the @ref MBG_ERROR_CODES * - * @param wsa_err A Windows non-socket API error code as returned by GetLastError() - * @param info An optional informational text string, or NULL + * @param[in] last_err A Windows non-socket API error code as returned by GetLastError() + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ - int mbg_win32_last_err_to_mbg( DWORD wsa_err, const char *info ) ; + int mbg_win32_last_err_to_mbg( DWORD last_err, const char *info ) ; /** * @brief Translate a Windows socket API error code to one of the @ref MBG_ERROR_CODES * - * @param wsa_err A Windows socket API error code as returned by WSAGetLastError() - * @param info An optional informational text string, or NULL + * @param[in] wsa_err A Windows socket API error code as returned by WSAGetLastError() + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -233,8 +425,8 @@ extern "C" { /** * @brief Translate a POSIX errno error code to one of the @ref MBG_ERROR_CODES * - * @param posix_errno A POSIX error code as usually defined in errno.h - * @param info An optional informational text string, or NULL + * @param[in] posix_errno A POSIX error code as usually defined in errno.h + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -250,8 +442,8 @@ extern "C" { * The functions gethostbyname() and gethostbyaddr() are obsolete, * and getaddressinfo() should be used preferably. * - * @param posix_h_errno An error code as usually defined in netdb.h - * @param info An optional informational text string, or NULL + * @param[in] posix_h_errno An error code as usually defined in netdb.h + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -269,7 +461,7 @@ extern "C" { * code from non-socket POSIX-like functions has to be retrieved * by calling GetLastError(). * - * @param info An optional informational text string, or NULL + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -286,7 +478,7 @@ extern "C" { * has to be retrieved by calling WSAGetLastError, whereas the "last error" * code from non-socket POSIX-like functions is stored in errno as usual. * - * @param info An optional informational text string, or NULL + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ @@ -304,12 +496,24 @@ extern "C" { * The functions gethostbyname() and gethostbyaddr() are obsolete, * and getaddressinfo() should be used preferably. * - * @param info An optional informational text string, or NULL + * @param[in] info An optional informational text string, or NULL * * @return One of the @ref MBG_ERROR_CODES */ int mbg_get_gethostbyname_error( const char *info ) ; + /** + * @brief Retrieve and convert last zlib internal error code + * + * @param[in] zlib_error zlib internal error code + * @param[in] info An optional informational text string, or NULL + * @param[in] msg An optional zlib specific error msg, or NULL. + * Struct z_stream contains member msg. + * + * @return One of the @ref MBG_ERROR_CODES + */ + int mbg_zlib_error_to_mbg( int zlib_error, const char *info, const char *msg ) ; + /* ----- function prototypes end ----- */ diff --git a/mbglib/common/mbgextio.c b/mbglib/common/mbgextio.c index 182d27d..0f57573 100644 --- a/mbglib/common/mbgextio.c +++ b/mbglib/common/mbgextio.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgextio.c 1.20.1.19 2015/07/22 16:02:07Z martin TEST martin $ + * $Id: mbgextio.c 1.20.1.33.1.160 2017/04/12 08:34:53Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -24,7 +24,369 @@ * * ----------------------------------------------------------------------- * $Log: mbgextio.c $ - * Revision 1.20.1.19 2015/07/22 16:02:07Z martin + * Revision 1.20.1.33.1.160 2017/04/12 08:34:53Z martin + * *** empty log message *** + * Revision 1.20.1.33.1.159 2017/04/12 07:34:20 martin + * Fixed build with VC6. + * Revision 1.20.1.33.1.158 2017/04/11 14:28:26Z martin + * Revision 1.20.1.33.1.157 2017/04/11 14:12:49Z martin + * Fixed DOS build. + * Revision 1.20.1.33.1.156 2017/04/11 13:19:41Z martin + * Made mbgextio_setup_receiver_info() more fault tolerant. + * Use function call to retrieve RECEIVER_INFO address + * from message control block. + * Revision 1.20.1.33.1.155 2017/04/10 13:41:55Z martin + * Fixed some compiler warnings. + * Revision 1.20.1.33.1.154 2017/04/10 07:49:07Z martin + * Fixed a compiler warning. + * Revision 1.20.1.33.1.153 2017/04/05 16:06:38 martin + * Added mbgextio_dev_has_bvar_stat(). + * Revision 1.20.1.33.1.152 2017/03/27 10:38:40 thomas-b + * Added functions to read and write PTPv1 common datasets + * Revision 1.20.1.33.1.151 2017/03/20 17:11:07 martin + * Replaced dummy swab...() macro calls by real macros. + * Revision 1.20.1.33.1.150 2017/03/20 10:10:03 martin + * Fixed build without _PRELIMINARY_CODE. + * Revision 1.20.1.33.1.149 2017/03/07 13:45:55 thomas-b + * Added functions to get and set ignore lock + * Revision 1.20.1.33.1.148 2017/03/03 06:46:04 thomas-b + * Added functions to read/write NTP key, server, refclock and orphan mode settings + * Revision 1.20.1.33.1.147 2017/02/23 14:32:08 thomas-b + * *** empty log message *** + * Revision 1.20.1.33.1.146 2017/02/22 08:31:13 thomas-b + * Added functions to read/write event info and read monitoring status and event status + * Revision 1.20.1.33.1.145 2017/02/16 13:01:52 thomas-b + * Changed get and set functions for PTPv2 port dataset to use idx structure + * Revision 1.20.1.33.1.144 2017/02/16 09:27:59 thomas-b + * Fixed doxygen docu + * Revision 1.20.1.33.1.143 2017/02/16 09:24:32 thomas-b + * Added functions to get and set PTPv2 common datasets + * Revision 1.20.1.33.1.142 2017/02/15 16:17:37 martin + * *** empty log message *** + * Revision 1.20.1.33.1.141 2017/02/08 13:12:36 thomas-b + * Added functions to get and set SNMP configuration + * Revision 1.20.1.33.1.140 2017/02/07 14:24:52 thomas-b + * Added function mbgextio_dev_has_monitoring, which checks if the extended feature MBG_XFEATURE_MONITORING is set + * Revision 1.20.1.33.1.139 2017/02/07 14:10:19 daniel + * Added calls to check for new License TLV feature types + * Revision 1.20.1.33.1.138 2016/12/07 09:33:58 martin + * Renamed mbgextio_get_utc_param() to mbgextio_get_utc_parm() + * and mbgextio_set_utc_param() to mbgextio_set_utc_parm() + * for consisten naming with related functions. + * Check if index of received data set matches requested index, and + * keep receiving if not. Only in mbgextio_get_xmr_status_idx() for now. + * Revision 1.20.1.33.1.137 2016/12/01 10:17:27 thomas-b + * Temporarily removed ACK request from GPS_SCU_STAT set command + * Revision 1.20.1.33.1.136 2016/11/30 16:12:54 thomas-b + * Added functions to get/set SCU_STAT_INFO/SCU_STAT_SETTINGS + * Revision 1.20.1.33.1.135 2016/11/24 07:06:34 philipp + * Honour big endian system when swapping bytes + * Revision 1.20.1.33.1.134 2016/11/22 10:33:15 philipp + * Implemented I/O ports + * Revision 1.20.1.33.1.133 2016/11/22 10:28:04 gregoire.diehl + * chk index added in mbgextio_get_xmr_status_idx + * Revision 1.20.1.33.1.132 2016/11/15 15:44:12Z martin + * Account for modified mbgserio functions. + * Revision 1.20.1.33.1.131 2016/11/02 12:15:17 thomas-b + * Added function to check if a device has MBG_XFEATURE_REQ_TTM and adapted the documentation for mbgextio_get_time + * Revision 1.20.1.33.1.130 2016/11/01 07:39:02 thomas-b + * Fixed reception of XBP packets, copy std_msg_data from xbp_msg_data + * Revision 1.20.1.33.1.129 2016/10/31 09:28:06 martin + * Doxygen fixes. + * Revision 1.20.1.33.1.128 2016/10/25 09:11:17 thomas-b + * Added functions to get CFGH, ALM and IONO structures from a device + * Revision 1.20.1.33.1.127 2016/10/24 13:59:42 thomas-b + * Removed needless space from comment + * Fixed mbgextio_rcv_msg_unlocked for reception of XBP packets + * Revision 1.20.1.33.1.126 2016/10/20 14:46:03 thomas-b + * Added function to check if XBP is supported + * Revision 1.20.1.33.1.125 2016/10/20 11:29:10 martin + * Added missing const qualifier in mbgextio_get_utc_param(). + * Revision 1.20.1.33.1.124 2016/10/20 10:43:34 thomas-b + * Added function to check if a device is a bus level device + * Revision 1.20.1.33.1.123 2016/10/19 14:33:43 thomas-b + * Added functions to read and write ucap via network configuration + * Revision 1.20.1.33.1.122 2016/10/14 11:09:40 thomas-b + * Added function to check MBG_XFEATURE_UCAP_NET + * Revision 1.20.1.33.1.121 2016/10/14 08:18:54 thomas-b + * Decreased poll timeout + * Revision 1.20.1.33.1.120 2016/10/12 08:13:27 thomas-b + * Fixed check_init_winsock to return MBG_SUCCESS if WSAStartup returns 0 + * Revision 1.20.1.33.1.119 2016/09/30 05:36:53 thomas-b + * Increased serial poll timeout + * Revision 1.20.1.33.1.118 2016/09/29 14:35:12 thomas-b + * Moved new get and set functions for NET_CFG_API stage 2 to mbgextio + * Revision 1.20.1.33.1.117 2016/09/29 12:19:57 thomas-b + * Added function to check transactions feature + * Revision 1.20.1.33.1.116 2016/09/20 14:18:27 martin + * Fixed a compiler warning. + * Revision 1.20.1.33.1.115 2016/09/20 13:52:38 martin + * Moved GPS_REQACK preprocessor handling to the header file. + * Revision 1.20.1.33.1.114 2016/09/16 08:00:20 thomas-b + * Always try to use high speed baud in mbgextio_open_serial_force_default + * Revision 1.20.1.33.1.113 2016/09/15 10:15:12 philipp + * Fixed compiler warning (uninitialized variable may be used) + * Revision 1.20.1.33.1.112 2016/09/12 15:26:24 martin + * Conditionally try to retrieve serial number from very old devices. + * Revision 1.20.1.33.1.111 2016/09/12 13:42:35Z martin + * *** empty log message *** + * Revision 1.20.1.33.1.110 2016/08/23 15:56:59 martin + * Set up default receiver info for very old devices + * which don't provide it. + * Revision 1.20.1.33.1.109 2016/08/23 11:02:59Z martin + * *** empty log message *** + * Revision 1.20.1.33.1.108 2016/08/23 09:25:17 martin + * *** empty log message *** + * Revision 1.20.1.33.1.107 2016/08/23 08:33:25 udo + * renamed some Time Mon functions + * Revision 1.20.1.33.1.106 2016/08/22 14:14:47 gregoire.diehl + * new call: mbgextio_get_corr_info + * Revision 1.20.1.33.1.105 2016/08/15 09:36:23Z udo + * added mbgextio_time_mon_get_target_ext_data_set_idx() + * Revision 1.20.1.33.1.104 2016/08/11 10:25:53 martin + * Started to support time_mon. + * Revision 1.20.1.33.1.103 2016/08/09 16:00:36 martin + * Removed obsolete string variable. + * Revision 1.20.1.33.1.102 2016/08/09 07:12:26 martin + * *** empty log message *** + * Revision 1.20.1.33.1.101 2016/08/01 10:32:53 daniel + * Add functions to get ptp statistics + * Revision 1.20.1.33.1.100 2016/07/07 15:04:11 martin + * Renamed functions due to renamed library symbols. + * Revision 1.20.1.33.1.99 2016/06/29 11:59:11 philipp + * Extended socket API by TCP client + * Revision 1.20.1.33.1.98 2016/06/15 10:15:49 thomas-b + * Added functions which check if the user capture feature is supported by a device + * Revision 1.20.1.33.1.97 2016/06/14 10:33:21 thomas-b + * Added functions which check if the event log feature is supported by a device + * Revision 1.20.1.33.1.96 2016/06/08 09:55:12 thomas-b + * Added function mbgextio_open_serial_force_default + * Revision 1.20.1.33.1.95 2016/06/07 14:50:33 udo + * Reset Meinberg USB device in case if the open_usb function return MBG_ERR_BUSY + * Revision 1.20.1.33.1.94 2016/06/07 07:43:06 philipp + * New function to check for Irig Rx feature + * Revision 1.20.1.33.1.93 2016/06/03 11:15:49 thomas-b + * Fixed Windows compatibility issues in get_sock_error and mbgextio_find_lan_devices + * Revision 1.20.1.33.1.92 2016/06/02 10:15:38 philipp + * Renaming all MBG_EXT_REV_INFO related stuff to MBG_EXT_SYS_INFO. + * Revision 1.20.1.33.1.91 2016/05/30 08:10:44 thomas-b + * Added functions to check several builtin features + * Revision 1.20.1.33.1.90 2016/05/27 05:18:17 philipp + * New functions mbgextio_get_xmr_ext_source_stats_idx and mbgextio_get_xmr_ext_source_metrics_idx + * Revision 1.20.1.33.1.89 2016/05/25 09:22:58 philipp + * New function mbgextio_get_xmr_ext_source_stats_idx + * Revision 1.20.1.33.1.88 2016/05/20 13:37:53 philipp + * New function mbgextio_set_gpio_settings_idx + * Revision 1.20.1.33.1.87 2016/05/20 09:41:33 thomas-b + * Removed functions which check for a specific IMS card + * Revision 1.20.1.33.1.86 2016/05/20 08:51:19 thomas-b + * Added functions mbgextio_dev_has_time_scale and mbgextio_dev_has_tzcode + * Revision 1.20.1.33.1.85 2016/05/20 07:51:32 thomas-b + * Added function mbgextio_dev_has_tzdl + * Revision 1.20.1.33.1.84 2016/05/20 06:42:06 thomas-b + * Added function mbgextio_dev_has_enable_flags + * Revision 1.20.1.33.1.83 2016/05/18 13:15:40 philipp + * Fixed wrong GPS command in mbgextio_cmd_save_cfg + * Revision 1.20.1.33.1.82 2016/05/17 13:29:35 philipp + * New function to check whether device is LNO + * Revision 1.20.1.33.1.81 2016/05/17 06:33:07 philipp + * New function to check whether a device has serial outputs + * Revision 1.20.1.33.1.80 2016/05/12 10:41:35 philipp + * New functions to check bpe card and IRIG Tx feature + * Revision 1.20.1.33.1.79 2016/05/10 06:15:26 philipp + * New function to check whether a device has programmable pulses + * Revision 1.20.1.33.1.78 2016/05/04 13:04:55 thomas-b + * Fixed double mutex acquisition in dns set functions (NULL pointer) + * Revision 1.20.1.33.1.77 2016/04/26 06:55:45 thomas-b + * Added functions to check if NET_CFG and LAN_IP4 APIs are supported + * Revision 1.20.1.33.1.76 2016/04/25 14:47:13 martin + * *** empty log message *** + * Revision 1.20.1.33.1.75 2016/04/22 10:53:58 philipp + * New function to check whether device is LIU + * Revision 1.20.1.33.1.74 2016/04/20 13:20:25 thomas-b + * Added function to check if a device supports NTP + * Revision 1.20.1.33.1.73 2016/04/20 09:26:11 philipp + * Moved all HPS-PTP related structures to gpspriv.h and removed related extended feature bit from gpsdefs.h. + * Also removed functions from mbgextio and xdevfeat since HPS-PTP handling needs a redesign concerning structures. + * Thus, handle everything explicitly for now! + * -> Redesing this A.S.A.P.!!! + * Revision 1.20.1.33.1.72 2016/04/15 08:17:25 philipp + * New feature MBG_XFEATURE_EXT_PTP + * Revision 1.20.1.33.1.71 2016/04/13 07:01:20 philipp + * New function to check whether device is HPS + * Revision 1.20.1.33.1.70 2016/04/12 13:27:40 philipp + * Several new functions to check for device models and device features + * Revision 1.20.1.33.1.69 2016/04/11 13:56:47 thomas-b + * Added function mbgextio_dev_has_xmulti_ref + * Revision 1.20.1.33.1.68 2016/04/07 14:08:33 philipp + * Added function mbgextio_get_ext_rev_info + * Revision 1.20.1.33.1.67 2016/04/07 12:45:43 martin + * New function mbgextio_dev_has_ext_rev_info(). + * Revision 1.20.1.33.1.66 2016/03/24 14:08:50 martin + * *** empty log message *** + * Revision 1.20.1.33.1.65 2016/03/23 13:49:44 thomas-b + * Added case for overflow error after check_transfer + * Revision 1.20.1.33.1.64 2016/03/23 10:12:52 martin + * *** empty log message *** + * Revision 1.20.1.33.1.63 2016/03/23 09:48:51 thomas-b + * Stop mbgextio_rcv_msg_unlocked after poll_timeout expires + * Several changes in mbgextio_find_lan_devices + * Revision 1.20.1.33.1.62 2016/03/22 14:52:37 thomas-b + * Shutdown socket before close in mbgextio_find_lan_devices + * Revision 1.20.1.33.1.61 2016/03/22 14:24:26 thomas-b + * Several fixes in mbgextio_find_lan_devices + * Revision 1.20.1.33.1.60 2016/03/22 12:53:30 thomas-b + * Added functions to find and free Meinberg LAN devices + * Revision 1.20.1.33.1.59 2016/03/22 08:39:42 thomas-b + * Removed debug output + * Revision 1.20.1.33.1.58 2016/03/22 08:16:16 martin + * *** empty log message *** + * Revision 1.20.1.33.1.57 2016/03/21 13:27:33 martin + * *** empty log message *** + * Revision 1.20.1.33.1.56 2016/03/18 11:21:55 martin + * *** empty log message *** + * Revision 1.20.1.33.1.55 2016/03/18 10:48:32 martin + * *** empty log message *** + * Revision 1.20.1.33.1.54 2016/03/17 11:33:10 philipp + * Added XMR functions + * Revision 1.20.1.33.1.53 2016/03/16 15:08:50 martin + * Moved some low level functions to new module xtiocomm.c. + * Revision 1.20.1.33.1.52 2016/03/14 11:53:15 martin + * Moved some low level feature check functions to new + * module xdevfeat.c, and use those functions. + * Removed function mbgextio_get_xfeature_buffer(). + * Revision 1.20.1.33.1.51 2016/03/11 11:48:18 thomas-b + * Check MBG_SUCCESS with macro mbg_rc_is_success + * Revision 1.20.1.33.1.50 2016/03/11 10:29:03 thomas-b + * Decreased default serial message timeout + * Read more than one byte in each call to serial read + * Increase timeout if header has been completely received + * Revision 1.20.1.33.1.49 2016/03/11 08:20:13 marvin + * Added function to save PTP unicast master settings. + * Revision 1.20.1.33.1.48 2016/03/02 16:31:40Z marvin + * Do not close socket if opened successfully. + * Revision 1.20.1.33.1.47 2016/02/25 12:02:54Z udo + * used mbgextio_req_data_idx instead of mbgextio_req_data for TIME_MON_TARGET_STATUS_IDX + * Revision 1.20.1.33.1.46 2016/02/17 15:03:16 udo + * used MBG_TIME_MON_TARGET_STATUS_IDX + * Revision 1.20.1.33.1.45 2016/02/15 08:28:29 gregoire + * typo fixed + * Revision 1.20.1.33.1.44 2016/02/15 08:23:51Z gregoire + * mbgextio_get_xfeature_buffer_addr added + * Revision 1.20.1.33.1.43 2016/02/11 10:18:47Z thomas-b + * Added function mbgextio_set_fdm_tdev + * Revision 1.20.1.33.1.42 2016/02/03 09:16:48 martin + * *** empty log message *** + * Revision 1.20.1.33.1.41 2016/02/02 15:58:42 martin + * Added mbgextio_get_raw_irig_data(). + * Revision 1.20.1.33.1.40 2016/01/19 14:13:53 udo + * improve time monitor functions + * Revision 1.20.1.33.1.39 2016/01/18 08:53:34 udo + * added support for PTP Time Monitoring on TSU/HPS100 + * Revision 1.20.1.33.1.38 2016/01/04 15:55:07 martin + * New function mbgextio_open_usb_ldev which takes a libusb_device as parameter. + * Revision 1.20.1.33.1.37 2015/12/10 16:30:16 martin + * *** empty log message *** + * Revision 1.20.1.33.1.36 2015/12/10 11:55:14 martin + * *** empty log message *** + * Revision 1.20.1.33.1.35 2015/12/10 11:10:39 martin + * Don't try to read RECEIVER_INFO etc. from legacy USB devices. + * Revision 1.20.1.33.1.34 2015/12/09 17:35:01 martin + * *** empty log message *** + * Revision 1.20.1.33.1.33 2015/12/09 10:45:34 martin + * Revision 1.20.1.33.1.32 2015/12/09 10:21:22Z martin + * *** empty log message *** + * Revision 1.20.1.33.1.31 2015/12/07 16:34:54 martin + * *** empty log message *** + * Revision 1.20.1.33.1.30 2015/12/03 16:00:20 martin + * Also mbgextio_xmt_cmd() and mbgextio_xmt_cmd() now wait for ACK or NACK + * if the transmitted command code has been or'ed with GPS_REQACK. + * Doxygen stuff. + * Revision 1.20.1.33.1.29 2015/12/01 11:54:49 martin + * *** empty log message *** + * Revision 1.20.1.33.1.28 2015/12/01 11:36:01 martin + * *** empty log message *** + * Revision 1.20.1.33.1.27 2015/11/30 17:00:49 martin + * *** empty log message *** + * Revision 1.20.1.33.1.26 2015/11/30 08:16:14 philipp + * Added (wrapper) functions to test for TLV features + * Revision 1.20.1.33.1.25 2015/11/26 16:19:26 martin + * Reworked check feature API causing some other API calls to be + * simplified/changed since receiver info is now stored inside + * the message control block. + * Revision 1.20.1.33.1.24 2015/11/26 09:57:10 martin + * *** empty log message *** + * Revision 1.20.1.33.1.23 2015/11/23 12:55:25 philipp + * Removed TLV functions + * Revision 1.20.1.33.1.21 2015/11/20 10:47:12 daniel + * Removed debug messages + * Revision 1.20.1.33.1.20 2015/11/20 08:14:36 philipp + * Added id member to struct MBG_TLV_ANNOUNCE + * Revision 1.20.1.33.1.19 2015/11/20 07:31:19 philipp + * Added _mbg_swab_tlv macro in function mbgextio_send_tlv_chunk + * Revision 1.20.1.33.1.18 2015/11/20 07:27:37 philipp + * Adjusted functions and prototypes to match new TLV structures from gpsdefs.h + * Revision 1.20.1.33.1.17 2015/11/19 16:31:14 daniel + * Added debug messages + * Revision 1.20.1.33.1.16 2015/11/19 13:15:39 philipp + * Added TLV functionality + * Revision 1.20.1.33.1.15 2015/11/02 10:12:27 martin + * *** empty log message *** + * Revision 1.20.1.33.1.14 2015/10/19 16:42:20 martin + * *** empty log message *** + * Revision 1.20.1.33.1.13 2015/10/19 09:35:10 martin + * *** empty log message *** + * Revision 1.20.1.33.1.12 2015/10/19 09:16:44 martin + * Fixed some spelling. + * Revision 1.20.1.33.1.11 2015/10/15 14:00:57 martin + * Doxygen comments. + * Revision 1.20.1.33.1.10 2015/10/09 11:09:16 martin + * *** empty log message *** + * Revision 1.20.1.33.1.9 2015/10/06 14:19:06 martin + * *** empty log message *** + * Revision 1.20.1.33.1.8 2015/10/02 08:57:44 thomas-b + * Added several functions to retrieve and set parameter structures of the new FDM API + * Revision 1.20.1.33.1.7 2015/10/02 08:18:52 martin + * *** empty log message *** + * Revision 1.20.1.33.1.6 2015/10/01 09:15:56 philipp + * _USE_USB_DIRECT_IO: Return MBG_ERR_TIMEOUT and MBG_ERR_DISCONN if poll times out or holds POLLHUP event after reading data returns + * Revision 1.20.1.33.1.5 2015/09/15 13:25:55 martin + * *** empty log message *** + * Revision 1.20.1.33.1.4 2015/09/14 07:23:32 martin + * *** empty log message *** + * Revision 1.20.1.33.1.3 2015/09/11 12:06:16 martin + * *** empty log message *** + * Revision 1.20.1.33.1.2 2015/09/10 14:45:16 martin + * Unified timeout handling. + * If a NACK is received then accept and return an optional + * error code which may have been appended by the device. + * Revision 1.20.1.33.1.1 2015/09/09 16:00:08 martin + * Debug timing. + * Revision 1.20.1.33 2015/09/09 15:26:13 martin + * Revision 1.20.1.32 2015/09/09 08:41:01 martin + * Revision 1.20.1.31 2015/09/09 08:26:27 martin + * Revision 1.20.1.30 2015/09/09 06:57:51 daniel + * Revision 1.20.1.29 2015/09/08 15:25:48 martin + * Copy received data to destination buffer before + * device mutex is release. + * Revision 1.20.1.28 2015/09/08 14:22:32 martin + * Added some some missing mutex code. + * Use new inline functions mbg_rc_is_error() and mbg_rc_is_success(). + * Revision 1.20.1.27 2015/09/08 12:15:02 martin + * Changed xmt_mutex to dev_mutex. + * Revision 1.20.1.26 2015/09/08 08:38:22 daniel + * Use mutex in mbgextio_req_data() + * Revision 1.20.1.25 2015/09/04 09:20:17 daniel + * Added fuctions to exchange refclock state and tsu version with TSU + * Revision 1.20.1.24 2015/09/02 16:42:20 martin + * Preliminary code which is only included if a preprocessor symbol + * _PRELIMINARY_CODE is defined in the project Makefile. + * Revision 1.20.1.23 2015/08/27 16:21:30 martin + * Revision 1.20.1.22 2015/08/25 15:33:56 martin + * Use safe string copy function from str_util.c. + * Revision 1.20.1.21 2015/08/20 14:50:05 martin + * Revision 1.20.1.20 2015/08/12 15:53:57 martin + * Revision 1.20.1.19 2015/07/22 16:02:07 martin * Started to support variable USB endpoint numbers. * Revision 1.20.1.18 2015/07/14 15:08:43 martin * Unified parameter naming and updated doxygen comments. @@ -156,19 +518,50 @@ #include <mbgextio.h> #undef _MBGEXTIO +#include <xtiocomm.h> +#include <xdevfeat.h> #include <mbgserio.h> +#include <cfg_hlp.h> #include <mbg_arch.h> +#include <mbgerror.h> +#include <gpsutils.h> +#include <str_util.h> + #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <gpsutils.h> -#include <mbgerror.h> +#include <ctype.h> + + +#if !defined( _TRY_IDENT_DECODE ) + #define _TRY_IDENT_DECODE 0 +#endif + +#if _TRY_IDENT_DECODE + #include <identdec.h> +#endif + +#if _USE_SOCKET_IO + #if defined( MBG_TGT_POSIX ) + #include <ifaddrs.h> + #elif defined( MBG_TGT_WIN32 ) + #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 ) // at least up to VC6 + #define VS_MISSING_IPHLPAPI + #endif + + #if !defined( VS_MISSING_IPHLPAPI ) + #include <IPHlpApi.h> + #endif + #endif +#endif #if defined( MBG_TGT_POSIX ) #include <fcntl.h> #include <errno.h> -#else - typedef int ssize_t; +#endif + +#if defined( MBG_TGT_DOS ) + #include <dos.h> #endif #if _USE_USB_IO @@ -179,197 +572,294 @@ #include <poll.h> #endif -#if !defined( _MBGEXTIO_REQ_ACK ) - // If _MBGEXTIO_REQ_ACK is != 0 then mbgextio_...() functions writing - // configuration parameters send the cmd code with the ACK request bit set - // which lets mbgextio_xmt_msg() try to receive a response from the device - // after the parameters have been sent. - #define _MBGEXTIO_REQ_ACK 0 +#if defined( DEBUG ) + #define DEBUG_SOCK_IO 1 + #define DEBUG_FORCE_CONN 1 + #define DEBUG_INIT_CONN 1 +#else + #define DEBUG_SOCK_IO 0 + #define DEBUG_FORCE_CONN 0 + #define DEBUG_INIT_CONN 0 #endif -#if _MBGEXTIO_REQ_ACK - #define OPT_GPS_ACK_CODE GPS_REQACK +#if defined( MBG_TGT_WIN32 ) && _USE_SOCKET_IO + #define _USE_WIN32_CONSOLE_CONTROL_HANDLER 1 #else - #define OPT_GPS_ACK_CODE 0 // dummy + #define _USE_WIN32_CONSOLE_CONTROL_HANDLER 0 #endif -#define DEBUG_SOCK_IO ( 1 && defined( DEBUG ) ) - - // default serial message timeout -#if !defined ( MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL ) - #define MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL 3000 // [ms] +#if !defined( MBGEXTIO_MSG_TIMEOUT_SERIAL ) + #define MBGEXTIO_MSG_TIMEOUT_SERIAL 2000 // [ms] #endif // default serial single character timeout -#if !defined ( MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL ) - #define MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL 200 // [ms] +#if !defined( MBGEXTIO_POLL_TIMEOUT_SERIAL ) + #define MBGEXTIO_POLL_TIMEOUT_SERIAL 200 // [ms] #endif +// default USB message timeout +#if !defined( MBGEXTIO_MSG_TIMEOUT_USB ) + #define MBGEXTIO_MSG_TIMEOUT_USB 100 // [ms] +#endif -static const char force_conn_cmd_str[] = MBG_FORCE_CONN_CMD_STR; -static const char force_conn_hs_cmd_str[] = MBG_FORCE_CONN_HS_CMD_STR; - +// default USB character timeout, same as message timeout +#if !defined( MBGEXTIO_POLL_TIMEOUT_USB ) + #define MBGEXTIO_POLL_TIMEOUT_USB MBGEXTIO_MSG_TIMEOUT_USB +#endif -typedef struct -{ - int model_code; - long feature_mask; -} BUILTIN_FEATURE_TABLE_ENTRY; -static BUILTIN_FEATURE_TABLE_ENTRY builtin_feature_table[] = GPS_MODEL_BUILTIN_FEATURES; +static const char force_conn_cmd_str[] = MBG_FORCE_CONN_CMD_STR; +static const char force_conn_hs_cmd_str[] = MBG_FORCE_CONN_HS_CMD_STR; -static /*HDR*/ /** - * @brief Deallocate a message control structure + * @brief Binary message control device flags * - * Free the memory allocated for a message control structure - * and set the pointer to NULL. + * Used to define ::MSG_CTL_DEVICE_FLAG_MSKS * - * @param[in,out] ppmctl Address of a pointer to a message control structure + * @see ::MSG_CTL_DEVICE_FLAG_MSKS + */ +enum MSG_CTL_DEVICE_FLAGS +{ + MSG_CTL_DEVICE_FLAG_LEGACY, ///< legacy device with proprietary protocol, see ::mbgextio_dev_is_legacy + N_MSG_CTL_DEVICE_FLAGS +}; + + + +/** + * @brief Binary message control device flag masks * - * @see ::alloc_msg_ctl + * Used with ::MBG_MSG_CTL::device_flags */ -void dealloc_msg_ctl( MBG_MSG_CTL **ppmctl ) +enum MSG_CTL_DEVICE_FLAG_MSKS { - MBG_MSG_CTL *pmctl = *ppmctl; + MSG_CTL_DEVICE_FLAG_MSK_LEGACY = ( 1UL << MSG_CTL_DEVICE_FLAG_LEGACY ) ///< see ::MSG_CTL_DEVICE_FLAG_LEGACY +}; + - if ( pmctl ) + +//### TODO proper header / prototype +/*HDR*/ +const char *mbgextio_get_cmd_name( GPS_CMD cmd_code ) +{ + return xtiocomm_get_cmd_name( cmd_code ); + +} // mbgextio_get_cmd_name + + + +#if _USE_WIN32_CONSOLE_CONTROL_HANDLER + +static /*HDR*/ +BOOL WINAPI mbgextio_on_console_event( DWORD dwCtrlType ) +{ + switch ( dwCtrlType ) { - if ( pmctl->rcv.pmb ) - { - free( pmctl->rcv.pmb ); - pmctl->rcv.pmb = NULL; - } + case CTRL_BREAK_EVENT: + case CTRL_C_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_SHUTDOWN_EVENT: + exit( 0 ); - pmctl->rcv.buf_size = 0; + } // switch + + return FALSE; + +} // mbgextio_on_console_event - if ( pmctl->xmt.pmb ) - { - free( pmctl->xmt.pmb ); - pmctl->xmt.pmb = NULL; - } - pmctl->xmt.buf_size = 0; - free( pmctl ); - *ppmctl = NULL; +static /*HDR*/ +void mbgextio_set_console_control_handler( void ) +{ + static int has_been_set; + + if ( !has_been_set ) + { + SetConsoleCtrlHandler( mbgextio_on_console_event, TRUE ); + has_been_set = 1; } -} // dealloc_msg_ctl +} // mbgextio_set_console_control_handler + +#endif // _USE_WIN32_CONSOLE_CONTROL_HANDLER + +#if _USE_USB_IO static /*HDR*/ /** - * @brief Allocate a message control structure - * - * Allocate memory for a message control structure and associated - * message receive and transmit buffers. + * @brief Check if a USB device is a legacy device which doesn't support the binary protocol * - * @param[out] ppmctl Address of a pointer to a message control structure to be allocated, set to NULL on error + * There are some legacy USB devices which only support a proprietary protocol + * instead of the standard binary protocol. + * We try to find this out based on the USB vendor and device IDs, and we need + * to check this *before* we call any of the standard API functions, since otherwise + * a binary message sent to the device may have unpredictable side-effects. * - * @return ::MBG_SUCCESS or one of the @ref MBG_ERROR_CODES + * @param[in] mdev An ::MBGUSBIO_DEV handle of the device + * @param[out] p_ri Pointer to a ::RECEIVER_INFO to be set up, or NULL * - * @see ::dealloc_msg_ctl + * @return One of the @ref MBG_RETURN_CODES */ -int alloc_msg_ctl( MBG_MSG_CTL **ppmctl ) +int check_setup_legacy_usb_device( const MBG_USB_DEV_INFO *mdev_info, RECEIVER_INFO *p_ri ) { - int rc = MBG_ERR_UNSPEC; - - MBG_MSG_CTL *pmctl = malloc( sizeof( *pmctl ) ); + int model_code = GPS_MODEL_UNKNOWN; + const char *model_name = str_unknown; - if ( pmctl == NULL ) + if ( mdev_info->ven_id == USB_VENDOR_MEINBERG ) { - #if defined( DEBUG ) - fprintf( stderr, "failed to malloc control block in %s\n", __func__ ); - #endif - goto fail; - } + switch ( mdev_info->prod_id ) + { + case USB_DEV_CPC_01: + model_code = GPS_MODEL_CPC_01; + model_name = GPS_MODEL_NAME_CPC_01; + break; + + case USB_DEV_CPC180: + model_code = GPS_MODEL_CPC180; + model_name = GPS_MODEL_NAME_CPC180; + break; - memset( pmctl, 0, sizeof( *pmctl ) ); + case USB_DEV_TSU_01: + model_code = GPS_MODEL_TSU_01; + model_name = GPS_MODEL_NAME_TSU_01; + break; - // allocate receive buffer - pmctl->rcv.buf_size = sizeof( *(pmctl->rcv.pmb) ); - pmctl->rcv.pmb = malloc( pmctl->rcv.buf_size ); + case USB_DEV_CMC: + model_code = GPS_MODEL_CMC_01; + model_name = GPS_MODEL_NAME_CMC_01; + break; - if ( pmctl->rcv.pmb == NULL ) - { - #if defined( DEBUG ) - fprintf( stderr, "failed to malloc rcv buffer in %s\n", __func__ ); - #endif - goto fail; - } + case USB_DEV_SCU_USB: + model_code = GPS_MODEL_SCU_01; + model_name = GPS_MODEL_NAME_SCU_01; + break; - // allocate transmit buffer - pmctl->xmt.buf_size = sizeof( *(pmctl->xmt.pmb) ); - pmctl->xmt.pmb = malloc( pmctl->xmt.buf_size ); + case USB_DEV_FCU_01: + model_code = GPS_MODEL_FCU_01; + model_name = GPS_MODEL_NAME_FCU_01; + break; - if ( pmctl->xmt.pmb == NULL ) - { - #if defined( DEBUG ) - fprintf( stderr, "failed to malloc xmt buffer in %s\n", __func__ ); + #if 0 // //### TODO check these device, they probably do support binary + case USB_DEV_SDI_01: + model_code = GPS_MODEL_UNKNOWN; + model_name = str_unknown; + break; + + case USB_DEV_MDU300: + model_code = GPS_MODEL_MDU300; + model_name = str_unknown; + break; #endif - goto fail; + } } + #if DEBUG + fprintf( stderr, "Checking for legacy USB device %04X:%04X: %s, code %i\n", + mdev_info->ven_id, mdev_info->ven_id, model_name, model_code ); + #endif - // buffers allocated successfully - rc = MBG_SUCCESS; - goto out; + if ( model_code == GPS_MODEL_UNKNOWN ) + return MBG_ERR_DEV_NOT_SUPP; + if ( p_ri ) + { + memset( p_ri, 0, sizeof( *p_ri ) ); -fail: // if not all memory blocks could be allocated, clean up - dealloc_msg_ctl( &pmctl ); // also sets pmctl to NULL - rc = MBG_ERR_NO_MEM; + p_ri->model_code = model_code; + sn_cpy_str_safe( p_ri->model_name, sizeof( p_ri->model_name ), model_name ); + p_ri->ticks_per_sec = DEFAULT_GPS_TICKS_PER_SEC; + } -out: - *ppmctl = pmctl; - return rc; + return MBG_SUCCESS; -} // alloc_msg_ctl +} // check_setup_legacy_usb_device +#endif // _USE_USB_IO -#if defined( MBG_TGT_WIN32 ) && _USE_SOCKET_IO static /*HDR*/ -BOOL WINAPI mbgextio_on_console_event( DWORD dwCtrlType ) +/** + * @brief Set up some extended device info for a device which has just been opened + * + * This function should be after a device has been opened successfully to read + * some extended information which is stored in (and can be retrieved from) + * the message control structure. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return One of the @ref MBG_RETURN_CODES + */ +int setup_extended_device_info( MBG_MSG_CTL *pmctl ) { - switch ( dwCtrlType ) + MBG_XDEV_FEATURES *p_xdf = &pmctl->xdev_features; + int rc; + + memset( p_xdf, 0, sizeof( *p_xdf ) ); + + // Get the receiver info first. + rc = mbgextio_setup_receiver_info( pmctl, NULL, &p_xdf->receiver_info ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + // If the device supports extended features then read the + // extended feature buffer from the device, else clear extended features. + if ( p_xdf->receiver_info.features & GPS_HAS_XFEATURE ) { - case CTRL_BREAK_EVENT: - case CTRL_C_EVENT: - case CTRL_CLOSE_EVENT: - case CTRL_SHUTDOWN_EVENT: - exit( 0 ); + rc = mbgextio_req_data( pmctl, NULL, GPS_XFEATURES, &p_xdf->xfeature_buffer, sizeof( p_xdf->xfeature_buffer ) ); + //### TODO use special API call? + } - } // switch +#if defined( _PRELIMINARY_CODE ) - return FALSE; + // If the device supports TLVs then read the TLV info and supported TLV + // features from the device, else clear the structure. + if ( mbg_rc_is_success( xdevfeat_has_tlv_api( p_xdf ) ) ) + { + rc = mbgextio_req_data( pmctl, NULL, GPS_TLV_INFO, &p_xdf->tlv_info, sizeof( p_xdf->tlv_info ) ); + //### TODO use special API call? + } -} // mbgextio_on_console_event +#endif // defined( _PRELIMINARY_CODE ) + +out: + return rc; + +} // setup_extended_device_info static /*HDR*/ -void mbgextio_set_console_control_handler( void ) +//### TODO +int dev_open_finish_setup( MBG_MSG_CTL **ppmctl, MBG_MSG_CTL **caller_ppmctl ) { - static int has_been_set; + int rc; - if ( !has_been_set ) - { - SetConsoleCtrlHandler( mbgextio_on_console_event, TRUE ); - has_been_set = 1; - } + #if _USE_WIN32_CONSOLE_CONTROL_HANDLER + mbgextio_set_console_control_handler(); + #endif -} // mbgextio_set_console_control_handler + #if _USE_MUTEX + _mbg_mutex_init( &(*ppmctl)->dev_mutex ); + #endif + + rc = setup_extended_device_info( *ppmctl ); + + if ( mbg_rc_is_error( rc ) ) + return dev_open_fail_close( rc, ppmctl, caller_ppmctl ); + + return dev_open_finish( rc, *ppmctl, caller_ppmctl ); -#endif // defined MBG_TGT_WIN32 +} // dev_open_finish_setup @@ -457,7 +947,7 @@ int get_sock_error( MBG_SOCK_FD sock_fd ) { int so_err = 0; socklen_t so_err_sz = sizeof( so_err ); - int rc = getsockopt( sock_fd, SOL_SOCKET, SO_ERROR, (void *) &so_err, &so_err_sz ); // returns 0 on success + int rc = getsockopt( sock_fd, SOL_SOCKET, SO_ERROR, (char *) &so_err, &so_err_sz ); // returns 0 on success if ( rc != 0 ) // error { @@ -603,42 +1093,362 @@ out: } // wait_nonblocking_socket_ready +#if defined( MBG_TGT_WIN32 ) -static /*HDR*/ /** - * @brief Close a socket and make the socket descriptor invalid + * @brief Cleans up the winsock lib by calling WSACleanup + * + * This function is automatically called at the exit of a program. + * It is registered in ::check_init_winsock * - * @param[in,out] pmctl Pointer to a valid message control structure containing the socket descriptor + * @see ::check_init_winsock + */ +void deinit_winsock( void ) +{ + WSACleanup( ); +} + + +/** + * @brief Checks if the winsock lib has been initialized before and initializes it if not * * @return One of the @ref MBG_RETURN_CODES */ -int socket_close( MBG_MSG_CTL *pmctl ) +int check_init_winsock( void ) { - int rc; + static bool wsa_init; + int rc = MBG_SUCCESS; - #if defined( MBG_TGT_CVI ) || defined( MBG_TGT_WIN32 ) - rc = closesocket( pmctl->st.sockio.sockfd ); // returns 0 on success - #elif defined( MBG_TGT_POSIX ) - rc = close( pmctl->st.sockio.sockfd ); // returns 0 on success - #else - #error close socket needs to be implemented for this target - #endif + if( !wsa_init ) + { + WORD wVersionRequested = MAKEWORD( 2, 2 ); + WSADATA wsaData; + + rc = WSAStartup( wVersionRequested, &wsaData ); + if ( rc != 0 ) + rc = mbg_win32_wsa_err_to_mbg( rc , NULL ); + else rc = MBG_SUCCESS; - pmctl->st.sockio.sockfd = MBG_INVALID_SOCK_FD; + if( mbg_rc_is_success( rc ) ) + { + wsa_init = true; + atexit( deinit_winsock ); + } + + } - if ( rc != 0 ) + return rc; +} + +#endif // defined( MBG_TGT_WIN32 ) + + +/*HDR*/ +/** + * @brief Sets up a list of all available Meinberg LAN devices in the network + * + * List entries will be allocated and have to be freed by calling ::mbgextio_free_lan_devices + * + * @param[out] list Pointer to the list + * @param[in] timeout_ms Timeout in ms for each network interface + * + * @return One of the @ref MBG_RETURN_CODES or the number of found devices on success + * + * @see ::mbgextio_free_lan_devices + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_find_lan_devices( MBG_LAN_DEV_LIST **list, uint16_t timeout_ms ) +{ +#if defined( VS_MISSING_IPHLPAPI ) + return MBG_ERR_NOT_SUPP_ON_OS; +#else + struct sockaddr_in src_addr = { 0 }; + struct sockaddr_in bcast_addr = { 0 }; + struct sockaddr_in global_bcast_addr = { 0 }; + MBG_LAN_DEV_LIST *list_head = NULL; + MBG_LAN_DEV_LIST *curr_entry = NULL; + MBG_LAN_DEV_LIST *tmp_entry; + const uint32_t query = htonl( MBG_LAN_REQUEST_CONFIG ); + socklen_t addr_len = sizeof ( struct sockaddr_in ); + struct in_addr src_in_addr = { 0 }; + struct in_addr broad_in_addr = { 0 }; + struct timeval select_timeout; + int opt = 1; + int rc = MBG_SUCCESS; + MBG_SOCK_FD sock = MBG_INVALID_SOCK_FD; + MBG_TMO_TIME t_end; + MBG_TMO_TIME t_now; + MBG_LAN_DEV_CFG buf; + fd_set socks; + bool found; + +#if defined( MBG_TGT_POSIX ) + + struct ifaddrs *ifaddr = NULL, *ifa; + +#elif defined( MBG_TGT_WIN32 ) + + PIP_ADAPTER_ADDRESSES pAdptAddrs, pAdptAddr; + PIP_ADAPTER_UNICAST_ADDRESS pUnicastAddr; + ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; + unsigned long adptAddrsBuflen = sizeof( IP_ADAPTER_ADDRESSES ); + uint8_t prefix; + +#endif + + global_bcast_addr.sin_family = AF_INET; + global_bcast_addr.sin_addr.s_addr = htonl( INADDR_BROADCAST ); + global_bcast_addr.sin_port = htons( MBG_LAN_UDP_BROADCAST_PORT ); + + bcast_addr.sin_family = AF_INET; + bcast_addr.sin_port = htons( MBG_LAN_UDP_BROADCAST_PORT ); + +#if defined( MBG_TGT_POSIX ) + + if ( getifaddrs( &ifaddr ) == 0 ) { - rc = mbg_get_last_socket_error( "failed to close socket socket_close" ); - goto out; + for ( ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next ) + { + if ( ifa->ifa_addr && ( ifa->ifa_addr->sa_family == AF_INET ) ) + { + src_in_addr.s_addr = ( (struct sockaddr_in *) ifa->ifa_addr )->sin_addr.s_addr; + + if ( ifa->ifa_broadaddr ) + broad_in_addr = ( (struct sockaddr_in *) ifa->ifa_broadaddr )->sin_addr; + +#elif defined( MBG_TGT_WIN32 ) + + rc = check_init_winsock(); + if( mbg_rc_is_error( rc ) ) + return rc; + + pAdptAddrs = (PIP_ADAPTER_ADDRESSES) malloc( sizeof( IP_ADAPTER_ADDRESSES ) ); + + if ( !pAdptAddrs ) + return MBG_ERR_NO_MEM; + + rc = GetAdaptersAddresses( AF_INET, flags, NULL, pAdptAddrs, &adptAddrsBuflen ); + if ( rc == ERROR_BUFFER_OVERFLOW ) + { + free( pAdptAddrs ); + pAdptAddrs = (PIP_ADAPTER_ADDRESSES) malloc( adptAddrsBuflen ); + if ( !pAdptAddrs ) + return MBG_ERR_NO_MEM; + rc = GetAdaptersAddresses( AF_INET, flags, NULL, pAdptAddrs, &adptAddrsBuflen ); } - rc = MBG_SUCCESS; + if ( rc == NO_ERROR ) + { + for ( pAdptAddr = pAdptAddrs; pAdptAddr != NULL; pAdptAddr = pAdptAddr->Next ) + { + if ( pAdptAddr->OperStatus != IfOperStatusUp ) + continue; + + for ( pUnicastAddr = pAdptAddr->FirstUnicastAddress; pUnicastAddr != NULL; pUnicastAddr = pUnicastAddr->Next ) + { + if ( pUnicastAddr->Address.lpSockaddr->sa_family != AF_INET ) + continue; + + src_in_addr.s_addr = ( (struct sockaddr_in *) pUnicastAddr->Address.lpSockaddr )->sin_addr.s_addr; + + broad_in_addr = src_in_addr; + for( prefix = pUnicastAddr->OnLinkPrefixLength; prefix < 32; prefix++ ) + broad_in_addr.s_addr |= ( 1UL << prefix ); + +#endif + + if ( ntohl( src_in_addr.s_addr ) == INADDR_LOOPBACK ) + continue; + + sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + + if ( sock >= 0 ) + { + mbg_tmo_get_time( &t_end ); + mbg_tmo_add_ms( &t_end, timeout_ms ); + + src_addr.sin_family = AF_INET; + src_addr.sin_addr.s_addr = src_in_addr.s_addr; + + bcast_addr.sin_addr.s_addr = broad_in_addr.s_addr; + + if ( ( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (const char*) &opt, sizeof( opt ) ) == 0 ) && + ( bind( sock, (const struct sockaddr *) &src_addr, addr_len ) == 0 ) ) + { + if ( ( sendto( sock, (char *) &query, sizeof( query ), 0, (struct sockaddr *) &global_bcast_addr, addr_len ) == sizeof( query ) ) && + ( sendto( sock, (char *) &query, sizeof( query ), 0, (struct sockaddr *) &bcast_addr, addr_len ) == sizeof( query ) ) ) + { + while ( 1 ) + { + FD_ZERO( &socks ); + FD_SET( sock, &socks ); + + mbg_tmo_get_time( &t_now ); + if ( mbg_tmo_time_is_after( &t_now, &t_end ) ) + break; + mbg_msec_to_timeval( mbg_tmo_time_diff_ms( &t_end, &t_now ), &select_timeout ); + + addr_len = sizeof( struct sockaddr_in ); + + // The first parameter for select() is always an int, but sock + // is not an int in Windows, but always in POSIX. Since the parameter + // is ignored in windows anyway, it's safe to cast it to an int + // to avoid compiler warnings. + if( select( (int) ( sock + 1 ), &socks, NULL, NULL, &select_timeout ) > 0 ) + { + if( recvfrom( sock, (char *) &buf, sizeof( buf ), 0, (struct sockaddr *) &src_addr, &addr_len ) >= sizeof( buf ) ) + { + if( ( ntohl( buf.command ) == MBG_LAN_RESPOND_CONFIG ) && + ( ( ntohs( buf.channel_0.own_tcp_port ) == LAN_XPT_PORT ) || + ( buf.channel_0.own_tcp_port == LAN_XPT_PORT ) ) ) + { + found = false; + + if ( list_head ) + { + tmp_entry = list_head; + while( tmp_entry && !found ) + { + if( tmp_entry->config.ip_address == ntohl( src_addr.sin_addr.s_addr ) ) + found = true; + tmp_entry = tmp_entry->next; + } + } + + if ( !found ) + { + if ( curr_entry ) + { + curr_entry->next = (MBG_LAN_DEV_LIST *) malloc( sizeof( *curr_entry->next ) ); + if ( !curr_entry->next ) + { + rc = MBG_ERR_NO_MEM; + goto cleanup_and_return; + } + curr_entry = curr_entry->next; + } + else + { + curr_entry = (MBG_LAN_DEV_LIST *) malloc( sizeof( *curr_entry ) ); + if( !curr_entry ) + { + rc = MBG_ERR_NO_MEM; + goto cleanup_and_return; + } + list_head = curr_entry; + } + + memset( curr_entry, 0, sizeof( *curr_entry ) ); + curr_entry->config = buf; + curr_entry->config.ip_address = ntohl( src_addr.sin_addr.s_addr ); + rc++; + } + } + } + } + else + break; + } + } + else + { + rc = MBG_ERR_NBYTES; + goto cleanup_and_return; + } + } + else + { + rc = MBG_ERR_INV_SOCK_FD; + goto cleanup_and_return; + } + +#if defined( MBG_TGT_POSIX ) + + shutdown( sock, SHUT_RDWR ); + close( sock ); + +#elif defined( MBG_TGT_WIN32 ) + + shutdown( sock, SD_BOTH ); + closesocket( sock ); + +#endif + sock = -1; + } + else + { + rc = MBG_ERR_INV_SOCK_FD; + goto cleanup_and_return; + } + } + } + } + else + rc = MBG_ERR_GENERIC; + +cleanup_and_return: + +#if defined( MBG_TGT_POSIX ) + + if ( ifaddr ) + freeifaddrs( ifaddr ); + + if ( sock >= 0 ) + { + shutdown( sock, SHUT_RDWR ); + close( sock ); + } + +#elif defined( MBG_TGT_WIN32 ) + + if ( pAdptAddrs ) + free( pAdptAddrs ); + + if ( sock >= 0 ) + { + shutdown( sock, SD_BOTH ); + closesocket( sock ); + } + +#endif + + if ( rc <= 0 ) + { + mbgextio_free_lan_devices( list_head ); + list_head = NULL; + } + + *list = list_head; -out: return rc; +#endif +} -} // socket_close +/*HDR*/ +/** + * @brief Frees the ::MBG_LAN_DEV_LIST allocated by ::mbgextio_find_lan_devices + * + * @param[in] list The list that will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_find_lan_devices + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_free_lan_devices( MBG_LAN_DEV_LIST *list ) +{ + if( list ) + { + MBG_LAN_DEV_LIST *next_entry = list; + while( next_entry ) + { + list = next_entry; + next_entry = list->next; + free( list ); + } + return MBG_SUCCESS; + } + return MBG_ERR_INV_PARM; +} static /*HDR*/ @@ -658,26 +1468,15 @@ int socket_init( MBG_MSG_CTL *pmctl, const char *host ) int sz; int rc = MBG_ERR_UNSPEC; - //##++++++++ should use getaddrinfo() preferably - hp = gethostbyname( host ); - - #if defined( MBG_TGT_WIN32 ) - // Under Windows the winsock2.dll may not yet have been initialized, - // so initialize now and try once more. - if ( hp == NULL ) - { - WORD wVersionRequested; - WSADATA wsaData; +#if defined( MBG_TGT_WIN32 ) + rc = check_init_winsock( ); - wVersionRequested = MAKEWORD( 2, 2 ); - - rc = WSAStartup( wVersionRequested, &wsaData ); + if( !mbg_rc_is_success( rc ) ) + goto out; +#endif - // If initialization has succeeded, try once more. - if ( rc == 0 ) - hp = gethostbyname( host ); - } - #endif // defined( MBG_TGT_WIN32 ) + //##++++++++ should use getaddrinfo() preferably + hp = gethostbyname( host ); if ( hp == NULL ) // error { @@ -699,12 +1498,12 @@ int socket_init( MBG_MSG_CTL *pmctl, const char *host ) // which is offline. rc = set_socket_blocking_mode( pmctl->st.sockio.sockfd, 0 ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) goto out_close; // Now try to connect to the socket. - paddr = &pmctl->st.sockio.addr; + paddr = &pmctl->st.sockio._addr; memset( paddr, 0, sizeof( *paddr ) ); memcpy( &paddr->sin_addr, hp->h_addr, hp->h_length ); @@ -747,14 +1546,17 @@ int socket_init( MBG_MSG_CTL *pmctl, const char *host ) rc = wait_nonblocking_socket_ready( pmctl->st.sockio.sockfd, 1500 ); //##++++++++++++ - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) goto out_close; } // Set the socket back to blocking mode. rc = set_socket_blocking_mode( pmctl->st.sockio.sockfd, 1 ); - if ( rc == MBG_SUCCESS ) + pmctl->st.sockio.p_addr = &pmctl->st.sockio._addr; + pmctl->st.sockio.addrlen = sizeof( pmctl->st.sockio._addr ); + + if ( mbg_rc_is_success( rc ) ) goto out; // error, fall through and close socket @@ -790,18 +1592,22 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_secu_settings( MBG_MSG_CTL *pmctl, co { MBG_MSG_BUFF *pmb; SECU_SETTINGS *pss = &pmctl->secu_settings; - GPS_CMD cmd = GPS_SECU_SETTINGS; // GPS_REQACK is not supported by LAN_XPT, so omit it + GPS_CMD cmd = GPS_SECU_SETTINGS; // GPS_REQACK is not supported by LAN_XPT, so never use it int rc = MBG_ERR_UNSPEC; + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + memset( pss, 0, sizeof *pss ); - strncpy( pss->password, old_passwd, sizeof( pss->password ) ); + strncpy_safe( pss->password, old_passwd, sizeof( pss->password ) ); set_encryption_mode( pmctl, MBG_XFER_MODE_ENCRYPTED, pss->password ); if ( new_passwd ) { if ( strlen( new_passwd ) > 0 ) - strncpy( pss->new_password, new_passwd, sizeof( pss->new_password ) ); + strncpy_safe( pss->new_password, new_passwd, sizeof( pss->new_password ) ); pss->flags |= MSK_FLAG_CHANGE_PASSWORD; } @@ -811,16 +1617,16 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_secu_settings( MBG_MSG_CTL *pmctl, co pmb->hdr.cmd = cmd; pmb->hdr.len = sizeof( pmb->u.msg_data.secu_settings ); - rc = xmt_tbuff( pmctl, NULL ); //##++++++++++++++ TODO Use mbgextio_req_data instead? Is NULL OK? + rc = xmt_tbuff( pmctl, NULL ); //### TODO Use mbgextio_req_data instead? Is NULL OK? - if ( rc != MBG_SUCCESS ) // error + if ( mbg_rc_is_error( rc ) ) goto out; - rc = mbgextio_rcv_msg( pmctl, NULL, cmd ); //##++++++++++++++ TODO Is NULL OK? + rc = mbgextio_rcv_msg_unlocked( pmctl, NULL, cmd, NULL, 0 ); //### TODO Is XBP_ADDR NULL OK? // With some devices a timeout may also occur // if a wrong password has been used. - if ( rc != MBG_SUCCESS ) // error + if ( mbg_rc_is_error( rc ) ) goto out; cmd = pmctl->rcv.pmb->hdr.cmd; @@ -836,6 +1642,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_secu_settings( MBG_MSG_CTL *pmctl, co rc = MBG_SUCCESS; out: + #if _USE_MUTEX + _mbg_mutex_release( &pmctl->dev_mutex ); + #endif + return rc; } // mbgextio_xmt_secu_settings @@ -860,58 +1670,66 @@ out: * @see ::mbgextio_open_usb_direct_io * @see ::mbgextio_close_connection */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_open_socket( const char *host, MBG_MSG_CTL **ppmctl, const char *passwd ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_open_socket( const char *host, + MBG_MSG_CTL **ppmctl, const char *passwd ) { MBG_MSG_CTL *pmctl; int rc = alloc_msg_ctl( &pmctl ); - if ( rc != MBG_SUCCESS ) - goto out; - - - pmctl->conn_type = MBG_CONN_TYPE_SOCKET; - pmctl->msg_rcv_timeout = MBGEXTIO_RCV_TIMEOUT_SOCKET; - // pmctl->char_rcv_timeout is not used with sockets + if ( mbg_rc_is_error( rc ) ) + return dev_open_finish( rc, pmctl, ppmctl ); rc = socket_init( pmctl, host ); - if ( rc != MBG_SUCCESS ) - goto fail_free; + if ( mbg_rc_is_error( rc ) ) + return dev_open_fail_free( rc, &pmctl, ppmctl ); + + dev_open_init( pmctl, MBG_CONN_TYPE_SOCKET, MBGEXTIO_MSG_TIMEOUT_SOCKET, + MBGEXTIO_POLL_TIMEOUT_SOCKET ); rc = mbgextio_xmt_secu_settings( pmctl, NULL, passwd, NULL ); - if ( rc != MBG_SUCCESS ) - goto fail_close; + if ( mbg_rc_is_error( rc ) ) + return dev_open_fail_close( rc, &pmctl, ppmctl ); - #if defined( MBG_TGT_WIN32 ) - mbgextio_set_console_control_handler(); - #endif + return dev_open_finish_setup( &pmctl, ppmctl ); - #if _USE_MUTEX - _mbg_mutex_init( &pmctl->xmt.xmt_mutex ); - #endif +} // mbgextio_open_socket - rc = MBG_SUCCESS; - goto out; +#endif // _USE_SOCKET_IO -fail_close: - socket_close( pmctl ); -fail_free: - dealloc_msg_ctl( &pmctl ); -out: - *ppmctl = pmctl; +#if _USE_SERIAL_IO - return rc; +/*HDR*/ +int mbgextio_open_serial_raw( const char *dev, MBG_MSG_CTL **ppmctl, + uint32_t baud_rate, const char *framing ) +{ + MBG_MSG_CTL *pmctl; + int rc = alloc_msg_ctl( &pmctl ); -} // mbgextio_open_socket + if ( mbg_rc_is_error( rc ) ) + return dev_open_finish( rc, pmctl, ppmctl ); -#endif // _USE_SOCKET_IO + rc = mbgserio_open( &pmctl->st.p_serio, dev ); + if ( mbg_rc_is_error( rc ) ) + return dev_open_fail_free( rc, &pmctl, ppmctl ); + + dev_open_init( pmctl, MBG_CONN_TYPE_SERIAL, MBGEXTIO_MSG_TIMEOUT_SERIAL, + MBGEXTIO_POLL_TIMEOUT_SERIAL ); + + rc = mbgserio_set_parms( pmctl->st.p_serio, baud_rate, framing ); + + if ( mbg_rc_is_error( rc ) ) + return dev_open_fail_close( rc, &pmctl, ppmctl ); + + return dev_open_finish( rc, pmctl, ppmctl ); + +} // mbgextio_open_serial_raw -#if _USE_SERIAL_IO /*HDR*/ /** @@ -944,42 +1762,110 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial( const char *dev, MBG_MSG_CTL MBG_MSG_CTL *pmctl; int rc = alloc_msg_ctl( &pmctl ); - if ( rc != MBG_SUCCESS ) - goto out; + if ( mbg_rc_is_error( rc ) ) + return dev_open_finish( rc, pmctl, ppmctl ); + rc = mbgserio_open( &pmctl->st.p_serio, dev ); - pmctl->conn_type = MBG_CONN_TYPE_SERIAL; - pmctl->msg_rcv_timeout = MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL; - pmctl->char_rcv_timeout = MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL; + if ( mbg_rc_is_error( rc ) ) + return dev_open_fail_free( rc, &pmctl, ppmctl ); - rc = mbgserio_open( &pmctl->st.serio, dev ); + dev_open_init( pmctl, MBG_CONN_TYPE_SERIAL, MBGEXTIO_MSG_TIMEOUT_SERIAL, + MBGEXTIO_POLL_TIMEOUT_SERIAL ); - if ( rc != MBG_SUCCESS ) - goto fail_free; + rc = mbgserio_set_parms( pmctl->st.p_serio, baud_rate, framing ); - rc = mbgserio_set_parms( &pmctl->st.serio, baud_rate, framing ); + if ( mbg_rc_is_error( rc ) ) + return dev_open_fail_close( rc, &pmctl, ppmctl ); - if ( rc != MBG_SUCCESS ) - goto fail_free; + return dev_open_finish_setup( &pmctl, ppmctl ); - #if _USE_MUTEX - _mbg_mutex_init( &pmctl->xmt.xmt_mutex ); - #endif +} // mbgextio_open_serial - rc = MBG_SUCCESS; - goto out; -fail_free: - dealloc_msg_ctl( &pmctl ); +/*HDR*/ +/** + * @brief Open a binary communication channel forcing default serial parameters + * + * If current serial paramaters (baud rate and framing) do not match the default + * parameters for binary communication then the serial device is forced into + * binary communication mode. + * + * @param[in] dev Name of the serial port to which the device is connected, + * depending on the naming conventions of the host system. + * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure + * allocated and set up by this call. Set to NULL on error. + * @param[in] baud_rate Baud rate used for serial communication + * @param[in] framing Framing used for serial communication + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_open_serial + * @see ::mbgextio_open_serial_raw + * @see ::mbgserio_write + * @see ::mbgextio_close_connection + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial_force_default( const char *dev, MBG_MSG_CTL **ppmctl, uint32_t baud_rate, const char *framing ) +{ + const char* cmd_str = force_conn_hs_cmd_str; + int len = (int) strlen( cmd_str ); + MBG_MSG_CTL *pmctl = NULL; + int rc; + int high = 1; -out: - *ppmctl = pmctl; + if ( ( baud_rate == MBG_DEFAULT_BAUDRATE_HS ) && ( strcmp( framing, MBG_DEFAULT_FRAMING ) == 0 ) ) + return mbgextio_open_serial( dev, ppmctl, baud_rate, framing ); + +retry: + rc = mbgextio_open_serial_raw( dev, &pmctl, baud_rate, framing ); + + if ( mbg_rc_is_success( rc ) ) + { + mbgserio_write( pmctl->st.p_serio, cmd_str, len ); + + #ifdef MBG_TGT_WIN32 + // Flushing the output when the serial port is closed doesn't + // always work correctly under Windows, so we insert a delay + // here to make sure the string has been set. + // The required delay depends on the number of characters to + // send, and on the transmission speed (baud rate). + Sleep( ( ( 10 * 1000 * len ) / baud_rate ) + 1 ); + #endif + + mbgextio_close_connection( &pmctl ); + + // Sleep for 10ms, so the device has time to switch to the new baudrate + #if defined( MBG_TGT_WIN32 ) + Sleep( 10 ); + #elif defined( MBG_TGT_DOS ) + delay( 10 ); + #else + usleep( 10000 ); + #endif + + rc = mbgextio_open_serial( dev, &pmctl, high ? MBG_DEFAULT_BAUDRATE_HS : MBG_DEFAULT_BAUDRATE, MBG_DEFAULT_FRAMING ); + + if ( mbg_rc_is_error( rc ) && high ) + { + // If baud_rate is default baudrate and highspeed baud_rate did not work, simply open the port with default baudrate + if( ( baud_rate == MBG_DEFAULT_BAUDRATE ) && ( strcmp( framing, MBG_DEFAULT_FRAMING ) == 0 ) ) + return mbgextio_open_serial( dev, ppmctl, baud_rate, framing ); + + high = 0; + cmd_str = force_conn_cmd_str; + len = ( int )strlen( cmd_str ); + goto retry; + } + } + + if ( mbg_rc_is_success( rc ) ) + *ppmctl = pmctl; return rc; -} // mbgextio_open_serial +} // mbgextio_open_serial_force_default -#endif +#endif // _USE_SERIAL_IO @@ -995,7 +1881,7 @@ out: */ _NO_MBG_API_ATTR FT_HANDLE _MBG_API mbgextio_get_serial_ftdi_port_handle( MBG_MSG_CTL *pmctl ) { - return pmctl->st.ftdiio.port_handle; + return pmctl->st.ftdi.port_handle; } // mbgextio_get_serial_ftdi_port_handle @@ -1026,7 +1912,7 @@ _NO_MBG_API_ATTR FT_HANDLE _MBG_API mbgextio_get_serial_ftdi_port_handle( MBG_MS * @see ::mbgextio_close_connection */ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial_ftdi( int device_num, - MBG_MSG_CTL **ppmctl, uint32_t baud_rate, const char *framing ) + MBG_MSG_CTL **ppmctl, uint32_t baud_rate, const char *framing ) { FT_STATUS status; ULONG ft_baud; @@ -1037,22 +1923,19 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial_ftdi( int device_num, MBG_MSG_CTL *pmctl; int rc = alloc_msg_ctl( &pmctl ); - if ( rc != MBG_SUCCESS ) - goto out; - - - pmctl->conn_type = MBG_CONN_TYPE_SERIAL_FTDI; - pmctl->msg_rcv_timeout = MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL; - pmctl->char_rcv_timeout = MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL; + if ( mbg_rc_is_error( rc ) ) + return dev_open_finish( rc, pmctl, ppmctl ); - status = FT_Open( device_num, &pmctl->st.ftdiio.port_handle ); + status = FT_Open( device_num, &pmctl->st.ftdi.port_handle ); if ( status != FT_OK ) - goto ft_fail_free; + return dev_open_fail_free( mbg_ftdi_ft_status_to_mbg( status ), &pmctl, ppmctl ); + dev_open_init( pmctl, MBG_CONN_TYPE_SERIAL_FTDI, MBGEXTIO_MSG_TIMEOUT_SERIAL, + MBGEXTIO_POLL_TIMEOUT_SERIAL ); // setup transmission speed - switch( baud_rate ) + switch ( baud_rate ) { case 300: ft_baud = FT_BAUD_300; break; case 600: ft_baud = FT_BAUD_600; break; @@ -1070,8 +1953,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial_ftdi( int device_num, case 921600: ft_baud = FT_BAUD_921600; break; default: - rc = MBG_ERR_INV_PARM; - goto fail_free; + return dev_open_fail_close( MBG_ERR_INV_PARM, &pmctl, ppmctl ); } @@ -1094,42 +1976,23 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial_ftdi( int device_num, case '2': ft_stopbits = FT_STOP_BITS_2; break; default: - rc = MBG_ERR_INV_PARM; - goto fail_free; + return dev_open_fail_close( MBG_ERR_INV_PARM, &pmctl, ppmctl ); } } - status = FT_SetBaudRate( pmctl->st.ftdiio.port_handle, ft_baud ); + status = FT_SetBaudRate( pmctl->st.ftdi.port_handle, ft_baud ); if ( status != FT_OK ) - goto ft_fail_free; + return dev_open_fail_close( mbg_ftdi_ft_status_to_mbg( status ), &pmctl, ppmctl ); - status = FT_SetDataCharacteristics( pmctl->st.ftdiio.port_handle, + status = FT_SetDataCharacteristics( pmctl->st.ftdi.port_handle, ft_data_bits, ft_stopbits, ft_parity ); if ( status != FT_OK ) - goto ft_fail_free; - - - #if _USE_MUTEX - _mbg_mutex_init( &pmctl->xmt.xmt_mutex ); - #endif - - rc = MBG_SUCCESS; - goto out; - - -ft_fail_free: - rc = mbg_ftdi_ft_status_to_mbg( status ); - -fail_free: - dealloc_msg_ctl( &pmctl ); + return dev_open_fail_close( mbg_ftdi_ft_status_to_mbg( status ), &pmctl, ppmctl ); -out: - *ppmctl = pmctl; - - return rc; + return dev_open_finish_setup( &pmctl, ppmctl ); } // mbgextio_open_serial_ftdi @@ -1143,9 +2006,9 @@ out: /** * @brief Open a binary communication channel using direct USB I/O * - * @param[in] usbdev The USB device to communicate with. - * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure - * allocated and set up by this call. Set to NULL on error. + * @param[in] mdev_info The USB device to communicate with. + * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure + * allocated and set up by this call. Set to NULL on error. * * @return One of the @ref MBG_RETURN_CODES * @@ -1154,43 +2017,86 @@ out: * @see ::mbgextio_open_serial_ftdi * @see ::mbgextio_close_connection */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb( const MBG_USB_DEVICE *usbdev, MBG_MSG_CTL **ppmctl ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb( const MBG_USB_DEV_INFO *mdev_info, + MBG_MSG_CTL **ppmctl ) { MBG_MSG_CTL *pmctl; int rc = alloc_msg_ctl( &pmctl ); - if ( rc != MBG_SUCCESS ) - goto out; + if ( mbg_rc_is_error( rc ) ) + return dev_open_finish( rc, pmctl, ppmctl ); + rc = mbgusbio_open( &pmctl->st.usbio, mdev_info ); - pmctl->conn_type = MBG_CONN_TYPE_USB; - pmctl->msg_rcv_timeout = MBGEXTIO_MSG_RCV_TIMEOUT_SERIAL; - pmctl->char_rcv_timeout = MBGEXTIO_CHAR_RCV_TIMEOUT_SERIAL; + if ( mbg_rc_is_error( rc ) ) + return dev_open_fail_free( rc, &pmctl, ppmctl ); - pmctl->st.usbio = usbdev->iost; + dev_open_init( pmctl, MBG_CONN_TYPE_USB, MBGEXTIO_MSG_TIMEOUT_USB, + MBGEXTIO_POLL_TIMEOUT_USB ); - rc = mbgusbio_open( &pmctl->st.usbio ); + return dev_open_finish_setup( &pmctl, ppmctl ); - if ( rc != MBG_SUCCESS ) - goto fail_free; +} // mbgextio_open_usb - #if _USE_MUTEX - _mbg_mutex_init( &pmctl->xmt.xmt_mutex ); - #endif - rc = MBG_SUCCESS; - goto out; +/*HDR*/ +/** + * @brief Reset an USB device in case that the open_usb function return MBG_ERR_BUSY + * + * @param[in] mdev_info The USB device to communicate with. + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_open_socket + * @see ::mbgextio_open_serial + * @see ::mbgextio_open_serial_ftdi + * @see ::mbgextio_close_connection + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_reset_usb( const MBG_USB_DEV_INFO *mdev_info ) +{ + return mbgusbio_reset( mdev_info ); -fail_free: - dealloc_msg_ctl( &pmctl ); +} // mbgextio_reset_usb -out: - *ppmctl = pmctl; - return rc; -} // mbgextio_open_usb +/*HDR*/ +/** + * @brief Open a binary communication channel using direct USB I/O + * + * //### TODO group opening functions, ref to group only + * + * @param[in] ldev A libusb_device to communicate with. + * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure + * allocated and set up by this call. Set to NULL on error. + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_open_socket + * @see ::mbgextio_open_serial + * @see ::mbgextio_open_serial_ftdi + * @see ::mbgextio_close_connection + */ +int mbgextio_open_usb_ldev( libusb_device *ldev, MBG_MSG_CTL **ppmctl ) +{ + MBG_MSG_CTL *pmctl; + int rc = alloc_msg_ctl( &pmctl ); + + if ( mbg_rc_is_error( rc ) ) + return dev_open_finish( rc, pmctl, ppmctl ); + + rc = mbgusbio_open_specific_device( &pmctl->st.usbio, ldev ); + + if ( mbg_rc_is_error( rc ) ) + return dev_open_fail_free( rc, &pmctl, ppmctl ); + + dev_open_init( pmctl, MBG_CONN_TYPE_USB, MBGEXTIO_MSG_TIMEOUT_USB, + MBGEXTIO_POLL_TIMEOUT_USB ); + + return dev_open_finish_setup( &pmctl, ppmctl ); + +} // mbgextio_open_usb_ldev #endif @@ -1220,39 +2126,25 @@ out: * @see ::mbgextio_open_usb_direct_io * @see ::mbgextio_close_connection */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb_direct_io( const char *dev, int flags, MBG_MSG_CTL **ppmctl ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb_direct_io( const char *dev, + int flags, MBG_MSG_CTL **ppmctl ) { MBG_MSG_CTL *pmctl; - int rc; - - if ( dev == NULL ) - return MBG_ERR_NO_DEV; - - rc = alloc_msg_ctl( &pmctl ); - if ( rc != MBG_SUCCESS ) - goto out; + int rc = alloc_msg_ctl( &pmctl ); - pmctl->conn_type = MBG_CONN_TYPE_USB_DIRECT_IO; - pmctl->msg_rcv_timeout = MBGEXTIO_RCV_TIMEOUT_USB_DIRECT_IO; + if ( mbg_rc_is_error( rc ) ) + return dev_open_finish( rc, pmctl, ppmctl ); - pmctl->st.usbdio.usbdiofd = open(dev, flags); + pmctl->st.usbdio.usbdiofd = open( dev, flags ); if ( pmctl->st.usbdio.usbdiofd == MBG_USB_DIRECT_IO_INVALID_FD ) - { - rc = mbg_get_last_error( "failed to open direct USB I/O device" ); - goto fail_free; - } - - rc = MBG_SUCCESS; - goto out; - -fail_free: - dealloc_msg_ctl( &pmctl ); + return dev_open_fail_free( mbg_get_last_error( "failed to open direct USB I/O device" ), + &pmctl, ppmctl ); -out: - *ppmctl = pmctl; + dev_open_init( pmctl, MBG_CONN_TYPE_USB_DIRECT_IO, MBGEXTIO_MSG_TIMEOUT_USB_DIRECT_IO, + MBGEXTIO_POLL_TIMEOUT_USB_DIRECT_IO ); - return rc; + return dev_open_finish_setup( &pmctl, ppmctl ); } // mbgextio_open_usb_direct_io @@ -1293,15 +2185,15 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_close_connection( MBG_MSG_CTL **ppmctl ) { #if _USE_SERIAL_IO case MBG_CONN_TYPE_SERIAL: - rc = mbgserio_close( &pmctl->st.serio ); + rc = mbgserio_close( &pmctl->st.p_serio ); break; #endif // _USE_SERIAL_IO #if _USE_SERIAL_IO_FTDI case MBG_CONN_TYPE_SERIAL_FTDI: { - FT_STATUS status = FT_Close( pmctl->st.ftdiio.port_handle ); - pmctl->st.ftdiio.port_handle = MBG_INVALID_PORT_HANDLE; + FT_STATUS status = FT_Close( pmctl->st.ftdi.port_handle ); + pmctl->st.ftdi.port_handle = NULL; //### TODO FT_Handle is a PVOID rc = mbg_ftdi_ft_status_to_mbg( status ); } break; #endif // _USE_SERIAL_IO_FTDI @@ -1340,7 +2232,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_close_connection( MBG_MSG_CTL **ppmctl ) } // switch #if _USE_MUTEX - _mbg_mutex_destroy( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_destroy( &pmctl->dev_mutex ); #endif dealloc_msg_ctl( ppmctl ); @@ -1354,27 +2246,56 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_close_connection( MBG_MSG_CTL **ppmctl ) #if _USE_SERIAL_IO static /*HDR*/ -int do_force_conn_serial( const char *dev, const char *cmd_str, BAUD_RATE expected_baudrate ) +int do_force_conn_serial( const char *dev, int high_speed ) { - int i; - int j; MBG_MSG_CTL *pmctl; + const char *cmd_str = high_speed ? force_conn_hs_cmd_str : force_conn_cmd_str; + BAUD_RATE expected_baudrate = high_speed ? MBG_DEFAULT_BAUDRATE_HS : MBG_DEFAULT_BAUDRATE; + #if DEBUG_FORCE_CONN + const char *info = high_speed ? " (hs)" : ""; + #endif int len = (int) strlen( cmd_str ); + int baud_idx; + int frame_idx; int rc = MBG_ERR_UNSPEC; - for ( i = 0; i < N_MBG_BAUD_RATES; i++ ) + for ( baud_idx = 0; baud_idx < N_MBG_BAUD_RATES; baud_idx++ ) { - for ( j = 0; j < N_MBG_FRAMINGS; j++ ) + for ( frame_idx = 0; frame_idx < N_MBG_FRAMINGS; frame_idx++ ) { - uint32_t baud_rate = mbg_baud_rates[i]; - const char *framing = mbg_framing_strs[j]; + uint32_t baud_rate = mbg_baud_rates[baud_idx]; + const char *framing = mbg_framing_strs[frame_idx]; - rc = mbgextio_open_serial( dev, &pmctl, baud_rate, framing ); + rc = mbgextio_open_serial_raw( dev, &pmctl, baud_rate, framing ); - if ( rc != MBG_SUCCESS ) // failed to open port - goto out; + if ( mbg_rc_is_error( rc ) ) + { + if ( rc == MBG_ERR_NO_ENTITY ) //### TODO duplicate code + { + #if DEBUG_FORCE_CONN + fprintf( stderr, "force conn%s probing failed to open port %s: %s: aborting\n", + info, dev, mbg_strerror( rc ) ); + #endif + goto out; + } + + if ( rc == MBG_ERR_IO ) //### TODO duplicate code + { + #if DEBUG_FORCE_CONN + fprintf( stderr, "force conn%s failed for port %s with %li/%s: %s: aborting\n", + info, dev, (long) baud_rate, framing, mbg_strerror( rc ) ); + #endif + goto out; + } - mbgserio_write( pmctl->st.serio.port_handle, cmd_str, len ); + #if DEBUG_FORCE_CONN + fprintf( stderr, "force conn%s failed for port %s with %li/%s: %s: skipping\n", + info, dev, (long) baud_rate, framing, mbg_strerror( rc ) ); + #endif + continue; + } + + mbgserio_write( pmctl->st.p_serio, cmd_str, len ); // should we check rc here or just continue? #ifdef MBG_TGT_WIN32 @@ -1390,13 +2311,16 @@ int do_force_conn_serial( const char *dev, const char *cmd_str, BAUD_RATE expect } } - rc = mbgextio_open_serial( dev, &pmctl, expected_baudrate, MBG_DEFAULT_FRAMING ); + rc = mbgextio_open_serial_raw( dev, &pmctl, expected_baudrate, MBG_DEFAULT_FRAMING ); - if ( rc != MBG_SUCCESS ) // failed to open port + if ( mbg_rc_is_error( rc ) ) goto out; rc = mbgextio_get_receiver_info( pmctl, NULL, NULL ); + if ( mbg_rc_is_success( rc ) ) + rc = expected_baudrate; + mbgextio_close_connection( &pmctl); out: @@ -1439,16 +2363,19 @@ out: */ _NO_MBG_API_ATTR long _MBG_API mbgextio_force_conn_serial( const char *dev ) { - long rc = do_force_conn_serial( dev, force_conn_hs_cmd_str, MBG_DEFAULT_BAUDRATE_HS ); + long rc = do_force_conn_serial( dev, 1 ); - if ( rc == MBG_SUCCESS ) - return MBG_DEFAULT_BAUDRATE_HS; + if ( mbg_rc_is_success( rc ) ) + goto out; - rc = do_force_conn_serial( dev, force_conn_cmd_str, MBG_DEFAULT_BAUDRATE ); + // If we failed because the specified port is not available + // then it makes no sense to continue. + if ( ( rc == MBG_ERR_NO_ENTITY ) || ( rc == MBG_ERR_IO ) ) //### TODO duplicate code + goto out; - if ( rc == MBG_SUCCESS ) - return MBG_DEFAULT_BAUDRATE; + rc = do_force_conn_serial( dev, 0 ); +out: return rc; } // mbgextio_force_conn_serial @@ -1480,14 +2407,14 @@ int do_force_conn_serial_ftdi( int device_num, const char *cmd_str, BAUD_RATE ex rc = mbgextio_open_serial_ftdi( device_num, &pmctl, baud_rate, framing ); - if ( rc != MBG_SUCCESS ) // failed to open port + if ( mbg_rc_is_error( rc ) ) goto out; - port_handle = pmctl->st.ftdiio.port_handle; + port_handle = pmctl->st.ftdi.port_handle; status = FT_Write( port_handle, (LPVOID) force_conn_cmd_str, len, &bytes_written ); - #if 0 //##+++++++++++ do we need some error checking here? + #if 0 //### TODO we need some error checking here if ( status != FT_OK ) { rc = mbg_ftdi_ft_status_to_mbg( status ); @@ -1519,7 +2446,7 @@ int do_force_conn_serial_ftdi( int device_num, const char *cmd_str, BAUD_RATE ex rc = mbgextio_open_serial_ftdi( device_num, &pmctl, expected_baudrate, MBG_DEFAULT_FRAMING ); - if ( rc != MBG_SUCCESS ) // failed to open port + if ( mbg_rc_is_error( rc ) ) goto out; rc = mbgextio_get_receiver_info( pmctl, NULL, NULL ); @@ -1565,12 +2492,12 @@ _NO_MBG_API_ATTR long _MBG_API mbgextio_force_conn_serial_ftdi( int device_num ) { long rc = do_force_conn_serial_ftdi( device_num, force_conn_hs_cmd_str, MBG_DEFAULT_BAUDRATE_HS ); - if ( rc == MBG_SUCCESS ) + if ( mbg_rc_is_success( rc ) ) return MBG_DEFAULT_BAUDRATE_HS; rc = do_force_conn_serial_ftdi( device_num, force_conn_cmd_str, MBG_DEFAULT_BAUDRATE ); - if ( rc == MBG_SUCCESS ) + if ( mbg_rc_is_success( rc ) ) return MBG_DEFAULT_BAUDRATE; return rc; @@ -1583,6 +2510,46 @@ _NO_MBG_API_ATTR long _MBG_API mbgextio_force_conn_serial_ftdi( int device_num ) /*HDR*/ /** + * @brief Set a message callback function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] fnc Address of the callback function to be registered + * + * @return Address of the allocated receive buffer + * + * @see ::mbgextio_get_rcv_buffer_size + * @see ::mbgextio_get_xmt_buffer_addr + * @see ::mbgextio_get_xmt_buffer_size + */ +_NO_MBG_API_ATTR void _MBG_API mbgextio_register_msg_callback( MBG_MSG_CTL *pmctl, MBG_MSG_HANDLER *fnc ) +{ + pmctl->msg_handler_fnc = *fnc; + +} // mbgextio_register_msg_callback + + + +/*HDR*/ +/** + * @brief Retrieve address of the ::RECEIVER_INFO read from the device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Address of the ::RECEIVER_INFO read from the device when the device was opened + */ +_NO_MBG_API_ATTR RECEIVER_INFO * _MBG_API mbgextio_get_receiver_info_addr( MBG_MSG_CTL *pmctl ) +{ + if ( pmctl == NULL ) + return NULL; + + return &pmctl->xdev_features.receiver_info; + +} // mbgextio_get_receiver_info_addr + + + +/*HDR*/ +/** * @brief Retrieve address of the allocated receive buffer * * @param[in,out] pmctl Pointer to a valid message control structure @@ -1675,40 +2642,42 @@ _NO_MBG_API_ATTR size_t _MBG_API mbgextio_get_xmt_buffer_size( MBG_MSG_CTL *pmct /*HDR*/ /** - * @brief Set character receive timeout value + * @brief Set device poll timeout * * @param[in,out] pmctl Pointer to a valid message control structure - * @param[in] new_timeout New timeout value [ms] + * @param[in] new_timeout New poll timeout value [ms] + * + * @return Previous poll timeout value [ms] * - * @see ::mbgextio_get_char_rcv_timeout + * @see ::mbgextio_get_dev_poll_timeout * @see ::mbgextio_set_msg_rcv_timeout * @see ::mbgextio_get_msg_rcv_timeout */ -_NO_MBG_API_ATTR void _MBG_API mbgextio_set_char_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) +_NO_MBG_API_ATTR ulong _MBG_API mbgextio_set_dev_poll_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) { - pmctl->char_rcv_timeout = new_timeout; + return xtiocomm_set_dev_poll_timeout( pmctl, new_timeout ); -} // mbgextio_set_char_rcv_timeout +} // mbgextio_set_dev_poll_timeout /*HDR*/ /** - * @brief Get character receive timeout value + * @brief Get device poll timeout * * @param[in,out] pmctl Pointer to a valid message control structure * - * @return Current timeout value [ms] + * @return Current poll timeout value [ms] * - * @see ::mbgextio_set_char_rcv_timeout + * @see ::mbgextio_set_dev_poll_timeout * @see ::mbgextio_set_msg_rcv_timeout * @see ::mbgextio_get_msg_rcv_timeout */ -_NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_char_rcv_timeout( const MBG_MSG_CTL *pmctl ) +_NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_dev_poll_timeout( const MBG_MSG_CTL *pmctl ) { - return pmctl->char_rcv_timeout; + return xtiocomm_get_dev_poll_timeout( pmctl ); -} // mbgextio_get_char_rcv_timeout +} // mbgextio_get_dev_poll_timeout @@ -1719,13 +2688,13 @@ _NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_char_rcv_timeout( const MBG_MSG_CTL * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] new_timeout New timeout value [ms] * - * @see ::mbgextio_set_char_rcv_timeout - * @see ::mbgextio_get_char_rcv_timeout + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_get_dev_poll_timeout * @see ::mbgextio_get_msg_rcv_timeout */ _NO_MBG_API_ATTR void _MBG_API mbgextio_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) { - pmctl->msg_rcv_timeout = new_timeout; + xtiocomm_set_msg_rcv_timeout( pmctl, new_timeout ); } // mbgextio_set_msg_rcv_timeout @@ -1739,13 +2708,13 @@ _NO_MBG_API_ATTR void _MBG_API mbgextio_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, * * @return Current timeout value [ms] * - * @see ::mbgextio_set_char_rcv_timeout - * @see ::mbgextio_get_char_rcv_timeout + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_get_dev_poll_timeout * @see ::mbgextio_set_msg_rcv_timeout */ _NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_msg_rcv_timeout( const MBG_MSG_CTL *pmctl ) { - return pmctl->msg_rcv_timeout; + return xtiocomm_get_msg_rcv_timeout( pmctl ); } // mbgextio_get_msg_rcv_timeout @@ -1753,6 +2722,926 @@ _NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_msg_rcv_timeout( const MBG_MSG_CTL /*HDR*/ /** + * @brief Get last NACK error code + * + * If an API call has returned ::MBG_ERR_RCVD_NACK then this + * function can be used to retrieve an associated error code + * which eventually specifies the reason for the NACK message. + * + * A NACK message can be received from a device after the device + * has received a command which it doesn't recognize, or a + * parameter set which it doesn't accept, and the message can + * optionally contain one of the @ref MBG_ERROR_CODES. + * + * If the NACK message contains an error code then that code is + * saved, otherwise the saved code is set to ::MBG_ERR_UNSPEC. + * A saved error code is available and can be retrieved until + * the next API call starts to read some data from the device, + * in which case the stored code is set to ::MBG_SUCCESS. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return The saved return code, i.e. one of the @ref MBG_RETURN_CODES. + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_last_nack_err_code( const MBG_MSG_CTL *pmctl ) +{ + return pmctl->nack_err_code; + +} // mbgextio_get_last_nack_err_code + + + +/*HDR*/ +/** + * @brief Check if a device is a legacy device + * + * Legacy devices don't support the standard binary protocol, so the + * standard binary API functions must *not* be used with such a device. + * Any attempt to access the device using the standard binary API + * functions may have unpredictable side-effects for the device, but + * the low level read/write functions can be used to access the device + * via a proprietary protocol, depending on the device type. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_DEV_NOT_SUPP + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_is_legacy( const MBG_MSG_CTL *pmctl ) +{ + return ( pmctl->device_flags & MSG_CTL_DEVICE_FLAG_MSK_LEGACY ) ? MBG_SUCCESS : MBG_ERR_DEV_NOT_SUPP; + +} // mbgextio_dev_is_legacy + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_is_legacy; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_pos_xyz( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_pos_xyz( &pmctl->xdev_features ); + +} // mbgextio_dev_has_pos_xyz + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_pos_xyz; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_pos_lla( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_pos_lla( &pmctl->xdev_features ); + +} // mbgextio_dev_has_pos_lla + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_pos_lla; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_time_ttm( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_time_ttm( &pmctl->xdev_features ); + +} // mbgextio_dev_has_time_ttm + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_time_ttm; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ant_info( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_ant_info( &pmctl->xdev_features ); + +} // mbgextio_dev_has_ant_info + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_ant_info; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ant_cable_length( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_ant_cable_length( &pmctl->xdev_features ); + +} // mbgextio_dev_has_ant_cable_length + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_ant_cable_length; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_io_ports( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_io_ports( &pmctl->xdev_features ); + +} // mbgextio_dev_has_io_ports + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_io_ports; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::STAT_INFO structure and API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_gps_stat_info( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_gps_stat_info( &pmctl->xdev_features ); + +} // mbgextio_dev_has_gps_stat_info + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_gps_stat_info; + + + +/*HDR*/ +/** + * @brief Check if a device can receive the GPS satellite system + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_is_gps( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_is_gps( &pmctl->xdev_features ); + +} // mbgextio_dev_is_gps + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_is_gps; + + + +/*HDR*/ +/** + * @brief Check if a device supports the GNSS API + * + * This is usually supported by devices which can receive signals + * from different satellite systems, e.g. GPS, GLONASS, ... + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_chk_get_all_gnss_info + * @see ::MBG_GNSS_TYPES + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_is_gnss( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_is_gnss( &pmctl->xdev_features ); + +} // mbgextio_dev_is_gnss + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_is_gnss; + + + +/*HDR*/ +/** + * @brief Check if a device is a bus level device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_is_bus_lvl_dev( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_is_bus_lvl_dev( &pmctl->xdev_features ); + +} // mbgextio_dev_is_bus_lvl_dev + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_is_bus_lvl_dev; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_enable_flags( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_enable_flags( &pmctl->xdev_features ); + +} // mbgextio_dev_has_enable_flags + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_enable_flags; + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_time_scale( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_time_scale( &pmctl->xdev_features ); + +} // mbgextio_dev_has_time_scale + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_time_scale; + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_tzdl( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_tzdl( &pmctl->xdev_features ); + +} // mbgextio_dev_has_tzdl + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_tzdl; + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_tzcode( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_tzcode( &pmctl->xdev_features ); + +} // mbgextio_dev_has_tzcode + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_tzcode; + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ims( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_ims( &pmctl->xdev_features ); + +} // mbgextio_dev_has_ims + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_ims; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_synth( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_synth( &pmctl->xdev_features ); + +} // mbgextio_dev_has_synth + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_synth; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_gpio( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_gpio( &pmctl->xdev_features ); + +} // mbgextio_dev_has_gpio + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_gpio; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_prog_pulses( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_prog_pulses( &pmctl->xdev_features ); + +} // mbgextio_dev_has_prog_pulses + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_prog_pulses; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_irig_tx( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_irig_tx( &pmctl->xdev_features ); + +} // mbgextio_dev_has_irig_tx + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_irig_tx; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_irig_rx( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_irig_rx( &pmctl->xdev_features ); + +} // mbgextio_dev_has_irig_rx + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_irig_rx; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_serouts( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_serouts( &pmctl->xdev_features ); + +} // mbgextio_dev_has_serouts + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_serouts; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_bvar_stat( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_bvar_stat( &pmctl->xdev_features ); + +} // mbgextio_dev_has_serouts + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_bvar_stat; + + + +/*HDR*/ +/** + * @brief Check if the device supports the SCU_STAT structures + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + * @see ::mbgextio_get_scu_stat_info + * @see ::mbgextio_set_scu_stat_settings + * @see @ref group_scu + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_scu_stat( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_scu_stat( &pmctl->xdev_features ); + +} // mbgextio_dev_has_scu_stat + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_scu_stat; + + +/*HDR*/ +/** + * @brief Check if a timecode receiver provides ::MBG_RAW_IRIG_DATA + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_raw_irig_data + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_raw_irig_data( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_raw_irig_data( &pmctl->xdev_features ); + +} // mbgextio_dev_has_raw_irig_data + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_raw_irig_data; + + + +/*HDR*/ +/** + * @brief Check if a device supports the old LAN_IP4 API + * + * The LAN_IP4 API provides structures and functions to configure + * parts of the networking of a device and is superseded by the + * NET_CFG API. Some devices combine NET_CFG and LAN_IP4. + * Therefore, ::mbgextio_get_all_net_cfg_info should be used + * preferably to read the network configuration. + * It will translate the old structures into the new ones. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_all_net_cfg_info + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_lan_ip4( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_lan_ip4( &pmctl->xdev_features ); + +} // mbgextio_dev_has_lan_ip4 + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_lan_ip4; + + + +/*HDR*/ +/** + * @brief Check if a device supports the new NET_CFG API + * + * The NET_CFG API provides structures and functions to configure + * the complete networking part of a device and supersedes the + * LAN_IP4 API. Not all devices support the whole feature set + * of the NET_CFG API or combine NET_CFG and LAN_IP4. + * Therefore, ::mbgextio_get_all_net_cfg_info should be used + * preferably to read the network configuration. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_all_net_cfg_info + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_net_cfg( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_net_cfg( &pmctl->xdev_features ); + +} // mbgextio_dev_has_net_cfg + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_net_cfg; + + + +/*HDR*/ +/** + * @brief Check if a device supports the PTP API + * + * The PTP API consists of different calls and associated structures + * which * have evolved over time. Not all devices support every call, + * so ::mbgextio_get_all_ptp_cfg_info takes care to check which parts are + * supported and thus should be used preferably to read PTP information. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_all_ptp_cfg_info + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ptp( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_ptp( &pmctl->xdev_features ); + +} // mbgextio_dev_has_ptp + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_ptp; + + +/*HDR*/ +/** + * @brief Check if a device supports the NTP API + * + * The NTP API consists of different calls and associated structures + * which have evolved over time. Not all devices support every call, + * so ::mbgextio_get_all_ntp_cfg_info takes care to check which parts are + * supported and thus should be used preferably to read NTP information. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_all_ntp_cfg_info + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ntp( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_ntp( &pmctl->xdev_features ); + +} // mbgextio_dev_has_ntp + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_ntp; + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_evt_log( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_evt_log( &pmctl->xdev_features ); + +} // mbgextio_dev_has_evt_log + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_evt_log; + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ucap( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_ucap( &pmctl->xdev_features ); + +} // mbgextio_dev_has_ucap + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_ucap; + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ucap_net( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_ucap_net( &pmctl->xdev_features ); + +} // mbgextio_dev_has_ucap_net + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_ucap_net; + + +/*HDR*/ +/** + * @brief Check if a device supports the TLV API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref group_tlv_api + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_tlv_api( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_tlv_api( &pmctl->xdev_features ); + +} // mbgextio_dev_has_tlv_api + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_tlv_api; + + + +/*HDR*/ +/** + * @brief Check if a device supports a firmware update via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to fw update function + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_fw_update( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_supp_tlv_fw_update( &pmctl->xdev_features ); + +} // mbgextio_dev_supp_tlv_fw_update + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_supp_tlv_fw_update; + + + +/*HDR*/ +/** + * @brief Check if a device supports creating / sending a diagnostics file via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_diag_file( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_supp_tlv_diag_file( &pmctl->xdev_features ); + +} // mbgextio_dev_supp_tlv_diag_file + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_supp_tlv_diag_file; + +/*HDR*/ +/** + * @brief Check if a device supports upports PTPv2 license infos + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_ptpv2_license( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_supp_tlv_ptpv2_license( &pmctl->xdev_features ); + +} // mbgextio_dev_supp_tlv_ptpv2_license + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_supp_tlv_ptpv2_license; + +/*HDR*/ +/** + * @brief Check if a device supports supports PTPv1 License Infos via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_ptpv1_license( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_supp_tlv_ptpv1_license( &pmctl->xdev_features ); + +} // mbgextio_dev_supp_tlv_ptpv1_license + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_supp_tlv_ptpv1_license; + + +/*HDR*/ +/** + * @brief Check if a device supports supports NTP license infos via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_ntp_license( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_supp_tlv_ntp_license( &pmctl->xdev_features ); + +} // mbgextio_dev_supp_tlv_ntp_license + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_supp_tlv_ntp_license; + + +/*HDR*/ +/** + * @brief Check if a device supports supportsTime Monitor License infos via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_time_monitor_license( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_supp_tlv_time_monitor_license( &pmctl->xdev_features ); + +} // mbgextio_dev_supp_tlv_time_monitor_license + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_supp_tlv_time_monitor_license; + +/*HDR*/ +/** + * @brief Check if a device supports the ::GPS_SAVE_CFG command + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_cmd_save_cfg + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_cmd_save_cfg( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_cmd_save_cfg( &pmctl->xdev_features ); + +} // mbgextio_dev_has_cmd_save_cfg + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_cmd_save_cfg; + + + +/*HDR*/ +/** + * @brief Check if a device supports the extended feature monitoring + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see xdevfeat_has_monitoring + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_monitoring( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_monitoring( &pmctl->xdev_features ); + +} // mbgextio_dev_has_monitoring + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_monitoring; + + + +/*HDR*/ +/** + * @brief Check if a device supports the LED API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO ### + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_led_api( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_led_api( &pmctl->xdev_features ); + +} // mbgextio_dev_has_led_api + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_led_api; + + + +/*HDR*/ +/** + * @brief Check if a device supports the LNE API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO ### + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_lne_api( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_lne_api( &pmctl->xdev_features ); + +} // mbgextio_dev_has_lne_api + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_lne_api; + + + +/*HDR*/ +/** + * @brief Check if a device supports the power control API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO ### + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_pwr_ctl_api( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_pwr_ctl_api( &pmctl->xdev_features ); + +} // mbgextio_dev_has_pwr_ctl_api + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_pwr_ctl_api; + + + +/*HDR*/ +/** + * @brief Check if a device has MBG_XFEATURE_EXT_SYS_INFO + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ext_sys_info( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_ext_sys_info( &pmctl->xdev_features ); + +} // mbgextio_dev_has_ext_sys_info + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_ext_sys_info; + + + +/*HDR*/ +/** + * @brief Check if a device has MBG_XFEATURE_TRANSACTIONS + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_transactions( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_transactions( &pmctl->xdev_features ); + +} // mbgextio_dev_has_transactions + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_transactions; + + + +/*HDR*/ +/** + * @brief Check if a device has MBG_XFEATURE_REBOOT + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_reboot( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_reboot( &pmctl->xdev_features ); + +} // mbgextio_dev_has_reboot + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_reboot; + + + +/*HDR*/ +/** + * @brief Check if a device has MBG_XFEATURE_REQ_TTM + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + * @see mbgextio_get_time + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_req_ttm( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_req_ttm( &pmctl->xdev_features ); + +} // mbgextio_dev_has_req_ttm + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_req_ttm; + + + +/*HDR*/ +/** + * @brief Check if a device supports the up-to-date extended multi ref API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_xmulti_ref( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_xmulti_ref( &pmctl->xdev_features ); + +} // mbgextio_dev_has_xmulti_ref + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_xmulti_ref; + + + +/*HDR*/ +/** + * @brief Check if a device supports the extended binary protocl (XBP) feature + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_xbp( const MBG_MSG_CTL *pmctl ) +{ + return xdevfeat_has_xbp( &pmctl->xdev_features ); + +} // mbgextio_dev_has_xbp + +MBGEXTIO_CHK_SUPP_FNC mbgextio_dev_has_xbp; + + + +/*HDR*/ +/** * @brief Generic reception of a binary message * * @note A certain message type to be waited for can be specified by @@ -1760,38 +3649,50 @@ _NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_msg_rcv_timeout( const MBG_MSG_CTL * If the special cmd code ::GPS_WILDCARD is specified the function returns * successfully after *any* type of binary message has been received. * - * //##++ TODO: callback function to handle asynchronous spontaneous messages - * - * @param[in,out] pmctl Pointer to a valid message control structure - * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, or ::GPS_WILDCARD + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, or ::GPS_WILDCARD + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_xmt_msg //##++++ * @see ::mbgextio_xmt_cmd * @see ::mbgextio_req_data * @see ::mbgextio_xmt_cmd_us * @see ::mbgextio_req_data_idx */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg_unlocked( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + GPS_CMD cmd, void *buf, size_t buf_size ) { MBG_MSG_RCV_CTL *prctl; MBG_MSG_BUFF *pmb; - MBG_TMO_TIME msg_timeout; char buff[MBGEXTIO_READ_BUFFER_SIZE]; ssize_t n_bytes = 0; int rc = MBG_ERR_UNSPEC; int i; + #if _DEBUG_MSG_TIMING + MBG_MSG_TIMES *pmt = &pmctl->mt; + #else + MBG_MSG_TIMES mt; + MBG_MSG_TIMES *pmt = &mt; + #endif - mbg_tmo_set_timeout_ms( &msg_timeout, pmctl->msg_rcv_timeout ); + init_transfer( &pmctl->rcv ); + pmctl->nack_err_code = MBG_SUCCESS; // will be updated if a NACK msg is received + mbg_tmo_get_time( &pmt->t_start ); + pmt->t_tmo = pmt->t_start; + mbg_tmo_add_ms( &pmt->t_tmo, pmctl->msg_rcv_timeout ); for (;;) // loop until complete msg received { n_bytes = 0; - if ( mbg_tmo_curr_time_is_after( &msg_timeout ) ) + mbg_tmo_get_time( &pmt->t_now ); + + if ( mbg_tmo_time_is_after( &pmt->t_now, &pmt->t_tmo ) ) { rc = MBG_ERR_TIMEOUT; goto out; @@ -1806,7 +3707,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD fd_set fds; int max_fd; - mbg_msec_to_timeval( pmctl->msg_rcv_timeout, &tv_timeout ); + mbg_msec_to_timeval( pmctl->st.sockio.poll_timeout, &tv_timeout ); FD_ZERO( &fds ); FD_SET( pmctl->st.sockio.sockfd, &fds ); @@ -1823,25 +3724,29 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD rc = select( max_fd + 1, &fds, NULL, NULL, &tv_timeout ); - if ( rc == MBG_SOCKET_ERR_RETVAL ) // < 0, error + if ( rc == MBG_SOCKET_ERR_RETVAL ) // error, usually < 0, depending on build environment { - rc = mbg_get_last_socket_error( "select failed in mbgextio_rcv_msg" ); + rc = mbg_get_last_socket_error( "select failed in mbgextio_rcv_msg_unlocked" ); goto out; } if ( rc == 0 ) // timeout - { - rc = MBG_ERR_TIMEOUT; - goto out; - } + continue; // continue loop to check message timeout // data is available n_bytes = recv( pmctl->st.sockio.sockfd, buff, sizeof( buff ), 0 ); + /* 0 bytes mean remote site closed connection on TCP sockets */ + if ( n_bytes == 0 ) + { + rc = MBG_ERR_DISCONN; + goto out; + } + if ( n_bytes < 0 ) { - rc = mbg_get_last_socket_error( "recv failed in mbgextio_rcv_msg" ); + rc = mbg_get_last_socket_error( "recv failed in mbgextio_rcv_msg_unlocked" ); goto out; } @@ -1851,15 +3756,20 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD #if _USE_SERIAL_IO case MBG_CONN_TYPE_SERIAL: { - n_bytes = mbgserio_read_wait( pmctl->st.serio.port_handle, &buff[0], - sizeof( buff[0] ), pmctl->char_rcv_timeout ); + rc = mbgserio_read_wait( pmctl->st.p_serio, &buff[0], sizeof( buff[0] ) ); - if ( n_bytes < 0 ) + if ( mbg_rc_is_error( rc ) ) { - rc = n_bytes; - goto out; + // Do not continue with reception after character timeout + // if ( rc == MBG_ERR_TIMEOUT ) // just a character timeout + // continue; // continue loop to check message timeout + + goto out; // non-timeout error: fatal, quit } + // rc contains number of received bytes + n_bytes = rc; + } break; #endif // _USE_SERIAL_IO @@ -1869,8 +3779,8 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD DWORD bytes_read; FT_STATUS status; - //##++++++ pmctl->char_rcv_timeout, - status = FT_Read( pmctl->st.ftdiio.port_handle, &buff[0], + //### TODO pmctl->dev_poll_timeout + status = FT_Read( pmctl->st.ftdi.port_handle, &buff[0], sizeof( buff[0] ), &bytes_read ); if ( status != FT_OK ) @@ -1887,13 +3797,17 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD #if _USE_USB_IO case MBG_CONN_TYPE_USB: { - rc = mbgusbio_read( &pmctl->st.usbio, (uint8_t *) buff, sizeof( buff ), 1000 ); + rc = mbgusbio_read( &pmctl->st.usbio, (uint8_t *) buff, sizeof( buff ) ); - if ( rc < 0 ) - goto out; + if ( mbg_rc_is_error( rc ) ) + { + if ( rc == MBG_ERR_TIMEOUT ) // just a character timeout + continue; // continue loop to check message timeout - // data is available + goto out; // non-timeout error: fatal, quit + } + // rc contains number of received bytes n_bytes = rc; } break; @@ -1908,7 +3822,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD pfd.events = POLLIN | POLLRDNORM | POLLRDBAND; pfd.revents = 0; - rc = poll( &pfd, 1, pmctl->msg_rcv_timeout); + rc = poll( &pfd, 1, pmctl->st.usbdio.poll_timeout ); if ( rc == 0 ) // timeout { @@ -1922,11 +3836,17 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD goto out; } + if ( pfd.revents & POLLHUP ) + { + rc = MBG_ERR_DISCONN; + goto out; + } + // Other stuff? - if ( pfd.revents & ( POLLERR | POLLHUP | POLLNVAL ) ) + if ( pfd.revents & ( POLLERR | POLLNVAL ) ) { rc = MBG_ERR_UNSPEC; - goto out; + goto out; } // Read data? @@ -1942,6 +3862,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD n_bytes = rc; } + } break; #endif @@ -1964,40 +3885,52 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD switch ( rc ) { case TR_WAITING: /* no data transfer sequence in progress */ - #if _USE_CHK_TSTR - if ( prctl->chk_tstr_fnc ) /* optionally handle normal, non-protocol data */ - { - int tstr_rc = prctl->chk_tstr_fnc( c, prctl->chk_tstr_arg ); - - if ( tstr_rc > 0 ) // a valid time string has been received - { - // return only if the caller does not wait for a specific packet type - if ( cmd == GPS_WILDCARD ) - return TR_COMPLETE_TSTR; //##++++++++++++++++++++ TODO better way to detect string - } - } + #if _USE_MBG_TSTR + if ( prctl->tstr_rcv_fnc ) /* optionally handle normal, non-protocol data */ + prctl->tstr_rcv_fnc( c, prctl->tstr_rcv_arg ); #endif + // intentional fall-through case TR_RECEIVING: /* data transfer sequence in progress, keep waiting */ + // Increase timeout if header has been completely received + //if ( mbg_rc_is_success( chk_hdr_rcvd( prctl ) ) ) + //mbg_tmo_add_ms( &pmt->t_tmo, pmctl->st.serio.poll_timeout ); continue; case TR_COMPLETE: { GPS_CMD rcvd_cmd; - #if _USE_CHK_TSTR - //##+++++++++++++++++ + #if _USE_MBG_TSTR + //### TODO // If a valid binary packet has been received then discard // a partial time string possibly received before. #endif rcvd_cmd = pmb->hdr.cmd & ~GPS_CTRL_MSK; - if ( rcvd_cmd == cmd ) /* the received packet is what we've been waiting for */ + if ( ( rcvd_cmd == GPS_XBP_PACKET ) && p_addr ) { + if ( memcmp( &pmb->u.xbp_msg_data.xbp_addr, p_addr, sizeof( *p_addr ) ) == 0 ) + { + // If this packet is from the expected XBP node + mbg_memcpy( pmb, &pmb->u.xbp_msg_data.std_msg, sizeof( pmb->u.xbp_msg_data.std_msg ) ); + rcvd_cmd = pmb->hdr.cmd & ~GPS_CTRL_MSK; + } + } + + if( rcvd_cmd == cmd ) + { + /* the received packet is what we've been waiting for */ if ( pmb->hdr.cmd & GPS_NACK ) { + // If the device has sent an explicit error code then we save that one, + // otherwise we set the error code to "unspecified". + // See also ::mbgextio_get_last_nack_err_code + pmctl->nack_err_code = ( pmb->hdr.len == sizeof( pmb->u.msg_data.i16 ) ) ? + pmb->u.msg_data.i16 : MBG_ERR_UNSPEC; + rc = MBG_ERR_RCVD_NACK; goto out; } @@ -2007,7 +3940,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD } #if _USE_ENCRYPTION - /* if an encrypted packet has been received then decrypt it */ + // If an encrypted packet has been received then decrypt it. if ( rcvd_cmd == GPS_CRYPTED_PACKET ) { rc = decrypt_message( pmctl ); @@ -2017,29 +3950,55 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD rcvd_cmd = pmb->hdr.cmd & ~GPS_CTRL_MSK; - if ( pmb->hdr.cmd & GPS_NACK ) + if ( ( rcvd_cmd == GPS_XBP_PACKET ) && p_addr ) { - rc = MBG_ERR_RCVD_NACK; - goto out; + if ( memcmp( &pmb->u.xbp_msg_data.xbp_addr, p_addr, sizeof( *p_addr ) ) == 0 ) + { + // If this packet is from the expected XBP node + mbg_memcpy( pmb, &pmb->u.xbp_msg_data.std_msg, sizeof( pmb->u.xbp_msg_data.std_msg ) ); + rcvd_cmd = pmb->hdr.cmd & ~GPS_CTRL_MSK; + } } - if ( rcvd_cmd == cmd ) /* the received packet is what we've been waiting for */ + if( rcvd_cmd == cmd ) { + /* the received packet is what we've been waiting for */ + if ( pmb->hdr.cmd & GPS_NACK ) + { + // If the device has sent an explicit error code then we save that one, + // otherwise we set the error code to "unspecified". + // See also ::mbgextio_get_last_nack_err_code + pmctl->nack_err_code = ( pmb->hdr.len == sizeof( pmb->u.msg_data.i16 ) ) ? + pmb->u.msg_data.i16 : MBG_ERR_UNSPEC; + + rc = MBG_ERR_RCVD_NACK; + goto out; + } + rc = MBG_SUCCESS; goto out; } } #endif - /* not waiting for a specific packet, so return if any packet is complete */ + // Not waiting for a specific message, so return if any message is complete if ( cmd == GPS_WILDCARD ) { rc = MBG_SUCCESS; goto out; } - //##++ received a msg which does not match the expected code - prctl->cnt = 0; /* restart receiving */ + // We are waiting for a specific message, but have just received + // a message which does not match the expected code. + // If a message handler callback function has been registered via + // ::mbgextio_register_msg_callback then we call that function so + // it can eventually evaluate the message, and the message doesn't + // get lost. Otherwise the message is simply dropped. + // See ::mbgextio_register_msg_callback. + if ( pmctl->msg_handler_fnc ) + pmctl->msg_handler_fnc( pmctl ); + + init_transfer( prctl ); // restart receiving } break; @@ -2051,6 +4010,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD rc = MBG_ERR_DATA_CSUM; goto out; + case TR_OVERFLOW: + rc = MBG_ERR_OVERFLOW; + goto out; + default: /* any error condition */ rc = MBG_ERR_UNSPEC; //##+++++++++++++++++++++ use detailed rc goto out; @@ -2060,25 +4023,134 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_AD } out: + if ( mbg_rc_is_error( rc ) ) + goto out2; //### TODO + + // Successfully received a binary message. If a destinaton buffer + // has been specified then we copy the received data to that buffer + // *before* the device mutex is released, so we can be sure the + // received data isn't overwritten by a different thread. + if ( buf ) + { + MBG_MSG_BUFF *pmb = pmctl->rcv.pmb; + + if ( buf_size != pmb->hdr.len ) + { + #if defined( DEBUG ) + const char *cp = mbgextio_get_cmd_name( cmd ); + + fprintf( stderr, "received data size (%u) doesn't match buffer size (%llu) for cmd: %s\n", + pmb->hdr.len, (unsigned long long) buf_size, cp ? cp : "(unknown)" ); + #endif + + rc = MBG_ERR_DATA_SIZE; + goto out2; + } + + memcpy( buf, &pmb->u.msg_data, buf_size ); + } + +out2: + return rc; + +} // mbgextio_rcv_msg_unlocked + + + +/*HDR*/ +/** + * @brief Generic reception of a binary message + * + * @note A certain message type to be waited for can be specified by + * passing one of the ::GPS_CMD_CODES. + * If the special cmd code ::GPS_WILDCARD is specified the function returns + * successfully after *any* type of binary message has been received. + * + * //##++ TODO: callback function to handle asynchronous spontaneous messages + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, or ::GPS_WILDCARD + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_rcv_msg_unlocked + * @see ::mbgextio_xmt_msg //##++++ + * @see ::mbgextio_xmt_cmd + * @see ::mbgextio_req_data + * @see ::mbgextio_xmt_cmd_us + * @see ::mbgextio_req_data_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + GPS_CMD cmd, void *buf, size_t buf_size ) +{ + int rc; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, cmd, buf, buf_size ); // wait for a message + + #if _USE_MUTEX + _mbg_mutex_release( &pmctl->dev_mutex ); + #endif + return rc; } // mbgextio_rcv_msg +static /*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_check_ack( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + GPS_CMD cmd ) +{ + int rc = MBG_SUCCESS; + + // Simply return if no acknowledge has been requested + if ( !( cmd & GPS_REQACK ) ) + goto out; + + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, (GPS_CMD) ( cmd & ~GPS_CTRL_MSK ), NULL, 0 ); + + if ( mbg_rc_is_error( rc ) ) + goto out; + + if ( pmctl->rcv.pmb->hdr.cmd & GPS_NACK ) + { + rc = MBG_ERR_RCVD_NACK; + goto out; + } + + if ( !( pmctl->rcv.pmb->hdr.cmd & GPS_ACK ) ) + rc = MBG_ERR_RCVD_NO_ACK; + +out: + return rc; + +} // mbgextio_check_ack + + + /*HDR*/ /** * @brief Set up and send a generic binary message * - * @note This function should preferably be used only as low level function + * This function should preferably be used only as low level function * called from within more specific functions used to send specific data. - * If this function is called directly with a buffer to be sent then the - * transmit mutex is acquired by this function. However, other (higher level) - * API functions which set up the transmit buffer directly have to acquire - * the transmit mutex by themselves before they set up the transmit buffer, - * and pass a NULL pointer to indicate the transmit buffer has already been - * set up. The correct number of bytes to send (n_bytes) has to be specified - * anyway, though. + * + * If this function is called directly with a buffer p to be sent then the + * device mutex is acquired by this function, and after this the specified + * buffer p is copied to the transmit buffer. + * + * However, other (higher level) API functions which set up the transmit + * buffer directly have to acquire the device mutex by themselves *before* + * they set up the transmit buffer, and then pass p as NULL pointer to + * indicate the transmit buffer has already been set up. The correct number + * of bytes to be sent (n_bytes) has to be specified anyway, though. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL @@ -2089,7 +4161,7 @@ out: * @return One of the @ref MBG_RETURN_CODES */ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, - GPS_CMD cmd, const void *p, uint16_t n_bytes ) + GPS_CMD cmd, const void *p, uint16_t n_bytes ) { MBG_MSG_BUFF *pmb; int rc = MBG_ERR_UNSPEC; @@ -2097,54 +4169,46 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_msg( MBG_MSG_CTL *pmctl, const XBP_AD if ( n_bytes > sizeof( pmb->u.msg_data ) ) { rc = MBG_ERR_OVERFLOW; // bytes to send exceed transmit buffer size - goto out; + + // If p is not NULL then the transmit mutex has not yet + // been acquired, and thus we can exit immediately. + if ( p ) + goto out; + + // Otherwise we have to release the mutex before we exit. + goto out_release; } pmb = pmctl->xmt.pmb; + // If the buffer pointer p is NULL then we assume the transmit buffer + // has already been set up by the caller, and thus the caller has already + // acquired the device mutex. + // However, if a data buffer has been specified (i.e., p != NULL) + // then we have to acquire the device mutex before we start to + // set up the transmit buffer. if ( p ) { #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif memcpy( pmb->u.bytes, p, n_bytes ); } pmb->hdr.len = n_bytes; pmb->hdr.cmd = cmd; + rc = xmt_tbuff( pmctl, p_addr ); + if ( mbg_rc_is_success( rc ) ) + rc = mbgextio_check_ack( pmctl, p_addr, cmd ); + +out_release: #if _USE_MUTEX - _mbg_mutex_release( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_release( &pmctl->dev_mutex ); #endif - if ( rc != MBG_SUCCESS ) // error - goto out; - - - // If an acknowledge has been requested - // wait for a reply and check it. - if ( cmd & GPS_REQACK ) - { - rc = mbgextio_rcv_msg( pmctl, p_addr, (GPS_CMD) ( cmd & ~GPS_CTRL_MSK ) ); - - if ( rc != MBG_SUCCESS ) - { - //##++++++++++ rc = ... eventually return a different error code - goto out; - } - - if ( pmctl->rcv.pmb->hdr.cmd & GPS_NACK ) - { - rc = MBG_ERR_RCVD_NACK; - goto out; - } - - if ( !(pmctl->rcv.pmb->hdr.cmd & GPS_ACK) ) - rc = MBG_ERR_RCVD_NO_ACK; - } - out: return rc; @@ -2156,30 +4220,45 @@ out: /** * @brief Transmit a command-only message without additional data. * + * If the caller has or'ed the cmd code with ::GPS_REQACK then this + * function expects an ACK or a NACK message to be replied by the device. + * + * Transmission is protected by a mutex which is acquired before + * and released after the binary message has been sent. + * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, optionally or'ed with ::GPS_REQACK * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_xmt_msg - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_req_data * @see ::mbgextio_xmt_cmd_us * @see ::mbgextio_req_data_idx */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + GPS_CMD cmd ) { int rc; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif rc = xmt_cmd( pmctl, p_addr, cmd ); + // If the call above succeeded then this just means there + // was no transmission error. It does *not* necessarily mean + // the command has been received and understood by the device. + // So if the cmd code has been or'ed with a flag requesting + // an acknowledge then we wait for an ack msg from the device now. + if ( mbg_rc_is_success( rc ) ) + rc = mbgextio_check_ack( pmctl, p_addr, cmd ); + #if _USE_MUTEX - _mbg_mutex_release( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_release( &pmctl->dev_mutex ); #endif return rc; @@ -2190,11 +4269,14 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_AD /*HDR*/ /** - * @brief Transmit a message without a single ushort (uint16_t) parameter + * @brief Transmit a message with a single ushort (uint16_t) parameter * - * The ushort parameter is often used to send an index value when requesting + * The uint16_t parameter us is often used to send an index value when requesting * a certain element of an array of same data structures. * + * Transmission is protected by a mutex which is acquired before + * and released after the binary message has been sent. + * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES @@ -2203,23 +4285,27 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_AD * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_xmt_msg - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_xmt_cmd * @see ::mbgextio_req_data * @see ::mbgextio_req_data_idx */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t us ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + GPS_CMD cmd, uint16_t us ) { int rc; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif rc = xmt_cmd_us( pmctl, p_addr, cmd, us ); + if ( mbg_rc_is_success( rc ) ) + rc = mbgextio_check_ack( pmctl, p_addr, cmd ); + #if _USE_MUTEX - _mbg_mutex_release( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_release( &pmctl->dev_mutex ); #endif return rc; @@ -2235,28 +4321,38 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd_us( MBG_MSG_CTL *pmctl, const XBP * The ushort parameter is often used to send an index value when requesting * a specific element of an array of data structures. * - * @param[in,out] pmctl Pointer to a valid message control structure - * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_xmt_msg - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_xmt_cmd * @see ::mbgextio_xmt_cmd_us * @see ::mbgextio_req_data_idx */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_req_data( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_req_data( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + GPS_CMD cmd, void *buf, size_t buf_size ) { - int rc = xmt_cmd( pmctl, p_addr, cmd ); /* request a set of data */ + int rc; - if ( rc != MBG_SUCCESS ) // error - goto out; + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif - rc = mbgextio_rcv_msg( pmctl, p_addr, cmd ); + rc = xmt_cmd( pmctl, p_addr, cmd ); // request data + + if ( mbg_rc_is_success( rc ) ) + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, cmd, buf, buf_size ); // wait for the reply + + #if _USE_MUTEX + _mbg_mutex_release( &pmctl->dev_mutex ); + #endif -out: return rc; } // mbgextio_req_data @@ -2267,41 +4363,87 @@ out: /** * @brief Read a specific element of an array of data structures * - * The type of data is implicitely associated with the cmd parameter. + * This function dos not lock/unlock the device mutex, so this has to be done by + * The type of data is implicitly associated with the cmd parameter. + * The type of data is implicitly associated with the cmd parameter. * Usually the number of supported array elements has to be determined * by some other means, e.g. from a field in the ::RECEIVER_INFO structure. * - * @param[in,out] pmctl Pointer to a valid message control structure - * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES - * @param[in] idx The index of the array element to read + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[in] idx The index of the array element to read + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_xmt_msg - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked + * @see ::mbgextio_xmt_cmd + * @see ::mbgextio_req_data + * @see ::mbgextio_xmt_cmd_us + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_req_data_idx_unlocked( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + GPS_CMD cmd, uint16_t idx, void *buf, size_t buf_size ) +{ + int rc; + + rc = xmt_cmd_us( pmctl, p_addr, cmd, idx ); // request data + + if ( mbg_rc_is_success( rc ) ) + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, cmd, buf, buf_size ); // wait for the reply + + return rc; + +} // mbgextio_req_data_idx_unlocked + + + +/*HDR*/ +/** + * @brief Read a specific element of an array of data structures + * + * The type of data is implicitly associated with the cmd parameter. + * Usually the number of supported array elements has to be determined + * by some other means, e.g. from a field in the ::RECEIVER_INFO structure. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[in] idx The index of the array element to read + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_xmt_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_xmt_cmd * @see ::mbgextio_req_data * @see ::mbgextio_xmt_cmd_us */ _NO_MBG_API_ATTR int _MBG_API mbgextio_req_data_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, - GPS_CMD cmd, uint16_t idx ) + GPS_CMD cmd, uint16_t idx, void *buf, size_t buf_size ) { - int rc = xmt_cmd_us( pmctl, p_addr, cmd, idx ); // send a request for a set of data + int rc; - if ( rc < 0 ) // error - goto out; + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif - rc = mbgextio_rcv_msg( pmctl, p_addr, cmd ); // wait for the reply + rc = mbgextio_req_data_idx_unlocked( pmctl, p_addr, cmd, idx, buf, buf_size ); + + #if _USE_MUTEX + _mbg_mutex_release( &pmctl->dev_mutex ); + #endif -out: return rc; } // mbgextio_req_data_idx - /*HDR*/ /** * @brief Read a receiver info structure @@ -2326,13 +4468,10 @@ out: _NO_MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, RECEIVER_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_RECEIVER_INFO ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_RECEIVER_INFO, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.receiver_info; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_receiver_info( p ); - } return rc; @@ -2342,6 +4481,228 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl, /*HDR*/ /** + * @brief Read I/O port limits in ::MBG_IO_PORT_LIMITS format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent by the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_io_port_settings_idx + * @see ::mbgextio_get_io_port_info_idx + * @see ::mbgextio_get_io_port_type_info_idx + * @see ::mbgextio_get_io_port_status_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_io_port_limits( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + MBG_IO_PORT_LIMITS *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_IO_PORT_LIMITS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) ) + /* There is nothing to swaP */ + _mbg_swab_io_port_limits( p ); + + return rc; + +} // mbgextio_get_io_port_limits + + + +/*HDR*/ +/** + * @brief Send I/O port settings in ::MBG_IO_PORT_SETTINGS format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of I/O port settings to be configured, 0..MBG_IO_PORT_LIMITS::num_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_io_port_limits + * @see ::mbgextio_get_io_port_info_idx + * @see ::mbgextio_get_io_port_type_info_idx + * @see ::mbgextio_get_io_port_status_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_io_port_settings_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const MBG_IO_PORT_SETTINGS *p, + uint8_t idx ) +{ + GPS_CMD cmd = GPS_IO_PORT_SETTINGS_IDX | OPT_GPS_ACK_CODE; + MBG_IO_PORT_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.iop_settings_idx; + uint16_t sizes[] = MBG_IO_PORT_SETTINGS_IDX_SIZES; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + + _mbg_swab_io_port_settings_idx( p_data, 0 ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizes[p->type] ); + +} // mbgextio_set_io_port_settings_idx + + + +/*HDR*/ +/** + * @brief Read I/O port info in ::MBG_IO_PORT_INFO_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be read from the device + * @param[in] idx Index of I/O port info to be read, 0..MBG_IO_PORT_LIMITS::num_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_io_port_limits + * @see ::mbgextio_set_io_port_settings_idx + * @see ::mbgextio_get_io_port_type_info_idx + * @see ::mbgextio_get_io_port_status_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_io_port_info_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + MBG_IO_PORT_INFO_IDX *p, + uint8_t idx ) +{ + int rc; + size_t len; + MBG_MSG_BUFF *rbuf = mbgextio_get_rcv_buffer_addr(pmctl); + MBG_IO_PORT_INFO_IDX *iopi_idx = &rbuf->u.msg_data.iop_info_idx; + + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_IO_PORT_INFO_IDX, idx, NULL, 0 ); + if ( mbg_rc_is_error( rc ) ) + return rc; + + /* Check if at least header part is avail */ + if (rbuf->hdr.len < MBG_IO_PORT_INFO_IDX_MIN_SIZE) + return MBG_ERR_NBYTES; + + _mbg_swab_io_port_info_idx( iopi_idx, 1 ); + + len = sizeof(*p); + if (len > rbuf->hdr.len) + len = rbuf->hdr.len; + + memcpy(p, &rbuf->u.msg_data, len); + + return MBG_SUCCESS; + +} // mbgextio_get_io_port_info_idx + + + +/*HDR*/ +/** + * @brief Read I/O port type info in ::MBG_IO_PORT_TYPE_INFO_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be read from the device + * @param[in] port_idx Index of I/O port to be read, 0..MBG_IO_PORT_LIMITS::num_ports - 1 + * @param[in] port_type_idx Index of I/O port type info to be read, 0..MBG_IO_PORT_INFO::num_types - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_io_port_limits + * @see ::mbgextio_set_io_port_settings_idx + * @see ::mbgextio_get_io_port_info_idx + * @see ::mbgextio_get_io_port_status_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_io_port_type_info_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + MBG_IO_PORT_TYPE_INFO_IDX *p, + uint8_t port_idx, uint8_t port_type_idx) +{ + int rc; + size_t len; + uint16_t idx = ((port_idx << 8) | port_type_idx); + MBG_MSG_BUFF *rbuf = mbgextio_get_rcv_buffer_addr(pmctl); + MBG_IO_PORT_TYPE_INFO_IDX *iopti_idx = &rbuf->u.msg_data.iop_type_info_idx; + + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_IO_PORT_TYPE_INFO_IDX, idx, NULL, 0 ); + if ( mbg_rc_is_error( rc ) ) + return rc; + + /* Check if at least header part is avail */ + if (rbuf->hdr.len < MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE) + return MBG_ERR_NBYTES; + + _mbg_swab_io_port_type_info_idx( iopti_idx, 1 ); + + len = sizeof(*p); + if (len > rbuf->hdr.len) + len = rbuf->hdr.len; + + memcpy(p, &rbuf->u.msg_data, len); + + return MBG_SUCCESS; + +} // mbgextio_get_io_port_type_info_idx + + + +/*HDR*/ +/** + * @brief Read I/O port status in ::MBG_IO_PORT_STATUS_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be read from the device + * @param[in] idx Index of I/O port to be read, 0..MBG_IO_PORT_LIMITS::num_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_io_port_limits + * @see ::mbgextio_set_io_port_settings_idx + * @see ::mbgextio_get_io_port_info_idx + * @see ::mbgextio_get_io_port_type_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_io_port_status_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + MBG_IO_PORT_STATUS_IDX *p, + uint8_t idx) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_IO_PORT_STATUS_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_io_port_status_idx( p ); + + return rc; + +} // mbgextio_get_io_port_status_idx + + + +static /*HDR*/ +int chk_get_rcvr_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + RECEIVER_INFO *p ) +{ + #if DEBUG_INIT_CONN + static int cnt; + #endif + + // Try to read the RECEIVER_INFO structure from the device + int rc = mbgextio_get_receiver_info( pmctl, p_addr, p ); + + #if DEBUG_INIT_CONN + printf( "get rcvr info %i: %i\n", ++cnt, rc ); + #endif + + return rc; + +} // chk_get_rcvr_info + + + +/*HDR*/ +/** * @brief Setup a receiver info structure * * The ::RECEIVER_INFO should be read at first to identify the connected @@ -2362,12 +4723,107 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_setup_receiver_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, RECEIVER_INFO *p ) { - int rc = mbgextio_get_receiver_info( pmctl, p_addr, p ); + int rc; + + #if _USE_USB_IO + // If the device is a legacy USB device then it only supports a + // proprietary protocol instead of the standard binary protocol. + // We try to find this out based on the USB vendor and device IDs, + // and we need to check this *before* we try to read a RECEIVER_INFO + // structure from the device. + // See also ::mbgextio_dev_is_legacy + if ( pmctl->conn_type == MBG_CONN_TYPE_USB ) + { + RECEIVER_INFO *p_ri = mbgextio_get_receiver_info_addr( pmctl ); + rc = check_setup_legacy_usb_device(&pmctl->st.usbio.mdev_info, p_ri ); - if ( rc == MBG_SUCCESS ) //##++++++++++++++ or in all cases except of MBG_ERR_TIMEOUT ? + if ( mbg_rc_is_success( rc ) ) + { + // A legacy device was detected, and an appropriate RECEIVER_INFO + // for this device has been set up. + pmctl->device_flags |= MSG_CTL_DEVICE_FLAG_MSK_LEGACY; + goto out; + } + } + #endif // _USE_USB_IO + + // Try to read the RECEIVER_INFO structure from the device + rc = chk_get_rcvr_info( pmctl, p_addr, p ); + + if ( mbg_rc_is_success( rc ) ) + goto out; // RECEIVER_INFO was read successfully + + // Failed, but eventually some synchronization is required, + // e.g. if the baud rate was just changed, so retry once. + rc = chk_get_rcvr_info( pmctl, p_addr, p ); + + if ( mbg_rc_is_success( rc ) ) + goto out; // RECEIVER_INFO was read successfully from the device. + + // In all error cases except MBG_ERR_TIMEOUT we return with error anyway. + if ( rc != MBG_ERR_TIMEOUT ) goto out; - //##+++++++++++++ TODO try to read SW_REV, etc., evt. depending on p_addr == NULL or not + + // There are a few very old devices which support the binary protocol but + // don't support reading a RECEIVER_INFO, so we check if we can set up + // a default structure, depending on a device type. + // + // Affected devices, at least: + // GPS166 (all versions) + // GPS167PC (all versions) + // GPS167PCI < 4.22 + // GPS167 < 4.17 + // GPS167SV < 4.17 + { + SW_REV sw_rev = { 0 }; + IDENT ident = { { 0 } }; + + rc = mbgextio_get_sw_rev( pmctl, p_addr, &sw_rev ); + + if ( mbg_rc_is_error( rc ) ) // Failed to read SW revision, so + goto out; // probably no device connected. + + // set up a default receiver info structure + _setup_default_receiver_info_gps( p ); + + // set up some generic device name + sn_cpy_str_safe( p->model_name, sizeof( p->model_name ), "GPS16x" ); + + // copy the software revision info we have read from the device + p->sw_rev = sw_rev; + trim_whitespace( p->sw_rev.name ); + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + xmt_cmd( pmctl, p_addr, 0x400 ); + xmt_cmd( pmctl, p_addr, 0x20F ); + xmt_cmd( pmctl, p_addr, 0x001 ); + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, 0x20F, &ident, sizeof( ident ) ); + + #if _USE_MUTEX + _mbg_mutex_release( &pmctl->dev_mutex ); + #endif + + if ( mbg_rc_is_success( rc ) ) + { + // Unfortunately there are older devices and firmware versions out there + // where the serial number is saved word-wise, and others where it is + // saved byte-wise, so it can be really tricky to get it right. + // If we want to giver it a try we need to add some other library modules + #if _TRY_IDENT_DECODE + mbg_gps_ident_decode( p->sernum, &ident ); + #else + sn_cpy_str_safe( p->sernum, sizeof( p->sernum ), ident.c ); + #endif + } + + // Return successful in any case since we could + // at least read the SW_REV structure. + rc = MBG_SUCCESS; + } out: return rc; @@ -2395,13 +4851,10 @@ out: _NO_MBG_API_ATTR int _MBG_API mbgextio_get_sw_rev( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, SW_REV *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_SW_REV ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_SW_REV, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.sw_rev; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_sw_rev( p ); - } return rc; @@ -2411,6 +4864,65 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_sw_rev( MBG_MSG_CTL *pmctl, /*HDR*/ /** + * @brief Read the status of ignore lock + * + * @note Only supported if ::GPS_HAS_IGNORE_LOCK + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @see mbgextio_set_ignore_lock + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ignore_lock( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IGNORE_LOCK *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_IGNORE_LOCK, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab16( p ); + + return rc; + +} // mbgextio_get_ignore_lock + + + +/*HDR*/ +/** + * @brief Send the ignore lock configuration + * + * @note Only supported if ::GPS_HAS_IGNORE_LOCK + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ignore_lock + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ignore_lock( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const IGNORE_LOCK *p ) +{ + GPS_CMD cmd = GPS_IGNORE_LOCK | OPT_GPS_ACK_CODE; + IGNORE_LOCK *p_data = &pmctl->xmt.pmb->u.msg_data.ignore_lock; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab16( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ignore_lock + + + +/*HDR*/ +/** * @brief Read the status of buffered variables * * @note Only supported if ::GPS_MODEL_HAS_BVAR_STAT @@ -2424,13 +4936,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_sw_rev( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_bvar_stat( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, BVAR_STAT *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_BVAR_STAT ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_BVAR_STAT, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.bvar_stat; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_bvar_stat( p ); - } return rc; @@ -2442,27 +4951,25 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_bvar_stat( MBG_MSG_CTL *pmctl, /** * @brief Read the current time as ::TTM strucure * - * @note This function is only supported by GPS receivers. + * @note This function is only supported if the device has ::MBG_XFEATURE_REQ_TTM * - * The returned time is not very accurate since the response time - * transmission delay can't be determmined. + * The returned time is not very accurate since the request can be sent at any time and + * the response is sent immediately and not after a second change. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data * * @return One of the @ref MBG_RETURN_CODES + * + * @see mbgextio_dev_has_req_ttm */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_get_time( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, TTM *p ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TTM *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_TIME ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_TIME, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ttm; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_ttm( p ); - } return rc; @@ -2491,7 +4998,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_time( MBG_MSG_CTL *pmctl, TTM *p_data = &pmctl->xmt.pmb->u.msg_data.ttm; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -2523,7 +5030,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_pos_lla( MBG_MSG_CTL *pmctl, int i; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif for ( i = 0; i < N_LLA; i++ ) @@ -2554,18 +5061,14 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_pos_lla( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos_lla( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, LLA lla ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_POS_LLA ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_POS_LLA, lla, sizeof( LLA ) ); - if ( ( rc == MBG_SUCCESS ) && lla ) + if ( mbg_rc_is_success( rc ) && lla ) { - MSG_DATA *pmb = &pmctl->rcv.pmb->u.msg_data; int i; for ( i = 0; i < N_LLA; i++ ) - { - swap_double( &pmb->lla[i] ); - lla[i] = pmb->lla[i]; - } + swap_double( &lla[i] ); } return rc; @@ -2589,18 +5092,14 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos_lla( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos_xyz( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XYZ xyz ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_POS_XYZ ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_POS_XYZ, xyz, sizeof( XYZ ) ); - if ( ( rc == MBG_SUCCESS ) && xyz ) + if ( mbg_rc_is_success( rc ) && xyz ) { - MSG_DATA *pmb = &pmctl->rcv.pmb->u.msg_data; int i; for ( i = 0; i < N_XYZ; i++ ) - { - swap_double( &pmb->xyz[i] ); - xyz[i] = pmb->xyz[i]; - } + swap_double( &xyz[i] ); } return rc; @@ -2626,13 +5125,12 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pos( MBG_MSG_CTL *pmctl, { int rc = mbgextio_get_pos_xyz( pmctl, p_addr, p_pos->xyz ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) goto out; - rc = mbgextio_get_pos_lla( pmctl, p_addr, p_pos->lla ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) goto out; lla_to_dms( p_pos ); @@ -2659,13 +5157,10 @@ out: _NO_MBG_API_ATTR int _MBG_API mbgextio_get_tzdl( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TZDL *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_TZDL ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_TZDL, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.tzdl; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_tzdl( p ); - } return rc; @@ -2692,7 +5187,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_tzdl( MBG_MSG_CTL *pmctl, TZDL *p_data = &pmctl->xmt.pmb->u.msg_data.tzdl; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -2727,13 +5222,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_tzdl( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_port_parm( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PORT_PARM *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_PORT_PARM ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PORT_PARM, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.port_parm; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_port_parm( p ); - } return rc; @@ -2768,7 +5260,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_port_parm( MBG_MSG_CTL *pmctl, PORT_PARM *p_data = &pmctl->xmt.pmb->u.msg_data.port_parm; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -2797,13 +5289,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_port_parm( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_synth( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, SYNTH *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_SYNTH ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_SYNTH, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.synth; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_synth( p ); - } return rc; @@ -2832,7 +5321,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_synth( MBG_MSG_CTL *pmctl, SYNTH *p_data = &pmctl->xmt.pmb->u.msg_data.synth; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -2859,13 +5348,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_synth( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ant_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ANT_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_ANT_INFO ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_ANT_INFO, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ant_info; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_ant_info( p ); - } return rc; @@ -2890,7 +5376,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, { int rc = xmt_cmd( pmctl, p_addr, GPS_UCAP ); /* request a set of data */ - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) goto out; // Attention: Older firmware versions may reply with GPS_TIME @@ -2898,9 +5384,9 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, // at all if no capture event is available in the on-board FIFO. for (;;) { - rc = mbgextio_rcv_msg( pmctl, p_addr, -1 ); + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, -1, NULL, 0 ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) goto out; if ( pmctl->rcv.pmb->hdr.cmd == GPS_UCAP ) @@ -2935,6 +5421,124 @@ out: /*HDR*/ /** + * @brief Read the user capture network global info in ::MBG_UCAP_NET_GLB_INFO format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ucap_net_glb_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_UCAP_NET_GLB_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_UCAP_NET_GLB_INFO, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ucap_net_glb_info( p ); + + return rc; + +} // mbgextio_get_ucap_net_glb_info + + + +/*HDR*/ +/** + * @brief Send the user capture network global configuration in ::MBG_UCAP_NET_GLB_SETTINGS format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ucap_net_glb_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_UCAP_NET_GLB_SETTINGS *p ) +{ + GPS_CMD cmd = GPS_UCAP_NET_GLB_INFO | OPT_GPS_ACK_CODE; + MBG_UCAP_NET_GLB_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ucap_net_glb_settings; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ucap_net_glb_settings( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ucap_net_glb_settings + + + +/*HDR*/ +/** + * @brief Read the user capture network receiver info with the given index + * in ::MBG_UCAP_NET_RECV_INFO_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received dat + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_UCAP_NET_GLB_INFO::settings::num_recvs + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ucap_net_recv_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_UCAP_NET_RECV_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_UCAP_NET_RECV_INFO_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ucap_net_recv_info_idx( p ); + + return rc; + +} // mbgextio_get_ucap_net_recv_info_idx + + + +/*HDR*/ +/** + * @brief Send the user capture network receiver configuration with the given index + * in ::MBG_UCAP_NET_RECV_SETTINGS_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be sent, 0..::MBG_UCAP_NET_GLB_INFO::settings::num_recvs + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ucap_net_recv_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_UCAP_NET_RECV_SETTINGS_IDX *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_UCAP_NET_RECV_INFO_IDX | OPT_GPS_ACK_CODE; + MBG_UCAP_NET_RECV_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ucap_net_recv_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ucap_net_recv_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ucap_net_recv_settings_idx + + + +/*HDR*/ +/** * @brief Read the enable flags controlling when output signals are enabled * * @note Some devices may not support ::ENABLE_FLAGS @@ -2950,13 +5554,10 @@ out: _NO_MBG_API_ATTR int _MBG_API mbgextio_get_enable_flags( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ENABLE_FLAGS *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_ENABLE_FLAGS ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_ENABLE_FLAGS, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.enable_flags; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_enable_flags( p ); - } return rc; @@ -2985,7 +5586,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_enable_flags( MBG_MSG_CTL *pmctl, ENABLE_FLAGS *p_data = &pmctl->xmt.pmb->u.msg_data.enable_flags; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -3009,20 +5610,17 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_enable_flags( MBG_MSG_CTL *pmctl, * * @return One of the @ref MBG_RETURN_CODES */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_get_stat_info( MBG_MSG_CTL *pmctl, +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_gps_stat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STAT_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_STAT_INFO ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_STAT_INFO, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.stat_info; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_stat_info( p ); - } return rc; -} // mbgextio_get_stat_info +} // mbgextio_get_gps_stat_info @@ -3030,7 +5628,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_stat_info( MBG_MSG_CTL *pmctl, /** * @brief Read the configured length of the antenna cable * - * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LENGTH + * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LEN * * @note Some older devices may not reply to this request unless * the application has registered itself as terminal application @@ -3047,13 +5645,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_stat_info( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ant_cable_len( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, ANT_CABLE_LEN *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_ANT_CABLE_LENGTH ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_ANT_CABLE_LENGTH, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ant_cable_len; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_ant_cable_len( p ); - } return rc; @@ -3065,7 +5660,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ant_cable_len( MBG_MSG_CTL *pmctl, /** * @brief Send the GPS antenna cable length configuration * - * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LENGTH + * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LEN * @note Different devices may accept different maximum values, so the * written value should be re-read using ::mbgextio_get_ant_cable_len @@ -3086,7 +5681,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ant_cable_len( MBG_MSG_CTL *pmctl, ANT_CABLE_LEN *p_data = &pmctl->xmt.pmb->u.msg_data.ant_cable_len; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -3115,13 +5710,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ant_cable_len( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_irig_tx_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IRIG_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_IRIG_TX_INFO ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_IRIG_TX_INFO, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.irig_tx_info; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_irig_info( p ); - } return rc; @@ -3150,7 +5742,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_tx_settings( MBG_MSG_CTL *pmctl, IRIG_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.irig_tx_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -3179,13 +5771,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_tx_settings( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_irig_rx_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IRIG_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_IRIG_RX_INFO ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_IRIG_RX_INFO, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.irig_rx_info; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_irig_info( p ); - } return rc; @@ -3214,7 +5803,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_rx_settings( MBG_MSG_CTL *pmctl, IRIG_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.irig_rx_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -3228,6 +5817,40 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_rx_settings( MBG_MSG_CTL *pmctl, /*HDR*/ /** + * @brief Read raw IRIG data + * + * The ::MBG_RAW_IRIG_DATA structure can be read for debugging purposes, + * to decode application defined bits in the control field (CF) segment + * of the incoming time code, etc. Usually the data set is only updated + * once per second, even if the code format provides many data frames + * per second. + * + * @note Call ::mbgextio_dev_has_raw_irig_data to check if this is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @see ::mbgextio_dev_has_raw_irig_data + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_raw_irig_data( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, MBG_RAW_IRIG_DATA *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_RAW_IRIG_DATA, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_raw_irig_data( p ); + + return rc; + +} // mbgextio_get_raw_irig_data + + + +/*HDR*/ +/** * @brief Read current ref offset to %UTC configuration * * @note This is only supported if ::GPS_HAS_REF_OFFS is set in ::RECEIVER_INFO::features, @@ -3244,13 +5867,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_rx_settings( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ref_offs( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_REF_OFFS *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_REF_OFFS ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_REF_OFFS, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ref_offs; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_mbg_ref_offs( p ); - } return rc; @@ -3280,7 +5900,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ref_offs( MBG_MSG_CTL *pmctl, MBG_REF_OFFS *p_data = &pmctl->xmt.pmb->u.msg_data.ref_offs; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -3308,13 +5928,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ref_offs( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_debug_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_DEBUG_STATUS *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_DEBUG_STATUS ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_DEBUG_STATUS, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.debug_status; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_debug_status( p ); - } return rc; @@ -3339,13 +5956,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_debug_status( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_opt_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_OPT_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_OPT_INFO ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_OPT_INFO, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.opt_info; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_mbg_opt_info( p ); - } return rc; @@ -3374,7 +5988,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_opt_settings( MBG_MSG_CTL *pmctl, MBG_OPT_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.opt_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -3405,11 +6019,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_opt_settings( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_str_type_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX *p, uint16_t idx ) { - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_STR_TYPE_INFO_IDX, idx ); + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_STR_TYPE_INFO_IDX, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) + if ( mbg_rc_is_success( rc ) && p ) { - *p = pmctl->rcv.pmb->u.msg_data.str_type_info_idx; _mbg_swab_str_type_info_idx( p ); #if 0 //##++ TODO: check if received idx matches requested idx @@ -3437,24 +6050,24 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_str_type_info_idx( MBG_MSG_CTL *pmctl * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] stii An array which can hold at least ::RECEIVER_INFO::n_str_type entries - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_get_str_type_info_idx */ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_str_type_info( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[], - const RECEIVER_INFO *p_ri ) + const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[] ) { int rc = MBG_SUCCESS; + RECEIVER_INFO *p_ri = mbgextio_get_receiver_info_addr( pmctl ); + int n_str_type = p_ri->n_str_type; uint16_t i; - for ( i = 0; i < p_ri->n_str_type; i++ ) + for ( i = 0; i < n_str_type; i++ ) { rc = mbgextio_get_str_type_info_idx( pmctl, p_addr, &stii[i], i ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) break; } @@ -3483,11 +6096,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_str_type_info( MBG_MSG_CTL *pmctl _NO_MBG_API_ATTR int _MBG_API mbgextio_get_port_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PORT_INFO_IDX *p, uint16_t idx ) { - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_PORT_INFO_IDX, idx ); + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_PORT_INFO_IDX, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) + if ( mbg_rc_is_success( rc ) && p ) { - *p = pmctl->rcv.pmb->u.msg_data.port_info_idx; _mbg_swab_port_info_idx( p ); #if 0 //##++ TODO: check if received idx matches requested idx @@ -3515,7 +6127,6 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_port_info_idx( MBG_MSG_CTL *pmctl, * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] pii An array which can hold at least ::RECEIVER_INFO::n_com_ports entries - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure * * @return One of the @ref MBG_RETURN_CODES * @@ -3523,17 +6134,18 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_port_info_idx( MBG_MSG_CTL *pmctl, * @see ::mbgextio_set_port_settings_idx */ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_port_info( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, PORT_INFO_IDX pii[], - const RECEIVER_INFO *p_ri ) + const XBP_ADDR *p_addr, PORT_INFO_IDX pii[] ) { int rc = MBG_SUCCESS; + RECEIVER_INFO *p_ri = mbgextio_get_receiver_info_addr( pmctl ); + int n_com_ports = p_ri->n_com_ports; uint16_t i; - for ( i = 0; i < p_ri->n_com_ports; i++ ) + for ( i = 0; i < n_com_ports; i++ ) { rc = mbgextio_get_port_info_idx( pmctl, p_addr, &pii[i], i ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) break; } @@ -3566,7 +6178,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_port_settings_idx( MBG_MSG_CTL *pmctl PORT_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.port_settings_idx; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif p_data->port_settings = *p; @@ -3598,11 +6210,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_port_settings_idx( MBG_MSG_CTL *pmctl _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pout_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, POUT_INFO_IDX *p, uint16_t idx ) { - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_POUT_INFO_IDX, idx ); + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_POUT_INFO_IDX, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) + if ( mbg_rc_is_success( rc ) && p ) { - *p = pmctl->rcv.pmb->u.msg_data.pout_info_idx; _mbg_swab_pout_info_idx_on_get( p ); #if 0 //##++ TODO: check if received idx matches requested idx @@ -3630,26 +6241,27 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pout_info_idx( MBG_MSG_CTL *pmctl, * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] pii An array which can hold at least ::RECEIVER_INFO::n_prg_out entries - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_get_pout_info_idx * @see ::mbgextio_set_pout_settings_idx */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_pout_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, - POUT_INFO_IDX *pii, const RECEIVER_INFO *p_ri ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_pout_info( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, POUT_INFO_IDX *pii ) { int rc = MBG_SUCCESS; + RECEIVER_INFO *p_ri = mbgextio_get_receiver_info_addr( pmctl ); + int n_prg_out = p_ri->n_prg_out; uint16_t i; - memset( pii, 0, p_ri->n_prg_out * sizeof( *pii ) ); + memset( pii, 0, n_prg_out * sizeof( *pii ) ); - for ( i = 0; i < p_ri->n_prg_out; i++ ) + for ( i = 0; i < n_prg_out; i++ ) { rc = mbgextio_get_pout_info_idx( pmctl, p_addr, &pii[i], i ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) break; } @@ -3682,7 +6294,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl POUT_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.pout_settings_idx; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif p_data->pout_settings = *p; @@ -3697,6 +6309,42 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl /*HDR*/ /** + * @brief Send configuration settings for a specific GPIO + * + * @note This is only supported if ::GPS_HAS_GPIO is set in ::RECEIVER_INFO::features + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the pulse output to be configured, 0..MBG_GPIO_CFG_LIMITS::num_io - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_gpio_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_gpio_settings_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, const MBG_GPIO_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_GPIO_SETTINGS_IDX | OPT_GPS_ACK_CODE; + MBG_GPIO_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.gpio_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + + _mbg_swab_mbg_gpio_settings_idx( p_data, 0 ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_gpio_settings_idx + + + +/*HDR*/ +/** * @brief Clear the user capture event buffer on-board the device * * @param[in,out] pmctl Pointer to a valid message control structure @@ -3706,7 +6354,8 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl * * @see ::mbgextio_get_ucap */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_clr_ucap_buff( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_clr_ucap_buff( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr ) { return mbgextio_xmt_cmd( pmctl, p_addr, GPS_CLR_UCAP_BUFF ); @@ -3731,13 +6380,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_clr_ucap_buff( MBG_MSG_CTL *pmctl, const _NO_MBG_API_ATTR int _MBG_API mbgextio_get_time_scale_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_TIME_SCALE_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_TIME_SCALE ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_TIME_SCALE, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.time_scale_info; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_mbg_time_scale_info( p ); - } return rc; @@ -3766,7 +6412,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_time_scale_settings( MBG_MSG_CTL *pmc MBG_TIME_SCALE_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.time_scale_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -3793,7 +6439,8 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_time_scale_settings( MBG_MSG_CTL *pmc * @see ::mbgextio_get_first_evt_log_entry * @see ::mbgextio_get_next_evt_log_entry */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_clr_evt_log( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_clr_evt_log( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr ) { return mbgextio_xmt_cmd( pmctl, p_addr, GPS_CLR_EVT_LOG ); @@ -3820,13 +6467,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_clr_evt_log( MBG_MSG_CTL *pmctl, const XB _NO_MBG_API_ATTR int _MBG_API mbgextio_get_num_evt_log_entries( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NUM_EVT_LOG_ENTRIES *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_NUM_EVT_LOG_ENTRIES ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NUM_EVT_LOG_ENTRIES, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.num_evt_log_entries; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_mbg_num_evt_log_entries( p ); - } return rc; @@ -3856,13 +6500,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_num_evt_log_entries( MBG_MSG_CTL *pmc _NO_MBG_API_ATTR int _MBG_API mbgextio_get_first_evt_log_entry( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_EVT_LOG_ENTRY *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_FIRST_EVT_LOG_ENTRY ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_FIRST_EVT_LOG_ENTRY, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.evt_log_entry; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_mbg_evt_log_entry( p ); - } return rc; @@ -3894,13 +6535,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_first_evt_log_entry( MBG_MSG_CTL *pmc _NO_MBG_API_ATTR int _MBG_API mbgextio_get_next_evt_log_entry( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_EVT_LOG_ENTRY *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_NEXT_EVT_LOG_ENTRY ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NEXT_EVT_LOG_ENTRY, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.evt_log_entry; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_mbg_evt_log_entry( p ); - } return rc; @@ -3912,7 +6550,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_next_evt_log_entry( MBG_MSG_CTL *pmct /** * @brief Read the current IMS state and supported IMS features * - * @note This is only supported if ::GPS_HAS_IMS is set in ::RECEIVER_INFO::features + * @note This is only supported if ::mbgextio_dev_has_ims returns MBG_SUCCESS * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL @@ -3925,13 +6563,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_next_evt_log_entry( MBG_MSG_CTL *pmct _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_STATE *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_IMS_STATE ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_IMS_STATE, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ims_state; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_mbg_ims_state( p ); - } return rc; @@ -3958,13 +6593,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_state( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_sensor_state_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_SENSOR_STATE_IDX *p, uint16_t idx ) { - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_IMS_SENSOR_STATE_IDX, idx ); + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_IMS_SENSOR_STATE_IDX, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ims_sensor_state_idx; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_mbg_ims_sensor_state_idx( p ); - } return rc; @@ -3993,7 +6625,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_holdover_interval( MBG_MSG_CTL *pmctl XMR_HOLDOVER_INTV *p_data = &pmctl->xmt.pmb->u.msg_data.xmr_holdover_intv; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -4022,13 +6654,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_holdover_interval( MBG_MSG_CTL *pmctl _NO_MBG_API_ATTR int _MBG_API mbgextio_get_holdover_interval_counter( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMR_HOLDOVER_INTV *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_XMR_HOLDOVER_INTV ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_XMR_HOLDOVER_INTV, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.xmr_holdover_intv; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_xmr_holdover_intv( p ); - } return rc; @@ -4038,6 +6667,30 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_holdover_interval_counter( MBG_MSG_CT /*HDR*/ /** + * @brief Read the multi ref info from a device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmulti_ref_info_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, XMULTI_REF_INFO_IDX *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_MULTI_REF_INFO, p, sizeof( *p ) ); + + if ( ( rc == MBG_SUCCESS ) && p ) + *p = pmctl->rcv.pmb->u.msg_data.xmulti_ref_info_idx; + + return rc; + +} // mbgextio_get_xmulti_ref_info_idx + + + +/*HDR*/ +/** * @brief Read the local time conversion configuration in ::TZCODE format * * @note Some devices may not support ::TZCODE configuration @@ -4053,13 +6706,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_holdover_interval_counter( MBG_MSG_CT _NO_MBG_API_ATTR int _MBG_API mbgextio_get_tzcode( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TZCODE *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, PZF_TZCODE ); + int rc = mbgextio_req_data( pmctl, p_addr, PZF_TZCODE, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.tzcode; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_tzcode( p ); - } return rc; @@ -4088,7 +6738,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_tzcode( MBG_MSG_CTL *pmctl, TZCODE *p_data = &pmctl->xmt.pmb->u.msg_data.tzcode; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -4115,13 +6765,13 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_tzcode( MBG_MSG_CTL *pmctl, * @see //##+++++++++++++++++++++ */ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_tx_settings( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, HAVEQUICK_SETTINGS *p ) + const XBP_ADDR *p_addr, const HAVEQUICK_SETTINGS *p ) { GPS_CMD cmd = GPS_HAVEQUICK_TX_SETTINGS | OPT_GPS_ACK_CODE; HAVEQUICK_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.havequick_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -4148,13 +6798,13 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_tx_settings( MBG_MSG_CTL *pmctl, * @see //##+++++++++++++++++++++ */ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_rx_settings( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, HAVEQUICK_SETTINGS *p ) + const XBP_ADDR *p_addr, const HAVEQUICK_SETTINGS *p ) { GPS_CMD cmd = GPS_HAVEQUICK_RX_SETTINGS | OPT_GPS_ACK_CODE; HAVEQUICK_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.havequick_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -4183,13 +6833,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_rx_settings( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_tr_distance( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TR_DISTANCE *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, PZF_TR_DISTANCE ); + int rc = mbgextio_req_data( pmctl, p_addr, PZF_TR_DISTANCE, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.tr_distance; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_tr_distance( p ); - } return rc; @@ -4218,7 +6865,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_tr_distance( MBG_MSG_CTL *pmctl, TR_DISTANCE *p_data = &pmctl->xmt.pmb->u.msg_data.tr_distance; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -4247,13 +6894,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_tr_distance( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_gnss_mode_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_GNSS_MODE_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_GNSS_MODE ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_GNSS_MODE, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.gnss_mode_info; - _mbg_swab_dummy( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_gnss_mode_info( p ); return rc; @@ -4282,11 +6926,11 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_gnss_mode_settings( MBG_MSG_CTL *pmct MBG_GNSS_MODE_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.gnss_mode_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; - _mbg_swab_dummy( p_data ); + _mbg_swab_mbg_gnss_mode_settings( p_data ); return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); @@ -4296,31 +6940,104 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_gnss_mode_settings( MBG_MSG_CTL *pmct /*HDR*/ /** - * @brief Read an array of all supported string types //##+++++++++++++++++++++++++++++++++++++++++++++++ TODO + * @brief ::TODO * + * ### TODO this is obsolete + * Retrieve a single entry from an array of supported string types. * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[out] stii An array which can hold at least ::RECEIVER_INFO::n_str_type entries - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure + * @param[out] p Pointer to the data structure to return the received data * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_get_str_type_info_idx + * @see ::TODO + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_gnss_sat_info( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, GNSS_SAT_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_GNSS_SAT_INFO, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_gnss_sat_info( p ); + + return rc; + +} // mbgextio_get_gnss_sat_info + + + +/*HDR*/ +/** + * @brief ::TODO + * + * ### TODO + * Retrieve a single entry from an array of supported string types. + * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_str_type - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::TODO + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_gnss_sat_info_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, GNSS_SAT_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_GNSS_SAT_INFO_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + { + _mbg_swab_gnss_sat_info_idx( p ); + + #if 0 //##++ TODO: check if received idx matches requested idx + if ( pii.idx != i ) + { + printf( "** Info for port %i requested, but for %i received.\n", + pii.idx, i ); + rc = ...; + } + #endif + } + + return rc; + +} // mbgextio_get_gnss_sat_info_idx + + + +/*HDR*/ +/** + * @brief ::TODO Read an array of all supported string types + * + * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] gsii ::TODO + * @param[in] p_mi ::TODO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::TODO */ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gnss_sat_info( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[], - const RECEIVER_INFO *p_ri ) + const XBP_ADDR *p_addr, GNSS_SAT_INFO_IDX gsii[], + const MBG_GNSS_MODE_INFO *p_mi ) { int rc = MBG_SUCCESS; + int n_supp = num_bits_set( p_mi->supp_gnss_types ); uint16_t i; - for ( i = 0; i < p_ri->n_str_type; i++ ) + for ( i = 0; i < n_supp; i++ ) { - rc = mbgextio_get_str_type_info_idx( pmctl, p_addr, &stii[i], i ); + rc = mbgextio_get_gnss_sat_info_idx( pmctl, p_addr, &gsii[i], i ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) break; } @@ -4332,93 +7049,165 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gnss_sat_info( MBG_MSG_CTL *pmctl /*HDR*/ /** - * @brief Fill up a GNSS info structure //##+++++++++++++++++++++++++++++++++++++++++++++++ TODO + * @brief ::TODO + * + * ### TODO * * @param[in,out] pmctl Pointer to a valid message control structure - * @param[out] p_si Pointer to a ::STAT_INFO the data structure to return the received data - * @param[out] p_gmi Index of the NTP peer state to be configured, 0..::NTP_CLNT_MODE_INFO::n_supp_peers - 1 - * @param[out] p_gsii Blah ... //##++++++++++ TODO - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_str_type - 1 * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_get_ntp_sys_state - * @see ::mbgextio_get_ntp_peer_settings_idx - * @see ::mbgextio_get_ntp_clnt_mode_info + * @see @ref group_gnss_sv_status ::TODO */ -int mbgextio_chk_get_gnss_info( MBG_MSG_CTL *pmctl, STAT_INFO *p_si, - MBG_GNSS_MODE_INFO *p_gmi, GNSS_SAT_INFO_IDX *p_gsii, - const RECEIVER_INFO *p_ri ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_gnss_sv_status_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, GNSS_SV_STATUS_IDX *p, uint16_t idx ) { - int n_gnss_supp = 0; - int rc = -1; -#if 0 - int i = -1; + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_GNSS_SV_STATUS_IDX, idx, p, sizeof( *p ) ); -#if 0 //##++++++++++++++ - if ( !_pcps_has_stat_info( p_dev ) ) - return 0; -#endif - - rc = mbgextio_get_stat_info( pmctl, p_si ); - - if ( rc < 0 ) - goto fail; + if ( mbg_rc_is_success( rc ) && p ) + { + _mbg_swab_gnss_sv_status_idx( p ); + #if 0 //##++ TODO: check if received idx matches requested idx + if ( pii.idx != i ) + { + printf( "** Info for port %i requested, but for %i received.\n", + pii.idx, i ); + rc = ...; + } + #endif + } -//##+++++++++++++ if ( _pcps_is_gnss( p_dev ) ) - { - if ( ( rc = mbgextio_get_gnss_mode_info( pmctl, p_gmi ) ) < 0 ) - goto fail; + return rc; -// mbgextio_get_all_gnss_sat_info - for ( i = 0; i < p_gmi-> ; i++ ) - rc = mbgextio_get_all_gnss_sat_info( pmctl, p_gsii, p_gmi ); +} // mbgextio_get_gnss_sv_status_idx - if ( rc < 0 ) - goto fail; - } -//##++++ else - { -//##++++ if ( _pcps_has_stat_info_svs( p_dev ) ) // GPS is supported - { - GNSS_SAT_INFO *p_gsi; - // setup GNSS info from stat_info so we can use the same printing routine - p_gmi->supp_gnss_types = MBG_GNSS_TYPE_MSK_GPS; - p_gmi->settings.gnss_set = p_gmi->supp_gnss_types; - p_gsi = &p_gsii->gnss_sat_info; - p_gsi->gnss_type = GNSS_TYPE_GPS; - p_gsi->svs_in_view = p_si->svs_in_view; - p_gsi->good_svs = p_si->good_svs; - } - } +#if 0 ///### TODO - n_gnss_supp = num_bits_set( p_gmi->supp_gnss_types ); + /*HDR*/ +/** + * @brief ::TODO + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] gsii ::TODO + * @param[in] p_mi ::TODO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::TODO + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gnss_sat_info( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, GNSS_SAT_INFO_IDX gsii[], + const MBG_GNSS_MODE_INFO *p_mi ) +{ + int rc = MBG_SUCCESS; + int n_supp = num_bits_set( p_mi->supp_gnss_types ); + uint16_t i; - if ( n_gnss_supp > N_GNSS_TYPES ) + for ( i = 0; i < n_supp; i++ ) { - //##++++ show warning: device supports more GNSS types than this program - n_gnss_supp = N_GNSS_TYPES; + rc = mbgextio_get_gnss_sat_info_idx( pmctl, p_addr, &gsii[i], i ); + + if ( mbg_rc_is_error( rc ) ) + break; } - return n_gnss_supp; + return rc; +} // mbgextio_get_all_gnss_sat_info -fail: #endif + + + +/*HDR*/ +/** + * @brief Read ::XMULTI_REF_INSTANCES + * + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features AND + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_instances( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + XMULTI_REF_INSTANCES *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_XMR_INSTANCES, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) ) + _mbg_swab_xmulti_ref_instances( p ); + return rc; -} // mbg_chk_get_gnss_info +} // mbgextio_get_xmr_instances /*HDR*/ /** - * @brief Read the supported XMR features in ::XMULTI_REF_INFO_IDX format + * @brief Read ::XMR_EXT_SRC_INFO_IDX * - * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features. + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features AND + * ::XMRIF_MSK_EXT_SRC_INFO_SUPP is set in ::XMULTI_REF_INSTANCES::flags. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_holdover_status + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_ext_src_info_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + XMR_EXT_SRC_INFO_IDX *p, + uint16_t idx) +{ + int rc; + + p->idx = idx; + + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XMR_EXT_SRC_INFO_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) ) + _mbg_swab_xmr_ext_src_info_idx( p ); + + return rc; + +} // mbgextio_get_xmr_ext_src_info_idx + + + +/*HDR*/ +/** + * @brief Read ::XMR_HOLDOVER_STATUS + * + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features AND + * ::XMRIF_MSK_HOLDOVER_STATUS_SUPP is set in ::XMULTI_REF_INSTANCES::flags. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL @@ -4426,89 +7215,259 @@ fail: * * @return One of the @ref MBG_RETURN_CODES * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_holdover_status( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + XMR_HOLDOVER_STATUS *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_XMR_HOLDOVER_STATUS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) ) + _mbg_swab_xmr_holdover_status( p ); + + return rc; + +} // mbgextio_get_xmr_holdover_status + + + +/*HDR*/ +/** + * @brief Read ::XMULTI_REF_INFO_IDX for a specific XMR source + * + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx */ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_info_idx( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, XMULTI_REF_INFO_IDX *p ) + const XBP_ADDR *p_addr, + XMULTI_REF_INFO_IDX *p, + uint16_t idx) { - uint16_t idx = p->idx; - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XMR_INFO_IDX, idx ); + int rc; - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.xmulti_ref_info_idx; - _mbg_swab_dummy( p ); //##++++++ _mbg_xmr_info_idx( p ); - } + p->idx = idx; + + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XMR_INFO_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) ) + _mbg_swab_xmulti_ref_info_idx( p ); return rc; } // mbgextio_get_xmr_info_idx - /*HDR*/ /** - * @brief Read the supported XMR features ::XMULTI_REF_STATUS_IDX format + * @brief Read ::XMULTI_REF_STATUS_IDX for a specific XMR source * - * @note Only for devices which supports Multi references - * @note GPS_HAS_XMULTI_REF feature must set + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 * * @return One of the @ref MBG_RETURN_CODES * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx */ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_status_idx( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, XMULTI_REF_STATUS_IDX *p ) + const XBP_ADDR *p_addr, + XMULTI_REF_STATUS_IDX *p, + uint16_t idx) { - uint16_t idx = p->idx; - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XMR_STATUS_IDX, idx ); + int rc = MBG_ERR_UNSPEC; + GPS_CMD cmd = GPS_XMR_STATUS_IDX; - if ( ( rc == MBG_SUCCESS ) && p ) + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + //### TODO FIXME rc = mbgextio_req_data_idx_unlocked( pmctl, p_addr, GPS_XMR_STATUS_IDX, idx, p, sizeof( *p ) ); + + rc = xmt_cmd_us( pmctl, p_addr, cmd, idx ); // request data + + if ( mbg_rc_is_error( rc ) ) + goto out_release; + + for (;;) { - *p = pmctl->rcv.pmb->u.msg_data.xmulti_ref_status_idx; - //##++++++ _mbg_xmr_status_idx( p ); + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, cmd, p, sizeof( *p ) ); // wait for the reply + + if ( mbg_rc_is_error( rc ) ) + break; + + _mbg_swab_xmulti_ref_status_idx( p ); + + if ( p->idx == idx ) + break; + + #if defined( DEBUG ) + fprintf( stderr, "GPS_XMR_STATUS_IDX received reply idx %u, expected %u\n", idx, p->idx ); + #endif } +out_release: + + #if _USE_MUTEX + _mbg_mutex_release( &pmctl->dev_mutex ); + #endif + return rc; } // mbgextio_get_xmr_status_idx +/*HDR*/ +/** + * @brief Read ::XMR_STATS_IDX for a specific XMR source + * + * Only if ::mbgextio_dev_xmr_has_ext_source_stats returns ::MBG_SUCCESS for the specific index + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MULTI_REF_TYPES-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_ext_source_stats_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + XMR_STATS_IDX *p, + uint16_t idx) +{ + int rc; + + p->idx = idx; + + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XMR_STATS_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) ) + _mbg_swab_xmr_stats_idx( p ); + + return rc; + +} // mbgextio_get_xmr_ext_source_stats_idx + + +/*HDR*/ +/** + * @brief Read ::XMR_METRICS_IDX for a specific XMR source + * + * Only if ::mbgextio_dev_xmr_has_ext_source_stats returns ::MBG_SUCCESS for the specific index + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MULTI_REF_TYPES-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_ext_source_metrics_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + XMR_METRICS_IDX *p, + uint16_t idx) +{ + int rc; + + p->idx = idx; + + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XMR_METRICS_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) ) + _mbg_swab_xmr_metrics_idx( p ); + + return rc; + +} // mbgextio_get_xmr_ext_source_metrics_idx + /*HDR*/ /** - * @brief Save the supported XMR features ::XMULTI_REF_INFO_IDX format + * @brief Set ::XMULTI_REF_SETTINGS for a specific XMR source * - * @note Some devices may not support Multi Refernce Sources + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be retrieved, 0..0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 * * @return One of the @ref MBG_RETURN_CODES * - * @see //##+++++++++++++ + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_set_xmr_settings( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, const XMULTI_REF_SETTINGS_IDX *p ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_xmr_settings_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + const XMULTI_REF_SETTINGS *p, + uint16_t idx) { GPS_CMD cmd = GPS_XMR_SETTINGS_IDX | OPT_GPS_ACK_CODE; XMULTI_REF_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.xmulti_ref_settings_idx; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif - *p_data = *p; - //##++++++ _mbg_swab_xmr_settings( p_data ); + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_xmulti_ref_settings_idx( p_data ); return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); -} // mbgextio_set_xmr_settings +} // mbgextio_set_xmr_settings_idx @@ -4530,13 +7489,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_lan_if_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, LAN_IF_INFO *p ) { int rc; - rc = mbgextio_req_data( pmctl, p_addr, GPS_LAN_IF_INFO ); + rc = mbgextio_req_data( pmctl, p_addr, GPS_LAN_IF_INFO, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.lan_if_info; - //##++++++ _mbg_xmr_status_idx( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_lan_if_info( p ); return rc; @@ -4561,13 +7517,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_lan_if_info( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ip4_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IP4_SETTINGS *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_IP4_SETTINGS ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_IP4_SETTINGS, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ip4_settings; - //##++++++ _mbg_xmr_status_idx( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ip4_settings( p ); return rc; @@ -4596,11 +7549,11 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ip4_settings( MBG_MSG_CTL *pmctl, IP4_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ip4_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; - //##++++++ _mbg_swab_xmr_settings( p_data ); + _mbg_swab_ip4_settings( p_data ); return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); @@ -4625,13 +7578,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ip4_settings( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ip4_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IP4_SETTINGS *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_IP4_STATE ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_IP4_STATE, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ip4_settings; - //##++++++ _mbg_xmr_status_idx( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ip4_settings( p ); return rc; @@ -4654,14 +7604,12 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ip4_state( MBG_MSG_CTL *pmctl, * @see //##+++++++++++++ */ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_state( MBG_MSG_CTL *pmctl, - const XBP_ADDR *p_addr, PTP_STATE *p ) + const XBP_ADDR *p_addr, PTP_STATE *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_STATE); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_STATE, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ptp_state; - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_state( p ); return rc; @@ -4686,12 +7634,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_state( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PTP_CFG_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_CFG ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_CFG, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ptp_cfg_info; - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_cfg_info( p ); return rc; @@ -4716,12 +7662,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_cfg_info( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_uc_master_cfg_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PTP_UC_MASTER_CFG_LIMITS *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_UC_MASTER_CFG_LIMITS ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_UC_MASTER_CFG_LIMITS, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ptp_uc_master_cfg_limits; - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_uc_master_cfg_limits( p ); return rc; @@ -4755,13 +7699,13 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_ptp_uc_master_info( MBG_MSG_CTL * { xmt_cmd_us( pmctl, p_addr, GPS_PTP_UC_MASTER_CFG, i ); - rc = mbgextio_rcv_msg( pmctl, p_addr, GPS_PTP_UC_MASTER_CFG ); //##+++++++++++++++++++++++++ + rc = mbgextio_rcv_msg_unlocked( pmctl, p_addr, GPS_PTP_UC_MASTER_CFG, NULL, 0 ); //### TODO - if ( ( rc == MBG_SUCCESS ) && ptp_uc_master_info_idx ) + if ( mbg_rc_is_success( rc ) && ptp_uc_master_info_idx ) { PTP_UC_MASTER_INFO_IDX *p = &ptp_uc_master_info_idx[i]; *p = pmctl->rcv.pmb->u.msg_data.ptp_uc_master_info_idx; - _mbg_swab_dummy( p ); + _mbg_swab_ptp_uc_master_info_idx( p ); } else break; @@ -4794,7 +7738,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_cfg_settings( MBG_MSG_CTL *pmctl, PTP_CFG_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_cfg_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -4805,6 +7749,1173 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_cfg_settings( MBG_MSG_CTL *pmctl, } // mbgextio_set_ptp_cfg_settings +/*HDR*/ +/** + * @brief Send PTP unicast master configuration settings for a PTP unicast slave mode device. + * + * The number of supported PTP Masters is specified in ::PTP_UC_MASTER_CFG_LIMITS::n_supp_master. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the PTP unicast grandmaster to be configured, 0 ... PTP_UC_MASTER_CFG_LIMITS::n_supp_master - 1 . + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_ptp_cfg_settings + * @see ::mbgextio_get_all_ptp_uc_master_info + * @see ::mbgextio_get_ptp_uc_master_cfg_limits + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_state + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_uc_master_settings_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, const PTP_UC_MASTER_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_PTP_UC_MASTER_CFG | OPT_GPS_ACK_CODE; + PTP_UC_MASTER_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_uc_master_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_ptp_uc_master_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_uc_master_settings_idx + + + +/*HDR*/ +/** + * @brief Read the PTPv1 default dataset in ::MBG_PTP_V1_DEFAULT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_default_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_default_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V1_DEFAULT_DATASET *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_V1_DEFAULT_DS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v1_default_dataset( p ); + + return rc; + +} // mbgextio_get_ptp_v1_default_dataset + + + +/*HDR*/ +/** + * @brief Send PTPv1 default dataset to a device in ::MBG_PTP_V1_DEFAULT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_default_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_default_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V1_DEFAULT_DATASET *p ) +{ + GPS_CMD cmd = GPS_PTP_V1_DEFAULT_DS | OPT_GPS_ACK_CODE; + MBG_PTP_V1_DEFAULT_DATASET *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v1_default_dataset; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ptp_v1_default_dataset( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v1_default_dataset + + + +/*HDR*/ +/** + * @brief Read the PTPv1 current dataset in ::MBG_PTP_V1_CURRENT_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_current_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_current_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V1_CURRENT_DATASET *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_V1_CURRENT_DS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v1_current_dataset( p ); + + return rc; + +} // mbgextio_get_ptp_v1_current_dataset + + + +/*HDR*/ +/** + * @brief Send PTPv1 current dataset to a device in ::MBG_PTP_V1_CURRENT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_current_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_current_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V1_CURRENT_DATASET *p ) +{ + GPS_CMD cmd = GPS_PTP_V1_CURRENT_DS | OPT_GPS_ACK_CODE; + MBG_PTP_V1_CURRENT_DATASET *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v1_current_dataset; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ptp_v1_current_dataset( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v1_current_dataset + + + +/*HDR*/ +/** + * @brief Read the PTPv1 parent dataset in ::MBG_PTP_V1_PARENT_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_parent_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_parent_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V1_PARENT_DATASET *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_V1_PARENT_DS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v1_parent_dataset( p ); + + return rc; + +} // mbgextio_get_ptp_v1_parent_dataset + + + +/*HDR*/ +/** + * @brief Send PTPv1 parent dataset to a device in ::MBG_PTP_V1_PARENT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_parent_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_parent_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V1_PARENT_DATASET *p ) +{ + GPS_CMD cmd = GPS_PTP_V1_PARENT_DS | OPT_GPS_ACK_CODE; + MBG_PTP_V1_PARENT_DATASET *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v1_parent_dataset; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ptp_v1_parent_dataset( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v1_parent_dataset + + + +/*HDR*/ +/** + * @brief Read the PTPv1 time properties dataset in ::MBG_PTP_V1_TIME_PROPERTIES_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_time_properties_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_time_properties_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V1_TIME_PROPERTIES_DATASET *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_V1_TIME_PROP_DS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v1_time_properties_dataset( p ); + + return rc; + +} // mbgextio_get_ptp_v1_time_properties_dataset + + + +/*HDR*/ +/** + * @brief Send PTPv1 time properties dataset to a device in ::MBG_PTP_V1_TIME_PROPERTIES_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_time_properties_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_time_properties_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V1_TIME_PROPERTIES_DATASET *p ) +{ + GPS_CMD cmd = GPS_PTP_V1_TIME_PROP_DS | OPT_GPS_ACK_CODE; + MBG_PTP_V1_TIME_PROPERTIES_DATASET *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v1_time_properties_dataset; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ptp_v1_time_properties_dataset( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v1_time_properties_dataset + + + +/*HDR*/ +/** + * @brief Read the PTPv1 port dataset with the appropriate index in ::MBG_PTP_V1_PORT_DATASET_IDX format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the port dataset be received, 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_port_dataset_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_port_dataset_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V1_PORT_DATASET_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_PTP_V1_PORT_DS_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v1_port_dataset_idx( p ); + + return rc; + +} // mbgextio_get_ptp_v1_port_dataset_idx + + + +/*HDR*/ +/** + * @brief Send PTPv1 port dataset with the appropriate index to a device in ::MBG_PTP_V1_PORT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the port dataset to be written, 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_port_dataset_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_port_dataset_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V1_PORT_DATASET *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_PTP_V1_PORT_DS_IDX | OPT_GPS_ACK_CODE; + MBG_PTP_V1_PORT_DATASET_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v1_port_dataset_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->port_dataset = *p; + p_data->idx = idx; + _mbg_swab_ptp_v1_port_dataset_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v1_port_dataset_idx + + + +/*HDR*/ +/** + * @brief Read the PTPv2 default dataset in ::MBG_PTP_V2_DEFAULT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_default_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_default_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V2_DEFAULT_DATASET *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_V2_DEFAULT_DS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v2_default_dataset( p ); + + return rc; + +} // mbgextio_get_ptp_v2_default_dataset + + + +/*HDR*/ +/** + * @brief Send PTPv2 default dataset to a device in ::MBG_PTP_V2_DEFAULT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_default_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_default_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V2_DEFAULT_DATASET *p ) +{ + GPS_CMD cmd = GPS_PTP_V2_DEFAULT_DS | OPT_GPS_ACK_CODE; + MBG_PTP_V2_DEFAULT_DATASET *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v2_default_dataset; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ptp_v2_default_dataset( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v2_default_dataset + + + +/*HDR*/ +/** + * @brief Read the PTPv2 current dataset in ::MBG_PTP_V2_CURRENT_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_current_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_current_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V2_CURRENT_DATASET *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_V2_CURRENT_DS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v2_current_dataset( p ); + + return rc; + +} // mbgextio_get_ptp_v2_current_dataset + + + +/*HDR*/ +/** + * @brief Send PTPv2 current dataset to a device in ::MBG_PTP_V2_CURRENT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_current_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_current_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V2_CURRENT_DATASET *p ) +{ + GPS_CMD cmd = GPS_PTP_V2_CURRENT_DS | OPT_GPS_ACK_CODE; + MBG_PTP_V2_CURRENT_DATASET *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v2_current_dataset; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ptp_v2_current_dataset( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v2_current_dataset + + + +/*HDR*/ +/** + * @brief Read the PTPv2 parent dataset in ::MBG_PTP_V2_PARENT_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_parent_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_parent_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V2_PARENT_DATASET *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_V2_PARENT_DS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v2_parent_dataset( p ); + + return rc; + +} // mbgextio_get_ptp_v2_parent_dataset + + + +/*HDR*/ +/** + * @brief Send PTPv2 parent dataset to a device in ::MBG_PTP_V2_PARENT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_parent_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_parent_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V2_PARENT_DATASET *p ) +{ + GPS_CMD cmd = GPS_PTP_V2_PARENT_DS | OPT_GPS_ACK_CODE; + MBG_PTP_V2_PARENT_DATASET *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v2_parent_dataset; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ptp_v2_parent_dataset( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v2_parent_dataset + + + +/*HDR*/ +/** + * @brief Read the PTPv2 time properties dataset in ::MBG_PTP_V2_TIME_PROPERTIES_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_time_properties_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_time_properties_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V2_TIME_PROPERTIES_DATASET *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PTP_V2_TIME_PROP_DS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v2_time_properties_dataset( p ); + + return rc; + +} // mbgextio_get_ptp_v2_time_properties_dataset + + + +/*HDR*/ +/** + * @brief Send PTPv2 time properties dataset to a device in ::MBG_PTP_V2_TIME_PROPERTIES_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_time_properties_dataset + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_time_properties_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V2_TIME_PROPERTIES_DATASET *p ) +{ + GPS_CMD cmd = GPS_PTP_V2_TIME_PROP_DS | OPT_GPS_ACK_CODE; + MBG_PTP_V2_TIME_PROPERTIES_DATASET *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v2_time_properties_dataset; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ptp_v2_time_properties_dataset( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v2_time_properties_dataset + + + +/*HDR*/ +/** + * @brief Read the PTPv2 port dataset with the appropriate index in ::MBG_PTP_V2_PORT_DATASET_IDX format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the port dataset be received, 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_port_dataset_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_port_dataset_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_PTP_V2_PORT_DATASET_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_PTP_V2_PORT_DS_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ptp_v2_port_dataset_idx( p ); + + return rc; + +} // mbgextio_get_ptp_v2_port_dataset_idx + + + +/*HDR*/ +/** + * @brief Send PTPv2 port dataset with the appropriate index to a device in ::MBG_PTP_V2_PORT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the port dataset be written, 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_port_dataset_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_port_dataset_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_PTP_V2_PORT_DATASET *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_PTP_V2_PORT_DS_IDX | OPT_GPS_ACK_CODE; + MBG_PTP_V2_PORT_DATASET_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ptp_v2_port_dataset_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->port_dataset = *p; + p_data->idx = idx; + _mbg_swab_ptp_v2_port_dataset_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ptp_v2_port_dataset_idx + + + +/*HDR*/ +/** + * @brief Read the monitoring limits in ::MBG_MONITORING_LIMITS format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_monitoring_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_MONITORING_LIMITS *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_MONITORING_LIMITS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_monitoring_limits( p ); + + return rc; + +} // mbgextio_get_monitoring_limits + + + +/*HDR*/ +/** + * @brief Read the SNMP global info in ::MBG_SNMP_GLB_INFO format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_set_snmp_glb_settings + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_glb_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_SNMP_GLB_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_SNMP_GLB, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_snmp_glb_info( p ); + + return rc; + +} // mbgextio_get_snmp_glb_info + + + +/*HDR*/ +/** + * @brief Send the SNMP global settings in ::MBG_SNMP_GLB_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_glb_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_SNMP_GLB_SETTINGS *p ) +{ + GPS_CMD cmd = GPS_SNMP_GLB | OPT_GPS_ACK_CODE; + MBG_SNMP_GLB_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.snmp_glb_settings; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_snmp_glb_settings( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_snmp_glb_settings + + + +/*HDR*/ +/** + * @brief Read SNMP v1 or v2 info in ::MBG_SNMP_V12_INFO_IDX format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the SNMP info to be received, 0 ... MBG_SNMP_GLB_SETTINGS::num_v12_settings - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_set_snmp_v12_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_v12_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_SNMP_V12_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx(pmctl, p_addr, GPS_SNMP_V12_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_snmp_v12_info_idx( p ); + + return rc; + +} // mbgextio_get_snmp_v12_info_idx + + + +/*HDR*/ +/** + * @brief Write SNMP v1 or v2 settings in ::MBG_SNMP_V12_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the SNMP settings to be written, 0 ... MBG_SNMP_GLB_SETTINGS::num_v12_settings - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v12_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_v12_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_SNMP_V12_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_SNMP_V12_IDX | OPT_GPS_ACK_CODE; + MBG_SNMP_V12_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.snmp_v12_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_snmp_v12_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_snmp_v12_settings_idx + + + +/*HDR*/ +/** + * @brief Read SNMP v1 or v2 trap info in ::MBG_SNMP_V12_TRAP_INFO_IDX format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the SNMP trap info to be received, 0 ... MBG_SNMP_GLB_SETTINGS::num_v12_trap_receivers - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_set_snmp_v12_trap_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_v12_trap_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_SNMP_V12_TRAP_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx(pmctl, p_addr, GPS_SNMP_V12_TRAP_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_snmp_v12_trap_info_idx( p ); + + return rc; + +} // mbgextio_get_snmp_v12_trap_info_idx + + + +/*HDR*/ +/** + * @brief Write SNMP v1 or v2 trap settings in ::MBG_SNMP_V12_TRAP_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the SNMP settings to be written, 0 ... MBG_SNMP_GLB_SETTINGS::num_v12_trap_receivers - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v12_trap_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_v12_trap_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_SNMP_V12_TRAP_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_SNMP_V12_TRAP_IDX | OPT_GPS_ACK_CODE; + MBG_SNMP_V12_TRAP_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.snmp_v12_trap_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_snmp_v12_trap_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_snmp_v12_trap_settings_idx + + + +/*HDR*/ +/** + * @brief Read SNMP v3 info in ::MBG_SNMP_V3_INFO_IDX format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the SNMP info to be received, 0 ... MBG_SNMP_GLB_SETTINGS::num_v3_settings - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_set_snmp_v3_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_v3_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_SNMP_V3_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx(pmctl, p_addr, GPS_SNMP_V3_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_snmp_v3_info_idx( p ); + + return rc; + +} // mbgextio_get_snmp_v3_info_idx + + + +/*HDR*/ +/** + * @brief Write SNMP v3 settings in ::MBG_SNMP_V3_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the SNMP settings to be written, 0 ... MBG_SNMP_GLB_SETTINGS::num_v3_settings - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v3_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_v3_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_SNMP_V3_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_SNMP_V3_IDX | OPT_GPS_ACK_CODE; + MBG_SNMP_V3_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.snmp_v3_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_snmp_v3_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_snmp_v3_settings_idx + + + +/*HDR*/ +/** + * @brief Read SNMP v3 trap info in ::MBG_SNMP_V3_TRAP_INFO_IDX format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the SNMP trap info to be received, 0 ... MBG_SNMP_GLB_SETTINGS::num_v3_trap_receivers - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_set_snmp_v3_trap_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_v3_trap_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_SNMP_V3_TRAP_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx(pmctl, p_addr, GPS_SNMP_V3_TRAP_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_snmp_v3_trap_info_idx( p ); + + return rc; + +} // mbgextio_get_snmp_v3_trap_info_idx + + + +/*HDR*/ +/** + * @brief Write SNMP v3 trap settings in ::MBG_SNMP_V3_TRAP_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the SNMP trap settings to be written, 0 ... MBG_SNMP_GLB_SETTINGS::num_v3_trap_receivers - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v3_trap_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_v3_trap_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_SNMP_V3_TRAP_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_SNMP_V3_TRAP_IDX | OPT_GPS_ACK_CODE; + MBG_SNMP_V3_TRAP_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.snmp_v3_trap_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_snmp_v3_trap_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_snmp_v3_trap_settings_idx + + + +/*HDR*/ +/** + * @brief Read monitoring event info in ::MBG_EVENT_INFO_IDX format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * idx shall be the type of the appropriate event, it should be checked + * if this event is supported in ::MBG_MONITORING_LIMITS::supp_events + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the event info to be received, type of the appropriate event + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_monitoring_limits + * @see ::mbgextio_set_event_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_event_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_EVENT_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx(pmctl, p_addr, GPS_EVENT_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_event_info_idx( p ); + + return rc; + +} // mbgextio_get_event_info_idx + + + +/*HDR*/ +/** + * @brief Write monitoring event settings in ::MBG_EVENT_SETTINGS format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * idx shall be the type of the appropriate event, it should be checked + * if this event is supported in ::MBG_MONITORING_LIMITS::supp_events + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the event settings to be written, type of the appropriate event + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_monitoring_limits + * @see ::mbgextio_get_event_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_event_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_EVENT_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_EVENT_IDX | OPT_GPS_ACK_CODE; + MBG_EVENT_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.event_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_event_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_event_settings_idx + + + +/*HDR*/ +/** + * @brief Read the monitoring status in ::MBG_MONITORING_STATUS format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_monitoring_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_MONITORING_STATUS *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_MONITORING_STATUS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_monitoring_status( p ); + + return rc; + +} // mbgextio_get_monitoring_status + + +/*HDR*/ +/** + * @brief Read monitoring event status in ::MBG_EVENT_STATUS_IDX format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * idx shall be the type of the appropriate event, it should be checked + * if this event is supported in ::MBG_MONITORING_LIMITS::supp_events + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the event info to be received, type of the appropriate event + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_monitoring_limits + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_event_status_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_EVENT_STATUS_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx(pmctl, p_addr, GPS_EVENT_STAT_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_event_status_idx( p ); + + return rc; + +} // mbgextio_get_event_status_idx + /*HDR*/ /** @@ -4825,19 +8936,16 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_cfg_settings( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_glb_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_GLB_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_GLB_CFG ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_GLB_CFG, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ntp_glb_info; - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_glb_info( p ); return rc; } // mbgextio_get_ntp_glb_info - /*HDR*/ /** * @brief Send the NTP global configuration @@ -4859,7 +8967,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_glb_info( MBG_MSG_CTL *pmctl, NTP_GLB_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_glb_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -4871,6 +8979,263 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_glb_info( MBG_MSG_CTL *pmctl, +#if defined( _PRELIMINARY_CODE ) + +/*HDR*/ +/** + * @brief Read the NTP symmetric key limits in ::NTP_SYMM_KEY_LIMITS format + * + * @note ::NTP_MSK_SYMM_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_symm_key_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_SYMM_KEY_LIMITS *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_SYMM_KEY_LIMITS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_symm_key_limits( p ); + + return rc; + +} // mbgextio_get_ntp_symm_key_limits + + + +/*HDR*/ +/** + * @brief Read the NTP symmetric key info with the given index in ::NTP_SYMM_KEY_INFO_IDX format + * + * @note ::NTP_MSK_SYMM_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the NTP symmetric key info to be queried, 0 ... ::NTP_GLB_SETTINGS::num_symm_keys - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_symm_key_limits + * @see ::mbgextio_set_ntp_symm_key_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_symm_key_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + NTP_SYMM_KEY_INFO_IDX *p, uint16_t idx ) +{ + int rc; + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NTP_SYMM_KEY_CFG, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_symm_key_info_idx( p ); + + return rc; + +} // mbgextio_get_ntp_symm_key_info_idx + + + +/*HDR*/ +/** + * @brief Send NTP symmetric key settings with the given index in ::NTP_SYMM_KEY_SETTINGS format + * + * @note ::NTP_MSK_SYMM_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the NTP symmetric key to be configured, 0 ... ::NTP_GLB_SETTINGS::num_symm_keys - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_symm_key_limits + * @see ::mbgextio_get_ntp_symm_key_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_symm_key_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const NTP_SYMM_KEY_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_NTP_SYMM_KEY_CFG | OPT_GPS_ACK_CODE; + NTP_SYMM_KEY_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_symm_key_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_ntp_symm_key_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ntp_symm_key_settings_idx + + + +/*HDR*/ +/** + * @brief Read the NTP trusted key info with the given index in ::NTP_TRUSTED_KEY_INFO_IDX format + * + * @note ::NTP_MSK_TRUSTED_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the NTP trusted key info to be queried, 0 ... ::NTP_GLB_SETTINGS::num_trusted_keys - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_set_ntp_trusted_key_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_trusted_key_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + NTP_TRUSTED_KEY_INFO_IDX *p, uint16_t idx ) +{ + int rc; + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NTP_TRUSTED_KEY_CFG, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_trusted_key_info_idx( p ); + + return rc; + +} // mbgextio_get_ntp_trusted_key_info_idx + + + +/*HDR*/ +/** + * @brief Send NTP trusted key settings with the given index in ::NTP_TRUSTED_KEY_SETTINGS format + * + * @note ::NTP_MSK_TRUSTED_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the NTP trusted key to be configured, 0 ... ::NTP_GLB_SETTINGS::num_trusted_keys - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_trusted_key_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_trusted_key_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const NTP_TRUSTED_KEY_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_NTP_TRUSTED_KEY_CFG | OPT_GPS_ACK_CODE; + NTP_TRUSTED_KEY_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_trusted_key_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_ntp_trusted_key_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ntp_trusted_key_settings_idx + + + +/*HDR*/ +/** + * @brief Read the NTP misc limits in ::NTP_MISC_LIMITS format + * + * @note ::NTP_MSK_MISCELLANEOUS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_misc_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_MISC_LIMITS *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_MISC_LIMITS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_misc_limits( p ); + + return rc; + +} // mbgextio_get_ntp_misc_limits + + + +/*HDR*/ +/** + * @brief Read the NTP orphan mode information in ::NTP_MISC_ORPHAN_MODE_INFO format + * + * @note ::NTP_MISC_MSK_ORPHAN_MODE must be set in ::NTP_MISC_LIMITS::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_misc_limits + * @see ::mbgextio_set_ntp_misc_orphan_mode_settings + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_misc_orphan_mode_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + NTP_MISC_ORPHAN_MODE_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_MISC_ORPHAN_MODE, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_misc_orphan_mode_info( p ); + + return rc; + +} // mbgextio_get_ntp_misc_orphan_mode_info + + + +/*HDR*/ +/** + * @brief Send the NTP orphan mode configuration in ::NTP_MISC_ORPHAN_MODE_SETTINGS format + * + * @note ::NTP_MISC_MSK_ORPHAN_MODE must be set in ::NTP_MISC_LIMITS::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_misc_limits + * @see ::mbgextio_get_ntp_misc_orphan_mode_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_misc_orphan_mode_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const NTP_MISC_ORPHAN_MODE_SETTINGS *p ) +{ + GPS_CMD cmd = GPS_NTP_MISC_ORPHAN_MODE | OPT_GPS_ACK_CODE; + NTP_MISC_ORPHAN_MODE_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_misc_orphan_mode_settings; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ntp_misc_orphan_mode_settings( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ntp_misc_orphan_mode_settings + + + /*HDR*/ /** * @brief Read the ntp global information ::NTP_CLNT_MODE_INFO format @@ -4892,12 +9257,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_glb_info( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_clnt_mode_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_CLNT_MODE_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_CLNT_MODE_CFG ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_CLNT_MODE_CFG, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ntp_clnt_mode_info; - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_clnt_mode_info( p ); return rc; @@ -4929,7 +9292,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_clnt_mode_cfg( MBG_MSG_CTL *pmctl NTP_CLNT_MODE_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_clnt_mode_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -4960,12 +9323,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_peer_settings_idx( MBG_MSG_CTL *p const XBP_ADDR *p_addr, NTP_PEER_SETTINGS_IDX *p, uint16_t idx ) { int rc; - rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NTP_PEER_SETTINGS_IDX, idx ); + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NTP_PEER_SETTINGS_IDX, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ntp_peer_settings_idx; - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_peer_settings_idx( p ); return rc; @@ -4997,7 +9358,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_peer_settings_idx( MBG_MSG_CTL *p NTP_PEER_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_peer_settings_idx; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif p_data->peer_settings = *p; @@ -5012,9 +9373,141 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_peer_settings_idx( MBG_MSG_CTL *p /*HDR*/ /** + * @brief Read the ntp server mode information in ::NTP_SRV_MODE_INFO format + * + * @note NTP feature ::GPS_FEAT_NTP must be set + * @note NTP roles ::NTP_ROLE_SERVER or ::NTP_ROLE_CLIENT_SERVER must be set in ::NTP_GLB_INFO::supp_ntp_roles + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_set_ntp_srv_mode_cfg + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_srv_mode_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_SRV_MODE_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_SRV_MODE_CFG, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_srv_mode_info( p ); + + return rc; + +} // mbgextio_get_ntp_srv_mode_info + + +/*HDR*/ +/** + * @brief Send the NTP server mode configuration + * + * @note NTP feature ::GPS_FEAT_NTP must be set + * @note NTP roles ::NTP_ROLE_SERVER or ::NTP_ROLE_CLIENT_SERVER must be set in ::NTP_GLB_INFO::supp_ntp_roles + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_srv_mode_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_srv_mode_cfg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_SRV_MODE_SETTINGS *p ) +{ + GPS_CMD cmd = GPS_NTP_SRV_MODE_CFG | OPT_GPS_ACK_CODE; + NTP_SRV_MODE_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_srv_mode_settings; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_ntp_srv_mode_settings( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ntp_srv_mode_cfg + + +/*HDR*/ +/** + * @brief Read the NTP refclock config info with the given index in ::NTP_REFCLK_CFG_INFO_IDX format + * + * @note NTP feature ::GPS_FEAT_NTP must be set + * @note NTP roles ::NTP_ROLE_SERVER or ::NTP_ROLE_CLIENT_SERVER must be set in ::NTP_GLB_INFO::supp_ntp_roles + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the NTP refclock config to be queried, 0 ... ::NTP_SRV_MODE_SETTINGS::num_refclks - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_srv_mode_info + * @see ::mbgextio_set_ntp_refclk_cfg_settings_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_refclk_cfg_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + NTP_REFCLK_CFG_INFO_IDX *p, uint16_t idx ) +{ + int rc; + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NTP_REFCLK_CFG, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_refclk_cfg_info_idx( p ); + + return rc; + +} // mbgextio_get_ntp_refclk_cfg_info_idx + + + +/*HDR*/ +/** + * @brief Send NTP refclk config settings with the given index in ::NTP_REFCLK_CFG_SETTINGS format + * + * @note NTP feature ::GPS_FEAT_NTP must be set + * @note NTP roles ::NTP_ROLE_SERVER or ::NTP_ROLE_CLIENT_SERVER must be set in ::NTP_GLB_INFO::supp_ntp_roles + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the NTP refclock config to be set, 0 ... ::NTP_SRV_MODE_SETTINGS::num_refclks - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_srv_mode_info + * @see ::mbgextio_get_ntp_refclk_cfg_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_refclk_cfg_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const NTP_REFCLK_CFG_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_NTP_REFCLK_CFG | OPT_GPS_ACK_CODE; + NTP_REFCLK_CFG_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ntp_refclk_cfg_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_ntp_refclk_cfg_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ntp_refclk_cfg_settings_idx + + + +/*HDR*/ +/** * @brief Read the current system state of ntp device ::NTP_SYS_STATE format * - * @note ntp feature must set + * @note NTP feature must set * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL @@ -5028,13 +9521,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_peer_settings_idx( MBG_MSG_CTL *p _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_sys_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_SYS_STATE *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_SYS_STATE); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NTP_SYS_STATE, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ntp_sys_state; - //##++++++ _mbg_xmr_status_idx( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_sys_state( p ); return rc; @@ -5061,17 +9551,18 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_peer_state_idx( MBG_MSG_CTL *pmct const XBP_ADDR *p_addr, NTP_PEER_STATE_IDX *p, uint16_t idx ) { int rc; - rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NTP_PEER_STATE_IDX, idx ); + rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NTP_PEER_STATE_IDX, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ntp_peer_state_idx; - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ntp_peer_state_idx( p ); return rc; } // mbgextio_get_ntp_peer_state_idx +#endif // defined( _PRELIMINARY_CODE ) + + /*HDR*/ /** @@ -5090,18 +9581,17 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_peer_state_idx( MBG_MSG_CTL *pmct _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_glb_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_GLB_CFG_INFO *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_NET_GLB_CFG); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NET_GLB_CFG, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.net_glb_cfg_info; - _mbg_swab_dummy( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_glb_cfg_info( p ); return rc; } // mbgextio_get_net_glb_cfg_info + + /*HDR*/ /** * @brief Set the device's global network configuration settings @@ -5123,11 +9613,11 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_glb_cfg_settings( MBG_MSG_CTL *pm MBG_NET_GLB_CFG_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.net_glb_cfg_settings; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; - _mbg_swab_dummy( p ); + _mbg_swab_net_glb_cfg_settings( p_data ); return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); @@ -5137,14 +9627,14 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_glb_cfg_settings( MBG_MSG_CTL *pm /*HDR*/ /** - * @brief Read the network dns server ::MBG_IP_ADDR_IDX format + * @brief Read a network DNS server entry in ::MBG_IP_ADDR_IDX format * - * The number of DNS server provided by the device is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srvr + * The number of DNS server provided by the device is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data - * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1 + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -5154,13 +9644,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_glb_cfg_settings( MBG_MSG_CTL *pm _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_dns_srvr_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IP_ADDR_IDX *p, uint16_t idx ) { - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_DNS_SRVR, idx ); + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_DNS_SRVR, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ip_addr_idx; - _mbg_swab_dummy( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ip_addr_idx( p ); return rc; @@ -5173,12 +9660,12 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_dns_srvr_idx( MBG_MSG_CTL *pmctl, * @brief Send the network DNS server address in ::MBG_IP_ADDR format * * The number of DNS search domains supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to be sent to the device - * @param[in] idx Index of the serial port to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1 + * @param[in] idx Index of the DNS server port to be configured, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -5192,14 +9679,14 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srvr_idx( MBG_MSG_CTL *pmctl, MBG_IP_ADDR_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.ip_addr_idx; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif p_data->addr = *p; p_data->idx = idx; - _mbg_swab_dummy( p_data ); + _mbg_swab_ip_addr_idx( p_data ); - return mbgextio_xmt_msg( pmctl, p_addr, cmd, p_data, sizeof( *p_data ) ); + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); } // mbgextio_set_net_dns_srvr_idx @@ -5210,12 +9697,12 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srvr_idx( MBG_MSG_CTL *pmctl, * @brief Read the network DNS search domain in ::MBG_NET_NAME_IDX format * * The number of DNS search domains supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data - * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1 + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -5225,13 +9712,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srvr_idx( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_dns_srch_dom_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_NAME_IDX *p, uint16_t idx ) { - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_DNS_SRCH_DOM, idx ); + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_DNS_SRCH_DOM, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.net_name_idx; - _mbg_swab_dummy( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_name_idx( p ); return rc; @@ -5244,12 +9728,12 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_dns_srch_dom_idx( MBG_MSG_CTL *pm * @brief Send the network DNS search domain in ::MBG_NET_NAME format * * The number of DNS search domains supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to be sent to the device - * @param[in] idx Index of the serial port to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1 + * @param[in] idx Index of the DNS search domain entry to be configured, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -5263,14 +9747,14 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srch_dom_idx( MBG_MSG_CTL *pm MBG_NET_NAME_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.net_name_idx; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif p_data->net_name = *p; p_data->idx = idx; - _mbg_swab_dummy( p_data ); + _mbg_swab_net_name( p_data ); - return mbgextio_xmt_msg( pmctl, p_addr, cmd, p_data, sizeof( *p_data ) ); + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); } // mbgextio_set_net_dns_srch_dom_idx @@ -5281,12 +9765,12 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srch_dom_idx( MBG_MSG_CTL *pm * @brief Read the current network DNS server in ::MBG_IP_ADDR_IDX format * * The number of DNS servers supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srvr + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data - * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1 + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -5296,13 +9780,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_dns_srch_dom_idx( MBG_MSG_CTL *pm _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srvr_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IP_ADDR_IDX *p, uint16_t idx ) { - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_STAT_DNS_SRVR, idx ); + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_STAT_DNS_SRVR, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.ip_addr_idx; - _mbg_swab_dummy( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ip_addr_idx( p ); return rc; @@ -5315,12 +9796,12 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srvr_idx( MBG_MSG_CTL *p * @brief Read the current network DNS search domain in ::MBG_NET_NAME_IDX format * * The number of DNS search domains supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data - * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1 + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -5330,13 +9811,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srvr_idx( MBG_MSG_CTL *p _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srch_dom_stat_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_NAME_IDX *p, uint16_t idx ) { - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_STAT_DNS_SRCH_DOM, idx ); + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_STAT_DNS_SRCH_DOM, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.net_name_idx; - _mbg_swab_dummy( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_name_idx( p ); return rc; @@ -5346,6 +9824,331 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srch_dom_stat_idx( MBG_M /*HDR*/ /** + * @brief Read ::MBG_NET_INTF_LINK_INFO_IDX from the config with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_LINK_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_link. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_link - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_cfg_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_intf_link_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_NET_INTF_LINK_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_INTF_LINK_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_intf_link_info_idx( p ); + + return rc; + +} // mbgextio_get_net_intf_link_info_idx + + + +/*HDR*/ +/** + * @brief Send the network link configuration in ::MBG_NET_INTF_LINK_SETTINGS format + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the link to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_intf_link - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_net_intf_link_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_intf_link_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_NET_INTF_LINK_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_NET_INTF_LINK_IDX | OPT_GPS_ACK_CODE; + MBG_NET_INTF_LINK_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.net_intf_link_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_net_intf_link_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_net_intf_link_settings_idx + + + +/*HDR*/ +/** + * @brief Read ::MBG_NET_INTF_ADDR_INFO_IDX from the config with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_ADDR_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_addr. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::n_supp_intf_addr - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_cfg_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_intf_addr_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_NET_INTF_ADDR_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_INTF_ADDR_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_intf_addr_info_idx( p ); + + return rc; + +} // mbgextio_get_net_intf_addr_info_idx + + + +/*HDR*/ +/** + * @brief Send the network addr configuration in ::MBG_NET_INTF_ADDR_SETTINGS format + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the link to be configured, 0..::MBG_NET_GLB_CFG_INFO::n_supp_intf_addr - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_net_intf_addr_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_intf_addr_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_NET_INTF_ADDR_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_NET_INTF_ADDR_IDX | OPT_GPS_ACK_CODE; + MBG_NET_INTF_ADDR_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.net_intf_addr_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_net_intf_addr_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_net_intf_addr_settings_idx + + + +/*HDR*/ +/** + * @brief Read ::MBG_NET_INTF_ROUTE_INFO_IDX from the config with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_ROUTE_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_route. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_route - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_cfg_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_intf_route_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_NET_INTF_ROUTE_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_INTF_ROUTE_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_intf_route_info_idx( p ); + + return rc; + +} // mbgextio_get_net_intf_route_info_idx + + + +/*HDR*/ +/** + * @brief Send the network addr configuration in ::MBG_NET_INTF_ROUTE_SETTINGS format + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the link to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_intf_route - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_net_intf_route_info_idx + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_intf_route_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_NET_INTF_ROUTE_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_NET_INTF_ROUTE_IDX | OPT_GPS_ACK_CODE; + MBG_NET_INTF_ROUTE_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.net_intf_route_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_net_intf_route_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_net_intf_route_settings_idx + + + +/*HDR*/ +/** + * @brief Read the network global status information ::MBG_NET_GLB_CFG_INFO format + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_net_glb_cfg_settings + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_glb_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_NET_GLB_CFG_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_NET_STAT_GLB_CFG, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_glb_cfg_info( p ); + + return rc; + +} // mbgextio_get_net_stat_glb_cfg_info + + + +/*HDR*/ +/** + * @brief Read ::MBG_NET_INTF_LINK_INFO_IDX from the status with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_LINK_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_link. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_link - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_status_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_intf_link_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_NET_INTF_LINK_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_STAT_INTF_LINK_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_intf_link_info_idx( p ); + + return rc; + +} // mbgextio_get_net_stat_intf_link_info_idx + + + +/*HDR*/ +/** + * @brief Read ::MBG_NET_INTF_ADDR_INFO_IDX from the status with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_ADDR_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_addr. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_addr - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_status_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_intf_addr_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_NET_INTF_ADDR_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_STAT_INTF_ADDR_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_intf_addr_info_idx( p ); + + return rc; + +} // mbgextio_get_net_stat_intf_addr_info_idx + + + +/*HDR*/ +/** + * @brief Read ::MBG_NET_INTF_ROUTE_INFO_IDX from the status with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_ROUTE_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_route. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_route - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_status_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_intf_route_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_NET_INTF_ROUTE_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_NET_STAT_INTF_ROUTE_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_net_intf_route_info_idx( p ); + + return rc; + +} // mbgextio_get_net_stat_intf_route_info_idx + + + +/*HDR*/ +/** * @brief Read the ::XBP_LIMITS to check which XBP features are supported * * @note Only supported if ::GPS_HAS_XBP is set in ::RECEIVER_INFO::features @@ -5362,19 +10165,17 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srch_dom_stat_idx( MBG_M _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XBP_LIMITS *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_XBP_LIMITS ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_XBP_LIMITS, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.xbp_limits; - _mbg_swab_dummy( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_xbp_limits( p ); return rc; } // mbgextio_get_xbp_limits + /*HDR*/ /** * @brief Read the ::XBP_NODE_LIMITS to check how many ports are provided @@ -5393,19 +10194,17 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_limits( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_node_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XBP_NODE_LIMITS *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_XBP_NODE_LIMITS ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_XBP_NODE_LIMITS, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.xbp_node_limits; - _mbg_swab_dummy( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_xbp_node_limits( p ); return rc; } // mbgextio_get_xbp_node_limits + /*HDR*/ /** * @brief Read the ::XBP_NODE_INFO for a specific node in ::XBP_NODE_INFO_IDX format @@ -5425,13 +10224,10 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_node_limits( MBG_MSG_CTL *pmctl, _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xbp_node_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XBP_NODE_INFO_IDX *p, uint16_t idx ) { - int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XBP_NODE_INFO_IDX, idx ); + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_XBP_NODE_INFO_IDX, idx, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.xbp_node_info_idx; - _mbg_swab_dummy( p ); - } + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_xbp_node_info_idx( p ); return rc; @@ -5474,7 +10270,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_setup_xbp_node_list( MBG_MSG_CTL *pmctl, XBP_NODE_LIMITS node_limits; int rc = MBG_SUCCESS; - int16_t i; + uint16_t i; // This function can be called recursively, so first of all check the recursion level. if ( recursion_count > MAX_XBP_CASC_LVL ) //##++++ TODO: or even ">=" ?? @@ -5488,7 +10284,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_setup_xbp_node_list( MBG_MSG_CTL *pmctl, rc = mbgextio_get_xbp_node_limits( pmctl, p_addr, &node_limits ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) goto out_dec; for ( i = 0; i < node_limits.node_count; i++ ) @@ -5497,7 +10293,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_setup_xbp_node_list( MBG_MSG_CTL *pmctl, rc = mbgextio_get_xbp_node_info_idx( pmctl, p_addr, &node_info_idx, i ); - if ( rc != MBG_SUCCESS ) + if ( mbg_rc_is_error( rc ) ) break; #if 1 && DEBUG @@ -5514,7 +10310,7 @@ out_dec: recursion_count--; else { - // recursion count is unexpectedly 0 + //### recursion count is unexpectedly 0 } out: @@ -5526,6 +10322,85 @@ out: /*HDR*/ /** + * @brief Read configuration and health data of all satellites from a device + * + * @note Only supported by GPS receivers + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_cfgh( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, CFGH *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_CFGH, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_dummy( p ); + + return rc; + +} // mbgextio_get_cfgh + + + +/*HDR*/ +/** + * @brief Read the GPS almanach for the specified SV from a device + * + * @note Only supported by GPS receivers + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] svno SV number, for which the ::SV_ALM structure shall be requested + * + * @return One of the @ref MBG_RETURN_CODES + * + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_sv_alm( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, SV_ALM *p, SVNO svno ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_ALM, svno, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_dummy( p ); + + return rc; + +} // mbgextio_get_sv_alm + + + +/*HDR*/ +/** + * @brief Read the ionospheric correction parameters from a device + * + * @note Only supported by GPS receivers + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the ::IONO structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_iono( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IONO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_IONO, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_dummy( p ); + + return rc; + +} // mbgextio_get_iono + + + +/*HDR*/ +/** * @brief Read a ::UTC parameter structure from a device. * * The ::UTC parameter structure contains the current UTC/GPS time offset @@ -5539,21 +10414,18 @@ out: * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_set_utc_param + * @see ::mbgextio_set_utc_parm */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_get_utc_param( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, UTC *p ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_utc_parm( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, UTC *p ) { - int rc = mbgextio_req_data( pmctl, p_addr, GPS_UTC ); + int rc = mbgextio_req_data( pmctl, p_addr, GPS_UTC, p, sizeof( *p ) ); - if ( ( rc == MBG_SUCCESS ) && p ) - { - *p = pmctl->rcv.pmb->u.msg_data.utc; + if ( mbg_rc_is_success( rc ) && p ) _mbg_swab_utc_parm( p ); - } return rc; -} // mbgextio_get_utc_param +} // mbgextio_get_utc_parm @@ -5572,15 +10444,15 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_utc_param( MBG_MSG_CTL *pmctl, XBP_AD * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_get_utc_param + * @see ::mbgextio_get_utc_parm */ -_NO_MBG_API_ATTR int _MBG_API mbgextio_set_utc_param( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, const UTC *p ) +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_utc_parm( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, const UTC *p ) { GPS_CMD cmd = GPS_UTC | OPT_GPS_ACK_CODE; UTC *p_data = &pmctl->xmt.pmb->u.msg_data.utc; #if _USE_MUTEX - _mbg_mutex_acquire( &pmctl->xmt.xmt_mutex ); + _mbg_mutex_acquire( &pmctl->dev_mutex ); #endif *p_data = *p; @@ -5588,6 +10460,789 @@ _NO_MBG_API_ATTR int _MBG_API mbgextio_set_utc_param( MBG_MSG_CTL *pmctl, XBP_AD return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); -} // mbgextio_set_utc_param +} // mbgextio_set_utc_parm + + + +/*HDR*/ +/** + * @brief Read SCU_STAT_INFO from the device + * + * @note This is only supported if ::GPS_MODEL_HAS_SCU_STAT is set in + * the builtin features of the device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_scu_stat + * @see ::mbgextio_set_scu_stat_settings + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_scu_stat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, SCU_STAT_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_SCU_STAT, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_scu_stat_info( p ); + + return rc; + +} // mbgextio_get_scu_stat_info + + + +/*HDR*/ +/** + * @brief Send SCU_STAT_SETTINGS to the device + * + * @note This is only supported if ::GPS_MODEL_HAS_SCU_STAT is set in + * the builtin features of the device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_scu_stat + * @see ::mbgextio_get_scu_stat_info + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_scu_stat_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const SCU_STAT_SETTINGS *p ) +{ + // TODO: request ACK for SCU_STAT_SETTINGS (at the moment, this is not implemented in RSC/MDU) + GPS_CMD cmd = GPS_SCU_STAT; + SCU_STAT_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.scu_stat_settings; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_scu_stat_settings( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_scu_stat_settings + + + +#if _USE_TIME_MON && defined( _PRELIMINARY_CODE ) + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_get_inst_info( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, MBG_TIME_MON_INST_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_TIME_MON_INST_INFO, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_time_mon_inst_info( p ); + + return rc; + +} // mbgextio_time_mon_get_inst_info + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_send_inst_info( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, const MBG_TIME_MON_INST_INFO *p ) +{ + GPS_CMD cmd = GPS_TIME_MON_INST_INFO | OPT_GPS_ACK_CODE; + MBG_TIME_MON_INST_INFO *p_data = &pmctl->xmt.pmb->u.msg_data.time_mon_inst_info; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_time_mon_inst_info( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_time_mon_send_inst_info + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_send_target_settings( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, const MBG_TIME_MON_TARGET_SETTINGS *p ) +{ + GPS_CMD cmd = GPS_TIME_MON_TARGET_SETTINGS | OPT_GPS_ACK_CODE; + MBG_TIME_MON_TARGET_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.time_mon_target_settings; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_time_mon_target_settings( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_time_mon_send_target_settings + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_get_target_status_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, MBG_TIME_MON_TARGET_STATUS_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_TIME_MON_TARGET_STATUS_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_time_mon_target_status_idx( p ); + + return rc; + +} // mbgextio_time_mon_get_target_status_idx + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_get_target_ext_data_set_idx( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, MBG_TIME_MON_TARGET_EXT_DATA_SET_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_TIME_MON_TARGET_EXT_DATA_SET_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_time_mon_target_ext_data_set_idx( p ); + + return rc; + +} // mbgextio_time_mon_get_target_ext_data_set_idx() + +#endif // _USE_TIME_MON && defined( _PRELIMINARY_CODE ) + + + +#if defined( _PRELIMINARY_CODE ) + +/*HDR*/ +/** +* @brief Read a ::MBG_GPIO_FREQ parameter structure from a device. +* +* The ::MBG_GPIO_FREQ parameter structure contains the current frequency +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* +* @return One of the @ref MBG_RETURN_CODES +*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_fdm_freq( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_GPIO_FREQ *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_FDM_FREQ, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_gpio_freq( p ); + + return rc; + +} // mbgextio_get_fdm_freq + + + +/*HDR*/ +/** +* @brief Read a ::MBG_IMS_FDM_INFO parameter structure from a device. +* +* The ::MBG_IMS_FDM_INFO parameter structure contains the ::MBG_IMS_FDM_SETTINGS, the supported nominal frequencies and flags +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* +* @return One of the @ref MBG_RETURN_CODES +*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_FDM_INFO, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_ims_fdm_info( p ); + + return rc; + +} // mbgextio_get_ims_fdm_info + + + +/*HDR*/ +/** +* @brief Read a ::MBG_IMS_FDM_LIMITS parameter structure from a device. +* +* The ::MBG_IMS_FDM_LIMITS parameter structure contains the limits of the configurable parameters and number of outpus +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* +* @return One of the @ref MBG_RETURN_CODES +*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_LIMITS *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_FDM_LIMITS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_ims_fdm_limits( p ); + + return rc; + +} // mbgextio_get_ims_fdm_limits + + + +/*HDR*/ +/** +* @brief Read a ::MBG_IMS_FDM_OUTPUT_INFO_IDX parameter structure from a device. +* +* The ::MBG_IMS_FDM_OUTPUT_INFO parameter structure contains the ::MBG_IMS_FDM_OUTPUT_SETTINGS, the supported modes and specific DAC limits +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* @param[in] idx Index of the array element to be retrieved, 0..::MBG_IMS_FDM_LIMITS::n_outputs-1 +* +* @return One of the @ref MBG_RETURN_CODES +*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_output_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_OUTPUT_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_FDM_OUTPUT_INFO_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_ims_fdm_output_info_idx( p ); + + return rc; + +} // mbgextio_get_ims_fdm_output_info_idx + + + +/*HDR*/ +/** +* @brief Read a ::MBG_IMS_FDM_OUTPUT_STATE_IDX parameter structure from a device. +* +* The ::MBG_IMS_FDM_OUTPUT_STATE parameter structure contains the current DAC val and specs and the configured mode +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* @param[in] idx Index of the array element to be retrieved, 0..::MBG_IMS_FDM_LIMITS::n_outputs-1 +* +* @return One of the @ref MBG_RETURN_CODES +*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_output_state_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_OUTPUT_STATE_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_FDM_OUTPUT_STATE_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_ims_fdm_output_state_idx( p ); + + return rc; + +} // mbgextio_get_ims_fdm_output_state_idx + + + +/*HDR*/ +/** +* @brief Read a ::MBG_IMS_FDM_STATE parameter structure from a device. +* +* The ::MBG_IMS_FDM_STATE parameter structure contains the current frequency, the reference, powerline and sync time, the configured nominal frequency and flags +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* +* @return One of the @ref MBG_RETURN_CODES +*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_STATE *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_FDM_STATE, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_ims_fdm_state( p ); + + return rc; + +} // mbgextio_get_ims_fdm_state + + + +/*HDR*/ +/** +* @brief Write a ::MBG_IMS_FDM_SETTINGS parameter structure to a device. +* +* The ::MBG_IMS_FDM_SETTINGS parameter structure contains the limits for time and frequency deviation and the nominal frequency +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[in] p Pointer to the data structure to be sent to the device +* +* @return One of the @ref MBG_RETURN_CODES +*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ims_fdm_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_IMS_FDM_SETTINGS *p ) +{ + GPS_CMD cmd = GPS_FDM_SETTINGS | OPT_GPS_ACK_CODE; + MBG_IMS_FDM_SETTINGS *p_data = &pmctl->xmt.pmb->u.msg_data.fdm_settings; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_mbg_ims_fdm_settings( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ims_fdm_settings + + + +/*HDR*/ +/** + * @brief Write a ::MBG_IMS_FDM_OUTPUT_SETTINGS parameter structure to a device. + * + * The ::MBG_IMS_FDM_SETTINGS parameter structure contains the analog output mode + * + * @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be set, 0..::MBG_IMS_FDM_LIMITS::n_outputs-1 + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_ims_fdm_output_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + const MBG_IMS_FDM_OUTPUT_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_FDM_OUTPUT_SETTINGS_IDX | OPT_GPS_ACK_CODE; + MBG_IMS_FDM_OUTPUT_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.fdm_output_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_mbg_ims_fdm_output_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_ims_fdm_output_settings_idx + + + +/*HDR*/ +/** + * @brief Set time deviation of powerline time in relation to the current reference time + * + * @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags and + * ::MBG_IMS_FDM_FLAG_CAN_SET_TDEV is set in ::MBG_IMS_FDM_INFO::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_fdm_tdev( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NANO_TIME_64 *p ) +{ + GPS_CMD cmd = GPS_FDM_SET_TD | OPT_GPS_ACK_CODE; + NANO_TIME_64 *p_data = &pmctl->xmt.pmb->u.msg_data.nano_time_64; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_nano_time_64( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_fdm_tdev + +#endif // defined( _PRELIMINARY_CODE ) + + + +/*HDR*/ +/** + * @brief Send a command to let the device save it's current configuration as default + * + * Call ::mbgextio_dev_has_cmd_save_cfg to check if this function is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_cmd_save_cfg + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_cmd_save_cfg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) +{ + return mbgextio_xmt_cmd( pmctl, p_addr, GPS_SAVE_CFG | OPT_GPS_ACK_CODE ); + + //### TODO: check if ACK works + +} // mbgextio_cmd_save_cfg + + + +/*HDR*/ +/** + * @brief Read a ::MBG_IMS_FDM_STATE parameter structure from a device. + * ::TODO ### + * + * @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::TODO MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_lne_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LNE_LIMITS *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_LNE_LIMITS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_lne_limits( p ); + + return rc; + +} // mbgextio_get_lne_limits + + + +/*HDR*/ +/** + * @brief Read a ::MBG_LNE_PORT_INFO_IDX parameter structure from a device. + * + * @note ### ::TODO Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_LNE_LIMITS::num_ports-1 + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_lne_port_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LNE_PORT_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_LNE_PORT_INFO_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_lne_port_info_idx( p ); + + return rc; + +} // mbgextio_get_lne_port_info_idx + + + +/*HDR*/ +/** + * @brief Read a ::MBG_LNE_PORT_SETTINGS_IDX parameter structure from a device. + * + * @note ### ::TODO Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_LNE_LIMITS::num_ports + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_lne_port_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LNE_PORT_SETTINGS_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_LNE_PORT_SETTINGS_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_lne_port_settings_idx( p ); + + return rc; + +} // mbgextio_get_lne_port_settings_idx + + + +/*HDR*/ +/** + * @brief Write a ::MBG_LNE_PORT_SETTINGS parameter structure to a device. + * + * @note ### ::TODO Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be set, 0..::MBG_LNE_LIMITS::num_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_lne_port_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_LNE_PORT_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_LNE_PORT_SETTINGS_IDX | OPT_GPS_ACK_CODE; + MBG_LNE_PORT_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.lne_port_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_mbg_lne_port_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_lne_port_settings_idx + + + +/*HDR*/ +/** + * @brief Write a ::MBG_PWR_CTL parameter structure to a device. + * + * @note Only supported if ::MBG_XFEATURE_PWR_CTL_API is set + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_pwr_ctl( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PWR_CTL *p ) +{ + GPS_CMD cmd = GPS_PWR_CTL | OPT_GPS_ACK_CODE; + MBG_PWR_CTL *p_data = &pmctl->xmt.pmb->u.msg_data.pwr_ctl; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + *p_data = *p; + _mbg_swab_mbg_pwr_ctl( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_pwr_ctl + + + +/*HDR*/ +/** + * @brief Read a ::MBG_PWR_CTL parameter structure from a device. + * + * @note ### ::TODO Only supported if ::MBG_XFEATURE_PWR_CTL_API is set + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_pwr_ctl( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PWR_CTL *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_PWR_CTL, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_pwr_ctl( p ); + + return rc; + +} // mbgextio_get_pwr_ctl + + + +/*HDR*/ +/** + * @brief Read the ::MBG_LED_LIMITS to check how many LEDs are provided + * + * ::mbgextio_dev_has_led_api should be used to check if this is supported + * + * @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @ingroup group_led_api + * @see ::mbgextio_dev_has_led_api + * @see ::mbgextio_get_led_limits + * @see ::mbgextio_get_led_info_idx + * @see ::mbgextio_get_led_settings_idx + * @see ::mbgextio_set_led_settings_idx + * @see @ref group_led_api + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_led_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_LED_LIMITS *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_LED_LIMITS, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_led_limits( p ); + + return rc; + +} // mbgextio_get_led_limits + + + +/*HDR*/ +/** + * @brief Read the current settings and features of a particular LED + * + * ::mbgextio_dev_has_led_api should be used to check if this is supported + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_LED_LIMITS::num_leds-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @ingroup group_led_api + * @see ::mbgextio_dev_has_led_api + * @see ::mbgextio_get_led_limits + * @see ::mbgextio_get_led_settings_idx + * @see ::mbgextio_set_led_settings_idx + * @see @ref group_led_api + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_led_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, + MBG_LED_INFO_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_LED_INFO_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_led_info_idx( p ); + + return rc; + +} // mbgextio_get_led_info_idx + + + +/*HDR*/ +/** + * @brief Read a ::MBG_LED_SETTINGS_IDX parameter structure from a device. + * + * ::mbgextio_dev_has_led_api should be used to check if this is supported + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::num_leds-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @ingroup group_led_api + * @see ::mbgextio_dev_has_led_api + * @see ::mbgextio_get_led_limits + * @see ::mbgextio_get_led_info_idx + * @see ::mbgextio_set_led_settings_idx + * @see @ref group_led_api + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_led_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LED_SETTINGS_IDX *p, uint16_t idx ) +{ + int rc = mbgextio_req_data_idx( pmctl, p_addr, GPS_LED_SETTINGS_IDX, idx, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_mbg_led_settings_idx( p ); + + return rc; + +} // mbgextio_get_led_settings_idx + + + +/*HDR*/ +/** + * @brief Write a ::MBG_LED_SETTINGS parameter structure to a device. + * + * ::mbgextio_dev_has_led_api should be used to check if this is supported + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be set, 0..::MBG_LNE_LIMITS::num_ports-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @ingroup group_led_api + * @see ::mbgextio_dev_has_led_api + * @see ::mbgextio_get_led_limits + * @see ::mbgextio_get_led_info_idx + * @see ::mbgextio_get_led_settings_idx + * @see @ref group_led_api + */ +_NO_MBG_API_ATTR int _MBG_API mbgextio_set_led_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_LED_SETTINGS *p, uint16_t idx ) +{ + GPS_CMD cmd = GPS_LED_SETTINGS_IDX | OPT_GPS_ACK_CODE; + MBG_LED_SETTINGS_IDX *p_data = &pmctl->xmt.pmb->u.msg_data.led_settings_idx; + + #if _USE_MUTEX + _mbg_mutex_acquire( &pmctl->dev_mutex ); + #endif + + p_data->settings = *p; + p_data->idx = idx; + _mbg_swab_mbg_led_settings_idx( p_data ); + + return mbgextio_xmt_msg( pmctl, p_addr, cmd, NULL, sizeof( *p_data ) ); + +} // mbgextio_set_led_settings_idx + + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_ext_sys_info( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + MBG_EXT_SYS_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, GPS_EXT_SYS_INFO, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_ext_sys_info( p ); + + return rc; + +} // mbgextio_get_ext_sys_info + + +/*HDR*/ +_NO_MBG_API_ATTR int _MBG_API mbgextio_get_corr_info( MBG_MSG_CTL *pmctl, + const XBP_ADDR *p_addr, + CORR_INFO *p ) +{ + int rc = mbgextio_req_data( pmctl, p_addr, PZF_CORR_INFO, p, sizeof( *p ) ); + + if ( mbg_rc_is_success( rc ) && p ) + _mbg_swab_corr_info( p ); + + return rc; + +} // mbgextio_get_core_info + + + diff --git a/mbglib/common/mbgextio.h b/mbglib/common/mbgextio.h index 1fd5b89..d6370be 100644 --- a/mbglib/common/mbgextio.h +++ b/mbglib/common/mbgextio.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgextio.h 1.16.1.11 2015/07/22 16:02:08Z martin TEST martin $ + * $Id: mbgextio.h 1.16.1.126 2017/04/12 08:35:11Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,227 @@ * * ----------------------------------------------------------------------- * $Log: mbgextio.h $ - * Revision 1.16.1.11 2015/07/22 16:02:08Z martin + * Revision 1.16.1.126 2017/04/12 08:35:11Z martin + * Updated function prototypes. + * Revision 1.16.1.125 2017/04/05 16:07:36 martin + * Updated function prototypes. + * Revision 1.16.1.124 2017/03/27 10:38:41 thomas-b + * Added functions to read and write PTPv1 common datasets + * Revision 1.16.1.123 2017/03/20 10:10:03 martin + * Fixed build without _PRELIMINARY_CODE. + * Revision 1.16.1.122 2017/03/07 13:45:56 thomas-b + * Added functions to get and set ignore lock + * Revision 1.16.1.121 2017/03/03 06:46:05 thomas-b + * Added functions to read/write NTP key, server, refclock and orphan mode settings + * Revision 1.16.1.120 2017/02/23 14:32:09 thomas-b + * *** empty log message *** + * Revision 1.16.1.119 2017/02/22 08:31:14 thomas-b + * Added functions to read/write event info and read monitoring status and event status + * Revision 1.16.1.118 2017/02/16 13:01:53 thomas-b + * Changed get and set functions for PTPv2 port dataset to use idx structure + * Revision 1.16.1.117 2017/02/16 09:27:59 thomas-b + * Fixed doxygen docu + * Revision 1.16.1.116 2017/02/16 09:24:33 thomas-b + * Added functions to get and set PTPv2 common datasets + * Revision 1.16.1.115 2017/02/15 16:17:38 martin + * *** empty log message *** + * Revision 1.16.1.114 2017/02/08 13:12:36 thomas-b + * Added functions to get and set SNMP configuration + * Revision 1.16.1.113 2017/02/07 14:24:52 thomas-b + * Added function mbgextio_dev_has_monitoring, which checks if the extended feature MBG_XFEATURE_MONITORING is set + * Revision 1.16.1.112 2017/02/07 14:10:19 daniel + * Added calls to check for new License TLV feature types + * Revision 1.16.1.111 2016/12/07 09:34:14 martin + * Updated function prototypes. + * Revision 1.16.1.110 2016/11/30 16:12:55 thomas-b + * Added functions to get/set SCU_STAT_INFO/SCU_STAT_SETTINGS + * Revision 1.16.1.109 2016/11/22 10:33:15 philipp + * Implemented I/O ports + * Revision 1.16.1.108 2016/11/02 12:15:18 thomas-b + * Added function to check if a device has MBG_XFEATURE_REQ_TTM and adapted the documentation for mbgextio_get_time + * Revision 1.16.1.107 2016/10/31 09:28:06 martin + * Doxygen fixes. + * Revision 1.16.1.106 2016/10/25 09:11:19 thomas-b + * Added functions to get CFGH, ALM and IONO structures from a device + * Revision 1.16.1.105 2016/10/24 13:59:43 thomas-b + * Removed needless space from comment + * Fixed mbgextio_rcv_msg_unlocked for reception of XBP packets + * Revision 1.16.1.104 2016/10/20 14:46:04 thomas-b + * Added function to check if XBP is supported + * Revision 1.16.1.103 2016/10/20 11:29:15 martin + * Added missing const qualifier in mbgextio_get_utc_param(). + * Revision 1.16.1.102 2016/10/20 10:43:35 thomas-b + * Added function to check if a device is a bus level device + * Revision 1.16.1.101 2016/10/19 14:33:44 thomas-b + * Added functions to read and write ucap via network configuration + * Revision 1.16.1.100 2016/10/14 11:09:41 thomas-b + * Added function to check MBG_XFEATURE_UCAP_NET + * Revision 1.16.1.99 2016/09/29 14:35:12 thomas-b + * Moved new get and set functions for NET_CFG_API stage 2 to mbgextio + * Revision 1.16.1.98 2016/09/29 12:19:58 thomas-b + * Added function to check transactions feature + * Revision 1.16.1.97 2016/09/20 13:52:38 martin + * Moved GPS_REQACK preprocessor handling to the header file. + * Revision 1.16.1.96 2016/08/23 15:12:01 martin + * Updated function prototypes. + * Revision 1.16.1.95 2016/08/23 08:33:39 udo + * renamed some Time Mon functions + * Revision 1.16.1.94 2016/08/22 14:14:48 gregoire.diehl + * new call: mbgextio_get_corr_info + * Revision 1.16.1.93 2016/08/15 09:42:19Z udo + * added mbgextio_time_mon_get_target_ext_data_set_idx() + * Revision 1.16.1.92 2016/08/11 11:30:54 martin + * Conditionally support time monitoring API. + * Revision 1.16.1.91 2016/08/01 10:33:02 daniel + * Updated function prototypes + * Revision 1.16.1.90 2016/07/07 15:03:32 martin + * Updated function prototypes. + * Revision 1.16.1.89 2016/06/15 10:15:50 thomas-b + * Added functions which check if the user capture feature is supported by a device + * Revision 1.16.1.88 2016/06/14 10:33:22 thomas-b + * Added functions which check if the event log feature is supported by a device + * Revision 1.16.1.87 2016/06/08 09:55:14 thomas-b + * Added function mbgextio_open_serial_force_default + * Revision 1.16.1.86 2016/06/07 14:50:34 udo + * Reset Meinberg USB device in case if the open_usb function return MBG_ERR_BUSY + * Revision 1.16.1.85 2016/06/07 07:43:07 philipp + * New function to check for Irig Rx feature + * Revision 1.16.1.84 2016/06/02 10:23:58 philipp + * Renaming all MBG_EXT_REV_INFO related stuff to MBG_EXT_SYS_INFO + * Revision 1.16.1.83 2016/05/30 08:10:45 thomas-b + * Added functions to check several builtin features + * Revision 1.16.1.82 2016/05/27 05:18:20 philipp + * New functions mbgextio_get_xmr_ext_source_stats_idx and mbgextio_get_xmr_ext_source_metrics_idx + * Revision 1.16.1.81 2016/05/25 09:23:00 philipp + * New function mbgextio_get_xmr_ext_source_stats_idx + * Revision 1.16.1.80 2016/05/20 13:37:55 philipp + * New function mbgextio_set_gpio_settings_idx + * Revision 1.16.1.79 2016/05/20 09:41:36 thomas-b + * Removed functions which check for a specific IMS card + * Revision 1.16.1.78 2016/05/20 08:51:23 thomas-b + * Added functions mbgextio_dev_has_time_scale and mbgextio_dev_has_tzcode + * Revision 1.16.1.77 2016/05/20 07:51:35 thomas-b + * Added function mbgextio_dev_has_tzdl + * Revision 1.16.1.76 2016/05/20 06:42:09 thomas-b + * Added function mbgextio_dev_has_enable_flags + * Revision 1.16.1.75 2016/05/17 13:29:38 philipp + * New function to check whether device is LNO + * Revision 1.16.1.74 2016/05/17 06:33:10 philipp + * New function to check whether a device has serial outputs + * Revision 1.16.1.73 2016/05/12 10:41:38 philipp + * New functions to check bpe card and IRIG Tx feature + * Revision 1.16.1.72 2016/05/10 06:15:29 philipp + * New function to check whether a device has programmable pulses + * Revision 1.16.1.71 2016/04/26 06:55:47 thomas-b + * Added functions to check if NET_CFG and LAN_IP4 APIs are supported + * Revision 1.16.1.70 2016/04/25 14:47:15 martin + * *** empty log message *** + * Revision 1.16.1.69 2016/04/22 10:54:00 philipp + * New function to check whether device is LIU + * Revision 1.16.1.68 2016/04/20 13:20:27 thomas-b + * Added function to check if a device supports NTP + * Revision 1.16.1.67 2016/04/20 09:26:13 philipp + * Moved all HPS-PTP related structures to gpspriv.h and removed related extended feature bit from gpsdefs.h. + * Also removed functions from mbgextio and xdevfeat since HPS-PTP handling needs a redesign concerning structures. + * Thus, handle everything explicitly for now! + * -> Redesing this A.S.A.P.!!! + * Revision 1.16.1.66 2016/04/15 08:17:26 philipp + * New feature MBG_XFEATURE_EXT_PTP + * Revision 1.16.1.65 2016/04/13 07:01:21 philipp + * New function to check whether device is HPS + * Revision 1.16.1.64 2016/04/12 13:27:41 philipp + * Several new functions to check for device models and device features + * Revision 1.16.1.63 2016/04/11 13:56:48 thomas-b + * Added function mbgextio_dev_has_xmulti_ref + * Revision 1.16.1.62 2016/04/07 14:08:45 philipp + * Added function prototype mbgextio_get_ext_rev_info + * Revision 1.16.1.61 2016/04/07 12:46:19 martin + * Updated function prototypes. + * Revision 1.16.1.60 2016/03/24 14:08:51 martin + * *** empty log message *** + * Revision 1.16.1.59 2016/03/22 12:53:20 thomas-b + * Added functions to find and free Meinberg LAN devices + * Revision 1.16.1.58 2016/03/18 11:21:56Z martin + * *** empty log message *** + * Revision 1.16.1.57 2016/03/18 10:48:33 martin + * *** empty log message *** + * Revision 1.16.1.56 2016/03/17 11:33:11 philipp + * Added XMR functions + * Revision 1.16.1.55 2016/03/16 15:09:11 martin + * Updated function prototypes. + * Revision 1.16.1.54 2016/03/14 11:53:34 martin + * Updated function prototypes. + * Revision 1.16.1.53 2016/03/11 08:20:12 marvin + * Added function to save PTP unicast master settings. + * Revision 1.16.1.52 2016/02/25 12:03:18Z udo + * Revision 1.16.1.51 2016/02/17 15:03:17 udo + * used MBG_TIME_MON_TARGET_STATUS_IDX + * Revision 1.16.1.47 2016/02/03 09:30:57 martin + * Fixed build without libusb. + * Revision 1.16.1.46 2016/02/03 09:16:50Z martin + * *** empty log message *** + * Revision 1.16.1.45 2016/02/02 15:58:13 martin + * Updated function prototypes. + * Revision 1.16.1.44 2016/01/19 14:13:55 udo + * improve time monitor functions + * Revision 1.16.1.43 2016/01/18 08:53:35 udo + * added support for PTP Time Monitoring on TSU/HPS100 + * Revision 1.16.1.42 2016/01/04 15:55:41 martin + * Updated function prototypes. + * Revision 1.16.1.41 2015/12/10 11:55:16 martin + * *** empty log message *** + * Revision 1.16.1.40 2015/12/07 16:36:37 martin + * *** empty log message *** + * Revision 1.16.1.39 2015/12/03 16:00:40 martin + * *** empty log message *** + * Revision 1.16.1.38 2015/12/01 11:36:02 martin + * *** empty log message *** + * Revision 1.16.1.37 2015/11/30 08:16:15 philipp + * Added (wrapper) functions to test for TLV features + * Revision 1.16.1.36 2015/11/26 16:19:27 martin + * Reworked check feature API causing some other API calls to be + * simplified/changed since receiver info is now stored inside + * the message control block. + * Revision 1.16.1.35 2015/11/23 12:55:26 philipp + * Removed TLV functions + * Revision 1.16.1.33 2015/11/20 10:06:36 philipp + * Changed USB direct I/O receive buffer size to fit maximum message length + * Revision 1.16.1.32 2015/11/20 08:14:39 philipp + * Added id member to struct MBG_TLV_ANNOUNCE + * Revision 1.16.1.31 2015/11/20 07:27:38 philipp + * Adjusted functions and prototypes to match new TLV structures from gpsdefs.h + * Revision 1.16.1.30 2015/11/19 13:15:46 philipp + * Added TLV functionality + * Revision 1.16.1.29 2015/10/30 11:08:12 martin + * Removed obsolete definitions originating from mbgserio.h. + * Revision 1.16.1.28 2015/10/19 16:42:21Z martin + * *** empty log message *** + * Revision 1.16.1.27 2015/10/19 09:35:13 martin + * *** empty log message *** + * Revision 1.16.1.26 2015/10/09 11:09:18 martin + * *** empty log message *** + * Revision 1.16.1.25 2015/10/06 14:19:09 martin + * *** empty log message *** + * Revision 1.16.1.24 2015/10/02 08:57:47 thomas-b + * Added several functions to retrieve and set parameter structures of the new FDM API + * Revision 1.16.1.23 2015/10/02 08:18:51 martin + * *** empty log message *** + * Revision 1.16.1.22 2015/09/15 13:25:53 martin + * *** empty log message *** + * Revision 1.16.1.21 2015/09/09 11:05:46 gregoire + * Revision 1.16.1.20 2015/09/09 08:41:02Z martin + * Revision 1.16.1.19 2015/09/09 08:26:28 martin + * Revision 1.16.1.18 2015/09/08 15:25:11 martin + * Revision 1.16.1.17 2015/09/04 09:44:44 daniel + * Updated function prototypes + * Revision 1.16.1.16 2015/09/02 16:42:21 martin + * Preliminary code which is only included if a preprocessor symbol + * _PRELIMINARY_CODE is defined in the project Makefile. + * Revision 1.16.1.15 2015/08/27 16:21:32 martin + * Revision 1.16.1.14 2015/08/20 09:08:17 martin + * Revision 1.16.1.13 2015/08/18 09:54:03 martin + * Revision 1.16.1.12 2015/08/12 15:53:58Z martin + * Revision 1.16.1.11 2015/07/22 16:02:08 martin * Started to support variable USB endpoint numbers. * Revision 1.16.1.10 2015/07/14 15:10:27 martin * Updated function prototypes. @@ -104,6 +324,14 @@ #include <gpsserio.h> #include <mbggeo.h> +#if _USE_PCPSDEFS + #include <pcpsdefs.h> +#endif + +#if _USE_TIME_MON + #include <time_mon.h> +#endif + #include <time.h> #ifdef _MBGEXTIO @@ -116,6 +344,16 @@ /* Start of header body */ +/** + * @defgroup mbgextio_chk_supp_fncs mbgextio functions used to check if a particular feature is supported + * @ingroup chk_supp_fncs + * + * Each of these functions can be used to check if a device supports a particular feature. + * ::MBG_SUCCESS is returned if the requested feature is supported, otherwise one of the + * @ref MBG_ERROR_CODES is returned, as appropriate. + */ + + // The macros below can be used to set a TTM variable to a state // indicating "time not available", and to check this state. // This can be used for example to indicate if a capture event @@ -124,33 +362,32 @@ #define _ttm_time_is_avail( _t ) ( (uint8_t) (_t)->tm.sec != (uint8_t) 0xFF ) -#if _USE_SERIAL_IO - #if !defined( DEFAULT_DEV_NAME ) - #if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_DOS ) - #define DEFAULT_DEV_NAME "COM1" - #elif defined( MBG_TGT_LINUX ) - #define DEFAULT_DEV_NAME "/dev/ttyS0" - #endif - #endif -#endif // _USE_SERIAL_IO - - #if !_USE_SERIAL_IO_FTDI - // just to avoid build errors if USB not supported + // just to avoid build errors if FTDI serial is not supported #define FT_STATUS int #define FT_HANDLE int #endif #if !_USE_USB_IO - // just to avoid build errors if USB not supported - struct usb_device - { - int dummy; - }; + // just to avoid build errors if USB is not supported + typedef int MBG_USB_DEV_INFO; + typedef int libusb_device; +#endif + - typedef int MBG_USB_DEVICE; +#if !defined( _MBGEXTIO_REQ_ACK ) + // If _MBGEXTIO_REQ_ACK is != 0 then mbgextio_...() functions writing + // configuration parameters send the cmd code with the ACK request bit set + // which lets mbgextio_xmt_msg() try to receive a response from the device + // after the parameters have been sent. + #define _MBGEXTIO_REQ_ACK 1 +#endif +#if _MBGEXTIO_REQ_ACK + #define OPT_GPS_ACK_CODE GPS_REQACK +#else + #define OPT_GPS_ACK_CODE 0 // dummy #endif @@ -159,7 +396,7 @@ #define MBGEXTIO_READ_BUFFER_SIZE 1000 #else #if defined _USE_USB_DIRECT_IO - #define MBGEXTIO_READ_BUFFER_SIZE 512 // Max. USB transfer buffer size + #define MBGEXTIO_READ_BUFFER_SIZE (MAX_MSG_DATA_SIZE + 1) // See gpsserio.h + SOH #else #define MBGEXTIO_READ_BUFFER_SIZE 10 #endif @@ -186,6 +423,69 @@ _ext const char *mbg_framing_strs[N_MBG_FRAMINGS] ; +#if _USE_SOCKET_IO + + #define MBG_LAN_REQUEST_CONFIG 0x000000F8 + #define MBG_LAN_RESPOND_CONFIG 0x000000F9 + #define MBG_LAN_UDP_BROADCAST_PORT 30718 + + typedef struct + { + uint8_t interface_mode; + uint8_t line_speed; + uint8_t flow_control; + uint8_t reserved_0; + uint16_t own_tcp_port; + uint16_t remote_tcp_port; + uint32_t remote_ip_address; + uint8_t connect_mode; + uint8_t disconnect_mode; + uint8_t disconnect_timeout_min; + uint8_t disconnect_timeout_sec; + uint8_t trigger_char_semd_imm0; + uint8_t trigger_char_semd_imm1; + uint8_t flush_mode; + uint8_t pack_control; + uint32_t reserved_1[3]; + uint8_t terminal_name[16]; + } MBG_LAN_DEV_CHAN; + + typedef struct + { + uint32_t command; + uint32_t ip_address; + uint8_t reserved_0; + uint8_t flags; + uint8_t prefix; + uint8_t reserved_1; + uint32_t telnet_password; + uint32_t gateway_ip_address; + MBG_LAN_DEV_CHAN channel_0; + MBG_LAN_DEV_CHAN channel_1; + uint32_t reserved_2; + uint32_t reserved_3; + } MBG_LAN_DEV_CFG; + + typedef struct mbg_lan_dev_list + { + MBG_LAN_DEV_CFG config; + struct mbg_lan_dev_list *next; + } MBG_LAN_DEV_LIST; + +#else + + typedef int MBG_LAN_DEV_CHAN; + typedef int MBG_LAN_DEV_CFG; + typedef int MBG_LAN_DEV_LIST; + +#endif + + +/** + * @brief Type of functions to check if a feature is supported + */ +typedef int _MBG_API MBGEXTIO_CHK_SUPP_FNC( const MBG_MSG_CTL *pmctl ); + /* function prototypes: */ @@ -193,11 +493,44 @@ _ext const char *mbg_framing_strs[N_MBG_FRAMINGS] extern "C" { #endif + +#if defined( MBG_TGT_WIN32 ) + void deinit_winsock( void ); + int check_init_winsock( void ); +#endif + + /* ----- function prototypes begin ----- */ /* This section was generated automatically */ /* by MAKEHDR, do not remove the comments. */ + const char *mbgextio_get_cmd_name( GPS_CMD cmd_code ) ; + /** + * @brief Sets up a list of all available Meinberg LAN devices in the network + * + * List entries will be allocated and have to be freed by calling ::mbgextio_free_lan_devices + * + * @param[out] list Pointer to the list + * @param[in] timeout_ms Timeout in ms for each network interface + * + * @return One of the @ref MBG_RETURN_CODES or the number of found devices on success + * + * @see ::mbgextio_free_lan_devices + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_find_lan_devices( MBG_LAN_DEV_LIST **list, uint16_t timeout_ms ) ; + + /** + * @brief Frees the ::MBG_LAN_DEV_LIST allocated by ::mbgextio_find_lan_devices + * + * @param[in] list The list that will be freed + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_find_lan_devices + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_free_lan_devices( MBG_LAN_DEV_LIST *list ) ; + /** * @brief Send security settings for the socket connection * @@ -234,6 +567,7 @@ extern "C" { */ _NO_MBG_API_ATTR int _MBG_API mbgextio_open_socket( const char *host, MBG_MSG_CTL **ppmctl, const char *passwd ) ; + int mbgextio_open_serial_raw( const char *dev, MBG_MSG_CTL **ppmctl, uint32_t baud_rate, const char *framing ) ; /** * @brief Open a binary communication channel using direct serial I/O * @@ -261,6 +595,29 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial( const char *dev, MBG_MSG_CTL **ppmctl, uint32_t baud_rate, const char *framing ) ; /** + * @brief Open a binary communication channel forcing default serial parameters + * + * If current serial paramaters (baud rate and framing) do not match the default + * parameters for binary communication then the serial device is forced into + * binary communication mode. + * + * @param[in] dev Name of the serial port to which the device is connected, + * depending on the naming conventions of the host system. + * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure + * allocated and set up by this call. Set to NULL on error. + * @param[in] baud_rate Baud rate used for serial communication + * @param[in] framing Framing used for serial communication + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_open_serial + * @see ::mbgextio_open_serial_raw + * @see ::mbgserio_write + * @see ::mbgextio_close_connection + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_open_serial_force_default( const char *dev, MBG_MSG_CTL **ppmctl, uint32_t baud_rate, const char *framing ) ; + + /** * @brief Get the port handle of a serial FTDI device * * @param[in,out] pmctl Pointer to a valid message control structure @@ -297,7 +654,39 @@ extern "C" { /** * @brief Open a binary communication channel using direct USB I/O * - * @param[in] usbdev The USB device to communicate with. + * @param[in] mdev_info The USB device to communicate with. + * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure + * allocated and set up by this call. Set to NULL on error. + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_open_socket + * @see ::mbgextio_open_serial + * @see ::mbgextio_open_serial_ftdi + * @see ::mbgextio_close_connection + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb( const MBG_USB_DEV_INFO *mdev_info, MBG_MSG_CTL **ppmctl ) ; + + /** + * @brief Reset an USB device in case that the open_usb function return MBG_ERR_BUSY + * + * @param[in] mdev_info The USB device to communicate with. + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_open_socket + * @see ::mbgextio_open_serial + * @see ::mbgextio_open_serial_ftdi + * @see ::mbgextio_close_connection + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_reset_usb( const MBG_USB_DEV_INFO *mdev_info ) ; + + /** + * @brief Open a binary communication channel using direct USB I/O + * + * //### TODO group opening functions, ref to group only + * + * @param[in] ldev A libusb_device to communicate with. * @param[out] ppmctl Address of a pointer to a ::MBG_MSG_CTL control structure * allocated and set up by this call. Set to NULL on error. * @@ -308,7 +697,7 @@ extern "C" { * @see ::mbgextio_open_serial_ftdi * @see ::mbgextio_close_connection */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_open_usb( const MBG_USB_DEVICE *usbdev, MBG_MSG_CTL **ppmctl ) ; + int mbgextio_open_usb_ldev( libusb_device *ldev, MBG_MSG_CTL **ppmctl ) ; /** * @brief Open a binary communication channel using direct USB I/O @@ -420,6 +809,29 @@ extern "C" { _NO_MBG_API_ATTR long _MBG_API mbgextio_force_conn_serial_ftdi( int device_num ) ; /** + * @brief Set a message callback function + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] fnc Address of the callback function to be registered + * + * @return Address of the allocated receive buffer + * + * @see ::mbgextio_get_rcv_buffer_size + * @see ::mbgextio_get_xmt_buffer_addr + * @see ::mbgextio_get_xmt_buffer_size + */ + _NO_MBG_API_ATTR void _MBG_API mbgextio_register_msg_callback( MBG_MSG_CTL *pmctl, MBG_MSG_HANDLER *fnc ) ; + + /** + * @brief Retrieve address of the ::RECEIVER_INFO read from the device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Address of the ::RECEIVER_INFO read from the device when the device was opened + */ + _NO_MBG_API_ATTR RECEIVER_INFO * _MBG_API mbgextio_get_receiver_info_addr( MBG_MSG_CTL *pmctl ) ; + + /** * @brief Retrieve address of the allocated receive buffer * * @param[in,out] pmctl Pointer to a valid message control structure @@ -472,29 +884,31 @@ extern "C" { _NO_MBG_API_ATTR size_t _MBG_API mbgextio_get_xmt_buffer_size( MBG_MSG_CTL *pmctl ) ; /** - * @brief Set character receive timeout value + * @brief Set device poll timeout * * @param[in,out] pmctl Pointer to a valid message control structure - * @param[in] new_timeout New timeout value [ms] + * @param[in] new_timeout New poll timeout value [ms] + * + * @return Previous poll timeout value [ms] * - * @see ::mbgextio_get_char_rcv_timeout + * @see ::mbgextio_get_dev_poll_timeout * @see ::mbgextio_set_msg_rcv_timeout * @see ::mbgextio_get_msg_rcv_timeout */ - _NO_MBG_API_ATTR void _MBG_API mbgextio_set_char_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) ; + _NO_MBG_API_ATTR ulong _MBG_API mbgextio_set_dev_poll_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) ; /** - * @brief Get character receive timeout value + * @brief Get device poll timeout * * @param[in,out] pmctl Pointer to a valid message control structure * - * @return Current timeout value [ms] + * @return Current poll timeout value [ms] * - * @see ::mbgextio_set_char_rcv_timeout + * @see ::mbgextio_set_dev_poll_timeout * @see ::mbgextio_set_msg_rcv_timeout * @see ::mbgextio_get_msg_rcv_timeout */ - _NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_char_rcv_timeout( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_dev_poll_timeout( const MBG_MSG_CTL *pmctl ) ; /** * @brief Set message receive timeout value @@ -502,8 +916,8 @@ extern "C" { * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] new_timeout New timeout value [ms] * - * @see ::mbgextio_set_char_rcv_timeout - * @see ::mbgextio_get_char_rcv_timeout + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_get_dev_poll_timeout * @see ::mbgextio_get_msg_rcv_timeout */ _NO_MBG_API_ATTR void _MBG_API mbgextio_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) ; @@ -515,13 +929,498 @@ extern "C" { * * @return Current timeout value [ms] * - * @see ::mbgextio_set_char_rcv_timeout - * @see ::mbgextio_get_char_rcv_timeout + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_get_dev_poll_timeout * @see ::mbgextio_set_msg_rcv_timeout */ _NO_MBG_API_ATTR ulong _MBG_API mbgextio_get_msg_rcv_timeout( const MBG_MSG_CTL *pmctl ) ; /** + * @brief Get last NACK error code + * + * If an API call has returned ::MBG_ERR_RCVD_NACK then this + * function can be used to retrieve an associated error code + * which eventually specifies the reason for the NACK message. + * + * A NACK message can be received from a device after the device + * has received a command which it doesn't recognize, or a + * parameter set which it doesn't accept, and the message can + * optionally contain one of the @ref MBG_ERROR_CODES. + * + * If the NACK message contains an error code then that code is + * saved, otherwise the saved code is set to ::MBG_ERR_UNSPEC. + * A saved error code is available and can be retrieved until + * the next API call starts to read some data from the device, + * in which case the stored code is set to ::MBG_SUCCESS. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return The saved return code, i.e. one of the @ref MBG_RETURN_CODES. + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_last_nack_err_code( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device is a legacy device + * + * Legacy devices don't support the standard binary protocol, so the + * standard binary API functions must *not* be used with such a device. + * Any attempt to access the device using the standard binary API + * functions may have unpredictable side-effects for the device, but + * the low level read/write functions can be used to access the device + * via a proprietary protocol, depending on the device type. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_DEV_NOT_SUPP + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_is_legacy( const MBG_MSG_CTL *pmctl ) ; + + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_pos_xyz( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_pos_lla( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_time_ttm( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ant_info( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ant_cable_length( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_io_ports( const MBG_MSG_CTL *pmctl ) ; + /** + * @brief Check if a device supports the ::STAT_INFO structure and API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_gps_stat_info( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device can receive the GPS satellite system + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_is_gps( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the GNSS API + * + * This is usually supported by devices which can receive signals + * from different satellite systems, e.g. GPS, GLONASS, ... + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_chk_get_all_gnss_info + * @see ::MBG_GNSS_TYPES + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_is_gnss( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device is a bus level device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_is_bus_lvl_dev( const MBG_MSG_CTL *pmctl ) ; + + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_enable_flags( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_time_scale( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_tzdl( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_tzcode( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ims( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_synth( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_gpio( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_prog_pulses( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_irig_tx( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_irig_rx( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_serouts( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_bvar_stat( const MBG_MSG_CTL *pmctl ) ; + /** + * @brief Check if the device supports the SCU_STAT structures + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + * @see ::mbgextio_get_scu_stat_info + * @see ::mbgextio_set_scu_stat_settings + * @see @ref group_scu + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_scu_stat( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a timecode receiver provides ::MBG_RAW_IRIG_DATA + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_raw_irig_data + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_raw_irig_data( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the old LAN_IP4 API + * + * The LAN_IP4 API provides structures and functions to configure + * parts of the networking of a device and is superseded by the + * NET_CFG API. Some devices combine NET_CFG and LAN_IP4. + * Therefore, ::mbgextio_get_all_net_cfg_info should be used + * preferably to read the network configuration. + * It will translate the old structures into the new ones. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_all_net_cfg_info + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_lan_ip4( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the new NET_CFG API + * + * The NET_CFG API provides structures and functions to configure + * the complete networking part of a device and supersedes the + * LAN_IP4 API. Not all devices support the whole feature set + * of the NET_CFG API or combine NET_CFG and LAN_IP4. + * Therefore, ::mbgextio_get_all_net_cfg_info should be used + * preferably to read the network configuration. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_all_net_cfg_info + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_net_cfg( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the PTP API + * + * The PTP API consists of different calls and associated structures + * which * have evolved over time. Not all devices support every call, + * so ::mbgextio_get_all_ptp_cfg_info takes care to check which parts are + * supported and thus should be used preferably to read PTP information. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_all_ptp_cfg_info + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ptp( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the NTP API + * + * The NTP API consists of different calls and associated structures + * which have evolved over time. Not all devices support every call, + * so ::mbgextio_get_all_ntp_cfg_info takes care to check which parts are + * supported and thus should be used preferably to read NTP information. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_get_all_ntp_cfg_info + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ntp( const MBG_MSG_CTL *pmctl ) ; + + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_evt_log( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ucap( const MBG_MSG_CTL *pmctl ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ucap_net( const MBG_MSG_CTL *pmctl ) ; + /** + * @brief Check if a device supports the TLV API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref group_tlv_api + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_tlv_api( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports a firmware update via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to fw update function + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_fw_update( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports creating / sending a diagnostics file via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_diag_file( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports upports PTPv2 license infos + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_ptpv2_license( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports supports PTPv1 License Infos via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_ptpv1_license( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports supports NTP license infos via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_ntp_license( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports supportsTime Monitor License infos via TLV + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_supp_tlv_time_monitor_license( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the ::GPS_SAVE_CFG command + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::mbgextio_cmd_save_cfg + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_cmd_save_cfg( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the extended feature monitoring + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see xdevfeat_has_monitoring + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_monitoring( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the LED API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO ### + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_led_api( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the LNE API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO ### + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_lne_api( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the power control API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup mbgextio_chk_supp_fncs + * @see ::TODO ### + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_pwr_ctl_api( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device has MBG_XFEATURE_EXT_SYS_INFO + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_ext_sys_info( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device has MBG_XFEATURE_TRANSACTIONS + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_transactions( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device has MBG_XFEATURE_REBOOT + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_reboot( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device has MBG_XFEATURE_REQ_TTM + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + * @see mbgextio_get_time + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_req_ttm( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the up-to-date extended multi ref API + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_xmulti_ref( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Check if a device supports the extended binary protocl (XBP) feature + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup mbgextio_chk_supp_fncs + * @see @ref mbgextio_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_dev_has_xbp( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Generic reception of a binary message + * + * @note A certain message type to be waited for can be specified by + * passing one of the ::GPS_CMD_CODES. + * If the special cmd code ::GPS_WILDCARD is specified the function returns + * successfully after *any* type of binary message has been received. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, or ::GPS_WILDCARD + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_rcv_msg_unlocked + * @see ::mbgextio_xmt_msg //##++++ + * @see ::mbgextio_xmt_cmd + * @see ::mbgextio_req_data + * @see ::mbgextio_xmt_cmd_us + * @see ::mbgextio_req_data_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg_unlocked( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, void *buf, size_t buf_size ) ; + + /** * @brief Generic reception of a binary message * * @note A certain message type to be waited for can be specified by @@ -531,33 +1430,38 @@ extern "C" { * * //##++ TODO: callback function to handle asynchronous spontaneous messages * - * @param[in,out] pmctl Pointer to a valid message control structure - * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, or ::GPS_WILDCARD + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, or ::GPS_WILDCARD + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_xmt_msg //##++++ * @see ::mbgextio_xmt_cmd * @see ::mbgextio_req_data * @see ::mbgextio_xmt_cmd_us * @see ::mbgextio_req_data_idx */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_rcv_msg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, void *buf, size_t buf_size ) ; /** * @brief Set up and send a generic binary message * - * @note This function should preferably be used only as low level function + * This function should preferably be used only as low level function * called from within more specific functions used to send specific data. - * If this function is called directly with a buffer to be sent then the - * transmit mutex is acquired by this function. However, other (higher level) - * API functions which set up the transmit buffer directly have to acquire - * the transmit mutex by themselves before they set up the transmit buffer, - * and pass a NULL pointer to indicate the transmit buffer has already been - * set up. The correct number of bytes to send (n_bytes) has to be specified - * anyway, though. + * + * If this function is called directly with a buffer p to be sent then the + * device mutex is acquired by this function, and after this the specified + * buffer p is copied to the transmit buffer. + * + * However, other (higher level) API functions which set up the transmit + * buffer directly have to acquire the device mutex by themselves *before* + * they set up the transmit buffer, and then pass p as NULL pointer to + * indicate the transmit buffer has already been set up. The correct number + * of bytes to be sent (n_bytes) has to be specified anyway, though. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL @@ -572,14 +1476,20 @@ extern "C" { /** * @brief Transmit a command-only message without additional data. * + * If the caller has or'ed the cmd code with ::GPS_REQACK then this + * function expects an ACK or a NACK message to be replied by the device. + * + * Transmission is protected by a mutex which is acquired before + * and released after the binary message has been sent. + * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES, optionally or'ed with ::GPS_REQACK * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_xmt_msg - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_req_data * @see ::mbgextio_xmt_cmd_us * @see ::mbgextio_req_data_idx @@ -587,11 +1497,14 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_xmt_cmd( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) ; /** - * @brief Transmit a message without a single ushort (uint16_t) parameter + * @brief Transmit a message with a single ushort (uint16_t) parameter * - * The ushort parameter is often used to send an index value when requesting + * The uint16_t parameter us is often used to send an index value when requesting * a certain element of an array of same data structures. * + * Transmission is protected by a mutex which is acquired before + * and released after the binary message has been sent. + * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES @@ -600,7 +1513,7 @@ extern "C" { * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_xmt_msg - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_xmt_cmd * @see ::mbgextio_req_data * @see ::mbgextio_req_data_idx @@ -613,41 +1526,71 @@ extern "C" { * The ushort parameter is often used to send an index value when requesting * a specific element of an array of data structures. * - * @param[in,out] pmctl Pointer to a valid message control structure - * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_xmt_msg - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_xmt_cmd * @see ::mbgextio_xmt_cmd_us * @see ::mbgextio_req_data_idx */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_req_data( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_req_data( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, void *buf, size_t buf_size ) ; /** * @brief Read a specific element of an array of data structures * - * The type of data is implicitely associated with the cmd parameter. + * This function dos not lock/unlock the device mutex, so this has to be done by + * The type of data is implicitly associated with the cmd parameter. + * The type of data is implicitly associated with the cmd parameter. * Usually the number of supported array elements has to be determined * by some other means, e.g. from a field in the ::RECEIVER_INFO structure. * - * @param[in,out] pmctl Pointer to a valid message control structure - * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES - * @param[in] idx The index of the array element to read + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[in] idx The index of the array element to read + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_xmt_msg - * @see ::mbgextio_rcv_msg + * @see ::mbgextio_rcv_msg_unlocked * @see ::mbgextio_xmt_cmd * @see ::mbgextio_req_data * @see ::mbgextio_xmt_cmd_us */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_req_data_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t idx ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_req_data_idx_unlocked( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t idx, void *buf, size_t buf_size ) ; + + /** + * @brief Read a specific element of an array of data structures + * + * The type of data is implicitly associated with the cmd parameter. + * Usually the number of supported array elements has to be determined + * by some other means, e.g. from a field in the ::RECEIVER_INFO structure. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] cmd One of the command codes enumerated in ::GPS_CMD_CODES + * @param[in] idx The index of the array element to read + * @param[out] buf Pointer to a buffer to be filled with the requested data, or NULL + * @param[in] buf_size Size of the buffer specified by buf + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_xmt_msg + * @see ::mbgextio_rcv_msg_unlocked + * @see ::mbgextio_xmt_cmd + * @see ::mbgextio_req_data + * @see ::mbgextio_xmt_cmd_us + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_req_data_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GPS_CMD cmd, uint16_t idx, void *buf, size_t buf_size ) ; /** * @brief Read a receiver info structure @@ -672,6 +1615,91 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_get_receiver_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, RECEIVER_INFO *p ) ; /** + * @brief Read I/O port limits in ::MBG_IO_PORT_LIMITS format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent by the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_io_port_settings_idx + * @see ::mbgextio_get_io_port_info_idx + * @see ::mbgextio_get_io_port_type_info_idx + * @see ::mbgextio_get_io_port_status_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_io_port_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IO_PORT_LIMITS *p ) ; + + /** + * @brief Send I/O port settings in ::MBG_IO_PORT_SETTINGS format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of I/O port settings to be configured, 0..MBG_IO_PORT_LIMITS::num_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_io_port_limits + * @see ::mbgextio_get_io_port_info_idx + * @see ::mbgextio_get_io_port_type_info_idx + * @see ::mbgextio_get_io_port_status_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_io_port_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_IO_PORT_SETTINGS *p, uint8_t idx ) ; + + /** + * @brief Read I/O port info in ::MBG_IO_PORT_INFO_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be read from the device + * @param[in] idx Index of I/O port info to be read, 0..MBG_IO_PORT_LIMITS::num_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_io_port_limits + * @see ::mbgextio_set_io_port_settings_idx + * @see ::mbgextio_get_io_port_type_info_idx + * @see ::mbgextio_get_io_port_status_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_io_port_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IO_PORT_INFO_IDX *p, uint8_t idx ) ; + + /** + * @brief Read I/O port type info in ::MBG_IO_PORT_TYPE_INFO_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be read from the device + * @param[in] port_idx Index of I/O port to be read, 0..MBG_IO_PORT_LIMITS::num_ports - 1 + * @param[in] port_type_idx Index of I/O port type info to be read, 0..MBG_IO_PORT_INFO::num_types - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_io_port_limits + * @see ::mbgextio_set_io_port_settings_idx + * @see ::mbgextio_get_io_port_info_idx + * @see ::mbgextio_get_io_port_status_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_io_port_type_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IO_PORT_TYPE_INFO_IDX *p, uint8_t port_idx, uint8_t port_type_idx) ; + + /** + * @brief Read I/O port status in ::MBG_IO_PORT_STATUS_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be read from the device + * @param[in] idx Index of I/O port to be read, 0..MBG_IO_PORT_LIMITS::num_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_io_port_limits + * @see ::mbgextio_set_io_port_settings_idx + * @see ::mbgextio_get_io_port_info_idx + * @see ::mbgextio_get_io_port_type_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_io_port_status_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IO_PORT_STATUS_IDX *p, uint8_t idx) ; + + /** * @brief Setup a receiver info structure * * The ::RECEIVER_INFO should be read at first to identify the connected @@ -709,6 +1737,36 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_get_sw_rev( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, SW_REV *p ) ; /** + * @brief Read the status of ignore lock + * + * @note Only supported if ::GPS_HAS_IGNORE_LOCK + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @see mbgextio_set_ignore_lock + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ignore_lock( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IGNORE_LOCK *p ) ; + + /** + * @brief Send the ignore lock configuration + * + * @note Only supported if ::GPS_HAS_IGNORE_LOCK + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ignore_lock + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ignore_lock( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const IGNORE_LOCK *p ) ; + + /** * @brief Read the status of buffered variables * * @note Only supported if ::GPS_MODEL_HAS_BVAR_STAT @@ -724,16 +1782,18 @@ extern "C" { /** * @brief Read the current time as ::TTM strucure * - * @note This function is only supported by GPS receivers. + * @note This function is only supported if the device has ::MBG_XFEATURE_REQ_TTM * - * The returned time is not very accurate since the response time - * transmission delay can't be determmined. + * The returned time is not very accurate since the request can be sent at any time and + * the response is sent immediately and not after a second change. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data * * @return One of the @ref MBG_RETURN_CODES + * + * @see mbgextio_dev_has_req_ttm */ _NO_MBG_API_ATTR int _MBG_API mbgextio_get_time( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TTM *p ) ; @@ -929,6 +1989,62 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ucap( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, TTM *p ) ; /** + * @brief Read the user capture network global info in ::MBG_UCAP_NET_GLB_INFO format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ucap_net_glb_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_UCAP_NET_GLB_INFO *p ) ; + + /** + * @brief Send the user capture network global configuration in ::MBG_UCAP_NET_GLB_SETTINGS format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ucap_net_glb_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_UCAP_NET_GLB_SETTINGS *p ) ; + + /** + * @brief Read the user capture network receiver info with the given index + * in ::MBG_UCAP_NET_RECV_INFO_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received dat + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_UCAP_NET_GLB_INFO::settings::num_recvs + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ucap_net_recv_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_UCAP_NET_RECV_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Send the user capture network receiver configuration with the given index + * in ::MBG_UCAP_NET_RECV_SETTINGS_IDX format + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be sent, 0..::MBG_UCAP_NET_GLB_INFO::settings::num_recvs + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_ucap_net + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ucap_net_recv_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_UCAP_NET_RECV_SETTINGS_IDX *p, uint16_t idx ) ; + + /** * @brief Read the enable flags controlling when output signals are enabled * * @note Some devices may not support ::ENABLE_FLAGS @@ -969,12 +2085,12 @@ extern "C" { * * @return One of the @ref MBG_RETURN_CODES */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_get_stat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STAT_INFO *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_gps_stat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STAT_INFO *p ) ; /** * @brief Read the configured length of the antenna cable * - * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LENGTH + * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LEN * * @note Some older devices may not reply to this request unless * the application has registered itself as terminal application @@ -993,7 +2109,7 @@ extern "C" { /** * @brief Send the GPS antenna cable length configuration * - * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LENGTH + * This is only supported by GPS/GNSS receivers, check ::GPS_MODEL_HAS_ANT_CABLE_LEN * @note Different devices may accept different maximum values, so the * written value should be re-read using ::mbgextio_get_ant_cable_len @@ -1070,6 +2186,27 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_set_irig_rx_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const IRIG_SETTINGS *p ) ; /** + * @brief Read raw IRIG data + * + * The ::MBG_RAW_IRIG_DATA structure can be read for debugging purposes, + * to decode application defined bits in the control field (CF) segment + * of the incoming time code, etc. Usually the data set is only updated + * once per second, even if the code format provides many data frames + * per second. + * + * @note Call ::mbgextio_dev_has_raw_irig_data to check if this is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @see ::mbgextio_dev_has_raw_irig_data + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_raw_irig_data( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_RAW_IRIG_DATA *p ) ; + + /** * @brief Read current ref offset to %UTC configuration * * @note This is only supported if ::GPS_HAS_REF_OFFS is set in ::RECEIVER_INFO::features, @@ -1170,13 +2307,12 @@ extern "C" { * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] stii An array which can hold at least ::RECEIVER_INFO::n_str_type entries - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_get_str_type_info_idx */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_str_type_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[], const RECEIVER_INFO *p_ri ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_str_type_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[] ) ; /** * @brief Read current settings and capabilities of a specific serial port @@ -1203,14 +2339,13 @@ extern "C" { * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] pii An array which can hold at least ::RECEIVER_INFO::n_com_ports entries - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_get_port_info_idx * @see ::mbgextio_set_port_settings_idx */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_port_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PORT_INFO_IDX pii[], const RECEIVER_INFO *p_ri ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_port_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, PORT_INFO_IDX pii[] ) ; /** * @brief Send configuration settings for a specific serial port @@ -1254,14 +2389,13 @@ extern "C" { * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] pii An array which can hold at least ::RECEIVER_INFO::n_prg_out entries - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure * * @return One of the @ref MBG_RETURN_CODES * * @see ::mbgextio_get_pout_info_idx * @see ::mbgextio_set_pout_settings_idx */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_pout_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, POUT_INFO_IDX *pii, const RECEIVER_INFO *p_ri ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_pout_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, POUT_INFO_IDX *pii ) ; /** * @brief Send configuration settings for a specific programmable pulse output @@ -1281,6 +2415,22 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_set_pout_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const POUT_SETTINGS *p, uint16_t idx ) ; /** + * @brief Send configuration settings for a specific GPIO + * + * @note This is only supported if ::GPS_HAS_GPIO is set in ::RECEIVER_INFO::features + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the pulse output to be configured, 0..MBG_GPIO_CFG_LIMITS::num_io - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_gpio_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_gpio_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_GPIO_SETTINGS *p, uint16_t idx ) ; + + /** * @brief Clear the user capture event buffer on-board the device * * @param[in,out] pmctl Pointer to a valid message control structure @@ -1400,7 +2550,7 @@ extern "C" { /** * @brief Read the current IMS state and supported IMS features * - * @note This is only supported if ::GPS_HAS_IMS is set in ::RECEIVER_INFO::features + * @note This is only supported if ::mbgextio_dev_has_ims returns MBG_SUCCESS * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL @@ -1460,6 +2610,17 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_get_holdover_interval_counter( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMR_HOLDOVER_INTV *p ) ; /** + * @brief Read the multi ref info from a device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmulti_ref_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMULTI_REF_INFO_IDX *p ) ; + + /** * @brief Read the local time conversion configuration in ::TZCODE format * * @note Some devices may not support ::TZCODE configuration @@ -1502,7 +2663,7 @@ extern "C" { * * @see //##+++++++++++++++++++++ */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_tx_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, HAVEQUICK_SETTINGS *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_tx_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const HAVEQUICK_SETTINGS *p ) ; /** * @brief Send new configuration settings for the device's HAVEQUICK input @@ -1517,7 +2678,7 @@ extern "C" { * * @see //##+++++++++++++++++++++ */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_rx_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, HAVEQUICK_SETTINGS *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_hq_rx_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const HAVEQUICK_SETTINGS *p ) ; /** * @brief Read the distance from transmitter ::TR_DISTANCE format @@ -1580,83 +2741,248 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_set_gnss_mode_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_GNSS_MODE_SETTINGS *p ) ; /** - * @brief Read an array of all supported string types //##+++++++++++++++++++++++++++++++++++++++++++++++ TODO + * @brief ::TODO * + * ### TODO this is obsolete + * Retrieve a single entry from an array of supported string types. * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL - * @param[out] stii An array which can hold at least ::RECEIVER_INFO::n_str_type entries - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure + * @param[out] p Pointer to the data structure to return the received data * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_get_str_type_info_idx + * @see ::TODO */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gnss_sat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, STR_TYPE_INFO_IDX stii[], const RECEIVER_INFO *p_ri ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_gnss_sat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GNSS_SAT_INFO *p ) ; /** - * @brief Fill up a GNSS info structure //##+++++++++++++++++++++++++++++++++++++++++++++++ TODO + * @brief ::TODO + * + * ### TODO + * Retrieve a single entry from an array of supported string types. + * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type. * * @param[in,out] pmctl Pointer to a valid message control structure - * @param[out] p_si Pointer to a ::STAT_INFO the data structure to return the received data - * @param[out] p_gmi Index of the NTP peer state to be configured, 0..::NTP_CLNT_MODE_INFO::n_supp_peers - 1 - * @param[out] p_gsii Blah ... //##++++++++++ TODO - * @param[in] p_ri Pointer to a valid ::RECEIVER_INFO structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_str_type - 1 * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_get_ntp_sys_state - * @see ::mbgextio_get_ntp_peer_settings_idx - * @see ::mbgextio_get_ntp_clnt_mode_info + * @see ::TODO */ - int mbgextio_chk_get_gnss_info( MBG_MSG_CTL *pmctl, STAT_INFO *p_si, MBG_GNSS_MODE_INFO *p_gmi, GNSS_SAT_INFO_IDX *p_gsii, const RECEIVER_INFO *p_ri ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_gnss_sat_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GNSS_SAT_INFO_IDX *p, uint16_t idx ) ; /** - * @brief Read the supported XMR features in ::XMULTI_REF_INFO_IDX format + * @brief ::TODO Read an array of all supported string types + * + * The number of supported string types is specified in ::RECEIVER_INFO::n_str_type. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] gsii ::TODO + * @param[in] p_mi ::TODO + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::TODO + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_all_gnss_sat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GNSS_SAT_INFO_IDX gsii[], const MBG_GNSS_MODE_INFO *p_mi ) ; + + /** + * @brief ::TODO + * + * ### TODO + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::RECEIVER_INFO::n_str_type - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see @ref group_gnss_sv_status ::TODO + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_gnss_sv_status_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, GNSS_SV_STATUS_IDX *p, uint16_t idx ) ; + + /** + * @brief Read ::XMULTI_REF_INSTANCES + * + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features AND + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_instances( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMULTI_REF_INSTANCES *p ) ; + + /** + * @brief Read ::XMR_EXT_SRC_INFO_IDX + * + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features AND + * ::XMRIF_MSK_EXT_SRC_INFO_SUPP is set in ::XMULTI_REF_INSTANCES::flags. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_holdover_status + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_ext_src_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMR_EXT_SRC_INFO_IDX *p, uint16_t idx) ; + + /** + * @brief Read ::XMR_HOLDOVER_STATUS + * + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features AND + * ::XMRIF_MSK_HOLDOVER_STATUS_SUPP is set in ::XMULTI_REF_INSTANCES::flags. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_holdover_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMR_HOLDOVER_STATUS *p ) ; + + /** + * @brief Read ::XMULTI_REF_INFO_IDX for a specific XMR source + * + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMULTI_REF_INFO_IDX *p, uint16_t idx) ; + + /** + * @brief Read ::XMULTI_REF_STATUS_IDX for a specific XMR source * * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 * * @return One of the @ref MBG_RETURN_CODES * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMULTI_REF_INFO_IDX *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_status_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMULTI_REF_STATUS_IDX *p, uint16_t idx) ; /** - * @brief Read the supported XMR features ::XMULTI_REF_STATUS_IDX format + * @brief Read ::XMR_STATS_IDX for a specific XMR source * - * @note Only for devices which supports Multi references - * @note GPS_HAS_XMULTI_REF feature must set + * Only if ::mbgextio_dev_xmr_has_ext_source_stats returns ::MBG_SUCCESS for the specific index * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MULTI_REF_TYPES-1 * * @return One of the @ref MBG_RETURN_CODES * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_ext_source_stats_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMR_STATS_IDX *p, uint16_t idx) ; + + /** + * @brief Read ::XMR_METRICS_IDX for a specific XMR source + * + * Only if ::mbgextio_dev_xmr_has_ext_source_stats returns ::MBG_SUCCESS for the specific index + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MULTI_REF_TYPES-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_set_xmr_settings_idx + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_status_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMULTI_REF_STATUS_IDX *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_xmr_ext_source_metrics_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, XMR_METRICS_IDX *p, uint16_t idx) ; /** - * @brief Save the supported XMR features ::XMULTI_REF_INFO_IDX format + * @brief Set ::XMULTI_REF_SETTINGS for a specific XMR source * - * @note Some devices may not support Multi Refernce Sources + * Only if ::GPS_HAS_XMULTI_REF is set in ::RECEIVER_INFO::features. * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be retrieved, 0..0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 * * @return One of the @ref MBG_RETURN_CODES * - * @see //##+++++++++++++ + * @see ::mbgextio_get_xmr_instances + * @see ::mbgextio_get_xmr_ext_src_info_idx + * @see ::mbgextio_get_xmr_holdover_status + * @see ::mbgextio_get_xmr_info_idx + * @see ::mbgextio_get_xmr_status_idx + * @see ::mbgextio_get_xmr_ext_source_stats_idx + * @see ::mbgextio_get_xmr_ext_source_metrics_idx */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_set_xmr_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const XMULTI_REF_SETTINGS_IDX *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_xmr_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const XMULTI_REF_SETTINGS *p, uint16_t idx) ; /** * @brief Read the lan interface configuration ::LAN_IF_INFO format @@ -1795,6 +3121,615 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_cfg_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const PTP_CFG_SETTINGS *p ) ; /** + * @brief Send PTP unicast master configuration settings for a PTP unicast slave mode device. + * + * The number of supported PTP Masters is specified in ::PTP_UC_MASTER_CFG_LIMITS::n_supp_master. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the PTP unicast grandmaster to be configured, 0 ... PTP_UC_MASTER_CFG_LIMITS::n_supp_master - 1 . + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_ptp_cfg_settings + * @see ::mbgextio_get_all_ptp_uc_master_info + * @see ::mbgextio_get_ptp_uc_master_cfg_limits + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_state + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_uc_master_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const PTP_UC_MASTER_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read the PTPv1 default dataset in ::MBG_PTP_V1_DEFAULT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_default_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_default_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V1_DEFAULT_DATASET *p ) ; + + /** + * @brief Send PTPv1 default dataset to a device in ::MBG_PTP_V1_DEFAULT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_default_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_default_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V1_DEFAULT_DATASET *p ) ; + + /** + * @brief Read the PTPv1 current dataset in ::MBG_PTP_V1_CURRENT_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_current_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_current_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V1_CURRENT_DATASET *p ) ; + + /** + * @brief Send PTPv1 current dataset to a device in ::MBG_PTP_V1_CURRENT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_current_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_current_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V1_CURRENT_DATASET *p ) ; + + /** + * @brief Read the PTPv1 parent dataset in ::MBG_PTP_V1_PARENT_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_parent_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_parent_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V1_PARENT_DATASET *p ) ; + + /** + * @brief Send PTPv1 parent dataset to a device in ::MBG_PTP_V1_PARENT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_parent_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_parent_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V1_PARENT_DATASET *p ) ; + + /** + * @brief Read the PTPv1 time properties dataset in ::MBG_PTP_V1_TIME_PROPERTIES_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_time_properties_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_time_properties_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V1_TIME_PROPERTIES_DATASET *p ) ; + + /** + * @brief Send PTPv1 time properties dataset to a device in ::MBG_PTP_V1_TIME_PROPERTIES_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_time_properties_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_time_properties_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V1_TIME_PROPERTIES_DATASET *p ) ; + + /** + * @brief Read the PTPv1 port dataset with the appropriate index in ::MBG_PTP_V1_PORT_DATASET_IDX format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the port dataset be received, 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v1_port_dataset_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v1_port_dataset_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V1_PORT_DATASET_IDX *p, uint16_t idx ) ; + + /** + * @brief Send PTPv1 port dataset with the appropriate index to a device in ::MBG_PTP_V1_PORT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V1_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the port dataset to be written, 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v1_port_dataset_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v1_port_dataset_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V1_PORT_DATASET *p, uint16_t idx ) ; + + /** + * @brief Read the PTPv2 default dataset in ::MBG_PTP_V2_DEFAULT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_default_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_default_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V2_DEFAULT_DATASET *p ) ; + + /** + * @brief Send PTPv2 default dataset to a device in ::MBG_PTP_V2_DEFAULT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_default_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_default_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V2_DEFAULT_DATASET *p ) ; + + /** + * @brief Read the PTPv2 current dataset in ::MBG_PTP_V2_CURRENT_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_current_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_current_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V2_CURRENT_DATASET *p ) ; + + /** + * @brief Send PTPv2 current dataset to a device in ::MBG_PTP_V2_CURRENT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_current_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_current_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V2_CURRENT_DATASET *p ) ; + + /** + * @brief Read the PTPv2 parent dataset in ::MBG_PTP_V2_PARENT_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_parent_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_parent_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V2_PARENT_DATASET *p ) ; + + /** + * @brief Send PTPv2 parent dataset to a device in ::MBG_PTP_V2_PARENT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_parent_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_parent_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V2_PARENT_DATASET *p ) ; + + /** + * @brief Read the PTPv2 time properties dataset in ::MBG_PTP_V2_TIME_PROPERTIES_DATASET format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_time_properties_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_time_properties_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V2_TIME_PROPERTIES_DATASET *p ) ; + + /** + * @brief Send PTPv2 time properties dataset to a device in ::MBG_PTP_V2_TIME_PROPERTIES_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_time_properties_dataset + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_time_properties_dataset( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V2_TIME_PROPERTIES_DATASET *p ) ; + + /** + * @brief Read the PTPv2 port dataset with the appropriate index in ::MBG_PTP_V2_PORT_DATASET_IDX format + * + * @note only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the port dataset be received, 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_set_ptp_v2_port_dataset_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ptp_v2_port_dataset_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PTP_V2_PORT_DATASET_IDX *p, uint16_t idx ) ; + + /** + * @brief Send PTPv2 port dataset with the appropriate index to a device in ::MBG_PTP_V2_PORT_DATASET format + * + * @note This is only supported if ::PTP_CFG_MSK_HAS_V2_COMMON_DATASETS is set in ::PTP_CFG_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the port dataset be written, 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ptp_cfg_info + * @see ::mbgextio_get_ptp_v2_port_dataset_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ptp_v2_port_dataset_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PTP_V2_PORT_DATASET *p, uint16_t idx ) ; + + /** + * @brief Read the monitoring limits in ::MBG_MONITORING_LIMITS format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_monitoring_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_MONITORING_LIMITS *p ) ; + + /** + * @brief Read the SNMP global info in ::MBG_SNMP_GLB_INFO format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_set_snmp_glb_settings + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_glb_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_SNMP_GLB_INFO *p ) ; + + /** + * @brief Send the SNMP global settings in ::MBG_SNMP_GLB_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_glb_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_SNMP_GLB_SETTINGS *p ) ; + + /** + * @brief Read SNMP v1 or v2 info in ::MBG_SNMP_V12_INFO_IDX format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the SNMP info to be received, 0 ... MBG_SNMP_GLB_SETTINGS::num_v12_settings - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_set_snmp_v12_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_v12_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_SNMP_V12_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Write SNMP v1 or v2 settings in ::MBG_SNMP_V12_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the SNMP settings to be written, 0 ... MBG_SNMP_GLB_SETTINGS::num_v12_settings - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v12_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_v12_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_SNMP_V12_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read SNMP v1 or v2 trap info in ::MBG_SNMP_V12_TRAP_INFO_IDX format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the SNMP trap info to be received, 0 ... MBG_SNMP_GLB_SETTINGS::num_v12_trap_receivers - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_set_snmp_v12_trap_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_v12_trap_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_SNMP_V12_TRAP_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Write SNMP v1 or v2 trap settings in ::MBG_SNMP_V12_TRAP_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the SNMP settings to be written, 0 ... MBG_SNMP_GLB_SETTINGS::num_v12_trap_receivers - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v12_trap_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_v12_trap_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_SNMP_V12_TRAP_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read SNMP v3 info in ::MBG_SNMP_V3_INFO_IDX format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the SNMP info to be received, 0 ... MBG_SNMP_GLB_SETTINGS::num_v3_settings - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_set_snmp_v3_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_v3_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_SNMP_V3_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Write SNMP v3 settings in ::MBG_SNMP_V3_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the SNMP settings to be written, 0 ... MBG_SNMP_GLB_SETTINGS::num_v3_settings - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v3_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_v3_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_SNMP_V3_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read SNMP v3 trap info in ::MBG_SNMP_V3_TRAP_INFO_IDX format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the SNMP trap info to be received, 0 ... MBG_SNMP_GLB_SETTINGS::num_v3_trap_receivers - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_set_snmp_v3_trap_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_snmp_v3_trap_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_SNMP_V3_TRAP_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Write SNMP v3 trap settings in ::MBG_SNMP_V3_TRAP_SETTINGS format + * + * @note ::MBG_MONITORING_TYPE_MSK_SNMP must be set in MBG_MONITORING_LIMITS::supp_types + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the SNMP trap settings to be written, 0 ... MBG_SNMP_GLB_SETTINGS::num_v3_trap_receivers - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_snmp_glb_info + * @see ::mbgextio_get_snmp_v3_trap_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_snmp_v3_trap_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_SNMP_V3_TRAP_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read monitoring event info in ::MBG_EVENT_INFO_IDX format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * idx shall be the type of the appropriate event, it should be checked + * if this event is supported in ::MBG_MONITORING_LIMITS::supp_events + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the event info to be received, type of the appropriate event + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_monitoring_limits + * @see ::mbgextio_set_event_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_event_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_EVENT_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Write monitoring event settings in ::MBG_EVENT_SETTINGS format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * idx shall be the type of the appropriate event, it should be checked + * if this event is supported in ::MBG_MONITORING_LIMITS::supp_events + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the event settings to be written, type of the appropriate event + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_monitoring_limits + * @see ::mbgextio_get_event_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_event_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_EVENT_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read the monitoring status in ::MBG_MONITORING_STATUS format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_monitoring_status( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_MONITORING_STATUS *p ) ; + + /** + * @brief Read monitoring event status in ::MBG_EVENT_STATUS_IDX format + * + * @note extended feature ::MBG_XFEATURE_MONITORING must be set + * idx shall be the type of the appropriate event, it should be checked + * if this event is supported in ::MBG_MONITORING_LIMITS::supp_events + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the event info to be received, type of the appropriate event + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_monitoring + * @see ::mbgextio_get_monitoring_limits + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_event_status_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_EVENT_STATUS_IDX *p, uint16_t idx ) ; + + /** * @brief Read the ntp global information ::NTP_GLB_INFO format * * @note ntp feature must set @@ -1827,6 +3762,140 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_glb_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_GLB_SETTINGS *p ) ; /** + * @brief Read the NTP symmetric key limits in ::NTP_SYMM_KEY_LIMITS format + * + * @note ::NTP_MSK_SYMM_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_symm_key_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_SYMM_KEY_LIMITS *p ) ; + + /** + * @brief Read the NTP symmetric key info with the given index in ::NTP_SYMM_KEY_INFO_IDX format + * + * @note ::NTP_MSK_SYMM_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the NTP symmetric key info to be queried, 0 ... ::NTP_GLB_SETTINGS::num_symm_keys - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_symm_key_limits + * @see ::mbgextio_set_ntp_symm_key_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_symm_key_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_SYMM_KEY_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Send NTP symmetric key settings with the given index in ::NTP_SYMM_KEY_SETTINGS format + * + * @note ::NTP_MSK_SYMM_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the NTP symmetric key to be configured, 0 ... ::NTP_GLB_SETTINGS::num_symm_keys - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_symm_key_limits + * @see ::mbgextio_get_ntp_symm_key_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_symm_key_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_SYMM_KEY_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read the NTP trusted key info with the given index in ::NTP_TRUSTED_KEY_INFO_IDX format + * + * @note ::NTP_MSK_TRUSTED_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the NTP trusted key info to be queried, 0 ... ::NTP_GLB_SETTINGS::num_trusted_keys - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_set_ntp_trusted_key_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_trusted_key_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_TRUSTED_KEY_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Send NTP trusted key settings with the given index in ::NTP_TRUSTED_KEY_SETTINGS format + * + * @note ::NTP_MSK_TRUSTED_KEYS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the NTP trusted key to be configured, 0 ... ::NTP_GLB_SETTINGS::num_trusted_keys - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_trusted_key_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_trusted_key_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_TRUSTED_KEY_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read the NTP misc limits in ::NTP_MISC_LIMITS format + * + * @note ::NTP_MSK_MISCELLANEOUS must be set in ::NTP_GLB_INFO::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_misc_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_MISC_LIMITS *p ) ; + + /** + * @brief Read the NTP orphan mode information in ::NTP_MISC_ORPHAN_MODE_INFO format + * + * @note ::NTP_MISC_MSK_ORPHAN_MODE must be set in ::NTP_MISC_LIMITS::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_misc_limits + * @see ::mbgextio_set_ntp_misc_orphan_mode_settings + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_misc_orphan_mode_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_MISC_ORPHAN_MODE_INFO *p ) ; + + /** + * @brief Send the NTP orphan mode configuration in ::NTP_MISC_ORPHAN_MODE_SETTINGS format + * + * @note ::NTP_MISC_MSK_ORPHAN_MODE must be set in ::NTP_MISC_LIMITS::supp_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_misc_limits + * @see ::mbgextio_get_ntp_misc_orphan_mode_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_misc_orphan_mode_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_MISC_ORPHAN_MODE_SETTINGS *p ) ; + + /** * @brief Read the ntp global information ::NTP_CLNT_MODE_INFO format * * @note ntp feature must set @@ -1898,9 +3967,81 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_peer_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_PEER_SETTINGS *p, uint16_t idx ) ; /** + * @brief Read the ntp server mode information in ::NTP_SRV_MODE_INFO format + * + * @note NTP feature ::GPS_FEAT_NTP must be set + * @note NTP roles ::NTP_ROLE_SERVER or ::NTP_ROLE_CLIENT_SERVER must be set in ::NTP_GLB_INFO::supp_ntp_roles + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_set_ntp_srv_mode_cfg + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_srv_mode_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_SRV_MODE_INFO *p ) ; + + /** + * @brief Send the NTP server mode configuration + * + * @note NTP feature ::GPS_FEAT_NTP must be set + * @note NTP roles ::NTP_ROLE_SERVER or ::NTP_ROLE_CLIENT_SERVER must be set in ::NTP_GLB_INFO::supp_ntp_roles + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_srv_mode_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_srv_mode_cfg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_SRV_MODE_SETTINGS *p ) ; + + /** + * @brief Read the NTP refclock config info with the given index in ::NTP_REFCLK_CFG_INFO_IDX format + * + * @note NTP feature ::GPS_FEAT_NTP must be set + * @note NTP roles ::NTP_ROLE_SERVER or ::NTP_ROLE_CLIENT_SERVER must be set in ::NTP_GLB_INFO::supp_ntp_roles + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the NTP refclock config to be queried, 0 ... ::NTP_SRV_MODE_SETTINGS::num_refclks - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_srv_mode_info + * @see ::mbgextio_set_ntp_refclk_cfg_settings_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ntp_refclk_cfg_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, NTP_REFCLK_CFG_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Send NTP refclk config settings with the given index in ::NTP_REFCLK_CFG_SETTINGS format + * + * @note NTP feature ::GPS_FEAT_NTP must be set + * @note NTP roles ::NTP_ROLE_SERVER or ::NTP_ROLE_CLIENT_SERVER must be set in ::NTP_GLB_INFO::supp_ntp_roles + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the NTP refclock config to be set, 0 ... ::NTP_SRV_MODE_SETTINGS::num_refclks - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_ntp_glb_info + * @see ::mbgextio_get_ntp_srv_mode_info + * @see ::mbgextio_get_ntp_refclk_cfg_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ntp_refclk_cfg_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NTP_REFCLK_CFG_SETTINGS *p, uint16_t idx ) ; + + /** * @brief Read the current system state of ntp device ::NTP_SYS_STATE format * - * @note ntp feature must set + * @note NTP feature must set * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL @@ -1960,14 +4101,14 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_glb_cfg_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_NET_GLB_CFG_SETTINGS *p ) ; /** - * @brief Read the network dns server ::MBG_IP_ADDR_IDX format + * @brief Read a network DNS server entry in ::MBG_IP_ADDR_IDX format * - * The number of DNS server provided by the device is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srvr + * The number of DNS server provided by the device is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data - * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1 + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -1980,12 +4121,12 @@ extern "C" { * @brief Send the network DNS server address in ::MBG_IP_ADDR format * * The number of DNS search domains supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to be sent to the device - * @param[in] idx Index of the serial port to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1 + * @param[in] idx Index of the DNS server port to be configured, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -1998,12 +4139,12 @@ extern "C" { * @brief Read the network DNS search domain in ::MBG_NET_NAME_IDX format * * The number of DNS search domains supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data - * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1 + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -2016,12 +4157,12 @@ extern "C" { * @brief Send the network DNS search domain in ::MBG_NET_NAME format * * The number of DNS search domains supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to be sent to the device - * @param[in] idx Index of the serial port to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1 + * @param[in] idx Index of the DNS search domain entry to be configured, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -2034,12 +4175,12 @@ extern "C" { * @brief Read the current network DNS server in ::MBG_IP_ADDR_IDX format * * The number of DNS servers supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srvr + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data - * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srvr - 1 + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srvr - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -2052,12 +4193,12 @@ extern "C" { * @brief Read the current network DNS search domain in ::MBG_NET_NAME_IDX format * * The number of DNS search domains supported by the device - * is specified in ::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom + * is specified in ::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom * * @param[in,out] pmctl Pointer to a valid message control structure * @param[in] p_addr Pointer to an XBP address specifier, or NULL * @param[out] p Pointer to the data structure to return the received data - * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::num_dns_srch_dom - 1 + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::n_supp_dns_srch_dom - 1 * * @return One of the @ref MBG_RETURN_CODES * @@ -2067,6 +4208,183 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_dns_srch_dom_stat_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_NAME_IDX *p, uint16_t idx ) ; /** + * @brief Read ::MBG_NET_INTF_LINK_INFO_IDX from the config with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_LINK_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_link. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_link - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_cfg_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_intf_link_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_INTF_LINK_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Send the network link configuration in ::MBG_NET_INTF_LINK_SETTINGS format + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the link to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_intf_link - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_net_intf_link_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_intf_link_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_NET_INTF_LINK_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read ::MBG_NET_INTF_ADDR_INFO_IDX from the config with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_ADDR_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_addr. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::n_supp_intf_addr - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_cfg_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_intf_addr_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_INTF_ADDR_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Send the network addr configuration in ::MBG_NET_INTF_ADDR_SETTINGS format + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the link to be configured, 0..::MBG_NET_GLB_CFG_INFO::n_supp_intf_addr - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_net_intf_addr_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_intf_addr_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_NET_INTF_ADDR_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read ::MBG_NET_INTF_ROUTE_INFO_IDX from the config with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_ROUTE_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_route. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_route - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_cfg_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_intf_route_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_INTF_ROUTE_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Send the network addr configuration in ::MBG_NET_INTF_ROUTE_SETTINGS format + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the link to be configured, 0..::MBG_NET_GLB_CFG_INFO::num_intf_route - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_net_intf_route_info_idx + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_net_intf_route_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_NET_INTF_ROUTE_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Read the network global status information ::MBG_NET_GLB_CFG_INFO format + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_set_net_glb_cfg_settings + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_glb_cfg_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_GLB_CFG_INFO *p ) ; + + /** + * @brief Read ::MBG_NET_INTF_LINK_INFO_IDX from the status with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_LINK_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_link. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_link - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_status_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_intf_link_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_INTF_LINK_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Read ::MBG_NET_INTF_ADDR_INFO_IDX from the status with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_ADDR_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_addr. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_addr - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_status_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_intf_addr_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_INTF_ADDR_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Read ::MBG_NET_INTF_ROUTE_INFO_IDX from the status with the given index + * + * @note GPS_HAS_NET_CFG must be set and MBG_NET_GLB_SUPP_STAGE_2_MASK must be set in ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * The number of ::MBG_NET_INTF_ROUTE_INFO_IDX provided by the device is specified in + * ::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_route. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_NET_GLB_CFG_INFO::glb_settings::num_intf_route - 1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_get_all_net_status_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_net_stat_intf_route_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_NET_INTF_ROUTE_INFO_IDX *p, uint16_t idx ) ; + + /** * @brief Read the ::XBP_LIMITS to check which XBP features are supported * * @note Only supported if ::GPS_HAS_XBP is set in ::RECEIVER_INFO::features @@ -2122,6 +4440,49 @@ extern "C" { _NO_MBG_API_ATTR int _MBG_API mbgextio_setup_xbp_node_list( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) ; /** + * @brief Read configuration and health data of all satellites from a device + * + * @note Only supported by GPS receivers + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_cfgh( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, CFGH *p ) ; + + /** + * @brief Read the GPS almanach for the specified SV from a device + * + * @note Only supported by GPS receivers + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] svno SV number, for which the ::SV_ALM structure shall be requested + * + * @return One of the @ref MBG_RETURN_CODES + * + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_sv_alm( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, SV_ALM *p, SVNO svno ) ; + + /** + * @brief Read the ionospheric correction parameters from a device + * + * @note Only supported by GPS receivers + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the ::IONO structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_iono( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, IONO *p ) ; + + /** * @brief Read a ::UTC parameter structure from a device. * * The ::UTC parameter structure contains the current UTC/GPS time offset @@ -2135,9 +4496,9 @@ extern "C" { * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_set_utc_param + * @see ::mbgextio_set_utc_parm */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_get_utc_param( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, UTC *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_utc_parm( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, UTC *p ) ; /** * @brief Write a ::UTC parameter structure to a device. @@ -2153,10 +4514,370 @@ extern "C" { * * @return One of the @ref MBG_RETURN_CODES * - * @see ::mbgextio_get_utc_param + * @see ::mbgextio_get_utc_parm + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_utc_parm( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, const UTC *p ) ; + + /** + * @brief Read SCU_STAT_INFO from the device + * + * @note This is only supported if ::GPS_MODEL_HAS_SCU_STAT is set in + * the builtin features of the device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_scu_stat + * @see ::mbgextio_set_scu_stat_settings + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_scu_stat_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, SCU_STAT_INFO *p ) ; + + /** + * @brief Send SCU_STAT_SETTINGS to the device + * + * @note This is only supported if ::GPS_MODEL_HAS_SCU_STAT is set in + * the builtin features of the device + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_scu_stat + * @see ::mbgextio_get_scu_stat_info + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_scu_stat_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const SCU_STAT_SETTINGS *p ) ; + + _NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_get_inst_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_TIME_MON_INST_INFO *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_send_inst_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_TIME_MON_INST_INFO *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_send_target_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_TIME_MON_TARGET_SETTINGS *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_get_target_status_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_TIME_MON_TARGET_STATUS_IDX *p, uint16_t idx ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_time_mon_get_target_ext_data_set_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_TIME_MON_TARGET_EXT_DATA_SET_IDX *p, uint16_t idx ) ; + /** +* @brief Read a ::MBG_GPIO_FREQ parameter structure from a device. +* +* The ::MBG_GPIO_FREQ parameter structure contains the current frequency +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* +* @return One of the @ref MBG_RETURN_CODES +*/ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_fdm_freq( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_GPIO_FREQ *p ) ; + + /** +* @brief Read a ::MBG_IMS_FDM_INFO parameter structure from a device. +* +* The ::MBG_IMS_FDM_INFO parameter structure contains the ::MBG_IMS_FDM_SETTINGS, the supported nominal frequencies and flags +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* +* @return One of the @ref MBG_RETURN_CODES +*/ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_INFO *p ) ; + + /** +* @brief Read a ::MBG_IMS_FDM_LIMITS parameter structure from a device. +* +* The ::MBG_IMS_FDM_LIMITS parameter structure contains the limits of the configurable parameters and number of outpus +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* +* @return One of the @ref MBG_RETURN_CODES +*/ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_LIMITS *p ) ; + + /** +* @brief Read a ::MBG_IMS_FDM_OUTPUT_INFO_IDX parameter structure from a device. +* +* The ::MBG_IMS_FDM_OUTPUT_INFO parameter structure contains the ::MBG_IMS_FDM_OUTPUT_SETTINGS, the supported modes and specific DAC limits +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* @param[in] idx Index of the array element to be retrieved, 0..::MBG_IMS_FDM_LIMITS::n_outputs-1 +* +* @return One of the @ref MBG_RETURN_CODES +*/ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_output_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_OUTPUT_INFO_IDX *p, uint16_t idx ) ; + + /** +* @brief Read a ::MBG_IMS_FDM_OUTPUT_STATE_IDX parameter structure from a device. +* +* The ::MBG_IMS_FDM_OUTPUT_STATE parameter structure contains the current DAC val and specs and the configured mode +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* @param[in] idx Index of the array element to be retrieved, 0..::MBG_IMS_FDM_LIMITS::n_outputs-1 +* +* @return One of the @ref MBG_RETURN_CODES +*/ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_output_state_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_OUTPUT_STATE_IDX *p, uint16_t idx ) ; + + /** +* @brief Read a ::MBG_IMS_FDM_STATE parameter structure from a device. +* +* The ::MBG_IMS_FDM_STATE parameter structure contains the current frequency, the reference, powerline and sync time, the configured nominal frequency and flags +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[out] p Pointer to the data structure to return the received data +* +* @return One of the @ref MBG_RETURN_CODES +*/ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ims_fdm_state( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_IMS_FDM_STATE *p ) ; + + /** +* @brief Write a ::MBG_IMS_FDM_SETTINGS parameter structure to a device. +* +* The ::MBG_IMS_FDM_SETTINGS parameter structure contains the limits for time and frequency deviation and the nominal frequency +* +* @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags +* +* @param[in,out] pmctl Pointer to a valid message control structure +* @param[in] p_addr Pointer to an XBP address specifier, or NULL +* @param[in] p Pointer to the data structure to be sent to the device +* +* @return One of the @ref MBG_RETURN_CODES +*/ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ims_fdm_settings( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_IMS_FDM_SETTINGS *p ) ; + + /** + * @brief Write a ::MBG_IMS_FDM_OUTPUT_SETTINGS parameter structure to a device. + * + * The ::MBG_IMS_FDM_SETTINGS parameter structure contains the analog output mode + * + * @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be set, 0..::MBG_IMS_FDM_LIMITS::n_outputs-1 + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_ims_fdm_output_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_IMS_FDM_OUTPUT_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Set time deviation of powerline time in relation to the current reference time + * + * @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags and + * ::MBG_IMS_FDM_FLAG_CAN_SET_TDEV is set in ::MBG_IMS_FDM_INFO::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_fdm_tdev( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const NANO_TIME_64 *p ) ; + + /** + * @brief Send a command to let the device save it's current configuration as default + * + * Call ::mbgextio_dev_has_cmd_save_cfg to check if this function is supported. + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_dev_has_cmd_save_cfg + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_cmd_save_cfg( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr ) ; + + /** + * @brief Read a ::MBG_IMS_FDM_STATE parameter structure from a device. + * ::TODO ### + * + * @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::TODO MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_lne_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LNE_LIMITS *p ) ; + + /** + * @brief Read a ::MBG_LNE_PORT_INFO_IDX parameter structure from a device. + * + * @note ### ::TODO Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_LNE_LIMITS::num_ports-1 + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_lne_port_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LNE_PORT_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Read a ::MBG_LNE_PORT_SETTINGS_IDX parameter structure from a device. + * + * @note ### ::TODO Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_LNE_LIMITS::num_ports + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_lne_port_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LNE_PORT_SETTINGS_IDX *p, uint16_t idx ) ; + + /** + * @brief Write a ::MBG_LNE_PORT_SETTINGS parameter structure to a device. + * + * @note ### ::TODO Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be set, 0..::MBG_LNE_LIMITS::num_ports - 1 + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_lne_port_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_LNE_PORT_SETTINGS *p, uint16_t idx ) ; + + /** + * @brief Write a ::MBG_PWR_CTL parameter structure to a device. + * + * @note Only supported if ::MBG_XFEATURE_PWR_CTL_API is set + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_pwr_ctl( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_PWR_CTL *p ) ; + + /** + * @brief Read a ::MBG_PWR_CTL parameter structure from a device. + * + * @note ### ::TODO Only supported if ::MBG_XFEATURE_PWR_CTL_API is set + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_pwr_ctl( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_PWR_CTL *p ) ; + + /** + * @brief Read the ::MBG_LED_LIMITS to check how many LEDs are provided + * + * ::mbgextio_dev_has_led_api should be used to check if this is supported + * + * @note Only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * + * @return One of the @ref MBG_RETURN_CODES + * + * @ingroup group_led_api + * @see ::mbgextio_dev_has_led_api + * @see ::mbgextio_get_led_limits + * @see ::mbgextio_get_led_info_idx + * @see ::mbgextio_get_led_settings_idx + * @see ::mbgextio_set_led_settings_idx + * @see @ref group_led_api + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_led_limits( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LED_LIMITS *p ) ; + + /** + * @brief Read the current settings and features of a particular LED + * + * ::mbgextio_dev_has_led_api should be used to check if this is supported + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::MBG_LED_LIMITS::num_leds-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @ingroup group_led_api + * @see ::mbgextio_dev_has_led_api + * @see ::mbgextio_get_led_limits + * @see ::mbgextio_get_led_settings_idx + * @see ::mbgextio_set_led_settings_idx + * @see @ref group_led_api + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_led_info_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LED_INFO_IDX *p, uint16_t idx ) ; + + /** + * @brief Read a ::MBG_LED_SETTINGS_IDX parameter structure from a device. + * + * ::mbgextio_dev_has_led_api should be used to check if this is supported + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[out] p Pointer to the data structure to return the received data + * @param[in] idx Index of the array element to be retrieved, 0..::num_leds-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @ingroup group_led_api + * @see ::mbgextio_dev_has_led_api + * @see ::mbgextio_get_led_limits + * @see ::mbgextio_get_led_info_idx + * @see ::mbgextio_set_led_settings_idx + * @see @ref group_led_api + */ + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_led_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_LED_SETTINGS_IDX *p, uint16_t idx ) ; + + /** + * @brief Write a ::MBG_LED_SETTINGS parameter structure to a device. + * + * ::mbgextio_dev_has_led_api should be used to check if this is supported + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] p_addr Pointer to an XBP address specifier, or NULL + * @param[in] p Pointer to the data structure to be sent to the device + * @param[in] idx Index of the array element to be set, 0..::MBG_LNE_LIMITS::num_ports-1 + * + * @return One of the @ref MBG_RETURN_CODES + * + * @ingroup group_led_api + * @see ::mbgextio_dev_has_led_api + * @see ::mbgextio_get_led_limits + * @see ::mbgextio_get_led_info_idx + * @see ::mbgextio_get_led_settings_idx + * @see @ref group_led_api */ - _NO_MBG_API_ATTR int _MBG_API mbgextio_set_utc_param( MBG_MSG_CTL *pmctl, XBP_ADDR *p_addr, const UTC *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_set_led_settings_idx( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, const MBG_LED_SETTINGS *p, uint16_t idx ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_ext_sys_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, MBG_EXT_SYS_INFO *p ) ; + _NO_MBG_API_ATTR int _MBG_API mbgextio_get_corr_info( MBG_MSG_CTL *pmctl, const XBP_ADDR *p_addr, CORR_INFO *p ) ; /* ----- function prototypes end ----- */ @@ -2164,8 +4885,8 @@ extern "C" { } #endif -#define _mbgextio_xmt_msg( _pmctl, _cmd, _s ) \ - mbgextio_xmt_msg( _pmctl, _cmd, _s, sizeof( *(_s) ) ) +#define _mbgextio_xmt_msg( _pmctl, _addr, _cmd, _s ) \ + mbgextio_xmt_msg( _pmctl, _addr, _cmd, _s, sizeof( *(_s) ) ) /* End of header body */ diff --git a/mbglib/common/mbggeo.h b/mbglib/common/mbggeo.h index c3bdb40..70ada99 100644 --- a/mbglib/common/mbggeo.h +++ b/mbglib/common/mbggeo.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbggeo.h 1.11 2011/06/22 10:18:10Z martin REL_M $ + * $Id: mbggeo.h 1.13 2017/01/27 08:57:58Z martin REL_M $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,7 @@ * * Terms used: * - * WGS84 world geodetic system of 1984 + * WGS84 World Geodetic System of 1984 * * XYZ WGS84 earth centered, earth fixed (ECEF) kartesian * coordinates @@ -22,7 +22,12 @@ * * ----------------------------------------------------------------------- * $Log: mbggeo.h $ - * Revision 1.11 2011/06/22 10:18:10Z martin + * Revision 1.13 2017/01/27 08:57:58Z martin + * Fixed macro syntax. + * Revision 1.12 2016/10/31 16:50:56 martin + * Fixed a typo. + * Updated doxygen comments. + * Revision 1.11 2011/06/22 10:18:10 martin * Cleaned up handling of pragma pack(). * Revision 1.10 2008/09/03 14:54:28 martin * Added macros to swap endianess of structures. @@ -34,7 +39,7 @@ * Revision 1.7 2003/02/14 13:23:04Z martin * Omit inclusion of mystd.h. * Revision 1.6 2003/01/13 15:17:15 martin - * Structures were defined with default alignment which + * Structures were defined with default alignment which * could result in different data sizes on different platforms. * Revision 1.5 2002/12/18 14:46:41Z martin * Removed variable USER_POS meinberg. @@ -71,104 +76,130 @@ /** - Geographic longitude or latitude in [degrees, minutes, seconds] - longitude East latitude North and positve, South or West angles negative + * @brief Geographic longitude or latitude in [degrees, minutes, seconds] + * + * Longitude East and latitude North are positive angles, South or West + * angles are negative. */ typedef struct { - uint16_t prefix; /**< 'N', 'E', 'S' or 'W' */ - uint16_t deg; /**< [0...90 (lat) or 0...180 (lon)] */ - uint16_t min; /**< [0...59] */ - double sec; /**< [0...59.999] */ + uint16_t prefix; ///< 'N', 'E', 'S' or 'W' + uint16_t deg; ///< [0...90 (lat) or 0...180 (lon)] + uint16_t min; ///< [0...59] + double sec; ///< [0...59.99999...] + } DMS; -// The corresponding macro _mbg_swab_dms() is defined in gpsdefs.h. #define _mbg_swab_dms( _p ) \ +do \ { \ _mbg_swab16( &(_p)->prefix ); \ _mbg_swab16( &(_p)->deg ); \ _mbg_swab16( &(_p)->min ); \ _mbg_swab_double( &(_p)->sec ); \ -} +} while ( 0 ) +/** + * @brief A geographic position represented in different formats + */ typedef struct { - XYZ xyz; /**< always WGS84 ECEF coordinates */ - LLA lla; /**< depending on the ellipsoid used for reference */ - DMS longitude; /**< longitude in degrees, minutes, seconds */ - DMS latitude; /**< latitude in degrees, minutes, seconds */ - int16_t ellipsoid; /**< ellipsoid used for reference */ + XYZ xyz; ///< Always WGS84 ECEF coordinates + LLA lla; ///< Longitude, latitude and altitude, depending on the ellipsoid used for reference + DMS longitude; ///< Longitude broken down to degrees, minutes, seconds + DMS latitude; ///< Latitude broken down to degrees, minutes, seconds + int16_t ellipsoid; ///< Ellipsoid used for reference, see ::ELLIPSOIDS + } POS; #define _mbg_swab_pos( _p ) \ +do \ { \ _mbg_swab_xyz( (_p)->xyz ); \ _mbg_swab_lla( (_p)->lla ); \ _mbg_swab_dms( &(_p)->longitude ); \ _mbg_swab_dms( &(_p)->latitude ); \ _mbg_swab16( &(_p)->ellipsoid ); \ -} +} while ( 0 ) +/** + * @brief A structure used internally to compute a geographic position + * + * Also contains intermediate results useful for the computation. + */ typedef struct { - CSUM csum; /* checksum of the remaining bytes */ - int16_t valid; /* flag data are valid */ + CSUM csum; ///< Checksum of the remaining bytes + int16_t valid; ///< Indicator if data is valid - char name[40]; - POS pos; /* the position in WGS84 ECEF coords and LLA */ + char name[40]; ///< Informational string + POS pos; ///< The position in WGS84 ECEF coords and ::LLA double det; -/* The components below hold the results of intermediate terms */ -/* computed in complete_user_pos(). */ + // The components below hold the results of intermediate terms + // computed in complete_user_pos(). -/* The sin.., cos.., nt.. and ut.. variables are used to compute the */ -/* enu_dcos[] parameters of a SV structure in xyz_to_ead(). */ + // The sin.., cos.., nt.. and ut.. variables are used to compute the + // enu_dcos[] parameters of a SV structure in xyz_to_ead(). -/* The e_radius.. variables are used to compute the latitude, longitude */ -/* and altitude from ECEF coordinates in lla_to_xyz(). */ + // The e_radius.. variables are used to compute the latitude, longitude + // and altitude from ECEF coordinates in lla_to_xyz(). - double sin_lat; /* sin( latitude ) */ - double cos_lat; /* cos( latitude ) */ - double sin_lon; /* sin( longitude ) */ - double cos_lon; /* cos( longitude ) */ + double sin_lat; ///< sin( latitude ) + double cos_lat; ///< cos( latitude ) + double sin_lon; ///< sin( longitude ) + double cos_lon; ///< cos( longitude ) - double nt1; /* -sin_lat * cos_lon */ - double nt2; /* -sin_lat * sin_lon */ - double utx; /* cos_lat * cos_lon */ - double uty; /* cos_lat * sin_lon */ + double nt1; ///< -sin_lat * cos_lon + double nt2; ///< -sin_lat * sin_lon + double utx; ///< cos_lat * cos_lon + double uty; ///< cos_lat * sin_lon - double e_radius; /* N */ - double e_radius_alt; /* N + h */ + double e_radius; ///< N + double e_radius_alt; ///< N + h } USER_POS; +/** + * @brief Characteristics of a geographic reference ellipsoid + */ typedef struct { - CSUM csum; /* checksum of the remaining bytes */ - int16_t valid; /* flag data are valid */ + CSUM csum; ///< Checksum of the remaining bytes + int16_t valid; ///< Indicator if data is valid char name[40]; - XYZ dxyz; /* offset from the WGS84 ECEF coords */ - double a; /* semi major axis */ - double rcp_f; /* reciproke of flatness */ + XYZ dxyz; ///< Offset from the WGS84 ECEF coords + double a; ///< Semi major axis + double rcp_f; ///< Reciproke of flatness + + // The variables below are computed in the init_mbggeo() function: -/* the variables below will be computed in the init_mbggeo() function: */ + double f; ///< Flatness + double b; ///< Semi minor axis + double sqr_e; ///< Square of numerical eccentricity - double f; /* flatness */ - double b; /* semi minor axis */ - double sqr_e; /* square of numerical eccentricity */ } ELLIPSOID; -enum { WGS84, BESSEL, N_ELLIPSOIDS }; +/** + * @brief An enumeration of known ellipsoids + */ +enum ELLIPSOIDS +{ + WGS84, + BESSEL, + N_ELLIPSOIDS +}; + _ext ELLIPSOID ellipsoid[N_ELLIPSOIDS] #ifdef _DO_INIT @@ -191,15 +222,15 @@ _ext ELLIPSOID ellipsoid[N_ELLIPSOIDS] ; -/* WGS84 constants used */ +// WGS84 constants used -_ext double OMEGADOTe /* earth's rotation rate [rad/sec] */ +_ext double OMEGADOTe // Earth's rotation rate [rad/sec] #ifdef _DO_INIT = 7.2921151467e-5 #endif ; -_ext double mue /* earth's gravitational constant [m^3/sec^2] */ +_ext double mue // Earth's gravitational constant [m^3/sec^2] #ifdef _DO_INIT = 3.986005e14 #endif @@ -249,10 +280,10 @@ _ext double d2r ; -/* variables for simplifying computations */ +// Variables for simplifying computations _ext double gps_two_pi; -_ext double sqrt_mue; /* sqrt( mue ) */ +_ext double sqrt_mue; // sqrt( mue ) diff --git a/mbglib/common/mbgklist.h b/mbglib/common/mbgklist.h new file mode 100644 index 0000000..eaf8cc7 --- /dev/null +++ b/mbglib/common/mbgklist.h @@ -0,0 +1,304 @@ + +/************************************************************************** + * + * $Id: mbgklist.h 1.2.1.4 2017/01/12 15:09:45Z philipp TEST $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Userspace implementation of Linux Kernel's list.h + * + * ----------------------------------------------------------------------- + * $Log: mbgklist.h $ + * Revision 1.2.1.4 2017/01/12 15:09:45Z philipp + * Added more safe loop macros + * Revision 1.2.1.3 2017/01/12 12:21:22 philipp + * Added safe loop macros + * Revision 1.2.1.2 2016/08/11 14:13:22 martin + * Revision 1.2.1.1 2016/08/10 14:32:13Z martin + * *** empty log message *** + * Revision 1.2 2015/10/06 07:08:45 philipp + * Added functions to loop containers of list entries + * Revision 1.1 2015/09/09 10:42:27 martin + * Initial revision. + * + **************************************************************************/ + +#ifndef _MBGKLIST_H +#define _MBGKLIST_H + +/* Other headers to be included */ + +#include <mbg_cof.h> + + +#ifdef _MBGKLIST + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +#ifdef __cplusplus +extern "C" { +#endif + + +#define MBG_KLIST_INIT(name) { &(name), &(name) } + +#define MBG_KLIST_DECLARE(name) \ + struct mbg_klist_head name = MBG_KLIST_INIT(name) + +#define mbg_klist_for_each(head, pos) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +#define mbg_klist_for_each_safe(head, pos, n) \ + for (pos = (head)->next, n = (pos)->next; \ + pos != (head); \ + pos = n, n = pos->next) + +#define mbg_klist_for_each_rev(head, pos) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) + +#define mbg_klist_for_each_rev_safe(head, pos, n) \ + for (pos = (head)->prev, n = (pos)->prev; \ + pos != (head); \ + pos = n, n = pos->prev) + +#define mbg_klist_entry(ptr, type, member) \ + mbg_container_of(ptr, type, member) + +#define mbg_klist_first_entry(ptr, type, member) \ + mbg_klist_entry((ptr)->next, type, member) + +#define mbg_klist_last_entry(ptr, type, member) \ + mbg_klist_entry((ptr)->prev, type, member) + + + +#if defined( __GNUC__ ) || defined( __clang__ ) // "typeof" supported + +#define mbg_klist_next_entry(pos, member) \ + mbg_klist_entry((pos)->member.next, typeof(*pos), member) + +#define mbg_klist_prev_entry(pos, member) \ + mbg_klist_entry((pos)->member.prev, typeof(*pos), member) + +#define mbg_klist_for_each_entry(head, pos, member) \ + for (pos = mbg_klist_first_entry(head, typeof(*pos), member); \ + &pos->member != (head); \ + pos = mbg_klist_next_entry(pos, member)) + +#define mbg_klist_for_each_entry_rev(head, pos, member) \ + for (pos = mbg_klist_last_entry(head, typeof(*pos), member); \ + &pos->member != (head); \ + pos = mbg_klist_prev_entry(pos, member)) + +#define mbg_klist_for_each_entry_safe(head, pos, n, member) \ + for (pos = mbg_klist_first_entry(head, typeof(*pos), member), \ + n = mbg_klist_next_entry(pos, member); \ + &pos->member != (head); \ + pos = n, n = mbg_klist_next_entry(pos, member)) + +#define mbg_klist_for_each_entry_rev_safe(head, pos, n, member) \ + for (pos = mbg_klist_last_entry(head, typeof(*pos), member), \ + n = mbg_klist_prev_entry(pos, member); \ + &pos->member != (head); \ + pos = n, n = mbg_klist_prev_entry(pos, member)) + +#endif + + + +struct mbg_klist_head +{ + struct mbg_klist_head *prev; + struct mbg_klist_head *next; +}; + + + +/* function prototypes: */ + +static __mbg_inline +void mbg_klist_init( struct mbg_klist_head *head ) +{ + head->next = head; + head->prev = head; +} + + +static __mbg_inline +void __mbg_klist_add_item( struct mbg_klist_head *item, struct mbg_klist_head *prev, struct mbg_klist_head *next ) +{ + next->prev = item; + item->next = next; + item->prev = prev; + prev->next = item; +} + + +static __mbg_inline +void mbg_klist_prepend_item( struct mbg_klist_head *head, struct mbg_klist_head *item ) +{ + __mbg_klist_add_item( item, head, head->next ); +} + + +static __mbg_inline +void mbg_klist_append_item( struct mbg_klist_head *head, struct mbg_klist_head *item ) +{ + __mbg_klist_add_item( item, head->prev, head ); +} + + +static __mbg_inline +void __mbg_klist_delete_item( struct mbg_klist_head *prev, struct mbg_klist_head *next ) +{ + next->prev = prev; + prev->next = next; +} + + +static __mbg_inline +void mbg_klist_delete_item( struct mbg_klist_head *item ) +{ + __mbg_klist_delete_item( item->prev, item->next ); +} + + +static __mbg_inline +void mbg_klist_delete_item_init( struct mbg_klist_head *item ) +{ + __mbg_klist_delete_item( item->prev, item->next ); + mbg_klist_init( item ); +} + + +static __mbg_inline +void mbg_klist_replace_item( struct mbg_klist_head *old, struct mbg_klist_head *item ) +{ + item->next = old->next; + item->next->prev = item; + item->prev = old->prev; + item->prev->next = item; +} + + +static __mbg_inline +void mbg_klist_replace_item_init( struct mbg_klist_head *old, struct mbg_klist_head *item ) +{ + mbg_klist_replace_item( old, item ); + mbg_klist_init( item ); +} + + +static __mbg_inline +void mbg_klist_move_prepend_item( struct mbg_klist_head *head, struct mbg_klist_head *item ) +{ + mbg_klist_delete_item( item ); + mbg_klist_prepend_item( head, item ); +} + + +static __mbg_inline +void mbg_klist_move_append_item( struct mbg_klist_head *head, struct mbg_klist_head *item ) +{ + mbg_klist_delete_item( item ); + mbg_klist_append_item( head, item ); +} + + +static __mbg_inline +int mbg_klist_is_first( const struct mbg_klist_head *head, const struct mbg_klist_head *item ) +{ + return ( ( item->prev == head ) ? 1 : 0 ); +} + + +static __mbg_inline +int mbg_klist_is_last( const struct mbg_klist_head *head, const struct mbg_klist_head *item ) +{ + return ( ( item->next == head ) ? 1 : 0 ); +} + + +static __mbg_inline +int mbg_klist_is_empty( const struct mbg_klist_head *head ) +{ + return ( ( head->next == head ) ? 1 : 0 ); +} + + +static __mbg_inline +void __mbg_klist_add_list( const struct mbg_klist_head *list, struct mbg_klist_head *prev, struct mbg_klist_head *next ) +{ + struct mbg_klist_head *first = list->next; + struct mbg_klist_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + + +static __mbg_inline +void mbg_klist_prepend_list( struct mbg_klist_head *head, const struct mbg_klist_head *list ) +{ + if ( !mbg_klist_is_empty( list ) ) + __mbg_klist_add_list( list, head, head->next ); +} + + +static __mbg_inline +void mbg_klist_append_list( struct mbg_klist_head *head, const struct mbg_klist_head *list ) +{ + if ( !mbg_klist_is_empty( list ) ) + __mbg_klist_add_list( list, head->prev, head ); +} + + +static __mbg_inline +void mbg_klist_prepend_list_init( struct mbg_klist_head *head, struct mbg_klist_head *list ) +{ + if ( !mbg_klist_is_empty( list ) ) + { + __mbg_klist_add_list( list, head, head->next ); + mbg_klist_init( list ); + } +} + + +static __mbg_inline +void mbg_klist_append_list_init( struct mbg_klist_head *head, struct mbg_klist_head *list ) +{ + if ( !mbg_klist_is_empty( list ) ) + { + __mbg_klist_add_list( list, head->prev, head ); + mbg_klist_init( list ); + } +} + + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + +/* ----- function prototypes end ----- */ + +#ifdef __cplusplus +} +#endif + +/* End of header body */ + +#undef _ext +#undef _DO_INIT + +#endif /* _MBGKLIST_H */ diff --git a/mbglib/common/mbgserio.c b/mbglib/common/mbgserio.c index 6f03dac..723b56b 100644 --- a/mbglib/common/mbgserio.c +++ b/mbglib/common/mbgserio.c @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgserio.c 1.6.1.17 2015/07/22 16:02:52Z martin TEST martin $ + * $Id: mbgserio.c 1.6.1.32 2017/04/10 13:39:44Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,37 @@ * * ----------------------------------------------------------------------- * $Log: mbgserio.c $ - * Revision 1.6.1.17 2015/07/22 16:02:52Z martin + * Revision 1.6.1.32 2017/04/10 13:39:44Z martin + * Fixed some compiler warnings. + * Revision 1.6.1.31 2016/11/16 13:07:32Z thomas-b + * Fixed several compiler errors under Windows + * Revision 1.6.1.30 2016/11/15 15:45:59 martin + * Allocate a device control structure when opening a port, + * and free the structure when the port is closed. + * Cleanup. + * Revision 1.6.1.29 2016/11/08 17:22:39 martin + * Doxygen fixes. + * Revision 1.6.1.28 2016/08/22 13:39:55 gregoire.diehl + * Revision 1.6.1.27 2016/02/03 09:48:26Z martin + * Fixed Windows build. + * Revision 1.6.1.26 2015/12/10 16:30:17Z martin + * *** empty log message *** + * Revision 1.6.1.25 2015/12/10 10:38:39 martin + * *** empty log message *** + * Revision 1.6.1.24 2015/12/09 17:35:03 martin + * *** empty log message *** + * Revision 1.6.1.23 2015/11/27 09:57:00 martin + * More checking of function return codes. + * Revision 1.6.1.22 2015/10/30 16:02:18 martin + * Revision 1.6.1.21 2015/10/29 14:01:43Z martin + * *** empty log message *** + * Revision 1.6.1.20 2015/10/05 15:07:23 marvin + * Unicode support. + * Revision 1.6.1.19 2015/09/08 09:48:28Z martin + * Revision 1.6.1.18 2015/08/27 16:20:19Z martin + * Use safe string functions from str_util.c. + * Added doxygen comments. + * Revision 1.6.1.17 2015/07/22 16:02:52 martin * Cleanup. * Removed trailing whitespace. * Revision 1.6.1.16 2014/05/27 11:26:24 martin @@ -75,10 +105,12 @@ #include <mbgserio.h> #undef _MBGSERIO +#include <mbgerror.h> +#include <str_util.h> + #include <stdio.h> #include <ctype.h> #include <time.h> -#include <mbgerror.h> #if defined( MBG_TGT_POSIX ) #include <fcntl.h> @@ -153,20 +185,84 @@ int v24close( int port ); +static /*HDR*/ +/** + * @brief Deallocate a serial device control structure + * + * Free the memory allocated for the device control structure + * and set the pointer to NULL. + * + * @param[in,out] pp_mdev Address of a pointer to a device control structure + * + * @see ::alloc_mbgserio_dev + */ +void dealloc_mbgserio_dev( MBGSERIO_DEV **pp_mdev ) +{ + MBGSERIO_DEV *p_mdev = *pp_mdev; + + if ( p_mdev ) + { + free( p_mdev ); + *pp_mdev = NULL; + } + +} // dealloc_mbgserio_dev + + + +static /*HDR*/ +/** + * @brief Allocate a serial device control structure + * + * @param[in,out] pp_mdev Address of a pointer to a device control structure + * + * @return ::MBG_SUCCESS or one of the @ref MBG_ERROR_CODES + * + * @see ::dealloc_mbgserio_dev + */ +int alloc_mbgserio_dev( MBGSERIO_DEV **pp_mdev ) +{ + int rc; + MBGSERIO_DEV *p_mdev = (MBGSERIO_DEV *) malloc( sizeof( *p_mdev ) ); + + if ( p_mdev == NULL ) + { + rc = mbg_get_last_error( "malloc failed in alloc_mbgserio_dev" ); + goto out; + } + + memset( p_mdev, 0, sizeof( *p_mdev ) ); + p_mdev->port_handle = MBG_INVALID_PORT_HANDLE; + rc = MBG_SUCCESS; + +out: + *pp_mdev = p_mdev; + return rc; + +} // alloc_mbgserio_dev + + + #if defined( MBG_TGT_WIN32 ) static /*HDR*/ /** - * @brief + * @brief Win32-specific function which opens a serial port * - * @return One of the @ref MBG_RETURN_CODES + * @param[in] dev_name Basic device name, e.g. "COM1" + * @param[out] ph Pointer to a HANDLE which is set up on success + * + * @return ::MBG_SUCCESS on success, or one of the @ref MBG_ERROR_CODES */ -int win32_create_file( const char *dev, HANDLE *ph ) +int win32_open_serial_port( const char *dev_name, HANDLE *ph ) { + // A prefix is required for the device name to be able + // to open ports with large numbers, e.g. COM15. static const char prefix[] = "\\\\.\\"; - size_t len = strlen( prefix ) + strlen( dev ) + 1; + size_t len = strlen( prefix ) + strlen( dev_name ) + 1; char *tmp_name; + size_t n = 0; int rc = MBG_ERR_UNSPEC; tmp_name = (char *) malloc( len ); @@ -177,10 +273,10 @@ int win32_create_file( const char *dev, HANDLE *ph ) goto out; } - strcpy( tmp_name, prefix ); - strcat( tmp_name, dev ); + n = sn_cpy_str_safe( tmp_name, len, prefix ); + n += sn_cpy_str_safe( &tmp_name[n], len - n, dev_name ); - *ph = CreateFile( tmp_name, GENERIC_READ | GENERIC_WRITE, + *ph = CreateFileA( tmp_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, @@ -189,7 +285,7 @@ int win32_create_file( const char *dev, HANDLE *ph ) if ( *ph == INVALID_HANDLE_VALUE ) { - rc = mbg_win32_last_err_to_mbg( GetLastError(), "CreateFile failed in win32_create_file" ); + rc = mbg_win32_last_err_to_mbg( GetLastError(), "CreateFile failed in win32_open_serial_port" ); goto out_free; } @@ -201,86 +297,79 @@ out_free: out: return rc; -} // win32_create_file +} // win32_open_serial_port #endif // defined( MBG_TGT_WIN32 ) -static /*HDR*/ +/*HDR*/ /** - * @brief + * @brief Close a serial port specified by a ::MBGSERIO_DEV structure + * + * After the port has been closed the buffer which had been allocated + * for the ::MBGSERIO_DEV structure is freed, and the pointer to that + * buffer is set to NULL. + * + * @param[in,out] pp_mdev Address of a pointer to the control structure including the port handle * * @return One of the @ref MBG_RETURN_CODES */ -_NO_MBG_API_ATTR int _MBG_API mbgserio_close_port_by_handle( MBG_PORT_HANDLE *p ) +_NO_MBG_API_ATTR int _MBG_API mbgserio_close( MBGSERIO_DEV **pp_mdev ) { - if ( *p != MBG_INVALID_PORT_HANDLE ) + if ( *pp_mdev) // only if a MBGSERIO_DEV structure has been allocated { - #if defined( MBG_TGT_CVI ) + MBGSERIO_DEV *p_mdev = *pp_mdev; + MBG_PORT_HANDLE *p_handle = &p_mdev->port_handle; - CloseCom( *p ); + if ( *p_handle != MBG_INVALID_PORT_HANDLE ) + { + mbgserio_flush_tx( p_mdev ); - #elif defined( MBG_TGT_WIN32 ) + #if defined( MBG_TGT_CVI ) - CloseHandle( *p ); + CloseCom( *p_handle ); - #elif defined( MBG_TGT_POSIX ) + #elif defined( MBG_TGT_WIN32 ) - close( *p ); + // restore original settings that have been saved - #elif defined( MBG_TGT_DOS ) - #if defined( _USE_V24TOOLS ) + if ( p_mdev->org_dcb_has_been_read ) + SetCommState( *p_handle, &p_mdev->org_dcb ); - v24close( *p ); + if ( p_mdev->org_commtimeouts_have_been_read ) + SetCommTimeouts( *p_handle, &p_mdev->org_commtimeouts ); - #else + CloseHandle( *p_handle ); - #error Target DOS requires v24tools for serial I/O. + #elif defined( MBG_TGT_POSIX ) - #endif + // restore original settings that have been saved - #else + if ( p_mdev->org_tio_has_been_read ) + tcsetattr( *p_handle, TCSANOW, &p_mdev->org_tio ); - #error This target OS is not supported. + close( *p_handle ); - #endif + #elif defined( MBG_TGT_DOS ) + #if defined( _USE_V24TOOLS ) - *p = MBG_INVALID_PORT_HANDLE; - } - - return MBG_SUCCESS; + v24close( *p_handle ); -} // mbgserio_close_port_by_handle + #else + #error Target DOS requires v24tools for serial I/O. + #endif -/*HDR*/ -/** - * @brief - * - * @return One of the @ref MBG_RETURN_CODES - */ -_NO_MBG_API_ATTR int _MBG_API mbgserio_close( SERIAL_IO_STATUS *pst ) -{ - if ( pst->port_handle != MBG_INVALID_PORT_HANDLE ) - { - MBG_PORT_HANDLE port_handle = pst->port_handle; - - mbgserio_flush_tx( port_handle ); - - #if defined( MBG_TGT_WIN32 ) - - SetCommState( port_handle, &pst->old_dcb ); - SetCommTimeouts( port_handle, &pst->old_commtimeouts ); - - #elif defined( MBG_TGT_POSIX ) + #else - tcsetattr( port_handle, TCSANOW, &pst->old_tio ); + #error This target OS is not supported. - #endif + #endif + } - return mbgserio_close_port_by_handle( &pst->port_handle ); + dealloc_mbgserio_dev( pp_mdev ); } return MBG_SUCCESS; @@ -291,14 +380,27 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_close( SERIAL_IO_STATUS *pst ) /*HDR*/ /** - * @brief + * @brief Open a serial port and set up a ::MBGSERIO_DEV structure + * + * @param[in,out] pp_mdev Address of a pointer to a ::MBGSERIO_DEV device control structure + * allocated and set up by this call. Set to NULL on error. + * @param[in] dev_name Device name of the port to be opened. * * @return One of the @ref MBG_RETURN_CODES */ -_NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev ) +_NO_MBG_API_ATTR int _MBG_API mbgserio_open( MBGSERIO_DEV **pp_mdev, const char *dev_name ) { - MBG_PORT_HANDLE port_handle = MBG_INVALID_PORT_HANDLE; - int rc = MBG_ERR_UNSPEC; + MBGSERIO_DEV *p_mdev; + MBG_PORT_HANDLE *p_handle; + + int rc = alloc_mbgserio_dev( pp_mdev ); + + if ( mbg_rc_is_error( rc ) ) + return rc; + + + p_mdev = *pp_mdev; + p_handle = &p_mdev->port_handle; #if defined( MBG_TGT_CVI ) { @@ -313,11 +415,11 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char * // Under CVI the port handle passed to OpenComConfig and used furtheron // corresponds to the COM port number, e.g. 1 for COM1, so we extract // the number from the device name passed as parameter. - len = strlen( dev ); + len = strlen( dev_name ); for ( i = 0; i < len; i++ ) { - char c = dev[i]; + char c = dev_name[i]; if ( c >= '0' && c <= '9' ) break; @@ -329,31 +431,31 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char * goto out; } - port_handle = atoi( &dev[i] ); + *p_handle = atoi( &dev_name[i] ); - rc = OpenComConfig( port_handle, NULL, baud_rate, parity_code, data_bits, stop_bits, 8192, 1024 ); //##++ + rc = OpenComConfig( *p_handle, NULL, baud_rate, parity_code, data_bits, stop_bits, 8192, 1024 ); //##++ if ( rc < 0 ) { - port_handle = MBG_INVALID_PORT_HANDLE; - rc = MBG_ERR_UNSPEC; // translate rc ? + rc = mbg_get_last_error( "OpenComConfig failed in mbgserio_open" ); + *p_handle = MBG_INVALID_PORT_HANDLE; goto out; } - rc = SetComTime( port_handle, 1.0 ); //##+++++++ WTF? + rc = SetComTime( *p_handle, 1.0 ); //##+++++++ WTF? if ( rc < 0 ) { - rc = MBG_ERR_UNSPEC; //##+++++ translate rc ? - goto out_close; + rc = mbg_get_last_error( "SetComTime failed in mbgserio_open" ); + goto out; } - rc = SetXMode( port_handle, 0 ); + rc = SetXMode( *p_handle, 0 ); if ( rc < 0 ) { - rc = MBG_ERR_UNSPEC; //##+++++ translate rc ? - goto out_close; + rc = mbg_get_last_error( "SetXMode failed in mbgserio_open" ); + goto out; } } #elif defined( MBG_TGT_WIN32 ) @@ -361,16 +463,39 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char * COMMTIMEOUTS commtimeouts; DCB dcb; - rc = win32_create_file( dev, &port_handle ); + rc = win32_open_serial_port( dev_name, p_handle ); - if ( rc != MBG_SUCCESS ) + // rc is now one of the @ref MBG_RETURN_CODES, and in case of an error + // the handle has already been set to ::MBG_INVALID_PORT_HANDLE. + if ( mbg_rc_is_error( rc ) ) goto out; // save settings found at startup - pst->old_dcb.DCBlength = sizeof( pst->old_dcb ); - GetCommState( port_handle, &pst->old_dcb ); - GetCommTimeouts( port_handle, &pst->old_commtimeouts ); - GetCommProperties( port_handle, &pst->comm_prop ); + p_mdev->org_dcb.DCBlength = sizeof( p_mdev->org_dcb ); + + if ( !GetCommState( *p_handle, &p_mdev->org_dcb ) ) + { + rc = mbg_get_last_error( "GetCommState failed in mbgserio_open" ); + goto out; + } + + p_mdev->org_dcb_has_been_read = 1; + + if ( !GetCommTimeouts( *p_handle, &p_mdev->org_commtimeouts ) ) + { + rc = mbg_get_last_error( "GetCommTimeouts failed in mbgserio_open" ); + goto out; + } + + p_mdev->org_commtimeouts_have_been_read = 1; + + if ( !GetCommProperties( *p_handle, &p_mdev->comm_prop ) ) + { + rc = mbg_get_last_error( "GetCommProperties failed in mbgserio_open" ); + goto out; + } + + p_mdev->comm_prop_have_been_read = 1; #if 0 // fields provided by the Windows DCB structure DWORD DCBlength; /* sizeof(DCB) */ @@ -404,27 +529,27 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char * #endif // configure our settings - dcb = pst->old_dcb; // current settings as default + dcb = p_mdev->org_dcb; // current settings as default dcb.fOutxCtsFlow = FALSE; // CTS output flow control dcb.fOutxDsrFlow = FALSE; // DSR output flow control dcb.fDtrControl = DTR_CONTROL_ENABLE; // enable DTR dcb.fDsrSensitivity = FALSE; // don't require DSR input active - //##++ TODO: more missing here + //###++ TODO: more missing here dcb.fRtsControl = RTS_CONTROL_ENABLE; // enable RTS for C28COM dcb.fOutX = FALSE; - if ( !SetCommState( port_handle, &dcb ) ) + if ( !SetCommState( *p_handle, &dcb ) ) { rc = mbg_get_last_error( "SetCommState failed in mbgserio_open" ); - goto out_close; + goto out; } memset( &commtimeouts, 0, sizeof( commtimeouts ) ); - if ( !SetCommTimeouts( port_handle, &commtimeouts ) ) + if ( !SetCommTimeouts( *p_handle, &commtimeouts ) ) { rc = mbg_get_last_error( "SetCommTimeout failed in mbgserio_open" ); - goto out_close; + goto out; } #if !defined( MBGSERIO_IN_BUFFER_SIZE ) @@ -435,16 +560,16 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char * #define MBGSERIO_OUT_BUFFER_SIZE 2048 #endif - if ( !SetupComm( port_handle, MBGSERIO_IN_BUFFER_SIZE, MBGSERIO_OUT_BUFFER_SIZE ) ) + if ( !SetupComm( *p_handle, MBGSERIO_IN_BUFFER_SIZE, MBGSERIO_OUT_BUFFER_SIZE ) ) { rc = mbg_get_last_error( "SetupComm failed in mbgserio_open" ); - goto out_close; + goto out; } - PurgeComm( port_handle, PURGE_TXABORT | PURGE_TXCLEAR ); - PurgeComm( port_handle, PURGE_RXABORT | PURGE_RXCLEAR ); + PurgeComm( *p_handle, PURGE_TXABORT | PURGE_TXCLEAR ); + PurgeComm( *p_handle, PURGE_RXABORT | PURGE_RXCLEAR ); - //##++ TODO: mbgextio_set_console_control_handler() ? + //###++ TODO: mbgextio_set_console_control_handler() ? } #elif defined( MBG_TGT_POSIX ) { @@ -457,66 +582,68 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char * flags |= O_CLOEXEC; #endif - port_handle = open( dev, flags ); // returns -1 on error + *p_handle = open( dev_name, flags ); // returns -1 on error - if ( port_handle < 0 ) + if ( *p_handle < 0 ) { rc = mbg_get_last_error( "open failed in mbgserio_open" ); - port_handle = MBG_INVALID_PORT_HANDLE; + *p_handle = MBG_INVALID_PORT_HANDLE; goto out; } - //##++ TODO: Under Unix a serial port can by default be opened + //###++ TODO: Under Unix a serial port can by default be opened // by several processes. However, we don't want that, so we // should care about this using a lock file for the device // and/or setting the TIOCEXCL flag (which unfortunately // is not an atomic operation with open()). /* save current device settings */ - if ( tcgetattr( port_handle, &pst->old_tio ) < 0 ) + if ( tcgetattr( *p_handle, &p_mdev->org_tio ) < 0 ) { rc = mbg_get_last_error( "tcgetattr failed in mbgserio_open" ); - goto out_close; + goto out; } - //##++ atexit( port_deinit ); + p_mdev->org_tio_has_been_read = 1; - fflush( stdout ); //##++ - setvbuf( stdout, NULL, _IONBF, 0 ); + //##++ TODO atexit( port_deinit ); ?? } #elif defined( MBG_TGT_DOS ) #if defined( _USE_V24TOOLS ) { - port_handle = v24open( (char *) dev, OPEN_MODE ); + *p_handle = v24open( (char *) dev_name, OPEN_MODE ); - if ( port_handle < 0 ) + if ( *p_handle < 0 ) { - rc = MBG_ERR_UNSPEC; // translate rc ? + rc = MBG_ERR_UNSPEC; //##++ translate rc ? + *p_handle = MBG_INVALID_PORT_HANDLE; goto out; } - v24settimeout( port_handle, 1 ); + v24settimeout( *p_handle, 1 ); } #else #error Target DOS requires v24tools for serial I/O. + rc = MBG_ERR_NOT_SUPP_ON_OS; + goto out; #endif #else #error This target OS is not supported. + rc = MBG_ERR_NOT_SUPP_ON_OS; + goto out; #endif rc = MBG_SUCCESS; - goto out; - -out_close: - mbgserio_close_port_by_handle( &port_handle ); // also sets port handle invalid out: - pst->port_handle = port_handle; + if ( mbg_rc_is_error( rc ) ) + mbgserio_close( pp_mdev ); + return rc; } // mbgserio_open @@ -531,7 +658,7 @@ int scandir_filter_serial_port( const struct dirent *pde ) static const char dev_name_1[] = "ttyS"; static const char dev_name_2[] = "ttyUSB"; char tmp_str[100]; - SERIAL_IO_STATUS iost; + MBGSERIO_DEV *p_mdev; int rc; int l; @@ -555,9 +682,9 @@ check: if ( pde->d_name[l] < '0' || pde->d_name[l] > '9' ) return 0; - snprintf( tmp_str, sizeof( tmp_str ), "%s/%s", dev_dir, pde->d_name ); + snprintf_safe( tmp_str, sizeof( tmp_str ), "%s/%s", dev_dir, pde->d_name ); - rc = mbgserio_open( &iost, tmp_str ); + rc = mbgserio_open( &p_mdev, tmp_str ); if ( rc < 0 ) { @@ -572,7 +699,7 @@ check: fprintf( stderr, "port %s opened successfully\n", tmp_str ); #endif - mbgserio_close( &iost ); + mbgserio_close( &p_mdev ); return 1; @@ -650,8 +777,8 @@ found: HANDLE h = INVALID_HANDLE_VALUE; - sprintf( dev_name, "COM%i", i + 1 ); - rc = win32_create_file( dev_name, &h ); + snprintf_safe( dev_name, sizeof( dev_name ), "COM%i", i + 1 ); + rc = win32_open_serial_port( dev_name, &h ); // If access is denied then the port exists but is in use if ( rc != MBG_SUCCESS && rc != MBG_ERR_ACCESS ) @@ -662,21 +789,21 @@ found: #elif defined( MBG_TGT_LINUX ) - SERIAL_IO_STATUS iost; - sprintf( dev_name, "/dev/ttyS%i", i ); - rc = mbgserio_open( &iost, dev_name ); + MBGSERIO_DEV *p_mdev; + snprintf_safe( dev_name, sizeof( dev_name ), "/dev/ttyS%i", i ); + rc = mbgserio_open( &p_mdev, dev_name ); if ( rc < 0 ) { - sprintf( dev_name, "/dev/ttyUSB%i", i ); + snprintf_safe( dev_name, sizeof( dev_name ), "/dev/ttyUSB%i", i ); - rc = mbgserio_open( &iost, dev_name ); + rc = mbgserio_open( &p_mdev, dev_name ); if ( rc < 0 ) continue; } - mbgserio_close( &iost ); + mbgserio_close( &p_mdev ); #endif @@ -692,7 +819,7 @@ found: memset( (*list), 0, sizeof( **list ) ); n++; -// if ( ++i >= MBG_MAX_DEVICES ) +// if ( ++i >= N_SUPP_DEV_EXT ) // break; } @@ -758,10 +885,10 @@ _NO_MBG_API_ATTR void _MBG_API mbgserio_free_str_list( MBG_STR_LIST *list ) * * @return One of the @ref MBG_RETURN_CODES */ -_NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, - uint32_t baud_rate, const char *framing ) +_NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( MBGSERIO_DEV *mdev, + uint32_t baud_rate, const char *framing ) { - MBG_PORT_HANDLE port_handle = pst->port_handle; + MBG_PORT_HANDLE port_handle = mdev->port_handle; const char *cp; int rc = MBG_ERR_UNSPEC; @@ -801,21 +928,25 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, break; default: - rc = MBG_ERR_INV_PARM; // invalid framing string - goto out; + return MBG_ERR_INV_PARM; // invalid framing string } } rc = OpenComConfig( port_handle, NULL, baud_rate, parity_code, data_bits, stop_bits, 8192, 1024 ); if ( rc < 0 ) - { - rc = MBG_ERR_INV_PARM; - goto out; - } + return mbg_cvi_rs232_error_to_mbg( rc, "OpenComConfig failed in mbgserio_set_parms" ); + + rc = SetComTime( port_handle, 1.0 ); + + if ( rc < 0 ) + return mbg_cvi_rs232_error_to_mbg( rc, "SetComTime failed in mbgserio_set_parms" ); + + rc = SetXMode( port_handle, 0 ); + + if ( rc < 0 ) + return mbg_cvi_rs232_error_to_mbg( rc, "SetXMode failed in mbgserio_set_parms" ); - SetComTime( port_handle, 1.0 ); //##++++++++ check rc ? - SetXMode( port_handle, 0 ); } #elif defined( MBG_TGT_WIN32 ) { @@ -823,12 +954,13 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, // get current settings dcb.DCBlength = sizeof( DCB ); - GetCommState( port_handle, &dcb ); //##++++++++++++++++ check rc? + + if ( GetCommState( port_handle, &dcb ) == FALSE ) + return mbg_get_last_error( "GetCommState failed in mbgserio_set_parms" ); // update changed settings dcb.BaudRate = baud_rate; - // setup framing. for ( cp = framing; *cp; cp++ ) { @@ -862,22 +994,25 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, break; default: - rc = MBG_ERR_INV_PARM; // invalid framing string - goto out; + return MBG_ERR_INV_PARM; // invalid framing string } } - SetCommState( port_handle, &dcb ); //##++++++++ check rc + if ( SetCommState( port_handle, &dcb ) == FALSE ) + return mbg_get_last_error( "SetCommState failed in mbgserio_set_parms" ); } #elif defined( MBG_TGT_POSIX ) { tcflag_t c_cflag = 0; struct termios tio; - rc = tcgetattr( port_handle, &tio ); //##+++++++++++++++++ check rc + rc = tcgetattr( port_handle, &tio ); + + if ( rc < 0 ) + return mbg_get_last_error( "tcgetattr failed in mbgserio_set_parms" ); // setup transmission speed - switch( baud_rate ) + switch ( baud_rate ) { case 300: c_cflag = B300; break; case 600: c_cflag = B600; break; @@ -894,13 +1029,48 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, #if defined( B230400 ) case 230400: c_cflag = B230400; break; #endif + #if defined( B460800 ) + case 460800: c_cflag = B460800; break; + #endif + #if defined( B500000 ) + case 500000: c_cflag = B500000; break; + #endif + #if defined( B576000 ) + case 576000: c_cflag = B576000; break; + #endif + #if defined( B921600 ) + case 921600: c_cflag = B921600; break; + #endif + #if defined( B1000000 ) + case 1000000: c_cflag = B1000000; break; + #endif + #if defined( B1152000 ) + case 1152000: c_cflag = B1152000; break; + #endif + #if defined( B1500000 ) + case 1500000: c_cflag = B1500000; break; + #endif + #if defined( B2000000 ) + case 2000000: c_cflag = B2000000; break; + #endif + #if defined( B2500000 ) + case 2500000: c_cflag = B2500000; break; + #endif + #if defined( B3000000 ) + case 3000000: c_cflag = B3000000; break; + #endif + #if defined( B3500000 ) + case 3500000: c_cflag = B3500000; break; + #endif + #if defined( B4000000 ) + case 4000000: c_cflag = B4000000; break; + #endif default: - rc = MBG_ERR_INV_PARM; // invalid - goto out; + return MBG_ERR_INV_PARM; // invalid } - #if 0 //##++ This should be used preferably for portability reasons + #if 0 //###++ This should be used preferably for portability reasons int cfsetispeed( struct termios *termios_p, speed_t speed ); int cfsetospeed( struct termios *termios_p, speed_t speed ); #endif @@ -923,8 +1093,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, case '2': c_cflag |= CSTOPB; break; default: - rc = MBG_ERR_INV_PARM; // invalid - goto out; + return MBG_ERR_INV_PARM; // invalid } } @@ -983,7 +1152,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, // implement this bit, and acts as if it is always set. tio.c_iflag = 0; - #if 0 //##++ + #if 0 //###++ if ( c_cflag & PARENB ) tio.c_iflag |= IGNPAR; //##++ this also ignores framing errors #endif @@ -1124,11 +1293,11 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, tio.c_cc[VTIME] = 0; // now clean the modem line and activate the settings for modem - rc = tcflush( port_handle, TCIFLUSH ); - rc = tcsetattr( port_handle, TCSANOW, &tio ); //##+++++++++ check rc ? + if ( tcflush( port_handle, TCIFLUSH ) < 0 ) + return mbg_get_last_error( "tcflush failed in mbgserio_set_parms" ); - fflush( stdout ); - setvbuf( stdout, NULL, _IONBF, 0 ); + if ( tcsetattr( port_handle, TCSANOW, &tio ) < 0 ) + return mbg_get_last_error( "tcsetattr failed in mbgserio_set_parms" ); } #elif defined( MBG_TGT_DOS ) #if defined( _USE_V24TOOLS ) @@ -1161,12 +1330,11 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, break; default: - rc = MBG_ERR_INV_PARM; // invalid framing string - goto out; + return MBG_ERR_INV_PARM; // invalid framing string } } - v24setparams( port_handle, baud_rate, datab, parity, stopb ); //##++++++++++++++ check rc? + v24setparams( port_handle, baud_rate, datab, parity, stopb ); //### TODO check rc? } #else @@ -1182,7 +1350,6 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, rc = MBG_SUCCESS; -out: return rc; } // mbgserio_set_parms @@ -1190,11 +1357,11 @@ out: /*HDR*/ -_NO_MBG_API_ATTR int _MBG_API mbgserio_read( MBG_PORT_HANDLE h, void *buffer, unsigned int count ) +_NO_MBG_API_ATTR int _MBG_API mbgserio_read( MBGSERIO_DEV *mdev, void *buffer, unsigned int count ) { #if defined( MBG_TGT_CVI ) - return ComRd( h, (char *) buffer, count ); + return ComRd( mdev->port_handle, (char *) buffer, count ); //### TODO check return code #elif defined( MBG_TGT_WIN32 ) @@ -1203,7 +1370,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_read( MBG_PORT_HANDLE h, void *buffer, un DWORD dwErrorFlags; DWORD dwLength; - ClearCommError( h, &dwErrorFlags, &ComStat ); + ClearCommError( mdev->port_handle, &dwErrorFlags, &ComStat ); if ( dwErrorFlags ) // transmission error (parity, framing, etc.) return MBG_ERR_IO; //##+++++++++++++++++++++++++ @@ -1213,21 +1380,31 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_read( MBG_PORT_HANDLE h, void *buffer, un if ( dwLength ) { - fReadStat = ReadFile( h, buffer, dwLength, &dwLength, NULL ); + fReadStat = ReadFile( mdev->port_handle, buffer, dwLength, &dwLength, NULL ); if ( !fReadStat ) - return MBG_ERR_IO; //##++++++++++++++ + return MBG_ERR_IO; //### TODO retrieve and return real error code } return dwLength; #elif defined( MBG_TGT_POSIX ) - return read( h, buffer, count ); + int rc = read( mdev->port_handle, buffer, count ); + + if ( rc < 0 ) // usually -1 in case of error + rc = mbg_get_last_error( "read failed in mbgserio_read" ); + + return rc; #elif defined( MBG_TGT_DOS ) && defined( _USE_V24TOOLS ) - return v24read( h, buffer, count ); + int rc = v24read( mdev->port_handle, buffer, count ); + + if ( rc < 0 ) + rc = MBG_ERR_UNSPEC; + + return rc; #else @@ -1242,11 +1419,11 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_read( MBG_PORT_HANDLE h, void *buffer, un * @return one of the MBG_ERROR_CODES on error, else number of bytes written */ /*HDR*/ -_NO_MBG_API_ATTR int _MBG_API mbgserio_write( MBG_PORT_HANDLE h, const void *buffer, unsigned int count ) +_NO_MBG_API_ATTR int _MBG_API mbgserio_write( MBGSERIO_DEV *mdev, const void *buffer, unsigned int count ) { #if defined( MBG_TGT_CVI ) - return ComWrt( h, (char *) buffer, count ); + return ComWrt( mdev->port_handle, (char *) buffer, count ); //### TODO check return code #elif defined( MBG_TGT_WIN32 ) @@ -1255,6 +1432,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_write( MBG_PORT_HANDLE h, const void *buf DWORD dwErrorFlags; DWORD dwThisBytesWritten; DWORD dwTotalBytesWritten = 0; + MBG_PORT_HANDLE h = mdev->port_handle; while ( dwTotalBytesWritten < (DWORD) count ) { @@ -1295,16 +1473,16 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_write( MBG_PORT_HANDLE h, const void *buf #elif defined( MBG_TGT_POSIX ) - int rc = write( h, buffer, count ); // returns -1 on error, else number of byte written + int rc = write( mdev->port_handle, buffer, count ); // returns -1 on error, else number of byte written if ( rc == -1 ) - return mbg_get_last_error( "write failed in mbgserio_write" ); + rc = mbg_get_last_error( "write failed in mbgserio_write" ); return rc; #elif defined( MBG_TGT_DOS ) && defined( _USE_V24TOOLS ) - return v24write( h, buffer, count ); + return v24write( mdev->port_handle, buffer, count ); //### TODO check return code #else @@ -1317,11 +1495,11 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_write( MBG_PORT_HANDLE h, const void *buf /*HDR*/ -_NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBG_PORT_HANDLE h ) +_NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBGSERIO_DEV *mdev ) { #if defined( MBG_TGT_CVI ) - FlushOutQ( h ); + FlushOutQ( mdev->port_handle ); #elif defined( MBG_TGT_WIN32 ) @@ -1329,7 +1507,7 @@ _NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBG_PORT_HANDLE h ) printf( "Flushing TX buffers ...\n" ); #endif - FlushFileBuffers( h ); + FlushFileBuffers( mdev->port_handle ); #if ( 1 && defined( DEBUG ) ) //##++++++++++++++ { @@ -1338,7 +1516,7 @@ _NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBG_PORT_HANDLE h ) for (;;) { - ClearCommError( h, &dwErrorFlags, &ComStat ); + ClearCommError( mdev->port_handle, &dwErrorFlags, &ComStat ); printf( "ErrFlags: %04X, out queue: %u\n", dwErrorFlags, ComStat.cbOutQue ); @@ -1354,11 +1532,11 @@ _NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBG_PORT_HANDLE h ) #elif defined( MBG_TGT_POSIX ) - tcdrain( h ); + tcdrain( mdev->port_handle ); #elif defined( MBG_TGT_DOS ) && defined( _USE_V24TOOLS ) - v24flush( h, SND ); + v24flush( mdev->port_handle, SND ); #else @@ -1371,22 +1549,21 @@ _NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBG_PORT_HANDLE h ) /*HDR*/ -_NO_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer, - uint count, ulong char_timeout ) +_NO_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBGSERIO_DEV *mdev, void *buffer, + uint count ) { - int n_bytes; + int rc; #if _USE_SELECT_FOR_SERIAL_IO struct timeval tv_char_timeout; fd_set fds; int max_fd; - int rc; - mbg_msec_to_timeval( char_timeout, &tv_char_timeout ); + mbg_msec_to_timeval( mdev->poll_timeout, &tv_char_timeout ); FD_ZERO( &fds ); - FD_SET( h, &fds ); + FD_SET( mdev->port_handle, &fds ); #if defined( MBG_TGT_WIN32 ) // Under Windows an fd is a handle which can't simply @@ -1395,37 +1572,35 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffe // set max_fd to 0. max_fd = 0; #else - max_fd = h; + max_fd = mdev->port_handle; #endif rc = select( max_fd + 1, &fds, NULL, NULL, &tv_char_timeout ); if ( rc < 0 ) // error - goto fail; + return mbg_get_last_error( "select failed in mbgserio_read_wait" ); if ( rc == 0 ) // timeout - goto timeout; + return MBG_ERR_TIMEOUT; // data is available - n_bytes = mbgserio_read( h, buffer, count ); + rc = mbgserio_read( mdev, buffer, count ); #else + MBG_TMO_TIME tmo; - mbg_tmo_set_timeout_ms( &tmo, char_timeout ); + mbg_tmo_set_timeout_ms( &tmo, mdev->poll_timeout ); for (;;) // wait to read one new char { - n_bytes = mbgserio_read( h, buffer, count ); + rc = mbgserio_read( mdev, buffer, count ); - if ( n_bytes > 0 ) // new char(s) received + if ( rc != 0 ) // char(s) received, or error break; - if ( n_bytes < 0 ) // error - goto fail; - if ( mbg_tmo_curr_time_is_after( &tmo ) ) - goto timeout; + return MBG_ERR_TIMEOUT; #if defined( MBG_TGT_POSIX ) usleep( 10 * 1000 ); @@ -1433,13 +1608,7 @@ _NO_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffe } #endif - return n_bytes; - -timeout: - return MBG_ERR_TIMEOUT; - -fail: - return MBG_ERR_IO; + return rc; } // mbgserio_read_wait diff --git a/mbglib/common/mbgserio.h b/mbglib/common/mbgserio.h index 73a96e9..091aa00 100644 --- a/mbglib/common/mbgserio.h +++ b/mbglib/common/mbgserio.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgserio.h 1.7.1.4 2014/03/11 12:26:46Z martin TEST $ + * $Id: mbgserio.h 1.7.1.13 2016/11/23 13:41:37Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,26 @@ * * ----------------------------------------------------------------------- * $Log: mbgserio.h $ - * Revision 1.7.1.4 2014/03/11 12:26:46Z martin + * Revision 1.7.1.13 2016/11/23 13:41:37Z martin + * Defined DEFAULT_SERIAL_DEVICE_NAME_2 as default name + * for a second serial port to be used by specific applications. + * Revision 1.7.1.12 2016/11/15 15:48:16 martin + * Allocate a device control structure when opening a port, + * and free the structure when the port is closed. + * Modified some internal structure fields. + * Updated function prototypes. + * Revision 1.7.1.11 2016/11/08 17:22:47 martin + * Updated function prototypes. + * Revision 1.7.1.10 2015/12/10 16:30:17 martin + * *** empty log message *** + * Revision 1.7.1.9 2015/10/30 11:10:40 martin + * Revision 1.7.1.8 2015/10/06 14:50:49Z martin + * Revision 1.7.1.7 2015/10/06 14:20:02Z martin + * Account for library module chk_tstr renamed to mbg_tstr. + * Revision 1.7.1.6 2015/09/07 10:40:59 martin + * Revision 1.7.1.5 2015/08/27 16:18:49 martin + * Updated function prototypes. + * Revision 1.7.1.4 2014/03/11 12:26:46 martin * Revision 1.7.1.3 2014/03/04 12:08:13 martin * Revision 1.7.1.2 2014/01/08 17:19:42Z martin * MBG_TGT_POSIX @@ -57,8 +76,12 @@ #include <termios.h> #endif -#if _USE_CHK_TSTR - #include <chk_tstr.h> +#if _USE_MBG_TSTR + #include <mbg_tstr.h> +#else + // dummy types to avoid compiler errors + typedef int MBG_TSTR_RCV_FNC; + typedef int MBG_TSTR_RCV_ARG; #endif #if !defined( _USE_SELECT_FOR_SERIAL_IO ) @@ -80,11 +103,17 @@ /* Start of header body */ -#if !defined( DEFAULT_DEV_NAME ) +#if !defined( DEFAULT_SERIAL_DEVICE_NAME ) + // For applications which 2 serial ports we also define + // default names for the second port to be used. #if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_DOS ) - #define DEFAULT_DEV_NAME "COM1" + #define DEFAULT_SERIAL_DEVICE_NAME "COM1" + #define DEFAULT_SERIAL_DEVICE_NAME_2 "COM2" #elif defined( MBG_TGT_LINUX ) - #define DEFAULT_DEV_NAME "/dev/ttyS0" + #define DEFAULT_SERIAL_DEVICE_NAME "/dev/ttyS0" + #define DEFAULT_SERIAL_DEVICE_NAME_2 "/dev/ttyS1" + #else + #error DEFAULT_SERIAL_DEVICE_NAME needs to be defined for this target. #endif #endif @@ -134,19 +163,27 @@ typedef struct _MBG_STR_LIST typedef struct { - MBG_PORT_HANDLE port_handle; // the handle that will be used for the device + MBG_PORT_HANDLE port_handle; ///< the handle that will be used for the device + + ulong poll_timeout; ///< The default timeout when waiting for data #if defined( MBG_TGT_WIN32 ) - DCB old_dcb; - COMMTIMEOUTS old_commtimeouts; - COMMPROP comm_prop; + DCB org_dcb; + int org_dcb_has_been_read; + + COMMTIMEOUTS org_commtimeouts; + int org_commtimeouts_have_been_read; + + COMMPROP comm_prop; ///< configuration settings supported by the driver (r/o) + int comm_prop_have_been_read; #endif #if defined( MBG_TGT_POSIX ) - struct termios old_tio; + struct termios org_tio; ///< saved original port settings + int org_tio_has_been_read; #endif -} SERIAL_IO_STATUS; +} MBGSERIO_DEV; @@ -162,18 +199,28 @@ extern "C" { /* by MAKEHDR, do not remove the comments. */ /** - * @brief + * @brief Close a serial port specified by a ::MBGSERIO_DEV structure + * + * After the port has been closed the buffer which had been allocated + * for the ::MBGSERIO_DEV structure is freed, and the pointer to that + * buffer is set to NULL. + * + * @param[in,out] pp_mdev Address of a pointer to the control structure including the port handle * * @return One of the @ref MBG_RETURN_CODES */ - _NO_MBG_API_ATTR int _MBG_API mbgserio_close( SERIAL_IO_STATUS *pst ) ; + _NO_MBG_API_ATTR int _MBG_API mbgserio_close( MBGSERIO_DEV **pp_mdev ) ; /** - * @brief + * @brief Open a serial port and set up a ::MBGSERIO_DEV structure + * + * @param[in,out] pp_mdev Address of a pointer to a ::MBGSERIO_DEV device control structure + * allocated and set up by this call. Set to NULL on error. + * @param[in] dev_name Device name of the port to be opened. * * @return One of the @ref MBG_RETURN_CODES */ - _NO_MBG_API_ATTR int _MBG_API mbgserio_open( SERIAL_IO_STATUS *pst, const char *dev ) ; + _NO_MBG_API_ATTR int _MBG_API mbgserio_open( MBGSERIO_DEV **pp_mdev, const char *dev_name ) ; _NO_MBG_API_ATTR int _MBG_API mbgserio_setup_port_str_list( MBG_STR_LIST **list, int max_devs ) ; _NO_MBG_API_ATTR void _MBG_API mbgserio_free_str_list( MBG_STR_LIST *list ) ; @@ -182,12 +229,12 @@ extern "C" { * * @return One of the @ref MBG_RETURN_CODES */ - _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( SERIAL_IO_STATUS *pst, uint32_t baud_rate, const char *framing ) ; + _NO_MBG_API_ATTR int _MBG_API mbgserio_set_parms( MBGSERIO_DEV *mdev, uint32_t baud_rate, const char *framing ) ; - _NO_MBG_API_ATTR int _MBG_API mbgserio_read( MBG_PORT_HANDLE h, void *buffer, unsigned int count ) ; - _NO_MBG_API_ATTR int _MBG_API mbgserio_write( MBG_PORT_HANDLE h, const void *buffer, unsigned int count ) ; - _NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBG_PORT_HANDLE h ) ; - _NO_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBG_PORT_HANDLE h, void *buffer, uint count, ulong char_timeout ) ; + _NO_MBG_API_ATTR int _MBG_API mbgserio_read( MBGSERIO_DEV *mdev, void *buffer, unsigned int count ) ; + _NO_MBG_API_ATTR int _MBG_API mbgserio_write( MBGSERIO_DEV *mdev, const void *buffer, unsigned int count ) ; + _NO_MBG_API_ATTR void _MBG_API mbgserio_flush_tx( MBGSERIO_DEV *mdev ) ; + _NO_MBG_API_ATTR int _MBG_API mbgserio_read_wait( MBGSERIO_DEV *mdev, void *buffer, uint count ) ; /* ----- function prototypes end ----- */ diff --git a/mbglib/common/mbgtime.h b/mbglib/common/mbgtime.h index ebfc8e8..621a035 100644 --- a/mbglib/common/mbgtime.h +++ b/mbglib/common/mbgtime.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: mbgtime.h 1.20.1.1 2014/10/28 08:32:52Z martin TEST $ + * $Id: mbgtime.h 1.23.1.3 2017/03/17 11:33:05Z martin TEST martin $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,20 @@ * * ----------------------------------------------------------------------- * $Log: mbgtime.h $ - * Revision 1.20.1.1 2014/10/28 08:32:52Z martin + * Revision 1.23.1.3 2017/03/17 11:33:05Z martin + * *** empty log message *** + * Revision 1.23.1.2 2017/03/17 10:36:41 martin + * *** empty log message *** + * Revision 1.23.1.1 2017/03/16 15:24:46 martin + * Updated preliminary function prototypes. + * Revision 1.23 2017/03/16 12:26:13 martin + * Updated function prototypes. + * Revision 1.22 2017/01/25 13:10:55 gregoire.diehl + * nano_time_64_to_double and double_to_nano_time_64 added + * Revision 1.21 2016/12/15 17:44:59Z martin + * Changed conditions to include time.h. + * Fixed spelling. + * Removed trailing spaces. * Revision 1.20 2014/05/27 08:09:19 martin * Added NTP_SEC_BIAS. * Revision 1.19 2013/05/22 16:47:01 martin @@ -64,10 +77,7 @@ #include <gpsdefs.h> -#if _IS_MBG_FIRMWARE \ - || defined( MBG_TGT_WIN32 ) \ - || defined( MBG_TGT_DOS ) \ - || defined( MBG_TGT_QNX_NTO ) +#if !defined( MBG_TGT_KERNEL ) || defined( MBG_TGT_WIN32 ) #include <time.h> #endif @@ -78,6 +88,7 @@ extern "C" { #ifdef _MBGTIME #define _ext + #define _DO_INIT #else #define _ext extern #endif @@ -122,7 +133,7 @@ extern "C" { // The constant below defines the Windows FILETIME number (100 ns intervals -// since 1601-01-01) for 1970-01-01, which is usually the epoche for the time_t +// since 1601-01-01) for 1970-01-01, which is usually the epoch for the time_t // type used by the standard C library. #if !defined( FILETIME_1970 ) // FILETIME represents a 64 bit number, so we need to defined the @@ -191,6 +202,7 @@ typedef struct clock_t start; clock_t stop; short is_set; + } TIMEOUT; @@ -259,56 +271,56 @@ _ext TM_GPS datum; _ext const char *short_time_fmt -#ifdef _MBGTIME +#ifdef _DO_INIT = "%2i:%02i" #endif ; _ext const char *time_fmt -#ifdef _MBGTIME +#ifdef _DO_INIT = "%2i:%02i:%02i" #endif ; _ext const char *long_time_fmt -#ifdef _MBGTIME +#ifdef _DO_INIT = "%2i:%02i:%02i.%02i" #endif ; _ext const char *date_fmt -#ifdef _MBGTIME +#ifdef _DO_INIT = "%2i.%02i.%04i" #endif ; _ext const char *day_date_fmt -#ifdef _MBGTIME +#ifdef _DO_INIT = "%s, %2i.%02i.%04i" #endif ; _ext const char *day_name_eng[] -#ifdef _MBGTIME +#ifdef _DO_INIT = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" } #endif ; _ext const char *day_name_ger[] -#ifdef _MBGTIME +#ifdef _DO_INIT = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" } #endif ; _ext const TM_GPS init_tm -#ifdef _MBGTIME +#ifdef _DO_INIT = { 1980, 1, 1, 0, 0, 0, 0, 0, 0, 0 } #endif ; _ext DAYS_OF_MONTH_TABLE days_of_month -#ifdef _MBGTIME +#ifdef _DO_INIT = DAYS_OF_MONTH_TABLE_INIT #endif ; @@ -333,29 +345,296 @@ _ext DAYS_OF_MONTH_TABLE days_of_month /* This section was generated automatically */ /* by MAKEHDR, do not remove the comments. */ + /** + * @brief Set a timeout object to specified interval + * + * @param[out] t The timeout object + * @param[in] clk The current time, in clock_t ticks + * @param[in] interval The interval until expiration, in clock_t ticks + */ void set_timeout( TIMEOUT *t, clock_t clk, clock_t interval ) ; + + /** + * @brief Stretch a timeout specified in given timeout object + * + * @param[in,out] t The timeout object + * @param[in] interval The interval until expiration, in clock_t ticks + */ void stretch_timeout( TIMEOUT *t, clock_t interval ) ; + + /** + * @brief Check if a timeout object has expired + * + * @param[in] t The timeout object + * @param[in] clk The current time, in clock_t ticks + * + * @return 1 if timeout expired, else 0 + */ bit check_timeout( TIMEOUT *t, clock_t clk ) ; - int err_tm( TM_GPS *tm ) ; + + /** + * @brief Check if a ::TM_GPS structure contains a valid date and time + * + * @param[in] tm The date/time structure to be checked + * + * @return 0 if date/time is valid, else a negative number indicating + * which field was found invalid + */ + int err_tm( const TM_GPS *tm ) ; + + /** + * @brief Set the time in a ::TM_GPS structure to 00:00:00 + * + * FIXME what about the frac and UTC offset fields? + * + * @param[in] tm The date/time structure to be set + * + * @return Pointer to the ::TM_GPS structure that has been passed + */ TM_GPS *clear_time( TM_GPS *tm ) ; + + /** + * @brief Convert second-of-week to day-of-week and time-of-day + * + * @param[in] wsec The second-of-week number to be converted + * @param[out] tm Address of a ::TM_GPS structure which takes the computed results + * + * @return Pointer to the ::TM_GPS structure that has been passed + * + * @see ::tm_to_wsec + */ TM_GPS *wsec_to_tm( long wsec, TM_GPS *tm ) ; - long tm_to_wsec( TM_GPS *tm ) ; + + /** + * @brief Compute second-of-week from day-of-week and time-of-day + * + * @todo Specify input / output ranges + * + * @param[in] tm Address of a ::TM_GPS structure providing day-of-week and time-of-day + * + * @return The computed second-of-week number + * + * @see ::wsec_to_tm + */ + long tm_to_wsec( const TM_GPS *tm ) ; + + /** + * @brief Check if a specific year is a leap year + * + * @param[in] y The full year number + * + * @return != 0 if the year is a leap year, else 0 + */ int is_leap_year( int y ) ; + + /** + * @brief Compute the day-of-year from a given date + * + * @param[in] day The day-of-month + * @param[in] month The month + * @param[in] year The full year number + * + * @return The computed day-of-year + */ int day_of_year( int day, int month, int year ) ; + + /** + * @brief Compute a date from a given year and day-of-year + * + * @param[in] year The full year number + * @param[in] day_num Number of days from the beginning of that year, may be negative + * @param[out] tm Address of a ::TM_GPS structure which takes the computed results + */ void date_of_year ( int year, int day_num, TM_GPS *tm ) ; + + /** + * @brief Compute day-of-week from a given date + * + * @todo Specify range of returned day-of-week. Should we just call n_days()? + * + * @param[in] day The day-of-month + * @param[in] month The month + * @param[in] year The full year number + * + * @return The computed day-of-week + * + * @see ::n_days + */ int day_of_week( int day, int month, int year ) ; + + /** + * @brief FIXME Compute yearday-of-week from a given date + * + * @todo Specify range of returned day-of-week + * + * @param[in] day The day-of-month + * @param[in] month The month + * @param[in] year The full year number + * + * @return The computed day-of-week + */ int days_to_years( long *day_num, int year ) ; + + /** + * @brief Compute number of days after Jan 1, 0000 for a given date + * + * @param[in] mday The day-of-month + * @param[in] month The month + * @param[in] year The full year number + * + * @return The computed number of days + * + * @see ::day_of_week + */ long n_days( ushort mday, ushort month, ushort year ) ; + + /** + * @brief Convert a ::NANO_TIME time to double + * + * @param[in] p Address of a ::NANO_TIME structure to be converted + * + * @return The computed number of seconds with fractions, as double + * + * @see ::double_to_nano_time + */ double nano_time_to_double( const NANO_TIME *p ) ; + + /** + * @brief Setup a ::NANO_TIME structure from a time provided as double + * + * @param[out] p Address of a ::NANO_TIME structure to be set up + * @param[in] d The time to be converted, in seconds with fractions, as double + * + * @see ::nano_time_to_double + */ void double_to_nano_time( NANO_TIME *p, double d ) ; + + /** + * @brief Convert a ::NANO_TIME_64 time to double + * + * @param[in] p Address of a ::NANO_TIME_64 structure to be converted + * + * @return The computed number of seconds with fractions, as double + * + * @see ::double_to_nano_time_64 + */ + double nano_time_64_to_double( const NANO_TIME_64 *p ) ; + + /** + * @brief Setup a ::NANO_TIME_64 structure from a time as double + * + * @param[out] p Address of a ::NANO_TIME_64 structure to be set up + * @param[in] d The time to be converted, in seconds with fractions, as double + * + * @see ::nano_time_64_to_double + */ + void double_to_nano_time_64( NANO_TIME_64 *p, double d ) ; + + /** + * @brief Set up a ::NANO_TIME_64 structure from a string with a time in seconds and fractions + * + * @param[in] s A string with a time in seconds, with fractions separated by decimal point + * @param[out] p Address of a ::NANO_TIME_64 structure to be set up + */ + void str_s_to_nano_time_64( const char *s, NANO_TIME_64 *p ) ; + + /** + * @brief Set up a ::NANO_TIME_64 structure from a string with a time in milliseconds and fractions + * + * @param[in] s A string with a time in milliseconds, with fractions separated by decimal point + * @param[out] p Address of a ::NANO_TIME_64 structure to be set up + */ + void str_ms_to_nano_time_64( const char *s, NANO_TIME_64 *p ) ; + + /** + * @brief Convert a ::NTP_TSTAMP structure to a ::NANO_TIME_64 structure + * + * @param[in] p_nts The ::NTP_TSTAMP structure to be converted + * @param[out] p_nt64 The ::NANO_TIME_64 structure to be filled up + */ + void ntp_tstamp_to_nanotime_64( const NTP_TSTAMP *p_nts, NANO_TIME_64 *p_nt64 ) ; + + /** + * @brief Set up a ::NTP_TSTAMP structure from a hex string with a time in seconds and binary fractions + * + * @param[in] s A string with a time in seconds since epoch 1900-01-01, + * with binary fractions separated by decimal point, + * e.g. 'dc763e43.73bd5a8f' as printed by the ntpq utility + * @param[out] p Address of a ::NANO_TIME_64 structure to be set up + * + * @see ::str_ntp_hex_to_nano_time_64 + */ + void str_ntp_hex_to_ntp_tstamp( const char *s, NTP_TSTAMP *p ) ; + + /** + * @brief Set up a ::NANO_TIME_64 structure from a hex string with a time in seconds and binary fractions + * + * @param[in] s A string with a time in seconds since epoch 1900-01-01, + * with binary fractions separated by decimal point, + * e.g. 'dc763e43.73bd5a8f' as printed by the ntpq utility + * @param[out] p Address of a ::NANO_TIME_64 structure to be set up + * + * @see ::str_ntp_hex_to_ntp_tstamp + */ + void str_ntp_hex_to_nano_time_64( const char *s, NANO_TIME_64 *p ) ; + + /** + * @brief Print time with hours, minutes, seconds to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ int sprint_time( char *s, const TM_GPS *tm ) ; + + /** + * @brief Print time with hours, minutes to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ int sprint_short_time( char *s, TM_GPS *time ) ; + + /** + * @brief Print date to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ int sprint_date( char *s, const TM_GPS *tm ) ; + + /** + * @brief Print day-of-week and date to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ int sprint_day_date( char *s, const TM_GPS *tm ) ; + + /** + * @brief Print day-of-week, date and time to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ int sprint_tm( char *s, const TM_GPS *tm ) ; - void sscan_time( char *s, TM_GPS *tm ) ; + + /** + * @brief Extract a time from a string + * + * @param[in] s A time string in format hh:mm:ss + * @param[out] tm Address of a ::TM_GPS structure which takes the extracted time + */ + void sscan_time( const char *s, TM_GPS *tm ) ; + + /** + * @brief Extract a date from a string + * + * @param[in] s A date string in format dd.mm. or dd.mm.yyyy + * @param[out] tm Address of a ::TM_GPS structure which takes the extracted date + */ void sscan_date( char *s, TM_GPS *tm ) ; + /* ----- function prototypes end ----- */ @@ -363,6 +642,7 @@ _ext DAYS_OF_MONTH_TABLE days_of_month #undef _ext +#undef _DO_INIT #ifdef __cplusplus } diff --git a/mbglib/common/myutil.h b/mbglib/common/myutil.h index 9d41574..7695f95 100644 --- a/mbglib/common/myutil.h +++ b/mbglib/common/myutil.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: myutil.h 1.18 2014/10/20 12:30:38Z martin REL_M $ + * $Id: myutil.h 1.20 2017/03/22 15:09:03Z andre.hartmann TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,11 @@ * * ----------------------------------------------------------------------- * $Log: myutil.h $ - * Revision 1.18 2014/10/20 12:30:38Z martin + * Revision 1.20 2017/03/22 15:09:03Z andre.hartmann + * added macros for lin. interpolation + * Revision 1.19 2017/01/27 12:24:08Z martin + * Moved STRINGIFY() macro to words.h. + * Revision 1.18 2014/10/20 12:30:38 martin * Moved macro _isdigit() to words.h. * Revision 1.17 2014/07/15 06:19:48Z andre * added function _sgn( _x ), returns sign of _x @@ -80,21 +84,6 @@ #endif -// The two macros below can be used to define a constant string on the -// compiler's command line, e.g. like -DVERSION_STRING="v1.0 BETA". -// Source code like -// const char version_string[] = VERSION_STRING; -// may not work for every compiler since the double quotes -// in VERSION_STRING may be removed when the definition is evaluated. -// A proper solution is to use the STRINGIFY() macro below: -// const char version_string[] = STRINGIFY( VERSION_STRING ); -// The XSTRINGIFY() macro is simply a helper macro which should not -// be used alone. -#define STRINGIFY(x) XSTRINGIFY(x) -#define XSTRINGIFY(x) #x - - - #if MBG_TGT_HAS_64BIT_TYPES #define _frac( _x ) ( ( (_x) == 0.0 ) ? 0.0 : ( (_x) - (double) ( (int64_t) (_x) ) ) ) #else @@ -169,10 +158,15 @@ typedef union // Check if the (_i)th bit is set in a mask (_msk) #define _is_supported( _i, _msk ) \ ( ( (_msk) & _idx_bit( _i ) ) != 0 ) - -// return the sign of a number + +// return the sign of a number #define _sgn( _x ) ( ( ( _x ) < 0 ) ? -1 : 1 ) - + + +// macro for linear interpolation y = _m * x + _b between two points ( X1; Y1 ), ( X2; Y2 ) +#define _m( _Y1, _X1, _Y2, _X2 ) ( ( _Y2 -_Y1 ) / ( _X2 -_X1 ) ) +#define _b( _Y1, _X1, _Y2, _X2 ) ( ( ( _Y1 * _X2 ) - ( _Y2 * _X1 ) ) / ( _X2 -_X1 ) ) + /* * The macro below copies a string, taking care not to diff --git a/mbglib/common/pcpsdefs.h b/mbglib/common/pcpsdefs.h index 0c4dcd7..4ae5345 100644 --- a/mbglib/common/pcpsdefs.h +++ b/mbglib/common/pcpsdefs.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: pcpsdefs.h 1.55.1.2 2014/10/17 13:28:29Z martin TEST $ + * $Id: pcpsdefs.h 1.60 2017/03/17 12:00:05Z martin TEST $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,8 +10,20 @@ * * ----------------------------------------------------------------------- * $Log: pcpsdefs.h $ - * Revision 1.55.1.2 2014/10/17 13:28:29Z martin - * Revision 1.55.1.1 2014/10/17 11:36:44 martin + * Revision 1.60 2017/03/17 12:00:05Z martin + * Moved definitions of PCPS_HRT_FRAC_CONVERSION_TYPE, + * PCPS_HRT_BIN_FRAC_SCALE, and PCPS_HRT_FRAC_SCALE_FMT + * to cfg_hlp.h. + * Revision 1.59 2017/01/27 08:11:19 martin + * Fixed macro syntax. + * Revision 1.58 2016/11/08 16:42:52 martin + * New GPS cmd codes PC_GPS_XFEATURE_BUFFER and PC_GPS_TLV_INFO. + * Revision 1.57 2016/11/08 16:40:39 martin + * Doxygen cleanup. + * Revision 1.56 2016/10/26 13:22:41 martin + * Added definitions for GRC181PEX. + * New symbol IRIG_TIME_UNKNOWN_YEAR. + * Removed trailing spaces. * Updated doxygen comments. * Revision 1.55 2014/07/17 10:52:24 martin * Increased safety of firmware builds. @@ -44,7 +56,7 @@ * Support GPIO configuration. * Support PZF180PEX. * Added commands to read CORR_INFO, read/write TR_DISTANCE, - * PCPS_SYNC_PZF status, and associated structures. + * PCPS_SYNC_PZF status, and associated structures. * Added an initializer for a table of GPS command code/names. * Added definitions MBG_PCPS_FMT_STATUS. * Updated some comments. @@ -89,12 +101,12 @@ * Added new REF type PCPS_REF_MSF. * Revision 1.35 2008/01/17 09:18:46Z daniel * Made comments compatible for doxygen parser. - * No sourcecode changes. + * No sourcecode changes. * Revision 1.34 2007/07/17 08:22:47Z martin * Added support for TCR511PEX and GPS170PEX. * Revision 1.33 2007/05/20 21:39:51Z martin * Added support for PEX511. - * Added PCPS_GET_STATUS_PORT cmd code for devices + * Added PCPS_GET_STATUS_PORT cmd code for devices * that do not support a hardware status port. * Revision 1.32 2007/03/29 12:57:32Z martin * Renamed some TZCODE numbers for unique naming conventions. @@ -126,14 +138,14 @@ * Support configuration of on-board frequency synthesizer. * Revision 1.21 2004/11/09 12:55:32Z martin * Redefined interface data types using C99 fixed-size definitions. - * Added workaround macros for some structure sizes because the C166 - * compiler always reports an even structure size even if the structure - * size is in fact odd, which might lead to different sizes in C166 and + * Added workaround macros for some structure sizes because the C166 + * compiler always reports an even structure size even if the structure + * size is in fact odd, which might lead to different sizes in C166 and * other environments. - * Modifications were required in order to be able to configure IRIG + * Modifications were required in order to be able to configure IRIG * settings of cards which provide both IRIG input and output. - * The existing codes have been renamed with .._RX.. and are used to - * configure the IRIG receiver (input). New codes have been defined + * The existing codes have been renamed with .._RX.. and are used to + * configure the IRIG receiver (input). New codes have been defined * used to configure the IRIG transmitter. * Renamed PC_GPS_STAT to PC_GPS_BVAR_STAT. * Use more specific data types than generic types. @@ -151,12 +163,12 @@ * fill level. * Revision 1.16 2003/04/03 10:48:53 martin * Support for PCI510, GPS169PCI, and TCR510PCI. - * New codes PCPS_GET_REF_OFFS, PCPS_SET_REF_OFFS + * New codes PCPS_GET_REF_OFFS, PCPS_SET_REF_OFFS * and related structures. * New codes PCPS_GET_OPT_INFO, PCPS_SET_OPT_SETTINGS * and related structures. * New codes PCPS_GET_IRIG_INFO, PCPS_SET_IRIG_SETTINGS. - * Preliminary PCPS_TZDL structure and cmd codes + * Preliminary PCPS_TZDL structure and cmd codes * to read/write that structure. * Revision 1.15 2002/08/08 13:24:03 MARTIN * Moved definition of ref time sources here. @@ -373,6 +385,7 @@ enum PCPS_REF_TYPES #define PCI_DEV_GPS180PEX ( ( PCPS_REF_GPS << 8 ) | 0x06 ) #define PCI_DEV_GLN180PEX ( ( PCPS_REF_GPS << 8 ) | 0x07 ) #define PCI_DEV_GPS180AMC ( ( PCPS_REF_GPS << 8 ) | 0x08 ) +#define PCI_DEV_GRC181PEX ( ( PCPS_REF_GPS << 8 ) | 0x09 ) #define PCI_DEV_TCR510PCI ( ( PCPS_REF_IRIG << 8 ) | 0x01 ) #define PCI_DEV_TCR167PCI ( ( PCPS_REF_IRIG << 8 ) | 0x02 ) @@ -411,14 +424,16 @@ typedef uint8_t PCPS_STATUS_PORT; ///< see @ref PCPS_STATUS_PORT_BIT_MASKS * @brief Bit masks used with ::PCPS_STATUS_PORT * * The flags ::PCPS_ST_SEC and ::PCPS_ST_MIN are cleared whenever the clock - * is read, so they are not very reliable in multitasking environments. + * is read, so they are not very reliable in multitasking environments + * and thus should be considered deprecated. * - * The ::PCPS_ST_IRQF flag originates from old ISA cards. + * The ::PCPS_ST_IRQF flag was used with old ISA cards to check + * if the device has generated an IRQ. * Some PCI cards also support this, but in case of PCI cards the * associated flag of the PCI interface chip should be checked to see * if a particular card has generated an IRQ on the PC bus. * - * The macro _pcps_ddev_has_gen_irq() cares about this and should be used + * The macro ::_pcps_ddev_has_gen_irq() cares about this and should be used * to determine in a portable way whether a card has generated an IRQ. * * @anchor PCPS_STATUS_PORT_BIT_MASKS @{ */ @@ -462,324 +477,297 @@ typedef uint8_t PCPS_STATUS_PORT; ///< see @ref PCPS_STATUS_PORT_BIT_MASKS * the command code is passed. Every parameter byte has to be supplied * to the board exactly like a command byte. * - * Refer to function pcps_write_data() and the macro _pcps_write_var() + * Refer to function ::pcps_write() and the macro ::_pcps_write_var() * for details. * - * - #PCPS_GIVE_TIME<br> - * Return a PCPS_TIME structure with current date, - * time and status. Supported by all clocks. - * - * - #PCPS_GIVE_TIME_NOCLEAR<br> - * Same as #PCPS_GIVE_TIME but the bits #PCPS_ST_SEC - * and #PCPS_ST_MIN (see pcpsdev.h) of the status - * port are not cleared. - * Supported by all clocks except PC31/PS31 with - * firmware version older than v3.0. - * This is mainly used by the DOS TSR and should - * not be used in other environments. - * - * - #PCPS_GIVE_SYNC_TIME<br> - * Return a ::PCPS_TIME structure with date and time - * of last synchronization of the clock or - * the last time set via the interface. - * _pcps_has_sync_time() checks whether supported. - * - * - #PCPS_GIVE_HR_TIME<br> - * Return a PCPS_HR_TIME structure with current - * date, time and status. This command should be - * used to read the clock with higher resolution. - * _pcps_has_hr_time() checks whether supported. - * - * - #PCPS_GIVE_IRIG_TIME<br> - * Return a PCPS_IRIG_TIME structure with day-of-year, - * time and status as decoded from the IRIG signal. - * _pcps_has_irig_time() checks whether supported. - * - * - #PCPS_SET_TIME<br> - * Set the board date, time and status. This - * command expects sizeof( ::PCPS_STIME ) parameter - * bytes. - * _pcps_can_set_time() checks whether supported. - * - * - #PCPS_SET_EVENT_TIME<br> - * Send a high resolution time stamp to the clock to - * configure a %UTC time when the clock shall generate - * some event. This command expects a PCPS_TIME_STAMP - * parameter. - * _pcps_has_event_time() checks whether supported. - * (requires custom GPS CERN firmware) - * - * - #PCPS_IRQ_NONE<br> - * Disable the board's hardware IRQ<br> - * - #PCPS_IRQ_1_SEC<br> - * Enable hardware IRQs once per second<br> - * - #PCPS_IRQ_1_MIN<br> - * Enable hardware IRQs once per minute<br> - * - #PCPS_IRQ_10_MIN<br> - * Enable hardware IRQs once per 10 minutes<br> - * - #PCPS_IRQ_30_MIN<br> - * Enable hardware IRQs once per 30 minutes<br> - * - * - #PCPS_GET_SERIAL<br> - * #PCPS_SET_SERIAL<br> - * These commands read or set the configuration - * of a clock's serial port COM0. The commands - * expect PCPS_SERIAL_BYTES parameter bytes and - * should be used preferably with the DCF77 - * clocks which have only one COM port. - * _pcps_has_serial() checks whether supported. - * Recent GPS clocks' COM ports should be cfg'd - * using the structures RECEIVER_INFO, PORT_INFO, - * and STR_TYPE_INFO. - * _pcps_has_receiver_info() checks whether - * these are supported. If they are not, then - * the code #PC_GPS_PORT_PARM together with the - * #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA - * commands should be used. - * - * - #PCPS_GET_TZCODE<br> - * #PCPS_SET_TZCODE<br> - * These commands read or set a DCF77 clock's - * time zone code and should be used preferably - * with the newer DCF77 clocks which have limited - * support of different time zones. - * _pcps_has_tzcode() checks whether supported. - * A GPS clock's time zone must be cfg'd using - * the code #PC_GPS_TZDL together with the - * #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA - * commands. - * - * - #PCPS_GET_PCPS_TZDL<br> - * #PCPS_SET_PCPS_TZDL<br> - * These commands read or set a DCF77 clock's - * time zone / daylight saving configuration. - * _pcps_has_pcps_tzdl() checks whether supported. - * A GPS clock's time zone must be cfg'd using - * the code #PC_GPS_TZDL together with the - * #PCPS_READ_GPS_DATA and #PCPS_WRITE_GPS_DATA - * commands. - * - * - #PCPS_GET_REF_OFFS<br> - * #PCPS_SET_REF_OFFS<br> - * These commands can be used to configure the - * reference time offset from %UTC for clocks - * which can't determine the offset automatically, - * e.g. from an IRIG input signal. - * _pcps_has_ref_offs() checks whether supported. - * - * - #PCPS_GET_OPT_INFO<br> - * #PCPS_SET_OPT_SETTINGS<br> - * These commands can be used to configure some - * optional settings, controlled by flags. - * When reading, the clock returns a MBG_OPT_INFO - * structure which contains the supported values, - * plus the current settings. - * When writing, clocks accepts a MBG_OPT_SETTINGS - * structure only which contain the desired settings - * of the supported flags only. - * _pcps_has_opt_flags() checks whether supported. - * - * - #PCPS_GET_IRIG_RX_INFO<br> - * #PCPS_SET_IRIG_RX_SETTINGS<br> - * #PCPS_GET_IRIG_TX_INFO<br> - * #PCPS_SET_IRIG_TX_SETTINGS<br> - * These commands can be used to configure IRIG - * inputs and outputs.<br> - * When reading, the clock returns an IRIG_INFO - * structure which contains the supported values, - * plus the current settings.<br> - * When writing, clocks accepts an IRIG_SETTINGS - * structure only which contain the desired settings - * only. _pcps_is_irig_rx() and _pcps_is_irig_tx() - * check whether supported. - * - * - #PCPS_GET_IRIG_CTRL_BITS<br> - * This command can be used to retrieve the control function - * bits of the latest IRIG input frame. Those bits may carry - * some well-known information as in the IEEE1344 code, but - * may also contain some customized information, depending on - * the IRIG frame type and the configuration of the IRIG generator. - * So these bits are returned as-is and must be interpreted - * by the application. - * _pcps_has_irig_ctrl_bits() checks whether supported. - * - * - #PCPS_GET_SYNTH<br> - * #PCPS_SET_SYNTH<br> - * #PCPS_GET_SYNTH_STATE<br> + * - ::PCPS_GIVE_TIME<br> + * Return a ::PCPS_TIME structure with current date, + * time and status. Supported by all clocks. + * + * - ::PCPS_GIVE_TIME_NOCLEAR<br> + * Same as ::PCPS_GIVE_TIME but the bits ::PCPS_ST_SEC + * and ::PCPS_ST_MIN of the status port are not cleared. + * Supported by all clocks except PC31/PS31 with + * firmware version older than v3.0. + * This is mainly used by the DOS TSR and should + * not be used in other environments. + * + * - ::PCPS_GIVE_SYNC_TIME<br> + * Return a ::PCPS_TIME structure with date and time + * of last synchronization of the clock or + * the last time set via the interface. + * ::_pcps_has_sync_time() checks whether supported. + * + * - ::PCPS_GIVE_HR_TIME<br> + * Return a ::PCPS_HR_TIME structure with current + * date, time and status. This command should be + * used to read the clock with higher resolution. + * ::_pcps_has_hr_time() checks whether supported. + * + * - ::PCPS_GIVE_IRIG_TIME<br> + * Return a ::PCPS_IRIG_TIME structure with day-of-year, + * time and status as decoded from the IRIG signal. + * ::_pcps_has_irig_time() checks whether supported. + * + * - ::PCPS_SET_TIME<br> + * Set the board date, time and status. This command + * expects sizeof( ::PCPS_STIME ) parameter bytes. + * ::_pcps_can_set_time() checks whether supported. + * + * - ::PCPS_SET_EVENT_TIME<br> + * Send a high resolution time stamp to the clock to + * configure a %UTC time when the clock shall generate + * some event. This command expects a ::PCPS_TIME_STAMP + * parameter. + * ::_pcps_has_event_time() checks whether supported. + * (requires custom GPS CERN firmware) + * + * - ::PCPS_IRQ_NONE<br> + * Disable the card's hardware IRQ<br> + * - ::PCPS_IRQ_1_SEC<br> + * Enable hardware IRQs once per second<br> + * - ::PCPS_IRQ_1_MIN<br> + * Enable hardware IRQs once per minute (deprecated)<br> + * - ::PCPS_IRQ_10_MIN<br> + * Enable hardware IRQs once per 10 minutes (deprecated)<br> + * - ::PCPS_IRQ_30_MIN<br> + * Enable hardware IRQs once per 30 minutes (deprecated)<br> + * + * - ::PCPS_GET_SERIAL<br> + * ::PCPS_SET_SERIAL<br> + * Deprecated. Read or write the configuration of a card's + * serial port COM0 in ::PCPS_SERIAL format. + * ::_pcps_has_serial() checks whether supported. + * Newer cards should be configured using the structures ::RECEIVER_INFO, + * ::PORT_INFO, and STR_TYPE_INFO. + * ::_pcps_has_receiver_info() checks whether these are supported. + * + * - ::PCPS_GET_TZCODE<br> + * ::PCPS_SET_TZCODE<br> + * These commands read or set a DCF77 clock's + * time zone code and should be used preferably + * with older DCF77 receivers which have limited + * support of different time zones. + * ::_pcps_has_tzcode() checks whether supported. + * Most newer devices support the ::TZDL structure which can be + * read or written using ::PC_GPS_TZDL. + * + * - ::PCPS_GET_PCPS_TZDL<br> + * ::PCPS_SET_PCPS_TZDL<br> + * Read or write time zone / daylight saving information + * in ::PCPS_TZDL format. + * ::_pcps_has_pcps_tzdl() checks whether supported. + * + * - ::PCPS_GET_REF_OFFS<br> + * ::PCPS_SET_REF_OFFS<br> + * These commands can be used to configure the + * reference time offset from %UTC for clocks + * which can't determine the offset automatically, + * e.g. from an IRIG input signal. + * ::_pcps_has_ref_offs() checks whether supported. + * + * - ::PCPS_GET_OPT_INFO<br> + * ::PCPS_SET_OPT_SETTINGS<br> + * These commands can be used to configure some + * optional settings, controlled by flags. + * When reading, the clock returns a ::MBG_OPT_INFO + * structure which contains the supported values, + * plus the current settings. + * When writing, clocks accepts a ::MBG_OPT_SETTINGS + * structure only which contain the desired settings + * of the supported flags only. + * ::_pcps_has_opt_flags() checks whether supported. + * + * - ::PCPS_GET_IRIG_RX_INFO<br> + * ::PCPS_SET_IRIG_RX_SETTINGS<br> + * ::PCPS_GET_IRIG_TX_INFO<br> + * ::PCPS_SET_IRIG_TX_SETTINGS<br> + * These commands can be used to configure IRIG + * inputs and outputs.<br> + * When reading, the clock returns an ::IRIG_INFO + * structure which contains the supported values, + * plus the current settings.<br> + * When writing, clocks accepts an ::IRIG_SETTINGS + * structure only which contain the desired settings + * only. ::_pcps_is_irig_rx() and ::_pcps_has_irig_tx() + * check whether supported. + * + * - ::PCPS_GET_IRIG_CTRL_BITS<br> + * This command can be used to retrieve the control function + * bits of the latest IRIG input frame. Those bits may carry + * some well-known information as in the IEEE 1344 code, but + * may also contain some customized information, depending on + * the IRIG frame type and the configuration of the IRIG generator. + * So these bits are returned as-is and must be interpreted + * by the application. + * ::_pcps_has_irig_ctrl_bits() checks whether supported. + * + * - ::PCPS_GET_SYNTH<br> + * ::PCPS_SET_SYNTH<br> + * ::PCPS_GET_SYNTH_STATE<br> * These commands can be used to configure an on-board * frequency synthesizer and query the synthesizer * status. The commands are only supported if the board - * supports the RECEIVER_INFO structure and the flag - * #GPS_HAS_SYNTH is set in the RECEIVER_INFO::features. - * _pcps_has_synth() checks whether supported. - * The structures SYNTH and SYNTH_STATE used with these + * supports the ::RECEIVER_INFO structure and the flag + * #GPS_HAS_SYNTH is set in the ::RECEIVER_INFO::features. + * ::_pcps_has_synth() checks whether supported. + * The structures ::SYNTH and ::SYNTH_STATE used with these * commands are defined in gpsdefs.h. * - * - #PCPS_GIVE_FW_ID_1<br> - * #PCPS_GIVE_FW_ID_2<br> - * Returns the first/second block of PCPS_FIFO_SIZE - * characters of the firmware ID string. These - * commands can be used to check if the board - * responds properly. This is done by the clock - * detection functions. - * - * - #PCPS_GIVE_SERNUM<br> - * Returns PCPS_FIFO_SIZE characters of the - * clock's serial number. - * _pcps_has_sernum() checks whether supported. - * - * - #PCPS_GENERIC_IO<br> - * Generic I/O read and write. Can be used to query - * specific data, e.g. a selected element of an array. - * _pcps_has_generic_io() checks whether supported. - * - * - #PCPS_GET_DEBUG_STATUS<br> - * This command reads a MBG_DEBUG_STATUS structure - * which represents the internal status of the - * IRIG decoder and some additional debug info. - * _pcps_has_debug_status() checks whether supported. - * - * - #PCPS_READ_GPS_DATA<br> - * #PCPS_WRITE_GPS_DATA<br> - * These commands are used by the functions - * pcps_read_gps_data() and pcps_write_gps_data() - * to read or write large data structures to - * Meinberg GPS plug-in clocks. - * _pcps_is_gps() checks whether supported. - * - * - #PCPS_CLR_UCAP_BUFF<br> - * Clear a clock's time capture buffer. - * _pcps_can_clr_ucap_buff() checks whether - * supported. - * - * - #PCPS_GIVE_UCAP_ENTRIES<br> - * Read a PCPS_UCAP_ENTRIES structure which - * reports the max number of entries and the - * currently used number of entries in the - * user capture buffer. - * _pcps_has_ucap() checks whether supported. - * - * - #PCPS_GIVE_UCAP_EVENT<br> - * Read capture events using a PCPS_HR_TIME - * structure. This is faster than reading using the - * GPS command #PC_GPS_UCAP. If no capture event is - * available then the structure is filled with 0s. - * _pcps_has_ucap() checks whether supported. - * - * - #PCPS_GET_CORR_INFO<br> - * Read PZF correlation info using a CORR_INFO - * structure. - * _pcps_has_pzf() checks whether supported. - * - * - #PCPS_GET_TR_DISTANCE<br> - * #PCPS_SET_TR_DISTANCE<br> - * Read or write distance from the RF transmitter. - * This is used to compensate the RF propagation delay - * for PZF receivers. - * _pcps_has_tr_distance() checks whether supported. - * - * - #PCPS_CLR_EVT_LOG<br> - * Clear on-board event log. - * _pcps_has_evt_log() checks whether supported. - * - * - #PCPS_NUM_EVT_LOG_ENTRIES<br> - * Read max number of num event log entries which can - * be saved on the board, and how many entries actually - * have been saved. - * _pcps_has_evt_log() checks whether supported. - * - * - #PCPS_FIRST_EVT_LOG_ENTRY<br> - * - #PCPS_NEXT_EVT_LOG_ENTRY<br> - * Read first (oldest) or next event log entry. - * _pcps_has_evt_log() checks whether supported. - * - * - #PCPS_FORCE_RESET<br> - * Resets the microprocessor on the device. This is - * for special test scenarios only and should not be - * used by standard applications since this may lock up - * the computer. + * - ::PCPS_GIVE_FW_ID_1<br> + * ::PCPS_GIVE_FW_ID_2<br> + * Returns the first/second block of ::PCPS_FIFO_SIZE + * characters of the firmware ID string. These + * commands can be used to check if the board + * responds properly. This is done by the clock + * detection functions. + * + * - ::PCPS_GIVE_SERNUM<br> + * Returns ::PCPS_FIFO_SIZE characters of the + * clock's serial number. + * ::_pcps_has_sernum() checks whether supported. + * + * - ::PCPS_GENERIC_IO<br> + * Generic I/O read and write. Can be used to query + * specific data, e.g. a selected element of an array. + * ::_pcps_has_generic_io() checks whether supported. + * + * - ::PCPS_GET_DEBUG_STATUS<br> + * This command reads an ::MBG_DEBUG_STATUS structure + * which represents the internal status of the + * IRIG decoder and some additional debug info. + * ::_pcps_has_debug_status() checks whether supported. + * + * - ::PCPS_READ_GPS_DATA<br> + * ::PCPS_WRITE_GPS_DATA<br> + * These commands are used by the functions + * ::pcps_read_gps() and ::pcps_write_gps() + * to read or write large data structures to + * Meinberg GPS plug-in clocks. + * ::_pcps_is_gps() checks whether supported. + * + * - ::PCPS_CLR_UCAP_BUFF<br> + * Clear a clock's time capture buffer. + * ::_pcps_can_clr_ucap_buff() checks whether + * supported. + * + * - ::PCPS_GIVE_UCAP_ENTRIES<br> + * Read a ::PCPS_UCAP_ENTRIES structure which + * reports the max number of entries and the + * currently used number of entries in the + * user capture buffer. + * ::_pcps_has_ucap() checks whether supported. + * + * - ::PCPS_GIVE_UCAP_EVENT<br> + * Read capture events using a PCPS_HR_TIME + * structure. This is faster than reading using the + * GPS command ::PC_GPS_UCAP. If no capture event is + * available then the returned structure is all 0. + * ::_pcps_has_ucap() checks whether supported. + * + * - ::PCPS_GET_CORR_INFO<br> + * Read PZF correlation info using a ::CORR_INFO + * structure. + * ::_pcps_has_pzf() checks whether supported. + * + * - ::PCPS_GET_TR_DISTANCE<br> + * ::PCPS_SET_TR_DISTANCE<br> + * Read or write distance from the RF transmitter. + * This is used to compensate the RF propagation delay + * for PZF receivers. + * ::_pcps_has_tr_distance() checks whether supported. + * + * - ::PCPS_CLR_EVT_LOG<br> + * Clear on-board event log. + * ::_pcps_has_evt_log() checks whether supported. + * + * - ::PCPS_NUM_EVT_LOG_ENTRIES<br> + * Read max. number of num event log entries which can + * be saved on the board, and how many entries have currently + * been saved. + * ::_pcps_has_evt_log() checks whether supported. + * + * - ::PCPS_FIRST_EVT_LOG_ENTRY<br> + * ::PCPS_NEXT_EVT_LOG_ENTRY<br> + * Read first (oldest) or next event log entry. + * ::_pcps_has_evt_log() checks whether supported. + * + * - ::PCPS_FORCE_RESET<br> + * Resets the card's hardware. This may lock up the computer + * and thus should only be used by very specific applications. * * @anchor PCPS_CMD_CODES @{ */ -#define PCPS_GIVE_TIME 0x00 ///< (r-) read current time in ::PCPS_TIME format -#define PCPS_GIVE_TIME_NOCLEAR 0x01 ///< (r-) read current time in ::PCPS_TIME format, don't clear sec and min flags -#define PCPS_GIVE_SYNC_TIME 0x02 ///< (r-) read last sync time as ::PCPS_TIME, only if ::_pcps_has_sync_time() -#define PCPS_GIVE_HR_TIME 0x03 ///< (r-) read high res. time as ::PCPS_HR_TIME, only if ::_pcps_has_hr_time() -#define PCPS_GIVE_IRIG_TIME 0x04 ///< (r-) read raw IRIG time as ::PCPS_IRIG_TIME, only if ::_pcps_has_irig_time() +#define PCPS_GIVE_TIME 0x00 ///< (r-) Read current time in ::PCPS_TIME format +#define PCPS_GIVE_TIME_NOCLEAR 0x01 ///< (r-) Read current time in ::PCPS_TIME format, don't clear sec and min flags (deprecated) +#define PCPS_GIVE_SYNC_TIME 0x02 ///< (r-) Read last sync time as ::PCPS_TIME, only if ::_pcps_has_sync_time() +#define PCPS_GIVE_HR_TIME 0x03 ///< (r-) Read high res. time as ::PCPS_HR_TIME, only if ::_pcps_has_hr_time() +#define PCPS_GIVE_IRIG_TIME 0x04 ///< (r-) Read raw IRIG time as ::PCPS_IRIG_TIME, only if ::_pcps_has_irig_time() -#define PCPS_SET_TIME 0x10 ///< (-w) set on-board time, see ::PCPS_STIME -/* on error, return PCPS_ERR_STIME */ +#define PCPS_SET_TIME 0x10 ///< (-w) Set on-board time, see ::PCPS_STIME. Returns ::MBG_ERR_STIME on error. -#define PCPS_SET_EVENT_TIME 0x14 ///< (-w) write event time as ::PCPS_TIME_STAMP, only if ::_pcps_has_event_time() +#define PCPS_SET_EVENT_TIME 0x14 ///< (-w) Write event time as ::PCPS_TIME_STAMP, only if ::_pcps_has_event_time() -#define PCPS_IRQ_NONE 0x20 ///< (-w) disable IRQs -#define PCPS_IRQ_1_SEC 0x21 ///< (-w) enable IRQ per 1 second -#define PCPS_IRQ_1_MIN 0x22 ///< (-w) enable IRQ per 1 minute (deprecated) -#define PCPS_IRQ_10_MIN 0x24 ///< (-w) enable IRQ per 10 minutes (deprecated) -#define PCPS_IRQ_30_MIN 0x28 ///< (-w) enable IRQ per 10 minutes (deprecated) +#define PCPS_IRQ_NONE 0x20 ///< (-w) Disable IRQs +#define PCPS_IRQ_1_SEC 0x21 ///< (-w) Enable IRQ per 1 second +#define PCPS_IRQ_1_MIN 0x22 ///< (-w) Enable IRQ per 1 minute (deprecated) +#define PCPS_IRQ_10_MIN 0x24 ///< (-w) Enable IRQ per 10 minutes (deprecated) +#define PCPS_IRQ_30_MIN 0x28 ///< (-w) Enable IRQ per 10 minutes (deprecated) -#define PCPS_GET_SERIAL 0x30 ///< (r-) read serial settings as ::PCPS_SERIAL, superseded by ::PC_GPS_ALL_PORT_INFO -#define PCPS_SET_SERIAL 0x31 ///< (-w) write serial settings as ::PCPS_SERIAL, superseded by ::PC_GPS_PORT_SETTINGS_IDX -/* on error, return PCPS_ERR_CFG */ +#define PCPS_GET_SERIAL 0x30 ///< (r-) Read serial settings as ::PCPS_SERIAL, deprecated by ::PC_GPS_ALL_PORT_INFO +#define PCPS_SET_SERIAL 0x31 ///< (-w) Write serial settings as ::PCPS_SERIAL, deprecated by ::PC_GPS_PORT_SETTINGS_IDX, returns ::MBG_ERR_CFG on error -#define PCPS_GET_TZCODE 0x32 ///< (r-) read ::PCPS_TZCODE, only if ::_pcps_has_tzcode() -#define PCPS_SET_TZCODE 0x33 ///< (-w) write ::PCPS_TZCODE, only if ::_pcps_has_tzcode() -/* on error, return PCPS_ERR_CFG */ +#define PCPS_GET_TZCODE 0x32 ///< (r-) Read ::PCPS_TZCODE, only if ::_pcps_has_tzcode() +#define PCPS_SET_TZCODE 0x33 ///< (-w) Write ::PCPS_TZCODE, only if ::_pcps_has_tzcode(), returns ::MBG_ERR_CFG on error -#define PCPS_GET_PCPS_TZDL 0x34 ///< (r-) read ::PCPS_TZDL, only if ::_pcps_has_pcps_tzdl() -#define PCPS_SET_PCPS_TZDL 0x35 ///< (-w) write ::PCPS_TZDL, only if ::_pcps_has_pcps_tzdl() -/* on error, return PCPS_ERR_CFG */ +#define PCPS_GET_PCPS_TZDL 0x34 ///< (r-) Read ::PCPS_TZDL, only if ::_pcps_has_pcps_tzdl() +#define PCPS_SET_PCPS_TZDL 0x35 ///< (-w) Write ::PCPS_TZDL, only if ::_pcps_has_pcps_tzdl(), returns ::MBG_ERR_CFG on error -#define PCPS_GET_REF_OFFS 0x36 ///< (r-) read ::MBG_REF_OFFS, only if ::_pcps_has_ref_offs() -#define PCPS_SET_REF_OFFS 0x37 ///< (-w) write ::MBG_REF_OFFS, only if ::_pcps_has_ref_offs() -/* on error, return PCPS_ERR_CFG */ +#define PCPS_GET_REF_OFFS 0x36 ///< (r-) Read ::MBG_REF_OFFS, only if ::_pcps_has_ref_offs() +#define PCPS_SET_REF_OFFS 0x37 ///< (-w) Write ::MBG_REF_OFFS, only if ::_pcps_has_ref_offs(), returns ::MBG_ERR_CFG on error -#define PCPS_GET_OPT_INFO 0x38 ///< (r-) read ::MBG_OPT_INFO, only if ::_pcps_has_opt_flags() -#define PCPS_SET_OPT_SETTINGS 0x39 ///< (-w) write ::MBG_OPT_SETTINGS, only if ::_pcps_has_opt_flags() -/* on error, return PCPS_ERR_CFG */ +#define PCPS_GET_OPT_INFO 0x38 ///< (r-) Read ::MBG_OPT_INFO, only if ::_pcps_has_opt_flags() +#define PCPS_SET_OPT_SETTINGS 0x39 ///< (-w) Write ::MBG_OPT_SETTINGS, only if ::_pcps_has_opt_flags(), returns ::MBG_ERR_CFG on error -#define PCPS_GET_IRIG_RX_INFO 0x3A ///< (r-) read ::IRIG_INFO, only if ::_pcps_is_irig_rx() -#define PCPS_SET_IRIG_RX_SETTINGS 0x3B ///< (-w) write ::IRIG_SETTINGS, only if ::_pcps_is_irig_rx() -/* on error, return PCPS_ERR_CFG */ +#define PCPS_GET_IRIG_RX_INFO 0x3A ///< (r-) Read ::IRIG_INFO, only if ::_pcps_is_irig_rx() +#define PCPS_SET_IRIG_RX_SETTINGS 0x3B ///< (-w) Write ::IRIG_SETTINGS, only if ::_pcps_is_irig_rx(), returns ::MBG_ERR_CFG on error -#define PCPS_GET_IRIG_TX_INFO 0x3C ///< (r-) read ::IRIG_INFO, only if ::_pcps_has_irig_tx() -#define PCPS_SET_IRIG_TX_SETTINGS 0x3D ///< (-w) write ::IRIG_SETTINGS, only if ::_pcps_has_irig_tx() -/* on error, return PCPS_ERR_CFG */ +#define PCPS_GET_IRIG_TX_INFO 0x3C ///< (r-) Read ::IRIG_INFO, only if ::_pcps_has_irig_tx() +#define PCPS_SET_IRIG_TX_SETTINGS 0x3D ///< (-w) Write ::IRIG_SETTINGS, only if ::_pcps_has_irig_tx(), returns ::MBG_ERR_CFG on error -#define PCPS_GET_SYNTH 0x3E ///< (r-) read ::SYNTH, only if ::_pcps_has_synth() -#define PCPS_SET_SYNTH 0x3F ///< (-w) write ::SYNTH, only if ::_pcps_has_synth() -/* on error, return PCPS_ERR_CFG */ +#define PCPS_GET_SYNTH 0x3E ///< (r-) Read ::SYNTH, only if ::_pcps_has_synth() +#define PCPS_SET_SYNTH 0x3F ///< (-w) Write ::SYNTH, only if ::_pcps_has_synth(), returns ::MBG_ERR_CFG on error -#define PCPS_GIVE_FW_ID_1 0x40 ///< (r-) get first ::PCPS_FIFO_SIZE chars of firmware ID -#define PCPS_GIVE_FW_ID_2 0x41 ///< (r-) get last ::PCPS_FIFO_SIZE chars of firmware ID -#define PCPS_GIVE_SERNUM 0x42 ///< (r-) read serial number as ::PCPS_SN_STR, only if _pcps_has_sernum() -#define PCPS_GENERIC_IO 0x43 ///< (rw) see pcps_generic_io() or _mbgdevio_gen_io() -#define PCPS_GET_SYNTH_STATE 0x44 ///< (r-) read ::SYNTH_STATE, only if _pcps_has_synth() -#define PCPS_GET_IRIG_CTRL_BITS 0x45 ///< (r-) read ::MBG_IRIG_CTRL_BITS, only if ::_pcps_has_irig_ctrl_bits() -#define PCPS_GET_RAW_IRIG_DATA 0x46 ///< (r-) read ::MBG_RAW_IRIG_DATA, only if ::_pcps_has_raw_irig_data() +#define PCPS_GIVE_FW_ID_1 0x40 ///< (r-) Read first ::PCPS_FIFO_SIZE chars of firmware ID +#define PCPS_GIVE_FW_ID_2 0x41 ///< (r-) Read last ::PCPS_FIFO_SIZE chars of firmware ID +#define PCPS_GIVE_SERNUM 0x42 ///< (r-) Read serial number as ::PCPS_SN_STR, only if _pcps_has_sernum() +#define PCPS_GENERIC_IO 0x43 ///< (rw) See ::pcps_generic_io() or ::_mbgdevio_gen_io() +#define PCPS_GET_SYNTH_STATE 0x44 ///< (r-) Read ::SYNTH_STATE, only if ::_pcps_has_synth() +#define PCPS_GET_IRIG_CTRL_BITS 0x45 ///< (r-) Read ::MBG_IRIG_CTRL_BITS, only if ::_pcps_has_irig_ctrl_bits() +#define PCPS_GET_RAW_IRIG_DATA 0x46 ///< (r-) Read ::MBG_RAW_IRIG_DATA, only if ::_pcps_has_raw_irig_data() -#define PCPS_GET_STATUS_PORT 0x4B ///< (r-) read ::PCPS_STATUS_PORT -#define PCPS_GET_DEBUG_STATUS 0x4C ///< (r-) read ::MBG_DEBUG_STATUS, only if _pcps_has_debug_status() +#define PCPS_GET_STATUS_PORT 0x4B ///< (r-) Read ::PCPS_STATUS_PORT +#define PCPS_GET_DEBUG_STATUS 0x4C ///< (r-) Read ::MBG_DEBUG_STATUS, only if ::_pcps_has_debug_status() -// Command codes 0x4D, 0x4E, and 0x4F are reserved. +/// @note Command codes 0x4D, 0x4E, and 0x4F are reserved. -#define PCPS_READ_GPS_DATA 0x50 ///< (r-) read large data structure, see ::PC_GPS_CMD_CODES -#define PCPS_WRITE_GPS_DATA 0x51 ///< (-w) write large data structure, see ::PC_GPS_CMD_CODES +#define PCPS_READ_GPS_DATA 0x50 ///< (r-) Read large data structure, see ::PC_GPS_CMD_CODES +#define PCPS_WRITE_GPS_DATA 0x51 ///< (-w) Write large data structure, see ::PC_GPS_CMD_CODES -#define PCPS_CLR_UCAP_BUFF 0x60 ///< (-w) no param., clear on-board capture FIFO, only if ::_pcps_has_ucap() -#define PCPS_GIVE_UCAP_ENTRIES 0x61 ///< (r-) read ::PCPS_UCAP_ENTRIES, only if ::_pcps_has_ucap() -#define PCPS_GIVE_UCAP_EVENT 0x62 ///< (r-) return oldes event as ::PCPS_HR_TIME, only if ::_pcps_has_ucap() +#define PCPS_CLR_UCAP_BUFF 0x60 ///< (-w) No param., clear on-board capture FIFO, only if ::_pcps_has_ucap() +#define PCPS_GIVE_UCAP_ENTRIES 0x61 ///< (r-) Read ::PCPS_UCAP_ENTRIES, only if ::_pcps_has_ucap() +#define PCPS_GIVE_UCAP_EVENT 0x62 ///< (r-) Return oldest event as ::PCPS_HR_TIME, only if ::_pcps_has_ucap() -#define PCPS_GET_CORR_INFO 0x63 ///< (r-) read ::CORR_INFO structure, only if _pcps_has_pzf() -#define PCPS_GET_TR_DISTANCE 0x64 ///< (r-) read ::TR_DISTANCE, only if _pcps_has_tr_distance() -#define PCPS_SET_TR_DISTANCE 0x65 ///< (-w) write ::TR_DISTANCE, only if _pcps_has_tr_distance() +#define PCPS_GET_CORR_INFO 0x63 ///< (r-) Read ::CORR_INFO structure, only if ::_pcps_has_pzf() +#define PCPS_GET_TR_DISTANCE 0x64 ///< (r-) Read ::TR_DISTANCE, only if ::_pcps_has_tr_distance() +#define PCPS_SET_TR_DISTANCE 0x65 ///< (-w) Write ::TR_DISTANCE, only if ::_pcps_has_tr_distance() -#define PCPS_CLR_EVT_LOG 0x66 ///< (-w) write clear on-board event log, only if _pcps_has_evt_log() -#define PCPS_NUM_EVT_LOG_ENTRIES 0x67 ///< (r-) read ::MBG_NUM_EVT_LOG_ENTRIES, only if _pcps_has_evt_log() -#define PCPS_FIRST_EVT_LOG_ENTRY 0x68 ///< (r-) read first (oldest) ::MBG_EVT_LOG_ENTRY, only if _pcps_has_evt_log() -#define PCPS_NEXT_EVT_LOG_ENTRY 0x69 ///< (r-) read next ::MBG_EVT_LOG_ENTRY, only if _pcps_has_evt_log() +#define PCPS_CLR_EVT_LOG 0x66 ///< (-w) Write clear on-board event log, only if ::_pcps_has_evt_log() +#define PCPS_NUM_EVT_LOG_ENTRIES 0x67 ///< (r-) Read ::MBG_NUM_EVT_LOG_ENTRIES, only if ::_pcps_has_evt_log() +#define PCPS_FIRST_EVT_LOG_ENTRY 0x68 ///< (r-) Read first (oldest) ::MBG_EVT_LOG_ENTRY, only if ::_pcps_has_evt_log() +#define PCPS_NEXT_EVT_LOG_ENTRY 0x69 ///< (r-) Read next ::MBG_EVT_LOG_ENTRY, only if ::_pcps_has_evt_log() -#define PCPS_FORCE_RESET 0x80 ///< (-w) no param., reset the device (this can lockup the computer!!) +#define PCPS_FORCE_RESET 0x80 ///< (-w) No param., reset the device (deprecated, this can lock up the computer!!) /// @note Command codes 0xF0 through 0xFF are reserved. @@ -938,52 +926,11 @@ typedef struct } PCPS_TIME_STAMP; #define _mbg_swab_pcps_time_stamp( _p ) \ +do \ { \ _mbg_swab32( &(_p)->sec ); \ _mbg_swab32( &(_p)->frac ); \ -} - - - -// Depending on the target environment define a data type -// which can be used to convert binary fractions without -// range overflow. -#if defined( MBG_TGT_MISSING_64_BIT_TYPES ) - #define PCPS_HRT_FRAC_CONVERSION_TYPE double -#else - #define PCPS_HRT_FRAC_CONVERSION_TYPE int64_t -#endif - -/** - * @brief Constant used to convert ::PCPS_TIME_STAMP::frac values - * - * Max value of ::PCPS_TIME_STAMP::frac + 1, used for scaling - */ -#define PCPS_HRT_BIN_FRAC_SCALE ( (PCPS_HRT_FRAC_CONVERSION_TYPE) 4294967296.0 ) // == 0x100000000 - - -#ifndef PCPS_HRT_FRAC_SCALE - /** - * @brief Scale to be used to print ::PCPS_TIME_STAMP::frac values - * - * The function ::frac_sec_from_bin can be used for the conversion. - * - * @see ::PCPS_HRT_FRAC_SCALE_FMT - */ - #define PCPS_HRT_FRAC_SCALE 10000000UL -#endif - -#ifndef PCPS_HRT_FRAC_SCALE_FMT - /** - * @brief Format specifier used to print ::PCPS_TIME_STAMP::frac values - * - * Used to print values scaled with ::frac_sec_from_bin called - * with ::PCPS_HRT_FRAC_SCALE. - * - * @see ::PCPS_HRT_FRAC_SCALE - */ - #define PCPS_HRT_FRAC_SCALE_FMT "%07lu" -#endif +} while ( 0 ) @@ -1009,10 +956,11 @@ typedef struct } PCPS_TIME_STATUS_X_MASKS; #define _mbg_swab_pcps_time_status_x_masks( _p ) \ +do \ { \ _mbg_swab_pcps_time_status_x( &(_p)->set_mask ); \ _mbg_swab_pcps_time_status_x( &(_p)->clr_mask ); \ -} +} while ( 0 ) @@ -1068,11 +1016,12 @@ typedef struct } PCPS_HR_TIME; #define _mbg_swab_pcps_hr_time( _p ) \ +do \ { \ _mbg_swab_pcps_time_stamp( &(_p)->tstamp ); \ _mbg_swab32( &(_p)->utc_offs ); \ _mbg_swab_pcps_time_status_x( &(_p)->status ); \ -} +} while ( 0 ) /** @@ -1145,9 +1094,9 @@ typedef struct } PCPS_STIME; #ifdef _C166 - // This is a workaround to specify some structure sizes. The C166 compiler - // always reports an even structure size although the structure size may - // be odd due to the number of bytes. This might lead to errors between + // This is a workaround to specify some structure sizes. The C166 compiler + // always reports an even structure size although the structure size may + // be odd due to the number of bytes. This might lead to errors between // the C166 and other build environments. #define sizeof_PCPS_TIME ( sizeof( PCPS_TIME ) - 1 ) #define sizeof_PCPS_STIME ( sizeof( PCPS_STIME ) - 1 ) @@ -1175,29 +1124,42 @@ typedef union * depends on the update interval at which the structure is updated * by the firmeware. I.e., if the raw IRIG time is updated only * once per second, the ::PCPS_IRIG_TIME::frac value can always be 0. + * + * @see @ref group_icode + * @see ::ICODE_RX_CODES */ typedef struct { PCPS_TIME_STATUS_X status; ///< status bits, see @ref PCPS_TIME_STATUS_FLAGS - int16_t offs_utc; ///< [minutes], 0 unless supported by the code format, see ::ICODE_RX_CODES and @ref group_icode + int16_t offs_utc; ///< [minutes], 0 unless supported by the code format, see ::MSK_ICODE_RX_HAS_TZI uint16_t yday; ///< day of year, 1..365/366 uint16_t frac; ///< fractions of seconds, 0.1 ms units - uint8_t sec; ///< seconds, 0..59, or 60 if leap second + uint8_t sec; ///< seconds, 0..59, may be 60 for leap second uint8_t min; ///< minutes, 0..59 uint8_t hour; ///< hours, 0..23 - uint8_t year; ///< 2 digit year number, 0xFF if year not supp. by the time code, see ::ICODE_RX_CODES and @ref group_icode + uint8_t year; ///< 2 digit year number, or ::IRIG_TIME_UNKNOWN_YEAR if year not supported + ///< by the time code, see ::MSK_ICODE_RX_HAS_ANY_SHORT_YEAR PCPS_SIG_VAL signal; ///< signal strength, see @ref PCPS_SIG_VAL_DEFS uint8_t reserved; ///< currently not used, always 0 } PCPS_IRIG_TIME; #define _mbg_swab_pcps_irig_time( _p ) \ +do \ { \ _mbg_swab_pcps_time_status_x( &(_p)->status ); \ _mbg_swab16( &(_p)->offs_utc ); \ _mbg_swab16( &(_p)->yday ); \ _mbg_swab16( &(_p)->frac ); \ -} +} while ( 0 ) + + +/** + * @brief A constant representing a 2 digit unknown IRIG year number + * + * Used with ::PCPS_IRIG_TIME::year + */ +#define IRIG_TIME_UNKNOWN_YEAR 0xFF @@ -1431,9 +1393,10 @@ typedef struct } PCPS_DL_ONOFF; #define _mbg_swab_pcps_dl_onoff( _p ) \ +do \ { \ _mbg_swab16( &(_p)->year_or_wday ); \ -} +} while ( 0 ) /** * @brief A flag indicating if DST changeovers are to be computed automatically @@ -1472,12 +1435,13 @@ typedef struct } PCPS_TZDL; #define _mbg_swab_pcps_tzdl( _p ) \ +do \ { \ _mbg_swab16( &(_p)->offs ); \ _mbg_swab16( &(_p)->offs_dl ); \ _mbg_swab_pcps_dl_onoff( &(_p)->tm_on ); \ _mbg_swab_pcps_dl_onoff( &(_p)->tm_off ); \ -} +} while ( 0 ) @@ -1494,10 +1458,11 @@ typedef struct } PCPS_UCAP_ENTRIES; #define _mbg_swab_pcps_ucap_entries( _p ) \ +do \ { \ _mbg_swab32( &(_p)->used ); \ _mbg_swab32( &(_p)->max ); \ -} +} while ( 0 ) @@ -1591,8 +1556,7 @@ enum PZF_CORR_STATES */ enum PC_GPS_CMD_CODES { - // system data - PC_GPS_TZDL = 0, ///< (r/w) ::TZDL, time zone / daylight saving, only if ::GPS_MODEL_HAS_TZDL + PC_GPS_TZDL, ///< (r/w) ::TZDL, time zone / daylight saving, only if ::GPS_MODEL_HAS_TZDL PC_GPS_SW_REV, ///< (r/-) ::SW_REV, software revision, deprecated by ::PC_GPS_RECEIVER_INFO PC_GPS_BVAR_STAT, ///< (r/-) ::BVAR_STAT, status of buffered variables, only if ::GPS_MODEL_HAS_BVAR_STAT PC_GPS_TIME, ///< (r/w) ::TTM, current time, deprecated by ::PCPS_GIVE_HR_TIME @@ -1600,23 +1564,25 @@ enum PC_GPS_CMD_CODES PC_GPS_POS_LLA, ///< (-/w) ::LLA, current position in geographic coordinates, only if ::GPS_MODEL_HAS_POS_LLA PC_GPS_PORT_PARM, ///< (r/w) ::PORT_PARM, param. of the serial ports, deprecated by ::PC_GPS_ALL_PORT_INFO PC_GPS_ANT_INFO, ///< (r/-) ::ANT_INFO, time diff at sync. after antenna had been disconn., only if ::GPS_MODEL_HAS_ANT_INFO + PC_GPS_UCAP, ///< (r/-) ::TTM, user capture events, deprecated by ::PCPS_GIVE_UCAP_EVENT PC_GPS_ENABLE_FLAGS, ///< (r/w) ::ENABLE_FLAGS, when to enable serial, pulses, and synth, only if ::GPS_MODEL_HAS_ENABLE_FLAGS PC_GPS_STAT_INFO, ///< (r/-) ::GPS_STAT_INFO, satellite info, mode of operation, and DAC info, only if ::GPS_MODEL_HAS_STAT_INFO PC_GPS_CMD, ///< (-/w) ::GPS_CMD, send one of the ::PC_GPS_COMMANDS PC_GPS_IDENT, ///< (r/-) ::IDENT, serial number, deprecated by ::PC_GPS_RECEIVER_INFO PC_GPS_POS, ///< (r/-) ::POS, position ::XYZ, ::LLA, and ::DMS combined, only if ::GPS_MODEL_HAS_POS - PC_GPS_ANT_CABLE_LEN, ///< (r/w) ::ANT_CABLE_LEN, length of antenna cable, only if ::GPS_MODEL_HAS_ANT_CABLE_LENGTH + PC_GPS_ANT_CABLE_LEN, ///< (r/w) ::ANT_CABLE_LEN, length of antenna cable, only if ::GPS_MODEL_HAS_ANT_CABLE_LEN PC_GPS_RECEIVER_INFO, ///< (r/-) ::RECEIVER_INFO, rcvr model info, only if ::PCPS_HAS_RECEIVER_INFO + PC_GPS_ALL_STR_TYPE_INFO, ///< (r/-) n * ::STR_TYPE_INFO_IDX, names and capabilities of all supp. string types, only if ::RECEIVER_INFO::n_str_type > 0 PC_GPS_ALL_PORT_INFO, ///< (r/-) n * ::PORT_INFO_IDX, settings and capabilities of all serial ports, only if ::RECEIVER_INFO::n_com_ports > 0 PC_GPS_PORT_SETTINGS_IDX, ///< (-/w) ::PORT_SETTINGS_IDX, settings for specified serial port, only if ::RECEIVER_INFO::n_com_ports > 0 - PC_GPS_ALL_POUT_INFO, ///< (r/-) n * ::POUT_INFO_IDX, all programmable output info PC_GPS_POUT_SETTINGS_IDX, ///< (-/w) ::POUT_SETTINGS_IDX, settings for one programmable output PC_GPS_TIME_SCALE, ///< (r/w) ::MBG_TIME_SCALE_SETTINGS / ::MBG_TIME_SCALE_INFO, only if ::PCPS_HAS_TIME_SCALE PC_GPS_LAN_IF_INFO, ///< (r/-) ::LAN_IF_INFO, LAN interface info, only if ::PCPS_HAS_LAN_INTF PC_GPS_IP4_STATE, ///< (r/-) ::IP4_SETTINGS, LAN interface state, only if ::PCPS_HAS_LAN_INTF + PC_GPS_IP4_SETTINGS, ///< (r/w) ::IP4_SETTINGS, LAN interface configuration, only if ::PCPS_HAS_LAN_INTF PC_GPS_PTP_STATE, ///< (r/-) ::PTP_STATE, only if ::PCPS_HAS_PTP PC_GPS_PTP_CFG, ///< (r/w) ::PTP_CFG_SETTINGS / ::PTP_CFG_INFO, only if ::PCPS_HAS_PTP @@ -1625,6 +1591,7 @@ enum PC_GPS_CMD_CODES PC_GPS_PTP_UC_MASTER_SETTINGS_IDX, ///< (-/w) ::PTP_UC_MASTER_SETTINGS_IDX, only if ::PTP_CFG_MSK_SUPPORT_PTP_UNICAST PC_GPS_GPIO_CFG_LIMITS, ///< (r/-) ::MBG_GPIO_CFG_LIMITS, only if ::GPS_HAS_GPIO PC_GPS_ALL_GPIO_INFO, ///< (r/-) n * ::MBG_GPIO_INFO_IDX, all GPIO info, only if ::GPS_HAS_GPIO + PC_GPS_GPIO_SETTINGS_IDX, ///< (-/w) ::MBG_GPIO_SETTINGS_IDX, settings for a specific port, only if ::GPS_HAS_GPIO PC_GPS_GNSS_MODE, ///< (r/w) ::MBG_GNSS_MODE_INFO / ::MBG_GNSS_MODE_SETTINGS, only if ::PCPS_IS_GNSS PC_GPS_ALL_GNSS_SAT_INFO, ///< (r/-) n * ::GNSS_SAT_INFO_IDX, satellite info, only if ::PCPS_IS_GNSS @@ -1633,7 +1600,10 @@ enum PC_GPS_CMD_CODES PC_GPS_ALL_XMR_INFO, ///< (r/-) n * ::XMULTI_REF_INFO_IDX, where n == ::XMULTI_REF_INSTANCES::n_xmr_settings, only if ::GPS_HAS_XMULTI_REF PC_GPS_ALL_XMR_STATUS, ///< (r/w) n * ::XMULTI_REF_STATUS_IDX, where n == ::XMULTI_REF_INSTANCES::n_xmr_settings, one structure on write, only if ::GPS_HAS_XMULTI_REF PC_GPS_XMR_HOLDOVER_STATUS, ///< (r/-) ::XMR_HOLDOVER_STATUS, only if ::XMRIF_MSK_HOLDOVER_STATUS_SUPP + PC_GPS_ALL_GPIO_STATUS, ///< (r/-) n * ::MBG_GPIO_STATUS_IDX, where n == ::MBG_GPIO_CFG_LIMITS::num_io, only if ::MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP + PC_GPS_XFEATURE_BUFFER, ///< (r/-) ::MBG_XFEATURE_BUFFER, only if ::GPS_HAS_XFEATURE + PC_GPS_TLV_INFO, ///< (r/-) ::MBG_TLV_INFO, only if ::MBG_XFEATURE_TLV_API // GPS data PC_GPS_CFGH = 0x80, ///< (-/-) ::CFGH, SVs' config. and health codes (yet not used) @@ -1697,6 +1667,9 @@ enum PC_GPS_CMD_CODES _mbg_cn_table_entry( PC_GPS_ALL_XMR_STATUS ), \ _mbg_cn_table_entry( PC_GPS_XMR_HOLDOVER_STATUS ), \ _mbg_cn_table_entry( PC_GPS_ALL_GPIO_STATUS ), \ + _mbg_cn_table_entry( PC_GPS_XFEATURE_BUFFER ), \ + _mbg_cn_table_entry( PC_GPS_TLV_INFO ), \ + \ _mbg_cn_table_entry( PC_GPS_CFGH ), \ _mbg_cn_table_entry( PC_GPS_ALM ), \ _mbg_cn_table_entry( PC_GPS_EPH ), \ diff --git a/mbglib/common/str_util.c b/mbglib/common/str_util.c new file mode 100644 index 0000000..484acc0 --- /dev/null +++ b/mbglib/common/str_util.c @@ -0,0 +1,449 @@ + +/************************************************************************** + * + * $Id: str_util.c 1.3 2016/10/24 08:10:04Z thomas-b REL_M martin $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Meinberg Library module providing portable, safe string functions. + * + * ----------------------------------------------------------------------- + * $Log: str_util.c $ + * Revision 1.3 2016/10/24 08:10:04Z thomas-b + * Fixed counter var check in mbg_memcpy_reversed + * Revision 1.2 2016/08/05 12:31:04 martin + * New functions mbg_memcpy() and mbg_memcpy_reversed(). + * Moved string trim functions from cfg_util module here. + * Fixed some compiler warnings. + * Revision 1.1 2015/08/25 15:57:21 martin + * Initial revision. + * + **************************************************************************/ + +#define _STR_UTIL + #include <str_util.h> +#undef _STR_UTIL + +#include <stdio.h> +#include <string.h> + + +#if defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_CVI ) + #define mbg_vsnprintf _vsnprintf +#else + #define mbg_vsnprintf vsnprintf +#endif + + +#if defined( MBG_TGT_DOS ) + +static /*HDR*/ +// Under DOS we use the Borland C/C++ v3.1 compiler by default, which +// doesn't provide a vsnprintf() function, so we use a simple replacement +// here. Since we share most of the source code between several target +// systems we assume that if it our code works properly for other targets +// which really provide a vsnprintf() function then it also works properly +// under DOS. ;-) +int vsnprintf( char *s, size_t max_len, const char *fmt, va_list arg_list ) +{ + (void) max_len; // quiet compiler warning "not used" + + return vsprintf( s, fmt, arg_list ); + +} // vsnprintf + +#endif + + + +/*HDR*/ +/** + * @brief A portable, safe implementation of vsnprintf() + * + * Unfortunately the behaviour of vsnprintf() and thus snprintf() + * differs in detail across various build environments and run time + * libraries. + * + * If the output exceeds the buffer size and thus is truncated then:<br> + * + * - Under Windows a negative value is returned and eventually *no* + * terminating 0 is written to the output buffer, so the output string + * may not be terminated properly. + * + * - Some versions of glibc return the number of bytes that *would* + * have been written to the buffer *if* the buffer would have been + * large enough, instead of the true number of characters that have + * been written to the buffer. + * + * So subsequent calls like + * + * n = snprintf( s, max_len, ... ); + * n += snprintf( &s[n], max_len - n, ... ); + * + * may always work properly, or fail with buffer overruns or stack + * corruption depending on the build environment. + * This wrapper function takes care that strings are always terminated + * properly, and that the returned value always matches the number of + * characters really written to the string buffer, excluding the + * terminating 0 + * + * @note The "size_t" type parameter used to specify the buffer size + * can be larger (e.g. "unsigned long") than the "int" type returned + * by mostly all functions of the printf() family. So if a very large + * buffer is specified, and a large number of characters (more than + * MAXINT) are written to that buffer then how can an "int" type + * return the large number of characters written to the buffer? + * We also try to workaround this here. + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] fmt Format string according to subsequent parameters + * @param[in] ap Variable argument list in va_list format + * + * @return Number of characters written to the output buffer, except the terminating 0 + * + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ +size_t __attribute__( ( format( printf, 3, 0 ) ) ) +vsnprintf_safe( char *s, size_t max_len, const char *fmt, va_list ap ) +{ + if ( s == NULL || max_len == 0 ) + return 0; // nothing to do anyway + + + mbg_vsnprintf( s, max_len, fmt, ap ); + + // Force proper worst-case termination of the output string. + s[max_len - 1] = 0; + + // The return type of strlen() is usually size_t, so + // we can safely return the true length of the string + // written to the buffer. + return strlen( s ); + +} // vsnprintf_safe + + + +/*HDR*/ +/** + * @brief A portable, safe implementation of snprintf() + * + * For a detailed description see ::vsnprintf_safe + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] fmt Format string according to subsequent parameters + * @param[in] ... Variable argument list according to the format string + * + * @return Number of characters written to the output buffer, except the terminating 0 + * + * @see ::vsnprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ +size_t __attribute__( ( format( printf, 3, 4 ) ) ) +snprintf_safe( char *s, size_t max_len, const char * fmt, ... ) +{ + va_list ap; + size_t len; + + va_start( ap, fmt ); + + len = vsnprintf_safe( s, max_len, fmt, ap ); + + va_end( ap ); + + return len; + +} // snprintf_safe + + + +static __mbg_inline +/* (explicitly excluded from doxygen) + * @brief A portable, safe implementation of a copy function + * + * This is the basic function used to implemment ::strncpy_safe and + * ::sn_cpy_safe. This function takes care that the copied string + * is always terminated by 0, but any remaining buffer space + * is *not* filled up with '0' characters. + * + * @param[out] dst Pointer to the output buffer + * @param[in] src Pointer to the input buffer + * @param[in] n Number of characters to copy at most + * @param[in,out] p_i Pointer to a counter variable + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ +void do_str_copy_safe( char *dst, const char *src, size_t n, size_t *p_i ) +{ + *p_i = 0; + + if ( n > 0 ) + { + for (;;) + { + *dst = *src; + + if ( *dst == 0 ) + break; // just copied the terminating 0, done + + if ( --n == 0 ) // no more space left in buffer + { + *dst = 0; // force terminating 0 + break; + } + + (*p_i)++; // count normal characters + src++; + dst++; + } + } + +} // do_str_copy_safe + + + +/*HDR*/ +/** + * @brief A portable, safe implementation of strncpy() + * + * In the original implementation of strncpy(), if the length of the + * string to be copied into the destination buffer exceeds the specified + * buffer length then the string in the output buffer is not 0-terminated. + * + * Our implementation always forces a proper termination by 0, but unlike + * the original implementation of strncpy() it does *not* fill the whole + * remaining buffer space with '0' characters. + * + * @param[out] dst Pointer to the output buffer + * @param[in] src Pointer to the input buffer + * @param[in] max_len Size of the output buffer for 0-terminated string + * + * @return Pointer to the destination buffer + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ +char *strncpy_safe( char *dst, const char *src, size_t max_len ) +{ + size_t i = 0; + + do_str_copy_safe( dst, src, max_len, &i ); + + return dst; + +} // strncpy_safe + + + +/*HDR*/ +/** + * @brief A function to copy a string safely, returning the number of characters copied + * + * This basically works like ::strncpy_safe but instead of a pointer to + * the destination buffer it returns the number of characters copied + * to the destination buffer. + * + * @param[out] dst Pointer to the output buffer + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] src Pointer to the input buffer + * + * @return Number of characters copied to the destination buffer + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_char_safe + */ +size_t sn_cpy_str_safe( char *dst, size_t max_len, const char *src ) +{ + size_t i = 0; + + do_str_copy_safe( dst, src, max_len, &i ); + + return i; + +} // sn_cpy_str_safe + + + +/*HDR*/ +/** + * @brief A function to copy a character safely to a string buffer + * + * This basically works like ::sn_cpy_str_safe but expects a character + * to be copied to the destination buffer. Appends a terminating 0 to + * the string buffer and returns the number of characters copied to + * the destination buffer, usually 0 or 1. + * + * @param[out] dst Pointer to the output buffer + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] c Character to be copied to the destination buffer + * + * @return Number of characters copied to the destination buffer, without the terminating 0 + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + */ +size_t sn_cpy_char_safe( char *dst, size_t max_len, char c ) +{ + size_t i = 0; + char tmp_str[2]; + + tmp_str[0] = c; + tmp_str[1] = 0; + + do_str_copy_safe( dst, tmp_str, max_len, &i ); + + return i; + +} // sn_cpy_char_safe + + + +/*HDR*/ +/** + * @brief Trim whitespace at the end of a string + * + * @param[in,out] s The string to be trimmed + */ +void trim_trailing_whitespace( char *s ) +{ + char *cp; + + // set all trailing spaces to 0 + for ( cp = &s[strlen( s )]; cp > s; ) + { + --cp; + + if ( *cp >= ' ' ) + break; + + *cp = 0; + } + +} // trim_trailing_whitespace + + + +/*HDR*/ +/** + * @brief Trim whitespace at the beginning of a string + * + * @param[in,out] s The string to be trimmed + */ +void trim_leading_whitespace( char *s ) +{ + char *srcp; + char *dstp; + + // Search the first non-space character. + for ( srcp = s; *srcp; srcp++ ) + if ( *srcp > ' ' ) + break; + + // If there are leading spaces then srcp now + // points behind the beginning of the string, + // otherwise there's nothing to do. + if ( srcp > s ) + { + // Copy the remaining string. + dstp = s; + + while ( *srcp ) + *dstp++ = *srcp++; + + *dstp = 0; + } + +} // trim_leading_whitespace + + + +/*HDR*/ +/** + * @brief Trim both leading and trailing whitespace from a string + * + * @param[in,out] s The string to be trimmed + */ +void trim_whitespace( char *s ) +{ + trim_trailing_whitespace( s ); + trim_leading_whitespace( s ); + +} // trim_whitespace + + + +/*HDR*/ +/** + * @brief Copy array of bytes starting at beginning of buffer + * + * Can be used if the destination address is in the same buffer + * in front of the source address. Even though you would expect + * that memcpy() would also work for this properly, we have seen + * cases where it didn't, and only memmove() worked correctly. + * Anyway, we try to avoid the overhead of memmove(). + * + * @param[out] dst Destination address behind the source address + * @param[in] src Source address + * @param[in] n_bytes Number of bytes to copy + * + * @see ::mbg_memcpy_reversed + */ +void mbg_memcpy( void *dst, const void *src, size_t n_bytes ) +{ + uint8_t *dstp = (uint8_t *) dst; + uint8_t *srcp = (uint8_t *) src; + + while ( n_bytes-- ) + *dstp++ = *srcp++; + +} // mbg_memcpy + + + +/*HDR*/ +/** + * @brief Copy an array of bytes in reversed order, starting at end of buffer + * + * Can be used if the destination address is in the same buffer + * behind the source address, so the source address would be + * overwritten by a normal memcpy(). + * + * @param[out] dst Destination address behind the source address + * @param[in] src Source address + * @param[in] n_bytes Number of bytes to copy + * + * @see ::mbg_memcpy + */ +void mbg_memcpy_reversed( void *dst, const void *src, size_t n_bytes ) +{ + if ( n_bytes ) // just to be sure it isn't 0 + { + uint8_t *dstp = ( (uint8_t *) dst ) + n_bytes; + uint8_t *srcp = ( (uint8_t *) src ) + n_bytes; + + while ( n_bytes-- ) + *(--dstp) = *(--srcp); + } + +} // mbg_memcpy_reversed + + + diff --git a/mbglib/common/str_util.h b/mbglib/common/str_util.h new file mode 100644 index 0000000..66ba1d8 --- /dev/null +++ b/mbglib/common/str_util.h @@ -0,0 +1,269 @@ + +/************************************************************************** + * + * $Id: str_util.h 1.3 2016/12/14 16:22:24Z martin TEST $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Definitions and prototypes for str_util.c + * + * ----------------------------------------------------------------------- + * $Log: str_util.h $ + * Revision 1.3 2016/12/14 16:22:24Z martin + * Added macro _sn_cpy_str_safe() to simplify calls. + * Revision 1.2 2016/08/05 12:33:17 martin + * Moved string trim functions from cfg_util module here. + * Added variable str_not_avail. + * Fixed some spelling. + * Updated function prototypes. + * Revision 1.1 2015/08/25 15:57:43 martin + * Initial revision. + * + **************************************************************************/ + +#ifndef _STR_UTIL_H +#define _STR_UTIL_H + +/* Other headers to be included */ + +#include <words.h> // implicitly includes mbg_tgt.h for non-firmware projects + +#include <stdlib.h> +#include <stdarg.h> + + +#ifdef _STR_UTIL + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +#ifdef __cplusplus +extern "C" { +#endif + + +_ext const char *str_not_avail +#ifdef _DO_INIT + = "N/A" +#endif +; + +#define _sn_cpy_str_safe( _dst, _src ) sn_cpy_str_safe( _dst, sizeof( _dst ), _src ) + + +/* function prototypes: */ + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + + /** + * @brief A portable, safe implementation of vsnprintf() + * + * Unfortunately the behaviour of vsnprintf() and thus snprintf() + * differs in detail across various build environments and run time + * libraries. + * + * If the output exceeds the buffer size and thus is truncated then:<br> + * + * - Under Windows a negative value is returned and eventually *no* + * terminating 0 is written to the output buffer, so the output string + * may not be terminated properly. + * + * - Some versions of glibc return the number of bytes that *would* + * have been written to the buffer *if* the buffer would have been + * large enough, instead of the true number of characters that have + * been written to the buffer. + * + * So subsequent calls like + * + * n = snprintf( s, max_len, ... ); + * n += snprintf( &s[n], max_len - n, ... ); + * + * may always work properly, or fail with buffer overruns or stack + * corruption depending on the build environment. + * This wrapper function takes care that strings are always terminated + * properly, and that the returned value always matches the number of + * characters really written to the string buffer, excluding the + * terminating 0 + * + * @note The "size_t" type parameter used to specify the buffer size + * can be larger (e.g. "unsigned long") than the "int" type returned + * by mostly all functions of the printf() family. So if a very large + * buffer is specified, and a large number of characters (more than + * MAXINT) are written to that buffer then how can an "int" type + * return the large number of characters written to the buffer? + * We also try to workaround this here. + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] fmt Format string according to subsequent parameters + * @param[in] ap Variable argument list in va_list format + * + * @return Number of characters written to the output buffer, except the terminating 0 + * + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ + size_t __attribute__( ( format( printf, 3, 0 ) ) ) vsnprintf_safe( char *s, size_t max_len, const char *fmt, va_list ap ) ; + + /** + * @brief A portable, safe implementation of snprintf() + * + * For a detailed description see ::vsnprintf_safe + * + * @param[out] s The string buffer to be filled + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] fmt Format string according to subsequent parameters + * @param[in] ... Variable argument list according to the format string + * + * @return Number of characters written to the output buffer, except the terminating 0 + * + * @see ::vsnprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ + size_t __attribute__( ( format( printf, 3, 4 ) ) ) snprintf_safe( char *s, size_t max_len, const char * fmt, ... ) ; + + /** + * @brief A portable, safe implementation of strncpy() + * + * In the original implementation of strncpy(), if the length of the + * string to be copied into the destination buffer exceeds the specified + * buffer length then the string in the output buffer is not 0-terminated. + * + * Our implementation always forces a proper termination by 0, but unlike + * the original implementation of strncpy() it does *not* fill the whole + * remaining buffer space with '0' characters. + * + * @param[out] dst Pointer to the output buffer + * @param[in] src Pointer to the input buffer + * @param[in] max_len Size of the output buffer for 0-terminated string + * + * @return Pointer to the destination buffer + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ + char *strncpy_safe( char *dst, const char *src, size_t max_len ) ; + + /** + * @brief A function to copy a string safely, returning the number of characters copied + * + * This basically works like ::strncpy_safe but instead of a pointer to + * the destination buffer it returns the number of characters copied + * to the destination buffer. + * + * @param[out] dst Pointer to the output buffer + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] src Pointer to the input buffer + * + * @return Number of characters copied to the destination buffer + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_char_safe + */ + size_t sn_cpy_str_safe( char *dst, size_t max_len, const char *src ) ; + + /** + * @brief A function to copy a character safely to a string buffer + * + * This basically works like ::sn_cpy_str_safe but expects a character + * to be copied to the destination buffer. Appends a terminating 0 to + * the string buffer and returns the number of characters copied to + * the destination buffer, usually 0 or 1. + * + * @param[out] dst Pointer to the output buffer + * @param[in] max_len Size of the output buffer for 0-terminated string + * @param[in] c Character to be copied to the destination buffer + * + * @return Number of characters copied to the destination buffer, without the terminating 0 + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + */ + size_t sn_cpy_char_safe( char *dst, size_t max_len, char c ) ; + + /** + * @brief Trim whitespace at the end of a string + * + * @param[in,out] s The string to be trimmed + */ + void trim_trailing_whitespace( char *s ) ; + + /** + * @brief Trim whitespace at the beginning of a string + * + * @param[in,out] s The string to be trimmed + */ + void trim_leading_whitespace( char *s ) ; + + /** + * @brief Trim both leading and trailing whitespace from a string + * + * @param[in,out] s The string to be trimmed + */ + void trim_whitespace( char *s ) ; + + /** + * @brief Copy array of bytes starting at beginning of buffer + * + * Can be used if the destination address is in the same buffer + * in front of the source address. Even though you would expect + * that memcpy() would also work for this properly, we have seen + * cases where it didn't, and only memmove() worked correctly. + * Anyway, we try to avoid the overhead of memmove(). + * + * @param[out] dst Destination address behind the source address + * @param[in] src Source address + * @param[in] n_bytes Number of bytes to copy + * + * @see ::mbg_memcpy_reversed + */ + void mbg_memcpy( void *dst, const void *src, size_t n_bytes ) ; + + /** + * @brief Copy an array of bytes in reversed order, starting at end of buffer + * + * Can be used if the destination address is in the same buffer + * behind the source address, so the source address would be + * overwritten by a normal memcpy(). + * + * @param[out] dst Destination address behind the source address + * @param[in] src Source address + * @param[in] n_bytes Number of bytes to copy + * + * @see ::mbg_memcpy + */ + void mbg_memcpy_reversed( void *dst, const void *src, size_t n_bytes ) ; + + +/* ----- function prototypes end ----- */ + +#ifdef __cplusplus +} +#endif + + +/* End of header body */ + +#undef _ext +#undef _DO_INIT + +#endif /* _STR_UTIL_H */ diff --git a/mbglib/common/timeutil.c b/mbglib/common/timeutil.c new file mode 100644 index 0000000..1399429 --- /dev/null +++ b/mbglib/common/timeutil.c @@ -0,0 +1,172 @@ + +/************************************************************************** + * + * $Id: timeutil.c 1.1.1.5 2017/04/10 12:37:46Z martin TEST martin.burnicki $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Meinberg Library module for safe time conversion routines. + * + * ----------------------------------------------------------------------- + * $Log: timeutil.c $ + * Revision 1.1.1.5 2017/04/10 12:37:46Z martin + * Fixed some compiler warnings. + * Revision 1.1.1.4 2017/02/06 11:45:57Z martin + * Fixed build under Windows, and implemented mbg_clock_settime(), + * but system time is actually not yet set. + * Revision 1.1.1.3 2016/11/21 15:22:37Z martin + * Revision 1.1.1.2 2016/08/11 15:09:46Z martin + * *** empty log message *** + * Revision 1.1.1.1 2016/08/11 07:54:40 martin + * Fixed build with old Visual Studio. + * Revision 1.1 2016/07/15 14:14:19Z martin + * Initial revision + * + **************************************************************************/ + +#define _TIMEUTIL + #include <timeutil.h> +#undef _TIMEUTIL + +#include <str_util.h> +#include <mbgerror.h> + +#if defined( MBG_TGT_WIN32 ) + #include <stdio.h> +#endif + + + +/*HDR*/ +size_t snprint_gmtime_error( char *s, size_t max_len, int mbg_errno, time_t t, const char *calling_fnc ) +{ + size_t n = snprintf_safe( s, max_len, "gmtime() call failed" ); + + if ( calling_fnc ) + n += snprintf_safe( &s[n], max_len - n, " in %s", calling_fnc ); + + #if defined( _MSC_VER ) && ( _MSC_VER < 1500 ) + //### TODO E.g. in VC6 time_t is only 32 bit anyway. + n += snprintf_safe( &s[n], max_len - n, " for time_t %lu: %s", + (unsigned long) t, mbg_strerror( mbg_errno ) ); + #else + n += snprintf_safe( &s[n], max_len - n, " for time_t %llu: %s", + (unsigned long long) t, mbg_strerror( mbg_errno ) ); + #endif + + return n; + +} // snprint_gmtime_error + + + +#if defined( MBG_TGT_WIN32 ) + +typedef int clockid_t; +#define clockid_t clockid_t + +#define CLOCK_REALTIME ( (clockid_t) 0 ) + +/*HDR*/ +int mbg_clock_gettime( clockid_t clock_id, struct timespec *tp ) +{ + if ( clock_id == CLOCK_REALTIME ) + { + #if defined( TIME_UTC ) // C11 / VS2015+ + int rc = timespec_get( tp, TIME_UTC ); // TODO Check this code + return ( rc == 0 ) ? -1 : 0 // rc == 0 means error + #else + #define EPOCH_HNS 116444736000000000i64 + #define NSEC_PER_SEC 1000000000i64 + FILETIME ft; + unsigned __int64 tmp; + gstaft_fnc( &ft ); + tmp = ( (__int64) ft.dwHighDateTime << 32 ) | ft.dwLowDateTime; + tmp -= EPOCH_HNS; // convert to Unix epoch + tmp *= 100; // convert to nanoseconds + tp->tv_sec = ( tmp / NSEC_PER_SEC ); + tp->tv_nsec = ( tmp % NSEC_PER_SEC ); + return 0; + #endif + } + else + return -1; // TODO this is e.g. in case of CLOCK_MONOTONIC, we could use QPC then. + +} // mbg_clock_gettime + + + +/*HDR*/ +int mbg_clock_settime( clockid_t clock_id, const struct timespec *tp ) +{ + if ( clock_id == CLOCK_REALTIME ) + { +#if 0 // ### TODO FIXME This needs to be implemented. + #if defined( TIME_UTC ) // C11 / VS2015+ + int rc = timespec_get( res, TIME_UTC ); // TODO Check this code + return ( rc == 0 ) ? -1 : 0 // rc == 0 means error + #else + #define EPOCH_HNS 116444736000000000i64 + #define NSEC_PER_SEC 1000000000i64 + FILETIME ft; + unsigned __int64 tmp; + gstaft_fnc( &ft ); + tmp = ( (__int64) ft.dwHighDateTime << 32 ) | ft.dwLowDateTime; + tmp -= EPOCH_HNS; // convert to Unix epoch + tmp *= 100; // convert to nanoseconds + res->tv_sec = ( tmp / NSEC_PER_SEC ); + res->tv_nsec = ( tmp % NSEC_PER_SEC ); + return 0; + #endif +#endif + + return 0; // FIXME this is actually not true + } + else + return -1; // TODO this is e.g. in case of CLOCK_MONOTONIC, we could use QPC then. + +} // mbg_clock_settime + + + +bool force_legacy_gstaft; + + +/*HDR*/ +void check_precise_time_api( void ) +{ + const char *info =""; + GSTAFT_FNC tmp_fnc; + HINSTANCE h = LoadLibrary( "kernel32.dll" ); + + if ( h == NULL ) + { + info = "Precise system time may not be supported; failed to get handle for kernel32.dll."; + goto out; + } + + tmp_fnc = (GSTAFT_FNC) GetProcAddress( h, "GetSystemTimePreciseAsFileTime" ); + + if ( tmp_fnc == NULL ) + { + info = "Precise system time NOT supported"; + goto out; + } + + if ( force_legacy_gstaft ) + { + info = "Precise system time is supported, but legacy function used by request"; + goto out; + } + + gstaft_fnc = tmp_fnc; + info = "Precise system time is supported and used"; + +out: + printf( "%s\n", info ); + +} // check_precise_time_api + +#endif + diff --git a/mbglib/common/timeutil.h b/mbglib/common/timeutil.h new file mode 100644 index 0000000..1edf79e --- /dev/null +++ b/mbglib/common/timeutil.h @@ -0,0 +1,136 @@ + +/************************************************************************** + * + * $Id: timeutil.h 1.2.1.3 2017/04/10 13:30:04Z martin TEST $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Definitions and prototypes for timeutil.c + * + * ----------------------------------------------------------------------- + * $Log: timeutil.h $ + * Revision 1.2.1.3 2017/04/10 13:30:04Z martin + * Fixed some compiler warnings. + * Revision 1.2.1.2 2017/02/06 11:14:13Z martin + * Fixed build under windows. + * Updated function prototypes. + * Revision 1.2.1.1 2016/08/11 15:09:51Z martin + * *** empty log message *** + * Revision 1.2 2016/08/11 13:44:00 martin + * Include stddef.h. + * Revision 1.1 2016/07/15 14:14:20Z martin + * Initial revision + * + **************************************************************************/ + +#ifndef _TIMEUTIL_H +#define _TIMEUTIL_H + +/* Other headers to be included */ + +#include <words.h> // implicitly includes mbg_tgt.h for non-firmware projects +#include <mbgerror.h> + +#include <time.h> +#include <stddef.h> + + +#ifdef _TIMEUTIL + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_DOS ) + +typedef int clockid_t; +#define clockid_t clockid_t + +#define CLOCK_REALTIME ( (clockid_t) 0 ) + +#endif + + + +#if defined( MBG_TGT_WIN32 ) + +#define __const__ const + +/** + * @brief A pointer to a function returning the system time as FILETIME + * + * This can be e.g. the standard Windows API call GetSystemTimeAsFileTime() + * or the GetSystemTimeAsPreciseFileTime() API call introduced with Windows 8. + */ +typedef VOID (WINAPI *GSTAFT_FNC)(LPFILETIME lpSystemTimeAsFileTime); + +_ext GSTAFT_FNC gstaft_fnc +#ifdef _DO_INIT + = GetSystemTimeAsFileTime +#endif +; + +#endif + + +/* function prototypes: */ + +static __mbg_inline +time_t cvt_to_time_t( time_t t ) +{ + // Eventually we can do some epoch check here. + return (time_t) t; + +} // cvt_to_time_t + + + +static __mbg_inline +int mbg_gmtime( struct tm *p_tm, const time_t *p_time ) +{ + struct tm *p_tm_tmp = gmtime( p_time ); + + if ( p_tm_tmp == NULL ) // conversion failed + return mbg_get_last_error( NULL ); + + *p_tm = *p_tm_tmp; + + return MBG_SUCCESS; + +} // mbg_gmtime + + + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + + size_t snprint_gmtime_error( char *s, size_t max_len, int mbg_errno, time_t t, const char *calling_fnc ) ; + int mbg_clock_gettime( clockid_t clock_id, struct timespec *tp ) ; + int mbg_clock_settime( clockid_t clock_id, const struct timespec *tp ) ; + void check_precise_time_api( void ) ; + +/* ----- function prototypes end ----- */ + +#ifdef __cplusplus +} +#endif + + +/* End of header body */ + +#undef _ext +#undef _DO_INIT + +#endif /* _TIMEUTIL_H */ diff --git a/mbglib/common/words.h b/mbglib/common/words.h index fc35469..5fc62d0 100644 --- a/mbglib/common/words.h +++ b/mbglib/common/words.h @@ -1,7 +1,7 @@ /************************************************************************** * - * $Id: words.h 1.34 2014/10/20 12:31:20Z martin REL_M $ + * $Id: words.h 1.39 2017/03/15 10:01:09Z martin REL_M $ * * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany * @@ -10,7 +10,25 @@ * * ----------------------------------------------------------------------- * $Log: words.h $ - * Revision 1.34 2014/10/20 12:31:20Z martin + * Revision 1.39 2017/03/15 10:01:09Z martin + * Added comments how to represent negative numbers in NANO_TIME + * and NANO_TIME_64 structures. + * Added macros _nano_time_zero() and _nano_time_64_zero(). + * Revision 1.38 2017/02/22 11:56:33 martin + * Made MBG_CODE_NAME_TABLE_ENTRY::code signed to + * avoid signed/unsigned warnings with some code tables. + * Revision 1.37 2017/01/27 12:24:35Z martin + * Moved STRINGIFY() macro here. + * Revision 1.36 2017/01/27 08:59:43 martin + * Fixed macro syntax. + * Revision 1.35 2016/08/05 12:17:21 martin + * Moved definitions for NANO_TIME and NANO_TIME_64 here. + * New macro _nano_time_64_negative(). + * Conditionally define _abs64() macro. + * Include <inttypes.h> for Keil ARMCC target. + * Added some conditional debugging code. + * Fixed some spelling. + * Revision 1.34 2014/10/20 12:31:20 martin * Moved macro _isdigit() here. * Revision 1.33 2014/05/27 10:18:35Z martin * Finer control of which types are required for or already @@ -123,6 +141,7 @@ #if defined( __ARMCC_VERSION ) // Keil RealView Compiler for ARM #define __mbg_inline __inline #include <stdint.h> + #include <inttypes.h> #include <stdbool.h> #define MBG_TGT_HAS_EXACT_SIZE_TYPES 1 #else @@ -196,7 +215,7 @@ // The build environment does not support 64 bit types. However, // 64 bit types need to be defined to avoid build errors // if these types are formally used in function prototypes. - // We explicitely use abnormal data types to hopefully + // We explicitly use abnormal data types to hopefully // cause compiler errors in case these types are // unexpectedly used to generate real code for a target // platform which does not support 64 bit types. @@ -225,6 +244,10 @@ #define MBG_TGT_HAS_64BIT_TYPES 1 + #if !defined( MBG_TGT_HAS_ABS64 ) + #define _abs64( _i ) ( (int64_t) ( ( (_i) < 0 ) ? -(_i) : (_i) ) ) + #endif + #endif @@ -277,34 +300,109 @@ #endif -#if !defined( _BIT_DEFINED ) +#if defined( MBG_TGT_MISSING_BOOL_TYPE ) + //#error MBG_TGT_MISSING_BOOL_TYPE is defined + // BDS/Borland C++ Builder 2006 (non-C++ mode) + // Borland C++ Builder 5 (non-C++ mode) + // BC 3.1 + // VC6 + // DDKbuild + // VS2008 +#endif - // We need to implement a "bit" type. Preferably we use "bool" - // to do this, but this is only supported by C++ compilers, and - // by C compilers supporting the C99 standard. +#if defined( __cplusplus ) + //#error __cplusplus is defined +#endif - #if !defined( MBG_TGT_MISSING_BOOL_TYPE ) && \ - ( defined( __cplusplus ) || defined( __bool_true_false_are_defined ) ) +#if defined( __bool_true_false_are_defined ) + //#error __bool_true_false_are_defined is defined + // Keil armcc + // gcc / Linux user space + // clang / FreeBSD user space and kernel +#endif - typedef bool bit; - #define bit bit - #else // C99 types not supported +#if defined( MBG_TGT_MISSING_BOOL_TYPE ) /* from mbg_tgt.h */ \ + || ( !defined( __cplusplus ) /* C++ */ \ + && !defined( __bool_true_false_are_defined ) /* C99 */ \ + && !defined( _LINUX_TYPES_H ) ) - // Falling back to use "int" for "bit". This prevents error - // messages if "bit" is used in function prototypes, but may - // yield unexpected results for code like: - // return (bit) ( val & 0x10 ); - typedef int bit; - #define bit bit + // There's no native support for a "bool" type, so we + // need a substitute. + #if defined( _BIT_DEFINED ) + // A native "bit" type is supported, so we use it for bool. + //#error substituting bit for bool + // C166 + typedef bit bool; + #else + // Fall back to "int". This is just a hack which + // may yield unexpected results with code like: + // return (bool) ( val & 0x10 ); + // A safe way of coding would be: + // return (bool) ( ( val & 0x10 ) != 0 ); + //#error substituting int for bool + // Borland C++ Builder 5 + // BC 3.1 + // VC6 + // DDKbuild + // VS2008 + typedef int bool; #endif + // Eventually provoke a build error if the build + // environment unexpectedly supports "bool" natively. + #define bool bool + #define true 1 + #define false 0 +#else + //#error native bool type supported + // Borland C++ Builder 5 and newer (C++ mode only) + // Keil armcc + // gcc / Linux user space + // gcc / Linux kernel + // clang / FreeBSD user space and kernel +#endif + + +#if !defined( _BIT_DEFINED ) + + // There's no native support for a "bit" type, so we + // need a substitute. The "bool" type would fit best + // and should be fine if it's supported natively. + // + // However, if "bool" has been substituted above + // by "int"then this is just a hack which may yield + // unexpected results with code like: + // return (bit) ( val & 0x10 ); + // A safe way of coding would be: + // return (bit) ( ( val & 0x10 ) != 0 ); + + //#error substituting bool for bit + // Keil armcc + // Borland C++ Builder 5 + // BC 3.1 + // VC6 + // DDKbuild + // VS2008 + // gcc / Linux user space + // gcc / Linux kernel + // clang / FreeBSD user space and kernel + typedef bool bit; + + // Eventually provoke a build error if the build + // environment unexpectedly supports "bit" natively. + #define bit bit + #define _BIT_REDEFINED 1 +#else + //#error native bit type supported + // C166 #endif + #define BYTE_0( _x ) ( (uint8_t ) ( (_x) & 0xFF ) ) #define BYTE_1( _x ) ( (uint8_t ) ( ( ( (uint16_t) (_x) ) >> 8 ) & 0xFF ) ) #define BYTE_2( _x ) ( (uint8_t ) ( ( ( (uint32_t) (_x) ) >> 16 ) & 0xFF ) ) @@ -372,12 +470,36 @@ #endif + +#define _set_array_bit( _n, _byte_array, _max_bytes ) \ +do \ +{ \ + int byte_idx = (_n) >> 3; \ + \ + if ( byte_idx < _max_bytes ) \ + _byte_array[byte_idx] |= ( 1 << ( (_n) & 0x07 ) ); \ + \ +} while ( 0 ) + + +#define _clear_array_bit( _n, _byte_array, _max_bytes ) \ +do \ +{ \ + int byte_idx = (_n) >> 3; \ + \ + if ( byte_idx < _max_bytes ) \ + _byte_array[byte_idx] &= ~( 1 << ( (_n) & 0x07 ) ); \ + \ +} while ( 0 ) + + + #define _isdigit( _c ) ( (_c) >= '0' && (_c) <= '9' ) // A macro function which can safely be used without // side effects as a macro doing nothing. -// This is useful to define debug macros away in +// This is useful to define debug macros away in // release builds, etc. #if !defined( _nop_macro_fnc ) #define _nop_macro_fnc() do {} while (0) @@ -389,8 +511,9 @@ */ typedef struct { - ulong code; + long code; const char *name; + } MBG_CODE_NAME_TABLE_ENTRY; /** @@ -410,6 +533,127 @@ typedef struct #define _mbg_cn_table_end() { 0, NULL } + +/** + * @brief A timestamp with nanosecond resolution + * + * @note If the structure is to represent a negative value then both the + * fields nano_secs and secs have to be set to the negative values. + * Otherwise the sign of the represented number was ambiguous if either + * of the fields was accidentally 0, and only the other field was not 0. + * The macro ::_nano_time_negative should always be used to determine + * if the sign of the represented value is negative, or not. + * + * @note The secs field will roll over on 2038-01-19 03:14:07 + * if used for the number of seconds since 1970-01-01, just like + * 32 bit POSIX time_t. + * + * @see ::_nano_time_negative + * @see ::_nano_time_zero + * @see ::NANO_TIME_64 + */ +typedef struct +{ + // ATTENTION: + // This structure is and has has been used in public API calls for a long time, + // so even though the order of member fields is different than in NANO_TIME_64 + // this must *NOT* be changed, or API compatibility will get lost! + int32_t nano_secs; ///< [nanoseconds] + int32_t secs; ///< [seconds], usually since 1970-01-01 00:00:00 + +} NANO_TIME; + +#define _mbg_swab_nano_time( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->nano_secs ); \ + _mbg_swab32( &(_p)->secs ); \ +} while ( 0 ) + +/** + * Check if the value of the ::NANO_TIME structure _nt is negative + */ +#define _nano_time_negative( _nt ) \ + ( ( (_nt)->secs < 0 ) || ( (_nt)->nano_secs < 0 ) ) + +/** + * Check if the value of the ::NANO_TIME structure _nt is 0 + */ +#define _nano_time_zero( _nt ) \ + ( ( (_nt)->secs == 0 ) && ( (_nt)->nano_secs == 0 ) ) + + + +/** + * @brief A timestamp with nanosecond resolution, but 64 bit size + * + * @note If the structure is to represent a negative value then both the + * fields nano_secs and secs have to be set to the negative values. + * Otherwise the sign of the represented number was ambiguous if either + * of the fields was accidentally 0, and only the other field was not 0. + * The macro ::_nano_time_64_negative should always be used to determine + * if the sign of the represented value is negative, or not. + * + * @see ::_nano_time_64_negative + * @see ::_nano_time_64_zero + * @see ::NANO_TIME + */ +typedef struct +{ + // ATTENTION: + // This structure is and has been used in public API calls for a long time, + // so even though the order of member fields is different than in NANO_TIME + // this must *NOT* be changed, or API compatibility will get lost! + int64_t secs; ///< [seconds], usually since 1970-01-01 00:00:00 + int64_t nano_secs; ///< [nanoseconds] + +} NANO_TIME_64; + +#define _mbg_swab_nano_time_64( _p ) \ +do \ +{ \ + _mbg_swab64( &(_p)->secs ); \ + _mbg_swab64( &(_p)->nano_secs ); \ +} while ( 0 ) + +/** + * Check if the value of the ::NANO_TIME_64 structure _nt is negative + */ +#define _nano_time_64_negative( _nt ) \ + ( ( (_nt)->secs < 0 ) || ( (_nt)->nano_secs < 0 ) ) + +/** + * Check if the value of the ::NANO_TIME_64 structure _nt is 0 + */ +#define _nano_time_64_zero( _nt ) \ + ( ( (_nt)->secs == 0 ) && ( (_nt)->nano_secs == 0 ) ) + + + +/** + * @brief Make a string from a constant definition + * + * This macro can be used e.g. to define a constant string on the + * compiler's command line, e.g. like -DVERSION_STRING="v1.0 BETA". + * Source code like + * @code{.c} + const char version_string[] = VERSION_STRING; + * @endcode + * + * may not work for every compiler since the double quotes + * in VERSION_STRING may be removed when the definition is evaluated. + * A proper solution is to use the STRINGIFY() macro defined here: + * @code{.c} + const char version_string[] = STRINGIFY( VERSION_STRING ); + * @endcode + */ +#define STRINGIFY(x) XSTRINGIFY(x) + +// The XSTRINGIFY() macro is just a helper macro to implement STRINGIFY() +// and should not be used alone. +#define XSTRINGIFY(x) #x + + /* End of header body */ #undef _ext diff --git a/mbglib/common/xdevfeat.c b/mbglib/common/xdevfeat.c new file mode 100644 index 0000000..549dab3 --- /dev/null +++ b/mbglib/common/xdevfeat.c @@ -0,0 +1,1533 @@ + +/************************************************************************** + * + * $Id: xdevfeat.c 1.1.1.28.1.12 2017/03/07 13:45:34Z thomas-b TEST thomas-b $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Meinberg API functions to check extended device features. + * + * See notes near "defgroup xdevfeat_chk_supp_fncs" in xdevfeat.h. + * + * ----------------------------------------------------------------------- + * $Log: xdevfeat.c $ + * Revision 1.1.1.28.1.12 2017/03/07 13:45:34Z thomas-b + * Check receiver info feature instead of builtin feature for ignore lock + * Revision 1.1.1.28.1.11 2017/02/22 11:32:47 martin + * Fixed warnings due to preliminary, unfinished code. + * Revision 1.1.1.28.1.10 2017/02/07 14:24:09 thomas-b + * Added function xdevfeat_has_monitoring, which checks if the extended feature MBG_XFEATURE_MONITORING is set + * Revision 1.1.1.28.1.9 2017/02/07 14:10:36 daniel + * Check license feature types + * Revision 1.1.1.28.1.8 2016/12/06 10:43:37 thomas-b + * Added function xdevfeat_has_sv_info + * Revision 1.1.1.28.1.7 2016/12/01 13:47:49 philipp + * Moved helper function check_byte_array_bit from xdevfeat.c to xtiocomm.c and make it public + * Revision 1.1.1.28.1.6 2016/11/30 16:12:26 thomas-b + * Added function xdevfeat_has_scu_stat + * Revision 1.1.1.28.1.5 2016/11/22 10:33:16 philipp + * Implemented I/O ports + * Revision 1.1.1.28.1.4 2016/11/02 12:16:18 thomas-b + * Fixed documentation + * Revision 1.1.1.28.1.3 2016/11/02 12:08:21 thomas-b + * Added function to check for new MBG_XFEATURE_REQ_TTM + * Revision 1.1.1.28.1.2 2016/11/01 09:34:43 martin + * Doxygen fixes. + * Revision 1.1.1.28.1.1 2016/10/25 08:07:54 martin + * Merged changes from 1.1.1.23.1.x. + * Revision 1.1.1.28 2016/10/20 14:46:04 thomas-b + * Added function to check if XBP is supported + * Revision 1.1.1.27 2016/10/20 10:43:36 thomas-b + * Added function to check if a device is a bus level device + * Revision 1.1.1.26 2016/10/14 11:09:41 thomas-b + * Added function to check MBG_XFEATURE_UCAP_NET + * Revision 1.1.1.25 2016/09/29 14:35:35 thomas-b + * Added function to check reboot feature + * Revision 1.1.1.24 2016/09/29 12:19:59 thomas-b + * Added function to check transactions feature + * Revision 1.1.1.23 2016/07/07 15:04:11 martin + * Renamed functions due to renamed library symbols. + * Revision 1.1.1.22 2016/06/15 10:15:51 thomas-b + * Added functions which check if the user capture feature is supported by a device + * Revision 1.1.1.21 2016/06/14 10:33:23 thomas-b + * Added functions which check if the event log feature is supported by a device + * Revision 1.1.1.20 2016/06/07 07:43:08 philipp + * New function to check for Irig Rx feature + * Revision 1.1.1.19 2016/06/02 10:15:40 philipp + * Renaming all MBG_EXT_REV_INFO related stuff to MBG_EXT_SYS_INFO. + * Revision 1.1.1.18 2016/05/30 08:10:47 thomas-b + * Added functions to check several builtin features + * Revision 1.1.1.17 2016/05/20 09:41:38 thomas-b + * Removed functions which check for a specific IMS card + * Revision 1.1.1.16 2016/05/20 08:50:46 thomas-b + * Added functions xdevfeat_has_time_scale and xdevfeat_has_tzcode + * Revision 1.1.1.15 2016/05/17 06:33:12 philipp + * New function to check whether a device has serial outputs + * Revision 1.1.1.14 2016/05/12 10:41:40 philipp + * New functions to check bpe card and IRIG Tx feature + * Revision 1.1.1.13 2016/05/10 06:15:32 philipp + * New function to check whether a device has programmable pulses + * Revision 1.1.1.12 2016/04/26 06:52:46 thomas-b + * Added functions to check if NET_CFG and LAN_IP4 APIs are supported + * Revision 1.1.1.11 2016/04/22 10:54:01 philipp + * New function to check whether device is LIU + * Revision 1.1.1.10 2016/04/20 13:21:06 thomas-b + * Added function to check if a device supports NTP + * Revision 1.1.1.9 2016/04/20 09:26:03 philipp + * Moved all HPS-PTP related structures to gpspriv.h and removed related extended feature bit from gpsdefs.h. + * Also removed functions from mbgextio and xdevfeat since HPS-PTP handling needs a redesign concerning structures. + * Thus, handle everything explicitly for now! + * -> Redesing this A.S.A.P.!!! + * Revision 1.1.1.8 2016/04/15 08:17:27 philipp + * New feature MBG_XFEATURE_EXT_PTP + * Revision 1.1.1.7 2016/04/13 07:01:22 philipp + * New function to check whether device is HPS + * Revision 1.1.1.6 2016/04/12 13:27:42 philipp + * Several new functions to check for device models and device features + * Revision 1.1.1.5 2016/04/11 13:57:13 thomas-b + * Added function xdevfeat_has_xmulti_ref + * Revision 1.1.1.4 2016/04/07 12:36:37 martin + * New function xdevfeat_has_ext_rev_info(). + * Revision 1.1.1.3 2016/04/04 15:31:25 martin + * New function xdevfeat_is_vsg(). + * Revision 1.1.1.2 2016/03/24 14:08:52 martin + * *** empty log message *** + * Revision 1.1.1.1 2016/03/18 10:48:10 martin + * *** empty log message *** + * Revision 1.1 2016/03/16 14:32:52 martin + * Initial revision. + * + **************************************************************************/ + +#define _XDEVFEAT + #include <xdevfeat.h> +#undef _XDEVFEAT + +#include <mbgerror.h> +#include <xtiocomm.h> + + + +typedef uint32_t BUILTIN_FEATURE_MASK; + + +/** + * @brief Entry for a table to specify model-depending built-in features + */ +typedef struct +{ + /// Model code according to ::RECEIVER_INFO::model_code, see ::GPS_MODEL_CODES + uint16_t model_code; + + /// A combination of @ref GPS_FEATURE_MASKS bit masks specifying the + /// built-in features supported by the specified device model. + BUILTIN_FEATURE_MASK feature_mask; + +} BUILTIN_FEATURE_TABLE_ENTRY; + + +/** + * @brief A static table of builtin features + * + * Used to lookup the builtin features of a particular device model. + */ +static BUILTIN_FEATURE_TABLE_ENTRY builtin_feature_table[] = GPS_MODEL_BUILTIN_FEATURES; + + + +static /*HDR*/ +/** + * @brief Check if a device supports a specific built-in feature or API + * + * Some features or API calls are implicitly supported by particular devices. + * This function uses the ::RECEIVER_INFO::model_code to look up the specific + * device in a table of ::BUILTIN_FEATURE_TABLE_ENTRY entries, and checks if + * the requested feature bits are set for this device model. + * If the model code of the specific device can't be found in the table then + * then ::MBG_ERR_DEV_NOT_SUPP is returned and the source code files probably + * need to be updated to support this device. + * + * @param[in] msk One of the @ref GPS_FEATURE_MASKS bit masks + * @param[in] p_ri A ::RECEIVER_INFO structure read from the device before + * + * @return ::MBG_SUCCESS if all specified mask bits are set in ::RECEIVER_INFO::features, + * ::MBG_ERR_NOT_SUPP_BY_DEV if the bits are not set, and ::MBG_ERR_DEV_NOT_SUPP + * if the model code can't be found in the table. + */ +int check_builtin_feature( BUILTIN_FEATURE_MASK msk, const RECEIVER_INFO *p_ri ) +{ + BUILTIN_FEATURE_TABLE_ENTRY *p; + + //### TODO Implement a kind of cache so we don't have to search the whole + // table if several features of the same device are checked after each other. + + for ( p = builtin_feature_table; p->model_code || p->feature_mask; p++ ) + if ( p->model_code == p_ri->model_code ) + return ( ( p->feature_mask & msk ) == msk ) ? MBG_SUCCESS : MBG_ERR_NOT_SUPP_BY_DEV; + + return MBG_ERR_DEV_NOT_SUPP; + +} // check_builtin_feature + + + +static /*HDR*/ +/** + * @brief Check if a device supports a specific feature or API + * + * This API call checks if a specific feature or API is supported + * according to the ::RECEIVER_INFO::features mask read from the device. + * + * @param[in] msk One of the @ref GPS_FEATURE_MASKS bit masks + * @param[in] p_ri A ::RECEIVER_INFO structure read from the device before + * + * @return ::MBG_SUCCESS if all specified mask bits are set in ::RECEIVER_INFO::features, + * else ::MBG_ERR_NOT_SUPP_BY_DEV + */ +int check_ri_feature( RI_FEATURES msk, const RECEIVER_INFO *p_ri ) +{ + return ( ( p_ri->features & msk ) == msk ) ? MBG_SUCCESS : MBG_ERR_NOT_SUPP_BY_DEV; + +} // check_ri_feature + + + +static /*HDR*/ +/** + * @brief Check if a specific extended feature is supported + * + * This API call checks if a specific extended feature or API is supported + * according to the ::MBG_XFEATURE_BUFFER read from the device. + * + * @param[in] xf_bit One of the ::MBG_XFEATURE_BITS + * @param[in] xv_buf Pointer to a ::MBG_XFEATURE_BUFFER read from the device before + * + * @return ::MBG_SUCCESS if the specified feature bit is set, else ::MBG_ERR_NOT_SUPP_BY_DEV or ::MBG_ERR_RANGE + * + * @see ::check_byte_array_bit + */ +int check_xfeature( int xf_bit, const MBG_XFEATURE_BUFFER *xv_buf ) +{ + return check_byte_array_bit( xf_bit, xv_buf->b, sizeof( xv_buf->b ) ); + +} // check_xfeature + + + +#if defined( _PRELIMINARY_CODE ) //### TODO do we need this? + +static /*HDR*/ +/** + * @brief Check if a specific bit is set in TLV's byte array. + * + * This API call checks if a specific TLV feature is supported according to + * the ::MBG_TLV_INFO read from the device. + * + * @param[in] tlv_feat_bit One of the ::MBG_TLV_FEAT_TYPES + * @param[in] tlv_info Pointer to a ::MBG_TLV_INFO read from the device before + * + * @return ::MBG_SUCCESS if the specified feature bit is set, else ::MBG_ERR_NOT_SUPP_BY_DEV or ::MBG_ERR_RANGE + * + * @see ::check_byte_array_bit + */ +int check_tlv_feat_supp( int tlv_feat_bit, const MBG_TLV_INFO *tlv_info ) +{ + return check_byte_array_bit( tlv_feat_bit, tlv_info->supp_tlv_feat.b, sizeof( tlv_info->supp_tlv_feat.b ) ); + +} // check_tlv_feat_supp + +#endif // defined( _PRELIMINARY_CODE ) + + + +/*HDR*/ +/** + * @brief Check if a device can receive the GPS satellite system + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_is_gps + * @see ::mbg_chk_dev_is_gps + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_gps( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_IS_GPS, &p_xdf->receiver_info ); + +} // xdevfeat_is_gps + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_is_gps; + + + +/*HDR*/ +/** + * @brief Check if a device supports the GNSS API + * + * This is usually supported by devices which can receive signals + * from different satellite systems, e.g. GPS, GLONASS, ... + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_is_gnss + * @see ::mbg_chk_dev_is_gnss + * @see ::MBG_GNSS_TYPES + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_gnss( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_IS_GNSS, &p_xdf->receiver_info ); + +} // xdevfeat_is_gnss + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_is_gnss; + + + +/*HDR*/ +/** + * @brief Check if a device is a time code receiver (IRIG or similar) + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_is_tcr //### TODO + * @see ::mbg_chk_dev_is_tcr //### TODO + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_tcr( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_IS_TCR, &p_xdf->receiver_info ); + +} // xdevfeat_is_tcr + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_is_tcr; + + + +/*HDR*/ +/** + * @brief Check if a device is a DCF77 AM receiver + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_is_dcf //### TODO + * @see ::mbg_chk_dev_is_dcf + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_dcf( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_IS_DCF_AM, &p_xdf->receiver_info ); + +} // xdevfeat_is_dcf_am + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_is_dcf; + + + +/*HDR*/ +/** + * @brief Check if a device can receive DCF77 PZF + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_has_pzf //### TODO + * @see ::mbg_chk_dev_has_pzf + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pzf( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_IS_DCF_PZF, &p_xdf->receiver_info ); + +} // xdevfeat_has_pzf + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_pzf; + + + +/*HDR*/ +/** + * @brief Check if a device is an MSF receiver + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_msf( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_IS_MSF, &p_xdf->receiver_info ); + +} // xdevfeat_is_msf + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_is_msf; + + + +/*HDR*/ +/** + * @brief Check if a device is a JJY receiver + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_jjy( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_IS_JJY, &p_xdf->receiver_info ); + +} // xdevfeat_is_jjy + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_is_jjy; + + + +/*HDR*/ +/** + * @brief Check if a device is a WWVB receiver + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_wwvb( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_IS_WWVB, &p_xdf->receiver_info ); + +} // xdevfeat_is_wwvb + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_is_wwvb; + + + +/*HDR*/ +/** + * @brief Check if a device is a bus level device + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_bus_lvl_dev( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_IS_BUS_LVL_DEV, &p_xdf->receiver_info ); + +} // xdevfeat_is_bus_lvl_dev + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_is_bus_lvl_dev; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ims( const MBG_XDEV_FEATURES *p_xdf ) +{ + if ( mbg_rc_is_success( check_ri_feature( GPS_HAS_IMS, &p_xdf->receiver_info ) ) ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // xdevfeat_has_ims + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_ims; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_gpio( const MBG_XDEV_FEATURES *p_xdf ) +{ + if ( mbg_rc_is_success( check_ri_feature( GPS_HAS_GPIO, &p_xdf->receiver_info ) ) ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // xdevfeat_has_gpio + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_gpio; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_synth( const MBG_XDEV_FEATURES *p_xdf ) +{ + if ( mbg_rc_is_success( check_ri_feature( GPS_HAS_SYNTH, &p_xdf->receiver_info ) ) ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // xdevfeat_has_synth + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_synth; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_prog_pulses( const MBG_XDEV_FEATURES *p_xdf ) +{ + const RECEIVER_INFO *ri = &p_xdf->receiver_info; + + if ( ri->n_prg_out > 0 ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // xdevfeat_has_prog_pulses + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_prog_pulses; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_irig_tx( const MBG_XDEV_FEATURES *p_xdf ) +{ + if ( mbg_rc_is_success( check_ri_feature( GPS_HAS_IRIG_TX, &p_xdf->receiver_info ) ) ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // xdevfeat_has_irig_tx + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_irig_tx; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_irig_rx( const MBG_XDEV_FEATURES *p_xdf ) +{ + if ( mbg_rc_is_success( check_ri_feature( GPS_HAS_IRIG_RX, &p_xdf->receiver_info ) ) ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // xdevfeat_has_irig_rx + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_irig_rx; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_serouts( const MBG_XDEV_FEATURES *p_xdf ) +{ + const RECEIVER_INFO *ri = &p_xdf->receiver_info; + + if ( ri->n_com_ports > 0 ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // xdevfeat_has_serouts + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_serouts; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::BVAR_STAT structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_bvar_stat( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_BVAR_STAT, &p_xdf->receiver_info ); + +} // xdevfeat_has_bvar_stat + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_bvar_stat; + + + +/*HDR*/ +/** + * @brief Check if a device supports reading the position as ::XYZ array + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pos_xyz( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_POS_XYZ, &p_xdf->receiver_info ); + +} // xdevfeat_has_pos_xyz + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_pos_xyz; + + + +/*HDR*/ +/** + * @brief Check if a device supports reading the position as ::LLA array + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pos_lla( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_POS_LLA, &p_xdf->receiver_info ); + +} // xdevfeat_has_pos_lla + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_pos_lla; + + + +/*HDR*/ +/** + * @brief Check if the device supports the builtin feature TIME + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_time_ttm( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_TIME_TTM, &p_xdf->receiver_info ); + +} // xdevfeat_has_time_ttm + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::MBG_TIME_SCALE_INFO structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_time_scale_info + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_time_scale( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_TIME_SCALE, &p_xdf->receiver_info ); + +} // xdevfeat_has_time_scale + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_time_scale; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::TZDL structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_tzdl( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_TZDL, &p_xdf->receiver_info ); + +} // xdevfeat_has_tzdl + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_tzdl; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::TZCODE API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_tzcode( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_TZCODE, &p_xdf->receiver_info ); + +} // xdevfeat_has_tzcode + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_tzcode; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::ANT_INFO structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ant_info( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_ANT_INFO, &p_xdf->receiver_info ); + +} // xdevfeat_has_ant_info + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_ant_info; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::ENABLE_FLAGS structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_enable_flags( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_ENABLE_FLAGS, &p_xdf->receiver_info ); + +} // xdevfeat_has_enable_flags + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_enable_flags; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::STAT_INFO structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_gps_stat_info( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_STAT_INFO, &p_xdf->receiver_info ); + +} // xdevfeat_has_gps_stat_info + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_gps_stat_info; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::ANT_CABLE_LEN structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ant_cable_length( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_ANT_CABLE_LEN, &p_xdf->receiver_info ); + +} // xdevfeat_has_ant_cable_length + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_ant_cable_length; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::IGNORE_LOCK structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_gps_ignore_lock( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_IGNORE_LOCK, &p_xdf->receiver_info ); + +} // xdevfeat_has_gps_ignore_lock + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_gps_ignore_lock; + + + +#if 0 //### TODO + + /*HDR*/ +/** + * @brief Check if a device supports the :: structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_, &p_xdf->receiver_info ); + +} // xdevfeat_has_ + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_; + + + + /*HDR*/ +/** + * @brief Check if a device supports the :: structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_, &p_xdf->receiver_info ); + +} // xdevfeat_has_ + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_; + +#endif // ### + + +/*HDR*/ +/** + * @brief Check if the device supports the SCU_STAT structures + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + * @see @ref group_scu + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_scu_stat( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_SCU_STAT, &p_xdf->receiver_info ); + +} // xdevfeat_has_scu_stat + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_scu_stat; + + +/*HDR*/ +/** + * @brief Check if the device supports the SV_INFO structures + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_sv_info( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_builtin_feature( GPS_MODEL_HAS_SV_INFO, &p_xdf->receiver_info ); + +} // xdevfeat_has_sv_info + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_sv_info; + + +/*HDR*/ +/** + * @brief Check if a timecode receiver provides ::MBG_RAW_IRIG_DATA + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_raw_irig_data + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_raw_irig_data( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_RAW_IRIG_DATA, &p_xdf->receiver_info ); + +} // xdevfeat_has_raw_irig_data + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_raw_irig_data; + + + +/*HDR*/ +/** + * @brief Check if a device supports the old LAN_IP4 API + * + * The LAN_IP4 API provides structures and functions to configure + * parts of the networking of a device and is superseded by the + * NET_CFG API. Some devices combine NET_CFG and LAN_IP4. + * Therefore, ::mbgextio_get_all_net_cfg_info should be used + * preferably to read the network configuration. + * It will translate the old structures into the new ones. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_net_cfg_info + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_lan_ip4( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_LAN_IP4, &p_xdf->receiver_info ); + +} // xdevfeat_has_lan_ip4 + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_lan_ip4; + + + +/*HDR*/ +/** + * @brief Check if a device supports the new NET_CFG API + * + * The NET_CFG API provides structures and functions to configure + * the complete networking part of a device and supersedes the + * LAN_IP4 API. Not all devices support the whole feature set + * of the NET_CFG API or combine NET_CFG and LAN_IP4. + * Therefore, ::mbgextio_get_all_net_cfg_info should be used + * preferably to read the network configuration. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_net_cfg_info + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_net_cfg( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_NET_CFG, &p_xdf->receiver_info ); + +} // xdevfeat_has_net_cfg + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_net_cfg; + + + +/*HDR*/ +/** + * @brief Check if a device supports the PTP API + * + * The PTP API consists of different calls and associated structures + * which * have evolved over time. Not all devices support every call, + * so ::mbgextio_get_all_ptp_cfg_info takes care to check which parts are + * supported and thus should be used preferably to read PTP information. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_ptp_cfg_info + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ptp( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_PTP, &p_xdf->receiver_info ); + +} // xdevfeat_has_ptp + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_ptp; + + +/*HDR*/ +/** + * @brief Check if a device supports the NTP API + * + * The NTP API consists of different calls and associated structures + * which have evolved over time. Not all devices support every call, + * so ::mbgextio_get_all_ntp_cfg_info takes care to check which parts are + * supported and thus should be used preferably to read NTP information. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_ntp_cfg_info + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ntp( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_NTP, &p_xdf->receiver_info ); + +} // xdevfeat_has_ntp + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_ntp; + + + +/*HDR*/ +/** + * @brief Check if a device supports the event log API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_evt_log( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_EVT_LOG, &p_xdf->receiver_info ); + +} // xdevfeat_has_evt_log + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_evt_log; + + +/*HDR*/ +/** + * @brief Check if a device supports the user capture API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ucap( const MBG_XDEV_FEATURES *p_xdf ) +{ + const RECEIVER_INFO *ri = &p_xdf->receiver_info; + + if ( ri->n_ucaps > 0 ) + return MBG_SUCCESS; + + return MBG_ERR_NOT_SUPP_BY_DEV; + +} // xdevfeat_has_ucap + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_ucap; + + +/*HDR*/ +/** + * @brief Check if a device supports the user capture via network feature + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref group_ucap_net + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ucap_net( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_UCAP_NET, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_ucap_net + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_ucap_net; + + + +/*HDR*/ +/** + * @brief Check if a device supports the TLV API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref group_tlv_api + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_tlv_api( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_TLV_API, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_ptp + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_tlv_api; + + + +/*HDR*/ +/** + * @brief Check if a device supports a firmware update via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_xmt_fw_update + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_fw_update( const MBG_XDEV_FEATURES *p_xdf ) +{ +#if defined( _PRELIMINARY_CODE ) + return check_tlv_feat_supp( MBG_TLV_FEAT_TYPE_FW_UPDATE, &p_xdf->tlv_info ); +#else + return MBG_ERR_NOT_SUPP_BY_DEV; +#endif + +} // xdevfeat_supp_tlv_fw_update + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_supp_tlv_fw_update; + + + +/*HDR*/ +/** + * @brief Check if a device supports creating / sending a diagnostics file via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_diag_file( const MBG_XDEV_FEATURES *p_xdf ) +{ +#if defined( _PRELIMINARY_CODE ) + return check_tlv_feat_supp( MBG_TLV_FEAT_TYPE_DIAG_FILE, &p_xdf->tlv_info ); +#else + return MBG_ERR_NOT_SUPP_BY_DEV; +#endif + +} // xdevfeat_supp_tlv_diag_file + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_supp_tlv_diag_file; + + + +/*HDR*/ +/** + * @brief Check if a device supports PTPv2 license infos + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ptpv2_license( const MBG_XDEV_FEATURES *p_xdf ) +{ +#if defined( _PRELIMINARY_CODE ) + return check_tlv_feat_supp( MBG_TLV_FEAT_TYPE_LICENSE_PTPV2_IDX, &p_xdf->tlv_info ); +#else + return MBG_ERR_NOT_SUPP_BY_DEV; +#endif + +} // xdevfeat_supp_tlv_ptpv2_license + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_supp_tlv_ptpv2_license; + + + +/*HDR*/ +/** + * @brief Check if a device supports NTP license infos via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ntp_license( const MBG_XDEV_FEATURES *p_xdf ) +{ +#if defined( _PRELIMINARY_CODE ) + return check_tlv_feat_supp( MBG_TLV_FEAT_TYPE_LICENSE_NTP_IDX, &p_xdf->tlv_info ); +#else + return MBG_ERR_NOT_SUPP_BY_DEV; +#endif + +} // xdevfeat_supp_tlv_ntp_license + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_supp_tlv_ntp_license; + + + +/*HDR*/ +/** + * @brief Check if a device supports PTPv1 License Infos via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ptpv1_license( const MBG_XDEV_FEATURES *p_xdf ) +{ +#if defined( _PRELIMINARY_CODE ) + return check_tlv_feat_supp( MBG_TLV_FEAT_TYPE_LICENSE_PTPV1_IDX, &p_xdf->tlv_info ); +#else + return MBG_ERR_NOT_SUPP_BY_DEV; +#endif + +} // xdevfeat_supp_tlv_ptpv1_license + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_supp_tlv_ptpv1_license; + + + +/*HDR*/ +/** + * @brief Check if a device supports Time Monitor License infos via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_time_monitor_license( const MBG_XDEV_FEATURES *p_xdf ) +{ +#if defined( _PRELIMINARY_CODE ) + return check_tlv_feat_supp( MBG_TLV_FEAT_TYPE_LICENSE_TIME_MONITOR_IDX, &p_xdf->tlv_info ); +#else + return MBG_ERR_NOT_SUPP_BY_DEV; +#endif + +} // xdevfeat_supp_tlv_time_monitor_license + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_supp_tlv_time_monitor_license; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::GPS_SAVE_CFG command + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_cmd_save_cfg + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_cmd_save_cfg( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_SAVE_CFG, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_cmd_save_cfg + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_cmd_save_cfg; + + + +/*HDR*/ +/** + * @brief Check if a device supports the extended feature monitoring + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_monitoring( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_MONITORING, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_monitoring + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_monitoring; + + + +/*HDR*/ +/** + * @brief Check if a device supports the LED API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_led_api( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_LED_API, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_led_api + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_led_api; + + + +/*HDR*/ +/** + * @brief Check if a device supports the LNE API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_lne_api( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_LNE_API, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_lne_api + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_lne_api; + + + +/*HDR*/ +/** + * @brief Check if a device supports the power control API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pwr_ctl_api( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_PWR_CTL_API, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_pwr_ctl_api + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_pwr_ctl_api; + + + +/*HDR*/ +/** + * @brief Check if a device supports the ::MBG_EXT_SYS_INFO command + * + * @param[in,out] p_xdf Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ext_sys_info( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_EXT_SYS_INFO, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_ext_sys_info + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_ext_sys_info; + + + +/*HDR*/ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_io_ports( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_IO_PORTS, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_io_ports + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_io_ports; + + + +/*HDR*/ +/** + * @brief Check if a device has ::MBG_XFEATURE_TRANSACTIONS + * + * @param[in,out] p_xdf Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_transactions( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_TRANSACTIONS, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_transactions + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_transactions; + + + +/*HDR*/ +/** + * @brief Check if a device has ::MBG_XFEATURE_REBOOT + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_reboot( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_REBOOT, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_reboot + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_reboot; + + + +/*HDR*/ +/** + * @brief Check if a device has ::MBG_XFEATURE_REQ_TTM + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + * @see mbgextio_get_time + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_req_ttm( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_xfeature( MBG_XFEATURE_REQ_TTM, &p_xdf->xfeature_buffer ); + +} // xdevfeat_has_req_ttm + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_req_ttm; + + + +/*HDR*/ +/** + * @brief Check if a device supports the extended multi ref features including multi instances + * + * The different multi ref feature and its appropriate flags have evolved over time. + * This function only checks the currently up-to-date GPS_HAS_XMRS_MULT_INSTC flag. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_xmulti_ref_info + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_xmulti_ref( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_XMRS_MULT_INSTC, &p_xdf->receiver_info ); + +} // xdevfeat_has_xmulti_ref + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_xmulti_ref; + + + +/*HDR*/ +/** + * @brief Check if a device supports the extended binary protocol (XBP) feature + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ +_NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_xbp( const MBG_XDEV_FEATURES *p_xdf ) +{ + return check_ri_feature( GPS_HAS_XBP, &p_xdf->receiver_info ); + +} // xdevfeat_has_xbp + +XDEVFEAT_CHK_SUPP_FNC xdevfeat_has_xbp; diff --git a/mbglib/common/xdevfeat.h b/mbglib/common/xdevfeat.h new file mode 100644 index 0000000..7a06d20 --- /dev/null +++ b/mbglib/common/xdevfeat.h @@ -0,0 +1,877 @@ + +/************************************************************************** + * + * $Id: xdevfeat.h 1.1.1.28.1.12 2017/03/07 13:45:34Z thomas-b TEST thomas-b $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Definitions and prototypes for xdevfeat.c. + * + * ----------------------------------------------------------------------- + * $Log: xdevfeat.h $ + * Revision 1.1.1.28.1.12 2017/03/07 13:45:34Z thomas-b + * Check receiver info feature instead of builtin feature for ignore lock + * Revision 1.1.1.28.1.11 2017/02/22 11:32:52 martin + * Fixed warnings due to preliminary, unfinished code. + * Revision 1.1.1.28.1.10 2017/02/07 14:24:09 thomas-b + * Added function xdevfeat_has_monitoring, which checks if the extended feature MBG_XFEATURE_MONITORING is set + * Revision 1.1.1.28.1.9 2017/02/07 14:10:48 daniel + * Updated function prototypes + * Revision 1.1.1.28.1.8 2016/12/06 10:43:37 thomas-b + * Added function xdevfeat_has_sv_info + * Revision 1.1.1.28.1.7 2016/11/30 16:12:27 thomas-b + * Added function xdevfeat_has_scu_stat + * Revision 1.1.1.28.1.6 2016/11/22 10:33:16 philipp + * Implemented I/O ports + * Revision 1.1.1.28.1.5 2016/11/07 11:31:49 thomas-b + * Fixed typedef for XDEVFEAT_CHK_SUPP_FNC + * Revision 1.1.1.28.1.4 2016/11/02 12:16:19 thomas-b + * Fixed documentation + * Revision 1.1.1.28.1.3 2016/11/02 12:08:22 thomas-b + * Added function to check for new MBG_XFEATURE_REQ_TTM + * Revision 1.1.1.28.1.2 2016/11/01 09:39:32 martin + * Doxygen changes + * Revision 1.1.1.28.1.1 2016/10/25 08:08:37 martin + * Updated function prototypes with preliminary changes. + * Revision 1.1.1.28 2016/10/20 14:46:05 thomas-b + * Added function to check if XBP is supported + * Revision 1.1.1.27 2016/10/20 10:43:36 thomas-b + * Added function to check if a device is a bus level device + * Revision 1.1.1.26 2016/10/14 11:09:41 thomas-b + * Added function to check MBG_XFEATURE_UCAP_NET + * Revision 1.1.1.25 2016/09/29 14:35:35 thomas-b + * Added function to check reboot feature + * Revision 1.1.1.24 2016/09/29 12:19:59 thomas-b + * Added function to check transactions feature + * Revision 1.1.1.23 2016/07/07 15:03:33 martin + * Updated function prototypes. + * Revision 1.1.1.22 2016/06/15 10:15:52 thomas-b + * Added functions which check if the user capture feature is supported by a device + * Revision 1.1.1.21 2016/06/14 10:33:23 thomas-b + * Added functions which check if the event log feature is supported by a device + * Revision 1.1.1.20 2016/06/07 07:43:09 philipp + * New function to check for Irig Rx feature + * Revision 1.1.1.19 2016/06/02 11:44:37 philipp + * Fixed prototype + * Revision 1.1.1.18 2016/05/30 08:10:47 thomas-b + * Added functions to check several builtin features + * Revision 1.1.1.17 2016/05/20 09:41:39 thomas-b + * Removed functions which check for a specific IMS card + * Revision 1.1.1.16 2016/05/20 08:50:47 thomas-b + * Added functions xdevfeat_has_time_scale and xdevfeat_has_tzcode + * Revision 1.1.1.15 2016/05/17 06:33:13 philipp + * New function to check whether a device has serial outputs + * Revision 1.1.1.14 2016/05/12 10:41:41 philipp + * New functions to check bpe card and IRIG Tx feature + * Revision 1.1.1.13 2016/05/10 06:15:32 philipp + * New function to check whether a device has programmable pulses + * Revision 1.1.1.12 2016/04/26 06:52:46 thomas-b + * Added functions to check if NET_CFG and LAN_IP4 APIs are supported + * Revision 1.1.1.11 2016/04/22 10:54:01 philipp + * New function to check whether device is LIU + * Revision 1.1.1.10 2016/04/20 13:12:58 thomas-b + * Added function to check if a device supports NTP + * Revision 1.1.1.9 2016/04/20 09:26:04 philipp + * Moved all HPS-PTP related structures to gpspriv.h and removed related extended feature bit from gpsdefs.h. + * Also removed functions from mbgextio and xdevfeat since HPS-PTP handling needs a redesign concerning structures. + * Thus, handle everything explicitly for now! + * -> Redesing this A.S.A.P.!!! + * Revision 1.1.1.8 2016/04/15 08:17:27 philipp + * New feature MBG_XFEATURE_EXT_PTP + * Revision 1.1.1.7 2016/04/13 07:01:22 philipp + * New function to check whether device is HPS + * Revision 1.1.1.6 2016/04/12 13:27:42 philipp + * Several new functions to check for device models and device features + * Revision 1.1.1.5 2016/04/11 13:57:17 thomas-b + * Added function xdevfeat_has_xmulti_ref + * Revision 1.1.1.4 2016/04/07 12:36:57 martin + * Updated function prototypes. + * Revision 1.1.1.3 2016/04/04 15:31:25 martin + * New function xdevfeat_is_vsg(). + * Revision 1.1.1.2 2016/03/24 14:08:52 martin + * *** empty log message *** + * Revision 1.1.1.1 2016/03/18 10:48:19 martin + * *** empty log message *** + * Revision 1.1 2016/03/16 14:32:52 martin + * Initial revision. + * + **************************************************************************/ + +#ifndef _XDEVFEAT_H +#define _XDEVFEAT_H + + +/* Other headers to be included */ + +#include <gpsdefs.h> + +#ifdef _XDEVFEAT + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + +/* Start of header body */ + +/** + * @defgroup chk_supp_fncs Groups of functions used to check if a particular feature is supported + * + * Each of these functions can be used to check if a device supports a particular + * feature. ::MBG_SUCCESS is returned if the requested feature is supported, + * otherwise one of the @ref MBG_ERROR_CODES is returned, as appropriate. + * + * Some features are supported by a device if an associated bit is set in the + * ::RECEIVER_INFO::features field, but since the number of bits in this field + * is limited, newer feature bits are defined in a ::MBG_XFEATURE_BUFFER. + * Finally there are some builtin features which may be implicitly supported + * by a particular device model, or not. + * + * These functions provide a unified API for all feature types to make + * application code more straightforward. + * + * If the mbgextio API is used then a ::MBG_XDEV_FEATURES structure embedded in + * the ::MBG_MSG_CTL structure is set up automatically when the device is opened, + * and there are mbgextio_... wrapper functions available which just expect the + * MBG_MSG_CTL * associated with the device to check if a feature is supported. + * See @ref mbgextio_chk_supp_fncs. + * + * Other implementations which retrieve the ::MBG_XDEV_FEATURES structure of + * a device in a different way can use some lower level functions. + * See @ref xdevfeat_chk_supp_fncs. + */ + + +/** + * @defgroup xdevfeat_chk_supp_fncs Low level functions used to check if a particular feature is supported + * @ingroup chk_supp_fncs + * + * @note Applications using the mbgextio API should use the mbgextio_ wrapper + * functions preferably. See @ref mbgextio_chk_supp_fncs. + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief A structure combining all device feature information + */ +typedef struct +{ + uint32_t reserved; ///< Currently reserved, unused, always 0 + RECEIVER_INFO receiver_info; ///< Receiver info provided by the device + MBG_XFEATURE_BUFFER xfeature_buffer; ///< Extended features provided by the device + MBG_TLV_INFO tlv_info; ///< TLV info provided by a device + +} MBG_XDEV_FEATURES; + + + +/** + * @brief Type of functions to check if a feature is supported + */ +typedef int _NO_MBG_API XDEVFEAT_CHK_SUPP_FNC( const MBG_XDEV_FEATURES *p_xdf ); + + + +/* function prototypes: */ + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + + /** + * @brief Check if a device can receive the GPS satellite system + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_is_gps + * @see ::mbg_chk_dev_is_gps + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_gps( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the GNSS API + * + * This is usually supported by devices which can receive signals + * from different satellite systems, e.g. GPS, GLONASS, ... + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_is_gnss + * @see ::mbg_chk_dev_is_gnss + * @see ::MBG_GNSS_TYPES + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_gnss( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device is a time code receiver (IRIG or similar) + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_is_tcr //### TODO + * @see ::mbg_chk_dev_is_tcr //### TODO + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_tcr( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device is a DCF77 AM receiver + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_is_dcf //### TODO + * @see ::mbg_chk_dev_is_dcf + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_dcf( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device can receive DCF77 PZF + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_dev_has_pzf //### TODO + * @see ::mbg_chk_dev_has_pzf + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pzf( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device is an MSF receiver + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_msf( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device is a JJY receiver + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_jjy( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device is a WWVB receiver + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_wwvb( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device is a bus level device + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_is_bus_lvl_dev( const MBG_XDEV_FEATURES *p_xdf ) ; + + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ims( const MBG_XDEV_FEATURES *p_xdf ) ; + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_gpio( const MBG_XDEV_FEATURES *p_xdf ) ; + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_synth( const MBG_XDEV_FEATURES *p_xdf ) ; + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_prog_pulses( const MBG_XDEV_FEATURES *p_xdf ) ; + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_irig_tx( const MBG_XDEV_FEATURES *p_xdf ) ; + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_irig_rx( const MBG_XDEV_FEATURES *p_xdf ) ; + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_serouts( const MBG_XDEV_FEATURES *p_xdf ) ; + /** + * @brief Check if a device supports the ::BVAR_STAT structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_bvar_stat( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports reading the position as ::XYZ array + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pos_xyz( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports reading the position as ::LLA array + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pos_lla( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if the device supports the builtin feature TIME + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_time_ttm( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::MBG_TIME_SCALE_INFO structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_time_scale_info + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_time_scale( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::TZDL structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_tzdl( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::TZCODE API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_tzcode( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::ANT_INFO structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ant_info( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::ENABLE_FLAGS structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_enable_flags( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::STAT_INFO structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_gps_stat_info( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::ANT_CABLE_LEN structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ant_cable_length( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::IGNORE_LOCK structure and API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_gps_ignore_lock( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if the device supports the SCU_STAT structures + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + * @see @ref group_scu + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_scu_stat( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if the device supports the SV_INFO structures + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else ::MBG_ERR_NOT_SUPP_BY_DEV + * or ::MBG_ERR_DEV_NOT_SUPP (see @ref xdevfeat_chk_supp_fncs) + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_sv_info( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a timecode receiver provides ::MBG_RAW_IRIG_DATA + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_raw_irig_data + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_raw_irig_data( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the old LAN_IP4 API + * + * The LAN_IP4 API provides structures and functions to configure + * parts of the networking of a device and is superseded by the + * NET_CFG API. Some devices combine NET_CFG and LAN_IP4. + * Therefore, ::mbgextio_get_all_net_cfg_info should be used + * preferably to read the network configuration. + * It will translate the old structures into the new ones. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_net_cfg_info + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_lan_ip4( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the new NET_CFG API + * + * The NET_CFG API provides structures and functions to configure + * the complete networking part of a device and supersedes the + * LAN_IP4 API. Not all devices support the whole feature set + * of the NET_CFG API or combine NET_CFG and LAN_IP4. + * Therefore, ::mbgextio_get_all_net_cfg_info should be used + * preferably to read the network configuration. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_net_cfg_info + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_net_cfg( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the PTP API + * + * The PTP API consists of different calls and associated structures + * which * have evolved over time. Not all devices support every call, + * so ::mbgextio_get_all_ptp_cfg_info takes care to check which parts are + * supported and thus should be used preferably to read PTP information. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_ptp_cfg_info + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ptp( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the NTP API + * + * The NTP API consists of different calls and associated structures + * which have evolved over time. Not all devices support every call, + * so ::mbgextio_get_all_ntp_cfg_info takes care to check which parts are + * supported and thus should be used preferably to read NTP information. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_ntp_cfg_info + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ntp( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the event log API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_evt_log( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the user capture API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ucap( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the user capture via network feature + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref group_ucap_net + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ucap_net( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the TLV API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref group_tlv_api + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_tlv_api( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports a firmware update via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_xmt_fw_update + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_fw_update( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports creating / sending a diagnostics file via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO //refer to get diag function + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_diag_file( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports PTPv2 license infos + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ptpv2_license( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports NTP license infos via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ntp_license( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports PTPv1 License Infos via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_ptpv1_license( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports Time Monitor License infos via TLV + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_tlv_feat_supp + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_supp_tlv_time_monitor_license( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::GPS_SAVE_CFG command + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_cmd_save_cfg + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_cmd_save_cfg( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the extended feature monitoring + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_monitoring( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the LED API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_led_api( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the LNE API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_lne_api( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the power control API + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_pwr_ctl_api( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the ::MBG_EXT_SYS_INFO command + * + * @param[in,out] p_xdf Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_ext_sys_info( const MBG_XDEV_FEATURES *p_xdf ) ; + + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_io_ports( const MBG_XDEV_FEATURES *p_xdf ) ; + /** + * @brief Check if a device has ::MBG_XFEATURE_TRANSACTIONS + * + * @param[in,out] p_xdf Pointer to a valid message control structure + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::TODO ### + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_transactions( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device has ::MBG_XFEATURE_REBOOT + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_reboot( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device has ::MBG_XFEATURE_REQ_TTM + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_xfeature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + * @see mbgextio_get_time + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_req_ttm( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the extended multi ref features including multi instances + * + * The different multi ref feature and its appropriate flags have evolved over time. + * This function only checks the currently up-to-date GPS_HAS_XMRS_MULT_INSTC flag. + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see ::mbgextio_get_all_xmulti_ref_info + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_xmulti_ref( const MBG_XDEV_FEATURES *p_xdf ) ; + + /** + * @brief Check if a device supports the extended binary protocol (XBP) feature + * + * @param[in,out] p_xdf Pointer to a ::MBG_XDEV_FEATURES buffer associated with the device + * + * @return ::MBG_SUCCESS if supported, else error code from ::check_ri_feature + * + * @ingroup xdevfeat_chk_supp_fncs + * @see @ref xdevfeat_chk_supp_fncs + */ + _NO_MBG_API_ATTR int _NO_MBG_API xdevfeat_has_xbp( const MBG_XDEV_FEATURES *p_xdf ) ; + + +/* ----- function prototypes end ----- */ + +#ifdef __cplusplus +} +#endif + +/* End of header body */ + +#undef _ext +#undef _DO_INIT + +#endif /* _XDEVFEAT_H */ diff --git a/mbglib/common/xtiocomm.c b/mbglib/common/xtiocomm.c new file mode 100644 index 0000000..04f7d8b --- /dev/null +++ b/mbglib/common/xtiocomm.c @@ -0,0 +1,547 @@ + +/************************************************************************** + * + * $Id: xtiocomm.c 1.2.1.5 2017/04/12 08:42:06Z martin TEST $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Common functions for the Meinberg binary data protocol. + * + * ----------------------------------------------------------------------- + * $Log: xtiocomm.c $ + * Revision 1.2.1.5 2017/04/12 08:42:06Z martin + * Fixed compiler warning. + * Revision 1.2.1.4 2016/12/01 13:47:49Z philipp + * Moved helper function check_byte_array_bit from xdevfeat.c to xtiocomm.c and make it public + * Revision 1.2.1.3 2016/11/15 15:43:31 martin + * Account for modified mbgserio functions. + * Revision 1.2.1.2 2016/10/28 07:31:36 thomas-b + * Use calloc instead of malloc for allocation of rcv and xmt buffer to avoid uninitialized buffer warnings + * Revision 1.2.1.1 2016/06/29 11:59:22 philipp + * Extended socket API by TCP client + * Revision 1.2 2016/06/28 13:39:21 philipp + * Added missing include files if _USE_SERIAL_IO is 0 + * Revision 1.1 2016/03/16 14:32:52 martin + * Initial revision. + * + **************************************************************************/ + +#define _XTIOCOMM + #include <xtiocomm.h> +#undef _XTIOCOMM + +#include <stdio.h> +#include <string.h> +#include <mbgerror.h> + + + +/*HDR*/ +/** + * @brief Deallocate a message control structure + * + * Free the memory allocated for a message control structure + * and set the pointer to NULL. + * + * @param[in,out] ppmctl Address of a pointer to a message control structure + * + * @see ::alloc_msg_ctl + */ +void dealloc_msg_ctl( MBG_MSG_CTL **ppmctl ) +{ + MBG_MSG_CTL *pmctl = *ppmctl; + + if ( pmctl ) + { + if ( pmctl->rcv.pmb ) + { + free( pmctl->rcv.pmb ); + pmctl->rcv.pmb = NULL; + } + + pmctl->rcv.buf_size = 0; + + if ( pmctl->xmt.pmb ) + { + free( pmctl->xmt.pmb ); + pmctl->xmt.pmb = NULL; + } + + pmctl->xmt.buf_size = 0; + + free( pmctl ); + *ppmctl = NULL; + } + +} // dealloc_msg_ctl + + + +/*HDR*/ +/** + * @brief Allocate a message control structure + * + * Allocate memory for a message control structure and associated + * message receive and transmit buffers. + * + * @param[out] ppmctl Address of a pointer to a message control structure to be allocated, set to NULL on error + * + * @return ::MBG_SUCCESS or one of the @ref MBG_ERROR_CODES + * + * @see ::dealloc_msg_ctl + */ +int alloc_msg_ctl( MBG_MSG_CTL **ppmctl ) +{ + int rc = MBG_ERR_UNSPEC; + + MBG_MSG_CTL *pmctl = (MBG_MSG_CTL *) malloc( sizeof( *pmctl ) ); + + if ( pmctl == NULL ) + { + #if defined( DEBUG ) + fprintf( stderr, "failed to malloc control block in %s\n", __func__ ); + #endif + goto fail; + } + + memset( pmctl, 0, sizeof( *pmctl ) ); + + // allocate receive buffer + pmctl->rcv.buf_size = sizeof( *(pmctl->rcv.pmb) ); + pmctl->rcv.pmb = (MBG_MSG_BUFF *) calloc( 1, pmctl->rcv.buf_size ); + + if ( pmctl->rcv.pmb == NULL ) + { + #if defined( DEBUG ) + fprintf( stderr, "failed to malloc rcv buffer in %s\n", __func__ ); + #endif + goto fail; + } + + // allocate transmit buffer + pmctl->xmt.buf_size = sizeof( *(pmctl->xmt.pmb) ); + pmctl->xmt.pmb = (MBG_MSG_BUFF *) calloc( 1, pmctl->xmt.buf_size ); + + if ( pmctl->xmt.pmb == NULL ) + { + #if defined( DEBUG ) + fprintf( stderr, "failed to malloc xmt buffer in %s\n", __func__ ); + #endif + goto fail; + } + + + // buffers allocated successfully + rc = MBG_SUCCESS; + goto out; + + +fail: // if not all memory blocks could be allocated, clean up + dealloc_msg_ctl( &pmctl ); // also sets pmctl to NULL + rc = MBG_ERR_NO_MEM; + +out: + *ppmctl = pmctl; + return rc; + +} // alloc_msg_ctl + + + +//### TODO proper header / prototype +/*HDR*/ +const char *xtiocomm_get_cmd_name( GPS_CMD cmd_code ) +{ + static const MBG_CODE_NAME_TABLE_ENTRY gps_cmd_names[] = GPS_CMD_CODES_TABLE; + + const MBG_CODE_NAME_TABLE_ENTRY *p; + + cmd_code &= ~GPS_CTRL_MSK; + + for ( p = gps_cmd_names; ; ) + { + if ( p->name == NULL ) + break; // end of table + + if ( p->code == cmd_code ) + return p->name; + + p++; + } + + return NULL; + +} // xtiocomm_get_cmd_name + + + +/*HDR*/ +//### TODO +int dev_open_finish( int rc, MBG_MSG_CTL *pmctl, MBG_MSG_CTL **caller_ppmctl ) +{ + *caller_ppmctl = pmctl; // valid pointer or NULL on error + + return rc; + +} // dev_open_finish + + + +/*HDR*/ +//### TODO +int dev_open_fail_free( int rc, MBG_MSG_CTL **ppmctl, MBG_MSG_CTL **caller_ppmctl ) +{ + dealloc_msg_ctl( ppmctl ); + + return dev_open_finish( rc, *ppmctl, caller_ppmctl ); + +} // dev_open_fail_free + + + +/*HDR*/ +//### TODO +int dev_open_fail_close( int rc, MBG_MSG_CTL **ppmctl, MBG_MSG_CTL **caller_ppmctl ) +{ + xtiocomm_close_connection( ppmctl ); // also frees the MBG_MSG_CTL structure + + return dev_open_finish( rc, *ppmctl, caller_ppmctl ); + +} // dev_open_fail_close + + + +/*HDR*/ +//### TODO +void dev_open_init( MBG_MSG_CTL *pmctl, int conn_type, int msg_timeout_ms, int poll_timeout_ms ) +{ + pmctl->conn_type = conn_type; + + xtiocomm_set_msg_rcv_timeout( pmctl, msg_timeout_ms ); + xtiocomm_set_dev_poll_timeout( pmctl, poll_timeout_ms ); + +} // dev_open_init + + + +/*HDR*/ +/** + * @brief Check if a specific bit is set in a byte array + * + * This API call checks if a specific bit is set in an array of bytes. + * Bits are counted starting from the least significant bit of the least + * significant byte. + * + * @param[in] bit_num Number of the bit to be tested, 0..(8*(max_bytes-1)) + * @param[in] p Pointer to a buffer with an array of bytes + * @param[in] max_bytes The number of bytes in the buffer p + * + * @return ::MBG_SUCCESS if the bit is set, ::MBG_ERR_NOT_SUPP_BY_DEV if not, + * or ::MBG_ERR_RANGE if the bit number is out of the range of the array + */ +int check_byte_array_bit( int bit_num, const uint8_t *p, int max_bytes ) +{ + int byte_num = bit_num >> 3; + + if ( byte_num < max_bytes ) // the normal case + { + ulong bit_mask = 1UL << ( bit_num & 0x07 ); + + return ( p[byte_num] & bit_mask ) ? MBG_SUCCESS : MBG_ERR_NOT_SUPP_BY_DEV; + } + + return MBG_ERR_RANGE; + +} // check_byte_array_bit + + + +#if _USE_SOCKET_IO + +/*HDR*/ +/** + * @brief Close a socket and make the socket descriptor invalid + * + * @param[in,out] pmctl Pointer to a valid message control structure containing the socket descriptor + * + * @return One of the @ref MBG_RETURN_CODES + */ +int socket_close( MBG_MSG_CTL *pmctl ) +{ + int rc; + + if ( pmctl->st.sockio.sockfd == MBG_INVALID_SOCK_FD ) + return MBG_SUCCESS; + + #if defined( MBG_TGT_CVI ) || defined( MBG_TGT_WIN32 ) + rc = closesocket( pmctl->st.sockio.sockfd ); // returns 0 on success + #elif defined( MBG_TGT_POSIX ) + rc = close( pmctl->st.sockio.sockfd ); // returns 0 on success + #else + #error close socket needs to be implemented for this target + #endif + + pmctl->st.sockio.sockfd = MBG_INVALID_SOCK_FD; + + if ( rc != 0 ) + { + rc = mbg_get_last_socket_error( "failed to close socket socket_close" ); + goto out; + } + + rc = MBG_SUCCESS; + +out: + return rc; + +} // socket_close + +#endif // _USE_SOCKET_IO + + + +/*HDR*/ +/** + * @brief Close a binary communication channel and release resources + * + * Closes a binary communication channel which has been opened by one + * of the mbgextio_open_...() functions and releases the buffers which + * have been allocated when the channel was opened. + * + * The pointer to the message control structure passed by address is set + * to NULL after the channel has been closed and the resources have + * been released. + * + * @param[in,out] ppmctl Address of a pointer to a message control structure + * created when the communication channel was opened + * by one of the mbgextio_open_...() calls. + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_open_socket + * @see ::mbgextio_open_serial + * @see ::mbgextio_open_serial_ftdi + * @see ::mbgextio_open_usb + * @see ::mbgextio_open_usb_direct_io + */ +_NO_MBG_API_ATTR int _MBG_API xtiocomm_close_connection( MBG_MSG_CTL **ppmctl ) +{ + MBG_MSG_CTL *pmctl = *ppmctl; + int rc = MBG_ERR_UNSPEC; + + switch ( pmctl->conn_type ) + { + #if _USE_SERIAL_IO + case MBG_CONN_TYPE_SERIAL: + rc = mbgserio_close( &pmctl->st.p_serio ); + break; + #endif // _USE_SERIAL_IO + + #if _USE_SERIAL_IO_FTDI + case MBG_CONN_TYPE_SERIAL_FTDI: + { + FT_STATUS status = FT_Close( pmctl->st.ftdi.port_handle ); + pmctl->st.ftdi.port_handle = NULL; //### TODO FT_Handle is a PVOID + rc = mbg_ftdi_ft_status_to_mbg( status ); + } break; + #endif // _USE_SERIAL_IO_FTDI + + #if _USE_SOCKET_IO + case MBG_CONN_TYPE_SOCKET: + rc = socket_close( pmctl ); + break; + #endif // _USE_SOCKET_IO + + #if _USE_USB_IO + case MBG_CONN_TYPE_USB: + rc = mbgusbio_close( &pmctl->st.usbio ); + break; + #endif // _USE_USB_IO + + #if _USE_USB_DIRECT_IO + case MBG_CONN_TYPE_USB_DIRECT_IO: + if ( pmctl->st.usbdio.usbdiofd == MBG_USB_DIRECT_IO_INVALID_FD ) + { + rc = MBG_SUCCESS; + break; + } + + rc = close( pmctl->st.usbdio.usbdiofd ); + + if ( rc < 0 ) + rc = mbg_get_last_error( "failed to close direct USB I/O device" ); + else + rc = MBG_SUCCESS; + #endif // _USE_USB_DIRECT_IO + + default: + rc = MBG_ERR_CONN_TYPE; + + } // switch + + #if _USE_MUTEX + _mbg_mutex_destroy( &pmctl->dev_mutex ); + #endif + + dealloc_msg_ctl( ppmctl ); + + return rc; + +} // xtiocomm_close_connection + + + +/*HDR*/ +/** + * @brief Set device poll timeout + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] new_timeout New poll timeout value [ms] + * + * @return Previous poll timeout value [ms] + * + * @see ::mbgextio_get_dev_poll_timeout + * @see ::mbgextio_set_msg_rcv_timeout + * @see ::mbgextio_get_msg_rcv_timeout + */ +_NO_MBG_API_ATTR ulong _MBG_API xtiocomm_set_dev_poll_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) +{ + ulong prev_poll_timeout = xtiocomm_get_dev_poll_timeout( pmctl ); + + switch ( pmctl->conn_type ) + { + #if _USE_SOCKET_IO + case MBG_CONN_TYPE_SOCKET: + pmctl->st.sockio.poll_timeout = new_timeout; + break; + #endif // _USE_SOCKET_IO + + #if _USE_SERIAL_IO + case MBG_CONN_TYPE_SERIAL: + pmctl->st.p_serio->poll_timeout = new_timeout; //### TODO call library function + break; + #endif // _USE_SERIAL_IO + + #if _USE_SERIAL_IO_FTDI + case MBG_CONN_TYPE_SERIAL_FTDI: + pmctl->st.ftdi.poll_timeout = new_timeout; //### TODO call FTDI library function + break; + #endif // _USE_SERIAL_IO_FTDI + + #if _USE_USB_IO + case MBG_CONN_TYPE_USB: + pmctl->st.usbio.poll_timeout = new_timeout; //### TODO call library function + break; + #endif // _USE_USB_IO + + #if _USE_USB_DIRECT_IO + case MBG_CONN_TYPE_USB_DIRECT_IO: + pmctl->st.usbdio.poll_timeout = new_timeout; + break; + #endif + + } // switch + + return prev_poll_timeout; + +} // xtiocomm_set_dev_poll_timeout + + + +/*HDR*/ +/** + * @brief Get device poll timeout + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Current poll timeout value [ms] + * + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_set_msg_rcv_timeout + * @see ::mbgextio_get_msg_rcv_timeout + */ +_NO_MBG_API_ATTR ulong _MBG_API xtiocomm_get_dev_poll_timeout( const MBG_MSG_CTL *pmctl ) +{ + ulong poll_timeout = 0; + + switch ( pmctl->conn_type ) + { + #if _USE_SOCKET_IO + case MBG_CONN_TYPE_SOCKET: + poll_timeout = pmctl->st.sockio.poll_timeout; + break; + #endif // _USE_SOCKET_IO + + #if _USE_SERIAL_IO + case MBG_CONN_TYPE_SERIAL: + poll_timeout = pmctl->st.p_serio->poll_timeout; + break; + #endif // _USE_SERIAL_IO + + #if _USE_SERIAL_IO_FTDI + case MBG_CONN_TYPE_SERIAL_FTDI: + poll_timeout = pmctl->st.ftdi.poll_timeout; + break; + #endif // _USE_SERIAL_IO_FTDI + + #if _USE_USB_IO + case MBG_CONN_TYPE_USB: + poll_timeout = pmctl->st.usbio.poll_timeout; + break; + #endif // _USE_USB_IO + + #if _USE_USB_DIRECT_IO + case MBG_CONN_TYPE_USB_DIRECT_IO: + poll_timeout = pmctl->st.usbdio.poll_timeout; + break; + #endif + + default: + break; + + } // switch + + return poll_timeout; + +} // xtiocomm_get_dev_poll_timeout + + + +/*HDR*/ +/** + * @brief Set message receive timeout value + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] new_timeout New timeout value [ms] + * + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_get_dev_poll_timeout + * @see ::mbgextio_get_msg_rcv_timeout + */ +_NO_MBG_API_ATTR void _MBG_API xtiocomm_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) +{ + pmctl->msg_rcv_timeout = new_timeout; + +} // xtiocomm_set_msg_rcv_timeout + + + +/*HDR*/ +/** + * @brief Get message receive timeout value + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Current timeout value [ms] + * + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_get_dev_poll_timeout + * @see ::mbgextio_set_msg_rcv_timeout + */ +_NO_MBG_API_ATTR ulong _MBG_API xtiocomm_get_msg_rcv_timeout( const MBG_MSG_CTL *pmctl ) +{ + return pmctl->msg_rcv_timeout; + +} // xtiocomm_get_msg_rcv_timeout + diff --git a/mbglib/common/xtiocomm.h b/mbglib/common/xtiocomm.h new file mode 100644 index 0000000..4b37b96 --- /dev/null +++ b/mbglib/common/xtiocomm.h @@ -0,0 +1,206 @@ + +/************************************************************************** + * + * $Id: xtiocomm.h 1.2 2016/12/01 13:47:49Z philipp TEST $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Definitions and prototypes for xtiocomm.c. + * + * ----------------------------------------------------------------------- + * $Log: xtiocomm.h $ + * Revision 1.2 2016/12/01 13:47:49Z philipp + * Moved helper function check_byte_array_bit from xdevfeat.c to xtiocomm.c and make it public + * Revision 1.1 2016/03/16 14:32:52 martin + * Initial revision. + * + **************************************************************************/ + +#ifndef _XTIOCOMM_H +#define _XTIOCOMM_H + + +/* Other headers to be included */ + +#include <mbg_tgt.h> +#include <gpsserio.h> + + +#ifdef _XTIOCOMM + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + +/* Start of header body */ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* function prototypes: */ + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + + /** + * @brief Deallocate a message control structure + * + * Free the memory allocated for a message control structure + * and set the pointer to NULL. + * + * @param[in,out] ppmctl Address of a pointer to a message control structure + * + * @see ::alloc_msg_ctl + */ + void dealloc_msg_ctl( MBG_MSG_CTL **ppmctl ) ; + + /** + * @brief Allocate a message control structure + * + * Allocate memory for a message control structure and associated + * message receive and transmit buffers. + * + * @param[out] ppmctl Address of a pointer to a message control structure to be allocated, set to NULL on error + * + * @return ::MBG_SUCCESS or one of the @ref MBG_ERROR_CODES + * + * @see ::dealloc_msg_ctl + */ + int alloc_msg_ctl( MBG_MSG_CTL **ppmctl ) ; + + const char *xtiocomm_get_cmd_name( GPS_CMD cmd_code ) ; + //### TODO +int dev_open_finish( int rc, MBG_MSG_CTL *pmctl, MBG_MSG_CTL **caller_ppmctl ) ; + + //### TODO +int dev_open_fail_free( int rc, MBG_MSG_CTL **ppmctl, MBG_MSG_CTL **caller_ppmctl ) ; + + //### TODO +int dev_open_fail_close( int rc, MBG_MSG_CTL **ppmctl, MBG_MSG_CTL **caller_ppmctl ) ; + + //### TODO +void dev_open_init( MBG_MSG_CTL *pmctl, int conn_type, int msg_timeout_ms, int poll_timeout_ms ) ; + + /** + * @brief Check if a specific bit is set in a byte array + * + * This API call checks if a specific bit is set in an array of bytes. + * Bits are counted starting from the least significant bit of the least + * significant byte. + * + * @param[in] bit_num Number of the bit to be tested, 0..(8*(max_bytes-1)) + * @param[in] p Pointer to a buffer with an array of bytes + * @param[in] max_bytes The number of bytes in the buffer p + * + * @return ::MBG_SUCCESS if the bit is set, ::MBG_ERR_NOT_SUPP_BY_DEV if not, + * or ::MBG_ERR_RANGE if the bit number is out of the range of the array + */ + int check_byte_array_bit( int bit_num, const uint8_t *p, int max_bytes ) ; + + /** + * @brief Close a socket and make the socket descriptor invalid + * + * @param[in,out] pmctl Pointer to a valid message control structure containing the socket descriptor + * + * @return One of the @ref MBG_RETURN_CODES + */ + int socket_close( MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Close a binary communication channel and release resources + * + * Closes a binary communication channel which has been opened by one + * of the mbgextio_open_...() functions and releases the buffers which + * have been allocated when the channel was opened. + * + * The pointer to the message control structure passed by address is set + * to NULL after the channel has been closed and the resources have + * been released. + * + * @param[in,out] ppmctl Address of a pointer to a message control structure + * created when the communication channel was opened + * by one of the mbgextio_open_...() calls. + * + * @return One of the @ref MBG_RETURN_CODES + * + * @see ::mbgextio_open_socket + * @see ::mbgextio_open_serial + * @see ::mbgextio_open_serial_ftdi + * @see ::mbgextio_open_usb + * @see ::mbgextio_open_usb_direct_io + */ + _NO_MBG_API_ATTR int _MBG_API xtiocomm_close_connection( MBG_MSG_CTL **ppmctl ) ; + + /** + * @brief Set device poll timeout + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] new_timeout New poll timeout value [ms] + * + * @return Previous poll timeout value [ms] + * + * @see ::mbgextio_get_dev_poll_timeout + * @see ::mbgextio_set_msg_rcv_timeout + * @see ::mbgextio_get_msg_rcv_timeout + */ + _NO_MBG_API_ATTR ulong _MBG_API xtiocomm_set_dev_poll_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) ; + + /** + * @brief Get device poll timeout + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Current poll timeout value [ms] + * + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_set_msg_rcv_timeout + * @see ::mbgextio_get_msg_rcv_timeout + */ + _NO_MBG_API_ATTR ulong _MBG_API xtiocomm_get_dev_poll_timeout( const MBG_MSG_CTL *pmctl ) ; + + /** + * @brief Set message receive timeout value + * + * @param[in,out] pmctl Pointer to a valid message control structure + * @param[in] new_timeout New timeout value [ms] + * + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_get_dev_poll_timeout + * @see ::mbgextio_get_msg_rcv_timeout + */ + _NO_MBG_API_ATTR void _MBG_API xtiocomm_set_msg_rcv_timeout( MBG_MSG_CTL *pmctl, ulong new_timeout ) ; + + /** + * @brief Get message receive timeout value + * + * @param[in,out] pmctl Pointer to a valid message control structure + * + * @return Current timeout value [ms] + * + * @see ::mbgextio_set_dev_poll_timeout + * @see ::mbgextio_get_dev_poll_timeout + * @see ::mbgextio_set_msg_rcv_timeout + */ + _NO_MBG_API_ATTR ulong _MBG_API xtiocomm_get_msg_rcv_timeout( const MBG_MSG_CTL *pmctl ) ; + + +/* ----- function prototypes end ----- */ + +#ifdef __cplusplus +} +#endif + +/* End of header body */ + +#undef _ext +#undef _DO_INIT + +#endif /* _XTIOCOMM_H */ diff --git a/windows/vc6/gpsxmple.dsp b/windows/vc6/gpsxmple.dsp index 2e6a9dd..a23a18e 100644 --- a/windows/vc6/gpsxmple.dsp +++ b/windows/vc6/gpsxmple.dsp @@ -91,6 +91,10 @@ SOURCE=..\..\mbglib\common\aes128.c # End Source File # Begin Source File +SOURCE=..\..\mbglib\common\cfg_hlp.c +# End Source File +# Begin Source File + SOURCE=..\..\mbglib\common\extiohlp.c # End Source File # Begin Source File @@ -107,6 +111,10 @@ SOURCE=..\..\gpsxmple.c # End Source File # Begin Source File +SOURCE=..\..\mbglib\common\lan_util.c +# End Source File +# Begin Source File + SOURCE=..\..\mbglib\common\mbgerror.c # End Source File # Begin Source File @@ -121,6 +129,18 @@ SOURCE=..\..\mbglib\common\mbgserio.c SOURCE=..\..\mbglib\common\myutil.c # End Source File +# Begin Source File + +SOURCE=..\..\mbglib\common\str_util.c +# End Source File +# Begin Source File + +SOURCE=..\..\mbglib\common\xdevfeat.c +# End Source File +# Begin Source File + +SOURCE=..\..\mbglib\common\xtiocomm.c +# End Source File # End Group # Begin Group "Header Files" @@ -151,10 +171,18 @@ SOURCE=..\..\mbglib\common\gpsutils.h # End Source File # Begin Source File +SOURCE=..\..\mbglib\common\lan_util.h +# End Source File +# Begin Source File + SOURCE=..\..\mbglib\common\mbg_arch.h # End Source File # Begin Source File +SOURCE=..\..\mbglib\common\mbg_cof.h +# End Source File +# Begin Source File + SOURCE=..\..\mbglib\common\mbg_tgt.h # End Source File # Begin Source File @@ -163,6 +191,10 @@ SOURCE=..\..\mbglib\common\mbg_tmo.h # End Source File # Begin Source File +SOURCE=..\..\mbglib\common\mbgerror.h +# End Source File +# Begin Source File + SOURCE=..\..\mbglib\common\mbgextio.h # End Source File # Begin Source File @@ -171,6 +203,10 @@ SOURCE=..\..\mbglib\common\mbggeo.h # End Source File # Begin Source File +SOURCE=..\..\mbglib\common\mbgklist.h +# End Source File +# Begin Source File + SOURCE=..\..\mbglib\common\mbgmutex.h # End Source File # Begin Source File @@ -179,6 +215,14 @@ SOURCE=..\..\mbglib\common\mbgserio.h # End Source File # Begin Source File +SOURCE=..\..\mbglib\common\mbgtime.h +# End Source File +# Begin Source File + +SOURCE=..\..\mbglib\common\myutil.h +# End Source File +# Begin Source File + SOURCE=..\..\mbglib\common\pcpsdefs.h # End Source File # Begin Source File @@ -187,12 +231,28 @@ SOURCE=..\..\mbglib\common\secudefs.h # End Source File # Begin Source File +SOURCE=..\..\mbglib\common\str_util.h +# End Source File +# Begin Source File + +SOURCE=..\..\mbglib\common\timeutil.h +# End Source File +# Begin Source File + SOURCE=..\..\mbglib\common\use_pack.h # End Source File # Begin Source File SOURCE=..\..\mbglib\common\words.h # End Source File +# Begin Source File + +SOURCE=..\..\mbglib\common\xdevfeat.h +# End Source File +# Begin Source File + +SOURCE=..\..\mbglib\common\xtiocomm.h +# End Source File # End Group # Begin Group "Resource Files" diff --git a/windows/vs2008/gpsxmple.sln b/windows/vs2008/gpsxmple.sln index 370ee40..53f7478 100644 --- a/windows/vs2008/gpsxmple.sln +++ b/windows/vs2008/gpsxmple.sln @@ -1,18 +1,24 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpsxmple", "gpsxmple.vcproj", "{D76586F4-E543-4FD1-88EA-621C84A82BD8}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpsxmple", "gpsxmple.vcproj", "{7F92F474-7257-4F71-B218-43491D36CAA3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D76586F4-E543-4FD1-88EA-621C84A82BD8}.Debug|Win32.ActiveCfg = Debug|Win32 - {D76586F4-E543-4FD1-88EA-621C84A82BD8}.Debug|Win32.Build.0 = Debug|Win32 - {D76586F4-E543-4FD1-88EA-621C84A82BD8}.Release|Win32.ActiveCfg = Release|Win32 - {D76586F4-E543-4FD1-88EA-621C84A82BD8}.Release|Win32.Build.0 = Release|Win32 + {7F92F474-7257-4F71-B218-43491D36CAA3}.Debug|Win32.ActiveCfg = Debug|Win32 + {7F92F474-7257-4F71-B218-43491D36CAA3}.Debug|Win32.Build.0 = Debug|Win32 + {7F92F474-7257-4F71-B218-43491D36CAA3}.Debug|x64.ActiveCfg = Debug|Win32 + {7F92F474-7257-4F71-B218-43491D36CAA3}.Debug|x64.Build.0 = Debug|Win32 + {7F92F474-7257-4F71-B218-43491D36CAA3}.Release|Win32.ActiveCfg = Release|Win32 + {7F92F474-7257-4F71-B218-43491D36CAA3}.Release|Win32.Build.0 = Release|Win32 + {7F92F474-7257-4F71-B218-43491D36CAA3}.Release|x64.ActiveCfg = Release|Win32 + {7F92F474-7257-4F71-B218-43491D36CAA3}.Release|x64.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/windows/vs2008/gpsxmple.vcproj b/windows/vs2008/gpsxmple.vcproj index c72881b..db9ae69 100644 --- a/windows/vs2008/gpsxmple.vcproj +++ b/windows/vs2008/gpsxmple.vcproj @@ -1,28 +1,28 @@ -<?xml version="1.0" encoding="Windows-1252"?> +<?xml version="1.0" encoding="UTF-8"?> <VisualStudioProject ProjectType="Visual C++" Version="9,00" Name="gpsxmple" - ProjectGUID="{D76586F4-E543-4FD1-88EA-621C84A82BD8}" + ProjectGUID="{7F92F474-7257-4F71-B218-43491D36CAA3}" + Keyword="Win32Proj" TargetFrameworkVersion="0" > <Platforms> <Platform Name="Win32" /> + <Platform + Name="x64" + /> </Platforms> <ToolFiles> </ToolFiles> <Configurations> <Configuration Name="Debug|Win32" - OutputDirectory=".\Debug" - IntermediateDirectory=".\Debug" + OutputDirectory="$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)-tmp\$(ConfigurationName)" ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" - UseOfMFC="0" - ATLMinimizesCRunTimeLibraryUsage="false" - CharacterSet="2" > <Tool Name="VCPreBuildEventTool" @@ -38,48 +38,37 @@ /> <Tool Name="VCMIDLTool" - TypeLibraryName=".\Debug/gpsxmple.tlb" - HeaderFileName="" /> <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories=".,..\..,..\..\mbglib\common" - PreprocessorDefinitions="_DEBUG;_USE_SOCKET_IO=1;MBG_LIB_EXPORT=1;WIN32;_CONSOLE" + AdditionalIncludeDirectories="..\..,..\..\mbglib\common" + PreprocessorDefinitions="_USE_SOCKET_IO=1;MBG_LIB_EXPORT=1;DEBUG=1" MinimalRebuild="true" BasicRuntimeChecks="3" - RuntimeLibrary="1" - PrecompiledHeaderFile=".\Debug/gpsxmple.pch" - AssemblerListingLocation=".\Debug/" - ObjectFile=".\Debug/" - ProgramDataBaseFileName=".\Debug/" + RuntimeLibrary="3" + UsePrecompiledHeader="0" BrowseInformation="1" WarningLevel="3" - SuppressStartupBanner="true" + Detect64BitPortabilityProblems="false" DebugInformationFormat="4" + CompileAs="0" /> <Tool Name="VCManagedResourceCompilerTool" /> <Tool Name="VCResourceCompilerTool" - PreprocessorDefinitions="_DEBUG" - Culture="1031" /> <Tool Name="VCPreLinkEventTool" /> <Tool Name="VCLinkerTool" - AdditionalDependencies="odbc32.lib odbccp32.lib ws2_32.lib" - OutputFile=".\Debug/gpsxmple.exe" + AdditionalDependencies="ws2_32.lib iphlpapi.lib" LinkIncremental="2" - SuppressStartupBanner="true" GenerateDebugInformation="true" - ProgramDatabaseFile=".\Debug/gpsxmple.pdb" SubSystem="1" - RandomizedBaseAddress="1" - DataExecutionPrevention="0" TargetMachine="1" /> <Tool @@ -93,8 +82,82 @@ /> <Tool Name="VCBscMakeTool" - SuppressStartupBanner="true" - OutputFile=".\Debug/gpsxmple.bsc" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)-tmp\$(ConfigurationName)" + ConfigurationType="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\..,..\..\mbglib\common" + PreprocessorDefinitions="_USE_SOCKET_IO=1;MBG_LIB_EXPORT=1;DEBUG=1" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + BrowseInformation="1" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="ws2_32.lib iphlpapi.lib" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" /> <Tool Name="VCFxCopTool" @@ -108,13 +171,9 @@ </Configuration> <Configuration Name="Release|Win32" - OutputDirectory=".\Release" - IntermediateDirectory=".\Release" + OutputDirectory="$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)-tmp\$(ConfigurationName)" ConfigurationType="1" - InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" - UseOfMFC="0" - ATLMinimizesCRunTimeLibraryUsage="false" - CharacterSet="2" > <Tool Name="VCPreBuildEventTool" @@ -130,46 +189,36 @@ /> <Tool Name="VCMIDLTool" - TypeLibraryName=".\Release/gpsxmple.tlb" - HeaderFileName="" /> <Tool Name="VCCLCompilerTool" - Optimization="2" - InlineFunctionExpansion="1" - AdditionalIncludeDirectories=".,..\..,..\..\mbglib\common" - PreprocessorDefinitions="NDEBUG;_USE_SOCKET_IO=1;MBG_LIB_EXPORT=1;WIN32;_CONSOLE" - StringPooling="true" - RuntimeLibrary="0" - EnableFunctionLevelLinking="true" - PrecompiledHeaderFile=".\Release/gpsxmple.pch" - AssemblerListingLocation=".\Release/" - ObjectFile=".\Release/" - ProgramDataBaseFileName=".\Release/" + AdditionalIncludeDirectories="..\..,..\..\mbglib\common" + PreprocessorDefinitions="_USE_SOCKET_IO=1;MBG_LIB_EXPORT=1;NDEBUG" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + BrowseInformation="1" WarningLevel="3" - SuppressStartupBanner="true" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + CompileAs="0" /> <Tool Name="VCManagedResourceCompilerTool" /> <Tool Name="VCResourceCompilerTool" - PreprocessorDefinitions="NDEBUG" - Culture="1031" /> <Tool Name="VCPreLinkEventTool" /> <Tool Name="VCLinkerTool" - AdditionalDependencies="odbc32.lib odbccp32.lib ws2_32.lib" - OutputFile=".\Release/gpsxmple.exe" - LinkIncremental="1" - SuppressStartupBanner="true" - ProgramDatabaseFile=".\Release/gpsxmple.pdb" + AdditionalDependencies="ws2_32.lib iphlpapi.lib" + LinkIncremental="2" + GenerateDebugInformation="true" SubSystem="1" - RandomizedBaseAddress="1" - DataExecutionPrevention="0" + OptimizeReferences="2" + EnableCOMDATFolding="2" TargetMachine="1" /> <Tool @@ -183,8 +232,81 @@ /> <Tool Name="VCBscMakeTool" - SuppressStartupBanner="true" - OutputFile=".\Release/gpsxmple.bsc" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)-tmp\$(ConfigurationName)" + ConfigurationType="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..,..\..\mbglib\common" + PreprocessorDefinitions="_USE_SOCKET_IO=1;MBG_LIB_EXPORT=1;NDEBUG" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + BrowseInformation="1" + WarningLevel="3" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="ws2_32.lib iphlpapi.lib" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" /> <Tool Name="VCFxCopTool" @@ -201,202 +323,72 @@ </References> <Files> <Filter - Name="Source Files" - Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > <File - RelativePath="..\..\mbglib\common\aes128.c" + RelativePath="..\..\mbglib\common\aes128.h" > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> </File> <File - RelativePath="..\..\mbglib\common\extiohlp.c" + RelativePath="..\..\mbglib\common\cfg_hlp.h" > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> </File> <File - RelativePath="..\..\mbglib\common\gpsserio.c" + RelativePath="..\..\mbglib\common\extiohlp.h" > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> </File> <File - RelativePath="..\..\mbglib\common\gpsutils.c" + RelativePath="..\..\mbglib\common\gpsdefs.h" > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> </File> <File - RelativePath="..\..\gpsxmple.c" + RelativePath="..\..\mbglib\common\gpsserio.h" > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> </File> <File - RelativePath="..\..\mbglib\common\mbgerror.c" + RelativePath="..\..\mbglib\common\gpsutils.h" > </File> <File - RelativePath="..\..\mbglib\common\mbgextio.c" + RelativePath="..\..\mbglib\common\lan_util.h" > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> </File> <File - RelativePath="..\..\mbglib\common\mbgserio.c" + RelativePath="..\..\mbglib\common\mbg_arch.h" > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="" - PreprocessorDefinitions="" - /> - </FileConfiguration> </File> <File - RelativePath="..\..\mbglib\common\myutil.c" + RelativePath="..\..\mbglib\common\mbg_cof.h" > </File> - </Filter> - <Filter - Name="Header Files" - Filter="h;hpp;hxx;hm;inl" - > <File - RelativePath="..\..\mbglib\common\aes128.h" + RelativePath="..\..\mbglib\common\mbg_tgt.h" > </File> <File - RelativePath="..\..\mbglib\common\gpsdefs.h" + RelativePath="..\..\mbglib\common\mbg_tmo.h" > </File> <File - RelativePath="..\..\mbglib\common\gpsserio.h" + RelativePath="..\..\mbglib\common\mbgerror.h" > </File> <File - RelativePath="..\..\mbglib\common\gpsutils.h" + RelativePath="..\..\mbglib\common\mbgextio.h" > </File> <File - RelativePath="..\..\mbglib\common\mbg_tgt.h" + RelativePath="..\..\mbglib\common\mbggeo.h" > </File> <File - RelativePath="..\..\mbglib\common\mbgextio.h" + RelativePath="..\..\mbglib\common\mbgklist.h" > </File> <File - RelativePath="..\..\mbglib\common\mbggeo.h" + RelativePath="..\..\mbglib\common\mbgmutex.h" > </File> <File @@ -404,6 +396,14 @@ > </File> <File + RelativePath="..\..\mbglib\common\mbgtime.h" + > + </File> + <File + RelativePath="..\..\mbglib\common\myutil.h" + > + </File> + <File RelativePath="..\..\mbglib\common\pcpsdefs.h" > </File> @@ -412,6 +412,14 @@ > </File> <File + RelativePath="..\..\mbglib\common\str_util.h" + > + </File> + <File + RelativePath="..\..\mbglib\common\timeutil.h" + > + </File> + <File RelativePath="..\..\mbglib\common\use_pack.h" > </File> @@ -419,11 +427,90 @@ RelativePath="..\..\mbglib\common\words.h" > </File> + <File + RelativePath="..\..\mbglib\common\xdevfeat.h" + > + </File> + <File + RelativePath="..\..\mbglib\common\xtiocomm.h" + > + </File> </Filter> <Filter Name="Resource Files" - Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + <File + RelativePath="..\..\mbglib\common\aes128.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\cfg_hlp.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\extiohlp.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\gpsserio.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\gpsutils.c" + > + </File> + <File + RelativePath="..\..\gpsxmple.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\lan_util.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\mbg_tmo.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\mbgerror.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\mbgextio.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\mbgserio.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\myutil.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\str_util.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\timeutil.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\xdevfeat.c" + > + </File> + <File + RelativePath="..\..\mbglib\common\xtiocomm.c" + > + </File> </Filter> </Files> <Globals> |