diff options
author | Martin Burnicki <martin.burnicki@meinberg.de> | 2018-07-31 12:00:00 +0200 |
---|---|---|
committer | Martin Burnicki <martin.burnicki@meinberg.de> | 2018-07-31 12:00:00 +0200 |
commit | 54ad38deb28269fc8b74173a4f513adab13dd503 (patch) | |
tree | f4fbf284921d0e6578506efd29bf0757e4e45ab0 | |
parent | 6b78f35618249cc4cd82f68ee868b7758145b0a1 (diff) | |
download | ntptest-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-x | mbglib/common/gpsdefs.h | 3811 | ||||
-rwxr-xr-x | mbglib/common/mbg_ntp_auth.c | 1925 | ||||
-rwxr-xr-x | mbglib/common/mbg_ntp_auth.h | 173 | ||||
-rwxr-xr-x | mbglib/common/mbg_ntp_test_util.c | 68 | ||||
-rwxr-xr-x | mbglib/common/mbg_tgt.h | 162 | ||||
-rwxr-xr-x | mbglib/common/mbgerror.c | 477 | ||||
-rwxr-xr-x | mbglib/common/mbgerror.h | 311 | ||||
-rwxr-xr-x | mbglib/common/mbgntp.h | 33 | ||||
-rwxr-xr-x | mbglib/common/str_util.c | 48 | ||||
-rwxr-xr-x | mbglib/common/str_util.h | 12 | ||||
-rwxr-xr-x | mbglib/common/words.h | 22 | ||||
-rwxr-xr-x | ntptest.c | 159 | ||||
-rwxr-xr-x | unix/BSDmakefile | 85 | ||||
-rwxr-xr-x | unix/Makefile | 41 |
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 @@ -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: |