summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Burnicki <martin.burnicki@meinberg.de>2018-07-31 12:00:00 +0200
committerMartin Burnicki <martin.burnicki@meinberg.de>2018-07-31 12:00:00 +0200
commit54ad38deb28269fc8b74173a4f513adab13dd503 (patch)
treef4fbf284921d0e6578506efd29bf0757e4e45ab0
parent6b78f35618249cc4cd82f68ee868b7758145b0a1 (diff)
downloadntptest-54ad38deb28269fc8b74173a4f513adab13dd503.tar.gz
ntptest-54ad38deb28269fc8b74173a4f513adab13dd503.zip
Conditionally support symmetric MD5 keys, and other improvements1.10
Configurable request packet mode number. Print request packet even if no response was received. Support build on FreeBSD.
-rwxr-xr-xmbglib/common/gpsdefs.h3811
-rwxr-xr-xmbglib/common/mbg_ntp_auth.c1925
-rwxr-xr-xmbglib/common/mbg_ntp_auth.h173
-rwxr-xr-xmbglib/common/mbg_ntp_test_util.c68
-rwxr-xr-xmbglib/common/mbg_tgt.h162
-rwxr-xr-xmbglib/common/mbgerror.c477
-rwxr-xr-xmbglib/common/mbgerror.h311
-rwxr-xr-xmbglib/common/mbgntp.h33
-rwxr-xr-xmbglib/common/str_util.c48
-rwxr-xr-xmbglib/common/str_util.h12
-rwxr-xr-xmbglib/common/words.h22
-rwxr-xr-xntptest.c159
-rwxr-xr-xunix/BSDmakefile85
-rwxr-xr-xunix/Makefile41
14 files changed, 6277 insertions, 1050 deletions
diff --git a/mbglib/common/gpsdefs.h b/mbglib/common/gpsdefs.h
index 32194a6..6dacbc8 100755
--- a/mbglib/common/gpsdefs.h
+++ b/mbglib/common/gpsdefs.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: gpsdefs.h 1.125 2017/07/05 18:18:27 martin REL_M $
+ * $Id: gpsdefs.h 1.126 2018/07/05 10:18:34 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -13,10 +13,64 @@
*
* -----------------------------------------------------------------------
* $Log: gpsdefs.h $
+ * Revision 1.126 2018/07/05 10:18:34 martin
+ * New models GPS_MODEL_PIO180, GPS_MODEL_FCM180, GPS_MODEL_TCR180USB,
+ * GPS_MODEL_SSP100, GPS_MODEL_GNS165, GPS_MODEL_RSC180RDMP,
+ * GPS_MODEL_GPS16X, GPS_MODEL_MSHPS100.
+ * New builtin features .._MODEL_HAS_UP_CONV, .._MODEL_HAS_MBG_OS.
+ * BUILTIN_FEAT_DCF_PZF_2 includes GPS_MODEL_IS_DCF_AM.
+ * Builtin features of some models were updated.
+ * Removed obsolete MBG_XFEATURE_USB_LOCK.
+ * New extended features MBG_XFEATURE_TAINTED_CFG, MBG_XFEATURE_PUSH_MSGS,
+ * MBG_XFEATURE_USER_AUTH, MBG_XFEATURE_USER_MNGMNT, MBG_XFEATURE_SERVICE,
+ * MBG_XFEATURE_UP_CONV, MBG_XFEATURE_FW_MNGMNT, MBG_XFEATURE_DAC_CTRL_PCI,
+ * MBG_XFEATURE_DATABASE, MBG_XFEATURE_GNSS_MODE.
+ * New string mode STR_CR_ON_SEC.
+ * Renamed legacy string modes to LGCY_STR_ON_REQ, etc. and provided
+ * compatibility definitions for old firmware builds.
+ * New XMR_SETTINGS_FLAG_BITS: XMRSF_BIT_IS_TRUSTED_SRC,
+ * XMRSF_BIT_USE_TRUSTED_SRC, XMRSF_BIT_IS_TIME_OF_DAY_SRC,
+ * XMRSF_BIT_IS_PHASE_SRC.
+ * New XMR_REF_STATUS_BITS: XMRS_BIT_TRS_LIMIT_VIOLATED.
+ * New XMR_INST_FLAGS: XMRIF_BIT_GNSS_BIAS_SUPP.
+ * New XMR_EXT_SRC_FEAT_FLAG_BITS: XMR_EXT_SRC_FEAT_FLAG_BIT_COASTING.
+ * Some MBG_EVT_IDS numbers were added.
+ * Some MBG_IMS_SENSORS were added.
+ * New MBG_NET_GLB_CFG_INFO_FLAGS: MBG_NET_GLB_SUPP_ADD_CONF,
+ * MBG_NET_GLB_SUPP_EXT_ROUTING.
+ * New MBG_NET_INTF_ADDR_BITS: MBG_NET_INTF_ADDR_BIT_AUTOCONF.
+ * Former PTP_CFG_SETTINGS::reserved field was split into
+ * PTP_CFG_SETTINGS::delay_asymmetry and PTP_CFG_SETTINGS::flags_ex.
+ * Former PTP_CFG_INFO::reserved_2 field was renmamed to
+ * PTP_CFG_INFO::supp_flags_ex.
+ * New PTP_CFG_FLAGS: PTP_CFG_ATOI, PTP_CFG_HAS_SMPTE_TLV_STATE,
+ * PTP_CFG_NTP_SW_SERVER, PTP_CFG_HAS_EXT_SUPP_FLAGS.
+ * New extended flags bits PTP_CFG_FLAGS_EX used with PTP configuration.
+ * New PTP profile ID PTP_OPT_EXT_C37238_2017.
+ * Former PTP_POWER_PROFILE_CFG::reserved_2 renamed to
+ * PTP_POWER_PROFILE_CFG::grandmaster_id_2017.
+ * New NTP_FLAGS: NTP_ADD_CONF and related definitions.
+ * NTP refclock configuration and statistics stuff was added.
+ * Former NTP_SYS_STATE::cfg_counter was renamed to
+ * NTP_SYS_STATE::service_state.
+ * IMS slot types were added.
+ * XBP_NODE_INFO structure was modified.
+ * New MBG_TLV_FEAT_TYPES: MBG_TLV_FEAT_TYPE_TIMEMON_FULL_STATUS.
+ * Some new MBG_EXT_SYS_INFO_BITS.
+ * OS type support was added.
+ * Extended management transactions support.
+ * Lots of new I/O port stuff.
+ * Some new definitions for SNMP support.
+ * New definitions for event logging.
+ * New tainted cfg stuff.
+ * Support for user and permission management.
+ * Support for services control.
+ * Support for firmware updates.
+ * Support for database management.
* Revision 1.125 2017/07/05 18:18:27 martin
* New models 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_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_GNS181PEX, GPS_MODEL_MDU180, GPS_MODEL_MDU312,
@@ -950,11 +1004,23 @@ enum GPS_MODEL_CODES
GPS_MODEL_LSG180, // Line Signal Generator
GPS_MODEL_GPS190,
GPS_MODEL_GNS181,
+ GPS_MODEL_PIO180, // Programmable I/O module
+ GPS_MODEL_FCM180, // Fake Clock Module
+ GPS_MODEL_TCR180USB,
+ GPS_MODEL_SSP100, // Secure Sync Processor (HPS with USB-Lock)
+ GPS_MODEL_GNS165,
+ GPS_MODEL_RSC180RDMP,
+ GPS_MODEL_GPS16X, // Some legacy GPS receiver
+ GPS_MODEL_MSHPS100, // microSYNC based on HPS100 hardware (but) as USB host
N_GPS_MODEL
/* If new model codes are added then care must be taken
* to update the associated string initializers GPS_MODEL_NAMES
* and GPS_MODEL_NAME_TABLE accordingly, and to check whether
* the classification macros also cover the new model names.
+ *
+ * CARE MUST BE TAKEN that the name string of bus level devices
+ * is limited to 9 characters. Longer strings will not fit into
+ * the name field of the PCPS_DEV_TYPE structure.
*/
};
@@ -971,99 +1037,112 @@ enum GPS_MODEL_CODES
*
* @anchor GPS_MODEL_NAMES @{ */
-#define GPS_MODEL_NAME_UNKNOWN "Unknown"
-#define GPS_MODEL_NAME_GPS166 "GPS166"
-#define GPS_MODEL_NAME_GPS167 "GPS167"
-#define GPS_MODEL_NAME_GPS167SV "GPS167SV"
-#define GPS_MODEL_NAME_GPS167PC "GPS167PC"
-#define GPS_MODEL_NAME_GPS167PCI "GPS167PCI"
-#define GPS_MODEL_NAME_GPS163 "GPS163"
-#define GPS_MODEL_NAME_GPS168PCI "GPS168PCI"
-#define GPS_MODEL_NAME_GPS161 "GPS161"
-#define GPS_MODEL_NAME_GPS169PCI "GPS169PCI"
-#define GPS_MODEL_NAME_TCR167PCI "TCR167PCI"
-#define GPS_MODEL_NAME_GPS164 "GPS164"
-#define GPS_MODEL_NAME_GPS170PCI "GPS170PCI"
-#define GPS_MODEL_NAME_PZF511 "PZF511"
-#define GPS_MODEL_NAME_GPS170 "GPS170"
-#define GPS_MODEL_NAME_TCR511 "TCR511"
-#define GPS_MODEL_NAME_AM511 "AM511"
-#define GPS_MODEL_NAME_MSF511 "MSF511"
-#define GPS_MODEL_NAME_GRC170 "GRC170"
-#define GPS_MODEL_NAME_GPS170PEX "GPS170PEX"
-#define GPS_MODEL_NAME_GPS162 "GPS162"
-#define GPS_MODEL_NAME_PTP270PEX "PTP270PEX"
-#define GPS_MODEL_NAME_FRC511PEX "FRC511PEX"
-#define GPS_MODEL_NAME_GEN170 "GEN170"
-#define GPS_MODEL_NAME_TCR170PEX "TCR170PEX"
-#define GPS_MODEL_NAME_WWVB511 "WWVB511"
-#define GPS_MODEL_NAME_MGR170 "MGR170"
-#define GPS_MODEL_NAME_JJY511 "JJY511"
-#define GPS_MODEL_NAME_PZF600 "PZF600"
-#define GPS_MODEL_NAME_TCR600 "TCR600"
-#define GPS_MODEL_NAME_GPS180 "GPS180"
-#define GPS_MODEL_NAME_GLN170 "GLN170"
-#define GPS_MODEL_NAME_GPS180PEX "GPS180PEX"
-#define GPS_MODEL_NAME_TCR180PEX "TCR180PEX"
-#define GPS_MODEL_NAME_PZF180PEX "PZF180PEX"
-#define GPS_MODEL_NAME_MGR180 "MGR180"
-#define GPS_MODEL_NAME_MSF600 "MSF600"
-#define GPS_MODEL_NAME_WWVB600 "WWVB600"
-#define GPS_MODEL_NAME_JJY600 "JJY600"
-#define GPS_MODEL_NAME_GPS180HS "GPS180HS"
-#define GPS_MODEL_NAME_GPS180AMC "GPS180AMC"
-#define GPS_MODEL_NAME_ESI180 "ESI180"
-#define GPS_MODEL_NAME_CPE180 "CPE180"
-#define GPS_MODEL_NAME_LNO180 "LNO180"
-#define GPS_MODEL_NAME_GRC180 "GRC180"
-#define GPS_MODEL_NAME_LIU "LIU"
-#define GPS_MODEL_NAME_DCF600HS "DCF600HS"
-#define GPS_MODEL_NAME_DCF600RS "DCF600RS"
-#define GPS_MODEL_NAME_MRI "MRI"
-#define GPS_MODEL_NAME_BPE "BPE"
-#define GPS_MODEL_NAME_GLN180PEX "GLN180PEX"
-#define GPS_MODEL_NAME_N2X "N2X"
-#define GPS_MODEL_NAME_RSC180 "RSC180"
-#define GPS_MODEL_NAME_LNE_GB "LNE_GB"
-#define GPS_MODEL_NAME_PPG180 "PPG180"
-#define GPS_MODEL_NAME_SCG "SCG"
-#define GPS_MODEL_NAME_MDU300 "MDU300"
-#define GPS_MODEL_NAME_SDI "SDI"
-#define GPS_MODEL_NAME_FDM180 "FDM180"
-#define GPS_MODEL_NAME_SPT "SPT"
-#define GPS_MODEL_NAME_PZF180 "PZF180"
-#define GPS_MODEL_NAME_REL1000 "REL1000"
-#define GPS_MODEL_NAME_HPS100 "HPS100"
-#define GPS_MODEL_NAME_VSG180 "VSG180"
-#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_GNS181PEX "GNS181PEX"
-#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"
-#define GPS_MODEL_NAME_LSG180 "LSG180"
-#define GPS_MODEL_NAME_GPS190 "GPS190"
-#define GPS_MODEL_NAME_GNS181 "GNS181"
+#define GPS_MODEL_NAME_UNKNOWN "Unknown"
+#define GPS_MODEL_NAME_GPS166 "GPS166"
+#define GPS_MODEL_NAME_GPS167 "GPS167"
+#define GPS_MODEL_NAME_GPS167SV "GPS167SV"
+#define GPS_MODEL_NAME_GPS167PC "GPS167PC"
+#define GPS_MODEL_NAME_GPS167PCI "GPS167PCI"
+#define GPS_MODEL_NAME_GPS163 "GPS163"
+#define GPS_MODEL_NAME_GPS168PCI "GPS168PCI"
+#define GPS_MODEL_NAME_GPS161 "GPS161"
+#define GPS_MODEL_NAME_GPS169PCI "GPS169PCI"
+#define GPS_MODEL_NAME_TCR167PCI "TCR167PCI"
+#define GPS_MODEL_NAME_GPS164 "GPS164"
+#define GPS_MODEL_NAME_GPS170PCI "GPS170PCI"
+#define GPS_MODEL_NAME_PZF511 "PZF511"
+#define GPS_MODEL_NAME_GPS170 "GPS170"
+#define GPS_MODEL_NAME_TCR511 "TCR511"
+#define GPS_MODEL_NAME_AM511 "AM511"
+#define GPS_MODEL_NAME_MSF511 "MSF511"
+#define GPS_MODEL_NAME_GRC170 "GRC170"
+#define GPS_MODEL_NAME_GPS170PEX "GPS170PEX"
+#define GPS_MODEL_NAME_GPS162 "GPS162"
+#define GPS_MODEL_NAME_PTP270PEX "PTP270PEX"
+#define GPS_MODEL_NAME_FRC511PEX "FRC511PEX"
+#define GPS_MODEL_NAME_GEN170 "GEN170"
+#define GPS_MODEL_NAME_TCR170PEX "TCR170PEX"
+#define GPS_MODEL_NAME_WWVB511 "WWVB511"
+#define GPS_MODEL_NAME_MGR170 "MGR170"
+#define GPS_MODEL_NAME_JJY511 "JJY511"
+#define GPS_MODEL_NAME_PZF600 "PZF600"
+#define GPS_MODEL_NAME_TCR600 "TCR600"
+#define GPS_MODEL_NAME_GPS180 "GPS180"
+#define GPS_MODEL_NAME_GLN170 "GLN170"
+#define GPS_MODEL_NAME_GPS180PEX "GPS180PEX"
+#define GPS_MODEL_NAME_TCR180PEX "TCR180PEX"
+#define GPS_MODEL_NAME_PZF180PEX "PZF180PEX"
+#define GPS_MODEL_NAME_MGR180 "MGR180"
+#define GPS_MODEL_NAME_MSF600 "MSF600"
+#define GPS_MODEL_NAME_WWVB600 "WWVB600"
+#define GPS_MODEL_NAME_JJY600 "JJY600"
+#define GPS_MODEL_NAME_GPS180HS "GPS180HS"
+#define GPS_MODEL_NAME_GPS180AMC "GPS180AMC"
+#define GPS_MODEL_NAME_ESI180 "ESI180"
+#define GPS_MODEL_NAME_CPE180 "CPE180"
+#define GPS_MODEL_NAME_LNO180 "LNO180"
+#define GPS_MODEL_NAME_GRC180 "GRC180"
+#define GPS_MODEL_NAME_LIU "LIU"
+#define GPS_MODEL_NAME_DCF600HS "DCF600HS"
+#define GPS_MODEL_NAME_DCF600RS "DCF600RS"
+#define GPS_MODEL_NAME_MRI "MRI"
+#define GPS_MODEL_NAME_BPE "BPE"
+#define GPS_MODEL_NAME_GLN180PEX "GLN180PEX"
+#define GPS_MODEL_NAME_N2X "N2X"
+#define GPS_MODEL_NAME_RSC180 "RSC180"
+#define GPS_MODEL_NAME_LNE_GB "LNE_GB"
+#define GPS_MODEL_NAME_PPG180 "PPG180"
+#define GPS_MODEL_NAME_SCG "SCG"
+#define GPS_MODEL_NAME_MDU300 "MDU300"
+#define GPS_MODEL_NAME_SDI "SDI"
+#define GPS_MODEL_NAME_FDM180 "FDM180"
+#define GPS_MODEL_NAME_SPT "SPT"
+#define GPS_MODEL_NAME_PZF180 "PZF180"
+#define GPS_MODEL_NAME_REL1000 "REL1000"
+#define GPS_MODEL_NAME_HPS100 "HPS100"
+#define GPS_MODEL_NAME_VSG180 "VSG180"
+#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_GNS181PEX "GNS181PEX"
+#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"
+#define GPS_MODEL_NAME_LSG180 "LSG180"
+#define GPS_MODEL_NAME_GPS190 "GPS190"
+#define GPS_MODEL_NAME_GNS181 "GNS181"
+#define GPS_MODEL_NAME_PIO180 "PIO180"
+#define GPS_MODEL_NAME_FCM180 "FCM180"
+#define GPS_MODEL_NAME_TCR180USB "TCR180USB"
+#define GPS_MODEL_NAME_SSP100 "SSP100"
+#define GPS_MODEL_NAME_GNS165 "GNS165"
+#define GPS_MODEL_NAME_RSC180RDMP "RSC180RDMP"
+#define GPS_MODEL_NAME_GPS16X "GPS16x"
+#define GPS_MODEL_NAME_MSHPS100 "MSHPS100"
+/*
+ * CARE MUST BE TAKEN that the name string of bus level devices
+ * is limited to 9 characters. Longer strings will not fit into
+ * the name field of the PCPS_DEV_TYPE structure.
+ */
/** @} anchor GPS_MODEL_NAMES */
@@ -1175,7 +1254,15 @@ enum GPS_MODEL_CODES
GPS_MODEL_NAME_FDM180M, \
GPS_MODEL_NAME_LSG180, \
GPS_MODEL_NAME_GPS190, \
- GPS_MODEL_NAME_GNS181 \
+ GPS_MODEL_NAME_GNS181, \
+ GPS_MODEL_NAME_PIO180, \
+ GPS_MODEL_NAME_FCM180, \
+ GPS_MODEL_NAME_TCR180USB, \
+ GPS_MODEL_NAME_SSP100, \
+ GPS_MODEL_NAME_GNS165, \
+ GPS_MODEL_NAME_RSC180RDMP, \
+ GPS_MODEL_NAME_GPS16X, \
+ GPS_MODEL_NAME_MSHPS100 \
}
@@ -1230,8 +1317,10 @@ enum GPS_BUILTIN_FEATURE_BITS
GPS_BIT_MODEL_HAS_ANT_CABLE_LEN,
GPS_BIT_MODEL_HAS_SCU_STAT,
GPS_BIT_MODEL_HAS_SV_INFO,
+ GPS_BIT_MODEL_HAS_UP_CONV, ///< Instead of a standard L1 antenna, a Meinberg antenna/converter can be used with this GNSS device.
+ GPS_BIT_MODEL_HAS_MBG_OS, ///< This model can be a management CPU for meinbergOS (i.e. v7)
- GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV,
+ GPS_BIT_MODEL_HAS_XMR_HOLDOVER_INTV__REMOVE_THIS, // TODO FIXME
#if 0 //### TODO This has to be discussed
GPS_BIT_MODEL_IS_LNO,
@@ -1274,14 +1363,16 @@ enum GPS_BUILTIN_FEATURE_BITS
#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
+#define GPS_MODEL_HAS_UP_CONV ( 1UL << GPS_BIT_MODEL_HAS_UP_CONV ) ///< see ::GPS_BIT_MODEL_HAS_UP_CONV
+#define GPS_MODEL_HAS_MBG_OS ( 1UL << GPS_BIT_MODEL_HAS_MBG_OS ) ///< see ::GPS_BIT_MODEL_HAS_MBG_OS
#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
-// ### 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 FIXME do we need the next one? Should be obsolete
+// #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?
#define GPS_MODEL_HAS_POS ( GPS_MODEL_HAS_POS_XYZ | GPS_MODEL_HAS_POS_LLA )
@@ -1503,6 +1594,7 @@ enum GPS_BUILTIN_FEATURE_BITS
*/
#define BUILTIN_FEAT_DCF_PZF_2 \
( \
+ GPS_MODEL_IS_DCF_AM | \
GPS_MODEL_IS_DCF_PZF | \
GPS_MODEL_HAS_TIME_TTM | \
GPS_MODEL_HAS_TZDL | \
@@ -1690,11 +1782,11 @@ enum GPS_BUILTIN_FEATURE_BITS
#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_VSG180 ( GPS_MODEL_HAS_TZDL )
#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_CTC100 ( GPS_MODEL_HAS_MBG_OS )
#define BUILTIN_FEAT_TCR180 ( BUILTIN_FEAT_TCR_2 )
#define BUILTIN_FEAT_LUE180 ( 0 )
#define BUILTIN_FEAT_CPC_01 ( 0 )
@@ -1702,7 +1794,7 @@ enum GPS_BUILTIN_FEATURE_BITS
#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_CSM100 ( GPS_MODEL_HAS_MBG_OS )
#define BUILTIN_FEAT_LNE180SFP ( 0 )
#define BUILTIN_FEAT_GTS180 ( 0 )
#define BUILTIN_FEAT_GPS180CSM ( BUILTIN_FEAT_GPS )
@@ -1712,14 +1804,22 @@ enum GPS_BUILTIN_FEATURE_BITS
#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_GNS181_UC ( BUILTIN_FEAT_GNSS | GPS_MODEL_HAS_UP_CONV )
+#define BUILTIN_FEAT_PSX_4GE ( GPS_MODEL_HAS_MBG_OS )
#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 )
#define BUILTIN_FEAT_LSG180 ( 0 )
#define BUILTIN_FEAT_GPS190 ( BUILTIN_FEAT_GPS )
#define BUILTIN_FEAT_GNS181 ( BUILTIN_FEAT_GNSS )
+#define BUILTIN_FEAT_PIO180 ( 0 )
+#define BUILTIN_FEAT_FCM180 ( 0 )
+#define BUILTIN_FEAT_TCR180USB ( 0 )
+#define BUILTIN_FEAT_SSP100 ( GPS_MODEL_HAS_MBG_OS )
+#define BUILTIN_FEAT_GNS165 ( BUILTIN_FEAT_GNSS )
+#define BUILTIN_FEAT_RSC180RDMP ( GPS_MODEL_HAS_SCU_STAT )
+#define BUILTIN_FEAT_GPS16X ( BUILTIN_FEAT_GPS )
+#define BUILTIN_FEAT_MSHPS100 ( GPS_MODEL_HAS_MBG_OS )
/**
* @brief Feature mask used for legacy devices
@@ -1735,6 +1835,8 @@ enum GPS_BUILTIN_FEATURE_BITS
+#if !defined( MBG_TGT_DOS )
+
/**
* @brief Initializer for a table of built-in features per device
*
@@ -1743,103 +1845,113 @@ enum GPS_BUILTIN_FEATURE_BITS
* @see ::GPS_MODEL_CODES
* @see @ref GPS_MODEL_BUILTIN_FEATURE_MASKS
*/
-#define GPS_MODEL_BUILTIN_FEATURES \
-{ \
- { GPS_MODEL_GPS166, BUILTIN_FEAT_GPS166 }, \
- { GPS_MODEL_GPS167, BUILTIN_FEAT_GPS167 }, \
- { GPS_MODEL_GPS167SV, BUILTIN_FEAT_GPS167SV }, \
- { GPS_MODEL_GPS167PC, BUILTIN_FEAT_GPS167PC }, \
- { GPS_MODEL_GPS167PCI, BUILTIN_FEAT_GPS167PCI }, \
- { GPS_MODEL_GPS163, BUILTIN_FEAT_GPS163 }, \
- { GPS_MODEL_GPS168PCI, BUILTIN_FEAT_GPS168PCI }, \
- { GPS_MODEL_GPS161, BUILTIN_FEAT_GPS161 }, \
- { GPS_MODEL_GPS169PCI, BUILTIN_FEAT_GPS169PCI }, \
- { GPS_MODEL_TCR167PCI, BUILTIN_FEAT_TCR167PCI }, \
- { GPS_MODEL_GPS164, BUILTIN_FEAT_GPS164 }, \
- { GPS_MODEL_GPS170PCI, BUILTIN_FEAT_GPS170PCI }, \
- { GPS_MODEL_PZF511, BUILTIN_FEAT_PZF511 }, \
- { GPS_MODEL_GPS170, BUILTIN_FEAT_GPS170 }, \
- { GPS_MODEL_TCR511, BUILTIN_FEAT_TCR511 }, \
- { GPS_MODEL_AM511, BUILTIN_FEAT_AM511 }, \
- { GPS_MODEL_MSF511, BUILTIN_FEAT_MSF511 }, \
- { GPS_MODEL_GRC170, BUILTIN_FEAT_GRC170 }, \
- { GPS_MODEL_GPS170PEX, BUILTIN_FEAT_GPS170PEX }, \
- { GPS_MODEL_GPS162, BUILTIN_FEAT_GPS162 }, \
- { GPS_MODEL_PTP270PEX, BUILTIN_FEAT_PTP270PEX }, \
- { GPS_MODEL_FRC511PEX, BUILTIN_FEAT_FRC511PEX }, \
- { GPS_MODEL_GEN170, BUILTIN_FEAT_GEN170 }, \
- { GPS_MODEL_TCR170PEX, BUILTIN_FEAT_TCR170PEX }, \
- { GPS_MODEL_WWVB511, BUILTIN_FEAT_WWVB511 }, \
- { GPS_MODEL_MGR170, BUILTIN_FEAT_MGR170 }, \
- { GPS_MODEL_JJY511, BUILTIN_FEAT_JJY511 }, \
- { GPS_MODEL_PZF600, BUILTIN_FEAT_PZF600 }, \
- { GPS_MODEL_TCR600, BUILTIN_FEAT_TCR600 }, \
- { GPS_MODEL_GPS180, BUILTIN_FEAT_GPS180 }, \
- { GPS_MODEL_GLN170, BUILTIN_FEAT_GLN170 }, \
- { GPS_MODEL_GPS180PEX, BUILTIN_FEAT_GPS180PEX }, \
- { GPS_MODEL_TCR180PEX, BUILTIN_FEAT_TCR180PEX }, \
- { GPS_MODEL_PZF180PEX, BUILTIN_FEAT_PZF180PEX }, \
- { GPS_MODEL_MGR180, BUILTIN_FEAT_MGR180 }, \
- { GPS_MODEL_MSF600, BUILTIN_FEAT_MSF600 }, \
- { GPS_MODEL_WWVB600, BUILTIN_FEAT_WWVB600 }, \
- { GPS_MODEL_JJY600, BUILTIN_FEAT_JJY600 }, \
- { GPS_MODEL_GPS180HS, BUILTIN_FEAT_GPS180HS }, \
- { GPS_MODEL_GPS180AMC, BUILTIN_FEAT_GPS180AMC }, \
- { GPS_MODEL_ESI180, BUILTIN_FEAT_ESI180 }, \
- { GPS_MODEL_CPE180, BUILTIN_FEAT_CPE180 }, \
- { GPS_MODEL_LNO180, BUILTIN_FEAT_LNO180 }, \
- { GPS_MODEL_GRC180, BUILTIN_FEAT_GRC180 }, \
- { GPS_MODEL_LIU, BUILTIN_FEAT_LIU }, \
- { GPS_MODEL_DCF600HS, BUILTIN_FEAT_DCF600HS }, \
- { GPS_MODEL_DCF600RS, BUILTIN_FEAT_DCF600RS }, \
- { GPS_MODEL_MRI, BUILTIN_FEAT_MRI }, \
- { GPS_MODEL_BPE, BUILTIN_FEAT_BPE }, \
- { GPS_MODEL_GLN180PEX, BUILTIN_FEAT_GLN180PEX }, \
- { GPS_MODEL_N2X, BUILTIN_FEAT_N2X }, \
- { GPS_MODEL_RSC180, BUILTIN_FEAT_RSC180 }, \
- { GPS_MODEL_LNE_GB, BUILTIN_FEAT_LNE_GB }, \
- { GPS_MODEL_PPG180, BUILTIN_FEAT_PPG180 }, \
- { GPS_MODEL_SCG, BUILTIN_FEAT_SCG }, \
- { GPS_MODEL_MDU300, BUILTIN_FEAT_MDU300 }, \
- { GPS_MODEL_SDI, BUILTIN_FEAT_SDI }, \
- { GPS_MODEL_FDM180, BUILTIN_FEAT_FDM180 }, \
- { GPS_MODEL_SPT, BUILTIN_FEAT_SPT }, \
- { GPS_MODEL_PZF180, BUILTIN_FEAT_PZF180 }, \
- { GPS_MODEL_REL1000, BUILTIN_FEAT_REL1000 }, \
- { GPS_MODEL_HPS100, BUILTIN_FEAT_HPS100 }, \
- { GPS_MODEL_VSG180, BUILTIN_FEAT_VSG180 }, \
- { 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_GNS181PEX, BUILTIN_FEAT_GNS181PEX }, \
- { 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 }, \
- { GPS_MODEL_LSG180, BUILTIN_FEAT_LSG180 }, \
- { GPS_MODEL_GPS190, BUILTIN_FEAT_GPS190 }, \
- { GPS_MODEL_GNS181, BUILTIN_FEAT_GNS181 }, \
- { 0, 0 } \
+#define GPS_MODEL_BUILTIN_FEATURES \
+{ \
+ { GPS_MODEL_GPS166, BUILTIN_FEAT_GPS166 }, \
+ { GPS_MODEL_GPS167, BUILTIN_FEAT_GPS167 }, \
+ { GPS_MODEL_GPS167SV, BUILTIN_FEAT_GPS167SV }, \
+ { GPS_MODEL_GPS167PC, BUILTIN_FEAT_GPS167PC }, \
+ { GPS_MODEL_GPS167PCI, BUILTIN_FEAT_GPS167PCI }, \
+ { GPS_MODEL_GPS163, BUILTIN_FEAT_GPS163 }, \
+ { GPS_MODEL_GPS168PCI, BUILTIN_FEAT_GPS168PCI }, \
+ { GPS_MODEL_GPS161, BUILTIN_FEAT_GPS161 }, \
+ { GPS_MODEL_GPS169PCI, BUILTIN_FEAT_GPS169PCI }, \
+ { GPS_MODEL_TCR167PCI, BUILTIN_FEAT_TCR167PCI }, \
+ { GPS_MODEL_GPS164, BUILTIN_FEAT_GPS164 }, \
+ { GPS_MODEL_GPS170PCI, BUILTIN_FEAT_GPS170PCI }, \
+ { GPS_MODEL_PZF511, BUILTIN_FEAT_PZF511 }, \
+ { GPS_MODEL_GPS170, BUILTIN_FEAT_GPS170 }, \
+ { GPS_MODEL_TCR511, BUILTIN_FEAT_TCR511 }, \
+ { GPS_MODEL_AM511, BUILTIN_FEAT_AM511 }, \
+ { GPS_MODEL_MSF511, BUILTIN_FEAT_MSF511 }, \
+ { GPS_MODEL_GRC170, BUILTIN_FEAT_GRC170 }, \
+ { GPS_MODEL_GPS170PEX, BUILTIN_FEAT_GPS170PEX }, \
+ { GPS_MODEL_GPS162, BUILTIN_FEAT_GPS162 }, \
+ { GPS_MODEL_PTP270PEX, BUILTIN_FEAT_PTP270PEX }, \
+ { GPS_MODEL_FRC511PEX, BUILTIN_FEAT_FRC511PEX }, \
+ { GPS_MODEL_GEN170, BUILTIN_FEAT_GEN170 }, \
+ { GPS_MODEL_TCR170PEX, BUILTIN_FEAT_TCR170PEX }, \
+ { GPS_MODEL_WWVB511, BUILTIN_FEAT_WWVB511 }, \
+ { GPS_MODEL_MGR170, BUILTIN_FEAT_MGR170 }, \
+ { GPS_MODEL_JJY511, BUILTIN_FEAT_JJY511 }, \
+ { GPS_MODEL_PZF600, BUILTIN_FEAT_PZF600 }, \
+ { GPS_MODEL_TCR600, BUILTIN_FEAT_TCR600 }, \
+ { GPS_MODEL_GPS180, BUILTIN_FEAT_GPS180 }, \
+ { GPS_MODEL_GLN170, BUILTIN_FEAT_GLN170 }, \
+ { GPS_MODEL_GPS180PEX, BUILTIN_FEAT_GPS180PEX }, \
+ { GPS_MODEL_TCR180PEX, BUILTIN_FEAT_TCR180PEX }, \
+ { GPS_MODEL_PZF180PEX, BUILTIN_FEAT_PZF180PEX }, \
+ { GPS_MODEL_MGR180, BUILTIN_FEAT_MGR180 }, \
+ { GPS_MODEL_MSF600, BUILTIN_FEAT_MSF600 }, \
+ { GPS_MODEL_WWVB600, BUILTIN_FEAT_WWVB600 }, \
+ { GPS_MODEL_JJY600, BUILTIN_FEAT_JJY600 }, \
+ { GPS_MODEL_GPS180HS, BUILTIN_FEAT_GPS180HS }, \
+ { GPS_MODEL_GPS180AMC, BUILTIN_FEAT_GPS180AMC }, \
+ { GPS_MODEL_ESI180, BUILTIN_FEAT_ESI180 }, \
+ { GPS_MODEL_CPE180, BUILTIN_FEAT_CPE180 }, \
+ { GPS_MODEL_LNO180, BUILTIN_FEAT_LNO180 }, \
+ { GPS_MODEL_GRC180, BUILTIN_FEAT_GRC180 }, \
+ { GPS_MODEL_LIU, BUILTIN_FEAT_LIU }, \
+ { GPS_MODEL_DCF600HS, BUILTIN_FEAT_DCF600HS }, \
+ { GPS_MODEL_DCF600RS, BUILTIN_FEAT_DCF600RS }, \
+ { GPS_MODEL_MRI, BUILTIN_FEAT_MRI }, \
+ { GPS_MODEL_BPE, BUILTIN_FEAT_BPE }, \
+ { GPS_MODEL_GLN180PEX, BUILTIN_FEAT_GLN180PEX }, \
+ { GPS_MODEL_N2X, BUILTIN_FEAT_N2X }, \
+ { GPS_MODEL_RSC180, BUILTIN_FEAT_RSC180 }, \
+ { GPS_MODEL_LNE_GB, BUILTIN_FEAT_LNE_GB }, \
+ { GPS_MODEL_PPG180, BUILTIN_FEAT_PPG180 }, \
+ { GPS_MODEL_SCG, BUILTIN_FEAT_SCG }, \
+ { GPS_MODEL_MDU300, BUILTIN_FEAT_MDU300 }, \
+ { GPS_MODEL_SDI, BUILTIN_FEAT_SDI }, \
+ { GPS_MODEL_FDM180, BUILTIN_FEAT_FDM180 }, \
+ { GPS_MODEL_SPT, BUILTIN_FEAT_SPT }, \
+ { GPS_MODEL_PZF180, BUILTIN_FEAT_PZF180 }, \
+ { GPS_MODEL_REL1000, BUILTIN_FEAT_REL1000 }, \
+ { GPS_MODEL_HPS100, BUILTIN_FEAT_HPS100 }, \
+ { GPS_MODEL_VSG180, BUILTIN_FEAT_VSG180 }, \
+ { 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_GNS181PEX, BUILTIN_FEAT_GNS181PEX }, \
+ { 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 }, \
+ { GPS_MODEL_LSG180, BUILTIN_FEAT_LSG180 }, \
+ { GPS_MODEL_GPS190, BUILTIN_FEAT_GPS190 }, \
+ { GPS_MODEL_GNS181, BUILTIN_FEAT_GNS181 }, \
+ { GPS_MODEL_PIO180, BUILTIN_FEAT_PIO180 }, \
+ { GPS_MODEL_FCM180, BUILTIN_FEAT_FCM180 }, \
+ { GPS_MODEL_TCR180USB, BUILTIN_FEAT_TCR180USB }, \
+ { GPS_MODEL_SSP100, BUILTIN_FEAT_SSP100 }, \
+ { GPS_MODEL_GNS165, BUILTIN_FEAT_GNS165 }, \
+ { GPS_MODEL_RSC180RDMP, BUILTIN_FEAT_RSC180RDMP }, \
+ { GPS_MODEL_GPS16X, BUILTIN_FEAT_GPS16X }, \
+ { GPS_MODEL_MSHPS100, BUILTIN_FEAT_MSHPS100 }, \
+ { 0, 0 } \
}
+#endif // !defined( MBG_TGT_DOS )
+
/** @} anchor GPS_BUILTIN_FEATURE_DEFS */
@@ -2230,22 +2342,31 @@ enum GPS_FEATURE_BITS
*/
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
+ 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_TAINTED_CFG, ///< Supports tainted config structures, see @ref group_tainted_cfg
+ MBG_XFEATURE_PUSH_MSGS, ///< Supports commands ::GPS_REGISTER_PUSH_MSGS and ::GPS_UNREGISTER_PUSH_MSGS
+ MBG_XFEATURE_USER_AUTH, ///< Supports user authentication and command ::GPS_AUTH_USER_INFO
+ MBG_XFEATURE_USER_MNGMNT, ///< Supports user management, see @ref group_user_mngmnt
+ MBG_XFEATURE_SERVICE, ///< Supports service management, see @ref group_service_mngmnt
+ MBG_XFEATURE_UP_CONV, ///< Instead of a standard L1 antenna, a Meinberg antenna/converter can be used with this GNSS device.
+ MBG_XFEATURE_FW_MNGMNT, ///< Supports firmware management, see @ref group_fw_mngmnt
+ MBG_XFEATURE_DAC_CTRL_PCI, ///< Supports DAC control via PCI or USB bus API.
+ MBG_XFEATURE_DATABASE, ///< Supports database(s), see @ref group_database
+ MBG_XFEATURE_GNSS_MODE, ///< Supports GPS_GNSS_MODE
+ 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.
@@ -2270,14 +2391,23 @@ enum MBG_XFEATURE_BITS
"Power Control API", \
"Extended Revision Info", \
"Transaction commands", \
- "Reboot command", \
+ "Reboot Command", \
"Clock Resolution Info", \
"Extended User Captures", \
"Request TTM", \
"I/O Ports", \
"Monitoring", \
- "XHE unit", \
- "USB lock" \
+ "XHE Unit", \
+ "Tainted Config", \
+ "Push Messages", \
+ "User Authentication", \
+ "User Management", \
+ "Service Management", \
+ "Antenna Converter", \
+ "Firmware Management", \
+ "DAC control via bus", \
+ "Database", \
+ "GNSS Messages" \
}
@@ -3631,6 +3761,7 @@ enum STR_MODES
STR_PER_MIN, ///< transmission automatically if minute changes
STR_AUTO, ///< transmission automatically if required, e.g. on capture event
STR_ON_REQ_SEC, ///< transmission if second changes and a request has been received before
+ STR_CR_ON_SEC, ///< transmisson automatically if second changes, but carriage return (0x13) on time
N_STR_MODE ///< the number of known modes
};
@@ -3649,7 +3780,8 @@ enum STR_MODE_MASKS
MSK_STR_PER_SEC = ( 1UL << STR_PER_SEC ), ///< see ::STR_PER_SEC
MSK_STR_PER_MIN = ( 1UL << STR_PER_MIN ), ///< see ::STR_PER_MIN
MSK_STR_AUTO = ( 1UL << STR_AUTO ), ///< see ::STR_AUTO
- MSK_STR_ON_REQ_SEC = ( 1UL << STR_ON_REQ_SEC ) ///< see ::STR_ON_REQ_SEC
+ MSK_STR_ON_REQ_SEC = ( 1UL << STR_ON_REQ_SEC ), ///< see ::STR_ON_REQ_SEC
+ MSK_STR_CR_ON_SEC = ( 1UL << STR_CR_ON_SEC ) ///< see ::STR_CR_ON_SEC
};
@@ -3664,7 +3796,8 @@ enum STR_MODE_MASKS
"1 sec", \
"1 min", \
"auto", \
- "'?' sec" \
+ "'?' sec", \
+ "<CR> on sec" \
}
@@ -3680,6 +3813,7 @@ enum STR_MODE_MASKS
#define ENG_MODE_NAME_STR_PER_MIN "per minute"
#define ENG_MODE_NAME_STR_AUTO "automatically"
#define ENG_MODE_NAME_STR_ON_REQ_SEC "sec after request"
+#define ENG_MODE_NAME_STR_CR_ON_SEC "per second, <CR> on second change"
/**
@@ -3695,7 +3829,8 @@ enum STR_MODE_MASKS
ENG_MODE_NAME_STR_PER_SEC, \
ENG_MODE_NAME_STR_PER_MIN, \
ENG_MODE_NAME_STR_AUTO, \
- ENG_MODE_NAME_STR_ON_REQ_SEC \
+ ENG_MODE_NAME_STR_ON_REQ_SEC, \
+ ENG_MODE_NAME_STR_CR_ON_SEC \
}
@@ -3786,13 +3921,15 @@ enum STR_MODE_MASKS
/**
* @brief A The structure used to store the configuration of two serial ports
*
- * @deprecated This structure is deprecated, ::PORT_SETTINGS and related structures
- * should be used instead, if supported by the device.
+ * @deprecated This structure is deprecated and should only be used
+ * with legacy GPS receivers that don't provide a ::RECEIVER_INFO structure.
+ *
+ * @see ::PORT_SETTINGS and ::PORT_INFO for current devices
*/
typedef struct
{
COM_PARM com[DEFAULT_N_COM]; ///< COM0 and COM1 settings
- uint8_t mode[DEFAULT_N_COM]; ///< COM0 and COM1 output mode
+ uint8_t mode[DEFAULT_N_COM]; ///< COM0 and COM1 output mode, see ::LGCY_STR_MODES
} PORT_PARM;
@@ -3808,26 +3945,34 @@ do \
} while ( 0 )
+
/**
- * @brief Deprecated codes for mode of operation
+ * @brief Deprecated codes for serial string modes
*
* @deprecated These codes have been used with the
- * deprecated ::PORT_PARM::mode. They are only still
- * defined for compatibility with older devices.
+ * deprecated ::PORT_PARM::mode field and are still
+ * defined for compatibility reasons.
*
* @see ::STR_MODES
*/
-enum
+enum LGCY_STR_MODES
{
- /* STR_ON_REQ, defined above */
- /* STR_PER_SEC, defined above */
- /* STR_PER_MIN, defined above */
- N_STR_MODE_0 = STR_AUTO, /* COM0 and COM1 */
- STR_UCAP = N_STR_MODE_0,
- STR_UCAP_REQ,
- N_STR_MODE_1 /* COM1 only */
+ LGCY_STR_ON_REQ, ///< On request '?' only, same as ::STR_ON_REQ, COM0 and COM1
+ LGCY_STR_PER_SEC, ///< Per second, same as ::STR_PER_SEC, COM0 and COM1
+ LGCY_STR_PER_MIN, ///< Per minute, same as ::STR_PER_MIN, COM0 and COM1
+ LGCY_STR_UCAP, ///< Automatically, when a capture event has occurred, COM1 only
+ LGCY_STR_UCAP_REQ, ///< On request only, if a capture event is available, COM1 only
+ N_LGCY_STR_MODES ///< Number of legacy string modes
};
+#if _IS_MBG_FIRMWARE // Old symbols for source code compatibility ...
+ #define STR_UCAP LGCY_STR_UCAP // Same numeric value as ::STR_AUTO
+ #define STR_UCAP_REQ LGCY_STR_UCAP_REQ // Same numeric value as ::STR_ON_REQ_SEC, but different function
+
+ #define N_STR_MODE_0 ( LGCY_STR_PER_MIN + 1 ) // Number of modes supp. for COM0
+ #define N_STR_MODE_1 N_LGCY_STR_MODES // Number of modes supp. for COM1
+#endif
+
/**
@@ -5652,12 +5797,15 @@ enum POUT_MODES
/// 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.
+ /// Generate a pulse at the time specified in the ::POUT_TIME[0]::on field
+ /// in ::POUT_DATA::tm of the ::POUT_SETTINGS (POUT_SETTINGS::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.
+ /// Generate a cyclic pulse at the interval specified in ::MBG_DATE_TIME::t
+ /// field of ::POUT_TIME[0]::on in ::POUT_DATA::tm of the ::POUT_SETTINGS
+ /// (POUT_SETTINGS::tm[0].on.t).
/// Pulse length according to ::POUT_SETTINGS::mode_param, in [10 ms] units.
/// See ::MAX_POUT_PULSE_LEN.
POUT_CYCLIC_PULSE,
@@ -6322,7 +6470,7 @@ enum MULTI_REF_TYPES
"(reserved)", \
"DCF77 PZF Receiver", \
"Long Wave Receiver", \
- "GLONASS/GPS Receiver", \
+ "GNSS Receiver", \
"HaveQuick Input", \
"ext. Osc.", \
"Synchronous Ethernet" \
@@ -6351,7 +6499,7 @@ enum MULTI_REF_TYPES
"(reserved)", \
"PZF", \
"LWR", \
- "GGR", \
+ "GNSS", \
"HQI", \
"EXT", \
"SYNCE" \
@@ -6622,6 +6770,10 @@ 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
+ XMRSF_BIT_IS_TRUSTED_SRC, ///< src can be used as a trusted src for spoofing detection
+ XMRSF_BIT_USE_TRUSTED_SRC, ///< use a trusted source for consistency check and spoofing detection
+ XMRSF_BIT_IS_TIME_OF_DAY_SRC, ///< src can be used for time of day synchronization
+ XMRSF_BIT_IS_PHASE_SRC, ///< src can be used for phase synchronization
N_XMRSF_BITS ///< number of known flag bits
};
@@ -6633,7 +6785,11 @@ enum XMR_SETTINGS_FLAG_MSKS
{
XMRSF_MSK_AUTO_BIAS_MASTER = ( 1UL << XMRSF_BIT_AUTO_BIAS_MASTER ), ///< see ::XMRSF_BIT_AUTO_BIAS_MASTER
XMRSF_MSK_AUTO_BIAS_SLAVE = ( 1UL << XMRSF_BIT_AUTO_BIAS_SLAVE ), ///< see ::XMRSF_BIT_AUTO_BIAS_SLAVE
- XMRSF_MSK_ASYMMETRY_STEP_DETECTION = ( 1UL << XMRSF_BIT_ASYMMETRY_STEP_DETECTION ) ///< see ::XMRSF_BIT_ASYMMETRY_STEP_DETECTION
+ XMRSF_MSK_ASYMMETRY_STEP_DETECTION = ( 1UL << XMRSF_BIT_ASYMMETRY_STEP_DETECTION ), ///< see ::XMRSF_BIT_ASYMMETRY_STEP_DETECTION
+ XMRSF_MSK_IS_TRUSTED_SRC = ( 1UL << XMRSF_BIT_IS_TRUSTED_SRC ), ///< see ::XMRSF_BIT_IS_TRUSTED_SRC
+ XMRSF_MSK_USE_TRUSTED_SRC = ( 1UL << XMRSF_BIT_USE_TRUSTED_SRC ), ///< see ::XMRSF_BIT_USE_TRUSTED_SRC
+ XMRSF_MSK_IS_TIME_OF_DAY_SRC = ( 1UL << XMRSF_BIT_IS_TIME_OF_DAY_SRC ), ///< see ::XMRSF_BIT_IS_TIME_OF_DAY_SRC
+ XMRSF_MSK_IS_PHASE_SRC = ( 1UL << XMRSF_BIT_IS_PHASE_SRC ) ///< see ::XMRSF_BIT_IS_PHASE_SRC
};
@@ -6799,6 +6955,7 @@ enum XMR_REF_STATUS_BITS
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)
+ XMRS_BIT_TRS_LIMIT_VIOLATED, ///< Trusted source offset limit violated (valid if device has ::XMRSF_MSK_USE_TRUSTED_SRC)
N_XMRS_BITS ///< number of know status bits
};
@@ -6825,6 +6982,7 @@ enum XMR_REF_STATUS_BITS
#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
+#define XMRS_MSK_TRS_LIMIT_VIOLATED ( 1UL << XMRS_BIT_TRS_LIMIT_VIOLATED ) ///< see ::XMRS_BIT_TRS_LIMIT_VIOLATED
/** @} anchor XMR_REF_STATUS_BIT_MASKS */
@@ -6848,7 +7006,8 @@ enum XMR_REF_STATUS_BITS
"Number sources exceeds limit", \
"Is external", \
"Low jitter", \
- "ITU Limit violated" \
+ "ITU Limit violated", \
+ "TRS Limit violated" \
}
@@ -6928,6 +7087,7 @@ enum XMR_INST_FLAGS
XMRIF_BIT_HOLDOVER_STATUS_SUPP, ///< ::XMR_HOLDOVER_STATUS and associated types supported
XMRIF_BIT_EXT_SRC_INFO_SUPP, ///< ::XMR_EXT_SRC_INFO structure supported
+ XMRIF_BIT_GNSS_BIAS_SUPP, ///< ::MULTI_REF_GPS or MULTI_REF_GRC can use XMULTI_REF_SETTINGS::bias
N_XMRIF_BITS ///< number of known flag bits
};
@@ -6944,7 +7104,8 @@ enum XMR_INST_FLAG_BIT_MASKS
{
XMRIF_MSK_MRF_NONE_SUPP = ( 1UL << XMRIF_BIT_MRF_NONE_SUPP ), ///< see ::XMRIF_BIT_MRF_NONE_SUPP
XMRIF_MSK_HOLDOVER_STATUS_SUPP = ( 1UL << XMRIF_BIT_HOLDOVER_STATUS_SUPP ), ///< see ::XMRIF_BIT_HOLDOVER_STATUS_SUPP
- XMRIF_MSK_EXT_SRC_INFO_SUPP = ( 1UL << XMRIF_BIT_EXT_SRC_INFO_SUPP ) ///< see ::XMRIF_BIT_EXT_SRC_INFO_SUPP
+ XMRIF_MSK_EXT_SRC_INFO_SUPP = ( 1UL << XMRIF_BIT_EXT_SRC_INFO_SUPP ), ///< see ::XMRIF_BIT_EXT_SRC_INFO_SUPP
+ XMRIF_MSK_GNSS_BIAS_SUPP = ( 1UL << XMRIF_BIT_GNSS_BIAS_SUPP ) ///< see ::XMRIF_BIT_GNSS_BIAS_SUPP
};
@@ -7091,6 +7252,7 @@ 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
+ XMR_EXT_SRC_FEAT_FLAG_BIT_COASTING, ///< XMR source provides coasting mode
N_XMR_EXT_SRC_FEAT_FLAG_BITS
};
@@ -7105,8 +7267,9 @@ enum 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
+ 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
+ XMR_EXT_SRC_FEAT_FLAG_MSK_COASTING = ( 1UL << XMR_EXT_SRC_FEAT_FLAG_BIT_COASTING ) ///< see ::XMR_EXT_SRC_FEAT_FLAG_BIT_COASTING
};
@@ -7574,7 +7737,7 @@ enum MBG_GPIO_SIGNAL_SHAPE_MASKS
{ \
"(unspec. shape)", \
"Sine wave", \
- "Rectangle Pulse" \
+ "Rectangle pulse" \
}
@@ -9449,44 +9612,93 @@ do \
*/
enum MBG_EVT_IDS
{
- MBG_EVT_ID_NONE, ///< no event (empty entry)
- MBG_EVT_ID_POW_UP_RES, ///< power up reset
- MBG_EVT_ID_WDOG_RES, ///< watchdog reset
- MBG_EVT_ID_COLD_BOOT, ///< entering cold boot mode
- MBG_EVT_ID_WARM_BOOT, ///< entering warm boot mode
- MBG_EVT_ID_NORMAL_OP, ///< entering normal operation
- MBG_EVT_ID_ANT_DISCONN, ///< antenna disconnect detected
- MBG_EVT_ID_ANT_SHORT, ///< antenna short circuit detected
- MBG_EVT_ID_ANT_OK, ///< antenna OK after failure
- MBG_EVT_ID_LOW_SATS, ///< no satellites can be received though antenna not failing
+ MBG_EVT_ID_NONE, ///< no event (empty entry)
+ MBG_EVT_ID_POW_UP_RES, ///< power up reset
+ MBG_EVT_ID_WDOG_RES, ///< watchdog reset
+ MBG_EVT_ID_COLD_BOOT, ///< entering cold boot mode
+ MBG_EVT_ID_WARM_BOOT, ///< entering warm boot mode
+ MBG_EVT_ID_NORMAL_OP, ///< entering normal operation
+ MBG_EVT_ID_ANT_DISCONN, ///< antenna disconnect detected
+ MBG_EVT_ID_ANT_SHORT, ///< antenna short circuit detected
+ MBG_EVT_ID_ANT_OK, ///< antenna OK after failure
+ MBG_EVT_ID_LOW_SATS, ///< no satellites can be received though antenna not failing
+ MBG_EVT_ID_FW_INSTALLED, ///< Firmware has successfully been installed
+ MBG_EVT_ID_PTP_PORT_STATE_UNINITIALIZED, ///< PTP state changed to UNINITIALIZED
+ MBG_EVT_ID_PTP_PORT_STATE_INITIALIZING, ///< PTP state changed to INITIALIZING
+ MBG_EVT_ID_PTP_PORT_STATE_FAULTY, ///< PTP state changed to FAULTY
+ MBG_EVT_ID_PTP_PORT_STATE_DISABLED, ///< PTP state changed to DISABLED
+ MBG_EVT_ID_PTP_PORT_STATE_LISTENING, ///< PTP state changed to LISTENING
+ MBG_EVT_ID_PTP_PORT_STATE_PRE_MASTER, ///< PTP state changed to PRE_MASTER
+ MBG_EVT_ID_PTP_PORT_STATE_MASTER, ///< PTP state changed to MASTER
+ MBG_EVT_ID_PTP_PORT_STATE_PASSIVE, ///< PTP state changed to PASSIVE
+ MBG_EVT_ID_PTP_PORT_STATE_UNCALIBRATED, ///< PTP state changed to UNCALIBRATED
+ MBG_EVT_ID_PTP_PORT_STATE_SLAVE, ///< PTP state changed to SLAVE
+ MBG_EVT_ID_FW_ACTIVATED, ///< Firmware has been activated
+ MBG_EVT_ID_FW_DELETED, ///< Firmware has been deleted
+ MBG_EVT_ID_FW_ROLLBACK, ///< Firmware reset to factory defaults
+ MBG_EVT_ID_UFU_FLASHED, ///< UFU file has been flashed
+ MBG_EVT_ID_UFU_PROGRESS, ///< UFU flashing is in progress
+ MBG_EVT_ID_DATABASE_CONNECTED, ///< Database(s) have been (re-)connected
N_MBG_EVT_ID
};
-#define ENG_EVT_ID_NAME_NONE "No event"
-#define ENG_EVT_ID_NAME_POW_UP_RES "Power Up Reset"
-#define ENG_EVT_ID_NAME_WDOG_RES "Watchdog Reset"
-#define ENG_EVT_ID_NAME_COLD_BOOT "Cold Boot"
-#define ENG_EVT_ID_NAME_WARM_BOOT "Warm Boot"
-#define ENG_EVT_ID_NAME_NORMAL_OP "Normal Operation"
-#define ENG_EVT_ID_NAME_ANT_DISCONN "Antenna Disconn."
-#define ENG_EVT_ID_NAME_ANT_SHORT "Ant. Short-Circ."
-#define ENG_EVT_ID_NAME_ANT_OK "Antenna OK"
-#define ENG_EVT_ID_NAME_LOW_SATS "Few Sats Only"
-
-
-#define MBG_EVT_ID_NAMES_ENG \
-{ \
- ENG_EVT_ID_NAME_NONE, \
- ENG_EVT_ID_NAME_POW_UP_RES, \
- ENG_EVT_ID_NAME_WDOG_RES, \
- ENG_EVT_ID_NAME_COLD_BOOT, \
- ENG_EVT_ID_NAME_WARM_BOOT, \
- ENG_EVT_ID_NAME_NORMAL_OP, \
- ENG_EVT_ID_NAME_ANT_DISCONN, \
- ENG_EVT_ID_NAME_ANT_SHORT, \
- ENG_EVT_ID_NAME_ANT_OK, \
- ENG_EVT_ID_NAME_LOW_SATS \
+#define ENG_EVT_ID_NAME_NONE "No event"
+#define ENG_EVT_ID_NAME_POW_UP_RES "Power Up Reset"
+#define ENG_EVT_ID_NAME_WDOG_RES "Watchdog Reset"
+#define ENG_EVT_ID_NAME_COLD_BOOT "Cold Boot"
+#define ENG_EVT_ID_NAME_WARM_BOOT "Warm Boot"
+#define ENG_EVT_ID_NAME_NORMAL_OP "Normal Operation"
+#define ENG_EVT_ID_NAME_ANT_DISCONN "Antenna Disconn."
+#define ENG_EVT_ID_NAME_ANT_SHORT "Ant. Short-Circ."
+#define ENG_EVT_ID_NAME_ANT_OK "Antenna OK"
+#define ENG_EVT_ID_NAME_LOW_SATS "Few Sats Only"
+#define ENG_EVT_ID_NAME_FW_INSTALLED "Firmware installed"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_UNINITIALIZED "PTP state: UNINITIALIZED"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_INITIALIZING "PTP state: INITIALIZING"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_FAULTY "PTP state: FAULTY"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_DISABLED "PTP state: DISABLED"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_LISTENING "PTP state: LISTENING"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_PRE_MASTER "PTP state: PRE_MASTER"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_MASTER "PTP state: MASTER"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_PASSIVE "PTP state: PASSIVE"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_UNCALIBRATED "PTP state: UNCALIBRATED"
+#define ENG_EVT_ID_NAME_PTP_PORT_STATE_SLAVE "PTP state: SLAVE"
+#define ENG_EVT_ID_NAME_FW_ACTIVATED "Firmware activated"
+#define ENG_EVT_ID_NAME_FW_DELETED "Firmware deleted"
+#define ENG_EVT_ID_NAME_FW_ROLLBACK "Firmware rollback"
+#define ENG_EVT_ID_NAME_UFU_FLASHED "UFU flashed"
+#define ENG_EVT_ID_NAME_DATABASE_CONNECTED "Database(s) connected"
+
+
+#define MBG_EVT_ID_NAMES_ENG \
+{ \
+ ENG_EVT_ID_NAME_NONE, \
+ ENG_EVT_ID_NAME_POW_UP_RES, \
+ ENG_EVT_ID_NAME_WDOG_RES, \
+ ENG_EVT_ID_NAME_COLD_BOOT, \
+ ENG_EVT_ID_NAME_WARM_BOOT, \
+ ENG_EVT_ID_NAME_NORMAL_OP, \
+ ENG_EVT_ID_NAME_ANT_DISCONN, \
+ ENG_EVT_ID_NAME_ANT_SHORT, \
+ ENG_EVT_ID_NAME_ANT_OK, \
+ ENG_EVT_ID_NAME_LOW_SATS, \
+ ENG_EVT_ID_NAME_FW_INSTALLED, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_UNINITIALIZED, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_INITIALIZING, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_FAULTY, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_DISABLED, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_LISTENING, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_PRE_MASTER, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_MASTER, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_PASSIVE, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_UNCALIBRATED, \
+ ENG_EVT_ID_NAME_PTP_PORT_STATE_SLAVE, \
+ ENG_EVT_ID_NAME_FW_ACTIVATED, \
+ ENG_EVT_ID_NAME_FW_DELETED, \
+ ENG_EVT_ID_NAME_FW_ROLLBACK, \
+ ENG_EVT_ID_NAME_UFU_FLASHED, \
+ ENG_EVT_ID_NAME_DATABASE_CONNECTED \
}
@@ -9537,16 +9749,27 @@ enum MBG_EVT_LVLS
*
* @anchor MBG_EVENT_CODES @{ */
-#define MBG_EVT_NONE _mbg_mk_evt_code( MBG_EVT_ID_NONE, MBG_EVT_LVL_NONE )
-#define MBG_EVT_POW_UP_RES _mbg_mk_evt_code( MBG_EVT_ID_POW_UP_RES, MBG_EVT_LVL_WARN )
-#define MBG_EVT_WDOG_RES _mbg_mk_evt_code( MBG_EVT_ID_WDOG_RES, MBG_EVT_LVL_CRIT )
-#define MBG_EVT_COLD_BOOT _mbg_mk_evt_code( MBG_EVT_ID_COLD_BOOT, MBG_EVT_LVL_ERR )
-#define MBG_EVT_WARM_BOOT _mbg_mk_evt_code( MBG_EVT_ID_WARM_BOOT, MBG_EVT_LVL_ERR )
-#define MBG_EVT_NORMAL_OP _mbg_mk_evt_code( MBG_EVT_ID_NORMAL_OP, MBG_EVT_LVL_INFO )
-#define MBG_EVT_ANT_DISCONN _mbg_mk_evt_code( MBG_EVT_ID_ANT_DISCONN, MBG_EVT_LVL_CRIT )
-#define MBG_EVT_ANT_SHORT _mbg_mk_evt_code( MBG_EVT_ID_ANT_SHORT, MBG_EVT_LVL_CRIT )
-#define MBG_EVT_ANT_OK _mbg_mk_evt_code( MBG_EVT_ID_ANT_OK, MBG_EVT_LVL_INFO )
-#define MBG_EVT_LOW_SATS _mbg_mk_evt_code( MBG_EVT_ID_LOW_SATS, MBG_EVT_LVL_WARN )
+#define MBG_EVT_NONE _mbg_mk_evt_code( MBG_EVT_ID_NONE, MBG_EVT_LVL_NONE )
+#define MBG_EVT_POW_UP_RES _mbg_mk_evt_code( MBG_EVT_ID_POW_UP_RES, MBG_EVT_LVL_WARN )
+#define MBG_EVT_WDOG_RES _mbg_mk_evt_code( MBG_EVT_ID_WDOG_RES, MBG_EVT_LVL_CRIT )
+#define MBG_EVT_COLD_BOOT _mbg_mk_evt_code( MBG_EVT_ID_COLD_BOOT, MBG_EVT_LVL_ERR )
+#define MBG_EVT_WARM_BOOT _mbg_mk_evt_code( MBG_EVT_ID_WARM_BOOT, MBG_EVT_LVL_ERR )
+#define MBG_EVT_NORMAL_OP _mbg_mk_evt_code( MBG_EVT_ID_NORMAL_OP, MBG_EVT_LVL_INFO )
+#define MBG_EVT_ANT_DISCONN _mbg_mk_evt_code( MBG_EVT_ID_ANT_DISCONN, MBG_EVT_LVL_CRIT )
+#define MBG_EVT_ANT_SHORT _mbg_mk_evt_code( MBG_EVT_ID_ANT_SHORT, MBG_EVT_LVL_CRIT )
+#define MBG_EVT_ANT_OK _mbg_mk_evt_code( MBG_EVT_ID_ANT_OK, MBG_EVT_LVL_INFO )
+#define MBG_EVT_LOW_SATS _mbg_mk_evt_code( MBG_EVT_ID_LOW_SATS, MBG_EVT_LVL_WARN )
+#define MBG_EVT_FW_INSTALLED _mbg_mk_evt_code( MBG_EVT_ID_FW_INSTALLED, MBG_EVT_LVL_INFO )
+#define MBG_EVT_PTP_PORT_STATE_UNINITIALIZED _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_UNINITIALIZED, MBG_EVT_LVL_WARN )
+#define MBG_EVT_PTP_PORT_STATE_INITIALIZING _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_INITIALIZING, MBG_EVT_LVL_INFO )
+#define MBG_EVT_PTP_PORT_STATE_FAULTY _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_FAULTY, MBG_EVT_LVL_ERR )
+#define MBG_EVT_PTP_PORT_STATE_DISABLED _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_DISABLED, MBG_EVT_LVL_INFO )
+#define MBG_EVT_PTP_PORT_STATE_LISTENING _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_LISTENING, MBG_EVT_LVL_INFO )
+#define MBG_EVT_PTP_PORT_STATE_PRE_MASTER _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_PRE_MASTER, MBG_EVT_LVL_INFO )
+#define MBG_EVT_PTP_PORT_STATE_MASTER _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_MASTER, MBG_EVT_LVL_INFO )
+#define MBG_EVT_PTP_PORT_STATE_PASSIVE _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_PASSIVE, MBG_EVT_LVL_INFO )
+#define MBG_EVT_PTP_PORT_STATE_UNCALIBRATED _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_UNCALIBRATED, MBG_EVT_LVL_INFO )
+#define MBG_EVT_PTP_PORT_STATE_SLAVE _mbg_mk_evt_code( MBG_EVT_ID_PTP_PORT_STATE_SLAVE, MBG_EVT_LVL_INFO )
/** @} anchor MBG_EVENT_CODES */
@@ -9660,10 +9883,16 @@ do \
*/
enum MBG_IMS_SENSORS
{
- MBG_IMS_SENSOR_TEMP_C, ///< temperature in degrees Celsius
- MBG_IMS_SENSOR_VOLTAGE, ///< voltage in val/exp, output state in flags
- MBG_IMS_SENSOR_PLL, ///< control voltage in val/exp, lock state in flags
- N_MBG_IMS_SENSORS ///< number of supported sensor types
+ MBG_IMS_SENSOR_TEMP_C, ///< temperature in degrees Celsius
+ MBG_IMS_SENSOR_VOLTAGE, ///< voltage in val/exp, output state in flags
+ MBG_IMS_SENSOR_PLL, ///< control voltage in val/exp, lock state in flags
+ MBG_IMS_SENSOR_VOLTAGE_INPUT, ///< input voltage in val/exp, output state in flags
+ MBG_IMS_SENSOR_VOLTAGE_OUTPUT, ///< output voltage in val/exp, output state in flags
+ MBG_IMS_SENSOR_VOLTAGE_SUPPLY, ///< supply voltage in val/exp, output state in flags
+ MBG_IMS_SENSOR_CURRENT, ///< generic current in val/exp, output state in flags
+ MBG_IMS_SENSOR_CURRENT_BOARD_SUPPLY, ///< board supply current in val/exp, output state in flags
+ MBG_IMS_SENSOR_CURRENT_OSC_SUPPLY, ///< oscillator supply current in val/exp, output state in flags
+ N_MBG_IMS_SENSORS ///< number of supported sensor types
};
@@ -10399,7 +10628,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
+ GNSS_TYPE_QZSS, ///< QZSS, Quasi Zenith Satellite System
N_GNSS_TYPES ///< Number of defined codes
};
@@ -11159,6 +11388,8 @@ 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
+ MBG_NET_GLB_SUPP_ADD_CONF, ///< Supports additional network configuration (i.e. via script)
+ MBG_NET_GLB_SUPP_EXT_ROUTING, ///< Supports extended routing (multiple default gateways, routing tables)
N_MBG_NET_GLB_INFO_FLAGS
};
@@ -11170,8 +11401,10 @@ enum 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
+ 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
+ MBG_NET_GLB_SUPP_ADD_CONF_MASK = (1UL << MBG_NET_GLB_SUPP_ADD_CONF), ///< see ::MBG_NET_GLB_SUPP_ADD_CONF
+ MBG_NET_GLB_SUPP_EXT_ROUTING_MASK = (1UL << MBG_NET_GLB_SUPP_EXT_ROUTING) ///< see ::MBG_NET_GLB_SUPP_EXT_ROUTING
};
@@ -11565,6 +11798,7 @@ enum MBG_NET_INTF_ADDR_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
+ MBG_NET_INTF_ADDR_BIT_AUTOCONF, ///< Address is an autoconf address, which should be ignored in the configuration
N_MBG_NET_INTF_ADDR_FLAGS
};
@@ -11578,7 +11812,8 @@ enum MBG_NET_INTF_ADDR_BITS
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
+ MBG_NET_INTF_ADDR_MASK_DHCP6 = ( 1UL << MBG_NET_INTF_ADDR_BIT_DHCP6 ), ///< see ::MBG_NET_INTF_ADDR_BIT_DHCP6
+ MBG_NET_INTF_ADDR_MASK_AUTOCONF = ( 1UL << MBG_NET_INTF_ADDR_BIT_AUTOCONF ) ///< see ::MBG_NET_INTF_ADDR_BIT_AUTOCONF
};
@@ -12703,7 +12938,7 @@ 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_TIME_MONITOR, ///< Net Sync 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
@@ -12766,7 +13001,7 @@ enum PTP_ROLE_MASKS
"UC+MC Master", \
"NTP Server", \
"NTP Client", \
- "Time Monitor", \
+ "Sync Monitor", \
"V1 Master", \
"V1 Slave" \
}
@@ -13066,7 +13301,9 @@ typedef struct
uint32_t upper_bound; ///< sync state set to false if above this limit [ns]
uint32_t lower_bound; ///< sync state set to true if below this limit [ns]
- uint32_t reserved; ///< reserved, currently always 0
+ int16_t delay_asymmetry; ///< static delay asymmetry [ns] to be compensated, only supported if
+ ///< ::PTP_CFG_MSK_HAS_DELAY_ASYMMETRY_CFG is set in ::PTP_CFG_INFO::supp_flags_ex
+ uint16_t flags_ex; ///< see @ref PTP_CFG_FLAG_EX_MASKS
uint32_t flags; ///< see @ref PTP_CFG_FLAG_MASKS
} PTP_CFG_SETTINGS;
@@ -13080,7 +13317,8 @@ do \
_mbg_swab16( &(_p)->delay_req_intv ); \
_mbg_swab32( &(_p)->upper_bound ); \
_mbg_swab32( &(_p)->lower_bound ); \
- _mbg_swab32( &(_p)->reserved ); \
+ _mbg_swab16( &(_p)->delay_asymmetry ); \
+ _mbg_swab16( &(_p)->flags_ex ); \
_mbg_swab32( &(_p)->flags ); \
} while ( 0 )
@@ -13107,7 +13345,7 @@ typedef struct
uint8_t ptp_proto_version; ///< PTP protocol version, 1, or 2, usually 2 for v2
uint8_t reserved_1; ///< reserved, currently always 0
- uint16_t reserved_2; ///< reserved, currently always 0
+ uint16_t supp_flags_ex; ///< A bit mask of extended supported features, see @ref PTP_CFG_FLAG_EX_MASKS
int16_t sync_intv_min; ///< log2 of minimum sync interval [s]
int16_t sync_intv_max; ///< log2 of maximum sync interval [s]
@@ -13127,7 +13365,7 @@ typedef struct
do \
{ \
_mbg_swab_ptp_cfg_settings( &(_p)->settings ); \
- _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab16( &(_p)->supp_flags_ex ); \
_mbg_swab16( &(_p)->sync_intv_min ); \
_mbg_swab16( &(_p)->sync_intv_max ); \
_mbg_swab16( &(_p)->ann_intv_min ); \
@@ -13197,11 +13435,16 @@ enum PTP_CFG_FLAGS
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
+ PTP_CFG_ATOI, ///< [R/-] supports the configurable usage of the Alternate Time Offset Indicator TLV
+ PTP_CFG_HAS_SMPTE_TLV_STATE, ///< [R/-] SMPTE TLV structure can be queried in slave state
+ PTP_CFG_NTP_SW_SERVER, ///< [R/W] PTP Module can run as NTP Server in Software mode in parallel to PTP HW time stamp modes
+ PTP_CFG_HAS_EXT_SUPP_FLAGS, ///< [R/-] PTP Config has extended supp_flags
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
*
@@ -13244,11 +13487,69 @@ enum PTP_CFG_FLAGS
#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
+#define PTP_CFG_MSK_ATOI ( 1UL << PTP_CFG_ATOI ) ///< see ::PTP_CFG_ATOI
+#define PTP_CFG_MSK_HAS_SMPTE_TLV_STATE ( 1UL << PTP_CFG_HAS_SMPTE_TLV_STATE ) ///< see ::PTP_CFG_HAS_SMPTE_TLV_STATE
+#define PTP_CFG_MSK_NTP_SW_SERVER ( 1UL << PTP_CFG_NTP_SW_SERVER ) ///< see ::PTP_CFG_NTP_SW_SERVER
+#define PTP_CFG_MSK_HAS_EXT_SUPP_FLAGS ( 1UL << PTP_CFG_HAS_EXT_SUPP_FLAGS ) ///< see ::PTP_CFG_CAN_BE_PTP_PROBE
/** @} defgroup group_PTP_CFG_FLAG_MASKS */
+/**
+ * @brief Extended flags bits used with PTP configuration
+ *
+ * Flags labeled [R/-] can only be used with ::PTP_CFG_INFO::supp_flags
+ * to indicate that the associated feature is supported in general.
+ *
+ * If a flag labeled [R/W] is set in ::PTP_CFG_INFO::supp_flags then
+ * this flag can also be used with ::PTP_CFG_SETTINGS::flags to control
+ * the associated feature.
+ *
+ * @note Originally, all devices supported the multicast slave role, so
+ * there was no extra flag to indicate this. However, some newer devices
+ * may not support the multicast slave role, so two new flags have been
+ * introduced to cope with this:
+ * If ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG is set then a different flag
+ * ::PTP_CFG_CAN_BE_MULTICAST_SLAVE needs to be checked to tell if
+ * the multicast slave role is supported, or not.
+ * If ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG is not set then the device
+ * definitely supports the multicast slave role.
+ *
+ * @see @ref PTP_CFG_FLAG_EX_MASKS
+ */
+enum PTP_CFG_FLAGS_EX
+{
+ PTP_CFG_CAN_BE_PTP_PROBE, ///< [R/W] PTP can be used in slave mode although not in slave capable slot
+ PTP_CFG_DISABLE_PTP, ///< [R/W] PTP Port state can be set to DISABLED permanentely
+ PTP_CFG_HAS_NTP_PKTGEN_IPV6, ///< [R/-] PTP packet generator supports IPv6
+ PTP_CFG_HAS_DELAY_ASYMMETRY_CFG,///< [R/-] PTP stack supports configuration of static delay asymmetry to be compensated
+ PTP_CFG_HAS_SOFT_NTP, ///< [R/-] PTP device supports software NTP daemon in parallel to PTP
+ N_PTP_CFG_FLAGS_EX
+};
+
+
+/**
+ * @defgroup group_PTP_CFG_FLAG_EX_MASKS Bit masks used with PTP_CFG_INFO::supp_flags_ex and PTP_CFG_SETTINGS::flags_ex
+ *
+ * @see ::PTP_CFG_INFO::supp_flags_ex
+ * @see ::PTP_CFG_SETTINGS::flags_ex // TODO Is this correct?
+ * @see ::PTP_CFG_FLAGS_EX
+ *
+ * @anchor PTP_CFG_FLAG_EX_MASKS
+ *
+ * @{ */
+
+#define PTP_CFG_MSK_CAN_BE_PTP_PROBE ( 1UL << PTP_CFG_CAN_BE_PTP_PROBE ) ///< see ::PTP_CFG_CAN_BE_PTP_PROBE
+#define PTP_CFG_MSK_DISABLE_PTP ( 1UL << PTP_CFG_DISABLE_PTP ) ///< see ::PTP_CFG_DISABLE_PTP
+#define PTP_CFG_MSK_HAS_NTP_PKTGEN_IPV6 ( 1UL << PTP_CFG_HAS_NTP_PKTGEN_IPV6 ) ///< see ::PTP_CFG_HAS_NTP_PKTGEN_IPV6
+#define PTP_CFG_MSK_HAS_DELAY_ASYMMETRY_CFG ( 1UL << PTP_CFG_HAS_DELAY_ASYMMETRY_CFG ) ///< see ::PTP_CFG_HAS_DELAY_ASYMMETRY_CFG
+#define PTP_CFG_MSK_HAS_SOFT_NTP ( 1UL << PTP_CFG_HAS_SOFT_NTP ) ///< see ::PTP_CFG_HAS_SOFT_NTP
+
+/** @} defgroup group_PTP_CFG_FLAG_EX_MASKS */
+
+
+
/** @brief A bit mask of the unicast role bits within the flag bits */
#define PTP_CFG_MSK_SUPPORT_PTP_UNICAST ( PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE | \
PTP_CFG_MSK_CAN_BE_UNICAST_MASTER )
@@ -13300,6 +13601,7 @@ enum PTP_OPT_EXTS
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
+ PTP_OPT_EXT_C37238_2017, ///< IEEE C37.238-2017 profile extension
N_PTP_OPT_EXT ///< number of known optional extensions
};
@@ -13318,7 +13620,8 @@ enum PTP_OPT_EXT_MASKS
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
+ PTP_MSK_OPT_EXT_TELECOM_PTS = ( 1UL << PTP_OPT_EXT_TELECOM_PTS ), ///< see ::PTP_OPT_EXT_TELECOM_PTS
+ PTP_MSK_OPT_EXT_C37238_2017 = ( 1UL << PTP_OPT_EXT_C37238_2017 ) ///< see ::PTP_MSK_OPT_EXT_C37238_2017
};
@@ -13346,6 +13649,7 @@ enum PTP_PRESETS
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
+ PTP_PRESETS_C37238_2017, ///< only if ::PTP_MSK_OPT_EXT_C37238_2017 is set
N_PTP_PRESETS ///< number of supported presets
};
@@ -13367,8 +13671,10 @@ enum PTP_PRESETS_MASKS
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
+ 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
+ PTP_MSK_PRESETS_C37238_2017 = ( 1UL << PTP_PRESETS_C37238_2017) ///< see ::PTP_PRESETS_C37238_2017
+
};
@@ -13382,7 +13688,7 @@ enum PTP_PRESETS_MASKS
"Custom", \
"Default E2E IEEE1588-2008", \
"Default P2P IEEE1588-2008", \
- "Power IEEE C37.238", \
+ "Power IEEE C37.238-2011", \
"Telecom ITU-T G.8265.1", \
"Telecom ITU-T G.8275.1", \
"SMPTE ST 2059-2", \
@@ -13390,7 +13696,8 @@ enum PTP_PRESETS_MASKS
"IEEE 802.1AS", \
"Utility IEC 61850-9-3", \
"Telecom ITU-T G.8275.2", \
- "DOCSIS 3.1" \
+ "DOCSIS 3.1", \
+ "Power IEEE C37.238-2017" \
}
@@ -13406,7 +13713,7 @@ typedef struct
uint32_t network_incaccuracy; ///< Pre-defined network inaccuracy from master in [ns]
uint8_t grandmaster_id; ///< [::PTP_POWER_PROFILE_GM_ID_MIN..::PTP_POWER_PROFILE_GM_ID_MAX]
uint8_t reserved_1;
- uint16_t reserved_2;
+ uint16_t grandmaster_id_2017; ///< Grandmaster ID defined in C.37.2017 is now 16 Bits
TZDL tzdl;
} PTP_POWER_PROFILE_CFG;
@@ -13417,7 +13724,7 @@ do \
_mbg_swab32( &(_p)->network_incaccuracy ); \
_mbg_swab8( &(_p)->grandmaster_id ); \
_mbg_swab8( &(_p)->reserved_1 ); \
- _mbg_swab16( &(_p)->reserved_2 ); \
+ _mbg_swab16( &(_p)->grandmaster_id_2017 ); \
_mbg_swab_tzdl( &(_p)->tzdl ); \
_mbg_swab32( &(_p)->flags ); \
} while ( 0 )
@@ -13567,6 +13874,20 @@ typedef struct
} PTP_SMPTE_PROFILE_CFG;
+#define _mbg_swab_ptp_smpte_profile_cfg( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->defaultSystemFrameRateNum ); \
+ _mbg_swab32( &(_p)->defaultSystemFrameRateDenum ); \
+ _mbg_swab32( &(_p)->currentLocalOffset ); \
+ _mbg_swab32( &(_p)->jumpSeconds ); \
+ _mbg_swab32( &(_p)->reserved_5 ); \
+ _mbg_swab32( &(_p)->previousJamLocalOffset ); \
+ _mbg_swab32( &(_p)->reserved_8 ); \
+ _mbg_swab32( &(_p)->reserved_8 ); \
+ _mbg_swab32( &(_p)->reserved_9 ); \
+ _mbg_swab32( &(_p)->reserved_10 ); \
+} while ( 0 )
/**
@@ -14835,6 +15156,7 @@ enum NTP_FLAGS
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
+ NTP_ADD_CONF, ///< Supports additional NTP configuration (i.e. via script)
N_NTP_FLAGS
};
@@ -14879,11 +15201,16 @@ enum NTP_FLAGS
#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
-
+#define NTP_MSK_ADD_CONF ( 1UL << NTP_ADD_CONF ) ///< see ::NTP_ADD_CONF
/** @} anchor NTP_FLAG_MASKS */
+#define NTP_DEF_ADD_CONF_PATH "/etc/mbg"
+#define NTP_DEF_ADD_CONF_FILENAME "ntp.conf.add"
+#define NTP_DEF_ADD_CONF_FILE NTP_DEF_ADD_CONF_PATH "/" NTP_DEF_ADD_CONF_FILENAME
+
+
/**
* @brief Global configuration settings of an NTP device (client/server)
@@ -15162,6 +15489,111 @@ do \
} 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 )
+
+
+#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_STATS_GLB_SETTINGS;
+ typedef int NTP_STATS_GLB_INFO;
+
+#endif // defined( _PRELIMINARY_CODE )
+
/**
* @brief Enumeration of supported refclock types
@@ -15202,9 +15634,6 @@ enum NTP_REFCLK_TYPE_MSKS
};
-
-
-
/**
* @brief Numbers related to the "fudge" flags used with ntpd's refclock interface
*
@@ -15244,7 +15673,6 @@ enum NTP_REFCLK_TYPE_MSKS
/** @} anchor NTP_FUDGE_FLAG_NUMBERS */
-
/**
* @brief NTP refclock specific settings
*
@@ -15261,7 +15689,7 @@ typedef struct
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_1; ///< Future use
uint8_t reserved_2; ///< Future use
NANO_TIME_64 time1; ///< Driver specific
@@ -15307,9 +15735,34 @@ do \
_mbg_swab_ntp_refclk_cfg_settings( &(_p)->settings ); \
} while ( 0 )
+/**
+ * @brief Enumeration of NTP refclock config flags
+ *
+ * @see @ref NTP_REFCLK_CFG_FLAGS
+ */
+enum NTP_REFCLK_CFG_FLAGS
+{
+ NTP_REFCLK_CFG_TRUSTTIME, ///< Trusttime of refclk configurable
+
+ N_NTP_REFCLK_CFG_FLAGS
+};
/**
+ * @brief Flag masks associated with ::NTP_REFCLK_CFG_FLAGS
+ *
+ * Used with ::NTP_REFCLK_CFG_INFO::supp_cfgs,
+ *
+ * @see ::NTP_REFCLK_CFG_FLAGS
+ *
+ * @anchor NTP_REFCLK_CFG_FLAGS_MASKS @{ */
+
+#define NTP_MSK_REFCLK_CFG_TRUSTTIME ( 1UL << NTP_REFCLK_CFG_TRUSTTIME ) ///< see ::NTP_REFCLK_CFG_TRUSTTIME
+
+
+/** @} anchor NTP_REFCLK_CFG_FLAGS_MASKS */
+
+/**
* @brief NTP refclock configuration and supported refclock types
*
* This structure can be used to set a NTP refclock's configuration
@@ -15319,7 +15772,9 @@ typedef struct
{
NTP_REFCLK_CFG_SETTINGS settings; ///< See ::NTP_REFCLK_CFG_SETTINGS
- uint32_t supp_refclk_types; ///< See ::NTP_REFCLK_TYPE_MSKS
+ uint8_t supp_cfgs; ///< See @ref NTP_REFCLK_CFG_FLAGS
+ uint8_t reserved; ///< Future use
+ uint16_t supp_refclk_types; ///< See ::NTP_REFCLK_TYPE_MSKS
} NTP_REFCLK_CFG_INFO;
@@ -15609,101 +16064,6 @@ do \
/**
- * @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
@@ -15865,37 +16225,6 @@ do \
} 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
*
@@ -16467,16 +16796,17 @@ enum NTP_SYS_EVT_BITS
*/
enum NTP_SYS_STATE_SUPP_FLAGS
{
- NTP_SYS_STATE_SUPP_STD = 0, ///< supports standard values of ::NTP_SYS_STATE, all fields except below and reserved
- NTP_SYS_STATE_SUPP_EVENTS, ///< supports sys state events (::NTP_SYS_STATE::sys_evt_cnt, ::NTP_SYS_STATE::sys_rec_evt)
- NTP_SYS_STATE_SUPP_PRECISION, ///< supports precision indication, see ::NTP_SYS_STATE::precision
- NTP_SYS_STATE_SUPP_ROOT_DELAY, ///< supports root delay to syspeer, see ::NTP_SYS_STATE::root_delay
- NTP_SYS_STATE_SUPP_ROOT_DISP, ///< supports root dispersion, see ::NTP_SYS_STATE::root_disp
- NTP_SYS_STATE_SUPP_FREQ, ///< supports frequency offset, see ::NTP_SYS_STATE::freq
- NTP_SYS_STATE_SUPP_SYS_JITTER, ///< supports combined jitter, see ::NTP_SYS_STATE::sys_jitter
- NTP_SYS_STATE_SUPP_CLK_JITTER, ///< supports clock jitter, see ::NTP_SYS_STATE::clk_jitter
- NTP_SYS_STATE_SUPP_CLK_WANDER, ///< supports clock wander, see ::NTP_SYS_STATE::clk_wander
- NTP_SYS_STATE_SUPP_SYS_ASSOC, ///< supports sys assoc ID as sys peer, see ::NTP_SYS_STATE::sys_assoc
+ NTP_SYS_STATE_SUPP_STD = 0, ///< supports standard values of ::NTP_SYS_STATE, all fields except below and reserved
+ NTP_SYS_STATE_SUPP_EVENTS, ///< supports sys state events (::NTP_SYS_STATE::sys_evt_cnt, ::NTP_SYS_STATE::sys_rec_evt)
+ NTP_SYS_STATE_SUPP_PRECISION, ///< supports precision indication, see ::NTP_SYS_STATE::precision
+ NTP_SYS_STATE_SUPP_ROOT_DELAY, ///< supports root delay to syspeer, see ::NTP_SYS_STATE::root_delay
+ NTP_SYS_STATE_SUPP_ROOT_DISP, ///< supports root dispersion, see ::NTP_SYS_STATE::root_disp
+ NTP_SYS_STATE_SUPP_FREQ, ///< supports frequency offset, see ::NTP_SYS_STATE::freq
+ NTP_SYS_STATE_SUPP_SYS_JITTER, ///< supports combined jitter, see ::NTP_SYS_STATE::sys_jitter
+ NTP_SYS_STATE_SUPP_CLK_JITTER, ///< supports clock jitter, see ::NTP_SYS_STATE::clk_jitter
+ NTP_SYS_STATE_SUPP_CLK_WANDER, ///< supports clock wander, see ::NTP_SYS_STATE::clk_wander
+ NTP_SYS_STATE_SUPP_SYS_ASSOC, ///< supports sys assoc ID as sys peer, see ::NTP_SYS_STATE::sys_assoc
+ NTP_SYS_STATE_SUPP_SERVICE_STATE, ///< supports service state, see ::NTP_SYS_STATE::service_state
N_NTP_SYS_STATE_SUPP_FLAGS
};
@@ -16491,19 +16821,48 @@ enum NTP_SYS_STATE_SUPP_FLAGS
*/
enum NTP_SYS_STATE_SUPP_FLAG_MASKS
{
- NTP_SYS_STATE_SUPP_STD_MSK = ( 1UL << NTP_SYS_STATE_SUPP_STD ), ///< see ::NTP_SYS_STATE_SUPP_STD
- NTP_SYS_STATE_SUPP_EVENTS_MSK = ( 1UL << NTP_SYS_STATE_SUPP_EVENTS ), ///< see ::NTP_SYS_STATE_SUPP_EVENTS
- NTP_SYS_STATE_SUPP_PRECISION_MSK = ( 1UL << NTP_SYS_STATE_SUPP_PRECISION ), ///< see ::NTP_SYS_STATE_SUPP_PRECISION
- NTP_SYS_STATE_SUPP_ROOT_DELAY_MSK = ( 1UL << NTP_SYS_STATE_SUPP_ROOT_DELAY ), ///< see ::NTP_SYS_STATE_SUPP_ROOT_DELAY
- NTP_SYS_STATE_SUPP_ROOT_DISP_MSK = ( 1UL << NTP_SYS_STATE_SUPP_ROOT_DISP ), ///< see ::NTP_SYS_STATE_SUPP_ROOT_DISP
- NTP_SYS_STATE_SUPP_FREQ_MSK = ( 1UL << NTP_SYS_STATE_SUPP_FREQ ), ///< see ::NTP_SYS_STATE_SUPP_FREQ
- NTP_SYS_STATE_SUPP_SYS_JITTER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_SYS_JITTER ), ///< see ::NTP_SYS_STATE_SUPP_SYS_JITTER
- NTP_SYS_STATE_SUPP_CLK_JITTER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_CLK_JITTER ), ///< see ::NTP_SYS_STATE_SUPP_CLK_JITTER
- NTP_SYS_STATE_SUPP_CLK_WANDER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_CLK_WANDER ), ///< see ::NTP_SYS_STATE_SUPP_CLK_WANDER
- NTP_SYS_STATE_SUPP_SYS_ASSOC_MSK = ( 1UL << NTP_SYS_STATE_SUPP_SYS_ASSOC ) ///< see ::NTP_SYS_STATE_SUPP_SYS_ASSOC
+ NTP_SYS_STATE_SUPP_STD_MSK = ( 1UL << NTP_SYS_STATE_SUPP_STD ), ///< see ::NTP_SYS_STATE_SUPP_STD
+ NTP_SYS_STATE_SUPP_EVENTS_MSK = ( 1UL << NTP_SYS_STATE_SUPP_EVENTS ), ///< see ::NTP_SYS_STATE_SUPP_EVENTS
+ NTP_SYS_STATE_SUPP_PRECISION_MSK = ( 1UL << NTP_SYS_STATE_SUPP_PRECISION ), ///< see ::NTP_SYS_STATE_SUPP_PRECISION
+ NTP_SYS_STATE_SUPP_ROOT_DELAY_MSK = ( 1UL << NTP_SYS_STATE_SUPP_ROOT_DELAY ), ///< see ::NTP_SYS_STATE_SUPP_ROOT_DELAY
+ NTP_SYS_STATE_SUPP_ROOT_DISP_MSK = ( 1UL << NTP_SYS_STATE_SUPP_ROOT_DISP ), ///< see ::NTP_SYS_STATE_SUPP_ROOT_DISP
+ NTP_SYS_STATE_SUPP_FREQ_MSK = ( 1UL << NTP_SYS_STATE_SUPP_FREQ ), ///< see ::NTP_SYS_STATE_SUPP_FREQ
+ NTP_SYS_STATE_SUPP_SYS_JITTER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_SYS_JITTER ), ///< see ::NTP_SYS_STATE_SUPP_SYS_JITTER
+ NTP_SYS_STATE_SUPP_CLK_JITTER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_CLK_JITTER ), ///< see ::NTP_SYS_STATE_SUPP_CLK_JITTER
+ NTP_SYS_STATE_SUPP_CLK_WANDER_MSK = ( 1UL << NTP_SYS_STATE_SUPP_CLK_WANDER ), ///< see ::NTP_SYS_STATE_SUPP_CLK_WANDER
+ NTP_SYS_STATE_SUPP_SYS_ASSOC_MSK = ( 1UL << NTP_SYS_STATE_SUPP_SYS_ASSOC ), ///< see ::NTP_SYS_STATE_SUPP_SYS_ASSOC
+ NTP_SYS_STATE_SUPP_SERVICE_STATE_MSK = ( 1UL << NTP_SYS_STATE_SUPP_SERVICE_STATE ) ///< see ::NTP_SYS_STATE_SUPP_SERVICE_STATE
+};
+
+
+/**
+ * @brief Enumeration of supported NTP service state values
+ */
+enum MBG_NTP_SERVICE_STATES
+{
+ MBG_NTP_SERVICE_INIT,
+ MBG_NTP_SERVICE_SYNC,
+ MBG_NTP_SERVICE_ASYNC,
+ MBG_NTP_SERVICE_STOPPED,
+ N_MBG_NTP_SERVICE_STATES
};
+/*
+ * Default initializers for NTP service state string names.
+ */
+#define MBG_NTP_SERVICE_INIT_STR "NTP service initializing"
+#define MBG_NTP_SERVICE_SYNC_STR "NTP service synchronized"
+#define MBG_NTP_SERVICE_ASYNC_STR "NTP service not synchronized"
+#define MBG_NTP_SERVICE_STOPPED_STR "NTP service stopped"
+
+#define MBG_NTP_SERVICE_STATES_STRS \
+{ \
+ MBG_NTP_SERVICE_INIT_STR, \
+ MBG_NTP_SERVICE_SYNC_STR, \
+ MBG_NTP_SERVICE_ASYNC_STR, \
+ MBG_NTP_SERVICE_STOPPED_STR \
+}
/**
* @brief Structure that represents the current system status of an NTP device
@@ -16551,7 +16910,7 @@ typedef struct
int32_t clk_jitter; ///< [us] Jitter of the clock
int32_t clk_wander; ///< [ppb] Frequency wander of the clock
- uint8_t cfg_counter; ///< Updated (increased) when config changes
+ uint8_t service_state; ///< Current state of the NTP service see ::MBG_NTP_SERVICE_STATES
uint8_t reserved_1; ///< Reserved, currently always 0
uint16_t reserved_2; ///< Reserved, currently always 0
@@ -17599,6 +17958,43 @@ enum XBP_DEVICE_STATES
};
+/**
+ * @brief Possible IMS slot types of an XBP device
+ *
+ * Used with ::XBP_NODE_INFO::slot_type.
+ */
+enum XBP_SLOT_TYPES
+{
+ XBP_SLOT_TYPE_UNKNOWN, ///< Unknown slot type, i.e. slot type not supp.
+ XBP_SLOT_TYPE_PWR, ///< Slot for power supply units
+ XBP_SLOT_TYPE_CLK, ///< Slot for reference clocks
+ XBP_SLOT_TYPE_SCU, ///< Slot for switch card units
+ XBP_SLOT_TYPE_CPU, ///< Slot for processing units
+ XBP_SLOT_TYPE_MRI, ///< Slot for MRI (multi reference input) cards
+ XBP_SLOT_TYPE_ESI, ///< Slot for ESI (extended reference input) cards
+ XBP_SLOT_TYPE_IO, ///< Slot for all other input/output cards
+ N_XBP_SLOT_TYPES
+};
+
+
+#define XBP_SLOT_TYPE_STRS \
+{ \
+ "Unknown", \
+ "PWR", \
+ "CLK", \
+ "SCU", \
+ "CPU", \
+ "MRI", \
+ "ESI", \
+ "IO" \
+}
+
+
+/// Maximum string length (including terminating zero) of a full XBP slot name
+/// which consists of ::XBP_NODE_INFO::slot_type and ::XBP_NODE_INFO::slot_type_id
+/// Examples: "CLK1", "MRI2", ...
+#define XBP_MAX_SLOT_NAME 5
+
/**
* @brief Information on a specific XBP node
@@ -17616,9 +18012,13 @@ typedef struct
/// is set to ::GPS_MODEL_UNKNOWN (== 0).
RECEIVER_INFO ri;
- uint8_t state; ///< The device state, see ::XBP_DEVICE_STATES
- uint8_t reserved; ///< Currently reserved, always 0
- uint32_t flags; ///< Currently reserved, always 0
+ uint8_t state; ///< The device state, see ::XBP_DEVICE_STATES
+
+ uint8_t slot_type; ///< The IMS slot type, see ::XBP_SLOT_TYPES
+ uint8_t slot_type_id; ///< ID depending on the ::XBP_NODE_INFO::slot_type, i.e. 1 for CLK1
+
+ uint8_t reserved; ///< Currently reserved, always 0
+ uint16_t flags; ///< Currently reserved, always 0
} XBP_NODE_INFO;
@@ -17628,8 +18028,10 @@ do \
_mbg_swab_xbp_addr( &(_p)->addr ); \
_mbg_swab_receiver_info( &(_p)->ri ); \
_mbg_swab8( &(_p)->state ); \
+ _mbg_swab8( &(_p)->slot_type ); \
+ _mbg_swab8( &(_p)->slot_type_id ); \
_mbg_swab8( &(_p)->reserved ); \
- _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab16( &(_p)->flags ); \
} while ( 0 )
@@ -17764,6 +18166,9 @@ enum MBG_TLV_FEAT_TYPES
/// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_TIME_MONITOR_IDX, see @ref group_license_limits
MBG_TLV_FEAT_TYPE_LICENSE_TIME_MONITOR_IDX,
+ /// used to receive full TimeMon Status structure
+ MBG_TLV_FEAT_TYPE_TIMEMON_FULL_STATUS,
+
/// 1) ::MBG_TLV_TYPE_BLOB => Unified Firmware Update (UFU) file, see mbg_ufu.h
MBG_TLV_FEAT_TYPE_UFU,
@@ -17782,21 +18187,22 @@ enum 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", \
- "TLV Unified Firmware Update" \
+#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 Sync Monitor", \
+ "TLV Sync Monitor Full Status", \
+ "TLV Unified Firmware Update" \
}
@@ -17841,7 +18247,7 @@ typedef struct
* @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 )
+ _set_array_bit( _tlv_feat_type, (_tlv_feat_buffp)->supp_tlv_feat.b, MAX_MBG_TLV_FEAT_BYTES )
/** @} defgroup group_tlv_feat */
@@ -18825,11 +19231,14 @@ enum MBG_EXT_SYS_INFO_BITS
MBG_EXT_SYS_INFO_BIT_OS_REV,
MBG_EXT_SYS_INFO_BIT_FPGA_REV,
MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV,
+ MBG_EXT_SYS_INFO_BIT_OS_TYPE,
+ MBG_EXT_SYS_INFO_BIT_RAM_SIZE,
+ MBG_EXT_SYS_INFO_BIT_STORAGE_SIZE,
+ MBG_EXT_SYS_INFO_BIT_RELEASE_CANDIDATE,
+ MBG_EXT_SYS_INFO_BIT_OS_TARGET,
N_MBG_EXT_SYS_INFO_BITS
};
-
-
/**
* @brief Bit masks of supported revision numbers
*
@@ -18839,11 +19248,16 @@ enum 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
+ 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
+ MBG_EXT_SYS_INFO_MSK_OS_TYPE = ( 1UL << MBG_EXT_SYS_INFO_BIT_OS_TYPE ), ///< see ::MBG_EXT_SYS_INFO_BIT_OS_TYPE
+ MBG_EXT_SYS_INFO_MSK_RAM_SIZE = ( 1UL << MBG_EXT_SYS_INFO_BIT_RAM_SIZE ), ///< see ::MBG_EXT_SYS_INFO_BIT_RAM_SIZE
+ MBG_EXT_SYS_INFO_MSK_STORAGE_SIZE = ( 1UL << MBG_EXT_SYS_INFO_BIT_STORAGE_SIZE ), ///< see ::MBG_EXT_SYS_INFO_BIT_STORAGE_SIZE
+ MBG_EXT_SYS_INFO_MSK_RELEASE_CANDIDATE = ( 1UL << MBG_EXT_SYS_INFO_BIT_RELEASE_CANDIDATE ), ///< see ::MBG_EXT_SYS_INFO_BIT_RELEASE_CANDIDATE
+ MBG_EXT_SYS_INFO_MSK_OS_TARGET = ( 1UL << MBG_EXT_SYS_INFO_BIT_OS_TARGET ) ///< see ::MBG_EXT_SYS_INFO_BIT_OS_TARGET
};
@@ -18900,6 +19314,93 @@ enum MBG_EXT_SYS_INFO_CORE_MOD_TYPES
"u-blox LEA-M8T" \
}
+/*
+ * OS Type can be used a GPS_MODEL_CODE
+ */
+enum MBG_EXT_SYS_INFO_OS_TYPES
+{
+ MBG_EXT_SYS_INFO_OS_TYPE_NONE,
+ MBG_EXT_SYS_INFO_OS_TYPE_PICO_OS,
+ MBG_EXT_SYS_INFO_OS_TYPE_NANO_OS,
+ MBG_EXT_SYS_INFO_OS_TYPE_MICRO_OS,
+ MBG_EXT_SYS_INFO_OS_TYPE_SYNC_OS,
+ MBG_EXT_SYS_INFO_OS_TYPE_ANY_OS,
+ N_MBG_EXT_SYS_INFO_OS_TYPES
+};
+
+
+#define MBG_EXT_SYS_INFO_OS_SHORT_STRS \
+{ \
+ " ", \
+ "p", \
+ "n", \
+ "u", \
+ "s", \
+ "x" \
+}
+
+
+#define MBG_EXT_SYS_INFO_OS_STRS \
+{ \
+ "none", \
+ "pico", \
+ "nano", \
+ "micro", \
+ "sync", \
+ "any" \
+}
+
+/// CPU mainline
+#define MBG_EXT_SYS_INFO_CPU_MSK 0xff
+
+/// CPU generation
+#define MBG_EXT_SYS_INFO_CPU_GEN_MSK 0xf
+
+/// CPU variant
+#define MBG_EXT_SYS_INFO_CPU_VAR_MSK 0xf
+
+#define _mbg_ext_sys_info_get_cpu(var) (((var) >> 8) & MBG_EXT_SYS_INFO_CPU_MSK)
+#define _mbg_ext_sys_info_get_cpu_gen(var) (((var) >> 4) & MBG_EXT_SYS_INFO_CPU_GEN_MSK)
+#define _mbg_ext_sys_info_get_cpu_var(var) ((var) & MBG_EXT_SYS_INFO_CPU_VAR_MSK)
+
+enum MBG_EXT_SYS_INFO_CPUS
+{
+ MBG_EXT_SYS_INFO_CPU_UNKNOWN,
+ MBG_EXT_SYS_INFO_CPU_HPS_USB_HOST,
+ MBG_EXT_SYS_INFO_CPU_HPS_USB_DEVICE,
+ N_MBG_EXT_SYS_INFO_CPUS
+};
+
+#define MBG_EXT_SYS_INFO_CPU_STRS \
+{ \
+ "Unknown", \
+ "HPS USB host", \
+ "HPS USB device" \
+}
+
+#define __CPU_CODEC(cpu, gen, var) \
+ (((cpu) & MBG_EXT_SYS_INFO_CPU_MSK) << 8) | \
+ (((gen) & MBG_EXT_SYS_INFO_CPU_GEN_MSK) << 4) | \
+ ((var) & MBG_EXT_SYS_INFO_CPU_VAR_MSK)
+
+/// CPU 1 : HPS USB host
+/// Gen 1 : HPS100
+/// Var 0 : Base (4xLED, USB to serial, 2xSMA, SFP, RJ-45)
+/// Product(s) : microSYNC HSXXX
+#define HPS_USB_HOST_G1_V0 __CPU_CODEC(MBG_EXT_SYS_INFO_CPU_HPS_USB_HOST, 1, 0)
+
+/// CPU 2 : HPS USB device
+/// Gen 1 : HPS100
+/// Var 0 : Base (4xLED, USB to serial, 2xSMA, SFP, RJ-45)
+/// Product(s) : HPS100
+#define HPS_USB_DEVICE_G1_V0 __CPU_CODEC(MBG_EXT_SYS_INFO_CPU_HPS_USB_DEVICE, 1, 0)
+
+/// CPU 2 : HPS USB device
+/// Gen 1 : HPS100
+/// Var 1 : USB lock (4xLED, USB to serial, SMA, USB lock, SFP, RJ-45)
+/// Product(s) : SSP100
+#define HPS_USB_DEVICE_G1_V1 __CPU_CODEC(MBG_EXT_SYS_INFO_CPU_HPS_USB_DEVICE, 1, 1)
+
typedef struct
{
uint32_t supp_members; ///< ::MBG_EXT_SYS_INFO_MSKS
@@ -18912,20 +19413,30 @@ typedef struct
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;
+ uint16_t mbg_os_type; ///< See ::MBG_EXT_SYS_INFO_OS_TYPES
uint32_t core_mod_rev;
+ uint32_t ram_size; ///< RAM size in MB
+ uint32_t storage_size; ///< Storage size in MB
+
+ uint8_t release_candidate;///< Release candidate number (0 = final release)
+
/* Reserved for future use, currently 0 */
- uint32_t reserved_rev_3;
- uint32_t reserved_rev_4;
+ uint8_t reserved_rev_3[3];
+
+ /// Layout (see ::MBG_EXT_SYS_INFO_CPU_CODECS)
+ /// os_target:8 8 Bit CPU
+ /// os_target:4 4 Bit CPU generation
+ /// os_target:4 4 Bit CPU variant (currently unused)
+ uint16_t os_target;
+
+ uint16_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;
@@ -18940,8 +19451,12 @@ do \
_mbg_swab16( &(_p)->proc_type ); \
_mbg_swab16( &(_p)->fpga_type ); \
_mbg_swab16( &(_p)->core_mod_type ); \
+ _mbg_swab16( &(_p)->os_type ); \
_mbg_swab16( &(_p)->reserved ); \
_mbg_swab32( &(_p)->core_mod_rev ); \
+ _mbg_swab32( &(_p)->ram_size ); \
+ _mbg_swab32( &(_p)->storage_size ); \
+ _mbg_swab16( &(_p)->os_target ); \
} while ( 0 )
@@ -19262,7 +19777,7 @@ enum MBG_LICENSE_TIME_MONITOR_MEMBERS
/**
- * @brief Bit masks of Time Monitor license specific members
+ * @brief Bit masks of Sync Monitor license specific members
*
* Used with ::MBG_LICENSE_TIME_MONITOR::supp_members
*
@@ -19276,7 +19791,7 @@ enum MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS
/**
- * @brief Time Monitor specific license information
+ * @brief Sync Monitor specific license information
*
*/
typedef struct
@@ -19464,13 +19979,64 @@ enum MBG_TRANSACTION_TYPES
*/
MBG_TRANSACTION_TYPE_EVENTS,
+ /*
+ * User Management transaction is supported,
+ * if ::MBG_XFEATURE_MONITORING is set in ::MBG_XFEATURE_BUFFER and
+ * requires at least and as first command: ::GPS_USER_MNGMNT_INFO
+ *
+ * Other commands in any order
+ *
+ * - ::GPS_USER_INFO_IDX
+ * - ::GPS_USER_LEVEL_INFO_IDX
+ * - ::GPS_USER_STATUS_IDX
+ */
+ MBG_TRANSACTION_TYPE_USER_MNGMNT,
+
+ /*
+ * Should be used within ::MBG_TRANSACTION_TYPE_MONITORING but may also be
+ * used stand-alone.
+ *
+ * - ::GPS_SYSLOG_GLB_INFO
+ * - ::GPS_SYSLOG_INFO_IDX
+ */
+ MBG_TRANSACTION_TYPE_MONITORING_SYSLOG,
+
+ /*
+ * Firmware Management transaction is supported,
+ * if ::MBG_XFEATURE_FW_MNGMNT is set in ::MBG_XFEATURE_BUFFER and
+ * requires at least and as first command: ::GPS_FW_GLB_INFO
+ *
+ * Other commands in any order
+ *
+ * - ::GPS_FW_INFO_IDX
+ * - ::GPS_FW_UFU_INFO_IDX
+ */
+ MBG_TRANSACTION_TYPE_FIRMWARE_MNGMNT,
+
+ /*
+ * Database transaction is supported,
+ * if ::MBG_XFEATURE_DATABASE is set in ::MBG_XFEATURE_BUFFER and
+ * requires at least and as first command: ::GPS_DATABASE_GLB_INFO
+ *
+ * Other commands in any order
+ *
+ * - ::GPS_DATABASE_GLB_INFO
+ * - ::GPS_DATABASE_INFO_IDX
+ */
+ MBG_TRANSACTION_TYPE_DATABASE,
+
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 )
+#define MBG_TRANSACTION_MSK_SET 0x8000 ///< Only relevant when starting a transaction
+#define MBG_TRANSACTION_MSK_SUCCESS 0x4000 ///< Only relevant when ending a transaction
+
+#define _mbg_is_set_transaction( _type ) ( ( _type ) & MBG_TRANSACTION_MSK_SET )
+#define _mbg_transaction_type_set( _type ) ( ( _type ) |= MBG_TRANSACTION_MSK_SET )
+
+#define _mbg_transaction_success( _type ) ( ( _type ) & MBG_TRANSACTION_MSK_SUCCESS )
+#define _mbg_transaction_set_success( _type ) ( ( _type ) |= MBG_TRANSACTION_MSK_SUCCESS )
/**
@@ -19496,6 +20062,13 @@ enum MBG_IO_PORT_TYPES
MBG_IO_PORT_TYPE_TERMINAL,
MBG_IO_PORT_TYPE_MULTI,
MBG_IO_PORT_TYPE_POUT,
+ MBG_IO_PORT_TYPE_SWITCH,
+ MBG_IO_PORT_TYPE_TIMECODE, ///< e.g. IRIG AM/DC, see ::MBG_IO_PORT_SHAPE_LEVELS
+ MBG_IO_PORT_TYPE_LIGHT,
+ MBG_IO_PORT_TYPE_ANTENNA,
+ MBG_IO_PORT_TYPE_UART,
+ MBG_IO_PORT_TYPE_DCF77,
+ MBG_IO_PORT_TYPE_POWER,
N_MBG_IO_PORT_TYPES
};
@@ -19525,7 +20098,14 @@ enum MBG_IO_PORT_TYPES
"Ethernet", \
"Terminal", \
"Multi", \
- "Prog. Output" \
+ "Prog. Output", \
+ "Switch", \
+ "Timecode", \
+ "Light", \
+ "Antenna", \
+ "UART", \
+ "DCF77", \
+ "Power" \
}
@@ -19584,16 +20164,19 @@ enum MBG_IO_PORT_DIR_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
+ 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
+ MBG_IO_PORT_SRC_SWITCH_CARD, ///< Switch Card Unit fixed (SCU, RSC, ...)
+ MBG_IO_PORT_SRC_CONFIGURABLE, ///< configurable
+ MBG_IO_PORT_SRC_EXTERNAL, ///< external (e.g. for inputs)
N_MBG_IO_PORT_SRCS
};
@@ -19616,7 +20199,10 @@ enum MBG_IO_PORT_SRCS
"Clock 2 fixed", \
"Any rate converter", \
"Oscillator", \
- "SyncE" \
+ "SyncE", \
+ "Switch card", \
+ "Configurable", \
+ "External" \
}
@@ -19629,15 +20215,18 @@ enum 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
+ 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
+ MBG_IO_PORT_SRC_MSK_SWITCH_CARD = (1UL << MBG_IO_PORT_SRC_SWITCH_CARD), ///< See ::MBG_IO_PORT_SRC_SWITCH_CARD
+ MBG_IO_PORT_SRC_MSK_CONFIGURABLE = (1UL << MBG_IO_PORT_SRC_CONFIGURABLE), ///< See ::MBG_IO_PORT_SRC_CONFIGURABLE
+ MBG_IO_PORT_SRC_MSK_EXTERNAL = (1UL << MBG_IO_PORT_SRC_EXTERNAL) ///< See ::MBG_IO_PORT_SRC_EXTERNAL
};
@@ -19666,11 +20255,45 @@ enum MBG_IO_PORT_CONN_TYPES
MBG_IO_PORT_CONN_TYPE_DSUB9,
MBG_IO_PORT_CONN_TYPE_FIBRE_ST,
MBG_IO_PORT_CONN_TYPE_XHE_SPI,
+ MBG_IO_PORT_CONN_TYPE_LED_BUTTON,
+ MBG_IO_PORT_CONN_TYPE_QUAD_LED,
+ MBG_IO_PORT_CONN_TYPE_5_PIN_DFK,
N_MBG_IO_PORT_CONN_TYPES
};
/**
+ * @brief Number of variable pols of the connector type, see ::MBG_IO_PORT_INFO::pols
+ *
+ * Used with ::MBG_IO_PORT_INFO::conn_type and ::MBG_IO_PORT_INFO::pols
+ *
+ */
+#define MBG_IO_PORT_CONN_TYPE_VAR_POLS \
+{ \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 16, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 1, \
+ 4, \
+ 1 \
+}
+
+
+/**
* @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,
@@ -19696,48 +20319,79 @@ enum MBG_IO_PORT_CONN_TYPES
"BNC isolated", \
"D-Sub 9", \
"Fibre ST", \
- "XHE SPI" \
+ "XHE SPI", \
+ "LED Button", \
+ "Quad LED", \
+ "DFK 5-Pin" \
+}
+
+
+enum MBG_IO_PORT_FLAGS
+{
+ MBG_IO_PORT_FLAG_HORIZONTAL_LAYOUT, ///< Modules (rows and columns) are layouted horizontally
+ MBG_IO_PORT_FLAG_FRONT_PORTS, ///< Device has ports at the front side
+ MBG_IO_PORT_FLAG_REAR_PORTS, ///< Device has ports at the rear side
+ MBG_IO_PORT_FLAG_NO_LABEL, ///< Device does not have a label
+ MBG_IO_PORT_FLAG_NO_GRASP, ///< Device does not have a grasp
+ N_MBG_IO_PORT_FLAGS
+};
+
+
+enum MBG_IO_PORT_MSKS
+{
+ MBG_IO_PORT_MSK_HORIZONTAL_LAYOUT = ( 1UL << MBG_IO_PORT_FLAG_HORIZONTAL_LAYOUT ), ///< See ::MBG_IO_PORT_FLAG_HORIZONTAL_LAYOUT
+ MBG_IO_PORT_MSK_FRONT_PORTS = ( 1UL << MBG_IO_PORT_FLAG_FRONT_PORTS ), ///< See ::MBG_IO_PORT_FLAG_FRONT_PORTS
+ MBG_IO_PORT_MSK_REAR_PORTS = ( 1UL << MBG_IO_PORT_FLAG_REAR_PORTS ), ///< See ::MBG_IO_PORT_FLAG_REAR_PORTS
+ MBG_IO_PORT_MSK_NO_LABEL = ( 1UL << MBG_IO_PORT_FLAG_NO_LABEL ), ///< See ::MBG_IO_PORT_FLAG_REAR_PORTS
+ MBG_IO_PORT_MSK_NO_GRASP = ( 1UL << MBG_IO_PORT_FLAG_NO_GRASP ) ///< See ::MBG_IO_PORT_FLAG_NO_GRASP
+};
+
+
+enum MBG_IO_PORT_BG_COLOURS
+{
+ MBG_IO_PORT_BG_COLOUR_SILVER,
+ MBG_IO_PORT_BG_COLOUR_BLACK,
+ MBG_IO_PORT_BG_COLOUR_BLUE,
+ N_MBG_IO_PORT_BG_COLOURS
+};
+
+
+#define MBG_IO_PORT_BG_COLOUR_STRS \
+{ \
+ "Silver", \
+ "Black", \
+ "Blue" \
}
/**
- * @brief Position of a port on a card
+ * @brief Enumeration of known signal shapes/levels
*
- * Used with ::MBG_IO_PORT_INFO::position
+ * Used to specify the signal shape/level of an I/O port.
*
+ * @see ::MBG_IO_PORT_SHAPE_LEVEL_STRS
*/
-enum MBG_IO_PORT_POS
+enum MBG_IO_PORT_SHAPE_LEVELS
{
- 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
+ MBG_IO_PORT_SHAPE_LEVEL_NONE, ///< Unknown or unspecified signal shape.
+ ///< Must be zero for backward compatibility.
+ MBG_IO_PORT_SHAPE_LEVEL_SINE, ///< Sine wave
+ MBG_IO_PORT_SHAPE_LEVEL_SQUARE, ///< Square wave
+ N_MBG_IO_PORT_SHAPE_LEVELS ///< Number of known signal shapes
};
/**
- * @brief Bit masks of Meinberg I/O port attitudes
+ * @brief String initializers for I/O port shapes/levels
*
- * Used with ::MBG_IO_PORT_TYPE_INFO::supp_srcs
- *
- * @see ::MBG_IO_PORT_POS
+ * @see ::MBG_IO_PORT_SHAPE_LEVELS
*/
-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
-};
+#define MBG_IO_PORT_SHAPE_LEVEL_STRS \
+{ \
+ "None", \
+ "Sine wave", \
+ "Rectangle Pulse" \
+}
/**
@@ -19757,16 +20411,30 @@ enum MBG_IO_PORT_POS_MSKS
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
+ uint8_t num_cols; ///< Number of port columns this device supports
+ uint8_t num_rows; ///< Number of port rows this device supports
+ uint8_t bg_colour; ///< Background colour of the IO ports, see ::MBG_IO_PORT_BG_COLOURS
+
+ uint32_t reserved; ///< Reserved, currently 0
+ uint32_t flags; ///< See ::MBG_IO_PORT_MSKS
+
+ uint8_t label_col; ///< Column position of the device label, consider ::MBG_IO_PORT_MSK_NO_LABEL
+ uint8_t label_row; ///< Row position of the device label, consider ::MBG_IO_PORT_MSK_NO_LABEL
+ uint8_t grasp_col; ///< Column position of the device grasp, consider ::MBG_IO_PORT_MSK_NO_GRASP
+ uint8_t grasp_row; ///< Row position of the device grasp, consider ::MBG_IO_PORT_MSK_NO_GRASP
+
+ uint8_t label_rear; ///< Indicates, that the label is on the rear side
+ uint8_t grasp_rear; ///< Indicates, that the grasp is on the rear side
+ uint16_t reserved_2; ///< Reserved, currently 0
+
+ uint32_t reserved_3[7]; ///< Reserved, currently 0
} MBG_IO_PORT_LIMITS;
#define _mbg_swab_io_port_limits( _p ) \
do \
{ \
- _mbg_swab32( &(_p)->supp_positions ); \
+ _mbg_swab32( &(_p)->flags ); \
} while ( 0 )
@@ -19788,6 +20456,8 @@ enum MBG_IO_PORT_OP_MODE_BITS
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
+ MBG_IO_PORT_OP_MODE_ENABLED, ///< Enabled
+ MBG_IO_PORT_OP_MODE_PASSTHROUGH, ///< Forwarded signals from backplane (e.g. PPS of BPE)
N_MBG_IO_PORT_OP_MODE_BITS
};
@@ -19805,7 +20475,9 @@ enum MBG_IO_PORT_OP_MODE_BITS
"Disabled", \
"Always enabled", \
"If sync only", \
- "Always after sync" \
+ "Always after sync", \
+ "Enabled", \
+ "Passed through" \
}
@@ -19822,7 +20494,9 @@ 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
+ MBG_IO_PORT_OP_MODE_MSK_AFTER_SYNC = (1UL << MBG_IO_PORT_OP_MODE_AFTER_SYNC), ///< See ::MBG_IO_PORT_OP_MODE_AFTER_SYNC
+ MBG_IO_PORT_OP_MODE_MSK_ENABLED = (1UL << MBG_IO_PORT_OP_MODE_ENABLED), ///< See ::MBG_IO_PORT_OP_MODE_ENABLED
+ MBG_IO_PORT_OP_MODE_MSK_PASSTHROUGH = (1UL << MBG_IO_PORT_OP_MODE_PASSTHROUGH) ///< See ::MBG_IO_PORT_OP_MODE_PASSTHROUGH
};
@@ -19877,6 +20551,69 @@ enum MBG_IO_PORT_GRP_ROLE_MSKS
/**
+ * @brief Supported members in ::MBG_IO_PORT_ANTENNA_INFO and ::MBG_IO_PORT_ANTENNA_SETTINGS
+ *
+ * Used with ::MBG_IO_PORT_ANTENNA_INFO::supp_members
+ *
+ */
+enum MBG_IO_PORT_ANT_MEMBERS
+{
+ /// Supports ::MBG_IO_PORT_ANT_INFO::gnss_info and ::MBG_IO_PORT_ANT_SETTINGS::gnss_settings
+ MBG_IO_PORT_ANT_MEMBER_GNSS,
+ /// Supports ::MBG_IO_PORT_ANT_SETTINGS::ant_cab_len
+ MBG_IO_PORT_ANT_MEMBER_CAB_LEN,
+ /// Supports ::MBG_IO_PORT_ANT_SETTINGS::ignore_lock
+ MBG_IO_PORT_ANT_MEMBER_IGN_LOCK,
+ /// Supports ::MBG_IO_PORT_ANT_SETTINGS::tr_dist
+ MBG_IO_PORT_ANT_MEMBER_TR_DIST,
+ N_MBG_IO_PORT_ANT_MEMBERS
+};
+
+
+enum MBG_IO_PORT_ANT_MEMBER_MSKS
+{
+ MBG_IO_PORT_ANT_MEMBER_MSK_GNSS = (1UL << MBG_IO_PORT_ANT_MEMBER_GNSS), /// See ::MBG_IO_PORT_ANT_MEMBER_GNSS
+ MBG_IO_PORT_ANT_MEMBER_MSK_CAB_LEN = (1UL << MBG_IO_PORT_ANT_MEMBER_CAB_LEN), /// See ::MBG_IO_PORT_ANT_MEMBER_CAB_LEN
+ MBG_IO_PORT_ANT_MEMBER_MSK_IGN_LOCK = (1UL << MBG_IO_PORT_ANT_MEMBER_IGN_LOCK), /// See ::MBG_IO_PORT_ANT_MEMBER_IGN_LOCK
+ MBG_IO_PORT_ANT_MEMBER_MSK_TR_DIST = (1UL << MBG_IO_PORT_ANT_MEMBER_TR_DIST) /// See ::MBG_IO_PORT_ANT_MEMBER_TR_DIST
+};
+
+
+typedef struct
+{
+ uint32_t supp_members;
+ MBG_GNSS_MODE_INFO gnss_info;
+
+} MBG_IO_PORT_ANT_INFO;
+
+#define _mbg_swab_io_port_ant_info( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->supp_members ); \
+ _mbg_swab_mbg_gnss_mode_info( &(_p)->gnss_info ); \
+} while ( 0 )
+
+typedef struct
+{
+ MBG_GNSS_MODE_SETTINGS gnss_settings;
+ ANT_CABLE_LEN ant_cab_len;
+ IGNORE_LOCK ignore_lock;
+ /* Do not include pcpsdefs.h -> Use the non-typedefed type */
+ uint16_t tr_dist;
+
+} MBG_IO_PORT_ANT_SETTINGS;
+
+#define _mbg_swab_io_port_ant_settings( _p ) \
+do \
+{ \
+ _mbg_swab_mbg_gnss_mode_settings( &(_p)->gnss_settings ); \
+ _mbg_swab_ant_cable_len( &(_p)->ant_cab_len ); \
+ _mbg_swab16( &(_p)->ignore_lock ); \
+ _mbg_swab16( &(_p)->tr_dist ); \
+} while ( 0 )
+
+
+/**
* @brief IO Port Settings Union
*
* @see @ref group_io_ports
@@ -19894,6 +20631,9 @@ typedef union
{
MBG_GPIO_SETTINGS gpio_settings;
POUT_SETTINGS pout_settings;
+ IRIG_SETTINGS irig_settings;
+ MBG_IO_PORT_ANT_SETTINGS ant_settings;
+ PORT_SETTINGS uart_settings;
} MBG_IO_PORT_SETTINGS_U;
@@ -19912,6 +20652,18 @@ do \
else _mbg_swab_pout_settings_on_set( &(_p)->pout_settings ); \
break; \
\
+ case MBG_IO_PORT_TYPE_TIMECODE: \
+ _mbg_swab_irig_settings( &(_p)->irig_settings ); \
+ break; \
+ \
+ case MBG_IO_PORT_TYPE_ANTENNA: \
+ _mbg_swab_io_port_ant_settings( &(_p)->ant_settings ); \
+ break; \
+ \
+ case MBG_IO_PORT_TYPE_UART: \
+ _mbg_swab_port_settings( &(_p)->uart_settings ); \
+ break; \
+ \
default: break; \
} \
} while ( 0 )
@@ -19940,7 +20692,8 @@ typedef struct
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
+ uint8_t pt_idx; ///< index of the port types (e.g. 0 for PPO0, 1 for PPO1, ...)
+ uint8_t reserved_1[2]; ///< Future use and padding, currently 0
uint32_t reserved_2[6]; ///< Future use and padding, currently 0
/*
@@ -20000,21 +20753,41 @@ do \
#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_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 */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SWITCH */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( IRIG_SETTINGS ), /* MBG_IO_PORT_TYPE_TIMECODE */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_LIGHT */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( MBG_IO_PORT_ANT_SETTINGS ), /* MBG_IO_PORT_TYPE_ANTENNA */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( PORT_SETTINGS ), /* MBG_IO_PORT_TYPE_UART */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_DCF77 */ \
+ MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE /* MBG_IO_PORT_TYPE_POWER */ \
}
+enum MBG_IO_PORT_INFO_BITS
+{
+ MBG_IO_PORT_INFO_BIT_IS_ALIGNED ///< Indicates, that this port shall be optically aligned to ::MBG_IO_PORT_INFO::align_rule_idx
+};
+
+
+enum MBG_IO_PORT_INFO_MASKS
+{
+ MBG_IO_PORT_INFO_MASK_IS_ALIGNED = ( 1UL << MBG_IO_PORT_INFO_BIT_IS_ALIGNED ) ///< see ::MBG_IO_PORT_INFO_BIT_IS_ALIGNED
+};
+
+
#define MBG_NO_PHYS_GROUP 0xFF
#define MBG_NO_LOG_GROUP 0xFF
+#define MBG_IO_PORT_STR_SIZE 16
/**
* @brief IO Port Info
@@ -20032,17 +20805,22 @@ do \
*/
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
+ uint8_t num_types; ///< See ::MBG_IO_PORT_TYPE_INFO
+ uint8_t conn_type; ///< See ::MBG_IO_PORT_CONN_TYPES
+ uint8_t reserved_1; ///< Future use and padding, currently 0
+ uint8_t align_rule_idx; ///< Index of the ::MBG_IO_PORT_INFO_IDX this port shall be optically aligned to
+ 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 pos_col; ///< Column position of this port
+ uint8_t pos_row; ///< Row position of this port
+ uint8_t rear; ///< Indicates, whether the port is on the front or rear side
+ uint32_t pols; ///< Pols which are used by this IO port, only if @p conn_type has more than 1 variable pol
+ uint32_t flags; ///< Flags, see ::MBG_IO_PORT_INFO_MASKS
+ uint32_t reserved_2[2]; ///< Future use and padding, currently 0
+ char use_str[MBG_IO_PORT_STR_SIZE]; ///< Informational string for user interface, i.e. "NTP Status LED"
+ char rel_str[MBG_IO_PORT_STR_SIZE]; ///< Internally used relation string, i.e. "lan0", "fpga0" or "/dev/ttyS0"
+ MBG_IO_PORT_SETTINGS settings; ///< See ::MBG_IO_PORT_SETTINGS
} MBG_IO_PORT_INFO;
@@ -20053,6 +20831,8 @@ do \
{ \
_mbg_swab16( &(_p)->supp_op_modes ); \
_mbg_swab16( &(_p)->supp_phys_grp_roles ); \
+ _mbg_swab32( &(_p)->pols ); \
+ _mbg_swab32( &(_p)->flags ); \
_mbg_swab_io_port_settings( &(_p)->settings, (_recv) ); \
} while ( 0 )
@@ -20098,16 +20878,23 @@ do \
#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 */ \
+#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 */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SWITCH */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( IRIG_SETTINGS ), /* MBG_IO_PORT_TYPE_TIMECODE */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_LIGHT */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( MBG_IO_PORT_ANT_SETTINGS ), /* MBG_IO_PORT_TYPE_ANTENNA */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( PORT_SETTINGS ), /* MBG_IO_PORT_TYPE_UART */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_DCF77 */ \
+ MBG_IO_PORT_INFO_IDX_MIN_SIZE /* MBG_IO_PORT_TYPE_POWER */ \
}
@@ -20130,6 +20917,9 @@ typedef union
{
MBG_GPIO_LIMITS gpio_limits;
POUT_INFO pout_info;
+ IRIG_INFO irig_info;
+ PORT_INFO uart_info;
+ MBG_IO_PORT_ANT_INFO ant_info;
} MBG_IO_PORT_TYPE_INFO_U;
@@ -20146,6 +20936,18 @@ do \
_mbg_swab_pout_info_on_get( &(_p)->pout_info ); \
break; \
\
+ case MBG_IO_PORT_TYPE_TIMECODE: \
+ _mbg_swab_irig_info( &(_p)->irig_info ); \
+ break; \
+ \
+ case MBG_IO_PORT_TYPE_ANTENNA: \
+ _mbg_swab_io_port_ant_info( &(_p)->ant_info ); \
+ break; \
+ \
+ case MBG_IO_PORT_TYPE_UART: \
+ _mbg_swab_port_info( &(_p)->uart_info ); \
+ break; \
+ \
default: break; \
} \
} while ( 0 )
@@ -20172,9 +20974,11 @@ do \
typedef struct
{
uint16_t port_type; ///< See ::MBG_IO_PORT_TYPES
- uint16_t reserved_1; ///< Future use and padding, currently 0
+ 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
+ uint8_t pt_idx; ///< index of the port types (e.g. 0 for PPO0, 1 for PPO1, ...)
+ uint8_t shape_level; ///< Signal shape/level, see ::MBG_IO_PORT_SHAPE_LEVELS
+ uint8_t reserved_2[1]; ///< 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
@@ -20202,16 +21006,23 @@ do \
#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 */ \
+#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 */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SWITCH */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( IRIG_INFO ), /* MBG_IO_PORT_TYPE_TIMECODE */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_LIGHT */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( MBG_IO_PORT_ANT_INFO ), /* MBG_IO_PORT_TYPE_ANTENNA */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( PORT_INFO ), /* MBG_IO_PORT_TYPE_UART */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_DCF77 */ \
+ MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE /* MBG_IO_PORT_TYPE_POWER */ \
}
@@ -20265,6 +21076,10 @@ enum MBG_IO_PORT_STATUS_BITS
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
+ MBG_IO_PORT_STATUS_BIT_LIGHT_RED, ///< LED shows red light
+ MBG_IO_PORT_STATUS_BIT_LIGHT_GREEN, ///< LED shows green light
+ MBG_IO_PORT_STATUS_BIT_LIGHT_BLUE, ///< LED shows blue light
+ MBG_IO_PORT_STATUS_BIT_LIGHT_YELLOW, ///< LED shows yellow light
N_MBG_IO_PORT_STATUS_BITS
};
@@ -20284,7 +21099,11 @@ enum MBG_IO_PORT_STATUS_BITS
"Input signal has never been avail", \
"Input signal is avail", \
"Input signal is currently lost", \
- "Short circuit" \
+ "Short circuit", \
+ "Red", \
+ "Green", \
+ "Blue", \
+ "Yellow" \
}
@@ -20335,6 +21154,19 @@ typedef struct
/**
+ * @brief Clear a 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 _clear_io_port_status_bit( _status_bit, _status_buffp ) \
+ _clear_array_bit( _status_bit, (_status_buffp)->b, MAX_IO_PORT_STATUS_BYTES )
+
+
+/**
* @brief IO Port Type Status
*
* @see @ref group_io_ports
@@ -20353,7 +21185,7 @@ 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 reserved; ///< Future use
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
@@ -20488,6 +21320,33 @@ enum MBG_SNMP_VERSION_MSKS
};
+enum MBG_SNMP_FLAGS
+{
+ MBG_SNMP_SYSTEM_USER,
+ MBG_SNMP_ADD_CONF, ///< Supports additional SNMP configuration (i.e. via script)
+ N_MBG_SNMP_FLAGS
+};
+
+
+#define MBG_SNMP_FLAG_STRS \
+{ \
+ "System user", \
+ "Additional config" \
+}
+
+
+enum MBG_SNMP_FLAG_MSKS
+{
+ MBG_SNMP_SYSTEM_USER_MSK = ( 1UL << MBG_SNMP_SYSTEM_USER ),
+ MBG_SNMP_ADD_CONF_MSK = ( 1UL << MBG_SNMP_ADD_CONF ) ///< see ::MBG_SNMP_ADD_CONF
+};
+
+
+#define SNMP_DEF_ADD_CONF_PATH "/etc/mbg"
+#define SNMP_DEF_ADD_CONF_FILENAME "snmp.conf.add"
+#define SNMP_DEF_ADD_CONF_FILE SNMP_DEF_ADD_CONF_PATH "/" SNMP_DEF_ADD_CONF_FILENAME
+
+
typedef struct
{
@@ -20501,6 +21360,7 @@ typedef struct
char location[MBG_MONITORING_STR_SIZE];
char contact[MBG_MONITORING_STR_SIZE];
char name[MBG_MONITORING_STR_SIZE];
+ char description[MBG_MONITORING_STR_SIZE];
char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use
char reserved_4[MBG_MONITORING_STR_SIZE]; ///< Future use
@@ -20522,7 +21382,9 @@ typedef struct
uint8_t max_v3_settings; ///< Only valid if ::MBG_SNMP_GLB_INFO::supp_versions contains ::MBG_SNMP_VERSION_MSK_V3
uint8_t max_v12_trap_receivers; ///< Only valid if ::MBG_SNMP_GLB_INFO::supp_versions contains ::MBG_SNMP_VERSION_MSK_V1 or ::MBG_SNMP_VERSION_MSK_V2c
uint8_t max_v3_trap_receivers; ///< Only valid if ::MBG_SNMP_GLB_INFO::supp_versions contains ::MBG_SNMP_VERSION_MSK_V3
- uint8_t reserved_1[3];
+ uint8_t reserved_1[1];
+ uint16_t supp_flags; ///< See ::MBG_SNMP_FLAG_MSKS
+ /// MBG_SNMP_SYSTEM_USER_MSK is only relevant for SNMPv3
uint32_t reserved_2[2];
} MBG_SNMP_GLB_INFO;
@@ -20531,6 +21393,7 @@ typedef struct
do \
{ \
_mbg_swab_snmp_glb_settings( &(_p)->settings ); \
+ _mbg_swab16( &(_p)->supp_flags ); \
} while ( 0 )
@@ -20744,11 +21607,13 @@ typedef struct
///< 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 ::MBG_SNMP_V3_SETTINGS::sec_level
///< is ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV
+ uint16_t flags; ///< See ::MBG_SNMP_FLAG_MSKS
+ uint16_t reserved_0;
uint32_t reserved_1[3];
char user_name[MBG_MONITORING_STR_SIZE]; ///< User name used for authentication, always required.
char auth_passwd[MBG_MONITORING_STR_SIZE]; ///< Password associated with ::MBG_SNMP_V3_SETTINGS::user_name, if ::MBG_SNMP_V3_SETTINGS::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 sec_engine_id[MBG_MONITORING_STR_SIZE]; ///< Mandatory for traps only
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
@@ -20889,17 +21754,21 @@ enum MBG_EVENT_TYPES
{
MBG_EVENT_TYPE_NTP_STATE,
MBG_EVENT_TYPE_HEARTBEAT,
+ MBG_EVENT_TYPE_RECEIVER_STATE,
N_MBG_EVENT_TYPES
};
#define MBG_EVENT_TYPE_STRS \
{ \
"NTP state", \
- "Heartbeat" \
+ "Heartbeat", \
+ "Receiver state" \
}
+
enum MBG_EVENT_SEVERITIES
{
+ MBG_EVENT_SEVERITY_OK,
MBG_EVENT_SEVERITY_INFO,
MBG_EVENT_SEVERITY_WARNING,
MBG_EVENT_SEVERITY_ERROR,
@@ -20909,26 +21778,18 @@ enum MBG_EVENT_SEVERITIES
#define MBG_EVENT_SEVERITY_STRS \
{ \
+ "OK", \
"Info", \
"Warning", \
"Error", \
"Critical" \
}
-enum MBG_EVENT_SEVERITY_MSKS
-{
- MBG_EVENT_SEVERITY_MSK_INFO = (1UL << MBG_EVENT_SEVERITY_INFO),
- MBG_EVENT_SEVERITY_MSK_WARNING = (1UL << MBG_EVENT_SEVERITY_WARNING),
- MBG_EVENT_SEVERITY_MSK_ERROR = (1UL << MBG_EVENT_SEVERITY_ERROR),
- MBG_EVENT_SEVERITY_MSK_CRITICAL = (1UL << MBG_EVENT_SEVERITY_CRITICAL)
-};
-
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; ///< [s], only if ::MBG_EVENT_SUPP_FLAG_INTERVAL is set in ::MBG_EVENT_INFO::supp_flags, else 0.
+ uint16_t reserved_1;
uint16_t reserved_2;
uint32_t reserved_3[6];
@@ -20978,40 +21839,53 @@ enum MBG_EVENT_SUPP_FLAG_MSKS
-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
-};
+/**
+ * @defgroup group_mbg_event_info_indexes Monitoring Event Info Indexes
+ *
+ * It's very important to understand how to use event indexes properly.
+ * In general, think of a management master system (MMS)
+ * like a LANTIME that is able to send its own events like "NTP not sync"
+ * and that is even able to send/forward events from other IMS modules
+ * like "CLK1 Antenna Disconnected". In case it is an event of the MMS
+ * itself, indexes in ::MBG_EVENT_INFO should be set to its "own" values below.
+ * But in case it is an event of an "IMS slave card" like a GPS180
+ * at least ::MBG_EVENT_INFO::slot_type and ::MBG_EVENT_INFO::slot_type_id
+ * should be set. Most events will likely not support a port or a foreign
+ * chassis, so set ::MBG_EVENT_INFO::port_idx to ::MBG_INV_EVENT_PORT and/or
+ * ::MBG_EVENT_INFO::chassis_idx to ::MBG_OWN_EVENT_CHASSIS.
+ * Please be aware that there are IMS modules like SSP100 that tend to be
+ * "IMS slave cards", but they are, in fact, MMS because most of the time
+ * they are not connected to the main CPU via USB and
+ * therefore they send their "own" events.
+ *
+ * @{ */
+#define MBG_OWN_EVENT_CHASSIS 0xFF ///< See ::MBG_EVENT_INFO::chassis_idx
+#define MBG_OWN_EVENT_SLOT_TYPE 0xFF ///< See ::MBG_EVENT_INFO::slot_type
+#define MBG_OWN_EVENT_SLOT_TYPE_ID 0xFF ///< See ::MBG_EVENT_INFO::slot_type_id
+#define MBG_INV_EVENT_PORT 0xFF ///< See ::MBG_EVENT_INFO::port_idx
-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
+/** @} defgroup group_mbg_event_info_indexes */
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
+ MBG_EVENT_SETTINGS settings; ///< See ::MBG_EVENT_SETTINGS
+ uint16_t type; ///< See ::MBG_EVENT_TYPES
+ uint8_t chassis_idx; ///< Index of the associated IMS chassis, or ::MBG_OWN_EVENT_CHASSIS
+ uint8_t slot_type; ///< See ::XBP_NODE_INFO::slot_type, or ::MBG_OWN_EVENT_SLOT_TYPE
+ uint8_t port_idx; ///< Index of the associated IO port, or ::MBG_INV_EVENT_PORT
+ uint8_t value_type; ///< See ::MBG_EVENT_VALUE_TYPES
+ uint16_t value_dict_entries; ///< Number of entries in value dictionary, see ::MBG_EVENT_VALUE_IDX
- 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
+ uint8_t slot_type_id; ///< See ::XBP_NODE_INFO::slot_type_id, or ::MBG_OWN_EVENT_SLOT_TYPE_ID
+ uint8_t reserved_1; ///< Future use
+ uint16_t supp_flags; ///< See ::MBG_EVENT_SUPP_FLAG_MSKS
+ uint16_t supp_triggers; ///< See ::MBG_MONITORING_TYPE_MSKS
+ uint16_t reserved_2; ///< Future use
- uint32_t reserved_3[4];
+ uint32_t reserved_3[6];
} MBG_EVENT_INFO;
@@ -21020,7 +21894,7 @@ do \
{ \
_mbg_swab_event_settings( &(_p)->settings ); \
_mbg_swab16( &(_p)->type ); \
- _mbg_swab16( &(_p)->supp_severities ); \
+ _mbg_swab16( &(_p)->value_dict_entries ); \
_mbg_swab16( &(_p)->supp_flags ); \
_mbg_swab16( &(_p)->supp_triggers ); \
_mbg_swab16( &(_p)->flags ); \
@@ -21053,138 +21927,1697 @@ do \
} while ( 0 )
+enum MBG_EVENT_VALUE_TYPES
+{
+ MBG_EVENT_VALUE_TYPE_NONE, ///< Sounds stupid but think of heartbeat
+ MBG_EVENT_VALUE_TYPE_INTEGER32,
+ MBG_EVENT_VALUE_TYPE_UNSIGNED32,
+ MBG_EVENT_VALUE_TYPE_STRING,
+ MBG_EVENT_VALUE_TYPE_IRANGE,
+ MBG_EVENT_VALUE_TYPE_URANGE,
+ MBG_EVENT_VALUE_TYPE_SELECTION,
+ N_MBG_EVENT_VALUE_TYPES
+};
+
+
+
+#define MBG_EVENT_VALUE_TYPE_STRS \
+{ \
+ "None", \
+ "Signed32", \
+ "Unsigned32", \
+ "String", \
+ "Signed range", \
+ "Unsigned range", \
+ "Selection" \
+}
+
+
+
+typedef char MBG_EVENT_STR[64];
+
+
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];
+ int32_t value;
+ MBG_EVENT_STR string;
-} MBG_MONITORING_STATUS;
+} MBG_EVENT_VALUE_SELECTION;
-#define _mbg_swab_monitoring_status( _p ) \
+#define _mbg_swab_event_value_selection( _p ) \
do \
{ \
+ _mbg_swab32( &(_p)->value ); \
} while ( 0 )
-enum MBG_EVENT_STATUS_FLAGS
+typedef struct
{
- MBG_EVENT_STATUS_FLAG_ACTIVE, ///< Event is currently active
- N_MBG_EVENT_STATUS_FLAGS
-};
+ int32_t min;
+ int32_t max;
+
+} MBG_EVENT_VALUE_IRANGE;
+#define _mbg_swab_event_value_irange( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->min ); \
+ _mbg_swab32( &(_p)->max ); \
+} while ( 0 )
-enum MBG_EVENT_STATUS_FLAG_MSKS
+
+
+typedef struct
{
- MBG_EVENT_STATUS_FLAG_MSK_ACTIVE = (1UL << MBG_EVENT_STATUS_FLAG_ACTIVE)
-};
+ uint32_t min;
+ uint32_t max;
+
+} MBG_EVENT_VALUE_URANGE;
+
+#define _mbg_swab_event_value_urange( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->min ); \
+ _mbg_swab32( &(_p)->max ); \
+} while ( 0 )
+
+
+/*
+ * Maximum size is limited to 68 bytes -> MBG_EVENT_VALUE_SELECTION
+ * Don't enlarge it due to compatibility reasons!!
+ */
+typedef union
+{
+ MBG_EVENT_VALUE_SELECTION selection;
+ MBG_EVENT_VALUE_IRANGE irange;
+ MBG_EVENT_VALUE_URANGE urange;
+
+} MBG_EVENT_VALUE;
+
+#define _mbg_swab_event_value( _p, _type ) \
+do \
+{ \
+ switch ( (_type) ) \
+ { \
+ case MBG_EVENT_VALUE_TYPE_SELECTION: \
+ _mbg_swab_event_value_selection( &(_p)->selection ); \
+ break; \
+ \
+ case MBG_EVENT_VALUE_TYPE_IRANGE: \
+ _mbg_swab_event_value_irange( &(_p)->irange ); \
+ break; \
+ \
+ case MBG_EVENT_VALUE_TYPE_URANGE: \
+ _mbg_swab_event_value_urange( &(_p)->urange ); \
+ break; \
+ \
+ default: \
+ break; \
+ } \
+} while ( 0 )
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];
+ uint32_t idx;
+ MBG_EVENT_VALUE value;
+
+} MBG_EVENT_VALUE_IDX;
+
+#define _mbg_swab_event_value_idx( _p, _type ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_event_value( &(_p)->value, (_type) ); \
+} while ( 0 )
+
+
+/*
+ * Maximum union size is limited to 64 bytes -> MBG_EVENT_STR
+ * Don't enlarge the union due to compatibility reasons!!
+ */
+typedef struct
+{
+ uint32_t last_changed; ///< Unix timestamp when this event state has been changed
+ uint32_t reserved_1[3]; ///< Future use
+ uint8_t severity; ///< See ::MBG_EVENT_SEVERITIES
+ uint8_t reserved_2[3]; ///< Future use
+ union
+ {
+ int32_t i32;
+ uint32_t u32;
+ MBG_EVENT_STR string;
+
+ } u;
} MBG_EVENT_STATUS;
-#define _mbg_swab_event_status( _p ) \
+#define _mbg_swab_event_status( _p, _type ) \
do \
{ \
- _mbg_swab16( &(_p)->flags ); \
- _mbg_swab32( &(_p)->last_triggered ); \
+ _mbg_swab32( &(_p)->last_changed ); \
+ switch ( (_type) ) \
+ { \
+ case MBG_EVENT_VALUE_TYPE_INTEGER32: \
+ _mbg_swab32( &(_p)->u.i32 ); \
+ break; \
+ \
+ case MBG_EVENT_VALUE_TYPE_UNSIGNED32: \
+ _mbg_swab32( &(_p)->u.u32 ); \
+ break; \
+ \
+ default: \
+ break; \
+ } \
} while ( 0 )
typedef struct
{
- uint16_t idx;
+ uint32_t idx;
MBG_EVENT_STATUS status;
} MBG_EVENT_STATUS_IDX;
-#define _mbg_swab_event_status_idx( _p ) \
+#define _mbg_swab_event_status_idx( _p, _type ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_event_status( &(_p)->status, (_type) ); \
+} while ( 0 )
+
+
+
+enum MBG_SYSLOG_FLAGS
+{
+ MBG_SYSLOG_FLAG_NULL_TIMESTAMP, ///< Receiver should use his own timestamp
+ N_MBG_SYSLOG_FLAGS
+};
+
+
+enum MBG_SYSLOG_FLAG_MSKS
+{
+ MBG_SYSLOG_FLAG_MSK_NULL_TIMESTAMP = (1UL << MBG_SYSLOG_FLAG_NULL_TIMESTAMP), ///< See ::MBG_SYSLOG_FLAG_NULL_TIMESTAMP
+};
+
+
+enum MBG_SYSLOG_PROTOCOLS
+{
+ MBG_SYSLOG_PROTOCOL_UDP,
+ MBG_SYSLOG_PROTOCOL_TCP,
+ N_MBG_SYSLOG_PROTOCOLS
+};
+
+#define MBG_SYSLOG_PROTOCOL_STRS \
+{ \
+ "UDP", \
+ "TCP" \
+}
+
+
+enum MBG_SYSLOG_PROTOCOL_MSKS
+{
+ MBG_SYSLOG_PROTOCOL_MSK_UDP = (1UL << MBG_SYSLOG_PROTOCOL_UDP), ///< See ::MBG_SYSLOG_PROTOCOL_UDP
+ MBG_SYSLOG_PROTOCOL_MSK_TCP = (1UL << MBG_SYSLOG_PROTOCOL_TCP) ///< See ::MBG_SYSLOG_PROTOCOL_TCP
+};
+
+
+typedef struct
+{
+ uint8_t num_servers; ///< Number of configured servers
+ uint8_t reserved_1[3];
+ uint32_t reserved_2[3];
+
+} MBG_SYSLOG_GLB_SETTINGS;
+
+#define _mbg_swab_syslog_glb_settings( _p ) \
+do \
+{ \
+} while ( 0 )
+
+
+typedef struct
+{
+ MBG_SYSLOG_GLB_SETTINGS settings; ///< MBG_SYSLOG_GLB_SETTINGS
+
+ uint8_t max_servers; ///< Maximum number of configurable servers
+ uint8_t reserved_1[3];
+ uint32_t supp_flags; ///< See ::MBG_SYSLOG_FLAG_MSKS
+ uint32_t supp_protocols; ///< See ::MBG_SYSLOG_PROTOCOL_MSKS
+
+ uint32_t reserved_2[5];
+
+} MBG_SYSLOG_GLB_INFO;
+
+#define _mbg_swab_syslog_glb_info( _p ) \
+do \
+{ \
+ _mbg_swab_syslog_glb_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+ _mbg_swab32( &(_p)->supp_protocols ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ char host[MBG_MAX_HOSTNAME_LEN];
+ uint8_t protocol; ///< See ::MBG_SYSLOG_PROTOCOLS
+ uint8_t reserved_1;
+ uint16_t port; ///< Protocol port
+ uint32_t flags; ///< See ::MBG_SYSLOG_FLAG_MSKS
+ uint32_t reserved_3[6];
+
+} MBG_SYSLOG_SETTINGS;
+
+#define _mbg_swab_syslog_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->port ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ MBG_SYSLOG_SETTINGS settings;
+ uint32_t idx;
+
+} MBG_SYSLOG_SETTINGS_IDX;
+
+#define _mbg_swab_syslog_settings_idx( _p ) \
do \
{ \
- _mbg_swab16( &(_p)->idx ); \
- _mbg_swab_event_status( &(_p)->status ); \
+ _mbg_swab_syslog_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->idx ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ MBG_SYSLOG_SETTINGS settings; ///< See ::MBG_SYSLOG_SETTINGS
+ uint32_t reserved[8];
+
+} MBG_SYSLOG_INFO;
+
+#define _mbg_swab_syslog_info( _p ) \
+do \
+{ \
+ _mbg_swab_syslog_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ MBG_SYSLOG_INFO info; ///< See ::MBG_SYSLOG_INFO
+ uint32_t idx;
+
+} MBG_SYSLOG_INFO_IDX;
+
+#define _mbg_swab_syslog_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab_syslog_info( &(_p)->info ); \
+ _mbg_swab32( &(_p)->idx ); \
} while ( 0 )
+
/** @} defgroup group_monitoring */
/**
- * @defgroup group_usb_lock USB locks
+ * @defgroup group_tainted_cfg Tainted config
*
* @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.
+ * if ::MBG_XFEATURE_TAINTED_CFG is set in the extended device features.
+ * Feature has a list of configuration counters for several sub-features.
+ * Each time a sub-feature's config changes, its counter in this structure
+ * is increased to indicate a config change. Thus, software can read this
+ * structure and request the changed config. Also use it for push notifications.
*
* TODO: Add proper Doxygen documentation
*
* @{ */
-enum MBG_USB_LOCK_FLAGS
+#define MBG_TAINTED_CFG_BYTES 256
+#define MBG_TAINTED_CFG_FLAG_BYTES (MBG_TAINTED_CFG_BYTES >> 3)
+
+/**
+ * @brief Array positions in ::MBG_TAINTED_CFG::tainted_cfgs
+ *
+ */
+enum MBG_TAINTED_CFGS
{
- MBG_USB_LOCK_FLAG_ACTIVE, ///< USB connection is interrupted
- N_MBG_USB_LOCK_FLAGS
+ MBG_TAINTED_CFG_INV = -1,
+ MBG_TAINTED_CFG_SNMP,
+ MBG_TAINTED_CFG_EMAIL,
+ MBG_TAINTED_CFG_SYSLOG,
+ MBG_TAINTED_CFG_EVENTS,
+ MBG_TAINTED_CFG_IOPORTS,
+ MBG_TAINTED_CFG_NTP,
+ MBG_TAINTED_CFG_XBP,
+ MBG_TAINTED_CFG_NETWORK,
+ MBG_TAINTED_CFG_USERS,
+ MBG_TAINTED_CFG_FIRMWARE,
+ MBG_TAINTED_CFG_XMR,
+ MBG_TAINTED_CFG_TIMECODE_RX,
+ MBG_TAINTED_CFG_TIMECODE_TX,
+ MBG_TAINTED_CFG_HAVEQUICK,
+ MBG_TAINTED_CFG_GPIO,
+ MBG_TAINTED_CFG_UART,
+ MBG_TAINTED_CFG_PROG_OUT,
+ MBG_TAINTED_CFG_VAR_SYNTH,
+ MBG_TAINTED_CFG_TIMESCALE,
+ MBG_TAINTED_CFG_IGNLOCK,
+ MBG_TAINTED_CFG_GNSSMODE,
+ MBG_TAINTED_CFG_EF,
+ MBG_TAINTED_CFG_TZDL,
+ MBG_TAINTED_CFG_CABLE_LENGTH,
+ MBG_TAINTED_CFG_DATABASE,
+ N_MBG_TAINTED_CFGS
};
+typedef struct
+{
+ uint8_t tainted_cfgs[MBG_TAINTED_CFG_BYTES]; ///< See ::MBG_TAINTED_CFGS
+ uint8_t supp_cfgs[MBG_TAINTED_CFG_FLAG_BYTES]; ///< See ::MBG_TAINTED_CFGS
+ uint32_t reserved[4]; ///< Future use
+
+} MBG_TAINTED_CFG;
+
+#define _mbg_swab_tainted_cfg( _p ) do {} while ( 0 )
+
+#define _mbg_tainted_cfg_increase(c, cfg) \
+do \
+{ \
+ if ( ( c >= MBG_TAINTED_CFG_BYTES ) || ( c >= N_MBG_TAINTED_CFGS ) ) \
+ break; \
+ \
+ ++(cfg)->tainted_cfgs[ c ]; \
+ \
+} while ( 0 );
+
+/**
+ * @brief Set a supported tainted config bit in a ::MBG_TAINTED_CFG::supp_cfgs
+ *
+ * Should be used by the firmware only to set one of the supported ::N_MBG_TAINTED_CFGS
+ * bits in :MBG_TAINTED_CFG::supp_cfgs.
+ *
+ * @param[in] _cfg_bit One of the ::MBG_TAINTED_CFGS
+ * @param[in] _tainted_cfg Pointer to ::MBG_TAINTED_CFG
+ */
+#define _set_supp_tainted_cfg_bit( _cfg_bit, _tainted_cfg ) \
+ _set_array_bit( _cfg_bit, (_tainted_cfg)->supp_cfgs, MBG_TAINTED_CFG_FLAG_BYTES )
+
+/**
+ * @brief Clear a supported tainted config bit in a ::MBG_TAINTED_CFG::supp_cfgs
+ *
+ * Should be used by the firmware only to clear one of the supported ::N_MBG_TAINTED_CFGS
+ * bits in :MBG_TAINTED_CFG::supp_cfgs.
+ *
+ * @param[in] _cfg_bit One of the ::MBG_TAINTED_CFGS
+ * @param[in] _tainted_cfg Pointer to ::MBG_TAINTED_CFG
+ */
+#define _clear_supp_tainted_cfg_bit( _cfg_bit, _tainted_cfg ) \
+ _clear_array_bit( _cfg_bit, (_tainted_cfg)->supp_cfgs, MBG_TAINTED_CFG_FLAG_BYTES )
-enum MBG_USB_LOCK_FLAG_MSKS
+/**
+ * @brief Check for a supported tainted config bit in a ::MBG_TAINTED_CFG::supp_cfgs
+ *
+ * @param[in] _cfg_bit One of the ::MBG_TAINTED_CFGS
+ * @param[in] _tainted_cfg Pointer to ::MBG_TAINTED_CFG
+ */
+#define _check_supp_tainted_cfg_bit( _cfg_bit, _tainted_cfg ) \
+ check_feat_supp_byte_array( _cfg_bit, (_tainted_cfg)->supp_cfgs, MBG_TAINTED_CFG_FLAG_BYTES )
+
+/** @} defgroup group_tainted_cfg */
+
+
+/**
+ * @defgroup group_user_mngmnt User Management
+ *
+ * @note These structures and definitions provide an extended user management
+ * for Meinberg devices based on the Linux user management and the files
+ * /etc/passwd and /etc/shadow. They are only supported by a device,
+ * if ::MBG_XFEATURE_USER_MNGMNT is set in the extended device features.
+ *
+ * @{ */
+
+typedef enum
+{
+ USER_PERM_SYSTEM, ///< permission to read/write system related structures
+ ///< ::GPS_SCU_STAT
+ ///< ::GPS_TIME_SCALE
+ ///< ::GPS_TZDL
+ ///< ::PZF_TZCODE
+ ///< ::GPS_REBOOT
+ ///< ::MBG_TLV_FEAT_TYPE_DIAG_FILE
+ ///< ::GPS_TAINTED_CFG
+ ///< ::GPS_XBP_LIMITS
+ ///< ::GPS_XBP_NODE_LIMITS
+ ///< ::GPS_XBP_NODE_INFO_IDX
+ USER_PERM_RECEIVER, ///< permission to read/write receiver related structures
+ ///< ::GPS_TIME
+ ///< ::GPS_ANT_CABLE_LENGTH
+ ///< ::GPS_GNSS_MODE
+ ///< ::GPS_IGNORE_LOCK
+ ///< ::GPS_SAVE_CFG
+ ///< ::GPS_POS_XYZ
+ ///< ::GPS_POS_LLA
+ ///< ::GPS_STAT_INFO
+ ///< ::GPS_SV_INFO
+ ///< ::GPS_GNSS_SAT_INFO_IDX
+ ///< ::GPS_GNSS_SV_STATUS_IDX
+ ///< ::GPS_CLR_EVT_LOG
+ ///< ::GPS_NUM_EVT_LOG_ENTRIES
+ ///< ::GPS_FIRST_EVT_LOG_ENTRY
+ ///< ::GPS_NEXT_EVT_LOG_ENTRY
+ USER_PERM_MRS, ///< permission to read/write MRS related structures
+ ///< ::GPS_XMR_INSTANCES
+ ///< ::GPS_XMR_INFO_IDX
+ ///< ::GPS_XMR_EXT_SRC_INFO_IDX
+ ///< ::GPS_XMR_STATUS_IDX
+ ///< ::GPS_XMR_HOLDOVER_STATUS
+ ///< ::GPS_XMR_STATS_IDX
+ ///< ::GPS_XMR_METRICS_IDX
+ USER_PERM_SERIAL, ///< permission to read/write serial port related structures
+ ///< ::GPS_PORT_INFO_IDX
+ ///< ::GPS_STR_TYPE_INFO_IDX
+ USER_PERM_IOPORTS, ///< permission to read/write IO port related structures
+ ///< ::GPS_IRIG_RX_INFO
+ ///< ::GPS_RAW_IRIG_DATA
+ ///< ::GPS_REF_OFFS
+ ///< ::GPS_IRIG_RX_SETTINGS
+ ///< ::GPS_IRIG_TX_INFO
+ ///< ::GPS_SYNTH
+ ///< ::GPS_ENABLE_FLAGS
+ ///< ::GPS_IRIG_TX_SETTINGS
+ ///< ::GPS_POUT_INFO_IDX
+ ///< ::GPS_POUT_SETTINGS_IDX
+ ///< ::GPS_GPIO_CFG_LIMITS
+ ///< ::GPS_GPIO_INFO_IDX
+ ///< ::GPS_GPIO_SETTINGS_IDX
+ ///< ::GPS_GPIO_STATUS_IDX
+ ///< ::GPS_IO_PORT_LIMITS
+ ///< ::GPS_IO_PORT_INFO_IDX
+ ///< ::GPS_IO_PORT_TYPE_INFO_IDX
+ ///< ::GPS_IO_PORT_SETTINGS_IDX
+ ///< ::GPS_IO_PORT_STATUS_IDX
+ ///< ::GPS_UCAP_NET_GLB_INFO
+ ///< ::GPS_UCAP_NET_RECV_INFO_IDX
+ ///< ::GPS_CLR_UCAP_BUFF
+ ///< ::GPS_UCAP
+ USER_PERM_MONITORING, ///< permission to read/write monitoring related structures
+ ///< ::GPS_MONITORING_LIMITS
+ ///< ::GPS_SNMP_GLB
+ ///< ::GPS_SNMP_V12_IDX
+ ///< ::GPS_SNMP_V12_TRAP_IDX
+ ///< ::GPS_SNMP_V3_IDX
+ ///< ::GPS_SNMP_V3_TRAP_IDX
+ ///< ::GPS_EVENT_IDX
+ ///< ::GPS_EVENT_STAT_IDX
+ ///< ::GPS_EVENT_VALUE_IDX
+ ///< ::GPS_NUM_EVT_LOG_ENTRIES
+ ///< ::GPS_FIRST_EVT_LOG_ENTRY
+ ///< ::GPS_NEXT_EVT_LOG_ENTRY
+ ///< ::GPS_CLR_EVT_LOG
+ ///< ::GPS_SYSLOG_GLB_INFO
+ ///< ::GPS_SYSLOG_INFO_IDX
+ USER_PERM_NETWORK, ///< permission to read/write network related structures
+ ///< ::GPS_NET_GLB_CFG
+ ///< ::GPS_NET_STAT_GLB_CFG
+ ///< ::GPS_NET_INTF_LINK_IDX
+ ///< ::GPS_NET_STAT_INTF_LINK_IDX
+ ///< ::GPS_NET_INTF_ADDR_IDX
+ ///< ::GPS_NET_STAT_INTF_ADDR_IDX
+ ///< ::GPS_NET_INTF_ROUTE_IDX
+ ///< ::GPS_NET_STAT_INTF_ROUTE_IDX
+ ///< ::GPS_NET_DNS_SRVR
+ ///< ::GPS_NET_STAT_DNS_SRVR
+ ///< ::GPS_NET_DNS_SRCH_DOM
+ ///< ::GPS_NET_STAT_DNS_SRCH_DOM
+ ///< ::GPS_LAN_IF_INFO
+ ///< ::GPS_IP4_SETTINGS
+ ///< ::GPS_IP4_STATE
+ USER_PERM_NTP, ///< permission to read/write NTP related structures
+ ///< ::GPS_NTP_GLB_CFG
+ ///< ::GPS_NTP_SYS_STATE
+ ///< ::GPS_NTP_SYMM_KEY_LIMITS
+ ///< ::GPS_NTP_SYMM_KEY_CFG
+ ///< ::GPS_NTP_TRUSTED_KEY_CFG
+ ///< ::GPS_NTP_CLNT_MODE_CFG
+ ///< ::GPS_NTP_PEER_SETTINGS_IDX
+ ///< ::GPS_NTP_PEER_STATE_IDX
+ ///< ::GPS_NTP_SRV_MODE_CFG
+ ///< ::GPS_NTP_REFCLK_CFG
+ ///< ::GPS_NTP_REFCLK_STATE_IDX
+ ///< ::GPS_NTP_MISC_LIMITS
+ ///< ::GPS_NTP_MISC_ORPHAN_MODE
+ USER_PERM_PTP, ///< permission to read/write PTP related structures
+ ///< ::GPS_PTP_CFG
+ ///< ::GPS_PTP_STATE
+ ///< ::GPS_PTP_UC_MASTER_CFG_LIMITS
+ ///< ::GPS_PTP_UC_MASTER_CFG
+ ///< ::GPS_PTP_V2_DEFAULT_DS
+ ///< ::GPS_PTP_V2_CURRENT_DS
+ ///< ::GPS_PTP_V2_PARENT_DS
+ ///< ::GPS_PTP_V2_TIME_PROP_DS
+ ///< ::GPS_PTP_V2_PORT_DS_IDX
+ ///< ::GPS_PTP_V1_DEFAULT_DS
+ ///< ::GPS_PTP_V1_CURRENT_DS
+ ///< ::GPS_PTP_V1_PARENT_DS
+ ///< ::GPS_PTP_V1_TIME_PROP_DS
+ ///< ::GPS_PTP_V1_PORT_DS_IDX
+ USER_PERM_FDM, ///< permission to read/write FDM related structures
+ ///< ::GPS_FDM_LIMITS
+ ///< ::GPS_FDM_INFO
+ ///< ::GPS_FDM_STATE
+ ///< ::GPS_FDM_SETTINGS
+ ///< ::GPS_FDM_OUTPUT_INFO_IDX
+ ///< ::GPS_FDM_OUTPUT_SETTINGS_IDX
+ ///< ::GPS_FDM_OUTPUT_STATE_IDX
+ ///< ::GPS_FDM_SET_TD
+ USER_PERM_SENSORS, ///< permission to read sensors related structures
+ ///< ::GPS_IMS_STATE
+ ///< ::GPS_IMS_SENSOR_STATE_IDX
+ USER_PERM_PASSWORD, ///< permission to read/change the user password
+ USER_PERM_USERS, ///< permission to read/write user related structures
+ ///< ::GPS_USER_MNGMNT_INFO
+ ///< ::GPS_USER_INFO_IDX
+ ///< ::GPS_USER_LEVEL_INFO_IDX
+ ///< ::GPS_USER_STATUS_IDX
+ USER_PERM_FIRMWARE, ///< permission to read/write firmware of a device
+ ///< ::GPS_FW_GLB_INFO
+ ///< ::GPS_FW_INFO_IDX
+ ///< ::GPS_FW_UFU_INFO_IDX
+ ///< ::GPS_FW_ACTIVATE
+ ///< ::GPS_FW_DELETE
+ ///< ::GPS_FW_UFU_FLASH
+ ///< ::MBG_TLV_FEAT_TYPE_FW_UPDATE
+ ///< ::MBG_TLV_FEAT_TYPE_UFU
+ ///< ::MBG_TLV_FEAT_TYPE_FW_ROLLBACK
+ USER_PERM_SERVICE, ///< permission to read/write service related structures
+ ///< ::GPS_SRV_MGMT_INFO
+ ///< ::GPS_SRV_INFO_IDX
+ ///< ::GPS_SRV_STATUS_IDX
+ ///< ::GPS_SRV_CTL_IDX
+ USER_PERM_DATABASE, ///< permission to read/write database related structures
+ ///< ::GPS_DATABASE_GLB_INFO
+ ///< ::GPS_DATABASE_INFO_IDX
+ N_USER_PERMS
+
+} MBG_USER_PERMS;
+
+
+/**
+ * @brief Strings for defined user permissions
+ *
+ * @see ::MBG_USER_PERMS
+ */
+#define MBG_USER_PERM_STRS \
+{ \
+ "System", \
+ "Receiver", \
+ "Ref. Sources", \
+ "Serial Ports", \
+ "IO Ports", \
+ "Monitoring", \
+ "Network", \
+ "NTP", \
+ "PTP", \
+ "FDM", \
+ "Sensors", \
+ "Password", \
+ "Users", \
+ "Firmware", \
+ "Services", \
+ "Database" \
+}
+
+
+typedef enum
{
- MBG_USB_LOCK_FLAG_MSK_ACTIVE = (1UL << MBG_USB_LOCK_FLAG_ACTIVE) ///< See ::MBG_USB_LOCK_FLAG_ACTIVE
-};
+ USER_SCOPE_STATUS_READ,
+ USER_SCOPE_CONFIG_READ,
+ USER_SCOPE_CONFIG_WRITE,
+ N_USER_SCOPES
+
+} MBG_USER_SCOPES;
+
+
+typedef enum
+{
+ USER_SCOPE_STATUS_READ_MSK = ( 1UL << USER_SCOPE_STATUS_READ ), ///< see ::USER_SCOPE_STATUS_READ
+ USER_SCOPE_CONFIG_READ_MSK = ( 1UL << USER_SCOPE_CONFIG_READ ), ///< see ::USER_SCOPE_CONFIG_READ
+ USER_SCOPE_CONFIG_WRITE_MSK = ( 1UL << USER_SCOPE_CONFIG_WRITE ) ///< see ::USER_SCOPE_CONFIG_WRITE
+
+} MBG_USER_SCOPE_MSKS;
+
+
+#define MAX_USER_PERM_BYTES 64
+#define MAX_USER_PERM_BITS MAX_USER_PERM_BYTES * 8
+
+
+typedef enum
+{
+ USER_CHANNEL_WEB_INTERFACE,
+ USER_CHANNEL_MBGDEVMAN,
+ USER_CHANNEL_SHELL,
+ USER_CHANNEL_SNMP,
+ USER_CHANNEL_NETCONF,
+ N_USER_CHANNELS
+
+} MBG_USER_CHANNELS;
+
+#define MAX_USER_CHANNEL_BYTES 16
+#define MAX_USER_CHANNEL_BITS MAX_USER_CHANNEL_BYTES * 8
+
+/**
+ * @brief Strings for defined user channels
+ *
+ * @see ::MBG_USER_CHANNELS
+ */
+#define MBG_USER_CHANNEL_STRS \
+{ \
+ "Web Interface", \
+ "Device Manager", \
+ "Shell", \
+ "SNMP", \
+ "Netconf" \
+}
+
+
+/**
+ * @brief A structure used to store user permissions.
+ *
+ * Up to ::MAX_USER_PERM_BITS totally can be stored.
+ * There should be one ::MBG_USER_PERM_BUF for status permissions,
+ * read configuration and write configuration permissions, each.
+ *
+ * @see ::MBG_USER_PERMS
+ * @see ::_set_user_perm
+ * @see ::_check_user_perm
+ */
typedef struct
{
- uint8_t flags; ///< ::MBG_USB_LOCK_FLAG_MSKS
+ uint8_t b[MAX_USER_PERM_BYTES]; ///< buffer for user permissions, see ::_set_user_perm and ::_check_user_perm
+
+} MBG_USER_PERM_BUF;
+
+
+/**
+ * @brief Set a user permission in a ::MBG_USER_PERM_BUF
+ *
+ * @param[in] _user_perm_bit One of ::MBG_USER_PERMS
+ * @param[in] _user_perm_buffp Pointer to an ::MBG_USER_PERM_BUF
+ */
+#define _set_user_perm( _user_perm_bit, _user_perm_buffp ) \
+ _set_array_bit( _user_perm_bit, (_user_perm_buffp)->b, MAX_USER_PERM_BYTES )
+
+
+/**
+ * @brief Unset a user permission in a ::MBG_USER_PERM_BUF
+ *
+ * @param[in] _user_perm_bit One of ::MBG_USER_PERMS
+ * @param[in] _user_perm_buffp Pointer to an ::MBG_USER_PERM_BUF
+ */
+#define _clear_user_perm( _user_perm_bit, _user_perm_buffp ) \
+ _clear_array_bit( _user_perm_bit, (_user_perm_buffp)->b, MAX_USER_PERM_BYTES )
+
+
+/**
+ * @brief Check a user permission in a ::MBG_USER_PERM_BUF
+ *
+ * @param[in] _user_perm_bit One of ::MBG_USER_PERMS
+ * @param[in] _user_perm_buffp Pointer to an ::MBG_USER_PERM_BUF
+ */
+#define _check_user_perm( _user_perm_bit, _user_perm_buffp ) \
+ check_feat_supp_byte_array( _user_perm_bit, (_user_perm_buffp)->b, MAX_USER_PERM_BYTES )
+
+
+/**
+ * @brief A structure used to store user channels.
+ *
+ * Up to ::MAX_USER_CHANNEL_BITS totally can be stored.
+ *
+ * @see ::MBG_USER_CHANNELS
+ * @see ::_set_user_channel
+ * @see ::_check_user_channel
+ */
+typedef struct
+{
+ uint8_t b[MAX_USER_CHANNEL_BYTES]; ///< buffer for user channels, see ::_set_user_channel and ::_check_user_channel
+
+} MBG_USER_CHANNEL_BUF;
+
+
+/**
+ * @brief Set a user channel in a ::MBG_USER_CHANNEL_BUF
+ *
+ * @param[in] _user_channel_bit One of ::MBG_USER_CHANNELS
+ * @param[in] _user_channel_buffp Pointer to an ::MBG_USER_CHANNEL_BUF
+ */
+#define _set_user_channel( _user_channel_bit, _user_channel_buffp ) \
+ _set_array_bit( _user_channel_bit, (_user_channel_buffp)->b, MAX_USER_CHANNEL_BYTES )
+
+
+/**
+ * @brief Unset a user channel in a ::MBG_USER_CHANNEL_BUF
+ *
+ * @param[in] _user_channel_bit One of ::MBG_USER_CHANNELS
+ * @param[in] _user_channel_buffp Pointer to an ::MBG_USER_CHANNEL_BUF
+ */
+#define _clear_user_channel( _user_channel_bit, _user_channel_buffp ) \
+ _clear_array_bit( _user_channel_bit, (_user_channel_buffp)->b, MAX_USER_CHANNEL_BYTES )
+
+
+/**
+ * @brief Check a user channel in a ::MBG_USER_CHANNEL_BUF
+ *
+ * @param[in] _user_channel_bit One of ::MBG_USER_CHANNELS
+ * @param[in] _user_channel_buffp Pointer to an ::MBG_USER_CHANNEL_BUF
+ */
+#define _check_user_channel( _user_channel_bit, _user_channel_buffp ) \
+ check_feat_supp_byte_array( _user_channel_bit, (_user_channel_buffp)->b, MAX_USER_CHANNEL_BYTES )
+
+
+typedef enum
+{
+ USER_MNGMNT_SUPP_USER_CFG, ///< device supports user configuration, otherwise users are static
+ USER_MNGMNT_SUPP_USER_LEVEL_CFG, ///< device supports user level configuration, otherwise user levels are static
+ N_USER_MNGMNT_FLAGS
+
+} MBG_USER_MNGMNT_FLAGS;
+
+
+typedef enum
+{
+ USER_MNGMNT_SUPP_USER_CFG_MASK = ( 1UL << USER_MNGMNT_SUPP_USER_CFG ), ///< see ::USER_MNGMNT_SUPP_USER_CFG
+ USER_MNGMNT_SUPP_USER_LEVEL_CFG_MASK = ( 1UL << USER_MNGMNT_SUPP_USER_LEVEL_CFG ) ///< see ::USER_MNGMNT_SUPP_USER_LEVEL_CFG
+
+} MBG_USER_MNGMNT_FLAG_MASKS;
+
+
+typedef struct
+{
+ uint32_t num_users; ///< current number of users
+ uint32_t num_levels; ///< current number of users
+ uint32_t reserved_1[2]; ///< reserved, currently always 0
+
+ uint32_t flags; ///< flags, see ::MBG_USER_MNGMNT_FLAG_MASKS
+
+ uint32_t reserved_2[16]; ///< reserved, currently always 0
+
+} MBG_USER_MNGMNT_SETTINGS;
+
+
+#define _mbg_swab_user_mngmnt_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->num_users ); \
+ _mbg_swab32( &(_p)->num_levels ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ MBG_USER_MNGMNT_SETTINGS settings; ///< settings, see ::MBG_USER_MNGMNT_SETTINGS
+
+ uint32_t n_supp_users; ///< supported number of users
+ uint32_t n_supp_levels; ///< supported number of user levels
+
+ MBG_USER_CHANNEL_BUF supp_user_channels; ///< supported channels for internal users
+ MBG_USER_CHANNEL_BUF supp_lvl_channels; ///< supported channels for external users
+ MBG_USER_PERM_BUF supp_perms; ///< supported user permissions
+
+ uint32_t supp_flags; ///< supported flags, see ::MBG_USER_MNGMNT_FLAG_MASKS
+
+ uint32_t reserved[16]; ///< reserved, currently always 0
+
+} MBG_USER_MNGMNT_INFO;
+
+
+#define _mbg_swab_user_mngmnt_info( _p ) \
+do \
+{ \
+ _mbg_swab_user_mngmnt_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->n_supp_users ); \
+ _mbg_swab32( &(_p)->n_supp_levels ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+typedef enum
+{
+ USER_TYPE_USER, ///< standard system user
+ USER_TYPE_LEVEL, ///< user level for external authentication and as template for new users
+ N_USER_TYPES
+
+} MBG_USER_TYPE;
+
+
+typedef enum
+{
+ USER_CFG_CAN_LOGIN, ///< the user is allowed to login (should not be set for root)
+ USER_CFG_CAN_REMOVE, ///< the user can be removed (should not be set for root)
+ USER_CFG_CAN_DISABLE_ON_FAILS, ///< the user supports the disabling after a number of login fails, see ::MBG_USER_SETTINGS::max_fails
+ USER_CFG_MULTI_SESSION, ///< allow user to login more than once (i.e. via TCP & Web)
+ USER_CFG_FORCE_CHANGE_ON_WARN, ///< user shall be forced to change the password on password warning
+ USER_CFG_FORCE_DISABLE_ON_EXP, ///< user account will immediately be disabled on password expiration, if this flags is not set,
+ ///< the user shall be forced to change the password on the next login attempt
+ USER_CFG_PASSWORD_CHANGED, ///< Indicates, that the password has been changed and needs to be crypted
+ N_USER_CFG_FLAGS
+
+} MBG_USER_CFG_FLAGS;
+
+
+typedef enum
+{
+ USER_CFG_CAN_LOGIN_MASK = ( 1UL << USER_CFG_CAN_LOGIN ), ///< see ::USER_CFG_CAN_LOGIN
+ USER_CFG_CAN_REMOVE_MASK = ( 1UL << USER_CFG_CAN_REMOVE ), ///< see ::USER_CFG_CAN_REMOVE
+ USER_CFG_CAN_DISABLE_ON_FAILS_MASK = ( 1UL << USER_CFG_CAN_DISABLE_ON_FAILS ), ///< see ::USER_CFG_CAN_DISABLE_ON_FAILS
+ USER_CFG_MULTI_SESSION_MASK = ( 1UL << USER_CFG_MULTI_SESSION ), ///< see ::USER_CFG_MULTI_SESSION
+ USER_CFG_FORCE_CHANGE_ON_WARN_MASK = ( 1UL << USER_CFG_FORCE_CHANGE_ON_WARN ), ///< see ::USER_CFG_FORCE_CHANGE_ON_WARN
+ USER_CFG_FORCE_DISABLE_ON_EXP_MASK = ( 1UL << USER_CFG_FORCE_DISABLE_ON_EXP ), ///< see ::USER_CFG_FORCE_DISABLE_ON_EXP
+ USER_CFG_PASSWORD_CHANGED_MASK = ( 1UL << USER_CFG_PASSWORD_CHANGED ) ///< see ::USER_CFG_PASSWORD_CHANGED
+
+} MBG_USER_CFG_FLAG_MASKS;
+
+
+#define MBG_MAX_USER_NAME_LEN 32 /// See manpage useradd
+#define MBG_MAX_USER_PASSWORD_LEN 32
+
+
+typedef struct
+{
+ char name[MBG_MAX_USER_NAME_LEN]; ///< user name
+ char password[MBG_MAX_USER_PASSWORD_LEN]; ///< user password, should only be set if it shall be changed
+
+ uint32_t level_id; ///< unique id for user level, only used if ::MBG_USER_INFO::type is ::USER_TYPE_LEVEL
+
+ uint32_t warn_days; ///< number of days, after which the user shall be warned about an upcoming password expiration,
+ uint32_t exp_days; ///< number of days, after which the password becomes invalid, see ::MBG_USER_INFO::password_doc,
+ uint32_t max_fails; ///< maximum number of login fails, before the user is disabled,
+ ///< only supported if ::USER_CFG_CAN_DISABLE_ON_FAILS_MASK
+ ///< all above values shall only be used, if they are not 0
+ uint32_t flags; ///< flags, see ::MBG_USER_CFG_FLAG_MASKS
+
+ MBG_USER_CHANNEL_BUF channels; ///< Channels, that are allowed for this user, see ::MBG_USER_CHANNEL_BUF
+
+ MBG_USER_PERM_BUF stat_read_perm; ///< status read permission configuration, see ::MBG_USER_PERM_BUF and ::MBG_USER_PERMS
+ MBG_USER_PERM_BUF cfg_read_perm; ///< config read permission configuration, see ::MBG_USER_PERM_BUF and ::MBG_USER_PERMS
+ MBG_USER_PERM_BUF cfg_write_perm; ///< config write permission configuration, see ::MBG_USER_PERM_BUF and ::MBG_USER_PERMS
+
+ uint32_t reserved[16]; ///< reserved, currently always 0
+
+} MBG_USER_SETTINGS;
+
+
+#define _mbg_swab_user_settings( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->warn_days ); \
+ _mbg_swab32( &(_p)->exp_days ); \
+ _mbg_swab32( &(_p)->max_fails ); \
+ _mbg_swab32( &(_p)->flags ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx; ///< the index of the user
+ MBG_USER_SETTINGS settings; ///< settings, see ::MBG_USER_SETTINGS
+
+} MBG_USER_SETTINGS_IDX;
+
+
+#define _mbg_swab_user_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_user_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ MBG_USER_SETTINGS settings;
+
+ uint8_t type; ///< type, see ::MBG_USER_TYPE
+ uint8_t reserved_1; ///< reserved, currently always 0
+ uint16_t reserved_2; ///< reserved, currently always 0
+
+ uint32_t uid; ///< user id assigned by the OS
+ uint32_t gid; ///< group id
+
+ uint32_t password_doc; ///< time of last password change (days since 1970)
+
+ uint32_t supp_flags; ///< supported flags, see ::MBG_USER_CFG_FLAG_MASKS
+ uint32_t reserved_3[16]; ///< reserved, currently always 0
+
+} MBG_USER_INFO;
+
+
+#define _mbg_swab_user_info( _p ) \
+do \
+{ \
+ _mbg_swab_user_settings( &(_p)->settings ); \
+ _mbg_swab32( &(_p)->uid ); \
+ _mbg_swab32( &(_p)->gid ); \
+ _mbg_swab32( &(_p)->password_doc ); \
+ _mbg_swab32( &(_p)->supp_flags ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx; ///< the index of the user
+ MBG_USER_INFO info; ///< info, see ::MBG_USER_INFO
+
+} MBG_USER_INFO_IDX;
+
+
+#define _mbg_swab_user_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_user_info( &(_p)->info ); \
+} while ( 0 )
+
+
+typedef enum
+{
+ USER_STAT_PASSWORD_WARN, ///< the user shall be warned about upcoming password expiration
+ USER_STAT_PASSWORD_EXP, ///< the user password has expired
+ USER_STAT_DISABLED_ON_EXP, ///< the user is disabled, because the password has expired
+ USER_STAT_DISABLED_ON_MAX_FAILS, ///< the user is disabled, because the max number of login fails has been exceeded
+ N_USER_STAT_FLAGS
+
+} MBG_USER_STAT_FLAGS;
+
+
+typedef enum
+{
+ USER_STAT_PASSWORD_WARN_MASK = ( 1UL << USER_STAT_PASSWORD_WARN ), ///< see ::USER_STAT_PASSWORD_WARN
+ USER_STAT_PASSWORD_EXP_MASK = ( 1UL << USER_STAT_PASSWORD_EXP ), ///< see ::USER_STAT_PASSWORD_EXP
+ USER_STAT_DISABLED_ON_EXP_MASK = ( 1UL << USER_STAT_DISABLED_ON_EXP ), ///< see ::USER_STAT_DISABLED_ON_EXP
+ USER_STAT_DISABLED_ON_MAX_FAILS_MASK = ( 1UL << USER_STAT_DISABLED_ON_MAX_FAILS ) ///< see ::USER_STAT_DISABLED_ON_MAX_FAILS
+
+} MBG_USER_STAT_FLAG_MASKS;
+
+
+typedef struct
+{
+ uint32_t flags; ///< flags, see ::MBG_USER_STAT_FLAG_MASKS
+ uint32_t login_cnt; ///< current number of active logins
+ uint32_t num_fails; ///< current number of unsuccessful login attempts
+
+ MBG_USER_PERM_BUF stat_read_perm; ///< current status read permissions, see ::MBG_USER_PERM_BUF and ::MBG_USER_PERMS
+ MBG_USER_PERM_BUF cfg_read_perm; ///< current config read permissions, see ::MBG_USER_PERM_BUF and ::MBG_USER_PERMS
+ MBG_USER_PERM_BUF cfg_write_perm; ///< current config write permissions, see ::MBG_USER_PERM_BUF and ::MBG_USER_PERMS
+
+ uint32_t reserved[16]; ///< reserved, currently always 0
+
+} MBG_USER_STATUS;
+
+
+#define _mbg_swab_user_status( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab32( &(_p)->login_cnt ); \
+ _mbg_swab32( &(_p)->num_fails ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx; ///< the index of the user
+ MBG_USER_STATUS status; ///< status, see ::MBG_USER_STATUS
+
+} MBG_USER_STATUS_IDX;
+
+
+#define _mbg_swab_user_status_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_user_status( &(_p)->status ); \
+} while ( 0 )
+
+
+/** @} defgroup group_user_mngmnt */
+
+
+
+/**
+ * @defgroup group_service_mngmnt Service Management
+ *
+ * @note These structures and definitions provide extended service management
+ * for Meinberg devices based on Linux / Windows.
+ * if ::MBG_XFEATURE_SERVICE is set in the extended device features.
+ *
+ * @{ */
+
+
+typedef enum
+{
+ MBG_SVC_TYPE_NTP, // Device supports NTP service (ntpd, or OpenNTP, etc ...)
+ MBG_SVC_TYPE_SNMP, // Device supports SNMP service (net-snmp, etc...)
+ N_MBG_SVC_TYPES
+
+} MBG_SERVICE_TYPES;
+
+
+#define MBG_SERVICE_TYPE_STRS \
+{ \
+ "NTP", \
+ "SNMP" \
+}
+
+
+typedef enum
+{
+ MBG_SVC_NTP_MSK = ( 1UL << MBG_SVC_TYPE_NTP ), ///< See ::MBG_SVC_TYPE_NTP
+ MBG_SVC_SNMP_MSK = ( 1UL << MBG_SVC_TYPE_SNMP ) ///< See ::MBG_SVC_TYPE_SNMP
+
+} MBG_SERVICE_MSKS;
+
+
+typedef struct
+{
+ uint8_t num_services; ///< Current number of supported services
uint8_t reserved_1[3];
uint32_t reserved_2[3];
-} MBG_USB_LOCK_SETTINGS;
+} MBG_SERVICE_MGMT_INFO;
+
+
+#define _mbg_swab_svc_mgmt_info( _p ) do {} while ( 0 )
+
+
+#define MBG_SVC_NAME_LEN 32
+#define MBG_SVC_CMD_LEN 192
+
+
+typedef enum
+{
+ MBG_SVC_UNKNOWN,
+ MBG_SVC_RUNNING,
+ MBG_SVC_STOPPED,
+ N_MBG_SVC_STATES
+
+} MBG_SERVICE_STATE;
+
+
+#define MBG_SERVICE_STATE_STRS \
+{ \
+ "Unknown", \
+ "Running", \
+ "Stopped" \
+}
+
+
+typedef enum
+{
+ MBG_SVC_START,
+ MBG_SVC_STOP,
+ MBG_SVC_RESTART,
+ N_MBG_SVC_CTLS
-#define _mbg_swab_usb_lock_settings( _p ) do {} while ( 0 )
+} MBG_SERVICE_CTL;
typedef struct
{
- MBG_USB_LOCK_SETTINGS settings;
- uint8_t supp_flags; ///< ::MBG_USB_LOCK_FLAG_MSKS
+ char cmdline[MBG_SVC_CMD_LEN];
+ uint8_t enabled;
uint8_t reserved_1[3];
uint32_t reserved_2[3];
-} MBG_USB_LOCK_INFO;
+} MBG_SERVICE_SETTINGS;
+
+
+#define _mbg_swab_svc_settings( _p ) do {} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SERVICE_SETTINGS settings;
+
+} MBG_SERVICE_SETTINGS_IDX;
+
+
+#define _mbg_swab_svc_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_svc_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+typedef enum
+{
+ MBG_SVC_CAN_BE_DISABLED,
+ MBG_SVC_CAN_EDIT_CMDLINE,
+ N_MBG_SVC_FLAGS
+
+} MBG_SERVICE_INFO_FLAGS;
+
+
+typedef enum
+{
+ MBG_SVC_MSK_CAN_BE_DISABLED = ( 1UL << MBG_SVC_CAN_BE_DISABLED ), ///< See ::MBG_SVC_CAN_BE_DISABLED
+ MBG_SVC_MSK_CAN_EDIT_CMDLINE = ( 1UL << MBG_SVC_CAN_EDIT_CMDLINE ) ///< See ::MBG_SVC_CAN_EDIT_CMDLINE
+
+} MBG_SERVICE_INFO_MSKS;
+
+
+typedef struct
+{
+ MBG_SERVICE_SETTINGS settings;
+ uint8_t type;
+ uint8_t flags; ///< See ::MBG_SERVICE_INFO_MSKS
+ uint8_t reserved_1[2];
+ char name[MBG_SVC_NAME_LEN];
+ uint32_t reserved_2[5];
+
+} MBG_SERVICE_INFO;
+
+
+#define _mbg_swab_svc_info( _p ) \
+do \
+{ \
+ _mbg_swab_svc_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SERVICE_INFO info;
+
+} MBG_SERVICE_INFO_IDX;
+
+
+#define _mbg_swab_svc_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_svc_info( &(_p)->info ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint8_t state; ///< See ::MBG_SERVICE_STATE
+ uint8_t reserved_1[3];
+ uint32_t reserved_2[3];
+
+} MBG_SERVICE_STATUS;
+
+
+#define _mbg_swab_svc_status( _p ) do {} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_SERVICE_STATUS status;
+
+} MBG_SERVICE_STATUS_IDX;
+
-#define _mbg_swab_usb_lock_info( _p ) \
+#define _mbg_swab_svc_status_idx( _p ) \
do \
{ \
- _mbg_swab_usb_lock_settings( _p ); \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_svc_status( &(_p)->status ); \
} while ( 0 )
+/** @} defgroup group_service_mngmnt */
+
+
+
+/**
+ * @defgroup group_fw_mngmnt Firmware Management
+ *
+ * @note These structures and definitions provide extended firmware management
+ * for Meinberg devices based on Linux / Windows.
+ * if ::MBG_XFEATURE_FW_MNGMNT is set in the extended device features.
+ *
+ * @{ */
+
+
typedef struct
{
- uint8_t flags; ///< ::MBG_USB_LOCK_FLAG_MSKS
+ uint8_t max_fws; ///< Maximum installable firmwares
+ uint8_t installed_fws; ///< Currently installed firmwares
+ uint8_t active_fw; ///< Index of currently active firmware
+ uint8_t osv_fw; ///< Index of OSV firmware
+ uint32_t reserved_1[15];
+
+} MBG_FW_GLB_INFO;
+
+
+#define _mbg_swab_fw_glb_info( _p ) \
+do \
+{ \
+} while ( 0 )
+
+
+enum MBG_FW_FLAGS
+{
+ MBG_FW_FLAG_OSV, ///< Originally Shipped Version
+ MBG_FW_FLAG_ACTIVE, ///< Version is active (currently running)
+ MBG_FW_FLAG_UNERASABLE, ///< Firmware cannot be erased / deleted (e.g. OSV)
+ MBG_FW_FLAG_IMMUTABLE, ///< Single files (e.g. UFUs) within firmware cannot be
+ ///< updated, added, deleted, etc...
+ N_MBG_FW_FLAGS
+};
+
+
+enum MBG_FW_FLAG_MSKS
+{
+ MBG_FW_FLAG_MSK_OSV = (1UL << MBG_FW_FLAG_OSV), ///< See ::MBG_FW_FLAG_OSV
+ MBG_FW_FLAG_MSK_ACTIVE = (1UL << MBG_FW_FLAG_ACTIVE), ///< See ::MBG_FW_FLAG_ACTIVE
+ MBG_FW_FLAG_MSK_UNERASABLE = (1UL << MBG_FW_FLAG_UNERASABLE), ///< See ::MBG_FW_FLAG_UNERASABLE
+ MBG_FW_FLAG_MSK_IMMUTABLE = (1UL << MBG_FW_FLAG_IMMUTABLE) ///< See ::MBG_FW_FLAG_IMMUTABLE
+};
+
+
+enum MBG_FW_FILES
+{
+ MBG_FW_FILE_UNKNOWN, ///< Indicate there are unknown files (older FW scans newer files)
+ MBG_FW_FILE_INCREMENTAL, ///< Indicate there are incremental update files
+ MBG_FW_FILE_MEINBERG_DTB, ///< Meinberg device tree describes e.g. front connectors
+ MBG_FW_FILE_PRELOADER, ///< Whatever preloader magic file
+ MBG_FW_FILE_ROOTFS, ///< Root filesystem
+ MBG_FW_FILE_KERNEL_DTB, ///< Kernel device tree
+ MBG_FW_FILE_RBF, ///< FPGA firmware binary
+ MBG_FW_FILE_INITRD, ///< Initial ramdisk
+ MBG_FW_FILE_VERSION_TXT, ///< File containing firmware version
+ MBG_FW_FILE_KERNEL, ///< Kernel (not necessarily Linux)
+ N_MBG_FW_FILES
+};
+
+
+#define MBG_FW_FILE_STRS \
+{ \
+ "Unknown file(s)", \
+ "Incremental file(s)", \
+ "Meinberg device tree", \
+ "Preloader", \
+ "Root filesystem", \
+ "Kernel device tree", \
+ "FPGA firmware binary", \
+ "Initial ramdisk", \
+ "Version.txt", \
+ "Kernel" \
+}
+
+
+enum MBG_FW_FILE_MSKS
+{
+ MBG_FW_FILE_MSK_UNKNOWN = (1UL << MBG_FW_FILE_UNKNOWN), ///< See ::MBG_FW_FILE_UNKNOWN
+ MBG_FW_FILE_MSK_INCREMENTAL = (1UL << MBG_FW_FILE_INCREMENTAL), ///< See ::MBG_FW_FILE_INCREMENTAL
+ MBG_FW_FILE_MSK_MEINBERG_DTB = (1UL << MBG_FW_FILE_MEINBERG_DTB), ///< See ::MBG_FW_FILE_MEINBERG_DTB
+ MBG_FW_FILE_MSK_PRELOADER = (1UL << MBG_FW_FILE_PRELOADER), ///< See ::MBG_FW_FILE_PRELOADER
+ MBG_FW_FILE_MSK_ROOTFS = (1UL << MBG_FW_FILE_ROOTFS), ///< See ::MBG_FW_FILE_ROOTFS
+ MBG_FW_FILE_MSK_KERNEL_DTB = (1UL << MBG_FW_FILE_KERNEL_DTB), ///< See ::MBG_FW_FILE_KERNEL_DTB
+ MBG_FW_FILE_MSK_RBF = (1UL << MBG_FW_FILE_RBF), ///< See ::MBG_FW_FILE_RBF
+ MBG_FW_FILE_MSK_INITRD = (1UL << MBG_FW_FILE_INITRD), ///< See ::MBG_FW_FILE_INITRD
+ MBG_FW_FILE_MSK_VERSION_TXT = (1UL << MBG_FW_FILE_VERSION_TXT), ///< See ::MBG_FW_FILE_VERSION_TXT
+ MBG_FW_FILE_MSK_KERNEL = (1UL << MBG_FW_FILE_KERNEL) ///< See ::MBG_FW_FILE_KERNEL
+};
+
+
+typedef struct
+{
+ uint32_t revision; ///< Main revision information
+ uint32_t flags; ///< See ::MBG_FW_FLAG_MSKS
+ uint16_t num_ufus; ///< Number of available UFUs
+ uint16_t reserved_1;
+ uint8_t release_candidate; ///< Release candidate revision information
+ uint8_t reserved_2[3];
+ uint32_t files; ///< Single file (list) flags, See ::MBG_FW_FILE_MSKS
+ uint32_t reserved_3[11];
+
+} MBG_FW_INFO;
+
+
+#define _mbg_swab_fw_info( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->revision ); \
+ _mbg_swab32( &(_p)->flags ); \
+ _mbg_swab16( &(_p)->num_ufus ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_FW_INFO info;
+
+} MBG_FW_INFO_IDX;
+
+
+#define _mbg_swab_fw_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_fw_info( &(_p)->info ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t revision; ///< Main revision information
+ uint8_t release_candidate; ///< Release candidate revision information
uint8_t reserved_1[3];
- uint32_t reserved_2[3];
+ uint16_t model_code; ///< One of ::GPS_MODEL_CODES
+ uint16_t reserved_2;
+ uint32_t reserved_3[5];
+
+} MBG_FW_UFU_INFO;
+
+
+#define _mbg_swab_fw_ufu_info( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->revision ); \
+ _mbg_swab16( &(_p)->model_code ); \
+} while ( 0 )
-} MBG_USB_LOCK_STATUS;
-#define _mbg_swab_usb_lock_status( _p ) do {} while ( 0 )
+typedef struct
+{
+ uint16_t fw_idx; ///< 0...::MBG_FW_GLB_INFO::installed_fws - 1
+ uint16_t ufu_idx; ///< 0...::MBG_FW_INFO::num_ufus-1
+ MBG_FW_UFU_INFO info; ///< See ::MBG_FW_UFU_INFO
+
+} MBG_FW_UFU_INFO_IDX;
+
+
+#define _mbg_swab_fw_ufu_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->fw_idx ); \
+ _mbg_swab16( &(_p)->ufu_idx ); \
+ _mbg_swab_fw_ufu_info( &(_p)->info ); \
+} while ( 0 )
+
+
+/**
+ * @brief Command types used to flash UFU(S) to device(s)
+ */
+enum MBG_FW_UFU_FLASH_CMDS
+{
+ /// ::MBG_FW_UFU_FLASH_CMD::ufu_idx and ::MBG_FW_UFU_FLASH_CMD::xbp_addr must be set.
+ /// Send one specific UFU to a specific device identified by its XBP address
+ MBG_FW_UFU_FLASH_CMD_DEVICE_UFU,
+
+ /// ::MBG_FW_UFU_FLASH_CMD::ufu_idx must be set.
+ /// Send one specific UFU to all suitable devices that fit the model code.
+ MBG_FW_UFU_FLASH_CMD_UFU_ALL,
+
+ /// ::MBG_FW_UFU_FLASH_CMD::xbp_addr must be set.
+ /// Find the newest firmware version for a device identified by its XBP address
+ /// and flash it.
+ MBG_FW_UFU_FLASH_CMD_DEVICE,
+
+ /// ::MBG_FW_UFU_FLASH_CMD::model_code must be set.
+ /// Find the newest firmware version for specific devices identified by
+ /// the firmware's model code and flash that firmware to all suitable devices.
+ MBG_FW_UFU_FLASH_CMD_TYPE,
+
+ /// Find the newest firmware version for each single device and flash
+ /// each device with a corresponding firmware.
+ MBG_FW_UFU_FLASH_CMD_ALL,
+
+ N_MBG_FW_UFU_FLASH_CMDS
+};
+
+
+typedef struct
+{
+ /// Please be aware that, depending on the command, specific members in
+ /// ::MBG_FW_UFU_FLASH_CMD are valid, all others should be zero and be ignored.
+ uint8_t cmd; ///< See ::MBG_FW_UFU_FLASH_CMDS
+ uint8_t reserved_1; ///< Future use
+ uint16_t ufu_idx; ///< See ::MBG_FW_UFU_FLASH_CMD_DEVICE_UFU
+ XBP_ADDR xbp_addr; ///< See ::MBG_FW_UFU_FLASH_CMD_DEVICE_UFU or
+ ///< ::MBG_FW_UFU_FLASH_CMD_DEVICE
+ uint16_t model_code; ///< see ::MBG_FW_UFU_FLASH_CMD_TYPE
+ uint16_t reserved_3; ///< Future use
+ uint32_t reserved_4[4]; ///< Future use
+
+} MBG_FW_UFU_FLASH_CMD;
+
+
+#define _mbg_swab_fw_ufu_flash_cmd( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->ufu_idx ); \
+ _mbg_swab16( &(_p)->model_code ); \
+} while ( 0 )
+
+
+/** @} defgroup group_fw_mngmnt */
+
+
+
+/**
+ * @defgroup group_database Database(s)
+ *
+ * @note These structures and definitions provide database functionality
+ * if ::MBG_XFEATURE_DATABASE is set in the extended device features.
+ *
+ * @{ */
+
+
+enum MBG_DATABASE_TYPES
+{
+ MBG_DATABASE_TYPE_SQLITE, ///< SQLite
+ MBG_DATABASE_TYPE_MYSQL, ///< MySQL
+ MBG_DATABASE_TYPE_POSTGRESQL, ///< PostgreSQL
+ N_MBG_DATABASE_TYPES
+};
+
+
+#define MBG_DATABASE_TYPE_STRS \
+{ \
+ "SQLite", \
+ "MySQL", \
+ "PostgreSQL" \
+}
+
+
+typedef struct
+{
+ uint8_t num_dbs; ///< Number of configurable databases
+ uint8_t reserved_1;
+ uint16_t reserved_2;
+ uint32_t reserved_3[3];
+
+} MBG_DATABASE_GLB_INFO;
+
+
+#define _mbg_swab_database_glb_info( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->supp_dbs ); \
+} while ( 0 )
+
+
+enum MBG_DATABASE_SETTINGS_FLAGS
+{
+ MBG_DATABASE_SETTINGS_FLAG_ENABLE, ///< Enable, disable logging to database
+ MBG_DATABASE_SETTINGS_FLAG_SAVE_PERSIST, ///< Save database (cyclically) to a persistent storage
+ N_MBG_DATABASE_SETTINGS_FLAGS
+};
+
+
+enum MBG_DATABASE_SETTINGS_FLAG_MSKS
+{
+ MBG_DATABASE_SETTINGS_FLAG_MSK_ENABLE = (1UL << MBG_DATABASE_SETTINGS_FLAG_ENABLE), ///< See ::MBG_DATABASE_SETTINGS_FLAG_ENABLE
+ MBG_DATABASE_SETTINGS_FLAG_MSK_SAVE_PERSIST = (1UL << MBG_DATABASE_SETTINGS_FLAG_SAVE_PERSIST) ///< See ::MBG_DATABASE_SETTINGS_FLAG_SAVE_PERSIST
+};
+
+
+#define MBG_DATABASE_MAX_STR 32
+
+
+typedef struct
+{
+ uint16_t flags; ///< See ::MBG_DATABASE_SETTINGS_FLAG_MSKS
+ uint16_t port; ///< Remote host port
+ uint32_t reserved_2[7];
+ char user[MBG_DATABASE_MAX_STR]; ///< Database username
+ char password[MBG_DATABASE_MAX_STR]; ///< Database password
+
+ /// ::MBG_DATABASE_SETTINGS::host can be set to a remote database server
+ /// (MySQL, PostgreSQL, etc...) or even to a local file path
+ /// in case of a SQLite database. In case of a local file database
+ /// ::MBG_DATABASE_INFO_FLAG_MSK_LOCAL_FILE should be set in ::MBG_DATABASE_INFO::flags
+ /// to announce its path. Thus, a capable piece of software can fetch it via
+ /// TLV API.
+ char host[MBG_MAX_HOSTNAME_LEN];
+
+ char dbname[MBG_DATABASE_MAX_STR]; ///< Database name
+ char reserved_3[MBG_DATABASE_MAX_STR];
+ char reserved_4[MBG_DATABASE_MAX_STR];
+
+} MBG_DATABASE_SETTINGS;
+
+
+#define _mbg_swab_database_settings( _p ) \
+do \
+{ \
+ _mbg_swab16( &(_p)->port ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_DATABASE_SETTINGS settings;
+
+} MBG_DATABASE_SETTINGS_IDX;
+
+
+#define _mbg_swab_database_settings_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_database_settings( &(_p)->settings ); \
+} while ( 0 )
+
+
+enum MBG_DATABASE_INFO_FLAGS
+{
+ MBG_DATABASE_INFO_FLAG_LOCAL_FILE, ///< Database is a local file only
+ N_MBG_DATABASE_INFO_FLAGS
+};
+
+
+enum MBG_DATABASE_INFO_FLAG_MSKS
+{
+ /// See ::MBG_DATABASE_INFO_FLAG_LOCAL_FILE
+ MBG_DATABASE_INFO_FLAG_MSK_LOCAL_FILE = ( 1UL << MBG_DATABASE_INFO_FLAG_LOCAL_FILE )
+};
+
+
+enum MBG_DATABASE_MEMBERS
+{
+ MBG_DATABASE_MEMBER_FLAGS, ///< ::MBG_DATABASE_SETTINGS::flags is valid
+ MBG_DATABASE_MEMBER_PORT, ///< ::MBG_DATABASE_SETTINGS::port is valid
+ MBG_DATABASE_MEMBER_USER, ///< ::MBG_DATABASE_SETTINGS::user is valid
+ MBG_DATABASE_MEMBER_PASSWORD, ///< ::MBG_DATABASE_SETTINGS::password is valid
+ MBG_DATABASE_MEMBER_HOST, ///< ::MBG_DATABASE_SETTINGS::host is valid
+ MBG_DATABASE_MEMBER_DBNAME, ///< ::MBG_DATABASE_SETTINGS::dbname is valid
+ N_MBG_DATABASE_MEMBERS
+};
+
+
+enum MBG_DATABASE_MEMBER_MSKS
+{
+ MBG_DATABASE_MEMBER_MSK_FLAGS = (1UL << MBG_DATABASE_MEMBER_FLAGS), ///< See ::MBG_DATABASE_MEMBER_FLAGS
+ MBG_DATABASE_MEMBER_MSK_PORT = (1UL << MBG_DATABASE_MEMBER_PORT), ///< See ::MBG_DATABASE_MEMBER_PORT
+ MBG_DATABASE_MEMBER_MSK_USER = (1UL << MBG_DATABASE_MEMBER_USER), ///< See ::MBG_DATABASE_MEMBER_USER
+ MBG_DATABASE_MEMBER_MSK_PASSWORD = (1UL << MBG_DATABASE_MEMBER_PASSWORD), ///< See ::MBG_DATABASE_MEMBER_PASSWORD
+ MBG_DATABASE_MEMBER_MSK_HOST = (1UL << MBG_DATABASE_MEMBER_HOST), ///< See ::MBG_DATABASE_MEMBER_HOST
+ MBG_DATABASE_MEMBER_MSK_DBNAME = (1UL << MBG_DATABASE_MEMBER_DBNAME) ///< See ::MBG_DATABASE_MEMBER_DBNAME
+};
+
+
+typedef struct
+{
+ MBG_DATABASE_SETTINGS settings; ///< See ::MBG_DATABASE_SETTINGS
+ uint8_t type; ///< See ::MBG_DATABASE_TYPES
+ uint8_t flags; ///< See ::MBG_DATABASE_INFO_FLAG_MSKS
+
+ /// Flag field which ::MBG_DATABASE_MEMBER_MSKS are valid.
+ uint16_t supp_members;
+
+ /// Flag field which ::MBG_DATABASE_MEMBER_MSKS are configurable.
+ /// Subset of ::MBG_DATABASE_INFO::supp_members.
+
+ uint16_t supp_cfgs;
+
+ /// If ::MBG_DATABASE_MEMBER_MSK_FLAGS is set in ::MBG_DATABASE_INFO::supp_members
+ /// and ::MBG_DATABASE_MEMBER_MSK_FLAGS is set in ::MBG_DATABASE_INFO::supp_cfgs,
+ /// this is the flag field of supported ::MBG_DATABASE_SETTINGS_FLAG_MSKS in
+ /// ::MBG_DATABASE_SETTINGS::flags
+ uint16_t supp_settings_flags;
+
+ uint32_t reserved_3[2];
+
+} MBG_DATABASE_INFO;
+
+
+#define _mbg_swab_database_info( _p ) \
+do \
+{ \
+ _mbg_swab_database_settings( &(_p)->settings ); \
+ _mbg_swab16( &(_p)->supp_members ); \
+ _mbg_swab16( &(_p)->supp_cfgs ); \
+} while ( 0 )
+
+
+typedef struct
+{
+ uint32_t idx;
+ MBG_DATABASE_INFO info;
+
+} MBG_DATABASE_INFO_IDX;
+
+
+#define _mbg_swab_database_info_idx( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->idx ); \
+ _mbg_swab_database_info( &(_p)->info ); \
+} while ( 0 )
+
+
+enum MBG_DATABASE_CMDS
+{
+ MBG_DATABASE_CMD_RESET_SV_LOGS,
+ N_MBG_DATABASE_CMDS
+};
+
+
+typedef struct
+{
+ uint32_t cmd; ///< See ::MBG_DATABASE_CMDS
+ uint32_t length; ///< Payload data length of ::MBG_DATABASE_CMD::payload
+ uint32_t reserved[2]; ///< Future use
+ unsigned char payload[240]; ///< Payload data
+
+} MBG_DATABASE_CMD;
+
+
+#define _mbg_swab_database_cmd( _p ) \
+do \
+{ \
+ _mbg_swab32( &(_p)->cmd ); \
+ _mbg_swab32( &(_p)->length ); \
+} while ( 0 )
+
+/** @} defgroup group_database */
-/** @} defgroup group_usb_lock */
#if defined( _USING_BYTE_ALIGNMENT )
diff --git a/mbglib/common/mbg_ntp_auth.c b/mbglib/common/mbg_ntp_auth.c
new file mode 100755
index 0000000..cc5dc69
--- /dev/null
+++ b/mbglib/common/mbg_ntp_auth.c
@@ -0,0 +1,1925 @@
+
+/**************************************************************************
+ *
+ * $Id: mbg_ntp_auth.c 1.2 2014/09/24 08:55:12 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Crypto functions useful for NTP implementations, stolen from
+ * original NTP source code.
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbg_ntp_auth.c $
+ * Revision 1.2 2014/09/24 08:55:12 martin
+ * Full support of NTP symmetric key authentication.
+ * Export only Meinberg-specific functions which call
+ * the NTP functions internally.
+ * Modifications to make the key cache thread-safe.
+ * Locking will be required in addition if keys are added,
+ * deleted, or made untrusted at run time.
+ * Revision 1.1 2014/09/10 15:37:57 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#define _MBG_NTP_AUTH
+ #include <mbg_ntp_auth.h>
+#undef _MBG_NTP_AUTH
+
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+
+#include <stddef.h> // offsetof()
+#include <math.h> // log10()
+#include <syslog.h> // log levels
+#include <ctype.h> // toupper()
+
+
+#if NTP_COMPAT
+ #define TRUE 1
+ #define FALSE 0
+
+ #define max(n1, n2) ( ( (n1) > (n2) ) ? (n1) : (n2) )
+ #define min(n1, n2) ( ( (n1) < (n2) ) ? (n1) : (n2) )
+
+ #define zero_mem(p, s) bzero(p, s)
+
+ #define DEBUG_ENSURE( _v ) do {} while(0)
+ static u_long current_time; /* seconds since startup */
+
+ #ifdef DEBUG
+ static int debug = DEBUG;
+ #endif
+
+/*
+ * macro for debugging output - cut down on #ifdef pollution.
+ *
+ * DPRINTF() is for use by ntpd only, and compiles away to nothing
+ * without DEBUG (configure --disable-debugging).
+ *
+ * TRACE() is similar for libntp and utilities, which retain full
+ * debug capability even when compiled without DEBUG.
+ *
+ * The calling convention is not attractive:
+ * DPRINTF(debuglevel, (fmt, ...));
+ * DPRINTF(2, ("shows #ifdef DEBUG and if debug >= %d\n", 2));
+ */
+#if 0 && defined( DEBUG ) //##++++++
+# define DPRINTF(lvl, arg) \
+ do { \
+ if (debug >= (lvl)) \
+ mprintf arg; \
+ } while (0)
+#else
+# define DPRINTF(lvl, arg) do {} while (0)
+#endif
+
+ #define msyslog mbglog
+ extern void mbglog( int lvl, const char *fmt, ... );
+#endif // NTP_COMPAT
+
+
+
+
+#if 1 // SLISTS from ntp_lists.h
+
+#ifdef DEBUG
+# define NTP_DEBUG_LISTS_H
+#endif
+
+/*
+ * If list debugging is not enabled, save a little time by not clearing
+ * an entry's link pointer when it is unlinked, as the stale pointer
+ * is harmless as long as it is ignored when the entry is not in a
+ * list.
+ */
+#ifndef NTP_DEBUG_LISTS_H
+#define MAYBE_Z_LISTS(p) do { } while (FALSE)
+#else
+#define MAYBE_Z_LISTS(p) (p) = NULL
+#endif
+
+#define LINK_SLIST(listhead, pentry, nextlink) \
+do { \
+ (pentry)->nextlink = (listhead); \
+ (listhead) = (pentry); \
+} while (FALSE)
+
+#define LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) \
+do { \
+ entrytype **pptail; \
+ \
+ pptail = &(listhead); \
+ while (*pptail != NULL) \
+ pptail = &((*pptail)->nextlink); \
+ \
+ (pentry)->nextlink = NULL; \
+ *pptail = (pentry); \
+} while (FALSE)
+
+#define LINK_SORT_SLIST_CURRENT() (*ppentry)
+#define L_S_S_CUR() LINK_SORT_SLIST_CURRENT()
+
+#define LINK_SORT_SLIST(listhead, pentry, beforecur, nextlink, \
+ entrytype) \
+do { \
+ entrytype **ppentry; \
+ \
+ ppentry = &(listhead); \
+ while (TRUE) { \
+ if (NULL == *ppentry || (beforecur)) { \
+ (pentry)->nextlink = *ppentry; \
+ *ppentry = (pentry); \
+ break; \
+ } \
+ ppentry = &((*ppentry)->nextlink); \
+ if (NULL == *ppentry) { \
+ (pentry)->nextlink = NULL; \
+ *ppentry = (pentry); \
+ break; \
+ } \
+ } \
+} while (FALSE)
+
+#define UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) \
+do { \
+ (punlinked) = (listhead); \
+ if (NULL != (punlinked)) { \
+ (listhead) = (punlinked)->nextlink; \
+ MAYBE_Z_LISTS((punlinked)->nextlink); \
+ } \
+} while (FALSE)
+
+#define UNLINK_EXPR_SLIST_CURRENT() (*ppentry)
+#define U_E_S_CUR() UNLINK_EXPR_SLIST_CURRENT()
+
+#define UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, \
+ entrytype) \
+do { \
+ entrytype **ppentry; \
+ \
+ ppentry = &(listhead); \
+ \
+ while (!(expr)) \
+ if (*ppentry != NULL && \
+ (*ppentry)->nextlink != NULL) { \
+ ppentry = &((*ppentry)->nextlink); \
+ } else { \
+ ppentry = NULL; \
+ break; \
+ } \
+ \
+ if (ppentry != NULL) { \
+ (punlinked) = *ppentry; \
+ *ppentry = (punlinked)->nextlink; \
+ MAYBE_Z_LISTS((punlinked)->nextlink); \
+ } else { \
+ (punlinked) = NULL; \
+ } \
+} while (FALSE)
+
+#define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \
+ entrytype) \
+ UNLINK_EXPR_SLIST(punlinked, listhead, (ptounlink) == \
+ U_E_S_CUR(), nextlink, entrytype)
+
+#define CHECK_SLIST(listhead, nextlink, entrytype) \
+do { \
+ entrytype *pentry; \
+ \
+ for (pentry = (listhead); \
+ pentry != NULL; \
+ pentry = pentry->nextlink){ \
+ NTP_INSIST(pentry != pentry->nextlink); \
+ NTP_INSIST((listhead) != pentry->nextlink); \
+ } \
+} while (FALSE)
+
+#endif // SLISTS from ntp_lists.h
+
+
+
+
+
+#if 1 // from ntp_lists.h
+
+/*
+ * DLIST
+ */
+#define DECL_DLIST_LINK(entrytype, link) \
+struct { \
+ entrytype * b; \
+ entrytype * f; \
+} link
+
+#define INIT_DLIST(listhead, link) \
+do { \
+ (listhead).link.f = &(listhead); \
+ (listhead).link.b = &(listhead); \
+} while (FALSE)
+
+#define HEAD_DLIST(listhead, link) \
+ ( \
+ (&(listhead) != (listhead).link.f) \
+ ? (listhead).link.f \
+ : NULL \
+ )
+
+#define TAIL_DLIST(listhead, link) \
+ ( \
+ (&(listhead) != (listhead).link.b) \
+ ? (listhead).link.b \
+ : NULL \
+ )
+
+#define NEXT_DLIST(listhead, entry, link) \
+ ( \
+ (&(listhead) != (entry)->link.f) \
+ ? (entry)->link.f \
+ : NULL \
+ )
+
+#define PREV_DLIST(listhead, entry, link) \
+ ( \
+ (&(listhead) != (entry)->link.b) \
+ ? (entry)->link.b \
+ : NULL \
+ )
+
+#define LINK_DLIST(listhead, pentry, link) \
+do { \
+ (pentry)->link.f = (listhead).link.f; \
+ (pentry)->link.b = &(listhead); \
+ (listhead).link.f->link.b = (pentry); \
+ (listhead).link.f = (pentry); \
+} while (FALSE)
+
+#define LINK_TAIL_DLIST(listhead, pentry, link) \
+do { \
+ (pentry)->link.b = (listhead).link.b; \
+ (pentry)->link.f = &(listhead); \
+ (listhead).link.b->link.f = (pentry); \
+ (listhead).link.b = (pentry); \
+} while (FALSE)
+
+#define UNLINK_DLIST(ptounlink, link) \
+do { \
+ (ptounlink)->link.b->link.f = (ptounlink)->link.f; \
+ (ptounlink)->link.f->link.b = (ptounlink)->link.b; \
+ MAYBE_Z_LISTS((ptounlink)->link.b); \
+ MAYBE_Z_LISTS((ptounlink)->link.f); \
+} while (FALSE)
+
+#define ITER_DLIST_BEGIN(listhead, iter, link, entrytype) \
+{ \
+ entrytype *i_dl_nextiter; \
+ \
+ for ((iter) = (listhead).link.f; \
+ (iter) != &(listhead) \
+ && ((i_dl_nextiter = (iter)->link.f), TRUE); \
+ (iter) = i_dl_nextiter) {
+#define ITER_DLIST_END() \
+ } \
+}
+
+#define REV_ITER_DLIST_BEGIN(listhead, iter, link, entrytype) \
+{ \
+ entrytype *i_dl_nextiter; \
+ \
+ for ((iter) = (listhead).link.b; \
+ (iter) != &(listhead) \
+ && ((i_dl_nextiter = (iter)->link.b), TRUE); \
+ (iter) = i_dl_nextiter) {
+#define REV_ITER_DLIST_END() \
+ } \
+}
+
+#endif // ntp_lists.h
+
+
+
+
+#if 1 // from ntp_malloc.h
+
+#ifdef EREALLOC_IMPL
+# define EREALLOC_CALLSITE /* preserve __FILE__ and __LINE__ */
+#else
+# define EREALLOC_IMPL(ptr, newsz, filenm, loc) \
+ realloc(ptr, (newsz))
+#endif
+
+#endif // from ntp_malloc.h
+
+
+
+
+#if 1 // from ntp_stdlib.h
+
+/* emalloc.c */
+#ifndef EREALLOC_CALLSITE /* ntp_malloc.h defines */
+static /*extern*/ void * ereallocz (void *, size_t, size_t, int);
+#define erealloczsite(p, n, o, z, f, l) ereallocz(p, n, o, (z))
+static /*extern*/ void * emalloc (size_t);
+#define emalloc_zero(c) ereallocz(NULL, (c), 0, TRUE)
+#define erealloc(p, c) ereallocz(p, (c), 0, FALSE)
+#define erealloc_zero(p, n, o) ereallocz(p, n, (o), TRUE)
+extern char * estrdup_impl (const char *);
+#define estrdup(s) estrdup_impl(s)
+#else
+extern void * ereallocz (void *, size_t, size_t, int,
+ const char *, int);
+#define erealloczsite ereallocz
+#define emalloc(c) ereallocz(NULL, (c), 0, FALSE, \
+ __FILE__, __LINE__)
+#define emalloc_zero(c) ereallocz(NULL, (c), 0, TRUE, \
+ __FILE__, __LINE__)
+#define erealloc(p, c) ereallocz(p, (c), 0, FALSE, \
+ __FILE__, __LINE__)
+#define erealloc_zero(p, n, o) ereallocz(p, n, (o), TRUE, \
+ __FILE__, __LINE__)
+extern char * estrdup_impl (const char *, const char *, int);
+#define estrdup(s) estrdup_impl((s), __FILE__, __LINE__)
+#endif
+
+/* ssl_init.c */
+#ifdef OPENSSL
+static /*extern*/ void ssl_init (void);
+// static /*extern*/ void ssl_check_version (void);
+static /*extern*/ int ssl_init_done;
+#define INIT_SSL() \
+ do { \
+ if (!ssl_init_done) \
+ ssl_init(); \
+ } while (0)
+#else /* !OPENSSL follows */
+#define INIT_SSL() do {} while (0)
+#endif
+
+#endif // from ntp_stdlib.h
+
+
+
+
+#if 1 // from ssl_init.c
+
+#ifdef OPENSSL
+
+static
+void atexit_ssl_cleanup(void);
+
+static
+int ssl_init_done;
+
+static
+void
+ssl_init(void)
+{
+//##+++++ init_lib();
+
+ if (ssl_init_done)
+ return;
+
+ ERR_load_crypto_strings();
+ //##+++++ ERR_load_BIO_strings(); // TODO: NTP doesn't use this. Do we need it?
+ OpenSSL_add_all_algorithms();
+ atexit(&atexit_ssl_cleanup);
+
+ ssl_init_done = TRUE;
+}
+
+
+static
+void
+atexit_ssl_cleanup(void)
+{
+ if (!ssl_init_done)
+ return;
+
+ ssl_init_done = FALSE;
+ EVP_cleanup();
+ ERR_free_strings();
+}
+
+
+
+#if 0
+
+static
+void
+ssl_check_version(void)
+{
+ if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) {
+ msyslog(LOG_WARNING,
+ "OpenSSL version mismatch. Built against %lx, you have %lx",
+ (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
+ fprintf(stderr,
+ "OpenSSL version mismatch. Built against %lx, you have %lx\n",
+ (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
+ }
+
+ INIT_SSL();
+}
+
+#endif // 0
+
+#endif /* OPENSSL */
+
+
+/*
+ * keytype_name returns OpenSSL short name for digest by NID.
+ *
+ * Used by ntpq and ntpdc keytype()
+ */
+static
+const char *
+keytype_name(
+ int nid
+ )
+{
+ static const char unknown_type[] = "(unknown key type)";
+ const char *name;
+
+#ifdef OPENSSL
+ INIT_SSL();
+ name = OBJ_nid2sn(nid);
+ if (NULL == name)
+ name = unknown_type;
+#else /* !OPENSSL follows */
+ if (NID_md5 == nid)
+ name = "MD5";
+ else
+ name = unknown_type;
+#endif
+ return name;
+}
+
+
+/*
+ * keytype_from_text returns OpenSSL NID for digest by name, and
+ * optionally the associated digest length.
+ *
+ * Used by ntpd authreadkeys(), ntpq and ntpdc keytype()
+ */
+static
+int
+keytype_from_text(
+ const char *text,
+ size_t *pdigest_len
+ )
+{
+ int key_type;
+ u_int digest_len;
+#ifdef OPENSSL
+ const u_long max_digest_len = MAX_MAC_LEN - sizeof(keyid_t);
+ u_char digest[EVP_MAX_MD_SIZE];
+ char * upcased;
+ char * pch;
+ EVP_MD_CTX ctx;
+
+ /*
+ * OpenSSL digest short names are capitalized, so uppercase the
+ * digest name before passing to OBJ_sn2nid(). If it is not
+ * recognized but begins with 'M' use NID_md5 to be consistent
+ * with past behavior.
+ */
+ INIT_SSL();
+ #if 1 // NOTE: modification by martin
+ upcased = strdup( text );
+ if ( upcased )
+ {
+ for (pch = upcased; '\0' != *pch; pch++)
+ *pch = (char)toupper(*pch);
+ key_type = OBJ_sn2nid( upcased );
+ free( upcased );
+ }
+ else
+ key_type = 0;
+ #else
+ LIB_GETBUF(upcased);
+ strlcpy(upcased, text, LIB_BUFLENGTH);
+ for (pch = upcased; '\0' != *pch; pch++)
+ *pch = (char)toupper(*pch);
+ key_type = OBJ_sn2nid(upcased);
+ #endif
+#else
+ key_type = 0;
+#endif
+
+ if (!key_type && 'm' == tolower(text[0]))
+ key_type = NID_md5;
+
+ if (!key_type)
+ return 0;
+
+ if (NULL != pdigest_len) {
+#ifdef OPENSSL
+ EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type));
+ EVP_DigestFinal(&ctx, digest, &digest_len);
+ if (digest_len > max_digest_len) {
+ fprintf(stderr,
+ "key type %s %u octet digests are too big, max %lu\n",
+ keytype_name(key_type), digest_len,
+ max_digest_len);
+ msyslog(LOG_ERR,
+ "key type %s %u octet digests are too big, max %lu",
+ keytype_name(key_type), digest_len,
+ max_digest_len);
+ return 0;
+ }
+#else
+ digest_len = 16;
+#endif
+ *pdigest_len = digest_len;
+ }
+
+ return key_type;
+}
+
+#endif // from ssl_init.c
+
+
+
+/*
+ * Structure to store keys in in the hash table.
+ */
+typedef struct savekey symkey;
+
+struct savekey {
+ symkey * hlink; /* next in hash bucket */
+ DECL_DLIST_LINK(symkey, llink); /* for overall & free lists */
+ // TODO: the next fields except 'lifetime' are also
+ // used by the key cache.
+ u_char * secret; /* shared secret */
+ u_long lifetime; /* remaining lifetime */
+ keyid_t keyid; /* key identifier */
+ u_short type; /* OpenSSL digest NID */
+ u_short secretsize; /* secret octets */
+ u_short flags; /* KEY_ flags that wave */
+};
+
+/* define the payload region of symkey beyond the list pointers */
+#define symkey_payload secret
+
+#define KEY_TRUSTED 0x001 /* this key is trusted */
+
+#ifdef DEBUG
+typedef struct symkey_alloc_tag symkey_alloc;
+
+struct symkey_alloc_tag {
+ symkey_alloc * link;
+ void * mem; /* enable free() atexit */
+};
+
+symkey_alloc * authallocs;
+#endif /* DEBUG */
+
+static inline u_short auth_log2(double x);
+static void auth_resize_hashtable(void);
+static void allocsymkey(symkey **, keyid_t, u_short,
+ u_short, u_long, u_short, u_char *);
+static void freesymkey(symkey *, symkey **);
+#ifdef DEBUG_KEYS
+static void free_auth_mem(KEY_CACHE *);
+#endif
+
+symkey key_listhead; /* list of all in-use keys */;
+/*
+ * The hash table. This is indexed by the low order bits of the
+ * keyid. We make this fairly big for potentially busy servers.
+ */
+#define DEF_AUTHHASHSIZE 64
+//#define HASHMASK ((HASHSIZE)-1)
+#define KEYHASH(keyid) ((keyid) & authhashmask)
+
+int authhashdisabled;
+u_short authhashbuckets = DEF_AUTHHASHSIZE;
+u_short authhashmask = DEF_AUTHHASHSIZE - 1;
+symkey **key_hash;
+
+u_long authkeynotfound; /* keys not found */
+u_long authkeylookups; /* calls to lookup keys */
+u_long authnumkeys; /* number of active keys */
+u_long authkeyexpired; /* key lifetime expirations */
+u_long authkeyuncached; /* cache misses */
+u_long authnokey; /* calls to encrypt with no key */
+u_long authencryptions; /* calls to encrypt */
+u_long authdecryptions; /* calls to decrypt */
+
+/*
+ * Storage for free symkey structures. We malloc() such things but
+ * never free them.
+ */
+symkey *authfreekeys;
+int authnumfreekeys;
+
+#define MEMINC 16 /* number of new free ones to get */
+
+#if 1 // from a_md5encrypt.c
+
+/*
+ * MD5authencrypt - generate message digest
+ *
+ * Returns length of MAC including key ID and digest.
+ */
+static
+int
+MD5authencrypt(
+ KEY_CACHE *p_cache, /* TODO: check cache and parameter usage */
+ int type, /* hash algorithm */
+ u_char *key, /* key pointer */
+ u_int32 *pkt, /* packet pointer */
+ int length /* packet length */
+ )
+{
+ u_char digest[EVP_MAX_MD_SIZE];
+ u_int len;
+ EVP_MD_CTX ctx;
+
+ /*
+ * Compute digest of key concatenated with packet. Note: the
+ * key type and digest type have been verified when the key
+ * was creaded.
+ */
+ INIT_SSL();
+#if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x0090700fL
+ if (!EVP_DigestInit(&ctx, EVP_get_digestbynid(type))) {
+ msyslog(LOG_ERR,
+ "MAC encrypt: digest init failed");
+ return (0);
+ }
+#else
+ EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
+#endif
+ EVP_DigestUpdate(&ctx, key, p_cache->secretsize);
+ EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length);
+ EVP_DigestFinal(&ctx, digest, &len);
+ memmove((u_char *)pkt + length + 4, digest, len);
+ return (len + 4);
+}
+
+
+/*
+ * MD5authdecrypt - verify MD5 message authenticator
+ *
+ * Returns one if digest valid, zero if invalid.
+ */
+static
+int
+MD5authdecrypt(
+ KEY_CACHE *p_cache, /* TODO: check cache and parameter usage */
+ int type, /* hash algorithm */
+ u_char *key, /* key pointer */
+ u_int32 *pkt, /* packet pointer */
+ int length, /* packet length */
+ int size /* MAC size */
+ )
+{
+ u_char digest[EVP_MAX_MD_SIZE];
+ u_int len;
+ EVP_MD_CTX ctx;
+
+ /*
+ * Compute digest of key concatenated with packet. Note: the
+ * key type and digest type have been verified when the key
+ * was created.
+ */
+ INIT_SSL();
+#if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x0090700fL
+ if (!EVP_DigestInit(&ctx, EVP_get_digestbynid(type))) {
+ msyslog(LOG_ERR,
+ "MAC decrypt: digest init failed");
+ return (0);
+ }
+#else
+ EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
+#endif
+ EVP_DigestUpdate(&ctx, key, p_cache->secretsize);
+ EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length);
+ EVP_DigestFinal(&ctx, digest, &len);
+ if ((u_int)size != len + 4) {
+ msyslog(LOG_ERR,
+ "MAC decrypt: MAC length error");
+ return (0);
+ }
+
+ #if DEBUG_MBG_NTP_AUTH
+ {
+ NTP_PACKET *p = (NTP_PACKET *) pkt;
+ unsigned char *cp;
+ int i;
+
+ #define N_NTP_MAC_BYTES 16
+
+ printf( "using MD5 key ID: %08X, len = %i\n", htonl( p->mac.key_id ), len );
+
+ printf( "packet MD5 key hash: " );
+
+ for ( i = 0, cp = (unsigned char *)pkt + length + 4; i < N_NTP_MAC_BYTES; i++, cp++ )
+ printf( "%02X", *cp );
+
+ printf( "\n" );
+
+ printf( "digest MD5 key hash: " );
+
+ for ( i = 0, cp = digest; i < N_NTP_MAC_BYTES; i++, cp++ )
+ printf( "%02X", *cp );
+
+ printf( "\n" );
+ }
+ #endif
+
+ return !memcmp(digest, (char *)pkt + length + 4, len);
+}
+
+
+
+#if 0 //##++++++++++++++++++++
+
+/*
+ * Calculate the reference id from the address. If it is an IPv4
+ * address, use it as is. If it is an IPv6 address, do a md5 on
+ * it and use the bottom 4 bytes.
+ * The result is in network byte order.
+ */
+u_int32
+addr2refid(sockaddr_u *addr)
+{
+ u_char digest[20];
+ u_int32 addr_refid;
+ EVP_MD_CTX ctx;
+ u_int len;
+
+ if (IS_IPV4(addr))
+ return (NSRCADR(addr));
+
+ INIT_SSL();
+
+#if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x0090700fL
+ EVP_MD_CTX_init(&ctx);
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+ /* MD5 is not used as a crypto hash here. */
+ EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+ if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) {
+ msyslog(LOG_ERR,
+ "MD5 init failed");
+ exit(1);
+ }
+#else
+ EVP_DigestInit(&ctx, EVP_md5());
+#endif
+
+ EVP_DigestUpdate(&ctx, (u_char *)PSOCK_ADDR6(addr),
+ sizeof(struct in6_addr));
+ EVP_DigestFinal(&ctx, digest, &len);
+ memcpy(&addr_refid, digest, sizeof(addr_refid));
+ return (addr_refid);
+}
+
+#endif // 0 //##++++++
+
+#endif // from a_md5encrypt.c
+
+
+
+
+
+#if 1 // from emalloc.c
+
+/*
+ * When using the debug MS CRT allocator, each allocation stores the
+ * callsite __FILE__ and __LINE__, which is then displayed at process
+ * termination, to track down leaks. We don't want all of our
+ * allocations to show up as coming from emalloc.c, so we preserve the
+ * original callsite's source file and line using macros which pass
+ * __FILE__ and __LINE__ as parameters to these routines.
+ * Other debug malloc implementations can be used by defining
+ * EREALLOC_IMPL() as ports/winnt/include/config.h does.
+ */
+
+static
+void *
+ereallocz(
+ void * ptr,
+ size_t newsz,
+ size_t priorsz,
+ int zero_init
+#ifdef EREALLOC_CALLSITE /* ntp_malloc.h */
+ ,
+ const char * file,
+ int line
+#endif
+ )
+{
+ char * mem;
+ size_t allocsz;
+
+ if (0 == newsz)
+ allocsz = 1;
+ else
+ allocsz = newsz;
+
+ mem = EREALLOC_IMPL(ptr, allocsz, file, line);
+ if (NULL == mem) {
+//##+++++ msyslog_term = TRUE;
+#ifndef EREALLOC_CALLSITE
+ msyslog(LOG_ERR, "fatal out of memory (%lu bytes)",
+ (u_long)newsz);
+#else
+ msyslog(LOG_ERR,
+ "fatal out of memory %s line %d (%lu bytes)",
+ file, line, (u_long)newsz);
+#endif
+ exit(1);
+ }
+
+ if (zero_init && newsz > priorsz)
+ zero_mem(mem + priorsz, newsz - priorsz);
+
+ return mem;
+}
+
+//##++++ [...]
+
+#ifndef EREALLOC_CALLSITE
+static
+void *
+emalloc(size_t newsz)
+{
+ return ereallocz(NULL, newsz, 0, FALSE);
+}
+#endif
+
+
+#endif // from emalloc.c
+
+
+
+/*
+ * init_auth - initialize internal data
+ */
+static
+void
+init_auth(void)
+{
+ size_t newalloc;
+
+ /*
+ * Initialize hash table and free list
+ */
+ newalloc = authhashbuckets * sizeof(key_hash[0]);
+
+ key_hash = erealloc(key_hash, newalloc);
+ memset(key_hash, '\0', newalloc);
+
+ INIT_DLIST(key_listhead, llink);
+
+#ifdef DEBUG_KEYS
+ atexit(&free_auth_mem);
+#endif
+}
+
+
+/*
+ * free_auth_mem - assist in leak detection by freeing all dynamic
+ * allocations from this module.
+ */
+#ifdef DEBUG_KEYS
+static void
+free_auth_mem( KEY_CACHE *p_cache )
+{
+ symkey * sk;
+ symkey_alloc * alloc;
+ symkey_alloc * next_alloc;
+
+ while (NULL != (sk = HEAD_DLIST(key_listhead, llink))) {
+ freesymkey(sk, &key_hash[KEYHASH(sk->keyid)]);
+ }
+ free(key_hash);
+ key_hash = NULL;
+ p_cache->keyid = 0;
+ p_cache->flags = 0;
+ for (alloc = authallocs; alloc != NULL; alloc = next_alloc) {
+ next_alloc = alloc->link;
+ free(alloc->mem);
+ }
+ authfreekeys = NULL;
+ authnumfreekeys = 0;
+}
+#endif /* DEBUG */
+
+
+/*
+ * auth_moremem - get some more free key structures
+ */
+static
+void
+auth_moremem(
+ int keycount
+ )
+{
+ symkey * sk;
+ int i;
+#ifdef DEBUG
+ void * base;
+ symkey_alloc * allocrec;
+# define MOREMEM_EXTRA_ALLOC (sizeof(*allocrec))
+#else
+# define MOREMEM_EXTRA_ALLOC (0)
+#endif
+
+ i = (keycount > 0)
+ ? keycount
+ : MEMINC;
+ sk = emalloc_zero(i * sizeof(*sk) + MOREMEM_EXTRA_ALLOC);
+#ifdef DEBUG
+ base = sk;
+#endif
+ authnumfreekeys += i;
+
+ for (; i > 0; i--, sk++) {
+ LINK_SLIST(authfreekeys, sk, llink.f);
+ }
+
+#ifdef DEBUG
+ allocrec = (void *)sk;
+ allocrec->mem = base;
+ LINK_SLIST(authallocs, allocrec, link);
+#endif
+}
+
+
+/*
+ * auth_prealloc_symkeys
+ */
+static
+void
+auth_prealloc_symkeys(
+ int keycount
+ )
+{
+ int allocated;
+ int additional;
+
+ allocated = authnumkeys + authnumfreekeys;
+ additional = keycount - allocated;
+ if (additional > 0)
+ auth_moremem(additional);
+ auth_resize_hashtable();
+}
+
+
+static inline u_short
+auth_log2(double x)
+{
+ return (u_short)(log10(x) / log10(2));
+}
+
+
+/*
+ * auth_resize_hashtable
+ *
+ * Size hash table to average 4 or fewer entries per bucket initially,
+ * within the bounds of at least 4 and no more than 15 bits for the hash
+ * table index. Populate the hash table.
+ */
+static void
+auth_resize_hashtable(void)
+{
+ u_long totalkeys;
+ u_short hashbits;
+ u_short hash;
+ size_t newalloc;
+ symkey * sk;
+
+ totalkeys = authnumkeys + authnumfreekeys;
+ hashbits = auth_log2(totalkeys / 4.0) + 1;
+ hashbits = max(4, hashbits);
+ hashbits = min(15, hashbits);
+
+ authhashbuckets = 1 << hashbits;
+ authhashmask = authhashbuckets - 1;
+ newalloc = authhashbuckets * sizeof(key_hash[0]);
+
+ key_hash = erealloc(key_hash, newalloc);
+ memset(key_hash, '\0', newalloc);
+
+ ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
+ hash = KEYHASH(sk->keyid);
+ LINK_SLIST(key_hash[hash], sk, hlink);
+ ITER_DLIST_END()
+}
+
+
+/*
+ * allocsymkey - common code to allocate and link in symkey
+ *
+ * secret must be allocated with a free-compatible allocator. It is
+ * owned by the referring symkey structure, and will be free()d by
+ * freesymkey().
+ */
+static void
+allocsymkey(
+ symkey ** bucket,
+ keyid_t id,
+ u_short flags,
+ u_short type,
+ u_long lifetime,
+ u_short secretsize,
+ u_char * secret
+ )
+{
+ symkey * sk;
+
+ if (authnumfreekeys < 1)
+ auth_moremem(-1);
+ UNLINK_HEAD_SLIST(sk, authfreekeys, llink.f);
+ DEBUG_ENSURE(sk != NULL);
+ sk->keyid = id;
+ sk->flags = flags;
+ sk->type = type;
+ sk->secretsize = secretsize;
+ sk->secret = secret;
+ sk->lifetime = lifetime;
+ LINK_SLIST(*bucket, sk, hlink);
+ LINK_TAIL_DLIST(key_listhead, sk, llink);
+ authnumfreekeys--;
+ authnumkeys++;
+}
+
+
+/*
+ * freesymkey - common code to remove a symkey and recycle its entry.
+ */
+static void
+freesymkey(
+ symkey * sk,
+ symkey ** bucket
+ )
+{
+ symkey * unlinked;
+
+ if (sk->secret != NULL) {
+ // TODO: why is it set to 0 before it is freed?
+ memset(sk->secret, '\0', sk->secretsize);
+ free(sk->secret);
+ }
+ UNLINK_SLIST(unlinked, *bucket, sk, hlink, symkey);
+ DEBUG_ENSURE(sk == unlinked);
+ UNLINK_DLIST(sk, llink);
+ memset((char *)sk + offsetof(symkey, symkey_payload), '\0',
+ sizeof(*sk) - offsetof(symkey, symkey_payload));
+ LINK_SLIST(authfreekeys, sk, llink.f);
+ authnumkeys--;
+ authnumfreekeys++;
+}
+
+
+/*
+ * auth_findkey - find a key in the hash table
+ */
+struct savekey *
+auth_findkey(
+ keyid_t id
+ )
+{
+ symkey * sk;
+
+ for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) {
+ if (id == sk->keyid) {
+ return sk;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+#if 0
+
+/*
+ * auth_havekey - return TRUE if the key id is zero or known
+ */
+int
+auth_havekey(
+ KEY_CACHE *p_cache,
+ keyid_t id
+ )
+{
+ symkey * sk;
+
+ if (0 == id || p_cache->keyid == id) {
+ return TRUE;
+ }
+
+ for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) {
+ if (id == sk->keyid) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+#endif
+
+
+
+/*
+ * authhavekey - return TRUE and cache the key, if zero or both known
+ * and trusted.
+ */
+int
+authhavekey(
+ KEY_CACHE *p_cache,
+ keyid_t id
+ )
+{
+ symkey * sk;
+
+ authkeylookups++;
+ if (0 == id || p_cache->keyid == id) {
+ return TRUE;
+ }
+
+ /*
+ * Seach the bin for the key. If found and the key type
+ * is zero, somebody marked it trusted without specifying
+ * a key or key type. In this case consider the key missing.
+ */
+ authkeyuncached++;
+ for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) {
+ if (id == sk->keyid) {
+ if (0 == sk->type) {
+ authkeynotfound++;
+ return FALSE;
+ }
+ break;
+ }
+ }
+
+ /*
+ * If the key is not found, or if it is found but not trusted,
+ * the key is not considered found.
+ */
+ if (NULL == sk) {
+ authkeynotfound++;
+ return FALSE;
+ }
+ if (!(KEY_TRUSTED & sk->flags)) {
+ authnokey++;
+ return FALSE;
+ }
+
+ /*
+ * The key is found and trusted. Initialize the key cache.
+ * TODO: Check if protection (locking) is required.
+ * Instead of duplicating the cached members in 'sk' we could
+ * make KEY_CACHE a sub-structure.
+ */
+ p_cache->keyid = sk->keyid;
+ p_cache->type = sk->type;
+ p_cache->flags = sk->flags;
+ p_cache->secret = sk->secret;
+ p_cache->secretsize = sk->secretsize;
+
+ return TRUE;
+}
+
+
+/*
+ * authtrust - declare a key to be trusted/untrusted
+ */
+void
+authtrust(
+ KEY_CACHE *p_cache,
+ keyid_t id,
+ u_long trust
+ )
+{
+ symkey ** bucket;
+ symkey * sk;
+ u_long lifetime;
+
+ /*
+ * Search bin for key; if it does not exist and is untrusted,
+ * forget it.
+ */
+ bucket = &key_hash[KEYHASH(id)];
+ for (sk = *bucket; sk != NULL; sk = sk->hlink) {
+ if (id == sk->keyid)
+ break;
+ }
+ if (!trust && NULL == sk)
+ return;
+
+ /*
+ * There are two conditions remaining. Either it does not
+ * exist and is to be trusted or it does exist and is or is
+ * not to be trusted.
+ */
+ if (sk != NULL) {
+ if (p_cache->keyid == id) {
+ p_cache->flags = 0;
+ p_cache->keyid = 0;
+ }
+
+ /*
+ * Key exists. If it is to be trusted, say so and
+ * update its lifetime.
+ */
+ if (trust > 0) {
+ sk->flags |= KEY_TRUSTED;
+ if (trust > 1)
+ sk->lifetime = current_time + trust;
+ else
+ sk->lifetime = 0;
+ return;
+ }
+
+ /* No longer trusted, return it to the free list. */
+ freesymkey(sk, bucket);
+ return;
+ }
+
+ /*
+ * keyid is not present, but the is to be trusted. We allocate
+ * a new key, but do not specify a key type or secret.
+ */
+ if (trust > 1) {
+ lifetime = current_time + trust;
+ } else {
+ lifetime = 0;
+ }
+ allocsymkey(bucket, id, KEY_TRUSTED, 0, lifetime, 0, NULL);
+}
+
+
+/*
+ * authistrusted - determine whether a key is trusted
+ */
+int
+authistrusted(
+ KEY_CACHE *p_cache,
+ keyid_t keyno
+ )
+{
+ symkey * sk;
+ symkey ** bucket;
+
+ if (keyno == p_cache->keyid)
+ return !!(KEY_TRUSTED & p_cache->flags);
+
+ authkeyuncached++;
+ bucket = &key_hash[KEYHASH(keyno)];
+ for (sk = *bucket; sk != NULL; sk = sk->hlink) {
+ if (keyno == sk->keyid)
+ break;
+ }
+ if (NULL == sk || !(KEY_TRUSTED & sk->flags)) {
+ authkeynotfound++;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+
+void
+MD5auth_setkey(
+ KEY_CACHE *p_cache,
+ keyid_t keyno,
+ int keytype,
+ const u_char *key,
+ int len
+ )
+{
+ symkey * sk;
+ symkey ** bucket;
+ u_char * secret;
+ size_t secretsize;
+
+ DEBUG_ENSURE(keytype <= USHRT_MAX);
+ DEBUG_ENSURE(len < 4 * 1024);
+ len = max(0, len);
+ /*
+ * See if we already have the key. If so just stick in the
+ * new value.
+ */
+ bucket = &key_hash[KEYHASH(keyno)];
+ for (sk = *bucket; sk != NULL; sk = sk->hlink) {
+ if (keyno == sk->keyid) {
+ sk->type = (u_short)keytype;
+ secretsize = len;
+ sk->secretsize = (u_short)secretsize;
+#ifndef DISABLE_BUG1243_FIX
+ memcpy(sk->secret, key, secretsize);
+#else
+ strlcpy((char *)sk->secret, (const char *)key,
+ secretsize);
+#endif
+ if (p_cache->keyid == keyno) {
+ p_cache->flags = 0;
+ p_cache->keyid = 0;
+ }
+ return;
+ }
+ }
+
+ /*
+ * Need to allocate new structure. Do it.
+ */
+ secretsize = len;
+ secret = emalloc(secretsize);
+#ifndef DISABLE_BUG1243_FIX
+ memcpy(secret, key, secretsize);
+#else
+ strlcpy((char *)secret, (const char *)key, secretsize);
+#endif
+ allocsymkey(bucket, keyno, 0, (u_short)keytype, 0,
+ (u_short)secretsize, secret);
+#ifdef DEBUG
+ if (debug >= 4) {
+ size_t j;
+
+ printf("auth_setkey: key %d type %d len %d ", (int)keyno,
+ keytype, (int)secretsize);
+ for (j = 0; j < secretsize; j++)
+ printf("%02x", secret[j]);
+ printf("\n");
+ }
+#endif
+}
+
+
+/*
+ * auth_delkeys - delete non-autokey untrusted keys, and clear all info
+ * except the trusted bit of non-autokey trusted keys, in
+ * preparation for rereading the keys file.
+ */
+void
+auth_delkeys(void)
+{
+ symkey * sk;
+
+ ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
+ if (sk->keyid > NTP_MAXKEY) { /* autokey */
+ continue;
+ }
+
+ /*
+ * Don't lose info as to which keys are trusted.
+ */
+ if (KEY_TRUSTED & sk->flags) {
+ if (sk->secret != NULL) {
+ memset(sk->secret, '\0', sk->secretsize);
+ free(sk->secret);
+ }
+ sk->secretsize = 0;
+ sk->lifetime = 0;
+ } else {
+ freesymkey(sk, &key_hash[KEYHASH(sk->keyid)]);
+ }
+ ITER_DLIST_END()
+}
+
+
+/*
+ * auth_agekeys - delete keys whose lifetimes have expired
+ */
+void
+auth_agekeys(void)
+{
+ symkey * sk;
+
+ ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
+ if (sk->lifetime > 0 && current_time > sk->lifetime) {
+ freesymkey(sk, &key_hash[KEYHASH(sk->keyid)]);
+ authkeyexpired++;
+ }
+ ITER_DLIST_END()
+ DPRINTF(1, ("auth_agekeys: at %lu keys %lu expired %lu\n",
+ current_time, authnumkeys, authkeyexpired));
+}
+
+
+/*
+ * authencrypt - generate message authenticator
+ *
+ * Returns length of authenticator field, zero if key not found.
+ */
+int
+authencrypt(
+ KEY_CACHE *p_cache,
+ keyid_t keyno,
+ u_int32 * pkt,
+ int length
+ )
+{
+ /*
+ * A zero key identifier means the sender has not verified
+ * the last message was correctly authenticated. The MAC
+ * consists of a single word with value zero.
+ */
+ authencryptions++;
+ pkt[length / 4] = htonl(keyno);
+ if (0 == keyno) {
+ return 4;
+ }
+ if (!authhavekey(p_cache, keyno)) {
+ return 0;
+ }
+
+ //##++++ TODO: This can be simplified. Check cache usage in MD5authencrypt
+ return MD5authencrypt(p_cache, p_cache->type, p_cache->secret, pkt, length);
+}
+
+
+/*
+ * authdecrypt - verify message authenticator
+ *
+ * Returns TRUE if authenticator valid, FALSE if invalid or not found.
+ */
+int
+authdecrypt(
+ KEY_CACHE *p_cache,
+ keyid_t keyno,
+ u_int32 * pkt,
+ int length,
+ int size
+ )
+{
+ /*
+ * A zero key identifier means the sender has not verified
+ * the last message was correctly authenticated. For our
+ * purpose this is an invalid authenticator.
+ */
+ authdecryptions++;
+ if (0 == keyno || !authhavekey(p_cache, keyno) || size < 4) {
+ return FALSE;
+ }
+
+ return MD5authdecrypt(p_cache, p_cache->type, p_cache->secret, pkt, length,
+ size);
+}
+
+
+
+#if 1 // from authreadkeys.c
+
+/*
+ * authreadkeys.c - routines to support the reading of the key file
+ */
+
+#if 0
+#include <config.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "ntp_fp.h"
+#include "ntp.h"
+#include "ntp_syslog.h"
+#include "ntp_stdlib.h"
+
+#ifdef OPENSSL
+#include "openssl/objects.h"
+#include "openssl/evp.h"
+#endif /* OPENSSL */
+#endif
+
+/* Forwards */
+static char *nexttok (char **);
+
+/*
+ * nexttok - basic internal tokenizing routine
+ */
+static char *
+nexttok(
+ char **str
+ )
+{
+ register char *cp;
+ char *starttok;
+
+ cp = *str;
+
+ /*
+ * Space past white space
+ */
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+
+ /*
+ * Save this and space to end of token
+ */
+ starttok = cp;
+ while (*cp != '\0' && *cp != '\n' && *cp != ' '
+ && *cp != '\t' && *cp != '#')
+ cp++;
+
+ /*
+ * If token length is zero return an error, else set end of
+ * token to zero and return start.
+ */
+ if (starttok == cp)
+ return NULL;
+
+ if (*cp == ' ' || *cp == '\t')
+ *cp++ = '\0';
+ else
+ *cp = '\0';
+
+ *str = cp;
+ return starttok;
+}
+
+
+/*
+ * authreadkeys - (re)read keys from a file.
+ */
+int
+authreadkeys(
+ const char *file
+ )
+{
+ KEY_CACHE key_cache = { 0 };
+ FILE *fp;
+ char *line;
+ char *token;
+ keyid_t keyno;
+ int keytype;
+ char buf[512]; /* lots of room for line */
+ u_char keystr[32]; /* Bug 2537 */
+ int len;
+ int j;
+
+ /*
+ * Open file. Complain and return if it can't be opened.
+ */
+ fp = fopen(file, "r");
+ if (fp == NULL) {
+#if 1 // NOTE: modification by martin
+ mbglog( LOG_ERR, "Failed to read file %s: %s",
+ file, strerror( errno ) );
+#else
+ msyslog(LOG_ERR, "authreadkeys: file %s: %m",
+ file);
+#endif
+ return (0);
+ }
+ INIT_SSL();
+
+ /*
+ * Remove all existing keys
+ */
+ auth_delkeys();
+
+ /*
+ * Now read lines from the file, looking for key entries
+ */
+ while ((line = fgets(buf, sizeof buf, fp)) != NULL) {
+ token = nexttok(&line);
+ if (token == NULL)
+ continue;
+
+ /*
+ * First is key number. See if it is okay.
+ */
+ keyno = atoi(token);
+ if (keyno == 0) {
+ msyslog(LOG_ERR,
+ "authreadkeys: cannot change key %s", token);
+ continue;
+ }
+
+ if (keyno > NTP_MAXKEY) {
+ msyslog(LOG_ERR,
+ "authreadkeys: key %s > %d reserved for Autokey",
+ token, NTP_MAXKEY);
+ continue;
+ }
+
+ /*
+ * Next is keytype. See if that is all right.
+ */
+ token = nexttok(&line);
+ if (token == NULL) {
+ msyslog(LOG_ERR,
+ "authreadkeys: no key type for key %d", keyno);
+ continue;
+ }
+#ifdef OPENSSL
+ /*
+ * The key type is the NID used by the message digest
+ * algorithm. There are a number of inconsistencies in
+ * the OpenSSL database. We attempt to discover them
+ * here and prevent use of inconsistent data later.
+ */
+ keytype = keytype_from_text(token, NULL);
+ if (keytype == 0) {
+ msyslog(LOG_ERR,
+ "authreadkeys: invalid type for key %d", keyno);
+ continue;
+ }
+ if (EVP_get_digestbynid(keytype) == NULL) {
+ msyslog(LOG_ERR,
+ "authreadkeys: no algorithm for key %d", keyno);
+ continue;
+ }
+#else /* !OPENSSL follows */
+
+ /*
+ * The key type is unused, but is required to be 'M' or
+ * 'm' for compatibility.
+ */
+ if (!(*token == 'M' || *token == 'm')) {
+ msyslog(LOG_ERR,
+ "authreadkeys: invalid type for key %d", keyno);
+ continue;
+ }
+ keytype = KEY_TYPE_MD5;
+#endif /* !OPENSSL */
+
+ /*
+ * Finally, get key and insert it. If it is longer than 20
+ * characters, it is a binary string encoded in hex;
+ * otherwise, it is a text string of printable ASCII
+ * characters.
+ */
+ token = nexttok(&line);
+ if (token == NULL) {
+ msyslog(LOG_ERR,
+ "authreadkeys: no key for key %d", keyno);
+ continue;
+ }
+ len = strlen(token);
+ if (len <= 20) { /* Bug 2537 */
+ MD5auth_setkey(&key_cache, keyno, keytype, (u_char *)token, len);
+ } else {
+ char hex[] = "0123456789abcdef";
+ u_char temp;
+ char *ptr;
+ int jlim;
+
+ jlim = min(len, 2 * sizeof(keystr));
+ for (j = 0; j < jlim; j++) {
+ ptr = strchr(hex, tolower(token[j]));
+ if (ptr == NULL)
+ break; /* abort decoding */
+ temp = (u_char)(ptr - hex);
+ if (j & 1)
+ keystr[j / 2] |= temp;
+ else
+ keystr[j / 2] = temp << 4;
+ }
+ if (j < jlim) {
+ msyslog(LOG_ERR,
+ "authreadkeys: invalid hex digit for key %d", keyno);
+ continue;
+ }
+ MD5auth_setkey(&key_cache, keyno, keytype, keystr, jlim / 2);
+ }
+ }
+ fclose(fp);
+ return (1);
+}
+
+#endif // from authreadkeys.c
+
+
+
+
+/*HDR*/
+/**
+ * @brief Check authentication of a received NTP packet
+ *
+ * @param[in,out] p_cache A ::KEY_CACHE structure use to cache keys
+ * @param[in] p_rcv ::NTP_PACKET_INFO structure containing a received packet
+ *
+ * @return one of the ::MBG_NTP_AUTH_CODES
+ */
+int mbg_ntp_auth_decrypt( KEY_CACHE *p_cache, NTP_PACKET_INFO *p_rcv )
+{
+ keyid_t skeyid;
+ int mac_len = get_mac_len( p_rcv );
+ int rc;
+
+ if ( mac_len < sizeof( NTP_KEY_ID ) )
+ return MBG_NTP_AUTH_NONE;
+
+ skeyid = htonl( p_rcv->packet.mac.key_id );
+
+ if ( skeyid == 0 ) // received a crypto NACK
+ return MBG_NTP_AUTH_NACK;
+
+ rc = authdecrypt( p_cache, skeyid, (u_int32 *) &p_rcv->packet,
+ NTP_BASE_PACKET_SIZE, mac_len );
+
+ return ( rc == 0 ) ? MBG_NTP_AUTH_FAIL : MBG_NTP_AUTH_OK;
+
+} // mbg_ntp_auth_decrypt
+
+
+
+/*HDR*/
+/**
+ * @brief Generate signature for a packet to be sent
+ *
+ * @param[in,out] p_cache A ::KEY_CACHE structure use to cache keys
+ * @param[in,out] p_xmt ::NTP_PACKET_INFO structure containing the base packet to transmit
+ * @param[in] key_id A valid key ID, or 0 in case a crypto NACK must be sent
+ *
+ * @return one of the ::MBG_NTP_AUTH_CODES
+ */
+int mbg_ntp_auth_encrypt( KEY_CACHE *p_cache, NTP_PACKET_INFO *p_xmt, NTP_KEY_ID key_id )
+{
+ int auth_len;
+
+ if ( key_id == 0 ) // must send crypto NACK
+ {
+ p_xmt->packet.mac.key_id = 0; // no need for htonl() with 0
+ p_xmt->len += sizeof( p_xmt->packet.mac.key_id );
+ return MBG_NTP_AUTH_NACK;
+ }
+
+ auth_len = authencrypt( p_cache, key_id, (uint32_t *) &p_xmt->packet, p_xmt->len );
+
+ p_xmt->len += auth_len;
+
+ if ( auth_len >= sizeof( NTP_KEY_ID ) )
+ return MBG_NTP_AUTH_OK;
+
+ return MBG_NTP_AUTH_FAIL;
+
+} // mbg_ntp_auth_encrypt
+
+
+
+/*HDR*/
+int mbg_ntp_read_conf_file( const char *fn )
+{
+ FILE *fp = fopen( fn, "rt" );
+
+ if ( fp == NULL )
+ {
+ int this_errno = errno;
+
+ mbglog( LOG_WARNING, "Failed to read NTP config file %s: %s",
+ fn, strerror( this_errno ) );
+ return -this_errno;
+ }
+
+ for (;;)
+ {
+ char s[256];
+ char *line = fgets( s, sizeof( s ), fp );
+ char *token;
+
+ if ( line == NULL ) // nothing could be read
+ break;
+
+ token = nexttok( &line );
+
+ if ( token == NULL )
+ continue;
+
+ if ( strcmp( token, "keys" ) == 0 )
+ {
+ token = nexttok( &line );
+
+ if ( token )
+ authreadkeys( token ); //##++ TODO: else error
+
+ continue;
+ }
+
+ if ( strcmp( token, "trustedkey" ) == 0 )
+ {
+ while ( ( token = nexttok( &line ) ) != NULL )
+ mbg_ntp_auth_trust_key( atol( token ), 1 );
+
+ continue;
+ }
+
+ } // for (;;)
+
+ fclose( fp );
+
+ return 0;
+
+} // mbg_ntp_read_conf_file
+
+
+
+/*HDR*/
+int mbg_ntp_auth_add_key( NTP_KEY_ID key_id, const char *key_type_str, const char *secret )
+{
+ KEY_CACHE key_cache = { 0 };
+ int key_type = keytype_from_text( key_type_str, NULL ); // usually type 'M' is read from the keys file
+
+ if ( key_type == 0 )
+ {
+ //##++++ error: key type invalid
+ return 0;
+ }
+
+ // The key type is the NID used by the message digest algorithm.
+ // We check if it is supported.
+ if ( EVP_get_digestbynid( key_type ) == NULL )
+ {
+ //##++++ error: key type not supported by openSSL
+ return 0;
+ }
+
+ // NOTE: the original code in authreadkeys() implementes a special handling
+ // if the length of the key hash is > 20. See also NTP bug #2537 for details.
+ MD5auth_setkey( &key_cache, key_id, key_type, (u_char *) secret, strlen( secret ) );
+
+ return 1;
+
+} // mbg_ntp_auth_add_key
+
+
+
+/*HDR*/
+int mbg_ntp_auth_trust_key( long key_id, int trust )
+{
+ KEY_CACHE key_cache = { 0 };
+
+ if ( key_id == 0 ) // unspecified
+ {
+ mbglog( LOG_WARNING, "trusted key ID 0 is invalid" );
+ return -1;
+ }
+
+ if ( key_id > NTP_MAXKEY ) // reserved for autokey
+ {
+ mbglog( LOG_WARNING, "trusted key IDs > %i are reserved for autokey", NTP_MAXKEY );
+ return -2;
+ }
+
+ authtrust( &key_cache, (NTP_KEY_ID) key_id, trust );
+
+ return 0; // success
+
+} // mbg_ntp_auth_trust_key
+
+
+
+/*HDR*/
+void mbg_ntp_auth_init( void )
+{
+ INIT_SSL();
+ init_auth();
+
+ auth_prealloc_symkeys( 0 ); //##++++ TODO or the number of trusted keys we have determined before?
+
+} // mbg_ntp_auth_init
+
+
+
+#if DEBUG_MBG_NTP_AUTH
+
+/*HDR*/
+int mbg_ntp_auth_test( keyid_t key_id )
+{
+ // test signature with known packet
+ KEY_CACHE key_cache = { 0 };
+ uint8_t x[sizeof( NTP_PACKET )] = { 0 };
+ NTP_PACKET *p = (NTP_PACKET *) x;
+ uint8_t *cp;
+ int i;
+ int rc;
+
+ int auth_len = authencrypt( &key_cache, key_id, (uint32_t *) x, NTP_BASE_PACKET_SIZE );
+
+ printf( "Test auth: key %i, result len %i\n", key_id, auth_len );
+
+ printf( "packet:" );
+
+ for ( i = 0, cp = x; i < NTP_BASE_PACKET_SIZE; i++, cp++ )
+ printf( " %02X", *cp );
+
+ printf( "\n" );
+
+ printf( "key & hash:" );
+
+ for ( i = 0; i < auth_len; i++, cp++ )
+ printf( " %02X", *cp );
+
+ printf( "\n" );
+
+ rc = authdecrypt( &key_cache, key_id, (uint32_t *) p, NTP_BASE_PACKET_SIZE, auth_len );
+
+ return rc;
+
+} // mbg_ntp_auth_test
+
+#endif // DEBUG_MBG_NTP_AUTH
+
+
+
+
diff --git a/mbglib/common/mbg_ntp_auth.h b/mbglib/common/mbg_ntp_auth.h
new file mode 100755
index 0000000..5476df5
--- /dev/null
+++ b/mbglib/common/mbg_ntp_auth.h
@@ -0,0 +1,173 @@
+
+/**************************************************************************
+ *
+ * $Id: mbg_ntp_auth.h 1.3 2018/07/31 14:03:38 martin REL_M $
+ *
+ * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
+ *
+ * Description:
+ * Definitions and prototypes used with mbg_ntp_auth.c
+ *
+ * -----------------------------------------------------------------------
+ * $Log: mbg_ntp_auth.h $
+ * Revision 1.3 2018/07/31 14:03:38 martin
+ * Fixed clang compiler warning.
+ * Revision 1.2 2014/09/24 08:56:27 martin
+ * Introduced a key cache structure which can be used to make
+ * the key cache thread-safe.
+ * Updated function prototypes.
+ * Revision 1.1 2014/09/10 15:37:57 martin
+ * Initial revision.
+ *
+ **************************************************************************/
+
+#ifndef _MBG_NTP_AUTH_H
+#define _MBG_NTP_AUTH_H
+
+
+/* Other headers to be included */
+
+#include <mbgntp.h>
+
+#define OPENSSL // use openSSL for MD5 directly
+
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
+
+#ifdef _MBG_NTP_AUTH
+ #define _ext
+ #define _DO_INIT
+#else
+ #define _ext extern
+#endif
+
+
+
+#if defined( _USE_PACK )
+// not used here
+// #pragma pack( 1 ) // set byte alignment
+// #define _USING_BYTE_ALIGNMENT
+#endif
+
+/* Start of header body */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined( DEBUG_MBG_NTP_AUTH )
+ #if defined( DEBUG )
+ #define DEBUG_MBG_NTP_AUTH 0 // Set != 0 for debug
+ #else
+ #define DEBUG_MBG_NTP_AUTH 0 // always 0
+ #endif
+#endif
+
+
+#define NTP_COMPAT 1
+
+#if NTP_COMPAT
+ typedef uint32_t u_int32;
+#endif
+
+typedef uint32_t keyid_t; /* cryptographic key ID */
+#define NTP_MAXKEY 65535 /* maximum symmetric key ID (ntp_crypto.h) */
+
+
+/* from ntp.h */
+#define LEN_PKT_NOMAC (12 * sizeof(u_int32)) /* min header length */
+#define MIN_MAC_LEN (1 * sizeof(u_int32)) /* crypto_NAK */
+#define MAX_MD5_LEN (5 * sizeof(u_int32)) /* MD5 */
+#define MAX_MAC_LEN (6 * sizeof(u_int32)) /* SHA */
+
+
+
+/*
+ * The key cache. We cache the last key we looked at here.
+ */
+#if 1
+
+// A structure holding key cache information.
+// Useful to make the auth functions thread-safe.
+
+typedef struct
+{
+ keyid_t keyid; /* key identifier */
+ u_char *secret; /* secret */
+ u_short secretsize; /* secret length */
+ int type; /* OpenSSL digest NID */
+ u_short flags; /* flags that wave */
+
+} KEY_CACHE;
+
+#else
+
+// The original code from the NTP sources
+keyid_t cache_keyid; /* key identifier */
+u_char *cache_secret; /* secret */
+u_short cache_secretsize; /* secret length */
+int cache_type; /* OpenSSL digest NID */
+u_short cache_flags; /* flags that wave */
+
+#endif
+
+
+
+
+
+
+/* function prototypes: */
+
+/* ----- function prototypes begin ----- */
+
+/* This section was generated automatically */
+/* by MAKEHDR, do not remove the comments. */
+
+ /**
+ * @brief Check authentication of a received NTP packet
+ *
+ * @param[in,out] p_cache A ::KEY_CACHE structure use to cache keys
+ * @param[in] p_rcv ::NTP_PACKET_INFO structure containing a received packet
+ *
+ * @return one of the ::MBG_NTP_AUTH_CODES
+ */
+ int mbg_ntp_auth_decrypt( KEY_CACHE *p_cache, NTP_PACKET_INFO *p_rcv ) ;
+
+ /**
+ * @brief Generate signature for a packet to be sent
+ *
+ * @param[in,out] p_cache A ::KEY_CACHE structure use to cache keys
+ * @param[in,out] p_xmt ::NTP_PACKET_INFO structure containing the base packet to transmit
+ * @param[in] key_id A valid key ID, or 0 in case a crypto NACK must be sent
+ *
+ * @return one of the ::MBG_NTP_AUTH_CODES
+ */
+ int mbg_ntp_auth_encrypt( KEY_CACHE *p_cache, NTP_PACKET_INFO *p_xmt, NTP_KEY_ID key_id ) ;
+
+ int mbg_ntp_read_conf_file( const char *fn ) ;
+ int mbg_ntp_auth_add_key( NTP_KEY_ID key_id, const char *key_type_str, const char *secret ) ;
+ int mbg_ntp_auth_trust_key( long key_id, int trust ) ;
+ void mbg_ntp_auth_init( void ) ;
+ int mbg_ntp_auth_test( keyid_t key_id ) ;
+
+/* ----- 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 /* _MBG_NTP_AUTH_H */
+
diff --git a/mbglib/common/mbg_ntp_test_util.c b/mbglib/common/mbg_ntp_test_util.c
index 52c04ee..5623668 100755
--- a/mbglib/common/mbg_ntp_test_util.c
+++ b/mbglib/common/mbg_ntp_test_util.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbg_ntp_test_util.c 1.9 2018/03/09 09:55:16 martin REL_M $
+ * $Id: mbg_ntp_test_util.c 1.11 2018/07/31 16:06:22 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,11 @@
*
* -----------------------------------------------------------------------
* $Log: mbg_ntp_test_util.c $
+ * Revision 1.11 2018/07/31 16:06:22 martin
+ * New function ntp_mode_name_str().
+ * Improved printing of packets.
+ * Revision 1.10 2018/07/31 12:12:13 martin
+ * More POSIX compatibility.
* Revision 1.9 2018/03/09 09:55:16 martin
* Improved printing of refid using functions from new module mbgntp.c.
* Moved snprint_ntp_prec() to mbgntp.c.
@@ -55,13 +60,32 @@
#include <ctype.h>
#include <time.h>
-#if defined( MBG_TGT_POSIX )
- #include <values.h>
-#elif defined( MBG_TGT_WIN32 )
- #include <float.h>
- #define MAXDOUBLE DBL_MAX
+#if defined( MBG_TGT_LINUX )
+ #include <limits.h> // LONG_MIN, LONG_MAX
+#elif defined( MBG_TGT_BSD )
+ #include <sys/limits.h> // LONG_MIN, LONG_MAX
#endif
+#include <float.h> // DBL_MIN, DBL_MAX
+
+
+
+/*HDR*/
+/**
+ * @brief Return a string associated with a packet mode
+ *
+ * @param[in] mode The mode number from an NTP packet, see ::NTP_MODES
+ *
+ * @return An associated mode name string
+ */
+const char *ntp_mode_name_str( int mode )
+{
+ static const char *mode_name_strs[N_NTP_MODES] = NTP_MODE_NAME_STRS;
+
+ return ( mode < N_NTP_MODES ) ? mode_name_strs[mode] : "(unknown)";
+
+}; // ntp_mode_name_str
+
/*HDR*/
@@ -74,14 +98,14 @@ void reset_query_stats( QUERY_STATS *p )
{
memset( p, 0, sizeof( *p ) );
- p->turnaround.min = MAXLONG;
- p->turnaround.max = -MAXLONG;
- p->latency.min = MAXDOUBLE;
- p->latency.max = -MAXDOUBLE;
- p->ntp_delay.min = MAXDOUBLE;
- p->ntp_delay.max = -MAXDOUBLE;
- p->ntp_offs.min = MAXDOUBLE;
- p->ntp_offs.max = -MAXDOUBLE;
+ p->turnaround.min = LONG_MAX;
+ p->turnaround.max = LONG_MIN;
+ p->latency.min = DBL_MAX;
+ p->latency.max = DBL_MIN;
+ p->ntp_delay.min = DBL_MAX;
+ p->ntp_delay.max = DBL_MIN;
+ p->ntp_offs.min = DBL_MAX;
+ p->ntp_offs.max = DBL_MIN;
} // reset_query_stats
@@ -214,13 +238,11 @@ void print_ntp_packet( const char *msg, const NTP_PACKET_INFO *p, int print_date
snprint_ntp_prec( prec_str, sizeof( prec_str ), pkt_precision );
- printf( "%s\n", msg );
+ printf( "%s: mode %u (%s)\n", msg, pbp->flags.mode,
+ ntp_mode_name_str( pbp->flags.mode ) );
printf( INDENT
- "mode %u, version %u, leap %u, "
- "stratum %u, poll %u, prec %i (%s)\n"
- ,
- pbp->flags.mode,
+ "version %u, leap %u, stratum %u, poll %u, prec %i (%s)\n",
pbp->flags.version,
pbp->flags.leap_ind,
pbp->flags.stratum,
@@ -489,13 +511,13 @@ void print_ntp_results( const NTP_RESULTS *p_rslt, const NTP_PACKET_INFO *p_req,
int print_date_time, int verbose )
{
if ( p_req )
- print_ntp_packet( "Request packet:", p_req, print_date_time, verbose );
+ print_ntp_packet( "Request packet", p_req, print_date_time, verbose );
if ( p_rcv )
{
double d;
bool smearing_active;
- print_ntp_packet( "Response packet:", p_rcv, print_date_time, verbose );
+ print_ntp_packet( "Response packet", p_rcv, print_date_time, verbose );
smearing_active = leap_smearing_active( &p_rcv->packet.base.refid, &d );
if ( verbose || smearing_active )
{
@@ -524,9 +546,9 @@ void print_ntp_results( const NTP_RESULTS *p_rslt, const NTP_PACKET_INFO *p_req,
printf( "Authentication: %s\n\n", cp );
print_query_stats( p_rslt, p_stats, 17, 10, 1e6 );
- }
- printf( "\n" );
+ printf( "\n" );
+ }
} // print_ntp_results
diff --git a/mbglib/common/mbg_tgt.h b/mbglib/common/mbg_tgt.h
index 0a268e6..de8b50e 100755
--- a/mbglib/common/mbg_tgt.h
+++ b/mbglib/common/mbg_tgt.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbg_tgt.h 1.38 2017/08/08 13:07:31 martin REL_M $
+ * $Id: mbg_tgt.h 1.40 2018/07/02 16:57:49 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,6 +11,23 @@
*
* -----------------------------------------------------------------------
* $Log: mbg_tgt.h $
+ * Revision 1.40 2018/07/02 16:57:49 martin
+ * Removed obsolete define MBG_USE_MM_IO_FOR_PCI.
+ * Revision 1.39 2018/06/25 10:52:00 martin
+ * Support MBG_TGT_NO_TGT.
+ * Default settings for KERNEL_HAS_BOOL and KERNEL_HAS_TRUE_FALSE
+ * for Linux can be overridden by project settings.
+ * Renamed MBG_PRE64_PREFIX to MBG_PRI_64_PREFIX.
+ * MBG_PRI_64_PREFIX_L or MBG_PRI_64_PREFIX_LL can be used
+ * to override the defaults with specific project settings.
+ * MBG_TGT_HAS_DEV_FN is supported on Windows, but
+ * MBG_TGT_HAS_DEV_FN_BASE is not supported.
+ * Enhanced debug support for Windows kernel drivers.
+ * Include limits.h under Windows.
+ * Defined MBG_TGT_MISSING_STRUCT_TIMESPEC for Borland C.
+ * Defined __func__ for BC 5 and for DOS, and provide a
+ * common default declaration..
+ * Updated some comments.
* Revision 1.38 2017/08/08 13:07:31 martin
* Proper fix for PRId64 and others.
* Define _CRT_SECURE_NO_WARNINGS only if not already defined.
@@ -197,6 +214,10 @@
/* Other headers to be included */
+#ifdef MBG_TGT_NO_TGT
+ #include <mbg_no_tgt.h>
+#else
+
#ifdef _MBG_TGT
#define _ext
#else
@@ -210,6 +231,20 @@
extern "C" {
#endif
+// The prefix required in a printf() format string to print an
+// int64_t type (i.e. "%li", "%lli", "I64i", etc.) may vary depending
+// on the compiler type and version, and the associated run time library.
+// For user space applications this is usually defined in the header
+// files provided by the build environment, but for kernel code there
+// are often no such defines, but there are some commonly used defaults.
+// This is a hack that can be used to override these defaults in the
+// project settings for kernel code, e.g. in the Makefile.
+#if defined( MBG_PRI_64_PREFIX_L )
+ #define MBG_PRI_64_PREFIX "l"
+#elif defined( MBG_PRI_64_PREFIX_LL )
+ #define MBG_PRI_64_PREFIX "ll"
+#endif
+
#if defined( _CVI_ )
@@ -258,7 +293,7 @@ extern "C" {
#elif defined( RC_INVOKED )
- //MS resource compiler
+ // MS resource compiler
#define MBG_TGT_WIN32
#elif defined( __WINDOWS_386__ )
@@ -364,11 +399,18 @@ extern "C" {
#define _CRT_SECURE_NO_WARNINGS 1
#endif
+ #include <limits.h>
+
+ #define MBG_TGT_HAS_DEV_FN 1
+ #define MBG_TGT_HAS_DEV_FN_BASE 0
+
#endif
// Some definitions depending on the build environment ...
+#define FUNC_UNKNOWN "func_???"
+
#if defined( __GNUC__ ) || defined( __clang__ )
#if defined( __clang__ )
@@ -400,7 +442,6 @@ extern "C" {
#elif defined( __sparc__ )
#define MBG_ARCH_SPARC
- #define MBG_USE_MM_IO_FOR_PCI 1
#define _NO_USE_PACK_INTF
@@ -425,17 +466,40 @@ extern "C" {
#endif
// The 'bool' type is supported by the vanilla Linux kernel 2.6.19 and later.
- // However, looks like at least the RedHat folks have backported this to 2.6.18,
- // so KERNEL_HAS_BOOL can be defined to avoid a compiler error due to
- // duplicate definition.
- #if ( ( LINUX_VERSION_CODE < KERNEL_VERSION( 2, 6, 19 ) ) && !defined( KERNEL_HAS_BOOL ) )
- typedef _Bool bool;
- #define bool bool
+ #if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2, 6, 19 ) )
+
+ // However, looks like at least the RedHat folks have backported this
+ // to 2.6.18, so KERNEL_HAS_BOOL can be defined to avoid a compiler error
+ // due to a duplicate definition.
+ #if !defined( KERNEL_HAS_BOOL )
+ typedef _Bool bool;
+ #define bool bool
+ #endif
+
+ // Similar for 'true' and 'false'.
+ #if !defined( KERNEL_HAS_TRUE_FALSE )
+ enum
+ {
+ false,
+ true
+ };
+ #define falso false
+ #define true true
+ #endif
+
#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.
+ // String formatter codes like "PRIi64" for int64_t types
+ // don't seem to be defined in Linux kernel mode, so we
+ // define the required "ll" or "l" modifier here as a hack.
+ // Code below uses this to define appropriate "PRIi64"-like
+ // definitions as "lli" or "li".
+ #if !defined( MBG_PRI_64_PREFIX )
+ // Please note that e.g. Linux 2.6.16 on Itanium (ia64)
+ // with gcc 4.1.2 expects "%li" to print an int64_t.
+ // This may be a bug in the specific gcc version, though.
+ #define MBG_PRI_64_PREFIX "ll"
+ #endif
#else
@@ -451,7 +515,8 @@ extern "C" {
#endif
- #define MBG_TGT_HAS_DEV_FN 1
+ #define MBG_TGT_HAS_DEV_FN 1
+ #define MBG_TGT_HAS_DEV_FN_BASE 1
#elif defined( MBG_TGT_BSD )
@@ -463,7 +528,19 @@ extern "C" {
#include <stdbool.h>
#endif
- #define MBG_TGT_HAS_DEV_FN 1
+ #define MBG_TGT_HAS_DEV_FN 1
+ #define MBG_TGT_HAS_DEV_FN_BASE 1
+
+ #if defined( MBG_TGT_FREEBSD ) && defined( MBG_TGT_KERNEL )
+ #if !defined( MBG_PRI_64_PREFIX )
+ // String formatter codes like "PRIi64" for int64_t types
+ // don't seem to be defined in FreeBSD kernel mode, so we
+ // define the required "ll" or "l" modifier here as a hack.
+ // Code below uses this to define appropriate "PRIi64"-like
+ // definitions as "lli" or "li".
+ #define MBG_PRI_64_PREFIX "l"
+ #endif
+ #endif
#elif defined( MBG_TGT_QNX_NTO ) // QNX 6.x (Neutrino)
@@ -513,7 +590,7 @@ extern "C" {
// 1500: MSVC++ 9.0 (Visual Studio 2008)
// 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)
+ // 1300: MSVC++ 7.0 (Visual Studio .NET 2002, Windows XP SP1 DDK / DDK 2600)
// 1200: MSVC++ 6.0
// 1100: MSVC++ 5.0
@@ -536,7 +613,7 @@ extern "C" {
#elif ( _MSC_VER >= 1310 )
#error 1310: MSVC++ 7.1 (Visual Studio .NET 2003, Windows Server 2003 DDK)
#elif ( _MSC_VER >= 1300 )
- #error 1300: MSVC++ 7.0 (Visual Studio .NET 2002, Windows XP SP1 DDK)
+ #error 1300: MSVC++ 7.0 (Visual Studio .NET 2002, Windows XP SP1 DDK / DDK 2600)
#elif ( _MSC_VER >= 1200 )
#error 1200: MSVC++ 6.0
#elif ( _MSC_VER >= 1100 )
@@ -561,17 +638,17 @@ extern "C" {
#endif
#endif
- #if ( _MSC_VER >= 1600 )
+ #if ( _MSC_VER >= 1600 ) // TODO Eventually even 1600 doesn't support this.
#include <stdint.h>
#include <inttypes.h>
#define MBG_TGT_HAS_EXACT_SIZE_TYPES 1
#if !defined( PRId64 )
- #define MBG_PRE64_PREFIX "I64"
+ #define MBG_PRI_64_PREFIX "I64"
#endif
#else
#define MBG_TGT_HAS_INT_8_16_32 1
- #define MBG_PRE64_PREFIX "I64"
+ #define MBG_PRI_64_PREFIX "I64"
#endif
#if !defined( __cplusplus )
@@ -590,7 +667,7 @@ extern "C" {
#if ( _MSC_VER >= 1300 )
#define __func__ __FUNCTION__
#else
- #define __func__ "func_???"
+ #define __func__ FUNC_UNKNOWN
#endif
// The "deprecated" attribute should be supported since Visual Studio 2005,
@@ -693,16 +770,18 @@ extern "C" {
#endif
#elif ( __BORLANDC__ >= 0x0550 )
#define MBG_TGT_HAS_INT_8_16_32 1
- #define MBG_PRE64_PREFIX "I64"
+ #define MBG_PRI_64_PREFIX "I64"
#if !defined( __cplusplus )
#define MBG_TGT_MISSING_BOOL_TYPE 1
#endif
+ #define __func__ FUNC_UNKNOWN
#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_STRUCT_TIMESPEC 1
+ #define __func__ __FILE__ ":" STRINGIFY(__LINE__)
typedef int ssize_t;
#endif
@@ -710,6 +789,8 @@ extern "C" {
#define MBG_TGT_HAS_WCHAR_T defined( MBG_TGT_WIN32 )
+ #define MBG_TGT_MISSING_STRUCT_TIMESPEC 1
+
#if defined( __cplusplus )
#define __mbg_inline inline // standard C++ syntax
#elif ( __BORLANDC__ > 0x410 ) // BC3.1 defines 0x410 !
@@ -755,19 +836,19 @@ extern "C" {
#endif
-// If the build environment doesn't provide a inttypes.h file
+// If the build environment doesn't provide an inttypes.h file
// with print format specifiers for 64 bit fixed size types
-// then MBG_PRE64_PREFIX should be defined which is used
+// then MBG_PRI_64_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"
+#if defined( MBG_PRI_64_PREFIX )
+ #define PRIi64 MBG_PRI_64_PREFIX "i"
+ #define PRId64 MBG_PRI_64_PREFIX "d"
+ #define PRIo64 MBG_PRI_64_PREFIX "o"
+ #define PRIu64 MBG_PRI_64_PREFIX "u"
+ #define PRIx64 MBG_PRI_64_PREFIX "x"
+ #define PRIX64 MBG_PRI_64_PREFIX "X"
#endif
#if !defined( __GNUC__ ) && !defined( __attribute__ )
@@ -793,8 +874,17 @@ extern "C" {
#if defined( _KDD_ )
#define MBG_TGT_KERNEL
+
#include <ntddk.h>
+ #if defined( DBG ) && DBG
+ #if defined( KDD_DEBUG_LVL )
+ #define DEBUG KDD_DEBUG_LVL
+ #else
+ #define DEBUG 1
+ #endif
+ #endif
+
#define _MBG_API
#else
// This must not be used for kernel drivers.
@@ -926,14 +1016,14 @@ extern "C" {
#define MBG_INVALID_PORT_HANDLE MBG_INVALID_HANDLE
#endif
-#if !defined( MBG_USE_MM_IO_FOR_PCI )
- #define MBG_USE_MM_IO_FOR_PCI 0
-#endif
-
#if !defined( MBG_TGT_HAS_DEV_FN )
#define MBG_TGT_HAS_DEV_FN 0
#endif
+#if !defined( MBG_TGT_HAS_DEV_FN_BASE )
+ #define MBG_TGT_HAS_DEV_FN_BASE 0
+#endif
+
#if defined( MBG_TGT_MISSING_STRUCT_TIMESPEC )
#include <time.h>
@@ -997,4 +1087,6 @@ extern "C" {
#undef _ext
-#endif /* _MBG_TGT_H */
+#endif // !defined( MBG_TGT_NO_TGT )
+
+#endif // !defined( _MBG_TGT_H )
diff --git a/mbglib/common/mbgerror.c b/mbglib/common/mbgerror.c
index ffd4bb8..9f8dfaf 100755
--- a/mbglib/common/mbgerror.c
+++ b/mbglib/common/mbgerror.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgerror.c 1.3 2017/07/05 09:20:07 martin REL_M $
+ * $Id: mbgerror.c 1.4 2018/06/25 14:21:09 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,10 @@
*
* -----------------------------------------------------------------------
* $Log: mbgerror.c $
+ * Revision 1.4 2018/06/25 14:21:09 martin
+ * Cleaned up definition and usage of control macros.
+ * Distinguish between kernel mode and user mode on Windows.
+ * Support some new error codes.
* Revision 1.3 2017/07/05 09:20:07 martin
* Fixed a bug where POSIX error ENODEV wasn't mapped at all, but
* EXDEV was instead translated erraneously to MBG_ERR_NO_DEV.
@@ -37,100 +41,170 @@
#include <mbg_tgt.h>
-#include <stdio.h>
-#include <string.h>
+#if defined( MBG_TGT_WIN32 )
-#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 !defined( MBG_TGT_KERNEL )
+ #include <errno.h>
+ #include <stdio.h>
-#if _MBG_TGT_HAS_POSIX_ERRNO
- #include <errno.h>
-#endif
+ #define _MBG_TGT_HAS_POSIX_ERRNO 1
+ #define _MBG_TGT_HAS_WIN32_ERR_API 1
+ #else
+ #define _MBG_TGT_OMIT_LAST_ERROR 1
+ #define _MBG_TGT_OMIT_ERR_MSG 1 // Not (yet) supported in Windows kernel mode
+ #endif
+
+#elif defined( MBG_TGT_CVI )
+
+ // Nothing to do here.
+
+#elif defined( MBG_TGT_LINUX )
+
+ #if !defined( MBG_TGT_KERNEL )
+ #include <errno.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <netdb.h>
+
+ #define _MBG_TGT_HAS_POSIX_ERRNO 1
+ #define _MBG_TGT_HAS_POSIX_H_ERRNO 1
+ #else
+ #include <asm/errno.h>
+
+ #define _MBG_TGT_HAS_POSIX_ERRNO 1
+ #define _MBG_TGT_OMIT_LAST_ERROR 1
+ #define _MBG_TGT_OMIT_ERR_MSG 1
+ #endif
+
+#elif defined( MBG_TGT_BSD )
-#if defined( MBG_TGT_DOS )
+ #if !defined( MBG_TGT_KERNEL )
+ #include <errno.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <netdb.h>
+
+ #define _MBG_TGT_HAS_POSIX_ERRNO 1
+ #define _MBG_TGT_HAS_POSIX_H_ERRNO 1
+ #else
+ #include <sys/errno.h>
+ #if defined( MBG_TGT_FREEBSD )
+ #include <sys/stddef.h> // NULL
+ #elif defined( MBG_TGT_NETBSD )
+ #include <sys/null.h> // NULL
+ #endif
+
+ #define _MBG_TGT_HAS_POSIX_ERRNO 1
+ #define _MBG_TGT_OMIT_LAST_ERROR 1
+ #define _MBG_TGT_OMIT_ERR_MSG 1
+ #endif
+
+#elif defined( MBG_TGT_DOS )
+
+ #include <stdio.h>
+ #include <stdlib.h>
#include <stddef.h>
-#endif
+ #include <errno.h>
+
+ #define _MBG_TGT_HAS_POSIX_ERRNO 1
+ #define _MBG_TGT_OMIT_SOCKET_ERRORS 1 // No network socket support
-#if defined( MBG_TGT_POSIX )
- #include <netdb.h>
#endif
-#if defined(USE_MBG_ZLIB)
+#if defined( USE_MBG_ZLIB )
#include <zlib.h>
#endif
+#if !defined( DEBUG )
+ // FIXME This should be done globally across projects.
+ #define DEBUG 0
+#endif
+
typedef struct
{
- int orig_errno;
- int mbg_errno;
+ int srch_errno;
+ int mapped_errno;
} ERRNO_CNV_ENTRY;
-#if _MBG_TGT_HAS_POSIX_ERRNO
+#if defined( _MBG_TGT_HAS_POSIX_ERRNO )
+/**
+ * @brief Mappings between Meinberg error codes and POSIX error codes
+ *
+ * Always refer to the symbolic names only. The numeric codes listed
+ * in the comments below are just for a quick reference, and may vary
+ * depending on the OS type and version.
+ *
+ * Linux: /usr/include/asm-generic/errno.h<br>
+ * FreeBSD/NetBSD: /usr/include/sys/errno.h
+ *
+ * @see ::mbg_posix_errno_to_mbg
+ * @see POSIX spec at http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_03
+ */
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, MBG_ERR_INV_PARM }, // 14, Bad address, e.g. invalid pointer
- // { ENOTBLK, }, // 15, Block device required
- { EBUSY, MBG_ERR_BUSY }, // 16, Device or resource busy
- { EEXIST, MBG_ERR_EXIST }, // 17, File exists
- // { EXDEV, }, // 18, Cross-device link
- { ENODEV, MBG_ERR_NO_DEV }, // 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
+ { EPERM, MBG_ERR_PERM }, // 1, Operation not permitted (e.g. when trying to set time without sufficient permissions).
+ { ENOENT, MBG_ERR_NO_ENTITY }, // 2, No such file or directory.
+ // { ESRCH, }, // 3, No such process.
+ { EINTR, MBG_ERR_INTR }, // 4, Interrupted function call.
+ { EIO, MBG_ERR_IO }, // 5, Input/output error (from physical device).
+ { ENXIO, MBG_ERR_NOT_FOUND }, // 6, No such device or address (refering to a device that doesn't exist, or request beyond its capabilities) of the device.
+ // { E2BIG, }, // 7, Argument list too long (or lack of space in an output buffer, or argument exceeds system-imposed maximum.
+ // { ENOEXEC, }, // 8, Exec format error (executable file format error).
+ // { EBADF, }, // 9, Bad file number/descriptor (or a read (write) tried on a file only open for writing (reading)).
+ // { ECHILD, }, // 10, No child processes (when waiting for child process).
+ { EAGAIN, MBG_ERR_AGAIN }, // 11, Try again, resource temporarily unavailable (later calls may complete normally, maybe same as EWOULDBLOCK).
+ { ENOMEM, MBG_ERR_NO_MEM }, // 12, Out of memory (can't allocate memory).
+ { EACCES, MBG_ERR_ACCESS }, // 13, Permission denied (e.g. when trying to access a device without sufficient permissions).
+ { EFAULT, MBG_ERR_INV_PARM }, // 14, Bad address (e.g. invalid address in a function argument).
+ // { ENOTBLK, }, // 15, Block device required (eventually no POSIX error, but supported in Linux and *BSD).
+ { EBUSY, MBG_ERR_BUSY }, // 16, Device or resource busy.
+ { EEXIST, MBG_ERR_EXIST }, // 17, File exists.
+ // { EXDEV, }, // 18, Cross-device link.
+ { ENODEV, MBG_ERR_NO_DEV }, // 19, ### No such device (operation not supported by device).
+ // { ENOTDIR, }, // 20, Not a directory (when a directory was expected for the operation).
+ // { EISDIR, }, // 21, Is a directory (when a directory was *not* expected for the operation).
+ { EINVAL, MBG_ERR_INV_PARM }, // 22, Invalid argument (was supplied to a function).
+ // { ENFILE, }, // 23, Too many files open in system (file table overflow).
+ // { EMFILE, }, // 24, Too many open files (or file descriptor value too large).
+ { ENOTTY, MBG_ERR_NOT_SUPP_BY_DEV }, // 25, ### Not a typewriter (actually means "inappropriate I/O control for device").
+ // { ETXTBSY, }, // 26, Text file busy ("text" actually means "binary program file").
+ // { EFBIG, }, // 27, File too large.
+ { ENOSPC, MBG_ERR_NO_SPACE }, // 28, No space left on device (when writing a file or extending directory).
+ { ESPIPE, MBG_ERR_PIPE }, // 29, Illegal seek (when attempting to access the file offset associated with a pipe or FIFO).
+ // { EROFS, }, // 30, Read-only file system.
+ // { EMLINK, }, // 31, Too many links (link count of a single file exceed).
+ // { EPIPE, }, // 32, Broken pipe (writing to a socket, pipe, or FIFO which has no process to read the data).
+ // { EDOM, }, // 33, Math argument out of domain of function.
+ { ERANGE, MBG_ERR_RANGE }, // 34, Math result too large or too small (not representable).
+#if defined( ETIME )
+ { ETIME, MBG_ERR_TIMER }, // 62, Timer expired (e.g. stream timeout on USB disconnect).
+#endif
#if defined( EOVERFLOW )
- { EOVERFLOW, MBG_ERR_OVERFLOW }, // 75, Value too large for defined data type
+ { EOVERFLOW, MBG_ERR_OVERFLOW }, // 75, Value too large for defined data type (can't be stored).
#endif
#if defined( ENOTSOCK )
- { ENOTSOCK, MBG_ERR_NOT_A_SOCKET }, // 88, Socket operation on non-socket
+ { ENOTSOCK, MBG_ERR_NOT_A_SOCKET }, // 88, Socket operation on non-socket (file descriptor is not a socket).
#endif
#if defined( ECONNRESET )
- { ECONNRESET, MBG_ERR_CONN_RESET }, // 104, Connection reset by peer
+ { ECONNRESET, MBG_ERR_CONN_RESET }, // 104, Connection reset by peer
+#endif
+#if defined( ETIMEDOUT )
+ { ETIMEDOUT, MBG_ERR_TIMEOUT }, // 110, Connection timed out
#endif
- { 0, 0 } // end-of-table identifier
+ { 0, 0 } // end-of-table identifier
}; // posix_errno_table
-#endif // _MBG_TGT_HAS_POSIX_ERRNO
+#endif // defined( _MBG_TGT_HAS_POSIX_ERRNO )
-#if defined( MBG_TGT_POSIX )
+#if defined( _MBG_TGT_HAS_POSIX_H_ERRNO )
static ERRNO_CNV_ENTRY posix_h_errno_table[] =
{
@@ -144,7 +218,7 @@ static ERRNO_CNV_ENTRY posix_h_errno_table[] =
}; // posix_h_errno_table
-#endif // defined( MBG_TGT_POSIX )
+#endif // defined( _MBG_TGT_HAS_POSIX_H_ERRNO )
@@ -209,34 +283,65 @@ static ERRNO_CNV_ENTRY cvi_rs232_error_table[] =
-#if defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_KERNEL )
+#if defined( MBG_TGT_WIN32 )
+
+#if defined( MBG_TGT_KERNEL )
+
+// FIXME TODO
+// Each of the predefined NTSTATUS codes STATUS_... used in Windows kernel drivers
+// is remapped to one of the positive ERROR_... codes defined in WinError.h when
+// passed up from kernel space to to user space.
+// For the mapping, see:
+// https://support.microsoft.com/en-us/help/113996/info-mapping-nt-status-error-codes-to-win32-error-codes
+//
+// Eventually, driver specific error codes can also be defined in kernel space,
+// e.g. by defining (NTSTATUS) (0x2000000 | 31). Look likes if these error codes
+// are passed up to user space, GetLastError() returns the negated value, e.g. -31.
+// This has to be tested, though, and could be used to pass direct Meinberg error
+// codes up to user space, without the need for win32_kernel_error_table.
+
+static ERRNO_CNV_ENTRY win32_kernel_error_table[] =
+{
+ { MBG_ERR_PERM, STATUS_ACCESS_DENIED }, // ERROR_ACCESS_DENIED
+ { MBG_ERR_INV_DEV_REQUEST, STATUS_INVALID_DEVICE_REQUEST }, // ERROR_BAD_COMMAND
+ { MBG_ERR_INV_PARM, STATUS_INVALID_PARAMETER }, // ERROR_INVALID_PARAMETER
+ { MBG_ERR_NOT_SUPP_BY_DEV, STATUS_NO_DATA_DETECTED }, // ERROR_NO_DATA_DETECTED (mis-used here)
+ { MBG_ERR_NO_MEM, STATUS_NO_MEMORY }, // ERROR_NOT_ENOUGH_MEMORY
+ { MBG_ERR_IRQ_UNSAFE, STATUS_DEVICE_BUSY }, // ERROR_BUSY
+ { MBG_ERR_IO, STATUS_IO_DEVICE_ERROR }, // ERROR_IO_DEVICE
+ { 0, 0 } // end-of-table identifier
+
+}; // win32_kernel_error_table
+
+#else // Windows user space
static ERRNO_CNV_ENTRY win32_error_table[] =
{
- // Windows System Error Codes (0-499)
- { ERROR_INVALID_PARAMETER, MBG_ERR_INV_PARM },
-
- // Windows 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
+ // Mappings for some Windows error codes defined in WinError.h
+ { ERROR_PATH_NOT_FOUND, MBG_ERR_NO_ENTITY }, // 3L: The system cannot find the path specified.
+ { ERROR_ACCESS_DENIED, MBG_ERR_ACCESS }, // 5L: Access is denied.
+ { ERROR_INVALID_HANDLE, MBG_ERR_INV_HANDLE }, // 6L: The handle is invalid.
+ { ERROR_NOT_ENOUGH_MEMORY, MBG_ERR_NO_MEM }, // 8L: Not enough storage is available to process this command.
+ { ERROR_OUTOFMEMORY, MBG_ERR_NO_MEM }, // 14L: Not enough storage is available to complete this operation.
+ // { ERROR_WRITE_PROTECT, }, // 19L: The media is write protected.
+ // { ERROR_BAD_UNIT, }, // 20L: The system cannot find the device specified.
+ { ERROR_NOT_READY, MBG_ERR_NOT_READY }, // 21L: The device is not ready.
+ { ERROR_WRITE_FAULT, MBG_ERR_IO }, // 29L: The system cannot write to the specified device.
+ { ERROR_READ_FAULT, MBG_ERR_IO }, // 30L: The system cannot read from the specified device.
+ { ERROR_GEN_FAILURE, MBG_ERR_UNSPEC }, // 31L: A device attached to the system is not functioning.
+ // { ERROR_SHARING_VIOLATION, }, // 32L: The process cannot access the file because it is being used by another process.
+ // { ERROR_LOCK_VIOLATION, }, // 33L: The process cannot access the file because another process has locked a portion of the file.
+ // { ERROR_NOT_SUPPORTED, }, // 50L: The request is not supported.
+ // { ERROR_DUP_NAME, }, // 52L: A duplicate name exists on the network.
+ // { ERROR_BAD_DEV_TYPE, }, // 66L: The network resource type is not correct.
+ { ERROR_INVALID_PARAMETER, MBG_ERR_INV_PARM }, // 87L: The parameter is incorrect.
+ // { ERROR_BUFFER_OVERFLOW, }, // 111L: The file name is too long.
+ { ERROR_BUSY, MBG_ERR_BUSY }, // 170L: The requested resource is in use.
+ // { ERROR_NOACCESS, }, // 998L: Invalid access to memory location.
+ { ERROR_NO_DATA_DETECTED, MBG_ERR_NOT_SUPP_BY_DEV }, // 1104L: No more data is on the tape. (mis-used here)
+ { ERROR_IO_DEVICE, MBG_ERR_IO }, // 1117L: The request could not be performed because of an I/O device error.
+ { ERROR_PRIVILEGE_NOT_HELD, MBG_ERR_PERM }, // 1314L: A required privilege is not held by the client.
+ { 0, 0 } // end-of-table identifier
}; // win32_error_table
@@ -250,7 +355,7 @@ static ERRNO_CNV_ENTRY win32_wsa_err_table[] =
{ WSAEFAULT, MBG_ERR_INV_PARM }, // 10014L The system detected an invalid pointer address in attempting to use a pointer argument in a call.
{ WSAEINVAL, MBG_ERR_INV_PARM }, // 10022L An invalid argument was supplied.
// { WSAEMFILE // 10024L Too many open sockets.
- // { WSAEWOULDBLOCK // 10035L A non-blocking socket operation could not be completed immediately.
+ { WSAEWOULDBLOCK, MBG_ERR_AGAIN }, // 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.
@@ -310,31 +415,96 @@ static ERRNO_CNV_ENTRY win32_wsa_err_table[] =
}; // win32_wsa_err_table
+#endif // Windows user space
+
#endif // defined( MBG_TGT_WIN32 )
+static /*HDR*/
/**
* @brief Lookup some error code in a conversion table
*
- * @param[in] orig_errno
- * @param[in] tbl
+ * @param[in] srch_errno The error number to be looked up in the conversion table
+ * @param[in] tbl A conversion table
+ * @param[in] dflt_val The code to be returned if no table entry was found.
*
* @return @ref MBG_ERROR_CODES associated with the original error code,
- * or ::MBG_ERR_UNSPEC if origianl code not found in table.
+ * or @p dflt_val if original code not found in table.
*/
-static /*HDR*/
-int lookup_mbg_errno( int orig_errno, const ERRNO_CNV_ENTRY tbl[] )
+int lookup_tbl_errno( int srch_errno, const ERRNO_CNV_ENTRY tbl[], int dflt_val )
{
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;
+ for ( p = tbl; p->srch_errno || p->mapped_errno; p++ )
+ if ( p->srch_errno == srch_errno )
+ return p->mapped_errno;
- return MBG_ERR_UNSPEC;
+ return dflt_val;
-} // lookup_mbg_errno
+} // lookup_tbl_errno
+
+
+#if !_USE_WIN32_PRIVATE_STATUS_CODES
+
+/*HDR*/
+/**
+ * @brief Convert one of the @ref MBG_ERROR_CODES to an OS-specific format
+ *
+ * @param[in] err_no One of the @ref MBG_ERROR_CODES.
+ *
+ * @see @ref MBG_ERROR_CODES
+ *
+ * @return An OS-specific error code
+ */
+int mbg_errno_to_os( int err_no )
+{
+ #if defined( MBG_TGT_KERNEL )
+
+ #if defined( MBG_TGT_WIN32 )
+
+ if ( err_no == MBG_SUCCESS )
+ return STATUS_SUCCESS;
+
+ return lookup_tbl_errno( err_no, win32_kernel_error_table, STATUS_UNSUCCESSFUL );
+
+ #elif defined( MBG_TGT_LINUX )
+
+ #elif defined( MBG_TGT_FREEBSD )
+
+ #elif defined( MBG_TGT_NETBSD )
+
+ #else
+
+ #error this needs to be implemented
+
+ #endif
+
+ #else // user space
+
+ #if 0
+ #if defined( MBG_TGT_WIN32 ) // FIXME TODO
+ // Windows uses specially encoded numbers
+ return ( -err_no | 0xE0000000L );
+
+ #elif defined( MBG_TGT_BSD )
+
+ return -err_no;
+
+ #else
+
+ return err_no;
+
+ #endif
+ #endif // 0
+
+ #endif
+
+ return err_no;
+
+} // mbg_errno_to_os
+
+#endif // _USE_WIN32_PRIVATE_STATUS_CODES
@@ -348,7 +518,7 @@ int lookup_mbg_errno( int orig_errno, const ERRNO_CNV_ENTRY tbl[] )
*/
const char *mbg_strerror( int mbg_errno )
{
- static const MBG_CODE_NAME_TABLE_ENTRY tbl[] = MBG_ERR_NAMES_ENG;
+ static const MBG_CODE_NAME_TABLE_ENTRY tbl[] = MBG_ERR_STR_TABLE_ENG;
const MBG_CODE_NAME_TABLE_ENTRY *p;
@@ -358,14 +528,13 @@ const char *mbg_strerror( int mbg_errno )
return p->name;
}
-
return "Unknown error";
} // mbg_strerror
-#if !( defined( MBG_TGT_WIN32 ) && defined( MBG_TGT_KERNEL ) ) // not supported in Windows kernel mode
+#if !defined( _MBG_TGT_OMIT_ERR_MSG )
/*HDR*/
/**
@@ -420,7 +589,7 @@ bool mbg_cond_err_msg_info( int rc, const char *what, const char *info )
} // mbg_cond_err_msg_info
-#endif // !( defined( MBG_TGT_WIN32 ) && defined( MBG_TGT_KERNEL ) )
+#endif // !defined( _MBG_TGT_OMIT_ERR_MSG )
@@ -446,7 +615,7 @@ int mbg_cvi_rs232_error_to_mbg( int cvi_rc, const char *info )
(void) info; // avoid compiler warning
#endif
- return ( cvi_rc < 0 ) ? lookup_mbg_errno( cvi_rc, cvi_rs232_error_table ) : MBG_SUCCESS;
+ return ( cvi_rc < 0 ) ? lookup_tbl_errno( cvi_rc, cvi_rs232_error_table, MBG_ERR_UNKNOWN ) : MBG_SUCCESS;
} // mbg_cvi_rs232_error_to_mbg
@@ -454,7 +623,13 @@ int mbg_cvi_rs232_error_to_mbg( int cvi_rc, const char *info )
-#if defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_KERNEL )
+#if defined( MBG_TGT_WIN32 )
+
+#if defined( MBG_TGT_KERNEL )
+
+// FIXME TODO
+
+#else // Windows user space
/*HDR*/
/**
@@ -467,14 +642,47 @@ int mbg_cvi_rs232_error_to_mbg( int cvi_rc, const char *info )
*/
int mbg_win32_last_err_to_mbg( DWORD last_err, const char *info )
{
+ int rc = MBG_SUCCESS;
+
+ if ( last_err == ERROR_SUCCESS )
+ goto out;
+
+ if ( last_err & 0x20000000L )
+ {
+ // This is a user-defined error code, e.g. returned by an IOCTL call.
+ // The lower 16 bits contain the (positive) error code while the upper
+ // 16 bits contain flags as specified for the Windows API in winerror.h.
+ // So we assume the error code is just the absolute value of one of the
+ // @ref MBG_ERROR_CODES, and we return the negated value.
+ rc = - (int) ( last_err & 0xFFFF );
+ goto out;
+ }
+
+#if 0 // TODO FIXME
+ rc = (int) last_err;
+
+ if ( rc < 0 )
+ {
+ // If the error code is negative then this is a user-defined
+ // error code e.g. returned by an IOCTL call. In this case we
+ // assume it's one of the
+ goto out;
+ }
+#endif
+
+ rc = lookup_tbl_errno( last_err, win32_error_table, MBG_ERR_UNKNOWN );
+
+out:
#if DEBUG
if ( info )
- fprintf( stderr, "%s, wsa_err: 0x%08lX\n", info, (long) last_err );
+ fprintf( stderr, "%s, last_err: 0x%08lX (%i) --> %i (%s)\n",
+ info, (long) last_err, (int) last_err,
+ rc, mbg_strerror( rc ) );
#else
(void) info; // avoid compiler warning
#endif
- return ( last_err == ERROR_SUCCESS ) ? MBG_SUCCESS : lookup_mbg_errno( last_err, win32_error_table );
+ return rc;
} // mbg_win32_last_err_to_mbg
@@ -500,15 +708,18 @@ int mbg_win32_wsa_err_to_mbg( DWORD wsa_err, const char *info )
// 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 );
+ return lookup_tbl_errno( wsa_err, win32_wsa_err_table, MBG_ERR_UNKNOWN );
} // mbg_win32_wsa_err_to_mbg
+#endif // Windows user space
+
#endif // defined( MBG_TGT_WIN32 )
-#if _MBG_TGT_HAS_POSIX_ERRNO
+
+#if defined( _MBG_TGT_HAS_POSIX_ERRNO )
/*HDR*/
/**
@@ -521,7 +732,7 @@ int mbg_win32_wsa_err_to_mbg( DWORD wsa_err, const char *info )
*/
int mbg_posix_errno_to_mbg( int posix_errno, const char *info )
{
- #if DEBUG
+ #if DEBUG && !defined( MBG_TGT_KERNEL )
if ( info )
fprintf( stderr, "%s: %s (errno: %i)\n", info,
strerror( posix_errno ), posix_errno );
@@ -529,15 +740,15 @@ int mbg_posix_errno_to_mbg( int posix_errno, const char *info )
(void) info; // avoid compiler warning
#endif
- return lookup_mbg_errno( posix_errno, posix_errno_table );
+ return lookup_tbl_errno( posix_errno, posix_errno_table, MBG_ERR_UNKNOWN );
} // mbg_posix_errno_to_mbg
-#endif // _MBG_TGT_HAS_POSIX_ERRNO
+#endif // defined( _MBG_TGT_HAS_POSIX_ERRNO )
-#if defined( MBG_TGT_POSIX )
+#if defined( _MBG_TGT_HAS_POSIX_H_ERRNO )
/*HDR*/
/**
@@ -557,7 +768,7 @@ int mbg_posix_errno_to_mbg( int posix_errno, const char *info )
*/
int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info )
{
- #if DEBUG
+ #if DEBUG && !defined( MBG_TGT_KERNEL )
if ( info )
fprintf( stderr, "%s: %s (h_errno: %i)\n", info,
hstrerror( posix_h_errno ), posix_h_errno );
@@ -565,13 +776,15 @@ int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info )
(void) info; // avoid compiler warning
#endif
- return lookup_mbg_errno( posix_h_errno, posix_h_errno_table );
+ return lookup_tbl_errno( posix_h_errno, posix_h_errno_table, MBG_ERR_UNKNOWN );
} // mbg_posix_h_errno_to_mbg
-#endif // defined( MBG_TGT_POSIX )
+#endif // defined( _MBG_TGT_HAS_POSIX_H_ERRNO )
+
+#if !defined( _MBG_TGT_OMIT_LAST_ERROR )
/*HDR*/
/**
@@ -594,15 +807,11 @@ int mbg_get_last_error( const char *info )
{
#if defined( MBG_TGT_WIN32 )
- #if !defined( MBG_TGT_KERNEL )
- // Under Windows the "last error" code after a non-socket function
- // 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_last_err_to_mbg( GetLastError(), info );
- #else
- return MBG_ERR_GENERIC;
- #endif
+ // Under Windows the "last error" code after a non-socket function
+ // 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_last_err_to_mbg( GetLastError(), info );
#elif defined( MBG_TGT_POSIX )
@@ -620,7 +829,7 @@ int mbg_get_last_error( const char *info )
-#if !defined( MBG_TGT_DOS )
+#if !defined( _MBG_TGT_OMIT_SOCKET_ERRORS )
/*HDR*/
/**
@@ -643,7 +852,7 @@ int mbg_get_last_socket_error( const char *info )
#if defined( MBG_TGT_CVI )
#warning This needs to be implemented for CVI
- return MBG_ERR_UNSPEC;
+ return MBG_ERR_UNKNOWN;
#elif defined( MBG_TGT_WIN32 )
@@ -654,7 +863,7 @@ int mbg_get_last_socket_error( const char *info )
// is stored in errno as usual.
return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info );
#else
- return MBG_ERR_GENERIC;
+ return MBG_ERR_GENERIC; // TODO should we only work with NTSTATUS codes in kernel mode?
#endif
#elif defined( MBG_TGT_POSIX )
@@ -694,7 +903,7 @@ int mbg_get_gethostbyname_error( const char *info )
#if defined( MBG_TGT_CVI )
#warning This needs to be implemented for CVI
- return MBG_ERR_UNSPEC;
+ return MBG_ERR_UNKNOWN;
#elif defined( MBG_TGT_WIN32 )
@@ -716,7 +925,9 @@ int mbg_get_gethostbyname_error( const char *info )
} // mbg_get_gethostbyname_error
-#endif // !defined( MBG_TGT_DOS )
+#endif // !defined( _MBG_TGT_OMIT_SOCKET_ERRORS )
+
+#endif // !defined( _MBG_TGT_OMIT_LAST_ERROR )
@@ -731,7 +942,7 @@ int mbg_gai_error( int rc, const char *info )
#if defined( MBG_TGT_CVI )
#warning This needs to be implemented for CVI
- return MBG_ERR_UNSPEC;
+ return MBG_ERR_UNKNOWN;
#elif defined( MBG_TGT_WIN32 )
@@ -743,7 +954,7 @@ int mbg_gai_error( int rc, const char *info )
#else
- return MBG_ERR_UNSPEC;
+ return MBG_ERR_UNKNOWN;
#endif
@@ -783,7 +994,7 @@ int mbg_zlib_error_to_mbg( int zlib_error, const char *info, const char *msg )
* So, it's hard to guess what they mean and we return MBG_UNSPEC so far.
*/
default:
- return MBG_ERR_UNSPEC;
+ return MBG_ERR_UNKNOWN;
}
} // mbg_zlib_error_to_mbg
diff --git a/mbglib/common/mbgerror.h b/mbglib/common/mbgerror.h
index 20a3edc..5694199 100755
--- a/mbglib/common/mbgerror.h
+++ b/mbglib/common/mbgerror.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgerror.h 1.15 2017/07/05 09:27:25 martin REL_M $
+ * $Id: mbgerror.h 1.16 2018/06/25 14:26:38 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -11,6 +11,14 @@
*
* -----------------------------------------------------------------------
* $Log: mbgerror.h $
+ * Revision 1.16 2018/06/25 14:26:38 martin
+ * Some new error codes were introduced.
+ * New macro mbg_rc_is_success_or_err_perm().
+ * New control macro _USE_WIN32_PRIVATE_STATUS_CODES.
+ * Split table initializers for error strings into two
+ * separate initializers to avoid overhead on target
+ * systems which don't support extended functions.
+ * Updated comments, string tables, and function prototypes.
* Revision 1.15 2017/07/05 09:27:25 martin
* New error code MBG_ERR_PARM_FMT.
* Changed message text for MBG_ERR_NO_ENTITY.
@@ -86,13 +94,29 @@ extern "C" {
#if defined( MBG_TGT_WIN32 )
- #if !defined( STATUS_SUCCESS ) // not in kernel mode
- #define STATUS_SUCCESS 0
+ #define _USE_WIN32_PRIVATE_STATUS_CODES 0
+
+ #if defined( MBG_TGT_KERNEL )
+ #define MBG_SYS_RC_SUCCESS STATUS_SUCCESS
+ #else
+ #define MBG_SYS_RC_SUCCESS ERROR_SUCCESS
#endif
+#elif defined( MBG_TGT_POSIX )
+
+ #define MBG_SYS_RC_SUCCESS 0
+
+#else
+
+ #define MBG_SYS_RC_SUCCESS 0
+
#endif
+#if !defined( _USE_WIN32_PRIVATE_STATUS_CODES ) // FIXME
+ #define _USE_WIN32_PRIVATE_STATUS_CODES 0
+#endif
+
#if !defined( MBG_TGT_WIN32 ) || defined( MBG_TGT_KERNEL )
// A dummy declaration for DWORD to avoid compiler errors.
// Also reqired in Windows kernel mode.
@@ -106,11 +130,11 @@ extern "C" {
*
* Appropriate error strings can be retrieved via the ::mbg_strerror function.
*
- * @see ::MBG_ERR_NAMES_ENG
+ * @see ::MBG_ERR_STR_TABLE_ENG
*
* @anchor MBG_RETURN_CODES @{ */
-/* ### TODO
+/* ### TODO FIXME
* 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
@@ -124,25 +148,25 @@ extern "C" {
// 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
+#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 ///< 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)
+#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
-#define MBG_ERR_GENERIC -19 ///< generic error
-#define MBG_ERR_TIMEOUT -20 ///< timeout accessing the device
-#define MBG_ERR_FW_ID -21 ///< invalid firmware ID
-#define MBG_ERR_NBYTES -22 ///< the number of parameter bytes passed to the device did not
- ///< match the number of bytes expected by the device
-
-#define MBG_ERR_INV_TIME -23 ///< the device doesn't have valid time
-#define MBG_ERR_FIFO -24 ///< the data FIFO of a bus-level device is empty, though it shouldn't be
-#define MBG_ERR_NOT_READY -25 ///< bus-level device is temp. unable to respond e.g. during init. after RESET
+#define MBG_ERR_GENERIC -19 ///< Generic error.
+#define MBG_ERR_TIMEOUT -20 ///< Timeout accessing the device.
+#define MBG_ERR_FW_ID -21 ///< Invalid firmware ID.
+#define MBG_ERR_NBYTES -22 ///< The number of parameter bytes passed to the device did not
+ ///< match the number of bytes expected by the device.
+
+#define MBG_ERR_INV_TIME -23 ///< The device doesn't have valid time.
+#define MBG_ERR_FIFO -24 ///< The data FIFO of a bus-level device is empty, though it shouldn't be.
+#define MBG_ERR_NOT_READY -25 ///< Bus-level device is temp. unable to respond e.g. during init. after RESET.
#define MBG_ERR_INV_TYPE -26 ///< bus-level device didn't recognize data type
@@ -152,7 +176,7 @@ extern "C" {
#define MBG_ERR_DEV_NOT_SUPP -29 ///< specified device type not supported by driver
#define MBG_ERR_INV_DEV_REQUEST -30 ///< IOCTL call not supported by driver
#define MBG_ERR_NOT_SUPP_BY_DEV -31 ///< cmd or feature not supported by device
-#define MBG_ERR_USB_ACCESS -32 ///< USB access failed
+// #define MBG_ERR_USB_ACCESS -32 ///< USB access failed (FIXME TODO this is B.S., we should return *why*)
#define MBG_ERR_CYCLIC_TIMEOUT -33 ///< cyclic event (IRQ, etc.) didn't occur
#define MBG_ERR_NOT_SUPP_ON_OS -34 ///< function is not supported under this operating system
#define MBG_ERR_LIB_NOT_COMPATIBLE -35 ///< installed shared lib. version not compat. with version used at build time
@@ -193,17 +217,17 @@ extern "C" {
#define MBG_ERR_NBLOCK_WAIT_SLCT -71 ///< select timed out when waiting for non-blocking network port to become ready
#define MBG_ERR_NBLOCK_WAIT_WR_FD -72 ///< write fd not set after select when waiting for non-blocking network port to become ready
-#define MBG_ERR_IO -73 ///< generic I/O error
+#define MBG_ERR_IO -73 ///< input/output error
#define MBG_ERR_INV_PARM -74 ///< invalid parameter
-#define MBG_ERR_NO_DEV -75 ///< specified device not found
+#define MBG_ERR_NO_DEV -75 ///< specified device not found ### No such device. Attempted an inappropriate function.
#define MBG_ERR_NOT_FOUND -76 ///< specified item not found
#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
-#define MBG_ERR_PERM -81 ///< operation not permitted, e.g. when trying to set the system time
-#define MBG_ERR_BUSY -82 ///< device busy
+#define MBG_ERR_INTR -79 ///< interrupted function call
+#define MBG_ERR_ACCESS -80 ///< Access denied, e.g. when trying to access a file or device without sufficient permissions
+#define MBG_ERR_PERM -81 ///< Operation not permitted, e.g. when trying to set the system time without sufficient permissions
+#define MBG_ERR_BUSY -82 ///< Device or resource busy, can't be used
#define MBG_ERR_INV_HANDLE -83 ///< invalid file/device handle specified
#define MBG_ERR_XBP_CASC_LVL -84 ///< too many XBP cascading levels
@@ -218,7 +242,7 @@ extern "C" {
#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_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 file or directory
#define MBG_ERR_ALREADY_ALLOC -96 ///< pointer already allocated when trying to allocate memory
@@ -231,10 +255,27 @@ extern "C" {
#define MBG_ERR_INV_IDX -102 ///< invalid index value used
#define MBG_ERR_PARM_FMT -103 ///< parameter string format error
+#define MBG_ERR_UNKNOWN -104 ///< Unknown error code from external API.
+
+#define MBG_ERR_PAM -105 ///< PAM error while authenticating user
+#define MBG_ERR_TIMER -106 ///< Timer expired (e.g. stream timeout on USB disconnect)
+
+#define MBG_ERR_AGAIN -107 ///< Try again (later). For example, a blocking operation
+ ///< on a non-blocking socket.
+
+#define MBG_ERR_STR_CHAR -108 ///< Invalid character in string
+#define MBG_ERR_STR_LEN -109 ///< Wrong string length
+#define MBG_ERR_SN_GCODE_LEN -110 ///< Invalid device group code length
+#define MBG_ERR_SN_GCODE_UNKN -111 ///< Unknown device group code
+#define MBG_ERR_SN_GCODE_WRONG -112 ///< Wrong device group code in S/N
+#define MBG_ERR_SN_LEN -113 ///< Wrong serial number string length
+#define MBG_ERR_SN_VRFY -114 ///< Serial number could not be verified
+
+#define MBG_ERR_RSRC_ITEM -115 ///< Too many resource items
// 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
+// to the ::MBG_ERR_STR_TABLE_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.
@@ -243,14 +284,26 @@ extern "C" {
/** @} anchor MBG_RETURN_CODES */
+
/**
- * @brief Strings associated with @ref MBG_RETURN_CODES
+ * @brief A basic subset of strings associated with @ref MBG_RETURN_CODES
+ *
+ * This initializer provides only the strings for basic error codes
+ * that are supported on all target systems.
+ *
+ * See the @ref MBG_ERR_STR_TABLE_EXT_ENG initializer for error strings
+ * associated with errors from network and other extended functions.
+ *
+ * The generic @ref MBG_ERR_STR_TABLE_ENG initializer should be used
+ * preferebly since it provides only the basic subset or the full
+ * set of strings depending on the target system.
*
+ * @see @ref MBG_ERR_STR_TABLE_ENG
+ * @see @ref MBG_ERR_STR_TABLE_EXT_ENG
* @see @ref MBG_RETURN_CODES
*/
-#define MBG_ERR_NAMES_ENG \
-{ \
- { MBG_SUCCESS, "Success, no error" }, \
+#define MBG_ERR_STR_TABLE_BASE_ENG \
+ { MBG_SUCCESS, "Success" }, \
{ MBG_ERR_STIME, "Invalid date/time for device" }, \
{ MBG_ERR_CFG, "Invalid configuration parameters for device" }, \
{ MBG_ERR_GENERIC, "Generic error" }, \
@@ -266,7 +319,6 @@ extern "C" {
{ 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" }, \
@@ -275,10 +327,6 @@ extern "C" {
{ 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" }, \
@@ -290,21 +338,11 @@ extern "C" {
{ 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_IO, "Input/output error" }, \
+ { MBG_ERR_INV_PARM, "Invalid parameter passed to function" }, \
+ { MBG_ERR_NO_DEV, "X No such device, or attempted an inappropriate function." }, \
{ 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" }, \
@@ -316,17 +354,86 @@ extern "C" {
{ 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 file or directory" }, \
{ 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"}, \
{ MBG_ERR_PARM_FMT, "Parameter string format error" }, \
+ { MBG_ERR_UNKNOWN, "Unknown error code from external API" }, \
+ { MBG_ERR_PAM, "PAM authentication error" }, \
+ { MBG_ERR_TIMER, "Timer expired" }, \
+ { MBG_ERR_AGAIN, "Try again (later)" }, \
+ { MBG_ERR_STR_CHAR, "Invalid character in string" }, \
+ { MBG_ERR_STR_LEN, "Wrong string length" }, \
+ { MBG_ERR_SN_GCODE_LEN, "Invalid device group code length" }, \
+ { MBG_ERR_SN_GCODE_UNKN, "Unknown device group code" }, \
+ { MBG_ERR_SN_GCODE_WRONG, "Wrong device group code in S/N" }, \
+ { MBG_ERR_SN_VRFY, "Serial number could not be verified" }, \
+ { MBG_ERR_RSRC_ITEM, "Too many resource items" }
+
+
+
+/**
+ * @brief A subset of extended strings associated with @ref MBG_RETURN_CODES
+ *
+ * This initializer provides only the strings associated with extended
+ * errors from network and other extended functions.
+ *
+ * See the @ref MBG_ERR_STR_TABLE_BASE_ENG initializer for error strings
+ * associated with basic error codes that are supported on all target systems.
+ *
+ * The generic @ref MBG_ERR_STR_TABLE_ENG initializer should be used
+ * preferebly since it provides only the basic subset or the full
+ * set of strings depending on the target system.
+ *
+ * @see @ref MBG_ERR_STR_TABLE_ENG
+ * @see @ref MBG_ERR_STR_TABLE_BASE_ENG
+ * @see @ref MBG_RETURN_CODES
+ */
+#if defined( MBG_TGT_DOS )
+
+#define MBG_ERR_STR_TABLE_EXT_ENG \
+ { 0, NULL }
+
+#else
+
+#define MBG_ERR_STR_TABLE_EXT_ENG \
+ { 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_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_PIPE, "Pipe error" }, \
+ { MBG_ERR_INTR, "Interrupted function call" }, \
+ { MBG_ERR_ACCESS, "Access denied, insufficient permission" }, \
+ { MBG_ERR_PERM, "Operation not permitted, insufficient rights" }, \
+ { MBG_ERR_EXIST, "File exists" }, \
+ { MBG_ERR_NO_ENTITY, "No such file or directory" }, \
+ { MBG_ERR_HOST_NOT_FOUND, "Host not found" }, \
+ { MBG_ERR_CONN_RESET, "Connection reset by peer" }, \
+ { MBG_ERR_NO_SPACE, "Insufficient disk space" }, \
+ { MBG_ERR_PAM, "PAM authentication was not successful" }, \
+ { MBG_ERR_TIMER, "Timer expired" } \
+
+#endif
+
+
+
+/**
+ * @brief Strings associated with @ref MBG_RETURN_CODES
+ *
+ * @see @ref MBG_RETURN_CODES
+ */
+#define MBG_ERR_STR_TABLE_ENG \
+{ \
+ MBG_ERR_STR_TABLE_BASE_ENG, \
+ MBG_ERR_STR_TABLE_EXT_ENG, \
{ 0, NULL } /* end of table */ \
}
@@ -345,12 +452,13 @@ static __mbg_inline
*/
bool mbg_rc_is_error( int rc )
{
- // Meinberg error codes are all < 0.
+ // MBG_SUCCESS is 0, and all Meinberg error codes are < 0.
return rc < MBG_SUCCESS;
} // mbg_rc_is_error
+
static __mbg_inline
/**
* @brief Check if the code returned by a function indicates success
@@ -369,69 +477,32 @@ bool mbg_rc_is_success( int 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
-
-static __mbg_inline /*HDR*/
-/**
- * @brief Convert one of the @ref MBG_ERROR_CODES to an OS-specific format
- *
- * @param[in] err_no One of the @ref MBG_ERROR_CODES.
- *
- * @see @ref MBG_ERROR_CODES
- */
-int mbg_errno_to_os( int err_no )
-{
- #if defined( MBG_TGT_WIN32 )
-
- // Windows uses specially encoded numbers
- return ( -err_no | 0xE0000000L );
-
- #elif defined( MBG_TGT_BSD )
-
- return -err_no;
-
- #else
-
- return err_no;
-
- #endif
-
-} // mbg_errno_to_os
-
-
-
-static __mbg_inline /*HDR*/
+static __mbg_inline
/**
- * @brief Convert one of the @ref MBG_RETURN_CODES to an OS-specific format
+ * @brief Check if a return code indicates success, or the specific code @ref MBG_ERR_PERM
*
- * @param[in] rc One of the @ref MBG_RETURN_CODES.
+ * @param[in] rc One of the @ref MBG_RETURN_CODES
*
+ * @see ::mbg_rc_is_success
* @see @ref MBG_RETURN_CODES
*/
-int mbg_ret_val_to_os( int rc )
+bool mbg_rc_is_success_or_err_perm( int rc )
{
- #if defined( MBG_TGT_WIN32 )
+ return mbg_rc_is_success( rc ) || ( rc == MBG_ERR_PERM );
- return mbg_rc_is_error( rc ) ? mbg_errno_to_os( rc ) : STATUS_SUCCESS;
+} // mbg_rc_is_success_or_err_perm
- #elif defined( MBG_TGT_BSD )
- return mbg_rc_is_error( rc ) ? mbg_errno_to_os( rc ) : MBG_SUCCESS;
+#else
- #else
+ #define mbg_rc_is_error( _rc ) ( (_rc) < MBG_SUCCESS )
+ #define mbg_rc_is_success( _rc ) ( !mbg_rc_is_error( _rc ) )
- return rc;
+ #define mbg_rc_is_success_or_err_perm( _rc ) ( mbg_rc_is_success( _rc ) || ( (_rc) == MBG_ERR_PERM ) )
- #endif
-
-} // mbg_ret_val_to_os
+#endif
@@ -441,6 +512,17 @@ int mbg_ret_val_to_os( int rc )
/* by MAKEHDR, do not remove the comments. */
/**
+ * @brief Convert one of the @ref MBG_ERROR_CODES to an OS-specific format
+ *
+ * @param[in] err_no One of the @ref MBG_ERROR_CODES.
+ *
+ * @see @ref MBG_ERROR_CODES
+ *
+ * @return An OS-specific error code
+ */
+ int mbg_errno_to_os( int err_no ) ;
+
+ /**
* @brief Return an error string associated with the @ref MBG_ERROR_CODES
*
* @param[in] mbg_errno One of the @ref MBG_ERROR_CODES
@@ -607,6 +689,29 @@ int mbg_ret_val_to_os( int rc )
/* ----- function prototypes end ----- */
+
+
+#if _USE_WIN32_PRIVATE_STATUS_CODES
+
+static __mbg_inline /*HDR*/
+/**
+ * @brief Convert one of the @ref MBG_RETURN_CODES to an OS-specific code
+ *
+ * @param[in] rc One of the @ref MBG_RETURN_CODES.
+ *
+ * @see @ref MBG_RETURN_CODES
+ *
+ * @return An OS-specific success or error code
+ */
+int mbg_ret_val_to_os( int rc )
+{
+ return mbg_rc_is_success( rc ) ? MBG_SYS_RC_SUCCESS : mbg_errno_to_os( rc );
+
+} // mbg_ret_val_to_os
+
+#endif // _USE_WIN32_PRIVATE_STATUS_CODES
+
+
#ifdef __cplusplus
}
#endif
diff --git a/mbglib/common/mbgntp.h b/mbglib/common/mbgntp.h
index d01b90d..afe2049 100755
--- a/mbglib/common/mbgntp.h
+++ b/mbglib/common/mbgntp.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgntp.h 1.13 2018/03/09 09:57:33 martin REL_M $
+ * $Id: mbgntp.h 1.14 2018/07/31 16:07:33 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,9 @@
*
* -----------------------------------------------------------------------
* $Log: mbgntp.h $
+ * Revision 1.14 2018/07/31 16:07:33 martin
+ * Changed packet modes to enum.
+ * Added initializer for mode name string array.
* Revision 1.13 2018/03/09 09:57:33 martin
* New inline function ntp_refid_should_be_text().
* Updated function prototypes.
@@ -115,15 +118,29 @@
#define DEFAULT_REQ_NTP_VERSION MAX_REQ_NTP_VERSION
-// From NTP's ntp.h:
-#define MODE_UNSPEC 0 /* unspecified (old version) */
-#define MODE_ACTIVE 1 /* symmetric active mode */
-#define MODE_PASSIVE 2 /* symmetric passive mode */
-#define MODE_CLIENT 3 /* client mode */
-#define MODE_SERVER 4 /* server mode */
-#define MODE_BROADCAST 5 /* broadcast mode */
+enum NTP_MODES
+{
+ MODE_UNSPEC, // 0, unspecified (old version)
+ MODE_ACTIVE, // 1, symmetric active mode
+ MODE_PASSIVE, // 2, symmetric passive mode
+ MODE_CLIENT, // 3, client mode
+ MODE_SERVER, // 4, server mode
+ MODE_BROADCAST, // 5, broadcast mode
+ // Modes 6 and 7 also exist, but aren't yet supported here.
+ N_NTP_MODES // number of defined modes
+};
+#define NTP_MODE_NAME_STRS \
+{ \
+ "unspecified (old version)", \
+ "symmetric active", \
+ "symmetric passive", \
+ "client", \
+ "server", \
+ "broadcast" \
+}
+
/**
diff --git a/mbglib/common/str_util.c b/mbglib/common/str_util.c
index c3c89cb..c851036 100755
--- a/mbglib/common/str_util.c
+++ b/mbglib/common/str_util.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: str_util.c 1.3 2016/10/24 08:10:04 thomas-b REL_M $
+ * $Id: str_util.c 1.4 2018/06/25 13:22:42 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,10 @@
*
* -----------------------------------------------------------------------
* $Log: str_util.c $
+ * Revision 1.4 2018/06/25 13:22:42 martin
+ * Many functios return int rather than size_t, like standard
+ * library functions.
+ * do_str_copy_safe() now returns the number of chars copied.
* Revision 1.3 2016/10/24 08:10:04 thomas-b
* Fixed counter var check in mbg_memcpy_reversed
* Revision 1.2 2016/08/05 12:31:04 martin
@@ -108,9 +112,11 @@ int vsnprintf( char *s, size_t max_len, const char *fmt, va_list arg_list )
* @see ::sn_cpy_str_safe
* @see ::sn_cpy_char_safe
*/
-size_t __attribute__( ( format( printf, 3, 0 ) ) )
+int __attribute__( ( format( printf, 3, 0 ) ) )
vsnprintf_safe( char *s, size_t max_len, const char *fmt, va_list ap )
{
+ size_t n;
+
if ( s == NULL || max_len == 0 )
return 0; // nothing to do anyway
@@ -123,7 +129,9 @@ vsnprintf_safe( char *s, size_t max_len, const char *fmt, va_list ap )
// 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 );
+ n = strlen( s );
+
+ return _int_from_size_t( n );
} // vsnprintf_safe
@@ -147,11 +155,11 @@ vsnprintf_safe( char *s, size_t max_len, const char *fmt, va_list ap )
* @see ::sn_cpy_str_safe
* @see ::sn_cpy_char_safe
*/
-size_t __attribute__( ( format( printf, 3, 4 ) ) )
+int __attribute__( ( format( printf, 3, 4 ) ) )
snprintf_safe( char *s, size_t max_len, const char * fmt, ... )
{
va_list ap;
- size_t len;
+ int len;
va_start( ap, fmt );
@@ -179,15 +187,17 @@ static __mbg_inline
* @param[in] n Number of characters to copy at most
* @param[in,out] p_i Pointer to a counter variable
*
+ * @return The number of characters copied.
+ *
* @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 )
+size_t do_str_copy_safe( char *dst, const char *src, size_t n )
{
- *p_i = 0;
+ size_t i = 0;
if ( n > 0 )
{
@@ -204,12 +214,14 @@ void do_str_copy_safe( char *dst, const char *src, size_t n, size_t *p_i )
break;
}
- (*p_i)++; // count normal characters
+ i++; // count normal characters
src++;
dst++;
}
}
+ return i;
+
} // do_str_copy_safe
@@ -239,9 +251,7 @@ void do_str_copy_safe( char *dst, const char *src, size_t n, size_t *p_i )
*/
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 );
+ do_str_copy_safe( dst, src, max_len );
return dst;
@@ -268,13 +278,11 @@ char *strncpy_safe( char *dst, const char *src, size_t max_len )
* @see ::strncpy_safe
* @see ::sn_cpy_char_safe
*/
-size_t sn_cpy_str_safe( char *dst, size_t max_len, const char *src )
+int 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 );
+ size_t n = do_str_copy_safe( dst, src, max_len );
- return i;
+ return _int_from_size_t( n );
} // sn_cpy_str_safe
@@ -300,17 +308,17 @@ size_t sn_cpy_str_safe( char *dst, size_t max_len, const char *src )
* @see ::strncpy_safe
* @see ::sn_cpy_str_safe
*/
-size_t sn_cpy_char_safe( char *dst, size_t max_len, char c )
+int sn_cpy_char_safe( char *dst, size_t max_len, char c )
{
- size_t i = 0;
+ size_t n;
char tmp_str[2];
tmp_str[0] = c;
tmp_str[1] = 0;
- do_str_copy_safe( dst, tmp_str, max_len, &i );
+ n = do_str_copy_safe( dst, tmp_str, max_len );
- return i;
+ return _int_from_size_t( n );
} // sn_cpy_char_safe
diff --git a/mbglib/common/str_util.h b/mbglib/common/str_util.h
index 3b49318..e4d7338 100755
--- a/mbglib/common/str_util.h
+++ b/mbglib/common/str_util.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: str_util.h 1.4 2017/05/10 15:26:10 martin REL_M $
+ * $Id: str_util.h 1.5 2018/06/25 13:24:15 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,8 @@
*
* -----------------------------------------------------------------------
* $Log: str_util.h $
+ * Revision 1.5 2018/06/25 13:24:15 martin
+ * Updated function prototypes.
* Revision 1.4 2017/05/10 15:26:10 martin
* Tiny cleanup.
* Revision 1.3 2016/12/14 16:22:24 martin
@@ -114,7 +116,7 @@ _ext const char *str_not_avail
* @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 ) ;
+ int __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()
@@ -133,7 +135,7 @@ _ext const char *str_not_avail
* @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, ... ) ;
+ int __attribute__( ( format( printf, 3, 4 ) ) ) snprintf_safe( char *s, size_t max_len, const char * fmt, ... ) ;
/**
* @brief A portable, safe implementation of strncpy()
@@ -177,7 +179,7 @@ _ext const char *str_not_avail
* @see ::strncpy_safe
* @see ::sn_cpy_char_safe
*/
- size_t sn_cpy_str_safe( char *dst, size_t max_len, const char *src ) ;
+ int 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
@@ -198,7 +200,7 @@ _ext const char *str_not_avail
* @see ::strncpy_safe
* @see ::sn_cpy_str_safe
*/
- size_t sn_cpy_char_safe( char *dst, size_t max_len, char c ) ;
+ int sn_cpy_char_safe( char *dst, size_t max_len, char c ) ;
/**
* @brief Trim whitespace at the end of a string
diff --git a/mbglib/common/words.h b/mbglib/common/words.h
index 3d4f2d5..d947bed 100755
--- a/mbglib/common/words.h
+++ b/mbglib/common/words.h
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: words.h 1.43 2018/01/29 10:30:23 martin REL_M $
+ * $Id: words.h 1.44 2018/06/25 09:21:02 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,9 @@
*
* -----------------------------------------------------------------------
* $Log: words.h $
+ * Revision 1.44 2018/06/25 09:21:02 martin
+ * Support MBG_TGT_NO_TGT.
+ * Improved STRINGIFY() macro.
* Revision 1.43 2018/01/29 10:30:23 martin
* Modified some comments.
* Revision 1.42 2017/07/26 14:28:50Z martin
@@ -144,7 +147,11 @@
#if !_IS_MBG_FIRMWARE
- #include <mbg_tgt.h>
+ #ifdef MBG_TGT_NO_TGT
+ #include <mbg_no_tgt.h>
+ #else
+ #include <mbg_tgt.h>
+ #endif
#else
#if defined( __ARMCC_VERSION ) // Keil RealView Compiler for ARM
#define __mbg_inline __inline
@@ -658,6 +665,17 @@ do \
/**
+ * @brief A helper macro to implement ::STRINGIFY correctly
+ *
+ * This just a helper macro which must be defined before
+ * ::STRINGIFY to work correctly, and should not be used alone.
+ *
+ * @see ::STRINGIFY
+ */
+#define XSTRINGIFY(x) #x
+
+
+/**
* @brief Make a string from a constant definition
*
* This macro can be used e.g. to define a constant string on the
diff --git a/ntptest.c b/ntptest.c
index 9bc84e8..ea63f4f 100755
--- a/ntptest.c
+++ b/ntptest.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: ntptest.c 1.13 2018/03/29 12:18:05 martin REL_M $
+ * $Id: ntptest.c 1.14 2018/07/31 16:14:14 martin REL_M $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -12,6 +12,12 @@
*
* -----------------------------------------------------------------------
* $Log: ntptest.c $
+ * Revision 1.14 2018/07/31 16:14:14 martin
+ * Changed version number to 1.10.
+ * Support symmetric MD5 keys.
+ * Configurable number for request packet mode.
+ * Print request packet even if no response was received.
+ * Support build on FreeBSD.
* Revision 1.13 2018/03/29 12:18:05 martin
* Don't print min/max results after single query.
* Changed version number to 1.9.
@@ -52,6 +58,10 @@
#include <mbg_ntp_test_util.h>
+#if defined( _USE_MBG_NTP_AUTH )
+ #include <mbg_ntp_auth.h>
+#endif
+
#include <mbgerror.h>
#include <timeutil.h>
@@ -63,6 +73,8 @@
#if defined( MBG_TGT_POSIX )
#include <unistd.h>
#include <netdb.h>
+ #include <netinet/in.h>
+ #include <sys/socket.h>
#endif
#include <stdio.h>
@@ -75,7 +87,7 @@
static const char program_name[] = "ntptest";
-static const char program_version[] = "v1.9";
+static const char program_version[] = "v1.10";
static const char program_copyright[] = "(c) Meinberg 2014-2018";
static const char program_contact[] = "contact: <martin.burnicki@meinberg.de>";
@@ -110,6 +122,7 @@ static int sleep_intv = MIN_SLEEP_INTV; // -s, (-u, -Z also on non-POSIX), slee
static int usleep_intv; // -u, -Z (POSIX only), short sleep interval between requests
#endif
static int prot_version; // -V, protocol version to be used
+static int req_mode = MODE_CLIENT; // -M, NTP packet mode sent in requests, "client" by default
static unsigned long rcv_timeout; // -T, [msec] receive timeout after request sent
static int print_packets; // print full packet details
static int verbose; // -v print more verbose output
@@ -125,6 +138,10 @@ static NTP_PACKET default_ntp_req_packet; // template of request packet
static QUERY_STATS glb_query_stats;
+#if defined( _USE_MBG_NTP_AUTH )
+ static NTP_KEY_ID md5_key_id;
+ static char md5_key[128];
+#endif
/*HDR*/
@@ -154,14 +171,16 @@ void do_ntp_queries( void )
fd_set read_set;
struct timeval tv_timeout;
NTP_PACKET_INFO req_info = { 0 }; // will be set up from template
- NTP_PACKET_INFO reply_info = { 0 };
+ NTP_PACKET_INFO resp_info = { 0 };
NTP_RESULTS rslt = { { 0 } };
+ #if defined( _USE_MBG_NTP_AUTH )
+ KEY_CACHE key_cache = { 0 };
+ #endif
MBG_SOCK_FD sock_fd;
int rc;
struct sockaddr_in si_src;
socklen_t slen_src;
-
sock_fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); // create socket on which to send
if ( sock_fd == MBG_INVALID_SOCK_FD )
@@ -177,18 +196,28 @@ void do_ntp_queries( void )
for (;;)
{
- // get time stamp when request packet was sent
+ struct timespec tsr;
+
+ // Get time stamp when request packet was sent.
clock_gettime( CLOCK_REALTIME, &req_info.tsr );
- // convert to NTP format and save in request packet
+ // Convert to NTP format and save in request packet.
timespec_to_ntp_tstamp( &req_info.packet.base.transmit_time, &req_info.tsr );
ntoh_ntp_time( &req_info.packet.base.transmit_time );
- // message authentication not yet supported, so only the base
- // packet is sent
req_info.len = NTP_BASE_PACKET_SIZE;
- // send request packet
+ #if defined( _USE_MBG_NTP_AUTH )
+ if ( md5_key_id )
+ {
+ int auth_code = mbg_ntp_auth_encrypt( &key_cache, &req_info, md5_key_id );
+
+ if ( auth_code != MBG_NTP_AUTH_OK )
+ mbglog( LOG_WARNING, "Failed to encrypt request packet with key %i", md5_key_id );
+ }
+ #endif
+
+ // Send request packet.
if ( sendto( sock_fd, (void *) &req_info.packet, req_info.len, 0,
(__const__ struct sockaddr *) &tgt_addr,
sizeof( tgt_addr ) ) == MBG_SOCKET_ERR_RETVAL )
@@ -209,6 +238,10 @@ void do_ntp_queries( void )
rc = select( sock_fd + 1, &read_set, NULL, NULL, &tv_timeout );
+ // Take a receive time stamp here, but discard it
+ // in case of an error.
+ clock_gettime( CLOCK_REALTIME, &tsr );
+
if ( rc == MBG_SOCKET_ERR_RETVAL ) // select() failed
{
mbglog( LOG_ERR, "Select failed in %s: %s", __func__,
@@ -216,36 +249,53 @@ void do_ntp_queries( void )
break;
}
- if ( rc == 0 ) // timeout
+ if ( rc == 0 ) // Timeout.
{
- mbglog( LOG_ERR, "Select timed out" );
+ // Eventually print at least the request packet.
+ if ( print_packets )
+ {
+ // Adjust the endianess of the request packet first.
+ ntoh_ntp_packet( &req_info );
+ print_ntp_results( NULL, &req_info, NULL, NULL, 1, verbose );
+ }
+
+ mbglog( LOG_ERR, "Select timed out, received no response." );
goto cont;
}
- // read response packet
+ // Read response packet.
slen_src = sizeof( si_src );
- reply_info.len = recvfrom( sock_fd, (void *) &reply_info.packet, sizeof( reply_info.packet ),
- 0, (struct sockaddr *) &si_src, &slen_src );
+ resp_info.len = recvfrom( sock_fd, (void *) &resp_info.packet, sizeof( resp_info.packet ),
+ 0, (struct sockaddr *) &si_src, &slen_src );
- if ( reply_info.len == MBG_SOCKET_ERR_RETVAL )
+ if ( resp_info.len == MBG_SOCKET_ERR_RETVAL )
{
mbglog( LOG_ERR, "Failed to receive from UDP socket: %s",
mbg_strerror( mbg_get_last_socket_error( NULL ) ) );
goto cont;
}
- // get time stamp when response was received
- clock_gettime( CLOCK_REALTIME, &reply_info.tsr );
+ // Use the receive time stamp taken earlier.
+ resp_info.tsr = tsr;
+
+ // Authentication must be checked *before* byte order is adjusted
+ #if defined( _USE_MBG_NTP_AUTH )
+ rslt.auth_code = mbg_ntp_auth_decrypt( &key_cache, &resp_info );
+ #else
+ rslt.auth_code = MBG_NTP_AUTH_NONE;
+ #endif
- eval_ntp_packet( &rslt, &reply_info, &glb_query_stats );
+ eval_ntp_packet( &rslt, &resp_info, &glb_query_stats );
+
+ // Adjust byte order of the request packet.
ntoh_ntp_packet( &req_info );
if ( print_packets )
- print_ntp_results( &rslt, &req_info, &reply_info,
- run_continuously ? &glb_query_stats : NULL, 1, verbose );
+ print_ntp_results( &rslt, &req_info, &resp_info, run_continuously ?
+ &glb_query_stats : NULL, 1, verbose );
else
{
- NTP_PACKET *p = &reply_info.packet;
+ NTP_PACKET *p = &resp_info.packet;
if ( compensate_initial_offset )
{
@@ -278,17 +328,17 @@ void do_ntp_queries( void )
printf( ", spoll: %u", p->base.flags.poll );
if ( verbose > 1 )
- printf( ", disp[s/s]: %.4f", _u_fp_to_d( p->base.root_dispersion ) );
+ printf( ", disp[s/s]: %.6f", _u_fp_to_d( p->base.root_dispersion ) );
if ( leap_smearing_active( &p->base.refid, &d ) || ( verbose > 2 ) )
printf( ", smear[s]: %.6f", d );
}
-
- printf( "\n" );
- fflush( NULL );
}
cont:
+ printf( "\n" );
+ fflush( NULL );
+
if ( !run_continuously )
break;
@@ -326,6 +376,7 @@ void usage( void )
printf( " -c run continuously, print summary output unless verbose\n" );
printf( " -s n n seconds delay between queries, default: %i s\n", sleep_intv );
printf( " -v verbose, print full packets even in continuous mode\n" );
+ printf( " -M mode send NTP request packets with specified mode\n" );
printf( " -V n NTP protocol version, %i..%i, default: %i\n",
MIN_REQ_NTP_VERSION, MAX_REQ_NTP_VERSION, DEFAULT_REQ_NTP_VERSION );
printf( " -P n NTP client poll value sent to server, default: %i\n", DEFAULT_CLIENT_POLL_VALUE );
@@ -333,6 +384,11 @@ void usage( void )
printf( " -Z send 4 req/s to server, print time, offset changes and status summary\n" );
printf( " e.g. for leap second tests\n" );
+#if defined( _USE_MBG_NTP_AUTH )
+ printf( " -m key_id use MD5 trusted key key_id for NTP authentication\n" );
+ printf( " -k key the alphanumeric MD5 key for NTP authentication\n" );
+#endif
+
#if defined( MBG_TGT_WIN32 )
printf( " -L use legacy system time function even if precise time is supported\n" );
#endif
@@ -355,7 +411,7 @@ void check_options( int argc, char *argv[] )
#define WIN32_OPTS
#endif
- while ( ( c = getopt( argc, argv, "cs:vV:P:T:Zh?" WIN32_OPTS ) ) != -1 )
+ while ( ( c = getopt( argc, argv, "cs:k:m:vM:P:T:V:Zh?" WIN32_OPTS ) ) != -1 )
{
switch ( c )
{
@@ -374,13 +430,32 @@ void check_options( int argc, char *argv[] )
break;
+ #if defined( _USE_MBG_NTP_AUTH )
+ case 'k':
+ strncpy( md5_key, optarg, sizeof( md5_key ) - 1 );
+ break;
+ #endif
+
+
+ #if defined( _USE_MBG_NTP_AUTH )
+ case 'm':
+ md5_key_id = strtol( optarg, NULL, 10 );
+ break;
+ #endif
+
+
case 'v':
verbose++;
break;
- case 'V':
- prot_version = strtol( optarg, NULL, 10 );
+ case 'M':
+ req_mode = strtol( optarg, NULL, 10 );
+ break;
+
+
+ case 'P':
+ client_poll_value = (uint8_t) strtol( optarg, NULL, 10 );
break;
@@ -389,8 +464,8 @@ void check_options( int argc, char *argv[] )
break;
- case 'P':
- client_poll_value = (uint8_t) strtol( optarg, NULL, 10 );
+ case 'V':
+ prot_version = strtol( optarg, NULL, 10 );
break;
@@ -491,7 +566,29 @@ int main( int argc, char *argv[] )
reset_query_stats( &glb_query_stats );
// setup packet templates
- init_ntp_req_packet( &default_ntp_req_packet, MODE_CLIENT, prot_version );
+ init_ntp_req_packet( &default_ntp_req_packet, req_mode, prot_version );
+
+ #if defined( _USE_MBG_NTP_AUTH )
+ // Setup authentication support
+ mbg_ntp_auth_init();
+
+ if ( md5_key_id ) // A key ID has been specified on the command line
+ {
+ // If also a key (secret) has been specified on the command line,
+ // add the key plus ID to the known keys.
+ if ( strlen( md5_key ) )
+ mbg_ntp_auth_add_key( md5_key_id, "MD5", md5_key );
+
+ // Make the key with the specified ID a "trusted" key.
+ mbg_ntp_auth_trust_key( md5_key_id, 1 );
+ }
+
+ #if DEBUG_MBG_NTP_AUTH
+ if ( md5_key_id )
+ mbg_ntp_auth_test( md5_key_id );
+ #endif
+
+ #endif // defined( _USE_MBG_NTP_AUTH )
printf( "Host %s%s\n", tgt_host, run_continuously ? ", running continuously" : "" );
diff --git a/unix/BSDmakefile b/unix/BSDmakefile
new file mode 100755
index 0000000..5c57a4f
--- /dev/null
+++ b/unix/BSDmakefile
@@ -0,0 +1,85 @@
+
+#########################################################################
+#
+# $Id: BSDmakefile 1.2 2018/07/31 16:03:33 martin REL_M $
+#
+# Description:
+# Makefile for ntptest on *BSD.
+#
+# -----------------------------------------------------------------------
+# $Log: BSDmakefile $
+# Revision 1.2 2018/07/31 16:03:33 martin
+# Conditionally support NTP auth.
+# Revision 1.1 2018/07/31 12:14:44 martin
+# Initial revision.
+#
+#########################################################################
+
+V ?= 0 # set to 1 to build verbosely
+
+USE_MBG_NTP_AUTH ?= 1
+
+# The lines below make the build output non-verbose by default.
+# Call make with parameter "V=1" to get verbose output.
+.if $(V) != 0
+ Q :=
+ QM :=
+ vecho = @true
+.else
+ Q := @
+ QM := -s
+ vecho = @echo
+.endif
+
+TARGET = ntptest
+
+OBJS = $(TARGET).o
+OBJS += mbgntp.o
+OBJS += mbg_ntp_test_util.o
+OBJS += timeutil.o
+OBJS += str_util.o
+OBJS += mbgerror.o
+
+.ifdef DEBUG
+ CPPFLAGS += -g2
+ CPPFLAGS += -DDEBUG=$(DEBUG)
+.else
+ CPPFLAGS += -O2
+.endif
+
+CPPFLAGS += -Wall
+CPPFLAGS += -I../mbglib/common
+
+# Conditionally support NTP authentication
+.if $(USE_MBG_NTP_AUTH) != 0
+ CPPFLAGS += -D_USE_MBG_NTP_AUTH=$(USE_MBG_NTP_AUTH)
+
+ OBJS += mbg_ntp_auth.o
+
+ LDFLAGS += -lcrypto
+ LDFLAGS += -lm # requires the math library
+.endif
+
+CFLAGS = $(CPPFLAGS)
+
+VPATH = ..:../mbglib/common
+
+
+.c.o:
+ $(vecho) " $(CC) ${.IMPSRC}"
+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -o ${.TARGET} -c ${.IMPSRC}
+
+
+.PHONY: all
+all: $(TARGET)
+
+$(TARGET): $(OBJS)
+ $(vecho) " Linking $@"
+ $(Q)$(CC) -o $@ $(OBJS) $(LDFLAGS)
+
+
+.PHONY: clean
+clean:
+ rm -f *.o *~ core
+ rm -f $(TARGET)
+
diff --git a/unix/Makefile b/unix/Makefile
index 9ad5b1d..dc9319f 100755
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -1,13 +1,17 @@
#########################################################################
#
-# $Id: Makefile 1.4 2018/03/09 09:58:03 martin REL_M $
+# $Id: Makefile 1.6 2018/07/31 16:03:44 martin REL_M $
#
# Description:
# Makefile for ntptest.
#
# -----------------------------------------------------------------------
# $Log: Makefile $
+# Revision 1.6 2018/07/31 16:03:44 martin
+# Conditionally support NTP auth.
+# Revision 1.5 2018/07/31 12:13:11 martin
+# Support silent build.
# Revision 1.4 2018/03/09 09:58:03 martin
# Added new module mbgntp.o.
# Revision 1.2 2016/08/05 12:40:28 martin
@@ -19,6 +23,23 @@
#
#########################################################################
+V ?= 0 # set to 1 to build verbosely
+
+USE_MBG_NTP_AUTH ?= 1
+
+
+# The lines below make the build output non-verbose by default.
+# Call make with parameter "V=1" to get verbose output.
+ifeq ("$(V)","1")
+ Q :=
+ QM :=
+ vecho = @true
+else
+ Q := @
+ QM := -s
+ vecho = @echo
+endif
+
TARGET = ntptest
MBGLIB = ../mbglib
@@ -43,14 +64,32 @@ CPPFLAGS += $(foreach dir,$(MBGLIB_DIRS),-I$(MBGLIB)/$(dir))
LDFLAGS += -lrt
+# conditionally support NTP authentication
+ifneq ("$(USE_MBG_NTP_AUTH)","0")
+ CPPFLAGS += -D_USE_MBG_NTP_AUTH=$(USE_MBG_NTP_AUTH)
+
+ OBJS += mbg_ntp_auth.o
+
+ LDFLAGS += -lcrypto
+ LDFLAGS += -lm # requires the math library
+endif
+
VPATH += ..
VPATH += $(foreach dir,$(MBGLIB_DIRS),$(MBGLIB)/$(dir))
+%.o: %.c
+ $(vecho) " $(CC) $@"
+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
+
+
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJS)
+ $(vecho) " Linking $@"
+ $(Q)$(CC) -o $@ $^ $(LDFLAGS)
+
.PHONY: clean
clean: