diff options
author | Martin Burnicki <martin.burnicki@meinberg.de> | 2023-02-28 23:13:18 +0100 |
---|---|---|
committer | Martin Burnicki <martin.burnicki@meinberg.de> | 2023-02-28 23:13:18 +0100 |
commit | 5e9bcf9738855d8371f15fc12cb934197056b4dc (patch) | |
tree | cd4e2c0e06714630b5eae51e543a3d2da320d739 | |
parent | 31dc5b6f6a84517a0e7b7f2fe4c49210771992fa (diff) | |
download | mbgreadtimestring-5e9bcf9738855d8371f15fc12cb934197056b4dc.tar.gz mbgreadtimestring-5e9bcf9738855d8371f15fc12cb934197056b4dc.zip |
Add mbglib files that are now required
-rw-r--r-- | mbglib/common/gpsdefs.h | 27521 | ||||
-rw-r--r-- | mbglib/common/mbgerror.c | 1215 | ||||
-rw-r--r-- | mbglib/common/mbgerror.h | 980 | ||||
-rw-r--r-- | mbglib/common/mbgtime.h | 1650 | ||||
-rw-r--r-- | mbglib/common/str_util.c | 477 | ||||
-rw-r--r-- | mbglib/common/str_util.h | 391 | ||||
-rw-r--r-- | mbglib/common/use_pack.h | 45 |
7 files changed, 32279 insertions, 0 deletions
diff --git a/mbglib/common/gpsdefs.h b/mbglib/common/gpsdefs.h new file mode 100644 index 0000000..2b329ab --- /dev/null +++ b/mbglib/common/gpsdefs.h @@ -0,0 +1,27521 @@ + +/************************************************************************** + * + * $Id: gpsdefs.h 1.127.3.1 2022/12/15 16:02:41 martin.burnicki REL_M $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * General definitions to be used with Meinberg clocks. + * These definitions have initially be used with GPS devices only. + * However, more and more Meinberg non-GPS devices also use some of + * these definitions. + * + * ----------------------------------------------------------------------- + * $Log: gpsdefs.h $ + * Revision 1.127.3.1 2022/12/15 16:02:41 martin.burnicki + * Fix potential compiler warnings, and optionally exclude code + * from build using preprocessor symbol OMIT_PTPV2. + * Revision 1.127 2019/09/27 13:10:17Z martin + * New model codes MSHPS100, BPE_STM, VSI180, + * GNM181, RSCRDU_TTL, RSC2000, FCU200, REL1000_RC. + * Replaced old model CSM100 by MSSB100. + * Replaced old model USYNCPWR by CPC200. + * New PTP configuration structures. + * New PTP SMPTE stuff. + * Some extension of NTP configuration. + * XMR_QL_INFO was added to XMR API. + * Port types SPST and SPDT and some other IO stuff was added. + * New XBP device state 'outdated'. + * New MBG_EXT_SYS_STATUS stuff. + * New MBG_EVENTS stuff. + * New FCU stuff. + * New sysinfo definitions. + * New bit mask GNSS_SV_STAT_DUAL_FREQ_MSK. + * Updated some SyncE definitions. + * New string table initializers. + * New types GPS_WNUM, GPS_WSEC, and GPS_TICK. + * New types MBG_MSG_IDX and MBG_MSG_IDX_32. + * Struct names were added by thomas-b to support forward declarations. + * Added an enumeration MBG_DEV_CPU_TYPES and as well as an + * initializer MBG_DEV_CPU_TYPE_TABLE_INIT for a table indicating + * which CPU type is used on which hardware device. + * Renamed type TM_STATUS_EXT to TM_GPS_STATUS_EXT, which is + * more similar to the name TM_GPS_STATUS, but provided a #define + * to avoid build problems with existing code. + * Moved some structures here that were previously private. + * Moved definitions of ANN_LIMIT and ANN_LIMIT_DCF here. + * Lots of doxygen updates. + * 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_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, + * GPS_MODEL_GPS165, GPS_MODEL_GNS181_UC, GPS_MODEL_PSX_4GE, + * GPS_MODEL_RSC180RDU, GPS_MODEL_USYNCPWR, GPS_MODEL_FDM180M, + * GPS_MODEL_LSG180, GPS_MODEL_GPS190, GPS_MODEL_GNS181 and + * associated definitions. + * New GPS_BUILTIN_FEATURE_BITS and associated definitions. + * New macros _setup_default_receiver_info_dcf() and + * _setup_default_receiver_info_gps() as well as associated + * definitions which can be used to set up a RECEIVER_INFO + * structure for legacy devices which don't provide it. + * New Receiver_INO feature bit GPS_FEAT_XFEATURE which + * indicates that a new, extended feature set is supported. + * Defined a new st of extended features (MBG_XFEATURE_BITS) + * and associated definitions. + * Moved definitions for NANO_TIME and NANO_TIME_64 to words.h. + * New IRIG TX codes ICODE_TX_A006_A136, ICODE_TX_A007_A137, + * and associated definitions. + * Renamed ICODE_RX_G142_G146 to ICODE_RX_G142, and + * ICODE_RX_G002_G006 to ICODE_RX_G002. + * New IRIG RX codes ICODE_RX_A136_A137, ICODE_RX_A006_A007, + * ICODE_RX_G146, ICODE_RX_G006, and associated definitions. + * New union POUT_DATA union used for varying configuration + * data in POUT_SETTINGS, depending on the output mode. + * New POUT_MODES POUT_PTTI_PPS, POUT_HAVEQUICK, and + * associated definitions. + * Definitions to support a configurable pulse shift + * of some programmable output signals. + * New multiref source MULTI_REF_SYNCE and associated + * definitions. + * Added a number of swab..() macros that were still missing. + * XMR statistics, XMR_QL and some other XMR stuff by andre. + * New GPIO types including video modes, and associated stuff. + * Renamed some structure fields and added some definitions + * related to FDM. + * Added some SCU_STAT_MASKS. + * New GNSS_TYPE_QZSS, and modified MBG_GNSS_MODE_INFO. + * New flag MBG_GNSS_FLAG_HAS_SV_STATUS, structure + * GNSS_SV_STATUS and associated definitions. + * A bunch of new structures and definitions for network + * configuration. + * Many new structures and definitions for NTP configuration. + * New structures and associated definitions used to send + * user capture events over the network (ext_ucap). + * New PTP_ROLES and associated stuff. + * Changed one of PTP_STATE's reserved fields to tsu_secs. + * Changed PTP_ANN_RCPT_TIMEOUT_MAX from 255 to 8. + * New PTP_CFG_FLAGS, PTP_OPT_EXTS flags, PTP_PRESETS_MASKS + * and associated definitions. + * Definitions for PTPv1 and v2 data sets, and PTP statistics. + * Preliminary definitions to support SMPTE and SDH. + * Definition for XBP addressing of devices. + * Definitions to support TLVs. + * Added LED and LNE API definitions. + * MBG_EXT_SYS_INFO_BITS and associated definitions for an + * extended sysinfo API. + * MBG_CLK_RES_INFO and associated stuff for clock resolution + * info. + * Definitions for configuration transaction handling. + * Definitions for a higher level I/O port API. + * Definitions for monitoring / notification. + * Definitions for USB locking. + * Preliminary licensing stuff. + * Defined macros in a safer way. + * Revision 1.124 2015/07/14 14:22:46 martin + * Doxygen fix. + * Revision 1.123 2015/07/06 13:00:10 martin + * Added definitions for VSG180, MSF180, WWVB180, and CPC180. + * Added definitions for PZF180. + * Definitions for SDI and MDU300 added by stephan. + * Definitions for HPS100 added by daniel. + * FDM180 and associated definitions added by paul. + * Started to support eXtended Binary Protocol (XBP). + * Merged daniel and gregoire's changes from the 1.120.2.x branch. + * Defines for IPv6 multicast scopes added by gregoire. + * XMR_EXT_SRC_INFO and associated XMR_SETTINGS_FLAG_MSKS flags + * defined by andre. + * Support XMULTI_REF_INFO::n_prio field again. + * Fixed _mbg_swab_gpio_cfg_limits() macro. + * Added MBG_NET_LINK_OPT_MASK_CAN_SYNCE to MBG_NET_LINK_OPT_MASKS. + * New PTP_ROLE_MASKS PTP_ROLE_NTP_SERVER and PTP_ROLE_NTP_CLIENT. + * Some PTP profile extensions added by daniel. + * Added missing defines for SPT. + * Added definitions for REL1000. + * Moved structure NANO_TIME_64 here. + * Revision 1.122 2014/07/29 08:57:44Z martin + * Updated doxygen comments. + * Revision 1.121 2014/07/17 09:41:50 martin + * Introduced XMR_HOLDOVER_STATUS, MBG_GPIO_STATUS, + * and associated definitions. + * Huge update and cleanup on doxygen comments. + * Revision 1.120 2014/05/27 08:34:40 martin + * Fixed braces in some _mbg_rcvr_is_..() macros. + * Definitions used with extended network cfg, VST, and SHS. + * Introduced XMR_HOLDOVER_STATUS. + * Introduced programmable output mode POUT_GPIO. + * Introduced oscillator type OCXO_SQ. + * Defined some new baud rates. + * Defines for IEEE C37.118.1-2011 CTQ. + * Support for new model SCG by paul. + * Support new model PPG180. + * New SCU control masks. + * New GNSS flag MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER. + * DEFAULT_MULTI_REF_NAMES_SHORT added by udo. + * Definitions used for NTP configuration by thomas-b and marvin. + * MBG_NET_ADDR structures changed to MBG_IP_ADDR, and + * associated symbols defined by marvin. + * Huge rework of comments in doxygen format. + * Revision 1.119 2013/12/05 10:13:13 daniel + * Support new PTP_CFG_FLAGS for 1-step-L2 and 1-step-P2P support + * Revision 1.118 2013/11/19 13:38:35 martin + * Added LAN_IF_TYPE_RSC. + * Revision 1.117 2013/11/18 14:13:39 martin + * Support model LNE_GB. + * Revision 1.116 2013/11/11 09:46:11 martin + * New PTP configuration flags PTP_CFG_SUPP_MCAST_SLAVE_FLAG and + * PTP_CFG_CAN_BE_MULTICAST_SLAVE, plus associated bit masks. + * New XMR_INST_FLAGS and XMR_INST_FLAG_MASKS defined by andre. + * Fixes for big-endian targets. + * Updated doxygen comments. + * Revision 1.115 2013/10/02 15:19:28 martin + * Changed PTP_CFG_SETTINGS::vlan_cfg back to a reserved field, + * and removed associated flag and flag mask. + * Revision 1.114 2013/09/25 11:02:10 martin + * Support models MRI, BPE, GLN180PEX, N2X, RSC180. + * Added feature bit GPS_FEAT_NTP. + * Enhanced VLAN configuration structures. + * Started to support IPv6. + * Renamed PTP_CFG_SETTINGS field "profile" to "selected_presets". + * Renamed PTP_CFG_INFO field "supp_profiles" to "supp_opt_ext". + * New PTP role PTP_ROLE_BOTH_MASTER. + * New PTP flag PTP_FLAG_ONE_STEP. + * Added some new PTP_CFG_FLAGS flags. + * Added PTP_OPT_EXTS and associated definitions. + * Added PTP_PRESETS and associated definitions. + * Added "tzdl" field to PTP_POWER_PROFILE_CFG. + * Made reserved PTP_CFG_SETTINGS field to "opt_ext" field. + * Made reserved PTP_CFG_SETTINGS field to "vlan_cfg" field. + * Made reserved PTP_STATE field to "parent_clock_class" and "parent_clock_accuracy". + * Definitions for MULTI_REF_EXT_OSC added by Andre. + * String initializers for supported HaveQuick formats added by Gregoire. + * Lots of doxygen changes. + * Revision 1.113 2013/04/04 09:02:01Z martin + * Added definitions to support HaveQuick. + * Fixed a typo. + * Revision 1.112 2013/02/19 15:39:13 martin + * New PTP settings field ann_rcpt_timeout and associated + * values PTP_ANN_RCPT_TIMEOUT_LIMITS. + * Changed many defines to named enums to simplify references + * with doxygen. + * Updated doxygen comments. + * Revision 1.111 2013/02/01 15:37:36 martin + * Added and modified a huge number of doxygen comments. + * Revision 1.110 2013/01/16 15:23:25 martin + * Fixed 2 comments which were interchanged. + * Revision 1.109 2013/01/11 10:39:34 martin + * Added definitions for IMS. + * Support XMR_HOLDOVER_INTV. + * New XMRS status bit XMRS_BIT_LOW_JITTER / XMRS_MSK_LOW_JITTER. + * Added framing type 8E2, though most UARTs don't support this. + * Added enum names and updated comments for doxygen. + * Revision 1.108 2012/10/30 11:31:16 martin + * Defined PTP_UC_MSG_DURATION_MIN and PTP_UC_MSG_DURATION_MAX. + * Fixed some doxygen comments. + * Changes by andre: changed reserved field to ssm and boc in BITS_OUT settings. + * Revision 1.107 2012/10/12 07:40:12 martin + * New PTP state flags PTP_FLAG_MSK_UTC_VALID and + * PTP_CFG_MSK_SUPP_UTC_VALID. + * Revision 1.106 2012/10/02 18:22:10 martin + * Added default baud rate and framing for binary protocol. + * Added definitions for IRIG codes E002/E112 and NASA36. + * Reworked GPIO structures. + * Added definitions for GRC, LIU, DCF600RS, and DCF600HS. + * New flag POUT_FIXED_PULSE_LEN. + * New flag POUT_NOT_INVERTIBLE. + * Unified capitalization in MBG_XMRS_STATUS_STRS. + * Revision 1.105 2012/06/01 16:31:16 martin + * Some TIME_SLOT definitions added by marvin. + * Moved some PTP configuration defaults and limits to ptpdflts.h. + * Revision 1.104 2012/04/11 16:02:55Z martin + * Fixed some doxygen comments. + * Revision 1.103 2012/04/02 11:08:57Z martin + * Extended description of GPS UTC/leap second data. + * Revision 1.102 2012/03/16 11:43:31 martin + * Fixed a potential compiler warning. + * Revision 1.101 2012/03/06 16:56:01Z martin + * Added support for PTP multicast auto role. + * Merged Daniel's definitions for PTP profile support. + * Support time slot mode for programmable pulse outputs. + * Support LNO180. + * Moved definition of MBG_MAC_ADDR here. + * Use MBG_MAC_ADDR in definition of LAN_IF_INFO. + * Revision 1.100 2012/01/17 13:33:55 martin + * Added new IRIG RX delay compensation code groups for G0xx and G1xx codes. + * As a consequence the value of N_IRIG_RX_COMP has changed. + * Added definition of IRIG_RX_COMP_MAX. + * Updated IRIG code classification macros. + * Removed obsolete/unused definition of CAL_REC_INFO. + * Added some comments. + * Revision 1.99 2011/12/09 09:22:03 martin + * Fixed a typo. + * Revision 1.98 2011/11/25 14:58:34 martin + * Renamed some evt_log definitions. + * Revision 1.97 2011/11/25 10:11:17 martin + * Initializers for XMRS status bit strings added by gregoire. + * New feature GPS_FEAT_EVT_LOG. + * Added definitions used with event logs. + * Moved cal_reg and gen_io stuff here. + * Added macro _mbg_swab_debug_status(). + * Updated some comments. + * Revision 1.96 2011/10/11 13:40:46Z andre + * changed reserved field into slot_id in XMULTI_REF_INSTANCES + * Revision 1.95.1.1 2011/10/07 09:31:58Z andre + * Revision 1.95 2011/10/04 09:35:41Z martin + * Added support for ESI180. + * Changed RECEIVER_INFO::flags bit GPS_10MHZ_DISBD to a RECEIVER_INFO::features bit. + * Support MULTI_REF_INTERNAL, MULTI_REF_LWR and MULTI_REF_PZF. + * Added MBG_GPIO_BITS structure and associated definitions. + * Revision 1.94 2011/08/25 07:42:43Z martin + * Fixed a bug in macro _mbg_swab_pout_settings() where the 16 bit timeout + * field was swapped using a macro for 32 bit types. + * Use shorter names for some PTP unicast master default values. + * Revision 1.93 2011/08/10 08:19:38Z martin + * New PORT_INFO and PORT_SETTINGS flag PORT_FLAG_PORT_INVISIBLE. + * Revision 1.92 2011/07/29 09:49:35 martin + * Support PZF180PEX, MGR180, MSF600, WWVB600, JJY600, + * GPS180HS, and GPS180AMC. + * Added receiver info features GPS_FEAT_PTP_UNICAST + * and GPS_FEAT_XMRS_MULT_INSTC. + * Added receiver info flag bit GPS_10MHZ_DISBD. + * Added initializers for PTP timescale names. + * New PTP_STATE flags bit PTP_FLAG_MSK_IS_UNICAST. + * Made unused PTP_STATE fields num_clients and num_masters reserved. + * Account for different PTP roles. + * Added / renamed some definitions for PTP. + * Modified default string for PTP layer 2 protocol. + * Support PTP unicast configuration. + * Support GPIO configuration. + * Introduced XMULTI_REF_INSTANCES. + * Moved flags XMRS_..._IS_EXTERNAL and XMRS_..._INSTC_EXCEEDED + * to definitions for XMULTI_REF_STATUS::status. + * Some comments added, updated, and converted to doxygen style. + * Cleaned up handling of pragma pack(). + * Removed trailing whitespace and hard tabs. + * Revision 1.91 2011/01/31 11:23:56Z martin + * Added model type name definitions for GPS180PEX and TCR180PEX. + * Introduced synthesizer mode for programmable outputs. + * Added IRIG-RX code TXC-101 DTR-6. + * Fixed missing comma bugs in DEFAULT_GPS_MODEL_NAMES. + * Fixed missing comma bugs in some IRIG string initializers. + * Fixed AFNOR notation. + * Modified some comments for doxygen. + * Revision 1.90 2010/10/15 11:47:53 martin + * Added definitions POUT_TIMEBASE_UTC and POUT_SUPP_DCF77_UTC. + * Added receiver info feature GPS_FEAT_RAW_IRIG_TIME. + * Support IRIG format C37.118. + * Added initializers for short IRIG code names. + * Cleaned up IRIG definitions and comments. + * Revision 1.89 2010/09/06 07:40:02Z martin + * Picked up Daniel's definitions for multi GNSS support. + * Moved MBG_IRIG_CTRL_BITS, MBG_RAW_IRIG_DATA and related definitions + * from pcpsdefs.h here. + * Added macros _pcps_tfom_from_irig_ctrl_bits() + * and _pcps_tfom_from_raw_irig_data(). + * Added RI_FEATURES type. + * Revision 1.88 2010/04/21 13:47:54 daniel + * Added support for new model GLN170. + * Revision 1.87 2010/03/10 11:29:37Z martin + * Added definitions for GPS180. + * Added multi ref source 1 PPS plus associated string. + * Revision 1.86 2010/02/17 14:16:42 martin + * Added definitions for PZF600 and TCR600. + * Revision 1.85 2010/02/15 11:34:36 martin + * Changed definition of PTP_TABLE::name to const char *. + * Added definitions to support new model JJY511. + * Revision 1.84 2010/02/01 13:20:50 martin + * Support programmable outputs being disabled when sync. is lost. + * Revision 1.83 2010/01/28 09:15:50 martin + * Added new POUT mode DCF77_M59 and associated definitions. + * Revision 1.82 2010/01/07 09:04:55 martin + * Added XMR status bit XMRS_BIT_NOT_PHASE_LOCKED. + * Revision 1.81 2009/11/09 09:08:24 martin + * New TM_GPS status bit TM_INVT. + * Added definitions to support VLAN. + * Changed DEFAULT_PTP_DELAY_MECH_MASK to include also + * PTP_DELAY_MECH_MSK_P2P. + * There is now only one type of TCXO supported which matches the former + * TCXO HQ, so the default name for TCXO HQ has been changed to TCXO. + * TCXO LQ and MQ names are still supported for backward compatibility. + * Revision 1.80 2009/09/28 14:55:53 martin + * Support IRIG formats G002/G142 and G006/G146. + * Modified IRIG format description strings. + * Revision 1.79 2009/08/12 14:12:38 daniel + * Added definitions to support new model MGR170. + * Added definitions and commands to support configuration + * of navigation engine (currently supported by u-blox + * receivers only). + * Renamed simulation values in PTP_SETTINGS to reserved. + * Added "UNINITIALIZED" to PTP port state. + * Removed obsolete braces in initializer. + * Revision 1.78 2009/06/25 15:49:05Z martin + * Added macro _nano_time_negative(). + * Revision 1.77 2009/06/08 19:22:32Z daniel + * Added feature GPS_HAS_PTP. + * Added preliminary structures and definitions for PTP + * configuration and state. + * Added IP4_ADDR type. + * Added Bitmask IP4_MSK_DHCP. + * Added byte swapper macros for LAN and PTP structures. + * Moved LAN interface configuration definitions here. + * Moved DAC_VAL definition here. + * Changed type iof FPGA_INFO::start_addr for non-firmware applications. + * Revision 1.76 2009/04/08 08:26:56 daniel + * Added feature GPS_FEAT_IRIG_CTRL_BITS. + * Revision 1.75 2009/03/19 14:06:39Z martin + * Modified string initializer for unknown oscillator type. + * Revision 1.74 2009/03/18 13:45:53 daniel + * Added missing commas in + * MBG_DEBUG_STATUS_STRS initializer. + * Adjusted some comments for doxygen parser. + * Revision 1.73 2009/03/10 16:55:33Z martin + * Support configurable time scales GPS and TAI. + * Defined extended TM status type and associated flags. + * Added definition TM_MSK_TIME_VALID. + * Added some macros to swap endianess of structures. + * Revision 1.72 2008/11/28 09:26:21Z daniel + * Added definitions to support WWVB511 + * Revision 1.71 2008/10/31 14:31:44Z martin + * Added definitions for TCR170PEX. + * Revision 1.70 2008/09/18 11:14:39 martin + * Added definitions to support GEN170. + * Revision 1.69 2008/09/15 14:16:17 martin + * Added more macros to convert the endianess of structures. + * Added N_COM_HS to the enumeration of handshake modes. + * Added MBG_PS_... codes. + * Revision 1.68 2008/08/25 10:51:13 martin + * Added definitions for PTP270PEX and FRC511PEX. + * Revision 1.67 2008/07/17 08:54:52Z martin + * Added macros to convert the endianess of structures. + * Added multi ref fixed frequency source. + * Revision 1.66 2008/05/19 14:49:07 daniel + * Renamed s_addr to start_addr in FPGA_INFO. + * Revision 1.65 2008/05/19 09:00:01Z martin + * Added definitions for GPS162. + * Added FPGA_INFO and GPS_HAS_FPGA. + * Added FPGA_START_INFO and associated definitions. + * Added new XMRS status XMRS_..._NOT_SETTLED. + * Added initializer XMULTI_REF_STATUS_INVALID. + * Revision 1.64 2008/01/17 11:50:33Z daniel + * Made IGNORE_LOCK bit maskable. + * Revision 1.63 2008/01/17 11:42:09Z daniel + * Made comments compatible for Doxygen parser. + * No sourcecode changes. + * Revision 1.62 2007/11/15 13:23:33Z martin + * Decide whether other Meinberg headers are to be included depending on whether + * CLOCK_MEINBERG is defined (as with NTP) or not. Previous versions checked + * for "PACKAGE" which is also defined by the Borland C++ build environment, though. + * Revision 1.61 2007/11/13 13:28:54 daniel + * Added definitions to support GPS170PEX. + * Revision 1.60 2007/09/13 12:37:35Z martin + * Modified and added initializers for TZDL. + * Added multi ref source PTP over E1. + * Added codes for MSF511 and GRC170 devices. + * Modified XMULTI_REF_SETTINGS and XMULTI_REF_STATUS structures. + * Avoid inclusion of other Meinberg headers in non-Meinberg projects. + * Added device classification macros _mbg_rcvr_is_...(). + * Modified feature name string initializer for non-GPS devices. + * Updated some comments. + * Removed some obsolete comments. + * Revision 1.59 2007/07/19 07:41:56Z martin + * Added symbol MBG_REF_OFFS_NOT_CFGD. + * Revision 1.58 2007/05/21 15:46:44Z martin + * Fixed a typo. + * Revision 1.57 2007/03/29 12:20:43 martin + * Fixed some TZDL initializers. + * Revision 1.56 2007/02/14 14:17:10Z andre + * bug fixed in mask XMRS_MSK_NO_CONN + * Revision 1.55 2007/02/06 16:23:18Z martin + * Added definitions for AM511. + * Made SVNO unsigned. + * Added support for OPT_SETTINGS. + * Added XMULTI_REF_... definitions. + * Added string initializer DEFAULT_FREQ_RANGES. + * Revision 1.54 2007/01/04 11:39:39Z martin + * Added definitions for TCR511. + * Added definition GPS_FEAT_5_MHZ. + * Updated some comments related to duplicate features/options + * IGNORE_LOCK and EMU_SYNC. + * Revision 1.53 2006/12/13 09:31:49 martin + * Added feature flag for ignore_lock. + * Revision 1.52 2006/12/12 15:47:18 martin + * Added MBG_DEBUG_STATUS type and associated definitions. + * Added definition GPS_HAS_REF_OFFS. + * Moved PCPS_REF_OFFS and associated definitions from pcpsdefs.h here + * and renamed them to MBG_REF_OFFS, etc. + * Revision 1.51 2006/10/23 15:31:27 martin + * Added definitions for GPS170. + * Added definitions for new multi_ref sources IRIG, NTP, and PTP. + * Added some definitions useful when editing synth frequency. + * Revision 1.50 2006/08/25 09:29:28Z martin + * Added structure NANO_TIME. + * Revision 1.49 2006/08/09 07:06:42Z martin + * New TM_GPS status flag TM_EXT_SYNC. + * Revision 1.48 2006/08/08 12:51:20Z martin + * Added definitions for IRIG codes B006/B126 and B007/B127. + * Revision 1.47 2006/07/06 08:41:45Z martin + * Added definition of MEINBERG_MAGIC. + * Revision 1.46 2006/06/21 14:08:53Z martin + * Added masks of IRIG codes which contain time zone information. + * Revision 1.45 2006/06/15 12:13:32Z martin + * Added MULTI_REF_STATUS and associated flags. + * Added ROM_CSUM, RCV_TIMEOUT, and IGNORE_LOCK types. + * Revision 1.44 2006/05/18 09:34:41Z martin + * Added definitions for POUT max. pulse_len and max timeout. + * Changed comment for POUT_SETTINGS::timeout. + * Units are minutes, not seconds. + * Added definition for MAX_POUT_TIME_STR_PORTS. + * Added definitions for POUT mode 10MHz. + * Added hint strings for POUT modes. + * Added definitions for PZF511. + * Revision 1.43 2006/01/24 07:53:29Z martin + * New TM_GPS status flag TM_HOLDOVER. + * Revision 1.42 2005/11/24 14:53:22Z martin + * Added definitions for manchester encoded DC IRIG frames. + * Added POUT_TIMESTR and related definitions. + * Revision 1.41 2005/11/03 15:06:59Z martin + * Added definitions to support GPS170PCI. + * Revision 1.40 2005/10/28 08:58:29Z martin + * Added definitions for OCXO_DHQ. + * Revision 1.39 2005/09/08 14:06:00Z martin + * Added definition SYNTH_PHASE_SYNC_LIMIT. + * Revision 1.38 2005/08/18 10:27:35 andre + * added definitions for GPS164, + * added POUT_TIMECODE, + * struct SCU_STAT changed, + * ulong flags changed into two byte clk_info and ushort flags + * Revision 1.37 2005/05/02 14:44:55Z martin + * Added structure SYNTH_STATE and associated definitions. + * Revision 1.36 2005/03/29 12:44:07Z martin + * New RECEIVER_INFO::flags code: GPS_IRIG_FO_IN + * Revision 1.35 2004/12/09 14:04:38Z martin + * Changed max synth freq from 12 MHz to 10 MHz. + * Revision 1.34 2004/11/23 16:20:09Z martin + * Added bit definitions for the existing TTM status bit masks. + * Revision 1.33 2004/11/09 12:39:59Z martin + * Redefined interface data types using C99 fixed-size definitions. + * Added model code and name for TCR167PCI. + * New type GPS_CMD. + * Defined type BVAR_STAT and associated flags. + * Revision 1.32 2004/09/20 12:46:25 andre + * Added structures and definitions for SCU board. + * Revision 1.31 2004/07/08 08:30:36Z martin + * Added feature GPS_FEAT_RCV_TIMEOUT. + * Revision 1.30 2004/06/21 13:38:42 martin + * New flag MBG_OPT_BIT_EMU_SYNC/MBG_OPT_FLAG_EMU_SYNC + * lets the receicer emulate/pretend to be always synchronized. + * Revision 1.30 2004/06/21 13:35:46Z martin + * Revision 1.29 2004/06/16 12:47:53Z martin + * Moved OPT_SETTINGS related definitions from pcpsdefs.h + * here and renamed symbols from PCPS_.. to to MBG_... + * Revision 1.28 2004/03/26 10:37:00Z martin + * Added definitions to support multiple ref sources. + * Added definitions OSC_DAC_RANGE, OSC_DAC_BIAS. + * Revision 1.27 2004/03/08 14:06:45Z martin + * New model code and name for GPS169PCI. + * Existing feature GPS_FEAT_IRIG has been + * renamed to GPS_FEAT_IRIG_TX. + * Added feature GPS_FEAT_IRIG_RX. + * Added IPv4 LAN interface feature flags. + * Renamed IFLAGS_IGNORE_TFOM to IFLAGS_DISABLE_TFOM. + * Revision 1.26 2003/12/05 12:28:20Z martin + * Added some codes used with IRIG cfg. + * Revision 1.25 2003/10/29 16:18:14Z martin + * Added 7N2 to DEFAULT_GPS_FRAMINGS_GP2021. + * Revision 1.24 2003/09/30 08:49:48Z martin + * New flag TM_LS_ANN_NEG which is set in addition to + * TM_LS_ANN if next leap second is negative. + * Revision 1.23 2003/08/26 14:32:33Z martin + * Added some initializers for commonly used + * TZDL configurations. + * Revision 1.22 2003/04/25 10:18:11 martin + * Fixed typo inside an IRIG name string initializer. + * Revision 1.21 2003/04/15 09:18:48 martin + * New typedef ANT_CABLE_LEN. + * Revision 1.20 2003/04/03 11:03:44Z martin + * Extended definitions for IRIG support. + * Revision 1.19 2003/01/31 13:38:20 MARTIN + * Modified type of RECEIVER_INFO::fixed_freq field. + * Revision 1.18 2002/10/28 09:24:07 MARTIN + * Added/renamed some POUT related symbols. + * Revision 1.17 2002/09/05 10:58:39 MARTIN + * Renamed some symbols related to programmable outputs. + * Revision 1.16 2002/08/29 08:04:47 martin + * Renamed structure POUT_PROG to POUT_SETTINGS. + * New structures POUT_SETTINGS_IDX, POUT_INFO, + * POUT_INFO_IDX and associated definitions. + * Updated some comments. + * Revision 1.15 2002/07/17 07:39:39Z Andre + * comma added in definition DEFAULT_GPS_OSC_NAMES + * Revision 1.14 2002/06/27 12:17:29Z MARTIN + * Added new oscillator code TCXO_MQ. + * Added initializer for oscillator names. + * Added initializer for oscillator list ordered by quality. + * Revision 1.13 2002/05/08 08:16:03 MARTIN + * Added GPS_OSC_CFG_SUPP for RECEIVER_INFO::flags. + * Fixed some comments. + * Revision 1.12 2002/03/14 13:45:56 MARTIN + * Changed type CSUM from short to ushort. + * Revision 1.11 2002/03/01 12:29:30 Andre + * Added GPS_MODEL_GPS161 and GPS_MODEL_NAME_GPS161. + * Revision 1.10 2002/02/25 08:02:33Z MARTIN + * Added array of chars to union IDENT. + * Revision 1.9 2002/01/29 15:21:46 MARTIN + * Added new field "reserved" to struct SW_REV to fix C166 data + * alignment/structure size. Converted structure IDENT to a union. + * The changes above should not affect existing monitoring programs. + * New status flag TM_ANT_SHORT. + * New structure RECEIVER_INFO and associated definitions to + * enhance control from monitoring programs. + * New structures PORT_INFO, STR_TYPE_INFO, and associated + * definitions to simplify and unify configuration from external programs. + * New structures IRIG_INFO and POUT_PROG_IDX to configure an + * optional IRIG interface and programmable pulse outputs. + * Modified some comments. + * Revision 1.8 2001/03/30 11:44:11 MARTIN + * Control alignment of structures from new file use_pack.h. + * Defined initializers with valid baud rate and framing parameters. + * Modified some comments. + * Revision 1.7 2001/03/01 08:09:22 MARTIN + * Modified preprocessor syntax. + * Revision 1.6 2000/07/21 14:04:33 MARTIN + * Added som #if directives to protect structures against being multiply + * defined. + * Modified some comments. + * Comments using characters for +/- and degree now include ASCII + * characters only. + * + **************************************************************************/ + +#ifndef _GPSDEFS_H +#define _GPSDEFS_H + +/* Other headers to be included */ + +#if defined( HAVE_CONFIG_H ) + // this is mainly to simplify usage in non-Meinberg projects + #include <config.h> +#endif + +// CLOCK_MEINBERG is defined in the config.h file provided +// by the NTP project to support Meinberg clocks. +#if !defined( CLOCK_MEINBERG ) + // Avoid having to use these headers in non-Meinberg projects. + #include <words.h> + #include <use_pack.h> +#endif + + + +/* Start of header body */ + +#if defined( _USE_PACK ) + #pragma pack( 1 ) // set byte alignment + #define _USING_BYTE_ALIGNMENT +#endif + + + +/* "magic" number */ +#define MEINBERG_MAGIC 0x6AAC + +/** + * @brief GNSS satellite numbers + * + * @todo Check if ::MAX_SVNO_GLONASS is 94 instead of 95, and thus + * ::N_SVNO_GLONASS is 30 instead of 31, as reported by Wikipedia. + */ +enum GNSS_SVNOS +{ + MIN_SVNO_GPS = 1, ///< min. GPS satellite PRN number + MAX_SVNO_GPS = 32, ///< max. GPS satellite PRN number + N_SVNO_GPS = 32, ///< max. number of active GPS satellites + + MIN_SVNO_WAAS = 33, ///< min. WAAS satellite number + MAX_SVNO_WAAS = 64, ///< max. WAAS satellite number + N_SVNO_WAAS = 32, ///< max. number of active WAAS satellites + + MIN_SVNO_GLONASS = 65, ///< min. Glonass satellite number (64 + sat slot ID) + MAX_SVNO_GLONASS = 95, ///< max. Glonass satellite number (64 + sat slot ID) + N_SVNO_GLONASS = 31 ///< max. number of active Glonass satellites +}; + +// for compatibility with GPS-only software: +#define MIN_SVNO MIN_SVNO_GPS ///< min. SV number +#define MAX_SVNO MAX_SVNO_GPS ///< max. SV number +#define N_SVNO N_SVNO_GPS ///< number of possibly active SVs + + + +#define GPS_ID_STR_LEN 16 +#define GPS_ID_STR_SIZE ( GPS_ID_STR_LEN + 1 ) + +#define GPS_EPLD_STR_LEN 8 +#define GPS_EPLD_STR_SIZE ( GPS_EPLD_STR_LEN + 1 ) + + +#define DEFAULT_GPS_TICKS_PER_SEC 10000000L ///< system time base, see ::GPS_TICKS_PER_SEC + +#if !defined( GPS_TICKS_PER_SEC ) + /* + * The actual ticks per seconds may vary for different + * GPS receiver models. If this is the case, the receiver + * model support the ::RECEIVER_INFO structure which contains + * the actual value. + */ + #define GPS_TICKS_PER_SEC DEFAULT_GPS_TICKS_PER_SEC ///< See ::DEFAULT_GPS_TICKS_PER_SEC + +#endif + + +typedef uint16_t SVNO; ///< The number of an SV (Space Vehicle, i.e. satellite). +typedef uint16_t HEALTH; ///< The 6 bit health code for an SV. +typedef uint16_t CFG; ///< The 4 bit configuration code for an SV. +typedef uint16_t IOD; ///< Issue-Of-Data code. + +typedef int16_t GPS_WNUM; ///< Type of a signed extended GPS week number. +typedef int16_t GPS_DNUM; ///< Type of a signed GPS day number as used with ::UTC. +typedef int32_t GPS_WSEC; ///< Type of a signed GPS second-of-week number. +typedef int32_t GPS_TICK; ///< Type of a signed tick-of-second number, see + ///< ::GPS_TICKS_PER_SEC and ::RECEIVER_INFO::ticks_per_sec. + + +typedef uint16_t MBG_MSG_IDX; ///< Standard type of an index number used with binary messages. +typedef uint32_t MBG_MSG_IDX_32; ///< Type of a 32 bit index number used with binary messages in some cases. + + +/* the type of various checksums */ + +#ifndef _CSUM_DEFINED + typedef uint16_t CSUM; ///< Checksum used by some structures stored in non-volatile memory. + #define _CSUM_DEFINED +#endif + +#define _mbg_swab_csum( _p ) _mbg_swab16( _p ) + + + +/** + * @brief The type of a GPS command code + * + * @see ::GPS_CMD_CODES + * @see ::PC_GPS_CMD_CODES + */ +typedef uint16_t GPS_CMD; + +#define _mbg_swab_gps_cmd( _p ) _mbg_swab16( _p ) + + +/** + * @brief Software revision information + * + * Contains a software revision code, plus an optional + * identifier for a customized version. + * + * @see @ref group_ext_sys_info + */ +typedef struct +{ + uint16_t code; ///< Version number, e.g. 0x0120 means v1.20 + char name[GPS_ID_STR_SIZE]; ///< Optional string identifying a customized firmware version, should be empty in standard versions + uint8_t reserved; ///< Reserved field to yield even structure size + +} SW_REV; + +#define _mbg_swab_sw_rev( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->code ); \ +} while ( 0 ) + + + +/** + * @defgroup group_bvar_stat Status of buffered (non-volatile) data + * + * Status word, associated bit numbers and bit masks indicating + * whether certain data from the GPS satellites are + * available and valid. + * + * These bits defined are set in ::BVAR_STAT if the corresponding + * parameters are NOT valid and complete. + * + * @{ */ + +/** + * @brief Status flags of battery buffered data + * + * Related to data received from the satellites, or data derived thereof. + * + * All '0' means OK, single bits set to '1' indicate + * the associated type of GPS data is not available. + * + * @see ::BVAR_FLAGS + * @see ::BVAR_FLAG_BITS + * @see ::BVAR_FLAG_NAMES + * @see ::BVAR_FLAG_NAMES_SHORT + */ +typedef uint16_t BVAR_STAT; + +#define _mbg_swab_bvar_stat( _p ) _mbg_swab16( (_p) ) + + +/** + * @brief Enumeration of flag bits used to define ::BVAR_FLAGS + * + * For each bit which is set this means the associated data set in + * non-volatile memory is not available, or incomplete. + * Most data sets will just be re-collected from the data streams sent + * by the satellites. However, the receiver position has usually been + * computed earlier during normal operation, and will be re-computed + * when a sufficient number of satellites can be received. + * + * @see ::BVAR_STAT + * @see ::BVAR_FLAGS + * @see ::BVAR_FLAG_NAMES + * @see ::BVAR_FLAG_NAMES_SHORT + */ +enum BVAR_FLAG_BITS +{ + BVAR_BIT_CFGH_INVALID, ///< Satellite configuration and health parameters incomplete. + BVAR_BIT_ALM_NOT_COMPLETE, ///< Almanac parameters incomplete. + BVAR_BIT_UTC_INVALID, ///< %UTC offset parameters incomplete. + BVAR_BIT_IONO_INVALID, ///< Ionospheric correction parameters incomplete. + BVAR_BIT_RCVR_POS_INVALID, ///< No valid receiver position available. + N_BVAR_BIT ///< number of defined ::BVAR_STAT bits. +}; + + +/** + * @brief Bit masks associated with ::BVAR_FLAG_BITS + * + * Used with ::BVAR_STAT. + * + * @see ::BVAR_STAT + * @see ::BVAR_FLAG_BITS + * @see ::BVAR_FLAG_NAMES + * @see ::BVAR_FLAG_NAMES_SHORT + */ +enum BVAR_FLAGS +{ + BVAR_CFGH_INVALID = ( 1UL << BVAR_BIT_CFGH_INVALID ), ///< See ::BVAR_BIT_CFGH_INVALID + BVAR_ALM_NOT_COMPLETE = ( 1UL << BVAR_BIT_ALM_NOT_COMPLETE ), ///< See ::BVAR_BIT_ALM_NOT_COMPLETE + BVAR_UTC_INVALID = ( 1UL << BVAR_BIT_UTC_INVALID ), ///< See ::BVAR_BIT_UTC_INVALID + BVAR_IONO_INVALID = ( 1UL << BVAR_BIT_IONO_INVALID ), ///< See ::BVAR_BIT_IONO_INVALID + BVAR_RCVR_POS_INVALID = ( 1UL << BVAR_BIT_RCVR_POS_INVALID ), ///< See ::BVAR_BIT_RCVR_POS_INVALID +}; + +#define BVAR_MASK ( ( 1UL << N_BVAR_BIT ) - 1 ) ///< Bit mask for all defined bits + + +/** + * @brief String initializer for long ::BVAR_STAT flag names. + * + * @see ::BVAR_FLAG_NAMES_SHORT + * @see ::BVAR_FLAG_BITS + * @see ::BVAR_FLAGS + * @see ::BVAR_STAT + */ +#define BVAR_FLAG_NAMES \ +{ \ + "Sat. config and health", \ + "Almanac", \ + "UTC offset", \ + "Ionospheric correction", \ + "Receiver position" \ +} + + + +/** + * @brief String initializer for short ::BVAR_STAT flag names. + * + * @see ::BVAR_FLAG_NAMES + * @see ::BVAR_FLAG_BITS + * @see ::BVAR_FLAGS + * @see ::BVAR_STAT + */ +#define BVAR_FLAG_NAMES_SHORT \ +{ \ + "CFGH", \ + "Alm.", \ + "UTC", \ + "IONO", \ + "Rcvr. pos." \ +} + +/** @} defgroup group_bvar_stat */ + + + +/** + * @brief A structure used to hold a fixed frequency value + * + * @note frequ[kHz] = khz_val * 10^range + */ +typedef struct +{ + uint16_t khz_val; ///< the base frequency in [kHz] + int16_t range; ///< an optional base 10 exponent + +} FIXED_FREQ_INFO; + +#define _mbg_swab_fixed_freq_info( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->khz_val ); \ + _mbg_swab16( &(_p)->range ); \ +} while ( 0 ) + + +/** + * @brief A data type to specify feature flags within ::RECEIVER_INFO + */ +typedef uint32_t RI_FEATURES; ///< see @ref GPS_FEATURE_MASKS + + + +/** + * @brief A structure used to identify a device type and supported features + * + * @note This may not be supported by some very old devices. + */ +typedef struct receiver_info_s +{ + uint16_t model_code; ///< identifier for receiver model, see ::GPS_MODEL_CODES + SW_REV sw_rev; ///< software revision and ID + char model_name[GPS_ID_STR_SIZE]; ///< ASCIIZ, name of receiver model + char sernum[GPS_ID_STR_SIZE]; ///< ASCIIZ, serial number + char epld_name[GPS_EPLD_STR_SIZE]; ///< ASCIIZ, file name of EPLD image (optional) + uint8_t n_channels; ///< number of satellites which can be tracked simultaneously + uint32_t ticks_per_sec; ///< resolution of fractions of seconds, see ::GPS_TICKS_PER_SEC + RI_FEATURES features; ///< optional features, see @ref GPS_FEATURE_MASKS + FIXED_FREQ_INFO fixed_freq; ///< optional non-standard fixed frequency, may be 0 if not supported + uint8_t osc_type; ///< type of installed oscillator, see ::GPS_OSC_TYPES + uint8_t osc_flags; ///< oscillator flags, actually not used and always 0 + uint8_t n_ucaps; ///< number of user time capture inputs + uint8_t n_com_ports; ///< number of on-board serial ports + uint8_t n_str_type; ///< max num of string types supported by any port + uint8_t n_prg_out; ///< number of programmable pulse outputs + uint16_t flags; ///< additional information, see ::RECEIVER_INFO_FLAG_MASKS + +} RECEIVER_INFO; + +#define _mbg_swab_receiver_info( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->model_code ); \ + _mbg_swab_sw_rev( &(_p)->sw_rev ); \ + _mbg_swab16( &(_p)->ticks_per_sec ); \ + _mbg_swab32( &(_p)->features ); \ + _mbg_swab_fixed_freq_info( &(_p)->fixed_freq ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + + +/** + * @brief Known device ID codes for ::RECEIVER_INFO::model_code + * + * @see @ref GPS_MODEL_NAMES + * @see ::DEFAULT_GPS_MODEL_NAMES + */ +enum GPS_MODEL_CODES +{ + GPS_MODEL_UNKNOWN, + GPS_MODEL_GPS166, + GPS_MODEL_GPS167, + GPS_MODEL_GPS167SV, + GPS_MODEL_GPS167PC, + GPS_MODEL_GPS167PCI, + GPS_MODEL_GPS163, + GPS_MODEL_GPS168PCI, + GPS_MODEL_GPS161, + GPS_MODEL_GPS169PCI, + GPS_MODEL_TCR167PCI, + GPS_MODEL_GPS164, + GPS_MODEL_GPS170PCI, + GPS_MODEL_PZF511, + GPS_MODEL_GPS170, + GPS_MODEL_TCR511, + GPS_MODEL_AM511, + GPS_MODEL_MSF511, + GPS_MODEL_GRC170, + GPS_MODEL_GPS170PEX, + GPS_MODEL_GPS162, + GPS_MODEL_PTP270PEX, + GPS_MODEL_FRC511PEX, + GPS_MODEL_GEN170, + GPS_MODEL_TCR170PEX, + GPS_MODEL_WWVB511, + GPS_MODEL_MGR170, + GPS_MODEL_JJY511, + GPS_MODEL_PZF600, + GPS_MODEL_TCR600, + GPS_MODEL_GPS180, + GPS_MODEL_GLN170, + GPS_MODEL_GPS180PEX, + GPS_MODEL_TCR180PEX, + GPS_MODEL_PZF180PEX, + GPS_MODEL_MGR180, + GPS_MODEL_MSF600, + GPS_MODEL_WWVB600, + GPS_MODEL_JJY600, + GPS_MODEL_GPS180HS, + GPS_MODEL_GPS180AMC, + GPS_MODEL_ESI180, + GPS_MODEL_CPE180, + GPS_MODEL_LNO180, + GPS_MODEL_GRC180, + GPS_MODEL_LIU, + GPS_MODEL_DCF600HS, + GPS_MODEL_DCF600RS, + GPS_MODEL_MRI, + GPS_MODEL_BPE, + GPS_MODEL_GLN180PEX, + GPS_MODEL_N2X, + GPS_MODEL_RSC180, + GPS_MODEL_LNE_GB, + GPS_MODEL_PPG180, + GPS_MODEL_SCG, + GPS_MODEL_MDU300, + GPS_MODEL_SDI, + GPS_MODEL_FDM180, + GPS_MODEL_SPT, + GPS_MODEL_PZF180, + GPS_MODEL_REL1000, + GPS_MODEL_HPS100, + GPS_MODEL_VSG180, + GPS_MODEL_MSF180, + GPS_MODEL_WWVB180, + GPS_MODEL_CPC180, + GPS_MODEL_CTC100, + GPS_MODEL_TCR180, + GPS_MODEL_LUE180, + GPS_MODEL_CPC_01, + GPS_MODEL_TSU_01, + GPS_MODEL_CMC_01, + GPS_MODEL_SCU_01, + GPS_MODEL_FCU_01, + GPS_MODEL_MSSB100, + GPS_MODEL_LNE180SFP, + GPS_MODEL_GTS180, + GPS_MODEL_GPS180CSM, + GPS_MODEL_GRC181, + GPS_MODEL_N2X180, + GPS_MODEL_GNS181PEX, + GPS_MODEL_MDU180, + GPS_MODEL_MDU312, + GPS_MODEL_GPS165, + GPS_MODEL_GNS181_UC, + GPS_MODEL_PSX_4GE, + GPS_MODEL_RSC180RDU, + GPS_MODEL_CPC200, // FIXME Try if this works. This entry was originally defined as GPS_MODEL_USYNCPWR + // in 1.124.1.303, which was already obsolete right from the beginning. + GPS_MODEL_FDM180M, + 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 + GPS_MODEL_BPE_STM, // BPE with STM M0 + GPS_MODEL_VSI180, + GPS_MODEL_GNM181, + GPS_MODEL_RSCRDU_TTL, // TTL version of ::GPS_MODEL_RSC180RDU + GPS_MODEL_RSC2000, // Variant of ::GPS_MODEL_RSC180 for LANTIME M2000 + GPS_MODEL_FCU200, // Fan (and power supply) Control Unit + GPS_MODEL_REL1000_RC, + 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. + */ +}; + + + +/** + * @brief Model name strings used with Meinberg devices + * + * String initializers for each of the device models + * enumerated in ::GPS_MODEL_CODES. + * + * @see ::GPS_MODEL_CODES + * @see ::DEFAULT_GPS_MODEL_NAMES + * + * @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_MSSB100 "MSSB100" +#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_CPC200 "CPC200" +#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" +#define GPS_MODEL_NAME_BPE_STM "BPE" +#define GPS_MODEL_NAME_VSI180 "VSI180" +#define GPS_MODEL_NAME_GNM181 "GNM181" +#define GPS_MODEL_NAME_RSCRDU_TTL "RSC180RDU_TTL" +#define GPS_MODEL_NAME_RSC2000 "RSC2000" +#define GPS_MODEL_NAME_FCU200 "FCU200" +#define GPS_MODEL_NAME_REL1000_RC "REL1000_RC" +/* + * 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 */ + + + +/** + * @brief An initializer for a table of device names + * + * Can be used to initialize an array of ::N_GPS_MODEL + * type name strings. + * + * @note Including the trailing 0, each name must not + * exceed ::GPS_ID_STR_SIZE chars. + * + * @see ::GPS_MODEL_CODES + * @see @ref GPS_MODEL_NAMES + */ +#define DEFAULT_GPS_MODEL_NAMES \ +{ \ + GPS_MODEL_NAME_UNKNOWN, \ + GPS_MODEL_NAME_GPS166, \ + GPS_MODEL_NAME_GPS167, \ + GPS_MODEL_NAME_GPS167SV, \ + GPS_MODEL_NAME_GPS167PC, \ + GPS_MODEL_NAME_GPS167PCI, \ + GPS_MODEL_NAME_GPS163, \ + GPS_MODEL_NAME_GPS168PCI, \ + GPS_MODEL_NAME_GPS161, \ + GPS_MODEL_NAME_GPS169PCI, \ + GPS_MODEL_NAME_TCR167PCI, \ + GPS_MODEL_NAME_GPS164, \ + GPS_MODEL_NAME_GPS170PCI, \ + GPS_MODEL_NAME_PZF511, \ + GPS_MODEL_NAME_GPS170, \ + GPS_MODEL_NAME_TCR511, \ + GPS_MODEL_NAME_AM511, \ + GPS_MODEL_NAME_MSF511, \ + GPS_MODEL_NAME_GRC170, \ + GPS_MODEL_NAME_GPS170PEX, \ + GPS_MODEL_NAME_GPS162, \ + GPS_MODEL_NAME_PTP270PEX, \ + GPS_MODEL_NAME_FRC511PEX, \ + GPS_MODEL_NAME_GEN170, \ + GPS_MODEL_NAME_TCR170PEX, \ + GPS_MODEL_NAME_WWVB511, \ + GPS_MODEL_NAME_MGR170, \ + GPS_MODEL_NAME_JJY511, \ + GPS_MODEL_NAME_PZF600, \ + GPS_MODEL_NAME_TCR600, \ + GPS_MODEL_NAME_GPS180, \ + GPS_MODEL_NAME_GLN170, \ + GPS_MODEL_NAME_GPS180PEX, \ + GPS_MODEL_NAME_TCR180PEX, \ + GPS_MODEL_NAME_PZF180PEX, \ + GPS_MODEL_NAME_MGR180, \ + GPS_MODEL_NAME_MSF600, \ + GPS_MODEL_NAME_WWVB600, \ + GPS_MODEL_NAME_JJY600, \ + GPS_MODEL_NAME_GPS180HS, \ + GPS_MODEL_NAME_GPS180AMC, \ + GPS_MODEL_NAME_ESI180, \ + GPS_MODEL_NAME_CPE180, \ + GPS_MODEL_NAME_LNO180, \ + GPS_MODEL_NAME_GRC180, \ + GPS_MODEL_NAME_LIU, \ + GPS_MODEL_NAME_DCF600HS, \ + GPS_MODEL_NAME_DCF600RS, \ + GPS_MODEL_NAME_MRI, \ + GPS_MODEL_NAME_BPE, \ + GPS_MODEL_NAME_GLN180PEX, \ + GPS_MODEL_NAME_N2X, \ + GPS_MODEL_NAME_RSC180, \ + GPS_MODEL_NAME_LNE_GB, \ + GPS_MODEL_NAME_PPG180, \ + GPS_MODEL_NAME_SCG, \ + GPS_MODEL_NAME_MDU300, \ + GPS_MODEL_NAME_SDI, \ + GPS_MODEL_NAME_FDM180, \ + GPS_MODEL_NAME_SPT, \ + GPS_MODEL_NAME_PZF180, \ + GPS_MODEL_NAME_REL1000, \ + GPS_MODEL_NAME_HPS100, \ + GPS_MODEL_NAME_VSG180, \ + GPS_MODEL_NAME_MSF180, \ + GPS_MODEL_NAME_WWVB180, \ + GPS_MODEL_NAME_CPC180, \ + GPS_MODEL_NAME_CTC100, \ + GPS_MODEL_NAME_TCR180, \ + GPS_MODEL_NAME_LUE180, \ + GPS_MODEL_NAME_CPC_01, \ + GPS_MODEL_NAME_TSU_01, \ + GPS_MODEL_NAME_CMC_01, \ + GPS_MODEL_NAME_SCU_01, \ + GPS_MODEL_NAME_FCU_01, \ + GPS_MODEL_NAME_MSSB100, \ + GPS_MODEL_NAME_LNE180SFP, \ + GPS_MODEL_NAME_GTS180, \ + GPS_MODEL_NAME_GPS180CSM, \ + GPS_MODEL_NAME_GRC181, \ + GPS_MODEL_NAME_N2X180, \ + GPS_MODEL_NAME_GNS181PEX, \ + GPS_MODEL_NAME_MDU180, \ + GPS_MODEL_NAME_MDU312, \ + GPS_MODEL_NAME_GPS165, \ + GPS_MODEL_NAME_GNS181_UC, \ + GPS_MODEL_NAME_PSX_4GE, \ + GPS_MODEL_NAME_RSC180RDU, \ + GPS_MODEL_NAME_CPC200, \ + GPS_MODEL_NAME_FDM180M, \ + GPS_MODEL_NAME_LSG180, \ + GPS_MODEL_NAME_GPS190, \ + 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, \ + GPS_MODEL_NAME_BPE_STM, \ + GPS_MODEL_NAME_VSI180, \ + GPS_MODEL_NAME_GNM181, \ + GPS_MODEL_NAME_RSCRDU_TTL, \ + GPS_MODEL_NAME_RSC2000, \ + GPS_MODEL_NAME_FCU200, \ + GPS_MODEL_NAME_REL1000_RC \ +} + + + + +/** + * @brief Definitions used to classify devices and built-in features + * + * @see ::GPS_MODEL_CODES + * @see ::GPS_BUILTIN_FEATURE_BITS + * @see @ref GPS_BUILTIN_FEATURE_MASKS + * + * @anchor GPS_BUILTIN_FEATURE_DEFS @{ */ + + +/** + * @brief A data type to hold a mask of @ref GPS_BUILTIN_FEATURE_MASKS + * + * @see @ref GPS_BUILTIN_FEATURE_MASKS + */ +typedef uint32_t BUILTIN_FEATURE_MASK; + + +/** + * @brief Enumeration of classifiers and built-in features + * + * @see ::GPS_MODEL_CODES + * @see @ref GPS_BUILTIN_FEATURE_MASKS + */ +enum GPS_BUILTIN_FEATURE_BITS +{ + GPS_BIT_MODEL_IS_GPS, + GPS_BIT_MODEL_IS_GNSS, + GPS_BIT_MODEL_IS_TCR, + GPS_BIT_MODEL_IS_DCF_AM, + GPS_BIT_MODEL_IS_DCF_PZF, + GPS_BIT_MODEL_IS_MSF, + GPS_BIT_MODEL_IS_JJY, + GPS_BIT_MODEL_IS_WWVB, + + GPS_BIT_MODEL_IS_BUS_LVL_DEV, + GPS_BIT_MODEL_HAS_BVAR_STAT, + GPS_BIT_MODEL_HAS_POS_XYZ, + GPS_BIT_MODEL_HAS_POS_LLA, + GPS_BIT_MODEL_HAS_TIME_TTM, + GPS_BIT_MODEL_HAS_TZDL, + GPS_BIT_MODEL_HAS_TZCODE, + GPS_BIT_MODEL_HAS_ANT_INFO, + + GPS_BIT_MODEL_HAS_ENABLE_FLAGS, + GPS_BIT_MODEL_HAS_STAT_INFO, + GPS_BIT_MODEL_HAS_ANT_CABLE_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__REMOVE_THIS, // TODO FIXME + +#if 0 //### TODO This has to be discussed + GPS_BIT_MODEL_IS_LNO, + GPS_BIT_MODEL_IS_SCU, +#endif + + N_GPS_BUILTIN_FEATURE_BITS +}; + + + +/** + * @brief Bit masks associated with classifiers and built-in features + * + * @see ::GPS_MODEL_CODES + * @see ::GPS_BUILTIN_FEATURE_BITS + * + * @anchor GPS_BUILTIN_FEATURE_MASKS @{ */ + +#define GPS_MODEL_IS_GPS ( 1UL << GPS_BIT_MODEL_IS_GPS ) ///< See ::GPS_BIT_MODEL_IS_GPS +#define GPS_MODEL_IS_GNSS ( 1UL << GPS_BIT_MODEL_IS_GNSS ) ///< See ::GPS_BIT_MODEL_IS_GNSS +#define GPS_MODEL_IS_TCR ( 1UL << GPS_BIT_MODEL_IS_TCR ) ///< See ::GPS_BIT_MODEL_IS_TCR +#define GPS_MODEL_IS_DCF_AM ( 1UL << GPS_BIT_MODEL_IS_DCF_AM ) ///< See ::GPS_BIT_MODEL_IS_DCF_AM +#define GPS_MODEL_IS_DCF_PZF ( 1UL << GPS_BIT_MODEL_IS_DCF_PZF ) ///< See ::GPS_BIT_MODEL_IS_DCF_PZF +#define GPS_MODEL_IS_MSF ( 1UL << GPS_BIT_MODEL_IS_MSF ) ///< See ::GPS_BIT_MODEL_IS_MSF +#define GPS_MODEL_IS_JJY ( 1UL << GPS_BIT_MODEL_IS_JJY ) ///< See ::GPS_BIT_MODEL_IS_JJY +#define GPS_MODEL_IS_WWVB ( 1UL << GPS_BIT_MODEL_IS_WWVB ) ///< See ::GPS_BIT_MODEL_IS_WWVB + +#define GPS_MODEL_IS_BUS_LVL_DEV ( 1UL << GPS_BIT_MODEL_IS_BUS_LVL_DEV ) ///< See ::GPS_BIT_MODEL_IS_BUS_LVL_DEV +#define GPS_MODEL_HAS_BVAR_STAT ( 1UL << GPS_BIT_MODEL_HAS_BVAR_STAT ) ///< See ::GPS_BIT_MODEL_HAS_BVAR_STAT +#define GPS_MODEL_HAS_POS_XYZ ( 1UL << GPS_BIT_MODEL_HAS_POS_XYZ ) ///< See ::GPS_BIT_MODEL_HAS_POS_XYZ +#define GPS_MODEL_HAS_POS_LLA ( 1UL << GPS_BIT_MODEL_HAS_POS_LLA ) ///< See ::GPS_BIT_MODEL_HAS_POS_LLA +#define GPS_MODEL_HAS_TIME_TTM ( 1UL << GPS_BIT_MODEL_HAS_TIME_TTM ) ///< See ::GPS_BIT_MODEL_HAS_TIME_TTM +#define GPS_MODEL_HAS_TZDL ( 1UL << GPS_BIT_MODEL_HAS_TZDL ) ///< See ::GPS_BIT_MODEL_HAS_TZDL +#define GPS_MODEL_HAS_TZCODE ( 1UL << GPS_BIT_MODEL_HAS_TZCODE ) ///< See ::GPS_BIT_MODEL_HAS_TZCODE +#define GPS_MODEL_HAS_ANT_INFO ( 1UL << GPS_BIT_MODEL_HAS_ANT_INFO ) ///< See ::GPS_BIT_MODEL_HAS_ANT_INFO + +#define GPS_MODEL_HAS_ENABLE_FLAGS ( 1UL << GPS_BIT_MODEL_HAS_ENABLE_FLAGS ) ///< See ::GPS_BIT_MODEL_HAS_ENABLE_FLAGS +#define GPS_MODEL_HAS_STAT_INFO ( 1UL << GPS_BIT_MODEL_HAS_STAT_INFO ) ///< See ::GPS_BIT_MODEL_HAS_STAT_INFO +#define GPS_MODEL_HAS_ANT_CABLE_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 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 ) + +/** @} anchor GPS_BUILTIN_FEATURE_MASKS */ + + +#if 0 //##++ more potential builtin features and classifiers + + GPS_MODEL_HAS_CFGH | \ + GPS_MODEL_HAS_ALM | \ + GPS_MODEL_HAS_EPH | \ + GPS_MODEL_HAS_UTC | \ + GPS_MODEL_HAS_IONO \ + +#define GPS_MODEL_HAS_AUTO_ON // -- +#define GPS_MODEL_HAS_AUTO_OFF // -- +#define GPS_MODEL_HAS_SW_REV // deprecated, use only if ri not supported +#define GPS_MODEL_HAS_BVAR_STAT // req +#define GPS_MODEL_HAS_POS_XYZ // GPS_MODEL_IS_GPS, GPS_MODEL_HAS_POS, GPS_MODEL_HAS_POS_XYZ ? +#define GPS_MODEL_HAS_POS_LLA // GPS_MODEL_IS_GPS, GPS_MODEL_HAS_POS, GPS_MODEL_HAS_POS_LLA ? +#define GPS_MODEL_HAS_TZDL // req +#define GPS_MODEL_HAS_PORT_PARM // deprecated, use only if ri not supported +#define GPS_MODEL_HAS_SYNTH // ri GPS_HAS_SYNTH +#define GPS_MODEL_HAS_ANT_INFO // GPS_MODEL_IS_GPS, also GNSS, or req? +#define GPS_MODEL_HAS_UCAP // ri n_ucap +#define GPS_MODEL_HAS_ENABLE_FLAGS // req +#define GPS_MODEL_HAS_STAT_INFO // req +#define GPS_MODEL_HAS_SWITCH_PARMS // deprecated, use ... +#define GPS_MODEL_HAS_STRING_PARMS // deprecated, use ... +#define GPS_MODEL_HAS_ANT_CABLE_LEN // GPS_MODEL_IS_GPS, also GNSS, or req? +#define GPS_MODEL_HAS_SYNC_OUTAGE_DELAY // custom +#define GPS_MODEL_HAS_PULSE_INFO // custom +#define GPS_MODEL_HAS_OPT_FEATURES // deprecated, use ri +#define GPS_MODEL_HAS_IRIG_TX_SETTINGS // ri GPS_HAS_IRIG_TX +#define GPS_MODEL_HAS_RECEIVER_INFO // -- +#define GPS_MODEL_HAS_STR_TYPE_INFO_IDX // ri n_str_type +#define GPS_MODEL_HAS_PORT_INFO_IDX // ri n_com +#define GPS_MODEL_HAS_PORT_SETTINGS_IDX // ri n_com +#define GPS_MODEL_HAS_POUT_INFO_IDX // ri n_pout +#define GPS_MODEL_HAS_POUT_SETTINGS_IDX // ri n_pout +#define GPS_MODEL_HAS_IRIG_TX_INFO // ri GPS_HAS_IRIG_TX +#define GPS_MODEL_HAS_MULTI_REF_SETTINGS // ri GPS_HAS_MULTI_REF +#define GPS_MODEL_HAS_MULTI_REF_INFO // ri GPS_HAS_MULTI_REF +#define GPS_MODEL_HAS_ROM_CSUM // ? +#define GPS_MODEL_HAS_MULTI_REF_STATUS // ri ... +#define GPS_MODEL_HAS_RCV_TIMEOUT // ri ... +#define GPS_MODEL_HAS_IRIG_RX_SETTINGS // ri ... +#define GPS_MODEL_HAS_IRIG_RX_INFO // ri ... +#define GPS_MODEL_HAS_REF_OFFS // ri ... +#define GPS_MODEL_HAS_DEBUG_STATUS // +#define GPS_MODEL_HAS_XMR_SETTINGS_IDX // +#define GPS_MODEL_HAS_XMR_INFO_IDX // +#define GPS_MODEL_HAS_XMR_STATUS_IDX // +#define GPS_MODEL_HAS_OPT_SETTINGS // +#define GPS_MODEL_HAS_OPT_INFO // +#define GPS_MODEL_HAS_CLR_UCAP_BUFF // +#define GPS_MODEL_HAS_TIME_SCALE // +#define GPS_MODEL_HAS_NAV_ENG_SETTINGS // +#define GPS_MODEL_HAS_RAW_IRIG_DATA // +#define GPS_MODEL_HAS_GPIO_CFG_LIMITS // +#define GPS_MODEL_HAS_GPIO_INFO_IDX // +#define GPS_MODEL_HAS_GPIO_SETTINGS_IDX // +#define GPS_MODEL_HAS_XMR_INSTANCES // +#define GPS_MODEL_HAS_CLR_EVT_LOG // +#define GPS_MODEL_HAS_NUM_EVT_LOG_ENTRIES // +#define GPS_MODEL_HAS_FIRST_EVT_LOG_ENTRY // +#define GPS_MODEL_HAS_NEXT_EVT_LOG_ENTRY // +#define GPS_MODEL_HAS_LNO_STATUS // +#define GPS_MODEL_HAS_IMS_STATE // +#define GPS_MODEL_HAS_IMS_SENSOR_STATE_IDX // +#define GPS_MODEL_HAS_XMR_HOLDOVER_INTV // +#define GPS_MODEL_HAS_HAVEQUICK_RX_SETTINGS // +#define GPS_MODEL_HAS_HAVEQUICK_RX_INFO // +#define GPS_MODEL_HAS_HAVEQUICK_TX_SETTINGS // +#define GPS_MODEL_HAS_HAVEQUICK_TX_INFO // +#define GPS_MODEL_HAS_PTP_CFG // +#define GPS_MODEL_HAS_PTP_STATE // +#define GPS_MODEL_HAS_PTP_UC_MASTER_CFG_LIMITS // +#define GPS_MODEL_HAS_PTP_UC_MASTER_CFG // +#define GPS_MODEL_HAS_NTP_GLB_CFG // +#define GPS_MODEL_HAS_NTP_CLNT_MODE_CFG // +#define GPS_MODEL_HAS_NTP_SRV_MODE_CFG // +#define GPS_MODEL_HAS_NTP_PEER_SETTINGS_IDX // +#define GPS_MODEL_HAS_NTP_SYS_STATE // +#define GPS_MODEL_HAS_NTP_PEER_STATE_IDX // +#define GPS_MODEL_HAS_SHS // +#define GPS_MODEL_HAS_SHS_STATUS // +#define GPS_MODEL_HAS_NET_GLB_CFG // +#define GPS_MODEL_HAS_NET_DNS_SRVR // +#define GPS_MODEL_HAS_NET_DNS_SRCH_DOM // +#define GPS_MODEL_HAS_NET_STAT_DNS_SRVR // +#define GPS_MODEL_HAS_NET_STAT_DNS_SRCH_DOM // +#define GPS_MODEL_HAS_GNSS_SAT_INFO_IDX // + +#define GPS_MODEL_HAS_CFGH // +#define GPS_MODEL_HAS_ALM // +#define GPS_MODEL_HAS_EPH // +#define GPS_MODEL_HAS_UTC // +#define GPS_MODEL_HAS_IONO // +#define GPS_MODEL_HAS_ASCII_MSG // + +#define GPS_MODEL_HAS_GLNS_ALM // +#define GPS_MODEL_HAS_GNSS_SAT_INFO // +//#define GPS_MODEL_HAS_GNSS_MODE // + +#define GPS_MODEL_HAS_IP4_SETTINGS // +#define GPS_MODEL_HAS_LAN_IF_INFO // +#define GPS_MODEL_HAS_IP4_STATE // + +#define GPS_MODEL_HAS_CRYPTED_PACKET // +#define GPS_MODEL_HAS_CRYPTED_RAW_PACKET // + +#define GPS_MODEL_HAS_SECU_INFO // +#define GPS_MODEL_HAS_SECU_SETTINGS // +#define GPS_MODEL_HAS_SECU_PUBLIC_KEY // + +#endif //##++ more potential builtin features and classifiers + + + +/** + * @brief Common builtin features of all GPS receivers + * + * @see ::BUILTIN_FEAT_GPS_BUS_LVL + * @see ::BUILTIN_FEAT_GNSS + */ +#define BUILTIN_FEAT_GPS \ +( \ + GPS_MODEL_IS_GPS | \ + GPS_MODEL_HAS_BVAR_STAT | \ + GPS_MODEL_HAS_POS_XYZ | \ + GPS_MODEL_HAS_POS_LLA | \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ANT_INFO | \ + GPS_MODEL_HAS_ENABLE_FLAGS | \ + GPS_MODEL_HAS_STAT_INFO | \ + GPS_MODEL_HAS_ANT_CABLE_LEN | \ + GPS_MODEL_HAS_SV_INFO \ +) + + +/** + * @brief Common builtin features of all GNSS receivers + * + * GNSS includes GPS but optionally other satellite systems, + * and the associated API. + * + * @see ::BUILTIN_FEAT_GNSS_BUS_LVL + * @see ::BUILTIN_FEAT_GPS + */ +#define BUILTIN_FEAT_GNSS \ +( \ + BUILTIN_FEAT_GPS | \ + GPS_MODEL_IS_GNSS \ +) + + + +/** + * @brief Common builtin features of all simple TCR devices + */ +#define BUILTIN_FEAT_TCR_1 \ +( \ + GPS_MODEL_IS_TCR \ +) + + +/** + * @brief Common builtin features of all enhanced TCR devices + */ +#define BUILTIN_FEAT_TCR_2 \ +( \ + GPS_MODEL_IS_TCR | \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ANT_INFO | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + + +/** + * @brief Common builtin features of all simple DCF77 AM receivers + */ +#define BUILTIN_FEAT_DCF_1 \ +( \ + GPS_MODEL_IS_DCF_AM | \ + GPS_MODEL_HAS_TZCODE \ +) + + +/** + * @brief Common builtin features of all enhanced DCF77 AM receivers + */ +#define BUILTIN_FEAT_DCF_2 \ +( \ + GPS_MODEL_IS_DCF_AM | \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ANT_INFO | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + +/** + * @brief Common builtin features of all simple DCF77 PZF receivers + */ +#define BUILTIN_FEAT_DCF_PZF_1 \ +( \ + GPS_MODEL_IS_DCF_PZF | \ + GPS_MODEL_HAS_TZCODE \ +) + + +/** + * @brief Common builtin features of all enhanced DCF77 PZF receivers + */ +#define BUILTIN_FEAT_DCF_PZF_2 \ +( \ + GPS_MODEL_IS_DCF_AM | \ + GPS_MODEL_IS_DCF_PZF | \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ANT_INFO | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + + +/** + * @brief Common builtin features of all simple MSF receivers + */ +#define BUILTIN_FEAT_MSF_1 \ +( \ + GPS_MODEL_IS_MSF | \ + GPS_MODEL_HAS_TZCODE \ +) + + +/** + * @brief Common builtin features of all enhanced MSF receivers + */ +#define BUILTIN_FEAT_MSF_2 \ +( \ + GPS_MODEL_IS_MSF | \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ANT_INFO | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + + +/** + * @brief Common builtin features of all simple WWVB receivers + */ +#define BUILTIN_FEAT_WVB_1 \ +( \ + GPS_MODEL_IS_WWVB | \ + GPS_MODEL_HAS_TZCODE \ +) + + +/** + * @brief Common builtin features of all enhanced WWVB receivers + */ +#define BUILTIN_FEAT_WVB_2 \ +( \ + GPS_MODEL_IS_WWVB | \ + GPS_MODEL_HAS_TZDL \ +) + + + +/** + * @brief Common builtin features of all simple JJY receivers + */ +#define BUILTIN_FEAT_JJY_1 \ +( \ + GPS_MODEL_IS_JJY | \ + GPS_MODEL_HAS_TZCODE \ +) + + + +/** + * @brief Common builtin features of all N2X devices + */ +#define BUILTIN_FEAT_COMM_N2X \ +( \ + GPS_MODEL_HAS_TIME_TTM | \ + GPS_MODEL_HAS_TZDL | \ + GPS_MODEL_HAS_ENABLE_FLAGS \ +) + + + +/** + * @brief Common builtin features of all bus-level GPS receivers + */ +#define BUILTIN_FEAT_GPS_BUS_LVL ( BUILTIN_FEAT_GPS | GPS_MODEL_IS_BUS_LVL_DEV ) + + +/** + * @brief Common builtin features of all bus-level GNSS receivers + */ +#define BUILTIN_FEAT_GNSS_BUS_LVL ( BUILTIN_FEAT_GNSS | GPS_MODEL_IS_BUS_LVL_DEV ) + + +/** + * @brief Common builtin features of all simple, bus-level TCR devices + */ +#define BUILTIN_FEAT_TCR_1_BUS_LVL ( BUILTIN_FEAT_TCR_1 | GPS_MODEL_IS_BUS_LVL_DEV ) + +/** + * @brief Common builtin features of all enhanced, bus-level TCR devices + */ +#define BUILTIN_FEAT_TCR_2_BUS_LVL ( BUILTIN_FEAT_TCR_2 | GPS_MODEL_IS_BUS_LVL_DEV ) + + +/** + * @brief Common builtin features of all simple, bus-level DCF77 AM receivers + */ +#define BUILTIN_FEAT_DCF_1_BUS_LVL ( BUILTIN_FEAT_DCF_1 | GPS_MODEL_IS_BUS_LVL_DEV ) + +/** + * @brief Common builtin features of all enhanced, bus-level DCF77 AM receivers + */ +#define BUILTIN_FEAT_DCF_2_BUS_LVL ( BUILTIN_FEAT_DCF_2 | GPS_MODEL_IS_BUS_LVL_DEV ) + +/** + * @brief Common builtin features of all enhanced, bus-level DCF77 PZF receivers + */ +#define BUILTIN_FEAT_DCF_PZF_2_BUS_LVL ( BUILTIN_FEAT_DCF_PZF_2 | GPS_MODEL_IS_BUS_LVL_DEV ) + + + +/** + * @brief Definitions of builtin features per device type + * + * @see ::GPS_MODEL_CODES + * @see @ref GPS_MODEL_BUILTIN_FEATURES + * + * @anchor GPS_MODEL_BUILTIN_FEATURE_MASKS @{ */ + +#define BUILTIN_FEAT_GPS166 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS167 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS167SV ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS167PC ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_GPS167PCI ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_GPS163 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS168PCI ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_GPS161 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS169PCI ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_TCR167PCI ( BUILTIN_FEAT_TCR_2_BUS_LVL ) +#define BUILTIN_FEAT_GPS164 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS170PCI ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_PZF511 ( BUILTIN_FEAT_DCF_PZF_1 ) +#define BUILTIN_FEAT_GPS170 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_TCR511 ( BUILTIN_FEAT_TCR_1_BUS_LVL | GPS_MODEL_HAS_TIME_TTM ) //### TODO Or full TCR_2? +#define BUILTIN_FEAT_AM511 ( BUILTIN_FEAT_DCF_1 ) +#define BUILTIN_FEAT_MSF511 ( BUILTIN_FEAT_MSF_1 ) +#define BUILTIN_FEAT_GRC170 ( BUILTIN_FEAT_GNSS ) +#define BUILTIN_FEAT_GPS170PEX ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_GPS162 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_PTP270PEX ( GPS_MODEL_IS_BUS_LVL_DEV ) +#define BUILTIN_FEAT_FRC511PEX ( GPS_MODEL_IS_BUS_LVL_DEV ) +#define BUILTIN_FEAT_GEN170 ( GPS_MODEL_HAS_TIME_TTM ) +#define BUILTIN_FEAT_TCR170PEX ( BUILTIN_FEAT_TCR_2_BUS_LVL ) +#define BUILTIN_FEAT_WWVB511 ( BUILTIN_FEAT_WVB_1 ) +#define BUILTIN_FEAT_MGR170 ( 0 ) +#define BUILTIN_FEAT_JJY511 ( BUILTIN_FEAT_JJY_1 ) +#define BUILTIN_FEAT_PZF600 ( BUILTIN_FEAT_DCF_PZF_1 ) //### TODO Or full PZF_2? +#define BUILTIN_FEAT_TCR600 ( BUILTIN_FEAT_TCR_1 | GPS_MODEL_HAS_TIME_TTM ) //### TODO Or full TCR_2? +#define BUILTIN_FEAT_GPS180 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GLN170 ( BUILTIN_FEAT_GNSS) +#define BUILTIN_FEAT_GPS180PEX ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_TCR180PEX ( BUILTIN_FEAT_TCR_2_BUS_LVL ) +#define BUILTIN_FEAT_PZF180PEX ( BUILTIN_FEAT_DCF_PZF_2_BUS_LVL ) +#define BUILTIN_FEAT_MGR180 ( 0 ) +#define BUILTIN_FEAT_MSF600 ( BUILTIN_FEAT_MSF_1 ) //### TODO Or full MSF_2? +#define BUILTIN_FEAT_WWVB600 ( BUILTIN_FEAT_WVB_1 ) //### TODO Or full WVB_2? +#define BUILTIN_FEAT_JJY600 ( BUILTIN_FEAT_JJY_1 ) //### TODO Or full JJY_2? +#define BUILTIN_FEAT_GPS180HS ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GPS180AMC ( BUILTIN_FEAT_GPS_BUS_LVL ) +#define BUILTIN_FEAT_ESI180 ( 0 ) +#define BUILTIN_FEAT_CPE180 ( 0 ) +#define BUILTIN_FEAT_LNO180 ( 0 ) +#define BUILTIN_FEAT_GRC180 ( BUILTIN_FEAT_GNSS ) +#define BUILTIN_FEAT_LIU ( 0 ) +#define BUILTIN_FEAT_DCF600HS ( BUILTIN_FEAT_DCF_2 ) //### TODO +#define BUILTIN_FEAT_DCF600RS ( BUILTIN_FEAT_DCF_2 ) //### TODO +#define BUILTIN_FEAT_MRI ( 0 ) +#define BUILTIN_FEAT_BPE ( 0 ) +#define BUILTIN_FEAT_GLN180PEX ( BUILTIN_FEAT_GNSS_BUS_LVL ) +#define BUILTIN_FEAT_N2X ( BUILTIN_FEAT_COMM_N2X ) +#define BUILTIN_FEAT_RSC180 ( GPS_MODEL_HAS_SCU_STAT ) +#define BUILTIN_FEAT_LNE_GB ( 0 ) +#define BUILTIN_FEAT_PPG180 ( 0 ) +#define BUILTIN_FEAT_SCG ( 0 ) +#define BUILTIN_FEAT_MDU300 ( 0 ) +#define BUILTIN_FEAT_SDI ( 0 ) +#define BUILTIN_FEAT_FDM180 ( GPS_MODEL_HAS_TZDL | GPS_MODEL_HAS_ENABLE_FLAGS ) +#define BUILTIN_FEAT_SPT ( 0 ) +#define BUILTIN_FEAT_PZF180 ( BUILTIN_FEAT_DCF_PZF_2 ) +#define BUILTIN_FEAT_REL1000 ( 0 ) +#define BUILTIN_FEAT_HPS100 ( 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 ( GPS_MODEL_HAS_MBG_OS ) +#define BUILTIN_FEAT_TCR180 ( BUILTIN_FEAT_TCR_2 ) +#define BUILTIN_FEAT_LUE180 ( 0 ) +#define BUILTIN_FEAT_CPC_01 ( 0 ) +#define BUILTIN_FEAT_TSU_01 ( 0 ) +#define BUILTIN_FEAT_CMC_01 ( 0 ) +#define BUILTIN_FEAT_SCU_01 ( 0 ) +#define BUILTIN_FEAT_FCU_01 ( 0 ) +#define BUILTIN_FEAT_MSSB100 ( GPS_MODEL_HAS_MBG_OS ) +#define BUILTIN_FEAT_LNE180SFP ( 0 ) +#define BUILTIN_FEAT_GTS180 ( 0 ) +#define BUILTIN_FEAT_GPS180CSM ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GRC181 ( BUILTIN_FEAT_GNSS ) +#define BUILTIN_FEAT_N2X180 ( BUILTIN_FEAT_COMM_N2X ) +#define BUILTIN_FEAT_GNS181PEX ( BUILTIN_FEAT_GNSS_BUS_LVL ) +#define BUILTIN_FEAT_MDU180 ( GPS_MODEL_HAS_SCU_STAT ) +#define BUILTIN_FEAT_MDU312 ( 0 ) +#define BUILTIN_FEAT_GPS165 ( BUILTIN_FEAT_GPS ) +#define BUILTIN_FEAT_GNS181_UC ( BUILTIN_FEAT_GNSS | 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_CPC200 ( 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 ) +#define BUILTIN_FEAT_BPE_STM ( 0 ) +#define BUILTIN_FEAT_VSI180 ( 0 ) +#define BUILTIN_FEAT_GNM181 ( BUILTIN_FEAT_GNSS ) +#define BUILTIN_FEAT_RSCRDU_TTL ( GPS_MODEL_HAS_SCU_STAT ) +#define BUILTIN_FEAT_RSC2000 ( GPS_MODEL_HAS_SCU_STAT ) +#define BUILTIN_FEAT_FCU200 ( 0 ) +#define BUILTIN_FEAT_REL1000_RC ( BUILTIN_FEAT_REL1000 ) + +/** + * @brief Feature mask used for legacy devices + * + * This code is used to set builtin feature flags + * legacy devices not listed here, so we can simply + * search for ::BUILTIN_FEAT_UNDEFINED to identify + * such devices. The numeric value is just 0, though. + */ +#define BUILTIN_FEAT_UNDEFINED ( 0 ) + +/** @} anchor GPS_MODEL_BUILTIN_FEATURE_MASKS */ + + + +#if !defined( MBG_TGT_DOS ) + +/** + * @brief Initializer for a table of built-in features per device + * + * Last entry is all zero to indicated end of table. + * + * @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_MSSB100, BUILTIN_FEAT_MSSB100 }, \ + { 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_CPC200, BUILTIN_FEAT_CPC200 }, \ + { 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 }, \ + { GPS_MODEL_BPE_STM, BUILTIN_FEAT_BPE_STM }, \ + { GPS_MODEL_VSI180, BUILTIN_FEAT_VSI180 }, \ + { GPS_MODEL_GNM181, BUILTIN_FEAT_GNM181 }, \ + { GPS_MODEL_RSCRDU_TTL, BUILTIN_FEAT_RSCRDU_TTL }, \ + { GPS_MODEL_RSC2000, BUILTIN_FEAT_RSC2000 }, \ + { GPS_MODEL_FCU200, BUILTIN_FEAT_FCU200 }, \ + { GPS_MODEL_REL1000_RC, BUILTIN_FEAT_REL1000_RC }, \ + { 0, 0 } \ +} + + + +/** + * @brief Enumeration of CPU types used in Meinberg products. + * + * @see @ref group_dev_cpu_type_names + * @see ::MBG_DEV_CPU_TYPE_NAMES + */ +enum MBG_DEV_CPU_TYPES +{ + MBG_DEV_CPU_TYPE_UNSPEC, ///< Unspecified, unknown, or special (e.g. embedded system) + MBG_DEV_CPU_TYPE_C509, + MBG_DEV_CPU_TYPE_C166_C167, + MBG_DEV_CPU_TYPE_C163, + MBG_DEV_CPU_TYPE_GP4020, + MBG_DEV_CPU_TYPE_XC164_XC167, + MBG_DEV_CPU_TYPE_T89C5XACX, + MBG_DEV_CPU_TYPE_XE167, + MBG_DEV_CPU_TYPE_SAM3U, + MBG_DEV_CPU_TYPE_SAM3S, + MBG_DEV_CPU_TYPE_STM32F0, + MBG_DEV_CPU_TYPE_STM32F4, + MBG_DEV_CPU_TYPE_STM32F7, + N_MBG_DEV_CPU_TYPES +}; + + + +/** + * @defgroup group_dev_cpu_type_names Name strings of CPU types used with Meinberg devices. + * + * Name strings for the CPU types enumerated in ::MBG_DEV_CPU_TYPES. + * + * @see ::MBG_DEV_CPU_TYPES + * @see ::MBG_DEV_CPU_TYPE_NAMES + * + * @{ */ + +#define MBG_DEV_CPU_NAME_UNSPEC "(unspecified)" +#define MBG_DEV_CPU_NAME_C509 "C509" +#define MBG_DEV_CPU_NAME_C166_C167 "C166/C167" +#define MBG_DEV_CPU_NAME_C163 "C163" +#define MBG_DEV_CPU_NAME_GP4020 "GP4020" +#define MBG_DEV_CPU_NAME_XC164_XC167 "XC164/XC167" +#define MBG_DEV_CPU_NAME_T89C5XACX "T89C5xACx" +#define MBG_DEV_CPU_NAME_XE167 "XE167" +#define MBG_DEV_CPU_NAME_SAM3U "SAM3U" +#define MBG_DEV_CPU_NAME_SAM3S "SAM3S" +#define MBG_DEV_CPU_NAME_STM32F0 "STM32F0" +#define MBG_DEV_CPU_NAME_STM32F4 "STM32F4" +#define MBG_DEV_CPU_NAME_STM32F7 "STM32F7" + +/** @} defgroup group_dev_cpu_type_names */ + + + +/** + * @brief Initializer for an array of CPU type name strings + * + * The array should have ::N_MBG_DEV_CPU_TYPES entries. + * + * @see ::MBG_DEV_CPU_TYPES + * @see @ref MBG_DEV_CPU_TYPE_NAMES + */ +#define MBG_DEV_CPU_TYPE_NAMES \ +{ \ + MBG_DEV_CPU_NAME_UNSPEC, \ + MBG_DEV_CPU_NAME_C509, \ + MBG_DEV_CPU_NAME_C166_C167, \ + MBG_DEV_CPU_NAME_C163, \ + MBG_DEV_CPU_NAME_GP4020, \ + MBG_DEV_CPU_NAME_XC164_XC167, \ + MBG_DEV_CPU_NAME_T89C5XACX, \ + MBG_DEV_CPU_NAME_XE167, \ + MBG_DEV_CPU_NAME_SAM3U, \ + MBG_DEV_CPU_NAME_SAM3S, \ + MBG_DEV_CPU_NAME_STM32F0 \ + MBG_DEV_CPU_NAME_STM32F4 \ + MBG_DEV_CPU_NAME_STM32F7 \ +} + + + +/** + * @brief Initializer for a table of CPU type per device. + * + * Last entry is all zero to indicated end of table. + * + * @see ::GPS_MODEL_CODES + * @see ::MBG_DEV_CPU_TYPES + */ +#define MBG_DEV_CPU_TYPE_TABLE_INIT \ +{ \ + { GPS_MODEL_GPS166, MBG_DEV_CPU_TYPE_C166_C167 }, \ + { GPS_MODEL_GPS167, MBG_DEV_CPU_TYPE_C166_C167 }, \ + { GPS_MODEL_GPS167SV, MBG_DEV_CPU_TYPE_C166_C167 }, \ + { GPS_MODEL_GPS167PC, MBG_DEV_CPU_TYPE_C166_C167 }, \ + { GPS_MODEL_GPS167PCI, MBG_DEV_CPU_TYPE_C166_C167 }, \ + { GPS_MODEL_GPS163, MBG_DEV_CPU_TYPE_C163 }, \ + { GPS_MODEL_GPS168PCI, MBG_DEV_CPU_TYPE_C166_C167 }, \ + { GPS_MODEL_GPS161, MBG_DEV_CPU_TYPE_GP4020 }, \ + { GPS_MODEL_GPS169PCI, MBG_DEV_CPU_TYPE_C166_C167 }, \ + { GPS_MODEL_TCR167PCI, MBG_DEV_CPU_TYPE_C166_C167 }, \ + { GPS_MODEL_GPS164, MBG_DEV_CPU_TYPE_XC164_XC167 }, \ + { GPS_MODEL_GPS170PCI, MBG_DEV_CPU_TYPE_XC164_XC167 }, \ + { GPS_MODEL_PZF511, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_GPS170, MBG_DEV_CPU_TYPE_XC164_XC167 }, \ + { GPS_MODEL_TCR511, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_AM511, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_MSF511, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_GRC170, MBG_DEV_CPU_TYPE_XC164_XC167 }, \ + { GPS_MODEL_GPS170PEX, MBG_DEV_CPU_TYPE_XC164_XC167 }, \ + { GPS_MODEL_GPS162, MBG_DEV_CPU_TYPE_XE167 }, \ + { GPS_MODEL_PTP270PEX, 0 /* Toradex */ }, \ + { GPS_MODEL_FRC511PEX, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_GEN170, MBG_DEV_CPU_TYPE_XC164_XC167 }, \ + { GPS_MODEL_TCR170PEX, MBG_DEV_CPU_TYPE_XE167 }, \ + { GPS_MODEL_WWVB511, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_MGR170, MBG_DEV_CPU_TYPE_XC164_XC167 }, \ + { GPS_MODEL_JJY511, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_PZF600, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_TCR600, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_GPS180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_GLN170, MBG_DEV_CPU_TYPE_XC164_XC167 }, \ + { GPS_MODEL_GPS180PEX, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_TCR180PEX, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_PZF180PEX, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_MGR180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_MSF600, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_WWVB600, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_JJY600, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_GPS180HS, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_GPS180AMC, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_ESI180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_CPE180, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_LNO180, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_GRC180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_LIU, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_DCF600HS, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_DCF600RS, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_MRI, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_BPE, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_GLN180PEX, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_N2X, MBG_DEV_CPU_TYPE_STM32F4 }, \ + { GPS_MODEL_RSC180, MBG_DEV_CPU_TYPE_STM32F4 }, \ + { GPS_MODEL_LNE_GB, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_PPG180, MBG_DEV_CPU_TYPE_STM32F4 }, \ + { GPS_MODEL_SCG, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_MDU300, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_SDI, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_FDM180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_SPT, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_PZF180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_REL1000, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_HPS100, 0 }, \ + { GPS_MODEL_VSG180, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_MSF180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_WWVB180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_CPC180, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_CTC100, 0 }, \ + { GPS_MODEL_TCR180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_LUE180, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_CPC_01, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_TSU_01, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_CMC_01, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_SCU_01, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_FCU_01, MBG_DEV_CPU_TYPE_T89C5XACX }, \ + { GPS_MODEL_MSSB100, 0 }, \ + { GPS_MODEL_LNE180SFP, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_GTS180, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_GPS180CSM, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_GRC181, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_N2X180, MBG_DEV_CPU_TYPE_STM32F4 }, \ + { GPS_MODEL_GNS181PEX, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_MDU180, MBG_DEV_CPU_TYPE_STM32F4 }, \ + { GPS_MODEL_MDU312, MBG_DEV_CPU_TYPE_SAM3S }, \ + { GPS_MODEL_GPS165, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_GNS181_UC, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_PSX_4GE, 0 }, \ + { GPS_MODEL_RSC180RDU, MBG_DEV_CPU_TYPE_STM32F4 }, \ + { GPS_MODEL_CPC200, MBG_DEV_CPU_TYPE_STM32F0 }, \ + { GPS_MODEL_FDM180M, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_LSG180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_GPS190, MBG_DEV_CPU_TYPE_STM32F7 }, \ + { GPS_MODEL_GNS181, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_PIO180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_FCM180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_TCR180USB, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_SSP100, 0 }, \ + { GPS_MODEL_GNS165, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_RSC180RDMP, MBG_DEV_CPU_TYPE_STM32F4 }, \ + { GPS_MODEL_GPS16X, MBG_DEV_CPU_TYPE_UNSPEC }, \ + { GPS_MODEL_MSHPS100, 0 }, \ + { GPS_MODEL_BPE_STM, MBG_DEV_CPU_TYPE_STM32F0 }, \ + { GPS_MODEL_VSI180, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_GNM181, MBG_DEV_CPU_TYPE_SAM3U }, \ + { GPS_MODEL_RSCRDU_TTL, 0 }, \ + { GPS_MODEL_RSC2000, 0 }, \ + { GPS_MODEL_FCU200, 0 }, \ + { GPS_MODEL_REL1000_RC, 0 }, \ + { 0, 0 } \ +} + +#endif // !defined( MBG_TGT_DOS ) + +/** @} anchor GPS_BUILTIN_FEATURE_DEFS */ + + + +/** + * @brief Initialize a ::RECEIVER_INFO structure for legacy DCF77 receivers + * + * Legacy DCF77 receivers may not provide a ::RECEIVER_INFO structure, + * but have well-known properties which can be used to set up a + * default ::RECEIVER_INFO. + * + * @param[in,out] _p Pointer to a ::RECEIVER_INFO STRUCTURE to be set up + * @param[in] _pdev Pointer to a ::PCPS_DEV structure read before + * + * @see ::_setup_default_receiver_info_gps + */ +#define _setup_default_receiver_info_dcf( _p, _pdev ) \ +do \ +{ \ + memset( (_p), 0, sizeof( *(_p) ) ); \ + \ + (_p)->ticks_per_sec = (uint32_t) DEFAULT_GPS_TICKS_PER_SEC; \ + (_p)->n_ucaps = (uint8_t) 0; \ + (_p)->n_com_ports = (uint8_t) ( _pcps_has_serial( _pdev ) ? 1 : 0 ); \ + (_p)->n_str_type = (uint8_t) ( ( (_p)->n_com_ports != 0 ) ? \ + DEFAULT_N_STR_TYPE_DCF : 0 ); \ +} while ( 0 ) + + + +/** + * @brief Initialize a ::RECEIVER_INFO structure for legacy GPS receivers + * + * Legacy GPS receivers may not provide a ::RECEIVER_INFO structure, + * but have well-known properties which can be used to set up a + * default ::RECEIVER_INFO. + * + * @param[in,out] _p Pointer to a ::RECEIVER_INFO STRUCTURE to be set up + * + * @see ::_setup_default_receiver_info_dcf + */ +#define _setup_default_receiver_info_gps( _p ) \ +do \ +{ \ + memset( (_p), 0, sizeof( *(_p) ) ); \ + \ + (_p)->ticks_per_sec = DEFAULT_GPS_TICKS_PER_SEC; \ + (_p)->n_ucaps = 2; \ + (_p)->n_com_ports = DEFAULT_N_COM; \ + (_p)->n_str_type = DEFAULT_N_STR_TYPE_GPS; \ +} while ( 0 ) + + + +/* + * The macros below can be used to classify a receiver, + * e.g. depending on the time source and/or depending on + * whether it's a plug-in card or an external device. + */ + +#define _mbg_rcvr_is_plug_in( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "PC" ) || \ + strstr( (_p_ri)->model_name, "PEX" ) ) + +#define _mbg_rcvr_is_gps( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "GPS" ) || \ + strstr( (_p_ri)->model_name, "MGR" ) ) + +#define _mbg_rcvr_is_mobile_gps( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "MGR" ) ) + +#define _mbg_rcvr_is_gps_plug_in( _p_ri ) \ + ( _mbg_rcvr_is_gps( _p_ri ) && \ + _mbg_rcvr_is_plug_in( _p_ri ) ) + +#define _mbg_rcvr_is_irig( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "TCR" ) ) + +#define _mbg_rcvr_is_irig_plug_in( _p_ri ) \ + ( _mbg_rcvr_is_irig( _p_ri ) && \ + _mbg_rcvr_is_plug_in( _p_ri ) ) + +#define _mbg_rcvr_is_dcf77_am( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "AM" ) ) + +#define _mbg_rcvr_is_dcf77_am_plug_in( _p_ri ) \ + ( _mbg_rcvr_is_dcf77_am( _p_ri ) && \ + _mbg_rcvr_is_plug_in( _p_ri ) ) + +#define _mbg_rcvr_is_dcf77_pzf( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "PZF" ) ) + +#define _mbg_rcvr_is_dcf77_pzf_plug_in( _p_ri ) \ + ( _mbg_rcvr_is_dcf77_pzf( _p_ri ) && \ + _mbg_rcvr_is_plug_in( _p_ri ) ) + +#define _mbg_rcvr_is_any_dcf77( _p_ri ) \ + ( _mbg_rcvr_is_dcf77_am( _p_ri ) || \ + _mbg_rcvr_is_dcf77_pzf( _p_ri ) ) + +#define _mbg_rcvr_is_any_dcf77_plug_in( _p_ri ) \ + ( _mbg_rcvr_is_any_dcf77( _p_ri ) && \ + _mbg_rcvr_is_plug_in( _p_ri ) ) + +#define _mbg_rcvr_is_msf( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "MSF" ) ) + +#define _mbg_rcvr_is_jjy( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "JJY" ) ) + +#define _mbg_rcvr_is_msf_plug_in( _p_ri ) \ + ( _mbg_rcvr_is_msf( _p_ri ) && \ + _mbg_rcvr_is_plug_in( _p_ri ) ) + +#define _mbg_rcvr_is_glonass( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "GRC" ) || \ + strstr( (_p_ri)->model_name, "GLN" ) ) + +#define _mbg_rcvr_is_glonass_plug_in( _p_ri ) \ + ( _mbg_rcvr_is_glonass( _p_ri ) && \ + _mbg_rcvr_is_plug_in( _p_ri ) ) + +#define _mbg_rcvr_is_wwvb( _p_ri ) \ + ( strstr( (_p_ri)->model_name, "WWVB" ) ) + +#define _mbg_rcvr_is_wwvb_plug_in( _p_ri ) \ + ( _mbg_rcvr_is_wwvb( _p_ri ) && \ + _mbg_rcvr_is_plug_in( _p_ri ) ) + + + +/** + * @brief Known oscillator types used with ::RECEIVER_INFO::osc_type + * + * The sequence of codes does NOT reflect the order of quality. + * New oscillator type codes will just be appended to the enumeration. + * + * @see ::DEFAULT_GPS_OSC_NAMES + * @see ::DEFAULT_GPS_OSC_QUALITY_IDX + */ +enum GPS_OSC_TYPES +{ + GPS_OSC_UNKNOWN, + GPS_OSC_TCXO_LQ, + GPS_OSC_TCXO_HQ, + GPS_OSC_OCXO_LQ, + GPS_OSC_OCXO_MQ, + GPS_OSC_OCXO_HQ, + GPS_OSC_OCXO_XHQ, + GPS_OSC_RUBIDIUM, + GPS_OSC_TCXO_MQ, + GPS_OSC_OCXO_DHQ, + GPS_OSC_OCXO_SQ, + N_GPS_OSC +}; + + +/** + * @brief Oscillator type name string initializer + * + * The sequence and number of oscillator names has to + * correspond to the enumeration in ::GPS_OSC_TYPES + * + * @see ::GPS_OSC_TYPES + * @see ::DEFAULT_GPS_OSC_QUALITY_IDX + */ +#define DEFAULT_GPS_OSC_NAMES \ +{ \ + "[unknown]", \ + "TCXO LQ", \ + "TCXO", \ + "OCXO LQ", \ + "OCXO MQ", \ + "OCXO HQ", \ + "OCXO XHQ", \ + "RUBIDIUM", \ + "TCXO MQ", \ + "OCXO DHQ", \ + "OCXO SQ" \ +} + + +/** + * @brief Oscillator quality index + * + * Can be used to initialize a index array + * (e.g. "int osc_quality_idx[N_GPS_OSC];") + * allowing to display the oscillator types + * ordered by quality + * + * @see ::GPS_OSC_TYPES + * @see ::DEFAULT_GPS_OSC_NAMES + */ +#define DEFAULT_GPS_OSC_QUALITY_IDX \ +{ \ + GPS_OSC_UNKNOWN, \ + GPS_OSC_TCXO_LQ, \ + GPS_OSC_TCXO_MQ, \ + GPS_OSC_TCXO_HQ, \ + GPS_OSC_OCXO_LQ, \ + GPS_OSC_OCXO_SQ, \ + GPS_OSC_OCXO_MQ, \ + GPS_OSC_OCXO_HQ, \ + GPS_OSC_OCXO_DHQ, \ + GPS_OSC_OCXO_XHQ, \ + GPS_OSC_RUBIDIUM \ +} + + + +/** + * @brief Enumeration of device features flags reported in ::RI_FEATURES + * + * Used with ::RECEIVER_INFO::features. Each flags indicates if a device + * supports the associated feature, but due to the limited bit size of + * the ::RI_FEATURES type the number of these features is limited to 32. + * + * To extend the number of possible features the ::MBG_XFEATURE_BITS, the + * ::MBG_XFEATURE_BUFFER structure and associated definitions have been + * introduced, which are supported by devices which have ::GPS_HAS_XFEATURE + * set in ::RI_FEATURES. + * + * @see ::RI_FEATURES + * @see ::MBG_XFEATURE_BITS + * @see ::MBG_XFEATURE_BUFFER + */ +enum GPS_FEATURE_BITS +{ + GPS_FEAT_PPS, ///< has pulse per second output + GPS_FEAT_PPM, ///< has pulse per minute output + GPS_FEAT_SYNTH, ///< has programmable synthesizer output + GPS_FEAT_DCFMARKS, ///< has DCF77 compatible time mark output + GPS_FEAT_IRIG_TX, ///< has on-board IRIG output + GPS_FEAT_IRIG_RX, ///< has on-board IRIG input + GPS_FEAT_LAN_IP4, ///< has simple LAN IPv4 interface, superseded by ::GPS_FEAT_NET_CFG + GPS_FEAT_MULTI_REF, ///< has multiple input sources with priorities, superseded by ::GPS_FEAT_XMULTI_REF + + GPS_FEAT_RCV_TIMEOUT, ///< timeout after GPS reception has stopped + GPS_FEAT_IGNORE_LOCK, ///< supports "ignore lock", ::MBG_OPT_BIT_EMU_SYNC can be set alternatively + GPS_FEAT_5_MHZ, ///< output 5 MHz rather than 100 kHz + GPS_FEAT_XMULTI_REF, ///< has extended multiple input source configuration, supersedes ::GPS_FEAT_MULTI_REF + GPS_FEAT_OPT_SETTINGS, ///< supports ::MBG_OPT_SETTINGS + GPS_FEAT_TIME_SCALE, ///< supports configurable time scale (%UTC, TAI, GPS, ...) + GPS_FEAT_IRIG_CTRL_BITS, ///< supports IRIG control bits (::MBG_IRIG_CTRL_BITS) + GPS_FEAT_PTP, ///< has PTP support + + GPS_FEAT_NAV_ENGINE_SETTINGS, ///< supports navigation engine configuration + GPS_FEAT_RAW_IRIG_DATA, ///< supports reading raw IRIG input data (::MBG_RAW_IRIG_DATA) + GPS_FEAT_RAW_IRIG_TIME, ///< supports reading decoded IRIG time (::PCPS_IRIG_TIME) + GPS_FEAT_PTP_UNICAST, ///< has PTP Unicast support + GPS_FEAT_GPIO, ///< has general purpose inputs/outputs + GPS_FEAT_XMRS_MULT_INSTC, ///< multiple XMRS instances of the same ref type supported (::XMULTI_REF_INSTANCES) + GPS_FEAT_10MHZ_DISBD, ///< 10 MHz output is always disabled + GPS_FEAT_EVT_LOG, ///< Event logging supported + + GPS_FEAT_IMS, ///< supports IMS data structures + GPS_FEAT_HAVEQUICK, ///< supports HaveQuick structures + GPS_FEAT_NTP, ///< supports NTP structures + GPS_FEAT_NET_CFG, ///< supports extended network interface configuration, supersedes ::GPS_FEAT_LAN_IP4 + GPS_FEAT_VST, ///< supports VST (Versatile Storage) API and structures + GPS_FEAT_SHS, ///< supports SHS (Secure Hybrid System) API and structures + GPS_FEAT_XBP, ///< supports XBP (eXtended Binary Protocol) API and structures, see @ref group_xbp + GPS_FEAT_XFEATURE, ///< support eXtended features, see @ref group_xfeature + N_GPS_FEATURE ///< the number of known ::GPS_FEATURE_BITS, should now be at its limit, i.e. 32. + + // WARNING: There are no more unassigned feature bits available here. + // New features have to be defined using the ::MBG_XFEATURE_BITS +}; + + +/** + * @brief Names of device features + * + * @see ::GPS_FEATURE_BITS + */ +#define DEFAULT_GPS_FEATURE_NAMES \ +{ \ + "Pulse Per Second", \ + "Pulse Per Minute", \ + "Programmable Synth.", \ + "DCF77 Time Marks", \ + "IRIG Out", \ + "IRIG In", \ + "IPv4 LAN Interface", \ + "Multiple Ref. Sources", \ + "Receive Timeout", \ + "Ignore Lock", \ + "5 MHz Output", \ + "Ext. Multiple Ref. Src. Cfg.", \ + "Optional Settings", \ + "Configurable Time Scale", \ + "IRIG Control Bits", \ + "PTP/IEEE1588", \ + "Nav. Engine Settings", \ + "Raw IRIG Data", \ + "Raw IRIG Time", \ + "PTP/IEEE1588 Unicast", \ + "General Purpose I/O", \ + "Multiple XMRS Instances", \ + "10 MHz Output Disabled", \ + "Event Logging", \ + "IMS data", \ + "HaveQuick", \ + "NTP", \ + "Ext. Network Config", \ + "Versatile Storage", \ + "SHS", \ + "Extended Binary Protocol", \ + "Extended Features" \ +} + + +/** + * @brief Bit masks used with ::RECEIVER_INFO::features + * + * @see ::GPS_FEATURE_BITS + * + * @anchor GPS_FEATURE_MASKS @{ */ + +#define GPS_HAS_PPS ( 1UL << GPS_FEAT_PPS ) ///< See ::GPS_FEAT_PPS +#define GPS_HAS_PPM ( 1UL << GPS_FEAT_PPM ) ///< See ::GPS_FEAT_PPM +#define GPS_HAS_SYNTH ( 1UL << GPS_FEAT_SYNTH ) ///< See ::GPS_FEAT_SYNTH +#define GPS_HAS_DCFMARKS ( 1UL << GPS_FEAT_DCFMARKS ) ///< See ::GPS_FEAT_DCFMARKS +#define GPS_HAS_IRIG_TX ( 1UL << GPS_FEAT_IRIG_TX ) ///< See ::GPS_FEAT_IRIG_TX +#define GPS_HAS_IRIG_RX ( 1UL << GPS_FEAT_IRIG_RX ) ///< See ::GPS_FEAT_IRIG_RX +#define GPS_HAS_LAN_IP4 ( 1UL << GPS_FEAT_LAN_IP4 ) ///< See ::GPS_FEAT_LAN_IP4 +#define GPS_HAS_MULTI_REF ( 1UL << GPS_FEAT_MULTI_REF ) ///< See ::GPS_FEAT_MULTI_REF + +#define GPS_HAS_RCV_TIMEOUT ( 1UL << GPS_FEAT_RCV_TIMEOUT ) ///< See ::GPS_FEAT_RCV_TIMEOUT +#define GPS_HAS_IGNORE_LOCK ( 1UL << GPS_FEAT_IGNORE_LOCK ) ///< See ::GPS_FEAT_IGNORE_LOCK +#define GPS_HAS_5_MHZ ( 1UL << GPS_FEAT_5_MHZ ) ///< See ::GPS_FEAT_5_MHZ +#define GPS_HAS_XMULTI_REF ( 1UL << GPS_FEAT_XMULTI_REF ) ///< See ::GPS_FEAT_XMULTI_REF +#define GPS_HAS_OPT_SETTINGS ( 1UL << GPS_FEAT_OPT_SETTINGS ) ///< See ::GPS_FEAT_OPT_SETTINGS +#define GPS_HAS_TIME_SCALE ( 1UL << GPS_FEAT_TIME_SCALE ) ///< See ::GPS_FEAT_TIME_SCALE +#define GPS_HAS_IRIG_CTRL_BITS ( 1UL << GPS_FEAT_IRIG_CTRL_BITS ) ///< See ::GPS_FEAT_IRIG_CTRL_BITS +#define GPS_HAS_PTP ( 1UL << GPS_FEAT_PTP ) ///< See ::GPS_FEAT_PTP + +#define GPS_HAS_NAV_ENGINE_SETTINGS ( 1UL << GPS_FEAT_NAV_ENGINE_SETTINGS ) ///< See ::GPS_FEAT_NAV_ENGINE_SETTINGS +#define GPS_HAS_RAW_IRIG_DATA ( 1UL << GPS_FEAT_RAW_IRIG_DATA ) ///< See ::GPS_FEAT_RAW_IRIG_DATA +#define GPS_HAS_RAW_IRIG_TIME ( 1UL << GPS_FEAT_RAW_IRIG_TIME ) ///< See ::GPS_FEAT_RAW_IRIG_TIME +#define GPS_HAS_PTP_UNICAST ( 1UL << GPS_FEAT_PTP_UNICAST ) ///< See ::GPS_FEAT_PTP_UNICAST +#define GPS_HAS_GPIO ( 1UL << GPS_FEAT_GPIO ) ///< See ::GPS_FEAT_GPIO +#define GPS_HAS_XMRS_MULT_INSTC ( 1UL << GPS_FEAT_XMRS_MULT_INSTC ) ///< See ::GPS_FEAT_XMRS_MULT_INSTC +#define GPS_HAS_10MHZ_DISBD ( 1UL << GPS_FEAT_10MHZ_DISBD ) ///< See ::GPS_FEAT_10MHZ_DISBD +#define GPS_HAS_EVT_LOG ( 1UL << GPS_FEAT_EVT_LOG ) ///< See ::GPS_FEAT_EVT_LOG + +#define GPS_HAS_IMS ( 1UL << GPS_FEAT_IMS ) ///< See ::GPS_FEAT_IMS +#define GPS_HAS_HAVEQUICK ( 1UL << GPS_FEAT_HAVEQUICK ) ///< See ::GPS_FEAT_HAVEQUICK +#define GPS_HAS_NTP ( 1UL << GPS_FEAT_NTP ) ///< See ::GPS_FEAT_NTP +#define GPS_HAS_NET_CFG ( 1UL << GPS_FEAT_NET_CFG ) ///< See ::GPS_FEAT_NET_CFG +#define GPS_HAS_VST ( 1UL << GPS_FEAT_VST ) ///< See ::GPS_FEAT_VST +#define GPS_HAS_SHS ( 1UL << GPS_FEAT_SHS ) ///< See ::GPS_FEAT_SHS +#define GPS_HAS_XBP ( 1UL << GPS_FEAT_XBP ) ///< See ::GPS_FEAT_XBP +#define GPS_HAS_XFEATURE ( 1UL << GPS_FEAT_XFEATURE ) ///< See ::GPS_FEAT_XFEATURE + +// the next ones are special since they just shadow another flag: +#define GPS_HAS_REF_OFFS GPS_HAS_IRIG_RX ///< always supported with IRIG inputs, see ::GPS_HAS_IRIG_RX +#define GPS_HAS_DEBUG_STATUS GPS_HAS_IRIG_RX ///< always supported with IRIG inputs, see ::GPS_HAS_IRIG_RX + +/** @} anchor GPS_FEATURE_MASKS */ + + +/** + * @defgroup group_xfeature Extended feature definitions + * + * @note These structures and definitions are only supported by a device + * if ::GPS_HAS_XFEATURE is set in ::RECEIVER_INFO::features. + * + * @{ */ + + +/** + * @brief The maximum number of feature bits supported by the MBG_XFEATURE API. + * + * Warning: Changing this number breaks API compatibility! + * + * @see ::MBG_XFEATURE_BITS + */ +#define MAX_XFEATURE_BITS 1024 + + + +/** + * @brief Enumeration of defined extended features. + * + * @see ::MBG_XFEATURE_NAMES + * @see ::MBG_XFEATURE_BUFFER + */ +enum MBG_XFEATURE_BITS +{ + MBG_XFEATURE_TLV_API, ///< Supports generic TLV API, see @ref group_tlv_api + MBG_XFEATURE_SAVE_CFG, ///< Supports the ::GPS_SAVE_CFG command + MBG_XFEATURE_LED_API, ///< Supports programmable LED API, see @ref group_led_api + MBG_XFEATURE_LNE_API, ///< Supports specific LNE API, see @ref group_lne_api + MBG_XFEATURE_PWR_CTL_API, ///< Supports power control, see @ref group_pwr_ctl_api + MBG_XFEATURE_EXT_SYS_INFO, ///< Supports extended revision information, see @ref group_ext_sys_info + MBG_XFEATURE_TRANSACTIONS, ///< Supports the ::GPS_BEGIN_TRANSACTION and ::GPS_END_TRANSACTION commands, see also ::MBG_TRANSACTION_TYPES + MBG_XFEATURE_REBOOT, ///< Supports the ::GPS_REBOOT command + MBG_XFEATURE_CLK_RES_INFO, ///< Supports the ::GPS_CLK_RES_INFO command, see @ref group_clk_res_info + MBG_XFEATURE_UCAP_NET, ///< Supports the ::GPS_UCAP_NET_GLB_INFO and ::GPS_UCAP_NET_RECV_INFO_IDX commands, see @ref group_ucap_net + MBG_XFEATURE_REQ_TTM, ///< Supports requesting ::TTM via the ::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 + MBG_XFEATURE_PTP_NG, ///< Supports PTP next gen API, see @ref group_ptp_ng + MBG_XFEATURE_SYS_REF, ///< Supports new system reference API, see @ref group_sys_ref + MBG_XFEATURE_FCU_API, ///< Supports FCU features, see @ref group_fcu_api + N_MBG_XFEATURE ///< Number of defined extended features + // NOTE If new features are appended here then an appropriate feature + // name string has to be appended to ::MBG_XFEATURE_NAMES, and care must + // be taken that ::N_MBG_XFEATURE doesn't exceed ::MAX_XFEATURE_BITS. +}; + + + +/** + * @brief Names of extended device features + * + * Can be used to initialize a string array of ::N_MBG_XFEATURE entries, + * so the number of strings must correspond to ::N_MBG_XFEATURE. + * + * @see ::MBG_XFEATURE_BITS + */ +#define MBG_XFEATURE_NAMES \ +{ \ + "Generic TLV API", \ + "Save Config On Card", \ + "Programmable LED API", \ + "LNE API", \ + "Power Control API", \ + "Extended Revision Info", \ + "Transaction commands", \ + "Reboot Command", \ + "Clock Resolution Info", \ + "Extended User Captures", \ + "Request TTM", \ + "I/O Ports", \ + "Monitoring", \ + "XHE Unit", \ + "Tainted Config", \ + "Push Messages", \ + "User Authentication", \ + "User Management", \ + "Service Management", \ + "Antenna Converter", \ + "Firmware Management", \ + "DAC control via bus", \ + "Database", \ + "GNSS Messages", \ + "PTP Next Gen.", \ + "System Reference" \ +} + + + +/** + * @brief Array size required to store all extended features + * + * The number of bytes required to store up to ::MAX_XFEATURE_BITS + * feature bits in a byte array. + */ +#define MAX_XFEATURE_BYTES ( MAX_XFEATURE_BITS / 8 ) + + + +/** + * @brief A structure used to store extended device features. + * + * Up to ::MAX_XFEATURE_BITS totally can be stored, but only + * ::N_MBG_XFEATURE extended features are currently defined. + * The ::_set_xfeature_bit macro should be used by the firmware + * to set a feature bit in the buffer, and the ::check_xfeature + * function should be used to implement API calls which test if an + * extended feature is supported. + * + * @see ::_set_xfeature_bit + * @see ::check_xfeature + */ +typedef struct mbg_xfeature_buffer_s +{ + uint8_t b[MAX_XFEATURE_BYTES]; + +} MBG_XFEATURE_BUFFER; + + + +/** + * @brief Set an extended feature bit in a ::MBG_XFEATURE_BUFFER + * + * Should be used by the firmware only to set one of the ::MBG_XFEATURE_BITS + * in an ::MBG_XFEATURE_BUFFER after power-up. + * + * @param[in] _xf_bit One of the ::MBG_XFEATURE_BITS + * @param[in] _xf_buffp Pointer to an ::MBG_XFEATURE_BUFFER + */ +#define _set_xfeature_bit( _xf_bit, _xf_buffp ) \ + _set_array_bit( _xf_bit, (_xf_buffp)->b, MAX_XFEATURE_BYTES ) + + +/** @} defgroup group_xfeature */ + + + +/* + * The features below are supported by default by older + * C166 based GPS receivers: + */ +#define DEFAULT_GPS_FEATURES_C166 \ +{ \ + GPS_HAS_PPS | \ + GPS_HAS_PPM | \ + GPS_HAS_SYNTH | \ + GPS_HAS_DCFMARKS \ +} + + +/** + * @brief Bits used to define ::RECEIVER_INFO_FLAG_MASKS + */ +enum RECEIVER_INFO_FLAG_BITS +{ + GPS_BIT_OSC_CFG_SUPP, ///< oscillator cfg is supported, see ::RECEIVER_INFO::osc_type + GPS_BIT_IRIG_FO_IN, ///< IRIG input via fiber optics + GPS_BIT_HAS_FPGA, ///< device provides on-board FPGA + N_RECEIVER_INFO_FLAG_BITS ///< number of known bits +}; + + +/** + * @brief Bit masks to be used with ::RECEIVER_INFO::flags + */ +enum RECEIVER_INFO_FLAG_MASKS +{ + GPS_OSC_CFG_SUPP = ( 1UL << GPS_BIT_OSC_CFG_SUPP ), ///< See ::GPS_BIT_OSC_CFG_SUPP + GPS_IRIG_FO_IN = ( 1UL << GPS_BIT_IRIG_FO_IN ), ///< See ::GPS_BIT_IRIG_FO_IN + GPS_HAS_FPGA = ( 1UL << GPS_BIT_HAS_FPGA ) ///< See ::GPS_BIT_HAS_FPGA +}; + + + +/* + * If the ::GPS_HAS_FPGA flag is set in ::RECEIVER_INFO::flags then the card + * provides an FPGA and the following information about the FPGA is available: + */ +#define FPGA_NAME_LEN 31 // max name length +#define FPGA_NAME_SIZE ( FPGA_NAME_LEN + 1 ) // size including trailing 0 + +#define FPGA_INFO_SIZE 128 + +typedef union +{ + struct + { + CSUM csum; + uint32_t fsize; + uint32_t start_addr; + char name[FPGA_NAME_SIZE]; + } hdr; + + char b[FPGA_INFO_SIZE]; + +} FPGA_INFO; + + + +/* + * The definitions below are used to specify where a FPGA image is located + * in the flash memory: + */ +typedef struct +{ + CSUM csum; + uint16_t fpga_start_seg; // Number of the 4k block where an FPGA image is located + +} FPGA_START_INFO; + +#define DEFAULT_FPGA_START_SEG 0x60 + +#define DEFAULT_FPGA_START_INFO \ +{ \ + 0x1234 + DEFAULT_FPGA_START_SEG, \ + DEFAULT_FPGA_START_SEG \ +} + + + +/** + * @brief A structure used to hold time in GPS format + * + * Date and time refer to the linear time scale defined by GPS, with + * the epoch starting at %UTC midnight at the beginning of January 6, 1980. + * + * GPS time is counted by the week numbers since the epoch, plus second + * of the week, plus fraction of the second. The week number transmitted + * by the satellites rolls over from 1023 to 0, but Meinberg devices + * simply continue counting weeks beyond the 1024-week limit to maintain + * the receiver's internal time. + * + * %UTC time differs from GPS time since a number of leap seconds have + * been inserted in the %UTC time scale after the GPS epoch. The number + * of leap seconds is disseminated by the satellites using the ::UTC + * parameter set, which also provides info on pending leap seconds. + */ +typedef struct +{ + GPS_WNUM wn; ///< The week number since the GPS system has been put into operation. + GPS_WSEC sec; ///< The second of a week. + GPS_TICK tick; ///< Fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units. + +} T_GPS; + +#define _mbg_swab_t_gps( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->wn ); \ + _mbg_swab32( &(_p)->sec ); \ + _mbg_swab32( &(_p)->tick ); \ +} while ( 0 ) + + + +/** + * @brief A type of status variable to be used with ::TM_GPS, etc. + * + * @see ::TM_GPS_STATUS_BIT_MASKS + */ +typedef uint16_t TM_GPS_STATUS; + +#define _mbg_swab_tm_gps_status( _p ) _mbg_swab16( _p ) + + + + +/** + * @brief Type of an extended TM status which is mainly used inside the firmware. + * + * @see ::TM_GPS_STATUS_BIT_MASKS + * @see @ref TM_GPS_STATUS_EXT_BIT_MASKS + */ +typedef uint32_t TM_GPS_STATUS_EXT; + +#define _mbg_swab_tm_gps_status_ext( _p ) _mbg_swab32( _p ) + + +/** + * @brief An alias for ::TM_GPS_STATUS_EXT + * + * This has been used in existing source code. + */ +#define TM_STATUS_EXT TM_GPS_STATUS_EXT + + + +/** + * @brief Local date and time computed from GPS time + * + * The current number of leap seconds have to be added to get %UTC + * from GPS time. Additional corrections could have been made according + * to the time zone/daylight saving parameters ::TZDL defined by the user. + * The status field can be checked to see which corrections + * have actually been applied. + * + * @note Conversion from GPS time to %UTC and/or local time can only be + * done if some valid ::UTC correction parameters are available in the + * receiver's non-volatile memory. + */ +typedef struct +{ + int16_t year; ///< year number, 0..9999 + int8_t month; ///< month, 1..12 + int8_t mday; ///< day of month, 1..31 + int16_t yday; ///< day of year, 1..365, or 366 in case of leap year + int8_t wday; ///< day of week, 0..6 == Sun..Sat + int8_t hour; ///< hours, 0..23 + int8_t min; ///< minutes, 0..59 + int8_t sec; ///< seconds, 0..59, or 60 in case of inserted leap second + int32_t frac; ///< fractions of a second, 1/::RECEIVER_INFO::ticks_per_sec units + int32_t offs_from_utc; ///< local time offset from %UTC [sec] + TM_GPS_STATUS status; ///< status flags, see ::TM_GPS_STATUS_BIT_MASKS + +} TM_GPS; + +#define _mbg_swab_tm_gps( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->year ); \ + _mbg_swab16( &(_p)->yday ); \ + _mbg_swab32( &(_p)->frac ); \ + _mbg_swab32( &(_p)->offs_from_utc ); \ + _mbg_swab_tm_gps_status( &(_p)->status ); \ +} while ( 0 ) + + +/** + * @brief Status flag bits used to define ::TM_GPS_STATUS_BIT_MASKS + * + * These bits report info on the time conversion from GPS time to %UTC + * and/or local time as well as device status info. + * + * @see ::TM_GPS_STATUS_BIT_MASKS + */ +enum TM_GPS_STATUS_BITS +{ + TM_BIT_UTC, ///< %UTC correction has been made + TM_BIT_LOCAL, ///< %UTC has been converted to local time according to ::TZDL settings + TM_BIT_DL_ANN, ///< state of daylight saving is going to change + TM_BIT_DL_ENB, ///< daylight saving is in effect + TM_BIT_LS_ANN, ///< leap second pending + TM_BIT_LS_ENB, ///< current second is leap second + TM_BIT_LS_ANN_NEG, ///< set in addition to ::TM_BIT_LS_ANN if leap sec is negative + TM_BIT_INVT, ///< invalid time, e.g. if RTC battery bas been empty + + TM_BIT_EXT_SYNC, ///< synchronized externally + TM_BIT_HOLDOVER, ///< in holdover mode after previous synchronization + TM_BIT_ANT_SHORT, ///< antenna cable short circuited + TM_BIT_NO_WARM, ///< oscillator control loop not settled + TM_BIT_ANT_DISCONN, ///< antenna currently disconnected + TM_BIT_SYN_FLAG, ///< clock not synchronized, reflects the state of the "time sync error" output pin + TM_BIT_NO_SYNC, ///< time sync actually not verified + TM_BIT_NO_POS ///< position actually not verified, LOCK LED off +}; + + +/** + * @brief Status flag masks used with ::TM_GPS::status + * + * These bits report info on the time conversion from GPS time to %UTC + * and/or local time as well as device status info. + * + * @see ::TM_GPS_STATUS_BITS + */ +enum TM_GPS_STATUS_BIT_MASKS +{ + TM_UTC = ( 1UL << TM_BIT_UTC ), ///< See ::TM_BIT_UTC + TM_LOCAL = ( 1UL << TM_BIT_LOCAL ), ///< See ::TM_BIT_LOCAL + TM_DL_ANN = ( 1UL << TM_BIT_DL_ANN ), ///< See ::TM_BIT_DL_ANN + TM_DL_ENB = ( 1UL << TM_BIT_DL_ENB ), ///< See ::TM_BIT_DL_ENB + TM_LS_ANN = ( 1UL << TM_BIT_LS_ANN ), ///< See ::TM_BIT_LS_ANN + TM_LS_ENB = ( 1UL << TM_BIT_LS_ENB ), ///< See ::TM_BIT_LS_ENB + TM_LS_ANN_NEG = ( 1UL << TM_BIT_LS_ANN_NEG ), ///< See ::TM_BIT_LS_ANN_NEG + TM_INVT = ( 1UL << TM_BIT_INVT ), ///< See ::TM_BIT_INVT + + TM_EXT_SYNC = ( 1UL << TM_BIT_EXT_SYNC ), ///< See ::TM_BIT_EXT_SYNC + TM_HOLDOVER = ( 1UL << TM_BIT_HOLDOVER ), ///< See ::TM_BIT_HOLDOVER + TM_ANT_SHORT = ( 1UL << TM_BIT_ANT_SHORT ), ///< See ::TM_BIT_ANT_SHORT + TM_NO_WARM = ( 1UL << TM_BIT_NO_WARM ), ///< See ::TM_BIT_NO_WARM + TM_ANT_DISCONN = ( 1UL << TM_BIT_ANT_DISCONN ), ///< See ::TM_BIT_ANT_DISCONN + TM_SYN_FLAG = ( 1UL << TM_BIT_SYN_FLAG ), ///< See ::TM_BIT_SYN_FLAG + TM_NO_SYNC = ( 1UL << TM_BIT_NO_SYNC ), ///< See ::TM_BIT_NO_SYNC + TM_NO_POS = ( 1UL << TM_BIT_NO_POS ) ///< See ::TM_BIT_NO_POS +}; + + + +/** + * @brief Extended status flag bits used to define @ref TM_GPS_STATUS_EXT_BIT_MASKS + * + * @note The lower 16 bits correspond to ::TM_GPS_STATUS_BITS + * + * @see ::TM_GPS_STATUS_BITS + * @see @ref TM_GPS_STATUS_EXT_BIT_MASKS + */ +enum TM_GPS_STATUS_EXT_BITS +{ + TM_BIT_SCALE_GPS = 16, ///< time scale configured to return GPS time + TM_BIT_SCALE_TAI ///< time scale configured to return TAI + // The remaining bits are reserved. +}; + + +/** + * @brief Bit masks to be only used with ::TM_GPS_STATUS_EXT. + * + * @note The lower 16 bits correspond to ::TM_GPS_STATUS_BIT_MASKS + * + * @see ::TM_GPS_STATUS_EXT + * @see ::TM_GPS_STATUS_BIT_MASKS + * @see ::TM_GPS_STATUS_EXT_BITS + * + * @anchor TM_GPS_STATUS_EXT_BIT_MASKS @{ */ + +#define TM_SCALE_GPS ( 1UL << TM_BIT_SCALE_GPS ) ///< See ::TM_BIT_SCALE_GPS +#define TM_SCALE_TAI ( 1UL << TM_BIT_SCALE_TAI ) ///< See ::TM_BIT_SCALE_TAI + +/** @} anchor TM_GPS_STATUS_EXT_BIT_MASKS */ + + +#define ANN_LIMIT ( - ( SECS_PER_HOUR - SECS_PER_MIN ) ) +#define ANN_LIMIT_DCF ( - ( SECS_PER_HOUR + SECS_PER_MIN ) ) + + +#define TM_MSK_TIME_VALID ( TM_UTC | TM_SCALE_GPS | TM_SCALE_TAI ) + + + +/** + * @brief A structure used to transmit information on date and time + * + * This structure can be used to transfer the current time, in which + * case the channel field has to be set to -1, or an event capture time + * retrieved from the on-board FIFO, in which case the channel field + * contains the index of the time capture input, e.g. 0 or 1. + */ +typedef struct +{ + int16_t channel; ///< -1: the current on-board time; >= 0 the capture channel number + T_GPS t; ///< time in GPS scale and format + TM_GPS tm; ///< time converted to %UTC and/or local time according to ::TZDL settings + +} TTM; + +#define _mbg_swab_ttm( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->channel ); \ + _mbg_swab_t_gps( &(_p)->t ); \ + _mbg_swab_tm_gps( &(_p)->tm ); \ +} while ( 0 ) + + + +#ifndef _XYZ_DEFINED + /** + * @brief Sequence and number of components of a cartesian position + */ + enum XYZ_FIELDS { XP, YP, ZP, N_XYZ }; // x, y, z + + /** + * @brief A position in cartesian coordinates + * + * Usually earth centered, earth fixed (ECEF) coordinates. + */ + typedef double XYZ[N_XYZ]; ///< values are in [m], see ::XYZ_FIELDS + + #define _XYZ_DEFINED +#endif + +#define _mbg_swab_xyz( _p ) _mbg_swab_doubles( _p, N_XYZ ) + + +#ifndef _LLA_DEFINED + /** + * @brief Sequence and number of components of a geographic position + */ + enum LLA_FIELDS { LAT, LON, ALT, N_LLA }; /* latitude, longitude, altitude */ + + /** + * @brief A geographic position based on latitude, longitude, and altitude + * + * The geographic position associated to specific cartesian coordinates + * depends on the characteristics of the ellipsoid used for the computation, + * the so-called geographic datum. GPS uses the WGS84 (World Geodetic System + * from 1984) ellipsoid by default. + */ + typedef double LLA[N_LLA]; ///< lon, lat in [rad], alt in [m], see ::LLA_FIELDS + + #define _LLA_DEFINED +#endif + +#define _mbg_swab_lla( _p ) _mbg_swab_doubles( _p, N_LLA ) + + +/** + * @defgroup group_synth Synthesizer parameters + * + * Synthesizer frequency is expressed as a + * four digit decimal number (freq) to be multiplied by 0.1 Hz and an + * base 10 exponent (range). If the effective frequency is less than + * 10 kHz its phase is synchronized corresponding to the variable phase. + * Phase may be in a range from -360 deg to +360 deg with a resolution + * of 0.1 deg, so the resulting numbers to be stored are in a range of + * -3600 to +3600. + * + * Example:<br> + * Assume the value of freq is 2345 (decimal) and the value of phase is 900. + * If range == 0 the effective frequency is 234.5 Hz with a phase of +90 deg. + * If range == 1 the synthesizer will generate a 2345 Hz output frequency + * and so on. + * + * Limitations:<br> + * If freq == 0 the synthesizer is disabled. If range == 0 the least + * significant digit of freq is limited to 0, 3, 5 or 6. The resulting + * frequency is shown in the examples below: + * - freq == 1230 --> 123.0 Hz + * - freq == 1233 --> 123 1/3 Hz (real 1/3 Hz, NOT 123.3 Hz) + * - freq == 1235 --> 123.5 Hz + * - freq == 1236 --> 123 2/3 Hz (real 2/3 Hz, NOT 123.6 Hz) + * + * If range == ::MAX_SYNTH_RANGE the value of freq must not exceed 1000, so + * the output frequency is limited to 10 MHz (see ::MAX_SYNTH_FREQ_VAL). + * + * @{ */ + +#define N_SYNTH_FREQ_DIGIT 4 ///< number of digits to edit +#define MAX_SYNTH_FREQ 1000 ///< if range == ::MAX_SYNTH_RANGE + +#define MIN_SYNTH_RANGE 0 +#define MAX_SYNTH_RANGE 5 +#define N_SYNTH_RANGE ( MAX_SYNTH_RANGE - MIN_SYNTH_RANGE + 1 ) + +#define N_SYNTH_PHASE_DIGIT 4 +#define MAX_SYNTH_PHASE 3600 + + +#define MAX_SYNTH_FREQ_EDIT 9999 ///< max sequence of digits when editing + + +/** + * @brief The maximum frequency that can be configured for the synthesizer + */ +#define MAX_SYNTH_FREQ_VAL 10000000UL ///< 10 MHz +/* == MAX_SYNTH_FREQ * 10^(MAX_SYNTH_RANGE-1) */ + +/** + * @brief The phase of the synthesizer is only synchronized when the frequency is below this limit. + */ +#define SYNTH_PHASE_SYNC_LIMIT 10000UL ///< 10 kHz + +/** + * A Macro used to determine the position of the decimal point + * when printing the synthesizer frequency as 4 digit value + */ +#define _synth_dp_pos_from_range( _r ) \ + ( ( ( N_SYNTH_RANGE - (_r) ) % ( N_SYNTH_FREQ_DIGIT - 1 ) ) + 1 ) + +/** + * @brief Synthesizer frequency units + * + * An initializer for commonly displayed synthesizer frequency units + * (::N_SYNTH_RANGE strings) + */ +#define DEFAULT_FREQ_RANGES \ +{ \ + "Hz", \ + "kHz", \ + "kHz", \ + "kHz", \ + "MHz", \ + "MHz", \ +} + + + +/** + * @brief Synthesizer configuration parameters + */ +typedef struct +{ + int16_t freq; ///< four digits used; scale: 0.1 Hz; e.g. 1234 -> 123.4 Hz + int16_t range; ///< scale factor for freq; 0..::MAX_SYNTH_RANGE + int16_t phase; ///< -::MAX_SYNTH_PHASE..+::MAX_SYNTH_PHASE; >0 -> pulses later + +} SYNTH; + +#define _mbg_swab_synth( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->freq ); \ + _mbg_swab16( &(_p)->range ); \ + _mbg_swab16( &(_p)->phase ); \ +} while ( 0 ) + + +/** + * @brief Enumeration of synthesizer states + */ +enum SYNTH_STATES +{ + SYNTH_DISABLED, ///< disbled by cfg, i.e. freq == 0.0 + SYNTH_OFF, ///< not enabled after power-up + SYNTH_FREE, ///< enabled, but not synchronized + SYNTH_DRIFTING, ///< has initially been sync'd, but now running free + SYNTH_SYNC, ///< fully synchronized + N_SYNTH_STATE ///< the number of known states +}; + + +/** + * @brief A structure used to report the synthesizer state + */ +typedef struct +{ + uint8_t state; ///< state code as enumerated in ::SYNTH_STATES + uint8_t flags; ///< reserved, currently always 0 + +} SYNTH_STATE; + +#define _mbg_swab_synth_state( _p ) _nop_macro_fnc() + +#define SYNTH_FLAG_PHASE_IGNORED 0x01 + +/** @} defgroup group_synth */ + + + +/** + * @defgroup group_tzdl Time zone / daylight saving parameters + * + * Example: <br> + * For automatic daylight saving enable/disable in Central Europe, + * the variables are to be set as shown below: <br> + * - offs = 3600L one hour from %UTC + * - offs_dl = 3600L one additional hour if daylight saving enabled + * - tm_on = first Sunday from March 25, 02:00:00h ( year |= ::DL_AUTO_FLAG ) + * - tm_off = first Sunday from October 25, 03:00:00h ( year |= ::DL_AUTO_FLAG ) + * - name[0] == "CET " name if daylight saving not enabled + * - name[1] == "CEST " name if daylight saving is enabled + * + * @{ */ + +/** + * @brief The name of a time zone + * + * @note Up to 5 printable characters, plus trailing zero + */ +typedef char TZ_NAME[6]; + +/** + * @brief Time zone / daylight saving parameters + * + * This structure is used to specify how a device converts on-board %UTC + * to local time, including computation of beginning and end of daylight + * saving time (DST), if required. + * + * @note The ::TZDL structure contains members of type ::TM_GPS to specify + * the times for beginning and end of DST. However, the ::TM_GPS::frac, + * ::TM_GPS::offs_from_utc, and ::TM_GPS::status fields of these ::TZDL::tm_on + * and ::TZDL::tm_off members are ignored for the conversion to local time, + * and thus should be 0. + */ +typedef struct +{ + int32_t offs; ///< standard offset from %UTC to local time [sec] + int32_t offs_dl; ///< additional offset if daylight saving enabled [sec] + TM_GPS tm_on; ///< date/time when daylight saving starts + TM_GPS tm_off; ///< date/time when daylight saving ends + TZ_NAME name[2]; ///< names without and with daylight saving enabled + +} TZDL; + +#define _mbg_swab_tzdl( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->offs ); \ + _mbg_swab32( &(_p)->offs_dl ); \ + _mbg_swab_tm_gps( &(_p)->tm_on ); \ + _mbg_swab_tm_gps( &(_p)->tm_off ); \ +} while ( 0 ) + + +/** + * @brief A flag indicating automatic computation of DST + * + * If this flag is or'ed to the year numbers in ::TZDL::tm_on and ::TZDL::tm_off + * then daylight saving is computed automatically year by year. + */ +#define DL_AUTO_FLAG 0x8000 + + + +// Below there are some initializers for commonly used TZDL configurations: + +#define DEFAULT_TZDL_AUTO_YEAR ( (int16_t) ( 2007L | DL_AUTO_FLAG ) ) + +#define DEFAULt_TZDL_OFFS_DL 3600L ///< usually DST is +1 hour + + +/** + * An initializer for ::TZDL::tm_on and ::TZDL::tm_off for time zones + * which do not observe DST. + */ +#define DEFAULT_TZDL_TM_ON_OFF_NO_DST \ + { DEFAULT_TZDL_AUTO_YEAR, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 } + + +// Settings used with %UTC: + +#define TZ_INFO_UTC "UTC (Universal Time, Coordinated)" + +#define DEFAULT_TZDL_NAMES_UTC { "UTC ", "UTC " } + +#define DEFAULT_TZDL_UTC \ +{ \ + 0L, /* offs */ \ + 0L, /* offs_dl */ \ + DEFAULT_TZDL_TM_ON_OFF_NO_DST, /* tm_on */ \ + DEFAULT_TZDL_TM_ON_OFF_NO_DST, /* tm_off */ \ + DEFAULT_TZDL_NAMES_UTC /* name */ \ +} + + +/** + * @brief An initializer for ::TZDL::tm_on according to the rules for Central Europe + */ +#define DEFAULT_TZDL_TM_ON_CET_CEST \ + { DEFAULT_TZDL_AUTO_YEAR, 3, 25, 0, 0, 2, 0, 0, 0L, 0L, 0 } + +/** + * @brief An initializer for ::TZDL::tm_off according to the rules for Central Europe + */ +#define DEFAULT_TZDL_TM_OFF_CET_CEST \ + { DEFAULT_TZDL_AUTO_YEAR, 10, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 } + + +// Settings used with Central European Time: + +#define TZ_INFO_CET_CEST_EN "CET/CEST (Central Europe)" +#define TZ_INFO_CET_CEST_DE "MEZ/MESZ (Mitteleuropa)" + +#define DEFAULT_TZDL_NAMES_CET_CEST_EN { "CET ", "CEST " } +#define DEFAULT_TZDL_NAMES_CET_CEST_DE { "MEZ ", "MESZ " } + +#define DEFAULT_TZDL_OFFS_CET 3600L + +#define DEFAULT_TZDL_CET_CEST_EN \ +{ \ + DEFAULT_TZDL_OFFS_CET, /* offs */ \ + DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \ + DEFAULT_TZDL_TM_ON_CET_CEST, /* tm_on */ \ + DEFAULT_TZDL_TM_OFF_CET_CEST, /* tm_off */ \ + DEFAULT_TZDL_NAMES_CET_CEST_EN /* name */ \ +} + +#define DEFAULT_TZDL_CET_CEST_DE \ +{ \ + DEFAULT_TZDL_OFFS_CET, /* offs */ \ + DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \ + DEFAULT_TZDL_TM_ON_CET_CEST, /* tm_on */ \ + DEFAULT_TZDL_TM_OFF_CET_CEST, /* tm_off */ \ + DEFAULT_TZDL_NAMES_CET_CEST_DE /* name */ \ +} + + +// The symbols below specify beginning and end of DST for +// Easter Europe, as constituted by the European Parliament: + +#define DEFAULT_TZDL_TM_ON_EET_EEST \ + { DEFAULT_TZDL_AUTO_YEAR, 3, 25, 0, 0, 3, 0, 0, 0L, 0L, 0 } + +#define DEFAULT_TZDL_TM_OFF_EET_EEST \ + { DEFAULT_TZDL_AUTO_YEAR, 10, 25, 0, 0, 4, 0, 0, 0L, 0L, 0 } + + +// Settings used with Eastern European Time: + +#define TZ_INFO_EET_EEST_EN "EET/EEST (East Europe)" +#define TZ_INFO_EET_EEST_DE "OEZ/OEST (Osteuropa)" + +#define DEFAULT_TZDL_NAMES_EET_EEST_EN { "EET ", "EEST " } +#define DEFAULT_TZDL_NAMES_EET_EEST_DE { "OEZ ", "OESZ " } + +#define DEFAULT_TZDL_OFFS_EET 7200L + +#define DEFAULT_TZDL_EET_EEST_EN \ +{ \ + DEFAULT_TZDL_OFFS_EET, /* offs */ \ + DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \ + DEFAULT_TZDL_TM_ON_EET_EEST, /* tm_on */ \ + DEFAULT_TZDL_TM_OFF_EET_EEST, /* tm_off */ \ + DEFAULT_TZDL_NAMES_EET_EEST_EN /* name */ \ +} + +#define DEFAULT_TZDL_EET_EEST_DE \ +{ \ + DEFAULT_TZDL_OFFS_EET, /* offs */ \ + DEFAULt_TZDL_OFFS_DL, /* offs_dl */ \ + DEFAULT_TZDL_TM_ON_EET_EEST, /* tm_on */ \ + DEFAULT_TZDL_TM_OFF_EET_EEST, /* tm_off */ \ + DEFAULT_TZDL_NAMES_EET_EEST_DE /* name */ \ +} + +/** @} defgroup group_tzdl */ + + + +/** + * @brief Antenna status and error at reconnect information + * + * The structure below reflects the status of the antenna, + * the times of last disconnect/reconnect, and the board's + * clock offset when it has synchronized again after the + * disconnection interval. + * + * @note ::ANT_INFO::status changes back to ::ANT_RECONN only + * after the antenna has been reconnected <b>and</b> the + * receiver has re-synchronized to the satellite signal. + * In this case ::ANT_INFO::delta_t reports the time offset + * before resynchronization, i.e. how much the internal + * time has drifted while the antenna was disconnected. + */ +typedef struct +{ + int16_t status; ///< current status of antenna, see ::ANT_STATUS_CODES + TM_GPS tm_disconn; ///< time of antenna disconnect + TM_GPS tm_reconn; ///< time of antenna reconnect + int32_t delta_t; ///< clock offs at reconn. time in 1/::RECEIVER_INFO::ticks_per_sec units + +} ANT_INFO; + +#define _mbg_swab_ant_info( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->status ); \ + _mbg_swab_tm_gps( &(_p)->tm_disconn ); \ + _mbg_swab_tm_gps( &(_p)->tm_reconn ); \ + _mbg_swab32( &(_p)->delta_t ); \ +} while ( 0 ) + + +/** + * @brief Status code used with ::ANT_INFO::status + */ +enum ANT_STATUS_CODES +{ + ANT_INVALID, ///< No other fields valid since antenna has not yet been disconnected + ANT_DISCONN, ///< Antenna is disconnected, tm_reconn and delta_t not yet set + ANT_RECONN, ///< Antenna has been disconnect, and receiver sync. after reconnect, so all fields valid + N_ANT_STATUS_CODES ///< the number of known status codes +}; + + + +/** + * @brief A structure controlling when output signals are enabled + * + * The structure holds some flags which let the corresponding outputs + * be disabled after power-up until the receiver has synchronized + * (flags == ::EF_OFF, the default) or force the outputs to be enabled + * immediately after power-up. The fixed frequency output is hard-wired + * to be enabled immediately after power-up, so ::ENABLE_FLAGS::freq must + * always be set to ::EF_FREQ_ALL. + */ +typedef struct +{ + uint16_t serial; ///< ::EF_OFF or ::EF_SERIAL_BOTH + uint16_t pulses; ///< ::EF_OFF or ::EF_PULSES_BOTH + uint16_t freq; ///< always ::EF_FREQ_ALL + uint16_t synth; ///< ::EF_OFF or ::EF_SYNTH + +} ENABLE_FLAGS; + +#define _mbg_swab_enable_flags( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->serial ); \ + _mbg_swab16( &(_p)->pulses ); \ + _mbg_swab16( &(_p)->freq ); \ + _mbg_swab16( &(_p)->synth ); \ +} while ( 0 ) + + +/** + * @brief Codes used with ::ENABLE_FLAGS + **/ +enum ENABLE_FLAGS_CODES +{ + EF_OFF = 0x00, ///< associated outputs off until synchronized + + EF_SERIAL_BOTH = 0x03, ///< both serial ports on, use with ::ENABLE_FLAGS::serial + EF_PULSES_BOTH = 0x03, ///< both pulses P_SEC and P_MIN on, use with ::ENABLE_FLAGS::pulses + EF_FREQ_ALL = 0x07, ///< all fixed freq. outputs on, use with ::ENABLE_FLAGS::freq + EF_SYNTH = 0x01 ///< synthesizer on, use with ::ENABLE_FLAGS::synth +}; + + + +#ifndef _COM_HS_DEFINED + /** + * @brief Enumeration of handshake modes. + */ + enum COM_HANSHAKE_MODES { HS_NONE, HS_XONXOFF, HS_RTSCTS, N_COM_HS }; + #define _COM_HS_DEFINED +#endif + +#ifndef _COM_PARM_DEFINED + /** + * @brief A data type to configure the baud rate of a serial port. + * + * @see ::MBG_BAUD_RATES + */ + typedef int32_t BAUD_RATE; + + /** + * @brief Indices used to identify a parameter in the framing string. + * + * @see ::MBG_FRAMING_STRS + */ + enum MBG_FRAMING_STR_IDXS { F_DBITS, F_PRTY, F_STBITS }; + + /** + * @brief A structure to store the configuration of a serial port. + */ + typedef struct + { + BAUD_RATE baud_rate; ///< Transmission speed, e.g. 19200L, see ::MBG_BAUD_RATES. + char framing[4]; ///< ASCIIZ framing string, e.g. "8N1" or "7E2", see ::MBG_FRAMING_STRS. + int16_t handshake; ///< Handshake mode, yet only ::HS_NONE supported. + + } COM_PARM; + + #define _COM_PARM_DEFINED +#endif + +#define _mbg_swab_baud_rate( _p ) _mbg_swab32( _p ) + +#define _mbg_swab_com_parm( _p ) \ +do \ +{ \ + _mbg_swab_baud_rate( &(_p)->baud_rate ); \ + _mbg_swab16( &(_p)->handshake ); \ +} while ( 0 ) + + +/** + * @brief Enumeration of serial port baud rates + * + * @note Most clock models and/or serial ports don't support all defined baud rates. + * + * @see ::MBG_BAUD_RATES + * @see ::MBG_BAUD_RATE_MASKS + */ +enum MBG_BAUD_RATE_CODES +{ + MBG_BAUD_RATE_300, + MBG_BAUD_RATE_600, + MBG_BAUD_RATE_1200, + MBG_BAUD_RATE_2400, + MBG_BAUD_RATE_4800, + MBG_BAUD_RATE_9600, + MBG_BAUD_RATE_19200, + MBG_BAUD_RATE_38400, + MBG_BAUD_RATE_57600, + MBG_BAUD_RATE_115200, + MBG_BAUD_RATE_230400, + MBG_BAUD_RATE_460800, + MBG_BAUD_RATE_921600, + N_MBG_BAUD_RATES ///< the number of known baud rates +}; + +/** + * @brief An initializer for a table of baud rate values + * + * These values can be used with ::COM_PARM::baud_rate, if the device + * supports the particular baud rate. + * + * The values must correspond to the enumeration ::MBG_BAUD_RATE_CODES + * + * @see ::MBG_BAUD_RATE_CODES + */ +#define MBG_BAUD_RATES \ +{ \ + 300L, \ + 600L, \ + 1200L, \ + 2400L, \ + 4800L, \ + 9600L, \ + 19200L, \ + 38400L, \ + 57600L, \ + 115200L, \ + 230400L, \ + 460800L, \ + 921600L \ +} + +/** + * @brief An initializer for a table of baud rate strings + * + * The values must correspond to the enumeration ::MBG_BAUD_RATE_CODES + * + * @see ::MBG_BAUD_RATE_CODES + */ +#define MBG_BAUD_STRS \ +{ \ + "300", \ + "600", \ + "1200", \ + "2400", \ + "4800", \ + "9600", \ + "19200", \ + "38400", \ + "57600", \ + "115200", \ + "230400", \ + "460800", \ + "921600" \ +} + +/** + * @brief Bit masks associated with baud rates enumerated in ::MBG_BAUD_RATE_CODES + * + * These bit masks are used e.g. with ::PORT_INFO::supp_baud_rates to + * determine which baud rates are supported by a particular serial port. + * + * @see ::MBG_BAUD_RATE_CODES + * @see ::MBG_FRAMING_MASKS + */ +enum MBG_BAUD_RATE_MASKS +{ + MBG_PORT_HAS_300 = ( 1UL << MBG_BAUD_RATE_300 ), ///< See ::MBG_BAUD_RATE_300 + MBG_PORT_HAS_600 = ( 1UL << MBG_BAUD_RATE_600 ), ///< See ::MBG_BAUD_RATE_600 + MBG_PORT_HAS_1200 = ( 1UL << MBG_BAUD_RATE_1200 ), ///< See ::MBG_BAUD_RATE_1200 + MBG_PORT_HAS_2400 = ( 1UL << MBG_BAUD_RATE_2400 ), ///< See ::MBG_BAUD_RATE_2400 + MBG_PORT_HAS_4800 = ( 1UL << MBG_BAUD_RATE_4800 ), ///< See ::MBG_BAUD_RATE_4800 + MBG_PORT_HAS_9600 = ( 1UL << MBG_BAUD_RATE_9600 ), ///< See ::MBG_BAUD_RATE_9600 + MBG_PORT_HAS_19200 = ( 1UL << MBG_BAUD_RATE_19200 ), ///< See ::MBG_BAUD_RATE_19200 + MBG_PORT_HAS_38400 = ( 1UL << MBG_BAUD_RATE_38400 ), ///< See ::MBG_BAUD_RATE_38400 + MBG_PORT_HAS_57600 = ( 1UL << MBG_BAUD_RATE_57600 ), ///< See ::MBG_BAUD_RATE_57600 + MBG_PORT_HAS_115200 = ( 1UL << MBG_BAUD_RATE_115200 ), ///< See ::MBG_BAUD_RATE_115200 + MBG_PORT_HAS_230400 = ( 1UL << MBG_BAUD_RATE_230400 ), ///< See ::MBG_BAUD_RATE_230400 + MBG_PORT_HAS_460800 = ( 1UL << MBG_BAUD_RATE_460800 ), ///< See ::MBG_BAUD_RATE_460800 + MBG_PORT_HAS_921600 = ( 1UL << MBG_BAUD_RATE_921600 ) ///< See ::MBG_BAUD_RATE_921600 +}; + + +/** + * @brief Enumeration of all known serial port framings + * + * @note Most clock models and/or serial ports don't support all defined framing types. + * + * @see ::MBG_FRAMING_STRS + */ +enum MBG_FRAMING_CODES +{ + MBG_FRAMING_7N2, + MBG_FRAMING_7E1, + MBG_FRAMING_7E2, + MBG_FRAMING_8N1, + MBG_FRAMING_8N2, + MBG_FRAMING_8E1, + MBG_FRAMING_7O1, + MBG_FRAMING_7O2, + MBG_FRAMING_8O1, + MBG_FRAMING_8E2, ///< Note: most serial ports don't support this! + N_MBG_FRAMINGS ///< the number of known framings +}; + +/** + * @brief An initializer for a table of known framing strings + * + * These values can be used with ::COM_PARM::framing, if the device + * supports the particular framing. + * + * The values must correspond to the enumeration ::MBG_FRAMING_CODES + * + * @see ::MBG_FRAMING_CODES + * @see ::MBG_FRAMING_MASKS + * @see ::MBG_FRAMING_STR_IDXS + */ +#define MBG_FRAMING_STRS \ +{ \ + "7N2", \ + "7E1", \ + "7E2", \ + "8N1", \ + "8N2", \ + "8E1", \ + "7O1", \ + "7O2", \ + "8O1", \ + "8E2" \ +} + +/** + * @brief Bit masks associated with framings enumerated in ::MBG_FRAMING_CODES + * + * These bit masks are used e.g. with ::PORT_INFO::supp_framings to + * determine which framings are supported by a particular serial port. + * + * @see ::MBG_FRAMING_CODES + * @see ::MBG_FRAMING_STRS + */ +enum MBG_FRAMING_MASKS +{ + MBG_PORT_HAS_7N2 = ( 1UL << MBG_FRAMING_7N2 ), ///< See ::MBG_FRAMING_7N2 + MBG_PORT_HAS_7E1 = ( 1UL << MBG_FRAMING_7E1 ), ///< See ::MBG_FRAMING_7E1 + MBG_PORT_HAS_7E2 = ( 1UL << MBG_FRAMING_7E2 ), ///< See ::MBG_FRAMING_7E2 + MBG_PORT_HAS_8N1 = ( 1UL << MBG_FRAMING_8N1 ), ///< See ::MBG_FRAMING_8N1 + MBG_PORT_HAS_8N2 = ( 1UL << MBG_FRAMING_8N2 ), ///< See ::MBG_FRAMING_8N2 + MBG_PORT_HAS_8E1 = ( 1UL << MBG_FRAMING_8E1 ), ///< See ::MBG_FRAMING_8E1 + MBG_PORT_HAS_7O1 = ( 1UL << MBG_FRAMING_7O1 ), ///< See ::MBG_FRAMING_7O1 + MBG_PORT_HAS_7O2 = ( 1UL << MBG_FRAMING_7O2 ), ///< See ::MBG_FRAMING_7O2 + MBG_PORT_HAS_8O1 = ( 1UL << MBG_FRAMING_8O1 ), ///< See ::MBG_FRAMING_8O1 + MBG_PORT_HAS_8E2 = ( 1UL << MBG_FRAMING_8E2 ) ///< See ::MBG_FRAMING_8E2 +}; + + + +/** + * @brief Definitions used with the Meinberg binary protocol + * + * @anchor GPS_BIN_PROT_DEFS @{ */ + +/** + * @brief Framing used with the binary protocol + * + * Different data length, or parity settings would corrupt + * the binary data. + */ +#define MBG_DEFAULT_FRAMING "8N1" + +/** + * @brief The standard baud rate used for the binary protocol + * + * This is supported by most devices. Some new devices may also + * support ::MBG_DEFAULT_BAUDRATE_HS + */ +#define MBG_DEFAULT_BAUDRATE 19200L + +/** + * @brief The high speed baud rate used for the binary protocol + * + * This is not supported by older devices which work + * with ::MBG_DEFAULT_BAUDRATE only. + */ +#define MBG_DEFAULT_BAUDRATE_HS 115200L + + +/** + * @brief Strings used to force connection settings for the binary protocol + * + * If a device supports this and receives one of these ASCII strings + * then it temporarily switches the serial port to some well-known + * baud rate and framing appropriate for the binary protocol. + * + * @anchor GPS_BIN_PROT_CMD_STRS @{ */ + +#define MBG_FORCE_CONN_CMD_STR "\nDFC\n" ///< switch to ::MBG_DEFAULT_BAUDRATE +#define MBG_FORCE_CONN_HS_CMD_STR "\nDFCHS\n" ///< switch to ::MBG_DEFAULT_BAUDRATE_HS + +/** @} anchor GPS_BIN_PROT_CMD_STRS */ + +/** @} anchor GPS_BIN_PROT_DEFS */ + + + +/* + * By default, the baud rates and framings below + * are supported by the UARTs integrated into + * the C166 microcontroller: + */ +#define DEFAULT_GPS_BAUD_RATES_C166 \ +( \ + MBG_PORT_HAS_300 | \ + MBG_PORT_HAS_600 | \ + MBG_PORT_HAS_1200 | \ + MBG_PORT_HAS_2400 | \ + MBG_PORT_HAS_4800 | \ + MBG_PORT_HAS_9600 | \ + MBG_PORT_HAS_19200 \ +) + +#define DEFAULT_GPS_FRAMINGS_C166 \ +( \ + MBG_PORT_HAS_7N2 | \ + MBG_PORT_HAS_7E1 | \ + MBG_PORT_HAS_7E2 | \ + MBG_PORT_HAS_8N1 | \ + MBG_PORT_HAS_8N2 | \ + MBG_PORT_HAS_8E1 \ +) + + +/* + * By default, the baud rates and framings below + * are supported by the UARTs integrated into + * the GP2021 chipset: + */ +#define DEFAULT_GPS_BAUD_RATES_GP2021 \ +( \ + MBG_PORT_HAS_300 | \ + MBG_PORT_HAS_600 | \ + MBG_PORT_HAS_1200 | \ + MBG_PORT_HAS_2400 | \ + MBG_PORT_HAS_4800 | \ + MBG_PORT_HAS_9600 | \ + MBG_PORT_HAS_19200 \ +) + +#define DEFAULT_GPS_FRAMINGS_GP2021 \ +( \ + MBG_PORT_HAS_7N2 | \ + MBG_PORT_HAS_7E2 | \ + MBG_PORT_HAS_8N1 | \ + MBG_PORT_HAS_8E1 | \ + MBG_PORT_HAS_8O1 \ +) + + +/** + * @brief Configuration settings of a serial port + * + * @note This should be used preferably instead of + * ::PORT_PARM, which is deprecated. + */ +typedef struct +{ + COM_PARM parm; ///< transmission speed, framing, etc. + uint8_t mode; ///< string mode, see ::STR_MODES + uint8_t str_type; ///< index of the supported time string formats, see ::STR_TYPE_INFO_IDX + uint32_t flags; ///< reserved, don't use, currently 0 + +} PORT_SETTINGS; + +#define _mbg_swab_port_settings( _p ) \ +do \ +{ \ + _mbg_swab_com_parm( &(_p)->parm ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + +/** + * @brief Flag bits used to mark individual ::PORT_SETTINGS fields + * + * These definitions can be used to mark specific fields of a + * ::PORT_SETTINGS structure, e.g. which fields have changed when + * editing, or which fields have settings which are not valid. + */ +enum MBG_COM_CFG_STATUS_BITS +{ + MBG_PS_BIT_BAUD_RATE_OVR_SW, ///< Baud rate index exceeds num supp by driver SW + MBG_PS_BIT_BAUD_RATE_OVR_DEV, ///< Baud rate index exceeds num supp by device + MBG_PS_BIT_BAUD_RATE, ///< Baud rate not supp by given port + MBG_PS_BIT_FRAMING_OVR_SW, ///< Framing index exceeds num supp by driver SW + MBG_PS_BIT_FRAMING_OVR_DEV, ///< Framing index exceeds num supp by device + MBG_PS_BIT_FRAMING, ///< Framing not supp by given port + MBG_PS_BIT_HS_OVR_SW, ///< Handshake index exceeds num supp by driver SW + MBG_PS_BIT_HS, ///< Handshake mode not supp by given port + MBG_PS_BIT_STR_TYPE_OVR_SW, ///< String type index exceeds num supp by driver SW + MBG_PS_BIT_STR_TYPE_OVR_DEV, ///< String type index exceeds num supp by device + MBG_PS_BIT_STR_TYPE, ///< String type not supp by given port + MBG_PS_BIT_STR_MODE_OVR_SW, ///< String mode index exceeds num supp by driver SW + MBG_PS_BIT_STR_MODE_OVR_DEV, ///< String mode index exceeds num supp by device + MBG_PS_BIT_STR_MODE, ///< String mode not supp by given port and string type + MBG_PS_BIT_FLAGS_OVR_SW, ///< Flags not supp by driver SW + MBG_PS_BIT_FLAGS, ///< Flags not supp by device + N_MBG_PS_BIT +}; + +/** + * @brief Flag bit masks associated with ::MBG_COM_CFG_STATUS_BITS + * + * These definitions can be used to mark specific fields of a + * ::PORT_SETTINGS structure, e.g. which fields have changed when + * editing, or which fields have settings which are not valid. + * + * @anchor MBG_COM_CFG_STATUS_MASKS @{ */ + +#define MBG_PS_MSK_BAUD_RATE_OVR_SW ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_SW ) ///< See ::MBG_PS_BIT_BAUD_RATE_OVR_SW +#define MBG_PS_MSK_BAUD_RATE_OVR_DEV ( 1UL << MBG_PS_BIT_BAUD_RATE_OVR_DEV ) ///< See ::MBG_PS_BIT_BAUD_RATE_OVR_DEV +#define MBG_PS_MSK_BAUD_RATE ( 1UL << MBG_PS_BIT_BAUD_RATE ) ///< See ::MBG_PS_BIT_BAUD_RATE +#define MBG_PS_MSK_FRAMING_OVR_SW ( 1UL << MBG_PS_BIT_FRAMING_OVR_SW ) ///< See ::MBG_PS_BIT_FRAMING_OVR_SW +#define MBG_PS_MSK_FRAMING_OVR_DEV ( 1UL << MBG_PS_BIT_FRAMING_OVR_DEV ) ///< See ::MBG_PS_BIT_FRAMING_OVR_DEV +#define MBG_PS_MSK_FRAMING ( 1UL << MBG_PS_BIT_FRAMING ) ///< See ::MBG_PS_BIT_FRAMING +#define MBG_PS_MSK_HS_OVR_SW ( 1UL << MBG_PS_BIT_HS_OVR_SW ) ///< See ::MBG_PS_BIT_HS_OVR_SW +#define MBG_PS_MSK_HS ( 1UL << MBG_PS_BIT_HS ) ///< See ::MBG_PS_BIT_HS +#define MBG_PS_MSK_STR_TYPE_OVR_SW ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_SW ) ///< See ::MBG_PS_BIT_STR_TYPE_OVR_SW +#define MBG_PS_MSK_STR_TYPE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_TYPE_OVR_DEV ) ///< See ::MBG_PS_BIT_STR_TYPE_OVR_DEV +#define MBG_PS_MSK_STR_TYPE ( 1UL << MBG_PS_BIT_STR_TYPE ) ///< See ::MBG_PS_BIT_STR_TYPE +#define MBG_PS_MSK_STR_MODE_OVR_SW ( 1UL << MBG_PS_BIT_STR_MODE_OVR_SW ) ///< See ::MBG_PS_BIT_STR_MODE_OVR_SW +#define MBG_PS_MSK_STR_MODE_OVR_DEV ( 1UL << MBG_PS_BIT_STR_MODE_OVR_DEV ) ///< See ::MBG_PS_BIT_STR_MODE_OVR_DEV +#define MBG_PS_MSK_STR_MODE ( 1UL << MBG_PS_BIT_STR_MODE ) ///< See ::MBG_PS_BIT_STR_MODE +#define MBG_PS_MSK_FLAGS_OVR_SW ( 1UL << MBG_PS_BIT_FLAGS_OVR_SW ) ///< See ::MBG_PS_BIT_FLAGS_OVR_SW +#define MBG_PS_MSK_FLAGS ( 1UL << MBG_PS_BIT_FLAGS ) ///< See ::MBG_PS_BIT_FLAGS + +/** @} anchor MBG_COM_CFG_STATUS_MASKS */ + + + +/** + * @brief Configuration settings of a specific serial port + * + * This structure should be sent to a device to configure + * a specific serial port. The number of supported ports + * is ::RECEIVER_INFO::n_com_ports. + * + * @note The ::PORT_INFO_IDX structure should be read from + * a device to retrieve the current settings and capabilities. + * + * @see ::STR_TYPE_INFO + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< Port index, 0..::RECEIVER_INFO::n_com_ports-1 + PORT_SETTINGS port_settings; + +} PORT_SETTINGS_IDX; + +#define _mbg_swab_port_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_port_settings( &(_p)->port_settings ); \ +} while ( 0 ) + + +/** + * @brief Current settings and general capabilities of a serial port + * + * @note This structure should be read from a device to retrieve + * the current settings of a serial port plus its capabilities, + * e.g. supported baud rates, supported string formats, etc. + * + * @see ::STR_TYPE_INFO + */ +typedef struct +{ + PORT_SETTINGS port_settings; ///< current configuration of the port + uint32_t supp_baud_rates; ///< bit mask of baud rates supp. by this port, see ::MBG_BAUD_RATE_MASKS + uint32_t supp_framings; ///< bit mask of framings supp. by this port, see ::MBG_FRAMING_MASKS + uint32_t supp_str_types; ///< bit mask of string types supp. by this port, i.e. bit 0 set if str_type[0] is supp. + uint32_t reserved; ///< reserved for future use, currently always 0 + uint32_t flags; ///< See ::PORT_INFO_FLAGS + +} PORT_INFO; + +#define _mbg_swab_port_info( _p ) \ +do \ +{ \ + _mbg_swab_port_settings( &(_p)->port_settings ); \ + _mbg_swab32( &(_p)->supp_baud_rates ); \ + _mbg_swab32( &(_p)->supp_framings ); \ + _mbg_swab32( &(_p)->supp_str_types ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + +/** + * @brief Flags bits used to define ::PORT_INFO_FLAGS + * + * @see ::PORT_INFO_FLAGS + */ +enum PORT_INFO_FLAG_BITS +{ + PORT_INFO_FLAG_BIT_PORT_INVISIBLE, ///< port is used internally and should not be displayed by config apps + PORT_INFO_FLAG_BIT_BIN_PROT_HS, ///< port supports binary protocol at high speed, see ::MBG_DEFAULT_BAUDRATE_HS + N_PORT_INFO_FLAG_BITS ///< the number of defined bits +}; + + +/** + * @brief Bit masks used with ::PORT_INFO::flags + * + * @see ::PORT_INFO_FLAG_BITS + */ +enum PORT_INFO_FLAGS +{ + PORT_INFO_FLAG_PORT_INVISIBLE = ( 1UL << PORT_INFO_FLAG_BIT_PORT_INVISIBLE ), ///< See ::PORT_INFO_FLAG_BIT_PORT_INVISIBLE + PORT_INFO_FLAG_BIN_PROT_HS = ( 1UL << PORT_INFO_FLAG_BIT_BIN_PROT_HS ) ///< See ::PORT_INFO_FLAG_BIT_BIN_PROT_HS +}; + + +/** + * @brief Current settings and general capabilities of a specific serial port + * + * This structure should be read from the device to retrieve the + * current settings of a specific serial port plus its capabilities, + * e.g. supported baud rates, supported string formats, etc. + * The number of supported ports is ::RECEIVER_INFO::n_com_ports. + * + * @note The ::PORT_SETTINGS_IDX structure should be send back to + * the device to configure the specified serial port. + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< Port index, 0..::RECEIVER_INFO::n_com_ports-1 + PORT_INFO port_info; + +} PORT_INFO_IDX; + +#define _mbg_swab_port_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_port_info( &(_p)->port_info ); \ +} while ( 0 ) + + +/** + * @brief Information on a supported string format + * + * Information includes the name of the string format, which + * transmission modes are supported, etc. + * + * The number of string types, and which string types are supported + * depends on the device type and firmware version. + * + * @note Multiple structures ::STR_TYPE_INFO_IDX should be read + * to retrieve all supported string types. + */ +typedef struct +{ + uint32_t supp_modes; ///< bit mask of modes supp. for this string type, see ::STR_MODE_MASKS + char long_name[23]; ///< long name of the string format + char short_name[11]; ///< short name of the string format + uint16_t flags; ///< reserved, currently always 0 + +} STR_TYPE_INFO; + +#define _mbg_swab_str_type_info( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_modes ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Information on a specific supported string format + * + * This structure should be read from a device to retrieve information + * on a specific supported time string type from an array of supported + * string types. The number of supported string types is returned + * in ::RECEIVER_INFO::n_str_type. + * + * A selected index number can be saved in ::PORT_SETTINGS::str_type to + * configure the selected string type for the specific serial port. + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< String type index, 0..::RECEIVER_INFO::n_str_type-1 + STR_TYPE_INFO str_type_info; + +} STR_TYPE_INFO_IDX; + +#define _mbg_swab_str_type_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_str_type_info( &(_p)->str_type_info ); \ +} while ( 0 ) + + +/** + * @brief Enumeration of modes supported for time string transmission + * + * This determines e.g. at which point in time a string starts + * to be transmitted via the serial port. + * Used with ::PORT_SETTINGS::mode. + * + * @see ::STR_MODE_MASKS + */ +enum STR_MODES +{ + STR_ON_REQ, ///< transmission on request by received '?' character only + STR_PER_SEC, ///< transmission automatically if second changes + 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 +}; + + +/** + * @brief Bit masks associated with ::STR_MODES + * + * Used with ::STR_TYPE_INFO::supp_modes to indicate which + * transmission modes are supported by the particular string type. + * + * @see ::STR_MODES + */ +enum STR_MODE_MASKS +{ + MSK_STR_ON_REQ = ( 1UL << STR_ON_REQ ), ///< See ::STR_ON_REQ + 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_CR_ON_SEC = ( 1UL << STR_CR_ON_SEC ) ///< See ::STR_CR_ON_SEC +}; + + +/** + * @brief Initializer for short name strings associated with ::STR_MODES + * + * @see ::STR_MODES + */ +#define DEFAULT_SHORT_MODE_NAMES \ +{ \ + "'?'", \ + "1 sec", \ + "1 min", \ + "auto", \ + "'?' sec", \ + "<CR> on sec" \ +} + + +/** + * @brief Default initializers for English mode name strings + * + * Initializers for multi-language strings can be found in pcpslstr.h. + * + * @see ::STR_MODES + */ +#define ENG_MODE_NAME_STR_ON_REQ "on request '?' only" +#define ENG_MODE_NAME_STR_PER_SEC "per second" +#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" + + +/** + * @brief Initializer for an English mode name string table + * + * Initializers for multi-language strings can be found in pcpslstr.h. + * + * @see ::STR_MODES + */ +#define DEFAULT_ENG_MODE_NAMES \ +{ \ + ENG_MODE_NAME_STR_ON_REQ, \ + 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_CR_ON_SEC \ +} + + +/* + * The modes below are supported by most string types: + */ +#define DEFAULT_STR_MODES \ +( \ + MSK_STR_ON_REQ | \ + MSK_STR_PER_SEC | \ + MSK_STR_PER_MIN \ +) + + +/* + * The modes below can be used with the capture string: + */ +#define DEFAULT_STR_MODES_UCAP \ +( \ + MSK_STR_ON_REQ | \ + MSK_STR_AUTO \ +) + + + +/** + * @brief The number of string types supported by legacy DCF77 receivers + * + * For receivers supporting a ::RECEIVER_INFO this should be determined + * from ::RECEIVER_INFO::n_str_type. + * + * @see ::DEFAULT_SUPP_STR_TYPES_DCF + */ +#define DEFAULT_N_STR_TYPE_DCF 1 + +/** + * @brief Bit mask of string types supported by legacy DCF77 receivers + * + * For receivers supporting a ::RECEIVER_INFO this should be determined + * from ::PORT_INFO::supp_str_types. + * + * @see ::DEFAULT_N_STR_TYPE_DCF + */ +#define DEFAULT_SUPP_STR_TYPES_DCF \ + ( ( 1UL << DEFAULT_N_STR_TYPE_DCF ) - 1 ) + + + +/** + * @brief The number of string types supported by legacy GPS receivers + * + * For receivers supporting a ::RECEIVER_INFO this should be determined + * from ::RECEIVER_INFO::n_str_type. + * + * @see ::DEFAULT_SUPP_STR_TYPES_GPS + */ +#define DEFAULT_N_STR_TYPE_GPS 2 + +/** + * @brief Bit mask of string types supported by legacy GPS receivers + * + * For receivers supporting a ::RECEIVER_INFO this should be determined + * from ::PORT_INFO::supp_str_types. + * + * @see ::DEFAULT_N_STR_TYPE_GPS + */ +#define DEFAULT_SUPP_STR_TYPES_GPS \ + ( ( 1UL << DEFAULT_N_STR_TYPE_GPS ) - 1 ) + + + +/* + * The number of serial ports which are at least available + * even with very old GPS receiver models. For devices providing + * a ::RECEIVER_INFO structure the number of provided COM ports + * is available in ::RECEIVER_INFO::n_com_ports. + */ +#define DEFAULT_N_COM 2 + +/* + * By default that's also the number of ports + * currently available: + */ +#ifndef N_COM + #define N_COM DEFAULT_N_COM +#endif + +/** + * @brief A The structure used to store the configuration of two serial ports + * + * @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, see ::LGCY_STR_MODES + +} PORT_PARM; + +#define _mbg_swab_port_parm( _p ) \ +do \ +{ \ + int i; \ + for ( i = 0; i < DEFAULT_N_COM; i++ ) \ + { \ + _mbg_swab_com_parm( &(_p)->com[i] ); \ + /* no need to swap mode byte */ \ + } \ +} while ( 0 ) + + + +/** + * @brief Deprecated codes for serial string modes + * + * @deprecated These codes have been used with the + * deprecated ::PORT_PARM::mode field and are still + * defined for compatibility reasons. + * + * @see ::STR_MODES + */ +enum LGCY_STR_MODES +{ + 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 + + + +/** + * @defgroup group_icode IRIG time codes + * + * The following definitions are used to configure an optional + * on-board IRIG input or output. Which frame types are supported + * by a device depends on the device type, and may depend on the + * firmware version of the device. + * + * All IRIG frames transport the day-of-year number plus the time-of-day, + * and include a control field segment which can transport user defined + * information. + * + * Some newer IRIG frames are compatible with older frame types but support + * well defined extensions like the year number, local time offset, DST status, + * etc., in the control fields: + * + * The following specification can be found in IRIG Standard 200-04 (September 2004): + * + * Format A: 1k pps + * Format B: 100 pps + * Format D: 1 ppm + * Format E: 10 pps + * Format G: 10k pps + * Format H: 1 pps + * + * 1st digit: Modulation Frequency + * 0 Pulse width code + * 1 Sine wave, amplitude modulated + * 2 Manchester modulated + * + * 2nd digit: Frequency / Resolution + * 0: No carrier / index count interval + * 1: 100 Hz / 10 ms + * 2: 1 kHz / 1 ms + * 3: 10 kHz / 0.1 ms + * 4: 100 kHz / 10 ms + * 5: 1 MHz / 1 ms + * + * 3rd digit: Coded expressions + * 0: DOY+TOD, CF, SBS + * 1: DOY+TOD, CF + * 2: DOY+TOD + * 3: DOY+TOD, SBS + * 4: DOY+TOD, Year, CF, SBS + * 5: DOY+TOD, Year, CF + * 6: DOY+TOD, Year + * 7: DOY+TOD, Year, SBS + * + * + * Table of Permissible Code Formats + * + * Letter 1st digit 2nd digit 3rd digit + * ---------------------------------------------- + * A 0,1,2 0,3,4,5 0,1,2,3,4,5,6,7 + * B 0,1,2 0,2,3,4,5 0,1,2,3,4,5,6,7 + * D 0,1 0,1,2 1,2 + * E 0,1 0,1,2 1,2,5,6 + * G 0,1,2 0,4,5 1,2,5,6 + * H 0,1 0,1,2 1,2 + * + * - Known IRIG signal code types: + * - \b A002: 1000 bps, DCLS, time-of-year + * - \b A003: 1000 bps, DCLS, time-of-year, SBS + * - \b A132: 1000 bps, 10 kHz carrier, time-of-year + * - \b A133: 1000 bps, 10 kHz carrier, time-of-year, SBS + * - \b B002: 100 bps, DCLS, time-of-year + * - \b B003: 100 bps, DCLS, time-of-year, SBS + * - \b B122: 100 bps, 1 kHz carrier, time-of-year + * - \b B123: 100 bps, 1 kHz carrier, time-of-year, SBS + * - \b B006: 100 bps, DCLS, complete date + * - \b B007: 100 bps, DCLS, complete date, SBS + * - \b B126: 100 bps, 1 kHz carrier, complete date + * - \b B127: 100 bps, 1 kHz carrier, complete date, SBS + * - \b B220/1344: 100 bps, DCLS, manchester encoded, IEEE1344 extensions + * - \b B222: 100 bps, DCLS, manchester encoded, time-of-year + * - \b B223: 100 bps, DCLS, manchester encoded, time-of-year, SBS + * - \b G002: 10 kbps, DCLS, time-of-year + * - \b G142: 10 kbps, 100 kHz carrier, time-of-year + * - \b G006: 10 kbps, DCLS, complete date + * - \b G146: 10 kbps, 100 kHz carrier, complete date + * - \b AFNOR: 100 bps, 1 kHz carrier, SBS, complete date + * - \b AFNOR DC: 100 bps, DCLS, SBS, complete date + * - \b IEEE1344: 100 bps, 1 kHz carrier, time-of-year, SBS, IEEE 1344 extensions (B120) + * - \b IEEE1344 DC: 100 bps, DCLS, time-of-year, SBS, IEEE 1344 extensions (B000) + * - \b C37.118: like IEEE 1344, but %UTC offset applied with reversed sign + * - \b C37.118 DC: like IEEE 1344 DC, but %UTC offset applied with reversed sign + * + * - time-of-year: day-of-year, hours, minutes, seconds + * - complete date: time-of-year plus year number + * - SBS: straight binary seconds, second-of-day + * + * AFNOR codes are based on the french standard AFNOR NF S87-500 + * + * IEEE 1344 codes are defined in IEEE standard 1344-1995. The code frame is compatible + * with B002/B122 but provides some well defined extensions in the control field which + * include a quality indicator (time figure of merit, TFOM), year number, DST and leap + * second status, and local time offset from %UTC. + * + * IEEE C37.118 codes are defined in IEEE standard C37.118-2005 which includes a revised version + * of the IEEE 1344 standard from 1995. These codes provide the same extensions as IEEE 1344 + * but unfortunately determine that the %UTC offset has to be applied with reversed sign. + * + * For example, if a -6 hours %UTC offset is transmitted in the time code:<br> + * IEEE 1344: (IRIG time 14:43:27 h) - (offs -6 h) = (%UTC 20:43:27)<br> + * IEEE C37.118: (IRIG time 14:43:27 h) + (offs -6 h) = (%UTC 08:43:27)<br> + * + * @see @ref MSK_ICODE_RX_UTC_OFFS_ADD and @ref MSK_ICODE_RX_UTC_OFFS_SUB + * + * @note There are 3rd party IRIG devices out there which apply the %UTC offset as specified + * in IEEE C37.118-2005, but claim to be compatible with IEEE 1344. So if local time is transmitted + * by the timecode then care must be taken that the %UTC offset is evaluated by the timecode + * receiver in the same way as computed by the timecode generator. Otherwise the %UTC + * time computed by the receiver may be <b>wrong</b>. + * + * @{ */ + +/** + * @brief Known IRIG TX code formats + * + * Used with ::IRIG_SETTINGS::icode for IRIG transmitters. + * For IRIG receivers see ::ICODE_RX_CODES. + * + * Meinberg timecode transmitters always generate the unmodulated (DCLS) + * and usually the modulated timecode signals internally at the same time, + * so the code definitions always refer to both. + * + * @note Not all device may provide both the modulated and unmodulated + * signal externally. + */ +enum ICODE_TX_CODES +{ + ICODE_TX_B002_B122, + ICODE_TX_B003_B123, + ICODE_TX_A002_A132, + ICODE_TX_A003_A133, + ICODE_TX_AFNOR, + ICODE_TX_IEEE1344, + ICODE_TX_B2201344, ///< DCLS only + ICODE_TX_B222, ///< DCLS only + ICODE_TX_B223, ///< DCLS only + ICODE_TX_B006_B126, + ICODE_TX_B007_B127, + ICODE_TX_G002_G142, + ICODE_TX_G006_G146, + ICODE_TX_C37118, + ICODE_TX_TXC101, + ICODE_TX_E002_E112, + ICODE_TX_NASA36, + ICODE_TX_A006_A136, + ICODE_TX_A007_A137, + N_ICODE_TX ///< number of known codes +}; + + +/** + * @brief Initializers for TX timecode format name strings + * + * @see ::ICODE_TX_CODES + */ +#define DEFAULT_ICODE_TX_NAMES \ +{ \ + /* B002_B122 */ "B002+B122", \ + /* B003_B123 */ "B003+B123", \ + /* A002_A132 */ "A002+A132", \ + /* A003_A133 */ "A003+A133", \ + /* AFNOR */ "AFNOR NF S87-500", \ + /* IEEE1344 */ "IEEE 1344", \ + /* B2201344 */ "B220(1344) DCLS", \ + /* B222 */ "B222 DCLS", \ + /* B223 */ "B223 DCLS", \ + /* B006_B126 */ "B006+B126", \ + /* B007_B127 */ "B007+B127", \ + /* G002_G142 */ "G002+G142", \ + /* G006_G146 */ "G006+G146", \ + /* C37118 */ "IEEE C37.118", \ + /* TXC101 */ "TXC-101 DTR-6", \ + /* E002_E112 */ "E002+E112", \ + /* NASA36 */ "NASA 36", \ + /* A006_A136 */ "A006+A136", \ + /* A007_A137 */ "A007+A137" \ +} + +/** + * @brief Initializers for short TX timecode format name strings + * + * @note Must not be longer than 10 printable characters + * + * @see ::ICODE_TX_CODES + */ +#define DEFAULT_ICODE_TX_NAMES_SHORT \ +{ \ + /* B002_B122 */ "B002+B122", \ + /* B003_B123 */ "B003+B123", \ + /* A002_A132 */ "A002+A132", \ + /* A003_A133 */ "A003+A133", \ + /* AFNOR */ "AFNOR NF S", \ + /* IEEE1344 */ "IEEE 1344", \ + /* B2201344 */ "B220/1344", \ + /* B222 */ "B222 DC", \ + /* B223 */ "B223 DC", \ + /* B006_B126 */ "B006+B126", \ + /* B007_B127 */ "B007+B127", \ + /* G002_G142 */ "G002+G142", \ + /* G006_G146 */ "G006+G146", \ + /* C37118 */ "C37.118", \ + /* TXC101 */ "TXC-101", \ + /* E002_E112 */ "E002+E112", \ + /* NASA36 */ "NASA 36", \ + /* A006_A136 */ "A006+A136", \ + /* A007_A137 */ "A007+A137" \ +} + + +/** + * @brief Initializers for English TX format description strings + * + * @see ::ICODE_TX_CODES + */ +#define DEFAULT_ICODE_TX_DESCRIPTIONS_ENG \ +{ \ + /* B002_B122 */ "100 bps, DCLS or 1 kHz carrier", \ + /* B003_B123 */ "100 bps, DCLS or 1 kHz carrier, SBS", \ + /* A002_A132 */ "1000 bps, DCLS or 10 kHz carrier", \ + /* A003_A133 */ "1000 bps, DCLS or 10 kHz carrier, SBS", \ + /* AFNOR */ "100 bps, DCLS or 1 kHz carrier, complete date, SBS", \ + /* IEEE1344 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number, SBS, UTC offset, DST and Leap sec status", \ + /* B2201344 */ "100 bps, Manchester enc., DCLS only, 2 digit year number, SBS, UTC offset, DST and Leap sec status", \ + /* B222 */ "100 bps, Manchester enc., DCLS only", \ + /* B223 */ "100 bps, Manchester enc., DCLS only, SBS", \ + /* B006_B126 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number", \ + /* B007_B127 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number, SBS", \ + /* G002_G142 */ "10 kbps, DCLS or 100 kHz carrier", \ + /* G006_G146 */ "10 kbps, DCLS or 100 kHz carrier, 2 digit year number", \ + /* C37118 */ "100 bps, DCLS or 1 kHz carrier, 2 digit year number, SBS, UTC offs. reverse to 1344, DST/Leap sec status", \ + /* TXC101 */ "code from TV time sync device TXC-101 DTR-6", \ + /* E002_E112 */ "10 bps, DCLS or 100 Hz carrier", \ + /* NASA36 */ "100 bps, DCLS or 1 kHz carrier", \ + /* A006_A136 */ "1000 bps, DCLS or 10 kHz carrier, 2 digit year number", \ + /* A007_A137 */ "1000 bps, DCLS or 10 kHz carrier, 2 digit year number, SBS" \ +} + + +/** + * @brief Bit masks used with ::IRIG_INFO::supp_codes for TX + * + * These bit masks are used with timecode receivers only + * + * @see @ref ICODE_TX_CODES + * @see @ref ICODE_RX_CODES + * @see @ref ICODE_RX_MASKS + * + * @anchor ICODE_TX_MASKS @{ */ + +#define MSK_ICODE_TX_B002_B122 ( 1UL << ICODE_TX_B002_B122 ) +#define MSK_ICODE_TX_B003_B123 ( 1UL << ICODE_TX_B003_B123 ) +#define MSK_ICODE_TX_A002_A132 ( 1UL << ICODE_TX_A002_A132 ) +#define MSK_ICODE_TX_A003_A133 ( 1UL << ICODE_TX_A003_A133 ) +#define MSK_ICODE_TX_AFNOR ( 1UL << ICODE_TX_AFNOR ) +#define MSK_ICODE_TX_IEEE1344 ( 1UL << ICODE_TX_IEEE1344 ) +#define MSK_ICODE_TX_B2201344 ( 1UL << ICODE_TX_B2201344 ) +#define MSK_ICODE_TX_B222 ( 1UL << ICODE_TX_B222 ) +#define MSK_ICODE_TX_B223 ( 1UL << ICODE_TX_B223 ) +#define MSK_ICODE_TX_B006_B126 ( 1UL << ICODE_TX_B006_B126 ) +#define MSK_ICODE_TX_B007_B127 ( 1UL << ICODE_TX_B007_B127 ) +#define MSK_ICODE_TX_G002_G142 ( 1UL << ICODE_TX_G002_G142 ) +#define MSK_ICODE_TX_G006_G146 ( 1UL << ICODE_TX_G006_G146 ) +#define MSK_ICODE_TX_C37118 ( 1UL << ICODE_TX_C37118 ) +#define MSK_ICODE_TX_TXC101 ( 1UL << ICODE_TX_TXC101 ) +#define MSK_ICODE_TX_E002_E112 ( 1UL << ICODE_TX_E002_E112 ) +#define MSK_ICODE_TX_NASA36 ( 1UL << ICODE_TX_NASA36 ) +#define MSK_ICODE_TX_A006_A136 ( 1UL << ICODE_TX_A006_A136 ) +#define MSK_ICODE_TX_A007_A137 ( 1UL << ICODE_TX_A007_A137 ) + +/** @} anchor ICODE_TX_MASKS */ + + +/** + * @brief A mask of IRIG TX formats with manchester encoded DC output + */ +#define MSK_ICODE_TX_DC_MANCH \ +( \ + MSK_ICODE_TX_B2201344 | \ + MSK_ICODE_TX_B222 | \ + MSK_ICODE_TX_B223 \ +) + +/** + * @brief A mask of IRIG TX formats with 100 Hz carrier + */ +#define MSK_ICODE_TX_100HZ \ +( \ + MSK_ICODE_TX_E002_E112 \ +) + +/** + * @brief A mask of IRIG TX formats with 1 kHz carrier + */ +#define MSK_ICODE_TX_1KHZ \ +( \ + MSK_ICODE_TX_B002_B122 | \ + MSK_ICODE_TX_B003_B123 | \ + MSK_ICODE_TX_AFNOR | \ + MSK_ICODE_TX_IEEE1344 | \ + MSK_ICODE_TX_B2201344 | \ + MSK_ICODE_TX_B222 | \ + MSK_ICODE_TX_B223 | \ + MSK_ICODE_TX_B006_B126 | \ + MSK_ICODE_TX_B007_B127 | \ + MSK_ICODE_TX_C37118 | \ + MSK_ICODE_TX_NASA36 \ +) + +/** + * @brief A mask of IRIG TX formats with 10 kHz carrier + */ +#define MSK_ICODE_TX_10KHZ \ +( \ + MSK_ICODE_TX_A002_A132 | \ + MSK_ICODE_TX_A003_A133 | \ + MSK_ICODE_TX_A006_A136 | \ + MSK_ICODE_TX_A007_A137 \ +) + +/** + * @brief A mask of IRIG TX formats with 100 kHz carrier + */ +#define MSK_ICODE_TX_100KHZ \ +( \ + MSK_ICODE_TX_G002_G142 | \ + MSK_ICODE_TX_G006_G146 \ +) + +/** + * @brief A mask of IRIG TX formats with 10 bps data rate + */ +#define MSK_ICODE_TX_10BPS \ +( \ + MSK_ICODE_TX_E002_E112 \ +) + +/** + * @brief A mask of IRIG TX formats with 100 bps data rate + */ +#define MSK_ICODE_TX_100BPS \ +( \ + MSK_ICODE_TX_B002_B122 | \ + MSK_ICODE_TX_B003_B123 | \ + MSK_ICODE_TX_AFNOR | \ + MSK_ICODE_TX_IEEE1344 | \ + MSK_ICODE_TX_B006_B126 | \ + MSK_ICODE_TX_B007_B127 | \ + MSK_ICODE_TX_C37118 \ +) + +/** + * @brief A mask of IRIG TX formats with 1000 bps data rate + */ +#define MSK_ICODE_TX_1000BPS \ +( \ + MSK_ICODE_TX_A002_A132 | \ + MSK_ICODE_TX_A003_A133 | \ + MSK_ICODE_TX_A006_A136 | \ + MSK_ICODE_TX_A007_A137 \ +) + +/** + * @brief A mask of IRIG TX formats with 10 kbps data rate + */ +#define MSK_ICODE_TX_10000BPS \ +( \ + MSK_ICODE_TX_G002_G142 | \ + MSK_ICODE_TX_G006_G146 \ +) + +/** + * @brief A mask of IRIG TX formats supporting 10ths of seconds + */ +#define MSK_ICODE_TX_HAS_SEC10THS \ +( \ + MSK_ICODE_TX_A002_A132 | \ + MSK_ICODE_TX_A003_A133 | \ + MSK_ICODE_TX_G002_G142 | \ + MSK_ICODE_TX_G006_G146 | \ + MSK_ICODE_TX_A006_A136 | \ + MSK_ICODE_TX_A007_A137 \ +) + +/** + * @brief A mask of IRIG TX formats supporting 100ths of seconds + */ +#define MSK_ICODE_TX_HAS_SEC100THS \ +( \ + MSK_ICODE_TX_G002_G142 | \ + MSK_ICODE_TX_G006_G146 \ +) + +/** + * @brief A mask of IRIG TX formats providing a short year number after P5 + * + * The IEEE codes, the AFNOR codes, and some IRIG codes provide a + * 2 digit year number after position identifier P5. However, some + * IRIG G codes provide a 100ths-of-seconds field after P5,and + * eventually provide a year number after P6. + * + * @see @ref MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P6 + * @see @ref MSK_ICODE_TX_HAS_ANY_SHORT_YEAR + */ +#define MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P5 \ +( \ + MSK_ICODE_TX_AFNOR | \ + MSK_ICODE_TX_IEEE1344 | \ + MSK_ICODE_TX_B2201344 | \ + MSK_ICODE_TX_B006_B126 | \ + MSK_ICODE_TX_B007_B127 | \ + MSK_ICODE_TX_C37118 | \ + MSK_ICODE_TX_A006_A136 | \ + MSK_ICODE_TX_A007_A137 \ +) + +/** + * @brief A mask of IRIG TX formats providing a short year number after P6 + * + * While most time codes that provide a year number do this after P5, + * there are some IRIG codes which provide a 100ths-of-seconds field + * at that position, and eventually provide a year number after P6. + * + * @see @ref MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P5 + * @see @ref MSK_ICODE_TX_HAS_ANY_SHORT_YEAR + */ + #define MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P6 \ +( \ + MSK_ICODE_TX_G006_G146 \ +) + +/** + * @brief A mask of IRIG TX formats providing a short year number in general + * + * Depending on the code format, the year number can be transmitted + * either after position identifier P5, or after P6. + * + * @see @ref MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P5 + * @see @ref MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P6 + */ +#define MSK_ICODE_TX_HAS_ANY_SHORT_YEAR \ +( \ + MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P5 | \ + MSK_ICODE_TX_HAS_SHORT_YEAR_AFTER_P6 \ +) + +/** + * @brief A mask of IRIG TX formats supporting TFOM + */ +#define MSK_ICODE_TX_HAS_TFOM \ +( \ + MSK_ICODE_TX_IEEE1344 | \ + MSK_ICODE_TX_C37118 \ +) + +/** + * @brief A mask of IRIG TX formats supporting CTQ continuous time quality + * + * This has been introduced in IEEE C37.118.1-2011 + */ +#define MSK_ICODE_TX_HAS_CTQ \ +( \ + MSK_ICODE_TX_IEEE1344 | \ + MSK_ICODE_TX_C37118 \ +) + +/** + * @brief A mask of IRIG TX formats supporting time zone information + */ +#define MSK_ICODE_TX_HAS_TZI \ +( \ + MSK_ICODE_TX_IEEE1344 | \ + MSK_ICODE_TX_C37118 \ +) + +/** + * @brief IRIG TX formats where %UTC offset must be subtracted to yield %UTC + * + * A mask of IRIG formats where the decoded %UTC offset must be + * subtracted from the time decoded from the IRIG signal to yield %UTC, e.g.:<br> + * (IRIG time 14:43:27 h) - (offs -6 h) = (%UTC 20:43:27) + */ +#define MSK_ICODE_TX_UTC_OFFS_SUB \ +( \ + MSK_ICODE_TX_IEEE1344 \ +) + +/** + * @brief IRIG TX formats where %UTC offset must be added to yield %UTC + * + * A mask of IRIG formats where the decoded %UTC offset must be + * added to the time decoded from the IRIG signal to yield %UTC, e.g.:<br> + * (IRIG time 14:43:27 h) + (offs -6 h) = (%UTC 08:43:27) + */ +#define MSK_ICODE_TX_UTC_OFFS_ADD \ +( \ + MSK_ICODE_TX_C37118 \ +) + +/** + * @brief A mask of IRIG TX formats supporting a day of week number + */ +#define MSK_ICODE_TX_HAS_AFNOR_WDAY \ +( \ + MSK_ICODE_TX_AFNOR | \ + MSK_ICODE_TX_AFNOR_DC \ +) + +/** + * @brief A mask of IRIG TX formats supporting a date (day-of-month, month) + */ +#define MSK_ICODE_TX_HAS_AFNOR_DATE \ +( \ + MSK_ICODE_TX_AFNOR | \ + MSK_ICODE_TX_AFNOR_DC \ +) + + +/** + * @brief The default mask of IRIG TX formats supported by IRIG transmitters + * + * @note The formats which are actually supported should be retrieved + * from the device + */ +#if !defined( SUPP_MSK_ICODE_TX ) + #define SUPP_MSK_ICODE_TX \ + ( \ + MSK_ICODE_TX_B002_B122 | \ + MSK_ICODE_TX_B003_B123 | \ + MSK_ICODE_TX_A002_A132 | \ + MSK_ICODE_TX_A003_A133 | \ + MSK_ICODE_TX_AFNOR \ + ) +#endif + + + +/** + * @brief Known IRIG RX code formats + * + * Used with ::IRIG_SETTINGS::icode for IRIG receivers. + * For IRIG transmitters see ::ICODE_TX_CODES. + * + * The SBS value is redundant and can easily by computed + * from the time-of-day, so Meinberg time code receivers + * usually don't evaluate the SBS field anyway, and thus + * it makes no difference if a code with or withour SBS + * is supplied. + */ +enum ICODE_RX_CODES +{ + ICODE_RX_B122_B123, ///< modulated + ICODE_RX_A132_A133, ///< modulated + ICODE_RX_B002_B003, ///< DCLS + ICODE_RX_A002_A003, ///< DCLS + ICODE_RX_AFNOR, ///< modulated + ICODE_RX_AFNOR_DC, ///< DCLS + ICODE_RX_IEEE1344, ///< modulated + ICODE_RX_IEEE1344_DC, ///< DCLS + ICODE_RX_B126_B127, ///< modulated + ICODE_RX_B006_B007, ///< DCLS + ICODE_RX_G142, ///< modulated (G143 is undefined, SBS not supported with Gxxx) + ICODE_RX_G002, ///< DCLS (G003 is undefined, SBS not supported with Gxxx) + ICODE_RX_C37118, ///< modulated + ICODE_RX_C37118_DC, ///< DCLS + ICODE_RX_TXC101, ///< modulated + ICODE_RX_TXC101_DC, ///< DCLS + ICODE_RX_E112, ///< modulated + ICODE_RX_E002, ///< DCLS + ICODE_RX_NASA36, ///< modulated + ICODE_RX_NASA36_DC, ///< DCLS + ICODE_RX_A136_A137, ///< modulated + ICODE_RX_A006_A007, ///< DCLS + ICODE_RX_G146, ///< modulated (G147 is undefined, SBS not supported with Gxxx) + ICODE_RX_G006, ///< DCLS (G007 is undefined, SBS not supported with Gxxx) + N_ICODE_RX ///< the number of known codes +}; + +/** + * @brief Initializers for RX timecode format name strings + * + * @see ::ICODE_RX_CODES + */ +#define DEFAULT_ICODE_RX_NAMES \ +{ \ + /* B122_B123 */ "B122/B123", \ + /* A132_A133 */ "A132/A133", \ + /* B002_B003 */ "B002/B003 (DCLS)", \ + /* A002_A003 */ "A002/A003 (DCLS)", \ + /* AFNOR */ "AFNOR NF S87-500", \ + /* AFNOR_DC */ "AFNOR NF S87-500 (DCLS)", \ + /* IEEE1344 */ "IEEE1344", \ + /* IEEE1344_DC */ "IEEE1344 (DCLS)", \ + /* B126_B127 */ "B126/B127", \ + /* B006_B007 */ "B006/B007 (DCLS)", \ + /* G142 */ "G142", \ + /* G002 */ "G002 (DCLS)", \ + /* C37118 */ "C37.118", \ + /* C37118_DC */ "C37.118 (DCLS)", \ + /* TXC101 */ "TXC-101 DTR-6", \ + /* TXC101_DC */ "TXC-101 DTR-6 (DCLS)", \ + /* E112 */ "E112", \ + /* E002 */ "E002 (DCLS)", \ + /* NASA36 */ "NASA-36", \ + /* NASA36_DC */ "NASA-36 (DCLS)", \ + /* A136_A137 */ "A136/A137", \ + /* A006_A007 */ "A006/A007 (DCLS)", \ + /* G146 */ "G146", \ + /* G006 */ "G006 (DCLS)" \ +} + +/** + * @brief Initializers for short RX timecode format name strings + * + * @note Must not be longer than 11 printable characters + * + * @see ::ICODE_RX_CODES + */ +#define DEFAULT_ICODE_RX_NAMES_SHORT \ +{ \ + /* B122_B123 */ "B122/B123", \ + /* A132_A133 */ "A132/A133", \ + /* B002_B003 */ "B002/B003", \ + /* A002_A003 */ "A002/A003", \ + /* AFNOR */ "AFNOR NF S", \ + /* AFNOR_DC */ "AFNOR DC", \ + /* IEEE1344 */ "IEEE1344", \ + /* IEEE1344_DC */ "IEEE1344 DC", \ + /* B126_B127 */ "B126/B127", \ + /* B006_B007 */ "B006/B007", \ + /* G142 */ "G142", \ + /* G002 */ "G002 DC", \ + /* C37118 */ "C37.118", \ + /* C37118_DC */ "C37.118 DC", \ + /* TXC101 */ "TXC-101", \ + /* TXC101_DC */ "TXC-101 DC", \ + /* E112 */ "E112", \ + /* E002 */ "E002 DC", \ + /* NASA36 */ "NASA-36", \ + /* NASA36_DC */ "NASA-36 DC", \ + /* A136_A137 */ "A136/A137", \ + /* A006_A007 */ "A006/A007", \ + /* G146 */ "G146", \ + /* G006 */ "G006 DC" \ +} + + +/** + * @brief Initializers for English RX format description strings + * + * @see ::ICODE_RX_CODES + */ +#define DEFAULT_ICODE_RX_DESCRIPTIONS_ENG \ +{ \ + /* B122_B123 */ "100 bps, 1 kHz carrier, SBS optionally", \ + /* A132_A133 */ "1000 bps, 10 kHz carrier, SBS optionally", \ + /* B002_B003 */ "100 bps, DCLS, SBS optionally", \ + /* A002_A003 */ "1000 bps, DCLS, SBS optionally", \ + /* AFNOR */ "100 bps, 1 kHz carrier, complete date, SBS", \ + /* AFNOR_DC */ "100 bps, DCLS, complete date, SBS", \ + /* IEEE1344 */ "100 bps, 1 kHz carrier, SBS, time zone info", \ + /* IEEE1344_DC */ "100 bps, DCLS, SBS, time zone info", \ + /* B126_B127 */ "100 bps, 1 kHz carrier, 2 digit year number, SBS optionally", \ + /* B006_B007 */ "100 bps, DCLS, 2 digit year number, SBS optionally", \ + /* G142 */ "10 kbps, 100 kHz carrier", \ + /* G002 */ "10 kbps, DCLS", \ + /* C37118 */ "like IEEE1344, but UTC offset with reversed sign", \ + /* C37118_DC */ "like IEEE1344 DC, but UTC offset with reversed sign", \ + /* TXC101 */ "code from TV time sync device TXC-101 DTR-6", \ + /* TXC101_DC */ "DC code from TV time sync device TXC-101 DTR-6", \ + /* E112 */ "10 bps, 100 Hz carrier", \ + /* E002 */ "10 bps, DCLS", \ + /* NASA36 */ "100 bps, 1 kHz carrier", \ + /* NASA36_DC */ "100 bps, DCLS", \ + /* A136_A137 */ "1000 bps, 10 kHz carrier, 2 digit year number, SBS optionally", \ + /* A006_A007 */ "1000 bps, DCLS, 2 digit year number, SBS optionally", \ + /* G146 */ "10 kbps, 100 kHz carrier, 2 digit year number", \ + /* G006 */ "10 kbps, DCLS, 2 digit year number" \ +} + +/** + * @brief Bit masks used with ::IRIG_INFO::supp_codes for RX + * + * These bit masks are used with timecode receivers only + * + * @see @ref ICODE_RX_CODES + * @see @ref ICODE_TX_CODES + * @see @ref ICODE_TX_MASKS + * + * @anchor ICODE_RX_MASKS @{ */ + +#define MSK_ICODE_RX_B122_B123 ( 1UL << ICODE_RX_B122_B123 ) +#define MSK_ICODE_RX_A132_A133 ( 1UL << ICODE_RX_A132_A133 ) +#define MSK_ICODE_RX_B002_B003 ( 1UL << ICODE_RX_B002_B003 ) +#define MSK_ICODE_RX_A002_A003 ( 1UL << ICODE_RX_A002_A003 ) +#define MSK_ICODE_RX_AFNOR ( 1UL << ICODE_RX_AFNOR ) +#define MSK_ICODE_RX_AFNOR_DC ( 1UL << ICODE_RX_AFNOR_DC ) +#define MSK_ICODE_RX_IEEE1344 ( 1UL << ICODE_RX_IEEE1344 ) +#define MSK_ICODE_RX_IEEE1344_DC ( 1UL << ICODE_RX_IEEE1344_DC ) +#define MSK_ICODE_RX_B126_B127 ( 1UL << ICODE_RX_B126_B127 ) +#define MSK_ICODE_RX_B006_B007 ( 1UL << ICODE_RX_B006_B007 ) +#define MSK_ICODE_RX_G142 ( 1UL << ICODE_RX_G142 ) +#define MSK_ICODE_RX_G002 ( 1UL << ICODE_RX_G002 ) +#define MSK_ICODE_RX_C37118 ( 1UL << ICODE_RX_C37118 ) +#define MSK_ICODE_RX_C37118_DC ( 1UL << ICODE_RX_C37118_DC ) +#define MSK_ICODE_RX_TXC101 ( 1UL << ICODE_RX_TXC101 ) +#define MSK_ICODE_RX_TXC101_DC ( 1UL << ICODE_RX_TXC101_DC ) +#define MSK_ICODE_RX_E112 ( 1UL << ICODE_RX_E112 ) +#define MSK_ICODE_RX_E002 ( 1UL << ICODE_RX_E002 ) +#define MSK_ICODE_RX_NASA36 ( 1UL << ICODE_RX_NASA36 ) +#define MSK_ICODE_RX_NASA36_DC ( 1UL << ICODE_RX_NASA36_DC ) +#define MSK_ICODE_RX_A136_A137 ( 1UL << ICODE_RX_A136_A137 ) +#define MSK_ICODE_RX_A006_A007 ( 1UL << ICODE_RX_A006_A007 ) +#define MSK_ICODE_RX_G146 ( 1UL << ICODE_RX_G146 ) +#define MSK_ICODE_RX_G006 ( 1UL << ICODE_RX_G006 ) + +/** @} anchor ICODE_RX_MASKS */ + + +/** + * @brief A mask of IRIG RX DCLS formats + */ +#define MSK_ICODE_RX_DC \ +( \ + MSK_ICODE_RX_B002_B003 | \ + MSK_ICODE_RX_A002_A003 | \ + MSK_ICODE_RX_AFNOR_DC | \ + MSK_ICODE_RX_IEEE1344_DC | \ + MSK_ICODE_RX_B006_B007 | \ + MSK_ICODE_RX_G002 | \ + MSK_ICODE_RX_C37118_DC | \ + MSK_ICODE_RX_TXC101_DC | \ + MSK_ICODE_RX_E002 | \ + MSK_ICODE_RX_NASA36_DC | \ + MSK_ICODE_RX_A006_A007 | \ + MSK_ICODE_RX_G006 \ +) + +/** + * @brief A mask of IRIG RX formats with 100 Hz carrier + */ +#define MSK_ICODE_RX_100HZ \ +( \ + MSK_ICODE_RX_E112 \ +) + +/** + * @brief A mask of IRIG RX formats with 1 kHz carrier + */ +#define MSK_ICODE_RX_1KHZ \ +( \ + MSK_ICODE_RX_B122_B123 | \ + MSK_ICODE_RX_AFNOR | \ + MSK_ICODE_RX_IEEE1344 | \ + MSK_ICODE_RX_B126_B127 | \ + MSK_ICODE_RX_C37118 | \ + MSK_ICODE_RX_TXC101 | \ + MSK_ICODE_RX_NASA36 \ +) + +/** + * @brief A mask of IRIG RX formats with 10 kHz carrier + */ +#define MSK_ICODE_RX_10KHZ \ +( \ + MSK_ICODE_RX_A132_A133 | \ + MSK_ICODE_RX_A136_A137 \ +) + +/** + * @brief A mask of IRIG RX formats with 100 kHz carrier + */ +#define MSK_ICODE_RX_100KHZ \ +( \ + MSK_ICODE_RX_G142 | \ + MSK_ICODE_RX_G146 \ +) + +/** + * @brief A mask of IRIG RX formats with 10 bps data rate + */ +#define MSK_ICODE_RX_10BPS \ +( \ + MSK_ICODE_RX_E002_E112 | \ + MSK_ICODE_RX_E002_E002 \ +) + +/** + * @brief A mask of IRIG RX formats with 100 bps data rate + */ +#define MSK_ICODE_RX_100BPS \ +( \ + MSK_ICODE_RX_B122_B123 | \ + MSK_ICODE_RX_B002_B003 | \ + MSK_ICODE_RX_AFNOR | \ + MSK_ICODE_RX_AFNOR_DC | \ + MSK_ICODE_RX_IEEE1344 | \ + MSK_ICODE_RX_IEEE1344_DC | \ + MSK_ICODE_RX_B126_B127 | \ + MSK_ICODE_RX_B006_B007 | \ + MSK_ICODE_RX_C37118 | \ + MSK_ICODE_RX_C37118_DC | \ + MSK_ICODE_RX_TXC101 | \ + MSK_ICODE_RX_TXC101_DC | \ + MSK_ICODE_RX_NASA36 | \ + MSK_ICODE_RX_NASA36_DC \ +) + +/** + * @brief A mask of IRIG RX formats with 1000 bps data rate + */ +#define MSK_ICODE_RX_1000BPS \ +( \ + MSK_ICODE_RX_A132_A133 | \ + MSK_ICODE_RX_A002_A003 | \ + MSK_ICODE_RX_A136_A137 | \ + MSK_ICODE_RX_A006_A007 \ +) + +/** + * @brief A mask of IRIG RX formats with 10 kbps data rate + */ +#define MSK_ICODE_RX_10000BPS \ +( \ + MSK_ICODE_RX_G142 | \ + MSK_ICODE_RX_G002 | \ + MSK_ICODE_RX_G146 | \ + MSK_ICODE_RX_G006 \ +) + +/** + * @brief A mask of IRIG RX formats supporting 10ths of seconds + */ +#define MSK_ICODE_RX_HAS_SEC10THS \ +( \ + MSK_ICODE_RX_A132_A133 | \ + MSK_ICODE_RX_A002_A003 | \ + MSK_ICODE_RX_G142 | \ + MSK_ICODE_RX_G002 | \ + MSK_ICODE_RX_A136_A137 | \ + MSK_ICODE_RX_A006_A007 | \ + MSK_ICODE_RX_G146 | \ + MSK_ICODE_RX_G006 \ +) + +/** + * @brief A mask of IRIG RX formats which support 100ths of seconds + */ +#define MSK_ICODE_RX_HAS_SEC100THS \ +( \ + MSK_ICODE_RX_G142 | \ + MSK_ICODE_RX_G002 | \ + MSK_ICODE_RX_G146 | \ + MSK_ICODE_RX_G006 \ +) + +/** + * @brief A mask of IRIG RX formats supporting a 2 digit year number after P5 + * + * Note: This macro specifies ONLY the codes where the year number + * is transmitted after position identifier P5. + * + * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 + * @see ::MSK_ICODE_RX_HAS_ANY_SHORT_YEAR + */ +#define MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 \ +( \ + MSK_ICODE_RX_AFNOR | \ + MSK_ICODE_RX_AFNOR_DC | \ + MSK_ICODE_RX_IEEE1344 | \ + MSK_ICODE_RX_IEEE1344_DC | \ + MSK_ICODE_RX_B126_B127 | \ + MSK_ICODE_RX_B006_B007 | \ + MSK_ICODE_RX_C37118 | \ + MSK_ICODE_RX_C37118_DC | \ + MSK_ICODE_RX_A136_A137 | \ + MSK_ICODE_RX_A006_A007 \ +) + +/** + * @brief A mask of IRIG RX formats supporting a 2 digit year number after P6 + * + * Note: This macro specifies ONLY the codes where the year number + * is transmitted after position identifier P6. + * + * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 + * @see ::MSK_ICODE_RX_HAS_ANY_SHORT_YEAR + */ +#define MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 \ +( \ + MSK_ICODE_RX_G146 | \ + MSK_ICODE_RX_G006 \ +) + +/** + * @brief A mask of IRIG RX formats providing any 2 digit year number + * + * Note: Different sets of code frames may provide a year number + * in different locations of the transmitted code. + * + * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 + * @see ::MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 + */ +#define MSK_ICODE_RX_HAS_ANY_SHORT_YEAR \ +( \ + MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P5 | \ + MSK_ICODE_RX_HAS_SHORT_YEAR_AFTER_P6 \ +) + + + +/** + * @brief A mask of IRIG RX formats supporting TFOM time quality indicator + */ +#define MSK_ICODE_RX_HAS_TFOM \ +( \ + MSK_ICODE_RX_IEEE1344 | \ + MSK_ICODE_RX_IEEE1344_DC | \ + MSK_ICODE_RX_C37118 | \ + MSK_ICODE_RX_C37118_DC \ +) + +/** + * @brief A mask of IRIG RX formats supporting CTQ continuous time quality + * + * This has been introduced in IEEE C37.118.1-2011 + */ +#define MSK_ICODE_RX_HAS_CTQ \ +( \ + MSK_ICODE_RX_IEEE1344 | \ + MSK_ICODE_RX_IEEE1344_DC | \ + MSK_ICODE_RX_C37118 | \ + MSK_ICODE_RX_C37118_DC \ +) + +/** + * @brief A mask of IRIG RX formats supporting time zone information + */ +#define MSK_ICODE_RX_HAS_TZI \ +( \ + MSK_ICODE_RX_IEEE1344 | \ + MSK_ICODE_RX_IEEE1344_DC | \ + MSK_ICODE_RX_C37118 | \ + MSK_ICODE_RX_C37118_DC \ +) + +/** + * @brief IRIG RX formats where %UTC offset must be subtracted to yield %UTC + * + * A mask of IRIG formats where the decoded %UTC offset must be + * subtracted from the time decoded from the IRIG signal to yield %UTC, e.g.:<br> + * (IRIG time 14:43:27 h) - (offs -6 h) = (%UTC 20:43:27) + */ +#define MSK_ICODE_RX_UTC_OFFS_SUB \ +( \ + MSK_ICODE_RX_IEEE1344 | \ + MSK_ICODE_RX_IEEE1344_DC \ +) + +/** + * @brief IRIG RX formats where %UTC offset must be added to yield %UTC + * + * A mask of IRIG formats where the decoded %UTC offset must be + * added to the time decoded from the IRIG signal to yield %UTC, e.g.:<br> + * (IRIG time 14:43:27 h) + (offs -6 h) = (%UTC 08:43:27) + */ +#define MSK_ICODE_RX_UTC_OFFS_ADD \ +( \ + MSK_ICODE_RX_C37118 | \ + MSK_ICODE_RX_C37118_DC \ +) + +/** + * @brief A mask of IRIG RX formats supporting a day of week number + */ +#define MSK_ICODE_RX_HAS_AFNOR_WDAY \ +( \ + MSK_ICODE_RX_AFNOR | \ + MSK_ICODE_RX_AFNOR_DC \ +) + +/** + * @brief A mask of IRIG RX formats supporting a date (day-of-month, month) + */ +#define MSK_ICODE_RX_HAS_AFNOR_DATE \ +( \ + MSK_ICODE_RX_AFNOR | \ + MSK_ICODE_RX_AFNOR_DC \ +) + + +/** + * @brief The default mask of IRIG RX formats supported by IRIG receivers + * + * @note The formats which are actually supported should be retrieved + * from the device + */ +#if !defined( SUPP_MSK_ICODE_RX ) + #define SUPP_MSK_ICODE_RX \ + ( \ + MSK_ICODE_RX_B122_B123 | \ + MSK_ICODE_RX_A132_A133 | \ + MSK_ICODE_RX_B002_B003 | \ + MSK_ICODE_RX_A002_A003 | \ + MSK_ICODE_RX_AFNOR | \ + MSK_ICODE_RX_AFNOR_DC \ + ) +#endif + +/** @} defgroup group_icode */ + + + +/** + * @brief Configuration settings of an IRIG input or output + * + * @see @ref group_icode + */ +typedef struct +{ + uint16_t icode; ///< IRIG signal code, see ::ICODE_RX_CODES and ::ICODE_TX_CODES + uint16_t flags; ///< See ::IFLAGS_BIT_MASKS + +} IRIG_SETTINGS; + +#define _mbg_swab_irig_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->icode ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Flag bits used to define ::IFLAGS_BIT_MASKS + * + * @see ::IFLAGS_BIT_MASKS + */ +enum IFLAGS_BITS +{ + IFLAGS_BIT_DISABLE_TFOM, ///< for RX ignore, for TX don't generate TFOM flag + IFLAGS_BIT_TX_GEN_LOCAL_TIME, ///< TX output local time instead of %UTC + N_IFLAGS_BITS ///< number of known bits +}; + + +/** + * @brief Bit masks used with ::IRIG_SETTINGS::flags + * + * @note The presence or absence of the ::IFLAGS_DISABLE_TFOM flag for the IRIG RX + * settings of some PCI cards may not be evaluated correctly by some firmware + * versions for those cards, even if an IRIG code has been configured which supports + * this flag. See the comments near the declaration of the ::_pcps_incoming_tfom_ignored + * macro in pcpsdev.h for details. + * + * @see ::IFLAGS_BITS + */ +enum IFLAGS_BIT_MASKS +{ + IFLAGS_DISABLE_TFOM = ( 1UL << IFLAGS_BIT_DISABLE_TFOM ), ///< See ::IFLAGS_BIT_DISABLE_TFOM + IFLAGS_TX_GEN_LOCAL_TIME = ( 1UL << IFLAGS_BIT_TX_GEN_LOCAL_TIME ), ///< See ::IFLAGS_BIT_TX_GEN_LOCAL_TIME + + IFLAGS_MASK = ( ( 1UL << N_IFLAGS_BITS ) - 1 ) ///< mask of all known flags +}; + + +/** + * @brief Current IRIG settings and supported codes + * + * Used to query the current IRIG settings + * plus a mask of supported codes. + */ +typedef struct +{ + IRIG_SETTINGS settings; ///< current settings + uint32_t supp_codes; ///< see @ref ICODE_TX_MASKS and @ref ICODE_RX_MASKS + +} IRIG_INFO; + +#define _mbg_swab_irig_info( _p ) \ +do \ +{ \ + _mbg_swab_irig_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_codes ); \ +} while ( 0 ) + + +/** + * @defgroup group_irig_comp IRIG input delay compensation + * + * These definitions are used with IRIG RX delay compensation + * which is supported by some IRIG receivers. Delay compensation + * depends on the basic frame type, so there are different records + * required for the different frame type groups. + * + * @{ */ + +/** + * The number of coefficients of a compensation record + * for a single frame type group, and the structure + * which contains those coefficients. + */ +#define N_IRIG_RX_COMP_VAL 4 + +/** + * @brief A structure used to store compensation values + */ +typedef struct +{ + /** + * @brief Delay compensation values [100 ns units] + * + * @note Only the first value is actually used to compensate + * a delay, so the remaining values should be 0. + */ + int16_t c[N_IRIG_RX_COMP_VAL]; + +} IRIG_RX_COMP; + +#define _mbg_swab_irig_rx_comp( _p ) \ +do \ +{ \ + int i; \ + for ( i = 0; i < N_IRIG_RX_COMP_VAL; i++ ) \ + _mbg_swab16( &(_p)->c[i] ); \ +} while ( 0 ) + + +/** The absolute value of the maximum compensation value accepted by a device */ +#define IRIG_RX_COMP_MAX 999 // [100 ns units], i.e. valid range is +/-99.9 us + + + +/** + * @brief Structure used to retrieve the number of records for a given type + */ +typedef struct +{ + uint16_t type; ///< Record type, see ::CAL_REC_TYPES + uint16_t idx; ///< Index if several records of same type are supported, see ::IRIG_RX_COMP_GROUPS + +} CAL_REC_HDR; + +#define _mbg_swab_cal_rec_hdr( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->type ); \ + _mbg_swab16( &(_p)->idx ); \ +} while ( 0 ) + + +/** + * @brief Types to be used with ::CAL_REC_HDR::type + */ +enum CAL_REC_TYPES +{ + CAL_REC_TYPE_UNDEF, ///< undefined type + CAL_REC_TYPE_IRIG_RX_COMP, ///< IRIG receiver delay compensation + N_CAL_REC_TYPE ///< number of known types +}; + + +/** + * @brief Types to be used with ::CAL_REC_HDR::idx + * + * IRIG frame type groups to be distinguished for delay compensation. + */ +enum IRIG_RX_COMP_GROUPS +{ + IRIG_RX_COMP_B1, ///< codes B1xx, AFNOR, IEEE1344 + IRIG_RX_COMP_A1, ///< code A1xx + IRIG_RX_COMP_B0, ///< codes B0xx, AFNOR DC, IEEE1344 DC + IRIG_RX_COMP_A0, ///< code A0xx + IRIG_RX_COMP_G1, ///< code G14x + IRIG_RX_COMP_G0, ///< code G00x + N_IRIG_RX_COMP ///< number of compensation values +}; + + +/** + * @brief Initializers for format name strings + */ +#define DEFAULT_IRIG_RX_COMP_NAMES \ +{ \ + "B1xx/AFNOR/IEEE1344", \ + "A1xx", \ + "B0xx/AFNOR DC/IEEE1344 DC", \ + "A0xx", \ + "G14X", \ + "G00X", \ +} + + + +/** + * @brief Structure used to transfer calibration records + */ +typedef struct +{ + CAL_REC_HDR hdr; ///< data header + IRIG_RX_COMP comp_data; ///< IRIG receiver delay compensation + +} CAL_REC_IRIG_RX_COMP; + +#define _mbg_swab_cal_rec_irig_rx_comp( _p ) \ +do \ +{ \ + _mbg_swab_cal_rec_hdr( &(_p)->hdr ); \ + _mbg_swab_irig_rx_comp( &(_p)->comp_data ); \ +} while ( 0 ) + +/** @} defgroup group_irig_comp */ + + + +/** + * @brief A data type used to read the debug status of the device. + * + * @note This also includes IRIG decoder status. + * + * @see @ref MBG_DEBUG_STATUS_BIT_MASKS + */ +typedef uint32_t MBG_DEBUG_STATUS; + +#define _mbg_swab_debug_status( _p ) \ + _mbg_swab32( _p ) + + + +/** + * @brief Enumeration of flag bits used for debug status + * + * @see @ref MBG_DEBUG_STATUS_BIT_MASKS + */ +enum MBG_DEBUG_STATUS_BITS +{ + MBG_IRIG_BIT_WARMED_UP, ///< Osc has warmed up + MBG_IRIG_BIT_PPS_ACTIVE, ///< PPS output is active + MBG_IRIG_BIT_INV_CONFIG, ///< Invalid config, e.g. data csum error + MBG_IRIG_BIT_MSG_DECODED, ///< IRIG msg could be decoded + MBG_IRIG_BIT_MSG_INCONSISTENT, ///< IRIG msg contains inconsistent data + MBG_IRIG_BIT_LOOP_LOCKED, ///< Decoder control loop is locked + MBG_IRIG_BIT_JITTER_TOO_LARGE, ///< Phase jitter too large + MBG_IRIG_BIT_INV_REF_OFFS, ///< %UTC ref offset not configured + + MBG_SYS_BIT_INV_TIME, ///< Internal time not valid/set + MBG_SYS_BIT_TIME_SET_VIA_API, ///< On board time set externally + MBG_SYS_BIT_INV_RTC, ///< On board RTC invalid + MBG_SYS_BIT_CPU_PLL_FAILED, ///< The CPU's PLL watchdog + + N_MBG_DEBUG_BIT ///< The number of known bits +}; + +/** + * @brief Initializers for debug status bit strings + * + * @see ::MBG_DEBUG_STATUS_BITS + */ +#define MBG_DEBUG_STATUS_STRS \ +{ \ + "Osc has warmed up", \ + "PPS output is active", \ + "Config set to default", \ + "IRIG msg decoded", \ + "IRIG msg not consistent", \ + "Decoder control loop locked", \ + "Phase jitter too large", \ + "Invalid ref offset", \ + \ + "Internal time not valid", \ + "On board time set via API", \ + "On board RTC invalid", \ + "CPU PLL failure, needs restart" \ +} + + +/** + * @brief Bit masks used with ::MBG_DEBUG_STATUS + * + * @see ::MBG_DEBUG_STATUS_BITS + * + * @anchor MBG_DEBUG_STATUS_BIT_MASKS @{ */ + +#define MBG_IRIG_MSK_WARMED_UP ( 1UL << MBG_IRIG_BIT_WARMED_UP ) +#define MBG_IRIG_MSK_PPS_ACTIVE ( 1UL << MBG_IRIG_BIT_PPS_ACTIVE ) +#define MBG_IRIG_MSK_INV_CONFIG ( 1UL << MBG_IRIG_BIT_INV_CONFIG ) +#define MBG_IRIG_MSK_MSG_DECODED ( 1UL << MBG_IRIG_BIT_MSG_DECODED ) +#define MBG_IRIG_MSK_MSG_INCONSISTENT ( 1UL << MBG_IRIG_BIT_MSG_INCONSISTENT ) +#define MBG_IRIG_MSK_LOOP_LOCKED ( 1UL << MBG_IRIG_BIT_LOOP_LOCKED ) +#define MBG_IRIG_MSK_JITTER_TOO_LARGE ( 1UL << MBG_IRIG_BIT_JITTER_TOO_LARGE ) +#define MBG_IRIG_MSK_INV_REF_OFFS ( 1UL << MBG_IRIG_BIT_INV_REF_OFFS ) + +#define MBG_SYS_MSK_INV_TIME ( 1UL << MBG_SYS_BIT_INV_TIME ) +#define MBG_SYS_MSK_TIME_SET_VIA_API ( 1UL << MBG_SYS_BIT_TIME_SET_VIA_API ) +#define MBG_SYS_MSK_INV_RTC ( 1UL << MBG_SYS_BIT_INV_RTC ) +#define MBG_SYS_MSK_CPU_PLL_FAILED ( 1UL << MBG_SYS_BIT_CPU_PLL_FAILED ) + +/** @} anchor MBG_DEBUG_STATUS_BIT_MASKS */ + + +/** + * @brief A data type used to configure the ref offset + * + * The ref offset if the offset of the incoming reference time from %UTC. + * For some types of signal (e.g. most IRIG frame formats) this can't be + * determined automatically. + * + * Valid range: -::MBG_REF_OFFS_MAX..::MBG_REF_OFFS_MAX, or ::MBG_REF_OFFS_NOT_CFGD + * + * @note There's a special flag ::MBG_REF_OFFS_NOT_CFGD indicating that + * this parameter is unconfigured, in which case a Meinberg time code + * receiver refuses to synchronize to the time code signal unless a time + * code frame has been configured which provides the %UTC offset (namely + * IEEE 1344 or IEEE C37.118). + */ +typedef int16_t MBG_REF_OFFS; + +#define _mbg_swab_mbg_ref_offs( _p ) _mbg_swab16( (_p) ) + + +/** + * @brief The maximum allowed positive / negative ref offset + */ +#define MBG_REF_OFFS_MAX ( ( 12L * 60 ) + 30 ) // [minutes] + +/** + * @brief A flag indicating that the ref offset has not yet been configured + * + * If this flag is set in ::MBG_REF_OFFS this means the ref offset + * (time offset from %UTC) has not yet been configured. This is usually + * the case for IRIG receiver devices right after they have been shipped. + */ +#define MBG_REF_OFFS_NOT_CFGD ( (MBG_REF_OFFS) 0x8000 ) + + + +/** + * @brief A structure used to configure optional settings + * + * Optional settings are a generic way to configure some extended settings. + */ +typedef struct +{ + uint32_t flags; ///< @see ::MBG_OPT_FLAGS + +} MBG_OPT_SETTINGS; + +#define _mbg_swab_mbg_opt_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + +/** + * @brief A structure used to configure optional settings + * + * This structure includes the current settings, and a bit mask + * indicating which flags are supported. + */ +typedef struct +{ + MBG_OPT_SETTINGS settings; ///< current settings + uint32_t supp_flags; ///< bit mask of supported flags, see ::MBG_OPT_FLAGS + +} MBG_OPT_INFO; + +#define _mbg_swab_mbg_opt_info( _p ) \ +do \ +{ \ + _mbg_swab_mbg_opt_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + +/** + * @brief Enumeration of flag bits used to define ::MBG_OPT_FLAGS + */ +enum MBG_OPT_BITS +{ + MBG_OPT_BIT_STR_UTC, ///< serial time string contains %UTC time + MBG_OPT_BIT_EMU_SYNC, ///< always pretend to be synchronized, alternatively ::GPS_FEAT_IGNORE_LOCK may be supported + N_MBG_OPT_BIT +}; + + +/** + * @brief Bit masks according to ::MBG_OPT_BITS + * + * Used with ::MBG_OPT_SETTINGS::flags and ::MBG_OPT_INFO::supp_flags. + */ +enum MBG_OPT_FLAGS +{ + MBG_OPT_FLAG_STR_UTC = ( 1UL << MBG_OPT_BIT_STR_UTC ), ///< See ::MBG_OPT_BIT_STR_UTC + MBG_OPT_FLAG_EMU_SYNC = ( 1UL << MBG_OPT_BIT_EMU_SYNC ) ///< See ::MBG_OPT_BIT_EMU_SYNC +}; + + + +/** + * @brief Bit coded return type for ::PCPS_GET_IRIG_CTRL_BITS + * + * The control bits a time code receiver has decoded from + * the incoming time code signal. + * + * @note ::MBG_RAW_IRIG_DATA is more versatile and should + * be used preferably, if supported. + * + * @see ::MBG_RAW_IRIG_DATA + */ +typedef uint32_t MBG_IRIG_CTRL_BITS; + +#define _mbg_swab_irig_ctrl_bits( _p ) _mbg_swab32( _p ) + + +/** + * @brief Extract the TFOM code from ::MBG_IRIG_CTRL_BITS + * + * The resulting code is only valid if the configured IRIG code frame format + * supports this. See @ref MSK_ICODE_TX_HAS_TFOM and @ref MSK_ICODE_RX_HAS_TFOM + * + * As specified in the IEEE 1344 standard as "Time Quality", the TFOM code is + * the range 0x0 (locked, maximum accuracy) to 0xF (failed, data unreliable). + */ +#define _pcps_tfom_from_irig_ctrl_bits( _p ) \ + ( ( ( *(_p) ) >> 24 ) & 0x0F ) + + + +#define RAW_IRIG_SIZE 16 + +/** + * @brief A buffer used to read raw IRIG data bits from an IRIG receiver + * + * Used to get the raw data bits from the IRIG decoder. A maximum number + * of ::RAW_IRIG_SIZE bytes can be filled up, depending on the IRIG code. + * If less bytes are used then the rest of the bytes are filled with zeros. + * + * @note The first IRIG bit received from the transmitter is saved + * in the MSB (bit 7) of data_bytes[0], etc. + */ +typedef struct +{ + uint8_t data_bytes[RAW_IRIG_SIZE]; + +} MBG_RAW_IRIG_DATA; + +#define _mbg_swab_mbg_raw_irig_data( _p ) _nop_macro_fnc() + +/** + * @brief Extract the TFOM code from ::MBG_RAW_IRIG_DATA + * + * The resulting code is only valid if the configured IRIG code frame format + * supports this. See @ref MSK_ICODE_TX_HAS_TFOM and @ref MSK_ICODE_RX_HAS_TFOM + * + * As specified in the IEEE 1344 standard as "Time Quality", the TFOM code is + * the range 0x0 (locked, maximum accuracy) to 0xF (failed, data unreliable). + */ +#define _pcps_tfom_from_raw_irig_data( _p ) \ + ( ( ( (_p)->data_bytes[9] >> 2 ) & 0x08 ) \ + | ( ( (_p)->data_bytes[9] >> 4 ) & 0x04 ) \ + | ( ( (_p)->data_bytes[9] >> 6 ) & 0x02 ) \ + | ( ( (_p)->data_bytes[8] & 0x01 ) ) ) + + + +/** + * @defgroup group_time_scale Time Scale Configuration + * + * Used to configure the basic time scale of the GPS receiver. + * By default this is %UTC which can optionally be converted + * to some local time. However, some applications prefer + * TAI or pure GPS time. This can be configured using the + * structures below if the ::GPS_HAS_TIME_SCALE flag is set + * in ::RECEIVER_INFO::features. + * + * @{ */ + +/** + * @brief Known time scales + * + * @see ::MBG_TIME_SCALE_MASKS + * @see ::TM_SCALE_GPS + * @see ::TM_SCALE_TAI + */ +enum MBG_TIME_SCALES +{ + MBG_TIME_SCALE_DEFAULT, ///< %UTC or local time according to ::UTC parameters and ::TZDL configuration + MBG_TIME_SCALE_GPS, ///< GPS time as sent by the satellites, monotonical + MBG_TIME_SCALE_TAI, ///< TAI, i.e. GPS time plus constant offset (see ::GPS_TAI_OFFSET) + N_MBG_TIME_SCALE +}; + +/** + * @brief Bit masks for known time scales + * + * @see ::MBG_TIME_SCALES + */ +enum MBG_TIME_SCALE_MASKS +{ + MBG_TIME_SCALE_MSK_DEFAULT = ( 1UL << MBG_TIME_SCALE_DEFAULT ), ///< See ::MBG_TIME_SCALE_DEFAULT + MBG_TIME_SCALE_MSK_GPS = ( 1UL << MBG_TIME_SCALE_GPS ), ///< See ::MBG_TIME_SCALE_GPS + MBG_TIME_SCALE_MSK_TAI = ( 1UL << MBG_TIME_SCALE_TAI ) ///< See ::MBG_TIME_SCALE_TAI +}; + +#define MBG_TIME_SCALE_STRS \ +{ \ + "UTC/local", \ + "GPS", \ + "TAI" \ +} + + + +/** + * @brief The constant time offset between the GPS and TAI time scales, in seconds + */ +#define GPS_TAI_OFFSET 19 ///< [s], TAI = GPS + GPS_TAI_OFFSET + + +/** + * @brief Time scale configuration settings + */ +typedef struct +{ + uint8_t scale; ///< current time scale code, see ::MBG_TIME_SCALES + uint8_t flags; ///< reserved, don't use, currently always 0 + +} MBG_TIME_SCALE_SETTINGS; + +#define _mbg_swab_mbg_time_scale_settings( _p ) \ + _nop_macro_fnc() + + +/** + * @brief Time scale configuration settings plus capabilities + */ +typedef struct +{ + MBG_TIME_SCALE_SETTINGS settings; ///< current settings + MBG_TIME_SCALE_SETTINGS max_settings; ///< number of scales, all supported flags + uint32_t supp_scales; ///< bit masks of supported scales, see ::MBG_TIME_SCALE_MASKS + +} MBG_TIME_SCALE_INFO; + +#define _mbg_swab_mbg_time_scale_info( _p ) \ +do \ +{ \ + _mbg_swab_mbg_time_scale_settings( &(_p)->settings ); \ + _mbg_swab_mbg_time_scale_settings( &(_p)->max_settings ); \ + _mbg_swab32( &(_p)->supp_scales ); \ +} while ( 0 ) + +/** @} defgroup group_time_scale */ + + + +/** + * @defgroup group_pout_api Programmable Output API + * + * These structures below are used to configure the programmable + * pulse outputs which are provided by some GPS receivers. + * The number of programmable pulse outputs supported by a GPS + * receiver is reported in the RECEIVER_INFO::n_prg_out field. + * + * @{ */ + + +/** + * @brief A calendar date including full year number + */ +typedef struct +{ + uint8_t mday; ///< 1..28,29,30,31 + uint8_t month; ///< 1..12 + uint16_t year; ///< including century + +} MBG_DATE; + +#define _mbg_swab_mbg_date( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->year ); \ +} while ( 0 ) + + +/** + * @brief The time of day including hundredths of seconds + */ +typedef struct +{ + uint8_t hour; ///< 0..23 + uint8_t min; ///< 0..59 + uint8_t sec; ///< 0..59,60 + uint8_t sec100; ///< 100ths of seconds + +} MBG_TIME; + +#define _mbg_swab_mbg_time( _p ) \ + _nop_macro_fnc() // nothing to swap + + +/** + * @brief Date and time specification for switching operations + */ +typedef struct +{ + MBG_DATE d; ///< date to switch + MBG_TIME t; ///< time to switch + uint8_t wday; ///< reserved, currently always 0 + uint8_t flags; ///< reserved, currently 0 + +} MBG_DATE_TIME; + +#define _mbg_swab_mbg_date_time( _p ) \ +do \ +{ \ + _mbg_swab_mbg_date( &(_p)->d ); \ + _mbg_swab_mbg_time( &(_p)->t ); \ +} while ( 0 ) + + +/** + * @brief A structure to define on/off cycle times + * + * @note Eventually the ::MBG_TIME::sec100 fields in + * ::POUT_TIME:on and ::POUT_TIME:off are not evaluated + * by the firmware in ::POUT_TIMER mode, and thus + * should be set to 0 for this mode. + */ +typedef struct +{ + MBG_DATE_TIME on; ///< date and time to switch on + MBG_DATE_TIME off; ///< date and time to switch off + +} POUT_TIME; + +#define _mbg_swab_pout_time( _p ) \ +do \ +{ \ + _mbg_swab_mbg_date_time( &(_p)->on ); \ + _mbg_swab_mbg_date_time( &(_p)->off ); \ +} while ( 0 ) + + + +/** + * @brief The number of ::POUT_TIME settings for each programmable pulse output + * + * @note This can't be changed without breaking compatibility of the API + */ +#define N_POUT_TIMES 3 + +/** + * @brief A Generic data field for programmable output settings + */ +typedef union +{ + /// Switching times. See ::POUT_MODES_DATA_TM, ::POUT_MODES_DATA_TM_0 + POUT_TIME tm[N_POUT_TIMES]; + + uint8_t b[N_POUT_TIMES * sizeof( POUT_TIME )]; + + /// Only if ::POUT_SUPP_PULSE_SHIFT is set, this field can be used to + /// configure the time interval in [ns] by which output pulse slopes are + /// to be shifted. The configured pulse shift must be in the range + /// ::DEFAULT_POUT_PULSE_SHIFT_MIN through ::DEFAULT_POUT_PULSE_SHIFT_MAX. + /// The resolution / steps at which the pulse shift interval can be configured + /// is returned in ::POUT_INFO::pulse_shift_res. + /// @see ::POUT_MODES_DATA_PULSE_SHIFT + int32_t pulse_shift; + +} POUT_DATA; + +#define DEFAULT_POUT_PULSE_SHIFT_MIN -500000000L ///< Default minimum value for ::POUT_DATA::pulse_shift, in [ns] +#define DEFAULT_POUT_PULSE_SHIFT_MAX 499000000L ///< Default maximum value for ::POUT_DATA::pulse_shift, in [ns] + + +/** + * @brief Convert ::POUT_DATA endianess depending on the mode + * + * Assuming the mode is passed to the macro with correct endianess. + */ +#define _mbg_swab_pout_data( _p, _mode ) \ +do \ +{ \ + uint32_t mode_mask = 1UL << _mode; \ + \ + if ( mode_mask & POUT_MODES_DATA_TM ) \ + { \ + int i; \ + \ + for ( i = 0; i < N_POUT_TIMES; i++ ) \ + _mbg_swab_pout_time( &(_p)->tm[i] ); \ + } \ + else \ + { \ + if ( mode_mask & POUT_MODES_DATA_TM_0 ) \ + _mbg_swab_pout_time( &(_p)->tm[0] ); \ + else \ + if ( mode_mask & POUT_MODES_DATA_PULSE_SHIFT ) \ + _mbg_swab32( &(_p)->pulse_shift ); \ + } \ + \ +} while ( 0 ) + + + +/** + * @brief Configuration settings for a single programmable pulse output + */ +typedef struct +{ + uint16_t mode; ///< Mode of operation, see ::POUT_MODES + uint16_t mode_param; ///< Optional parameter depending on the mode, see @ref POUT_MODES_PARAM_MASKS + + /// @brief Timeout [min] which can be specified for some modes, see ::POUT_MODES_TIMEOUT, ::MAX_POUT_DCF_TIMOUT. + /// + /// If the clock looses synchronization then the output + /// - is disabled ***immediately*** if ::POUT_IF_SYNC_ONLY is set in #flags + /// - is disabled after #timeout, if #timeout is not 0 (see ::MAX_POUT_DCF_TIMOUT) + /// - stays enabled if #timeout is 0 ***and*** ::POUT_IF_SYNC_ONLY is ***not*** set in #flags + uint16_t timeout; + + uint16_t flags; ///< @see ::POUT_SETTINGS_FLAGS + POUT_DATA pout_data; ///< Additional configuration data, see ::POUT_DATA + +} POUT_SETTINGS; + +/** + * @brief Convert ::POUT_SETTINGS endianess after reading from a device + */ +#define _mbg_swab_pout_settings_on_get( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->mode ); \ + _mbg_swab16( &(_p)->mode_param ); \ + _mbg_swab16( &(_p)->timeout ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab_pout_data( &(_p)->pout_data, (_p)->mode ); \ +} while ( 0 ) + +/** + * @brief Convert ::POUT_SETTINGS endianess before writing to a device + */ +#define _mbg_swab_pout_settings_on_set( _p ) \ +do \ +{ \ + _mbg_swab_pout_data( &(_p)->pout_data, (_p)->mode ); \ + _mbg_swab16( &(_p)->mode ); \ + _mbg_swab16( &(_p)->mode_param ); \ + _mbg_swab16( &(_p)->timeout ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Definitions used with ::POUT_TIME_SLOTS mode + * + * If ::POUT_SETTINGS::mode is set to ::POUT_TIME_SLOTS then the number + * of time slots per minute is stored in ::POUT_SETTINGS::mode_param. + * Valid numbers are all numbers n in the range ::MIN_TIME_SLOTS_PER_MINUTE + * to ::MAX_TIME_SLOTS_PER_MINUTE for which the remainder of 60 / n is 0. + * @see ::POUT_MODES_MODE_PARAM_AS_SLOTS_PER_MIN + * + * @anchor POUT_TIME_SLOTS_MODE_DEFS @{ */ + +#define MIN_TIME_SLOTS_PER_MINUTE 1 +#define MAX_TIME_SLOTS_PER_MINUTE 60 +#define TIME_SLOT_REGISTER_IN_SEC 60 + +#define TIMEOUT_DIVIDED_BY 10 +#define TIME_SLOT_SWITCH_OFF_BUFFER_MIN 50 / TIMEOUT_DIVIDED_BY +#define TIME_SLOT_SWITCH_OFF_BUFFER_MAX 500 / TIMEOUT_DIVIDED_BY +#define TIME_SLOT_SWITCH_OFF_BUFFER_STD 500 / TIMEOUT_DIVIDED_BY +#define TIME_SLOT_SWITCH_OFF_BUFFER_STEP_SIZE 50 / TIMEOUT_DIVIDED_BY + +#define _valid_time_slots_per_minute( _n ) \ + ( ( (_n) >= MIN_TIME_SLOTS_PER_MINUTE ) && \ + ( (_n) <= MAX_TIME_SLOTS_PER_MINUTE ) && \ + ( ( 60 % (_n) ) == 0 ) \ + ) + +/** @} anchor POUT_TIME_SLOTS_MODE_DEFS */ + + + +#define MAX_POUT_PULSE_LEN 1000 ///< 10 secs, in 10 msec units +#define MAX_POUT_DCF_TIMOUT ( 48 * 60 ) ///< 48 hours, in minutes + + + +/** + * @brief Enumeration of known operation modes for programmable pulse outputs + * + * These codes are used with ::POUT_SETTINGS::mode. One or more of + * the remaining fields in ::POUT_SETTINGS are evaluated depending + * on the selected mode. Unused fields should be set to 0. + * + * Unless ::POUT_NOT_INVERTIBLE is set in ::POUT_INFO::flags + * the output signal level can be inverted if ::POUT_INVERTED + * is set in ::POUT_SETTINGS::flags. + * + * @note Not every programmable pulse output supports all modes. + * + * @see @ref POUT_MODE_MASKS + * @see @ref POUT_MODES_PARAM_MASKS + * @see @ref ENG_POUT_NAMES + * @see @ref ENG_POUT_HINTS + */ +enum POUT_MODES +{ + /// Output is normally always 'off', or always 'on' in case + /// flag ::POUT_INVERTED is set in ::POUT_SETTINGS::flags. + POUT_IDLE, + + /// Switch 'on' or 'off' at the times specified in ::POUT_DATA::tm. + /// + /// @note Eventually the ::MBG_TIME::sec100 fields in + /// ::POUT_TIME:on and ::POUT_TIME:off are not evaluated + /// by the firmware in ::POUT_TIMER mode, and thus + /// should be always set to 0 in this mode. + POUT_TIMER, + + /// Generate a pulse at the time specified in the tm[0].on field + /// in ::POUT_SETTINGS::pout_data. + /// Pulse length as specified in ::POUT_SETTINGS::mode_param, + /// in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_SINGLE_SHOT, + + /// Generate a cyclic pulse at the time specified in the tm[0].on.t + /// field in ::POUT_SETTINGS::pout_data. + /// Pulse length as specified in ::POUT_SETTINGS::mode_param, + /// in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_CYCLIC_PULSE, + + /// Generate a pulse whenever the second changes. + /// Pulse length as specified in ::POUT_SETTINGS::mode_param, + /// in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_PER_SEC, + + /// Generate a pulse whenever the minute changes. + /// Pulse length as specified in ::POUT_SETTINGS::mode_param, + /// in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_PER_MIN, + + /// Generate a pulse whenever the hour changes. + /// Pulse length as specified in ::POUT_SETTINGS::mode_param, + /// in [10 ms] units. + /// See ::MAX_POUT_PULSE_LEN. + POUT_PER_HOUR, + + /// Generate DCF77-compatible second marks. + /// Pulse length according to the DCF77 specifications. + /// See ::POUT_DCF77_M59, ::POUT_SETTINGS::timeout and ::MAX_POUT_DCF_TIMOUT. + POUT_DCF77, + + /// Output switched on if receiver position verified (condition nav_solved). + POUT_POS_OK, + + /// Output switched on if time synchronized (condition time_syn). + POUT_TIME_SYNC, + + /// Output switched on if both position verified and time synchronized. + POUT_ALL_SYNC, + + /// IRIG/AFNOR DCLS time code signal mapped to this output. + POUT_TIMECODE, + + /// Serial time string of one one of the serial ports mapped to this output. + /// ::POUT_SETTINGS::mode_param contains the number of the COM port. + /// See ::MAX_POUT_TIMESTR_PORTS. + POUT_TIMESTR, + + /// 10 MHz fixed frequency output. + POUT_10MHZ, + + /// DCF77-like signal with extra 500 ms pulse in the 59th second + /// (the original DCF77 signal has no such pulse). See ::POUT_DCF77, + /// ::POUT_SETTINGS::timeout and ::MAX_POUT_DCF_TIMOUT. + POUT_DCF77_M59, + + /// Output signal generated by the programmable frequency synthesizer. + POUT_SYNTH, + + /// Programmable time slots during each minute. + /// ::POUT_SETTINGS::mode_param specifies the time slots per minute. + /// Uses ::POUT_DATA. ::TODO + POUT_TIME_SLOTS, + + /// A GPIO input or output signal is reflected at this pulse output. + /// ::POUT_SETTINGS::mode_param specifies the GPIO number which must + /// be in the range 0..::MBG_GPIO_CFG_LIMITS::num_io. + POUT_GPIO, + + /// A 1 PPS signal with a fixed 20 us pulse length + POUT_PTTI_PPS, + + /// A HaveQuick signal as configured in ::HAVEQUICK_SETTINGS::format + POUT_HAVEQUICK, + + // New modes have to be added here at the end of the enumeration, and the + // POUT_MODE_MASKS, the POUT_MODES_PARAM_MASKS as well as string initializers + // (also in pcpslstr.h) have to be updated accordingly. + N_POUT_MODES ///< the number of known modes +}; + + +/** + * @brief Bit masks associated with ::POUT_MODES + * + * Used with ::POUT_INFO::supp_modes to specify which ::POUT_MODES + * are supported for a particular programmable output. + * + * @see ::POUT_MODES + * + * @anchor POUT_MODE_MASKS @{ */ + +#define MSK_POUT_IDLE ( 1UL << POUT_IDLE ) ///< See ::POUT_IDLE +#define MSK_POUT_TIMER ( 1UL << POUT_TIMER ) ///< See ::POUT_TIMER +#define MSK_POUT_SINGLE_SHOT ( 1UL << POUT_SINGLE_SHOT ) ///< See ::POUT_SINGLE_SHOT +#define MSK_POUT_CYCLIC_PULSE ( 1UL << POUT_CYCLIC_PULSE ) ///< See ::POUT_CYCLIC_PULSE +#define MSK_POUT_PER_SEC ( 1UL << POUT_PER_SEC ) ///< See ::POUT_PER_SEC +#define MSK_POUT_PER_MIN ( 1UL << POUT_PER_MIN ) ///< See ::POUT_PER_MIN +#define MSK_POUT_PER_HOUR ( 1UL << POUT_PER_HOUR ) ///< See ::POUT_PER_HOUR +#define MSK_POUT_DCF77 ( 1UL << POUT_DCF77 ) ///< See ::POUT_DCF77 +#define MSK_POUT_POS_OK ( 1UL << POUT_POS_OK ) ///< See ::POUT_POS_OK +#define MSK_POUT_TIME_SYNC ( 1UL << POUT_TIME_SYNC ) ///< See ::POUT_TIME_SYNC +#define MSK_POUT_ALL_SYNC ( 1UL << POUT_ALL_SYNC ) ///< See ::POUT_ALL_SYNC +#define MSK_POUT_TIMECODE ( 1UL << POUT_TIMECODE ) ///< See ::POUT_TIMECODE +#define MSK_POUT_TIMESTR ( 1UL << POUT_TIMESTR ) ///< See ::POUT_TIMESTR +#define MSK_POUT_10MHZ ( 1UL << POUT_10MHZ ) ///< See ::POUT_10MHZ +#define MSK_POUT_DCF77_M59 ( 1UL << POUT_DCF77_M59 ) ///< See ::POUT_DCF77_M59 +#define MSK_POUT_SYNTH ( 1UL << POUT_SYNTH ) ///< See ::POUT_SYNTH +#define MSK_POUT_TIME_SLOTS ( 1UL << POUT_TIME_SLOTS ) ///< See ::POUT_TIME_SLOTS +#define MSK_POUT_GPIO ( 1UL << POUT_GPIO ) ///< See ::POUT_GPIO +#define MSK_POUT_PTTI_PPS ( 1UL << POUT_PTTI_PPS ) ///< See ::POUT_PTTI_PPS +#define MSK_POUT_HAVEQUICK ( 1UL << POUT_HAVEQUICK ) ///< See ::POUT_HAVEQUICK + +/** @} anchor POUT_MODE_MASKS */ + + + +/** + * @brief Bit masks indicating which parameters relevant for which ::POUT_MODES + * + * @see ::POUT_MODES + * @see @ref POUT_MODE_MASKS + * + * @anchor POUT_MODES_PARAM_MASKS @{ */ + + +/** + * @brief POUT modes which use the full ::POUT_DATA::tm array as parameter + */ +#define POUT_MODES_DATA_TM \ +( \ + MSK_POUT_TIMER \ +) + + +/** + * @brief POUT modes which use only ::POUT_DATA::tm[0] as parameter + */ +#define POUT_MODES_DATA_TM_0 \ +( \ + MSK_POUT_SINGLE_SHOT | \ + MSK_POUT_CYCLIC_PULSE \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::mode_param as pulse length + * + * @see ::MAX_POUT_PULSE_LEN + */ +#define POUT_MODES_MODE_PARAM_AS_PULSE_LEN \ +( \ + MSK_POUT_SINGLE_SHOT | \ + MSK_POUT_CYCLIC_PULSE | \ + MSK_POUT_PER_SEC | \ + MSK_POUT_PER_MIN | \ + MSK_POUT_PER_HOUR \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::mode_param as COM port index number + */ +#define POUT_MODES_MODE_PARAM_AS_COM_IDX \ +( \ + MSK_POUT_TIMESTR \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::mode_param as time slots per minute + * + * @see @ref POUT_TIME_SLOTS_MODE_DEFS + */ +#define POUT_MODES_MODE_PARAM_AS_SLOTS_PER_MIN \ +( \ + MSK_POUT_TIME_SLOTS \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::mode_param as GPIO index number + */ +#define POUT_MODES_MODE_PARAM_AS_GPIO_IDX \ +( \ + MSK_POUT_GPIO \ +) + + +/** + * @brief POUT modes which use ::POUT_SETTINGS::timeout + */ +#define POUT_MODES_TIMEOUT \ +( \ + MSK_POUT_DCF77 | \ + MSK_POUT_DCF77_M59 \ +) + + +/** + * @brief POUT modes which which support ::POUT_TIMEBASE_UTC + */ +#define POUT_MODES_SUPP_TIMEBASE_UTC \ +( \ + MSK_POUT_DCF77 | \ + MSK_POUT_DCF77_M59 \ +) + + +/** + * @brief POUT modes which use ::POUT_DATA::pulse_shift + * + * @note: Supported only if ::POUT_SUPP_PULSE_SHIFT is set + */ +#define POUT_MODES_DATA_PULSE_SHIFT \ +( \ + MSK_POUT_PER_SEC | \ + MSK_POUT_PER_MIN | \ + MSK_POUT_PER_HOUR \ +) + + +/** + * @brief POUT modes which support ::POUT_SUPP_IF_SYNC_ONLY + * + * Even if ::POUT_SUPP_IF_SYNC_ONLY is set in ::POUT_INFO::flags + * the associated flag ::POUT_IF_SYNC_ONLY in ::POUT_SETTINGS::flags + * may be evaluated depending on the mode. + * + * Modes ::POUT_POS_OK, ::POUT_TIME_SYNC, and ::MSK_POUT_ALL_SYNC + * are explicitly excluded. + * + * For modes ::MSK_POUT_DCF77 and ::MSK_POUT_DCF77_M59 see also + * ::POUT_SETTINGS::timeout. + */ +#define POUT_MODES_SUPP_IF_SYNC_ONLY \ +( \ + MSK_POUT_IDLE | \ + MSK_POUT_TIMER | \ + MSK_POUT_SINGLE_SHOT | \ + MSK_POUT_CYCLIC_PULSE | \ + MSK_POUT_PER_SEC | \ + MSK_POUT_PER_MIN | \ + MSK_POUT_PER_HOUR | \ + MSK_POUT_DCF77 | \ + MSK_POUT_TIMECODE | \ + MSK_POUT_TIMESTR | \ + MSK_POUT_10MHZ | \ + MSK_POUT_DCF77_M59 | \ + MSK_POUT_SYNTH | \ + MSK_POUT_TIME_SLOTS | \ + MSK_POUT_GPIO | \ + MSK_POUT_PTTI_PPS | \ + MSK_POUT_HAVEQUICK \ +) + +/** @} anchor POUT_MODES_PARAM_MASKS */ + + + +/** + * @brief Name strings associated with ::POUT_MODES + * + * Default initializers for English programmable output mode names. + * Initializers for multi-language strings can be found in pcpslstr.h. + * + * @see ::POUT_MODES + * @see ::DEFAULT_ENG_POUT_NAMES + * + * @anchor ENG_POUT_NAMES @{ */ + +#define ENG_POUT_NAME_IDLE "Idle" +#define ENG_POUT_NAME_TIMER "Timer" +#define ENG_POUT_NAME_SINGLE_SHOT "Single Shot" +#define ENG_POUT_NAME_CYCLIC_PULSE "Cyclic Pulse" +#define ENG_POUT_NAME_PER_SEC "Pulse Per Second" +#define ENG_POUT_NAME_PER_MIN "Pulse Per Min" +#define ENG_POUT_NAME_PER_HOUR "Pulse Per Hour" +#define ENG_POUT_NAME_DCF77 "DCF77 Marks" +#define ENG_POUT_NAME_POS_OK "Position OK" +#define ENG_POUT_NAME_TIME_SYNC "Time Sync" +#define ENG_POUT_NAME_ALL_SYNC "All Sync" +#define ENG_POUT_NAME_TIMECODE "DCLS Time Code" +#define ENG_POUT_NAME_TIMESTR "Serial Time String" +#define ENG_POUT_NAME_10MHZ "10 MHz Frequency" +#define ENG_POUT_NAME_DCF77_M59 "DCF77-like M59" +#define ENG_POUT_NAME_SYNTH "Synthesizer Frequency" +#define ENG_POUT_NAME_TIME_SLOTS "Time Slots per Minute" +#define ENG_POUT_NAME_GPIO "GPIO Signal" +#define ENG_POUT_PTTI_PPS "PTTI 1 PPS" +#define ENG_POUT_HAVEQUICK "HaveQuick" + +/** @} anchor ENG_POUT_NAMES */ + + + +/** + * @brief An initializer for a table of English POUT name strings + * + * @see @ref ENG_POUT_NAMES + */ +#define DEFAULT_ENG_POUT_NAMES \ +{ \ + ENG_POUT_NAME_IDLE, \ + ENG_POUT_NAME_TIMER, \ + ENG_POUT_NAME_SINGLE_SHOT, \ + ENG_POUT_NAME_CYCLIC_PULSE, \ + ENG_POUT_NAME_PER_SEC, \ + ENG_POUT_NAME_PER_MIN, \ + ENG_POUT_NAME_PER_HOUR, \ + ENG_POUT_NAME_DCF77, \ + ENG_POUT_NAME_POS_OK, \ + ENG_POUT_NAME_TIME_SYNC, \ + ENG_POUT_NAME_ALL_SYNC, \ + ENG_POUT_NAME_TIMECODE, \ + ENG_POUT_NAME_TIMESTR, \ + ENG_POUT_NAME_10MHZ, \ + ENG_POUT_NAME_DCF77_M59, \ + ENG_POUT_NAME_SYNTH, \ + ENG_POUT_NAME_TIME_SLOTS, \ + ENG_POUT_NAME_GPIO, \ + ENG_POUT_PTTI_PPS, \ + ENG_POUT_HAVEQUICK \ +} + + +/** + * @brief Hint strings associated with ::POUT_MODES + * + * Default initializers for English programmable output mode hints. + * Initializers for multi-language strings can be found in pcpslstr.h. + * + * @see ::POUT_MODES + * @see ::DEFAULT_ENG_POUT_HINTS + * + * @anchor ENG_POUT_HINTS @{ */ + +#define ENG_POUT_HINT_IDLE "Constant output level" +#define ENG_POUT_HINT_TIMER "Switch based on configured on/off times" +#define ENG_POUT_HINT_SINGLE_SHOT "Generate a single pulse of determined length" +#define ENG_POUT_HINT_CYCLIC_PULSE "Generate cyclic pulses of determined length" +#define ENG_POUT_HINT_PER_SEC "Generate pulse at beginning of new second" +#define ENG_POUT_HINT_PER_MIN "Generate pulse at beginning of new minute" +#define ENG_POUT_HINT_PER_HOUR "Generate pulse at beginning of new hour" +#define ENG_POUT_HINT_DCF77 "DCF77 compatible time marks" +#define ENG_POUT_HINT_POS_OK "Switch if receiver position has been verified" +#define ENG_POUT_HINT_TIME_SYNC "Switch if time is synchronized" +#define ENG_POUT_HINT_ALL_SYNC "Switch if full sync" +#define ENG_POUT_HINT_TIMECODE "Duplicate IRIG time code signal" +#define ENG_POUT_HINT_TIMESTR "Duplicate serial time string of specified port" +#define ENG_POUT_HINT_10MHZ "10 MHz fixed output frequency" +#define ENG_POUT_HINT_DCF77_M59 "DCF77 time marks with 500 ms pulse in 59th second" +#define ENG_POUT_HINT_SYNTH "Frequency generated by programmable synthesizer" +#define ENG_POUT_HINT_TIME_SLOTS "Output enabled during specified time slots per minute" +#define ENG_POUT_HINT_GPIO "Duplicated signal of the specified GPIO input or output" +#define ENG_POUT_HINT_PTTI_PPS "Generate 20us Pulse at beginning of the second" +#define ENG_POUT_HINT_HAVEQUICK "Duplicated HaveQuick Signal" + +/** @} anchor ENG_POUT_HINTS */ + + +/** + * @brief An initializer for a table of English POUT hint strings + * + * @see @ref ENG_POUT_HINTS + */ +#define DEFAULT_ENG_POUT_HINTS \ +{ \ + ENG_POUT_HINT_IDLE, \ + ENG_POUT_HINT_TIMER, \ + ENG_POUT_HINT_SINGLE_SHOT, \ + ENG_POUT_HINT_CYCLIC_PULSE, \ + ENG_POUT_HINT_PER_SEC, \ + ENG_POUT_HINT_PER_MIN, \ + ENG_POUT_HINT_PER_HOUR, \ + ENG_POUT_HINT_DCF77, \ + ENG_POUT_HINT_POS_OK, \ + ENG_POUT_HINT_TIME_SYNC, \ + ENG_POUT_HINT_ALL_SYNC, \ + ENG_POUT_HINT_TIMECODE, \ + ENG_POUT_HINT_TIMESTR, \ + ENG_POUT_HINT_10MHZ, \ + ENG_POUT_HINT_DCF77_M59, \ + ENG_POUT_HINT_SYNTH, \ + ENG_POUT_HINT_TIME_SLOTS, \ + ENG_POUT_HINT_GPIO, \ + ENG_POUT_HINT_PTTI_PPS, \ + ENG_POUT_HINT_HAVEQUICK \ +} + + + +/** + * @brief Flag bits used to define ::POUT_SETTINGS_FLAGS + * + * @see ::POUT_SETTINGS_FLAGS + */ +enum POUT_SETTINGS_FLAG_BITS +{ + /// Output level is to be inverted. Can only be used + /// if ::POUT_NOT_INVERTIBLE is ***not*** set, but is + /// supported by all ::POUT_MODES. + POUT_BIT_INVERTED, + + /// Enable output **only** while synchronized. This even overrides + /// the settings in ::ENABLE_FLAGS::pulses, so if this flag is set + /// the output is only enabled if the clock is synchronized, and is + /// disabled when synchronization is lost, i.e. the device enters + /// holdover mode. + /// This flag can only be used with outputs that have ::POUT_SUPP_IF_SYNC_ONLY + /// set, and is only supported for the ::POUT_MODES specified in + /// ::POUT_MODES_SUPP_IF_SYNC_ONLY. + POUT_BIT_IF_SYNC_ONLY, + + /// Output %UTC time instead of local time for DCF77 emulation. + /// This flag can only be used with outputs that have ::POUT_SUPP_DCF77_UTC + /// set, and is only supported for the ::POUT_MODES specified in + /// ::POUT_MODES_SUPP_TIMEBASE_UTC (e.g. ::POUT_DCF77 or ::POUT_DCF77_M59). + POUT_BIT_TIMEBASE_UTC, + + N_POUT_SETTINGS_FLAG_BITS ///< Number of known flag bits +}; + + +/** + * @brief Flag bit masks used with ::POUT_SETTINGS::flags + * + * @see ::POUT_SETTINGS_FLAG_BITS + */ +enum POUT_SETTINGS_FLAGS +{ + POUT_INVERTED = ( 1UL << POUT_BIT_INVERTED ), ///< See ::POUT_BIT_INVERTED, ::POUT_NOT_INVERTIBLE + POUT_IF_SYNC_ONLY = ( 1UL << POUT_BIT_IF_SYNC_ONLY ), ///< See ::POUT_BIT_IF_SYNC_ONLY, ::POUT_SUPP_IF_SYNC_ONLY + POUT_TIMEBASE_UTC = ( 1UL << POUT_BIT_TIMEBASE_UTC ) ///< See ::POUT_BIT_TIMEBASE_UTC, ::POUT_SUPP_DCF77_UTC +}; + + + +/** + * @brief Configuration settings for a specific programmable pulse output + * + * This structure can be used to send configuration settings for a specific + * programmable output to a device. + * The number of supported outputs is RECEIVER_INFO::n_prg_out. + * + * @note The ::POUT_INFO_IDX structure should be read from + * a device to retrieve the current settings and capabilities. + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::RECEIVER_INFO::n_prg_out-1 + POUT_SETTINGS pout_settings; + +} POUT_SETTINGS_IDX; + +#define _mbg_swab_pout_settings_idx_on_set( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_pout_settings_on_set( &(_p)->pout_settings ); \ +} while ( 0 ) + +#define _mbg_swab_pout_settings_idx_on_get( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_pout_settings_on_get( &(_p)->pout_settings ); \ +} while ( 0 ) + + +/** + * @brief Current settings and general capabilities of a programmable pulse output + * + * This structure should be read from the device to retrieve the + * current settings of a programmable pulse output plus its capabilities, + * e.g. the supported output modes, etc. + * + * @note The ::POUT_INFO_IDX structure should be used to read + * current settings and capabilities of a specific output. + */ +typedef struct +{ + POUT_SETTINGS pout_settings; + uint32_t supp_modes; ///< bit mask of modes supp. by this output, see @ref POUT_MODE_MASKS + uint8_t timestr_ports; ///< bit mask of COM ports supported for mode ::POUT_TIMESTR, see ::MAX_POUT_TIMESTR_PORTS + uint8_t pulse_shift_res; ///< pulse shift resolution, in [ns], only if ::POUT_SUPP_PULSE_SHIFT, see ::POUT_DATA::pulse_shift + uint16_t reserved_1; ///< reserved for future use, currently unused and always 0 + uint32_t flags; ///< @see ::POUT_INFO_FLAG_MASKS + +} POUT_INFO; + +#define _mbg_swab_pout_info_on_get( _p ) \ +do \ +{ \ + _mbg_swab_pout_settings_on_get( &(_p)->pout_settings ); \ + _mbg_swab32( &(_p)->supp_modes ); \ + _mbg_swab8( &(_p)->timestr_ports ); \ + _mbg_swab8( &(_p)->pulse_shift_res ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + +#define MAX_POUT_TIMESTR_PORTS 8 ///< The max number of COM ports that can be handled by ::POUT_INFO::timestr_ports + + + +/** + * @brief Flag bits used to define ::POUT_INFO_FLAG_MASKS + * + * @see ::POUT_INFO_FLAG_MASKS + */ +enum POUT_INFO_FLAG_BITS +{ + POUT_BIT_SUPP_IF_SYNC_ONLY, ///< ::POUT_IF_SYNC_ONLY is supported for this output + POUT_BIT_SUPP_DCF77_UTC, ///< ::POUT_SUPP_DCF77_UTC is supported for this output + POUT_BIT_FIXED_PULSE_LEN, ///< pulse length is limited to the value ::POUT_SETTINGS::mode_param + POUT_BIT_NOT_INVERTIBLE, ///< output level can't be inverted, thus ::POUT_INVERTED is not supported for this output + POUT_BIT_SUPP_PULSE_SHIFT, ///< output slopes can be shifted, see ::POUT_DATA::pulse_shift + N_POUT_INFO_FLAG_BITS ///< number of known flag bits +}; + + +/** + * @brief Flag bit masks used with ::POUT_INFO::flags + * + * @see ::POUT_INFO_FLAG_BITS + */ +enum POUT_INFO_FLAG_MASKS +{ + POUT_SUPP_IF_SYNC_ONLY = ( 1UL << POUT_BIT_SUPP_IF_SYNC_ONLY ), ///< See ::POUT_BIT_SUPP_IF_SYNC_ONLY, ::POUT_IF_SYNC_ONLY + POUT_SUPP_DCF77_UTC = ( 1UL << POUT_BIT_SUPP_DCF77_UTC ), ///< See ::POUT_BIT_SUPP_DCF77_UTC, ::POUT_SUPP_DCF77_UTC + POUT_FIXED_PULSE_LEN = ( 1UL << POUT_BIT_FIXED_PULSE_LEN ), ///< See ::POUT_BIT_FIXED_PULSE_LEN + POUT_NOT_INVERTIBLE = ( 1UL << POUT_BIT_NOT_INVERTIBLE ), ///< See ::POUT_BIT_NOT_INVERTIBLE, ::POUT_INVERTED + POUT_SUPP_PULSE_SHIFT = ( 1UL << POUT_BIT_SUPP_PULSE_SHIFT ) ///< See ::POUT_BIT_SUPP_PULSE_SHIFT, ::POUT_DATA::pulse_shift +}; + + + +/** + * @brief Current settings and general capabilities of a specific programmable pulse output + * + * This structure should be read from the device to retrieve the + * current settings of a specific programmable output plus its capabilities, + * e.g. supported modes of operation, etc. + * The number of supported ports is RECEIVER_INFO::n_prg_out. + * + * @note The ::POUT_SETTINGS_IDX structure should be send back to + * the device to configure the specified programmable pulse output. + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::RECEIVER_INFO::n_prg_out-1 + POUT_INFO pout_info; + +} POUT_INFO_IDX; + +#define _mbg_swab_pout_info_idx_on_get( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_pout_info_on_get( &(_p)->pout_info ); \ +} while ( 0 ) + +/** @} defgroup group_pout_api */ + + + +/** + * @defgroup group_multi_ref_all Support for multiple reference time sources + * + * Some devices can evaluate and synchronize to several different types + * of input signal, and eventually even several signals of the same type, + * e.g. several 1 PPS input signals. + * + * There are two different ways to configure multi ref devices. + * + * Newer devices which have the ::GPS_HAS_XMULTI_REF flag set in + * ::RECEIVER_INFO::features support the newer XMULTI_REF_... structures + * which provide a more flexible API, see @ref group_multi_ref_ext + * + * Older devices may have the ::GPS_FEAT_MULTI_REF flag set in which + * case an older API is supported, see @ref group_multi_ref_old + * + * Symbols defined in @ref group_multi_ref_common can be used + * with both APIs. + * + * @see @ref group_multi_ref_common + * @see @ref group_multi_ref_old + * @see @ref group_multi_ref_ext + * @{ */ + +/** + * @defgroup group_multi_ref_common Common multi ref definitions + * + * Common definitions used with both the old and the extended + * multi ref API. + * + * @{ */ + +/** + * @brief Enumeration of all known types of reference time source + * + * All known types of input signal which may possibly be supported + * by devices which support several different input signals, i.e. + * have the ::GPS_HAS_MULTI_REF or ::GPS_HAS_XMULTI_REF bit set + * in ::RECEIVER_INFO::features. Not all devices support each known + * type of input signal. + * + * @see @ref group_multi_ref_all + * @see ::DEFAULT_MULTI_REF_NAMES + * @see ::DEFAULT_MULTI_REF_NAMES_SHORT + * @see @ref MULTI_REF_TYPE_MASKS + */ +enum MULTI_REF_TYPES +{ + /// @brief This ref type must not be used as index. + /// + /// It marks particular ::XMULTI_REF_SETTINGS structures as "unused". + /// This is only supported if bit ::XMRIF_BIT_MRF_NONE_SUPP is set. + MULTI_REF_NONE = -1, + + MULTI_REF_GPS = 0, ///< standard GPS + MULTI_REF_10MHZ, ///< 10 MHz input frequency + MULTI_REF_PPS, ///< 1 PPS input signal + MULTI_REF_10MHZ_PPS, ///< combined 10 MHz plus PPS + MULTI_REF_IRIG, ///< IRIG input + MULTI_REF_NTP, ///< Network Time Protocol (NTP) + MULTI_REF_PTP, ///< Precision Time Protocol (PTP/IEEE1588) + MULTI_REF_PTP_E1, ///< PTP over E1 + MULTI_REF_FREQ, ///< fixed frequency + MULTI_REF_PPS_STRING, ///< 1 PPS in addition to time string + MULTI_REF_GPIO, ///< variable input signal via GPIO + MULTI_REF_INTERNAL, ///< reserved, used internally by firmware only + MULTI_REF_PZF, ///< DCF77 PZF providing much more accuracy than a standard LWR + MULTI_REF_LWR, ///< long wave receiver. e.g. DCF77 AM, WWVB, MSF, JJY + MULTI_REF_GRC, ///< Glonass / GPS receiver + MULTI_REF_HAVEQUICK, ///< HaveQuick input + MULTI_REF_EXT_OSC, ///< external oscillator disciplined and looped back via 1 PPS I/O + MULTI_REF_SYNCE, ///< Synchronous Ethernet, needs (external) ethernet interface + MULTI_REF_VIDEO_IN, ///< Video In (Blackburst, VITC,...) + MULTI_REF_LTC, ///< Linear Time Code (Audio) + N_MULTI_REF ///< the number of defined sources, must not exceed ::MAX_N_MULTI_REF_TYPES +}; + +/** + * @brief Theoretical maximum number of multi ref input signal types + * + * Actually only ::N_MULTI_REF types have been defined, but ::N_MULTI_REF + * must not exceed the number of bits which can be hold by a uint32_t type. + */ +#define MAX_N_MULTI_REF_TYPES 32 + + +/** + * @brief Names of known ref time sources + * + * @see ::MULTI_REF_TYPES + */ +#define DEFAULT_MULTI_REF_NAMES \ +{ \ + "GPS", \ + "10 MHz freq in", \ + "PPS in", \ + "10 MHz + PPS in", \ + "IRIG", \ + "NTP", \ + "PTP (IEEE1588)", \ + "PTP over E1", \ + "Fixed Freq. in", \ + "PPS plus string", \ + "Var. freq. via GPIO", \ + "(reserved)", \ + "DCF77 PZF Receiver", \ + "Long Wave Receiver", \ + "GNSS Receiver", \ + "HaveQuick Input", \ + "ext. Osc.", \ + "Synchronous Ethernet", \ + "Video Input", \ + "Linear Time Code" \ +} + +/** + * @brief Short names of supported ref time sources + * + * Used e.g. to configure a particular input signal type + * + * @see ::MULTI_REF_TYPES + */ +#define DEFAULT_MULTI_REF_NAMES_SHORT \ +{ \ + "GPS", \ + "FRQ", \ + "PPS", \ + "10MHZ+PPS", \ + "TCR", \ + "NTP", \ + "PTP", \ + "PTP_E1", \ + "FIXED_FREQ", \ + "STRING+PPS", \ + "GPIO", \ + "(reserved)", \ + "PZF", \ + "LWR", \ + "GNSS", \ + "HQI", \ + "EXT", \ + "SYNCE", \ + "VIDEO_IN", \ + "LTC" \ +} + + +/** + * @brief Bit masks associated with multi ref types + * + * Used to indicate which multi ref types are supported, e.g. + * in ::XMULTI_REF_INFO::supp_ref or ::MULTI_REF_INFO::supp_ref. + * + * @see ::MULTI_REF_TYPES + * + * @anchor MULTI_REF_TYPE_MASKS @{ */ + +#define HAS_MULTI_REF_GPS ( 1UL << MULTI_REF_GPS ) ///< See ::MULTI_REF_GPS +#define HAS_MULTI_REF_10MHZ ( 1UL << MULTI_REF_10MHZ ) ///< See ::MULTI_REF_10MHZ +#define HAS_MULTI_REF_PPS ( 1UL << MULTI_REF_PPS ) ///< See ::MULTI_REF_PPS +#define HAS_MULTI_REF_10MHZ_PPS ( 1UL << MULTI_REF_10MHZ_PPS ) ///< See ::MULTI_REF_10MHZ_PPS +#define HAS_MULTI_REF_IRIG ( 1UL << MULTI_REF_IRIG ) ///< See ::MULTI_REF_IRIG +#define HAS_MULTI_REF_NTP ( 1UL << MULTI_REF_NTP ) ///< See ::MULTI_REF_NTP +#define HAS_MULTI_REF_PTP ( 1UL << MULTI_REF_PTP ) ///< See ::MULTI_REF_PTP +#define HAS_MULTI_REF_PTP_E1 ( 1UL << MULTI_REF_PTP_E1 ) ///< See ::MULTI_REF_PTP_E1 + +#define HAS_MULTI_REF_FREQ ( 1UL << MULTI_REF_FREQ ) ///< See ::MULTI_REF_FREQ +#define HAS_MULTI_REF_PPS_STRING ( 1UL << MULTI_REF_PPS_STRING ) ///< See ::MULTI_REF_PPS_STRING +#define HAS_MULTI_REF_GPIO ( 1UL << MULTI_REF_GPIO ) ///< See ::MULTI_REF_GPIO +#define HAS_MULTI_REF_INTERNAL ( 1UL << MULTI_REF_INTERNAL ) ///< See ::MULTI_REF_INTERNAL +#define HAS_MULTI_REF_PZF ( 1UL << MULTI_REF_PZF ) ///< See ::MULTI_REF_PZF +#define HAS_MULTI_REF_LWR ( 1UL << MULTI_REF_LWR ) ///< See ::MULTI_REF_LWR +#define HAS_MULTI_REF_GRC ( 1UL << MULTI_REF_GRC ) ///< See ::MULTI_REF_GRC +#define HAS_MULTI_REF_HAVEQUICK ( 1UL << MULTI_REF_HAVEQUICK ) ///< See ::MULTI_REF_HAVEQUICK + +#define HAS_MULTI_REF_EXT_OSC ( 1UL << MULTI_REF_EXT_OSC ) ///< See ::MULTI_REF_EXT_OSC +#define HAS_MULTI_REF_SYNCE ( 1UL << MULTI_REF_SYNCE ) ///< See ::MULTI_REF_SYNCE +#define HAS_MULTI_REF_VIDEO_IN ( 1UL << MULTI_REF_VIDEO_IN ) ///< See ::MULTI_REF_VIDEO_IN +#define HAS_MULTI_REF_LTC ( 1UL << MULTI_REF_LTC ) ///< See ::MULTI_REF_LTC + + +/** @} anchor MULTI_REF_TYPE_MASKS */ + +/** @} defgroup group_multi_ref_common */ + + + +/** + * @defgroup group_multi_ref_old Definitions used with the old multi ref API + * + * This API has been deprecated by a newer one which should be used preferably. + * + * @see @ref group_multi_ref_ext + * + * @{ */ + +/** + * @brief Maximum number of input sources + * + * The number of supported input sources and priorities is + * limited to this value if the old API is used, i.e. if only + * the ::GPS_FEAT_MULTI_REF flag is set. + */ +#define N_MULTI_REF_PRIO 4 + + +/** + * @brief A structure used to configure the priority of the supported ref sources + * + * The number stored in prio[0] of the array indicates the ref time + * source with highest priority. If that source fails, the device + * falls back to the source indicated by prio[1]. Each field of + * the prio[] array has to be set to one of the values 0..::N_MULTI_REF-1, + * or to ::MULTI_REF_NONE if no time source is specified. + */ +typedef struct +{ + uint8_t prio[N_MULTI_REF_PRIO]; + +} MULTI_REF_SETTINGS; + + +/** + * @brief A structure used to query MULTI_REF configuration parameters + * + * This also includes a bit mask of supported ref sources. + */ +typedef struct +{ + MULTI_REF_SETTINGS settings; ///< current settings + uint32_t supp_ref; ///< bit mask of supported sources, see @ref MULTI_REF_TYPE_MASKS + uint16_t n_levels; ///< supported priority levels, 0..::N_MULTI_REF_PRIO-1 + uint16_t flags; ///< reserved, currently always 0 + +} MULTI_REF_INFO; + + +/** + * @brief A data type used to query MULTI_REF status information + * + * @see ::MULTI_REF_STATUS_BIT_MASKS + */ +typedef uint16_t MULTI_REF_STATUS; + + +/** + * @brief Enumeration of multi ref status bits + * + * @see ::MULTI_REF_STATUS_BIT_MASKS + */ +enum MULTI_REF_STATUS_BITS +{ + WRN_MODULE_MODE, ///< selected input mode was invalid, set to default + WRN_COLD_BOOT, ///< GPS is in cold boot mode + WRN_WARM_BOOT, ///< GPS is in warm boot mode + WRN_ANT_DISCONN, ///< antenna is disconnected + WRN_10MHZ_UNLOCK, ///< impossible to lock to external 10 MHz reference + WRN_1PPS_UNLOCK, ///< impossible to lock to external 1 PPS reference + WRN_GPS_UNLOCK, ///< impossible to lock to GPS + WRN_10MHZ_MISSING, ///< external 10 MHz signal not available + WRN_1PPS_MISSING, ///< external 1 PPS signal not available + N_MULTI_REF_STATUS_BITS ///< the number of known bits +}; + + +/** + * @brief Bit masks associated with ::MULTI_REF_STATUS_BITS + * + * Used with ::MULTI_REF_STATUS. + * + * @see ::MULTI_REF_STATUS_BITS + */ +enum MULTI_REF_STATUS_BIT_MASKS +{ + MSK_WRN_COLD_BOOT = ( 1UL << WRN_COLD_BOOT ), ///< See ::WRN_COLD_BOOT + MSK_WRN_WARM_BOOT = ( 1UL << WRN_WARM_BOOT ), ///< See ::WRN_WARM_BOOT + MSK_WRN_ANT_DISCONN = ( 1UL << WRN_ANT_DISCONN ), ///< See ::WRN_ANT_DISCONN + MSK_WRN_10MHZ_UNLOCK = ( 1UL << WRN_10MHZ_UNLOCK ), ///< See ::WRN_10MHZ_UNLOCK + MSK_WRN_1PPS_UNLOCK = ( 1UL << WRN_1PPS_UNLOCK ), ///< See ::WRN_1PPS_UNLOCK + MSK_WRN_GPS_UNLOCK = ( 1UL << WRN_GPS_UNLOCK ), ///< See ::WRN_GPS_UNLOCK + MSK_WRN_10MHZ_MISSING = ( 1UL << WRN_10MHZ_MISSING ), ///< See ::WRN_10MHZ_MISSING + MSK_WRN_1PPS_MISSING = ( 1UL << WRN_1PPS_MISSING ), ///< See ::WRN_1PPS_MISSING + MSK_WRN_MODULE_MODE = ( 1UL << WRN_MODULE_MODE ) ///< See ::WRN_MODULE_MODE +}; + +/** @} defgroup group_multi_ref_old */ + + + +/** + * @defgroup group_multi_ref_ext Extended multi ref definitions + * + * If the ::GPS_HAS_XMULTI_REF feature is set in ::RECEIVER_INFO::features then + * the XMULTI_REF (extended multi ref, XMR) feature and API are supported and + * have to be used in favor of the older multi ref API (see @ref group_multi_ref_old). + * + * Devices supporting the XMULTI_REF feature provide a number of + * priority levels addressed by the priority index, starting at 0 + * for highest priority. A single reference time source from the set + * of supported sources can be assigned to each priority level. + * + * These structures are used to configure the individual time source for each + * priority level, and retrieve the status of the time source at each priority level. + * + * If ::GPS_HAS_XMRS_MULT_INSTC is also set in ::RECEIVER_INFO::features then + * ::XMULTI_REF_INSTANCES can be used to find out which types of input source + * are supported (::XMULTI_REF_INSTANCES::n_inst array entries != 0), and + * how many priority levels are supported to which an input source can be + * assigned (::XMULTI_REF_INSTANCES::n_xmr_settings). + * + * If ::XMRIF_MSK_HOLDOVER_STATUS_SUPP is set in ::XMULTI_REF_INSTANCES::flags + * then ::XMR_HOLDOVER_STATUS can be used to monitor the switching between + * different time sources when they become available or unavailable. + * + * If an XMR time source at a high priority level becomes unavailable the + * XMR control function tries to find and switch to a different time source + * at a lower level of the priority list, which is still available. + * + * On the other hand, if a time source at a higher priority level becomes + * available again, the XMR control function switches over to the time source + * at the higher priority even if the current time source is still available. + * + * If the accuracy of the time source at the next priority level is better than + * the accuracy of the time source at the current priority level then switching + * can be done immediately. However, if the next time source is worse than + * the current one it makes more sense to switch only after a certain holdover + * interval. + * + * The holdover interval is computed so that the time error due to the expected + * drift of the previously disciplined time base grows until it reaches the + * accuracy level of the next available reference time source. + * + * Only if the time source at the current priority level is still unavailable + * when the holdover interval expires the reference time source is switched + * to the time source at the next available priority level. + * + * @{ */ + + +/** + * @brief Identifier for a reference source + */ +typedef struct +{ + uint8_t type; ///< See ::MULTI_REF_TYPES, and note for ::XMRIF_BIT_MRF_NONE_SUPP + uint8_t instance; ///< instance number, if multiple instances are supported, else 0 + +} XMULTI_REF_ID; + +#define _mbg_swab_xmulti_ref_id( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->type ); \ + _mbg_swab8( &(_p)->instance ); \ +} while ( 0 ) + + + +/** + * @brief Reference source configuration settings + */ +typedef struct +{ + XMULTI_REF_ID id; ///< reference time source identifier + uint16_t flags; ///< See ::XMR_SETTINGS_FLAG_MSKS and ::XMR_EXT_SRC_INFO::supp_flags + NANO_TIME bias; ///< time bias, e.g. path delay @todo specify sign vs. earlier/later + NANO_TIME precision; ///< precision of the time source + uint32_t reserved; ///< reserved, currently always 0 + +} XMULTI_REF_SETTINGS; + +#define _mbg_swab_xmulti_ref_settings( _p ) \ +do \ +{ \ + _mbg_swab_xmulti_ref_id( &(_p)->id ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab_nano_time( &(_p)->bias ); \ + _mbg_swab_nano_time( &(_p)->precision ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + + + +/** + * @brief Reference source configuration for a specific priority level + * + * @note After all other ::XMULTI_REF_SETTINGS_IDX configuration structures + * have been sent to a device, an additional structure with idx == -1 (0xFFFF) + * has to be sent to let the new settings come into effect. + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< The priority level index, 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, 0 == highest. + XMULTI_REF_SETTINGS settings; ///< The settings configured for this level. + +} XMULTI_REF_SETTINGS_IDX; + +#define _mbg_swab_xmulti_ref_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmulti_ref_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Bit masks used to define ::XMR_SETTINGS_FLAG_MSKS + */ +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 +}; + + +/** + * @brief Bit masks used with ::XMULTI_REF_SETTINGS::flags and ::XMR_EXT_SRC_INFO::supp_flags + */ +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_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 +}; + + + +/** + * @brief Reference source capabilities and current configuration + */ +typedef struct +{ + XMULTI_REF_SETTINGS settings; ///< current settings + + /** + * @deprecated Deprecated by ::XMULTI_REF_INSTANCES::n_inst. + * If ::GPS_HAS_XMRS_MULT_INSTC is ***not*** set then this field provides + * a bit mask of supported sources (see @ref MULTI_REF_TYPE_MASKS), + * and only a single instance of each source signal type is supported. + */ + uint32_t supp_ref; + + /** + * @deprecated Deprecated by ::XMULTI_REF_INSTANCES::n_xmr_settings. + * If ::GPS_HAS_XMRS_MULT_INSTC is ***not*** set then this field + * reports the number of priority levels supported by the device. + */ + uint8_t n_supp_ref; + + uint8_t n_prio; ///< reserved, don't use, currently always 0 //##++++ TODO: check which devices support/use this field + uint16_t flags; ///< reserved, don't use, currently always 0 + +} XMULTI_REF_INFO; + +#define _mbg_swab_xmulti_ref_info( _p ) \ +do \ +{ \ + _mbg_swab_xmulti_ref_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_ref ); \ + _mbg_swab8( &(_p)->n_supp_ref ); \ + _mbg_swab8( &(_p)->n_prio ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Reference source capabilities and current configuration for a specific priority level + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< The priority level index, 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, 0 == highest. + XMULTI_REF_INFO info; ///< Ref. source configuration and capabilities. + +} XMULTI_REF_INFO_IDX; + +#define _mbg_swab_xmulti_ref_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmulti_ref_info( &(_p)->info ); \ +} while ( 0 ) + + + +/** + * @brief Status information on a single ref time source + */ +typedef struct +{ + XMULTI_REF_ID id; ///< time source identifier + uint16_t status; ///< status bits, see @ref XMR_REF_STATUS_BIT_MASKS + NANO_TIME offset; ///< time offset from main time base @todo specify sign vs. earlier/later + uint16_t flags; ///< flags, see ::XMR_QL // TODO ### + uint8_t ssm; ///< synchronization status message, if supported by signal source + uint8_t soc; ///< signal outage counter, incremented on loss of signal + +} XMULTI_REF_STATUS; + +#define _mbg_swab_xmulti_ref_status( _p ) \ +do \ +{ \ + _mbg_swab_xmulti_ref_id( &(_p)->id ); \ + _mbg_swab16( &(_p)->status ); \ + _mbg_swab_nano_time( &(_p)->offset ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab8( &(_p)->ssm ); \ + _mbg_swab8( &(_p)->soc ); \ +} while ( 0 ) + + + +/** + * @brief Status information on a ref time source at a specific priority level + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< The priority level index, 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, 0 == highest. + XMULTI_REF_STATUS status; ///< Status information. + +} XMULTI_REF_STATUS_IDX; + +#define _mbg_swab_xmulti_ref_status_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmulti_ref_status( &(_p)->status ); \ +} while ( 0 ) + + + +/** + * @brief ::TODO + * + * Used with the ::... field of ::XMULTI_REF_STATUS::flags + * + * @see ::XMULTI_REF_STATUS::flags + * @see ::XMR_QL_TDEV_MASK + * @see ::_GET_XMR_QL_TDEV + * @see ::_PUT_XMR_QL_TDEV + * @see ::XMR_QL_MTIE_MASK + * @see ::_GET_XMR_QL_MTIE + * @see ::_PUT_XMR_QL_MTIE + */ +enum XMR_QL +{ + XMR_QL_UNKNOWN, + XMR_QL_GREEN, + XMR_QL_YELLOW, + XMR_QL_RED, + N_XMR_QL +}; + +#define XMR_QL_TDEV_MASK ( 0x03 << 0 ) +#define XMR_QL_MTIE_MASK ( 0x03 << 2 ) + +#define _GET_XMR_QL_TDEV( _x ) ( ( ( _x ) & XMR_QL_TDEV_MASK ) >> 0 ) +#define _PUT_XMR_QL_TDEV( _x, _ql ) \ +do { \ + ( _x ) = ( ( _x ) & ~XMR_QL_TDEV_MASK ) | ( ( ( _ql ) << 0 ) & XMR_QL_TDEV_MASK ); \ +} while ( 0 ) + + +#define _GET_XMR_QL_MTIE( _x ) ( ( ( _x ) & XMR_QL_MTIE_MASK ) >> 2 ) +#define _PUT_XMR_QL_MTIE( _x, _ql ) \ +do { \ + ( _x ) = ( ( _x ) & ~XMR_QL_MTIE_MASK ) | ( ( ( _ql ) << 2 ) & XMR_QL_MTIE_MASK ); \ +} while ( 0 ) + + + +/** + * @brief XMULTI_REF status bits + */ +enum XMR_REF_STATUS_BITS +{ + XMRS_BIT_NOT_SUPP, ///< ref type cfg'd for this level is not supported + XMRS_BIT_NO_CONN, ///< input signal is disconnected + XMRS_BIT_NO_SIGNAL, ///< no input signal + XMRS_BIT_IS_MASTER, ///< reference is master source + XMRS_BIT_IS_LOCKED, ///< locked to input signal + XMRS_BIT_IS_ACCURATE, ///< oscillator control has reached full accuracy + XMRS_BIT_NOT_SETTLED, ///< reference time signal not settled + XMRS_BIT_NOT_PHASE_LOCKED, ///< oscillator not phase locked to PPS + XMRS_BIT_NUM_SRC_EXC, ///< number of available sources exceeds what can be handled + XMRS_BIT_IS_EXTERNAL, ///< this ref source is on extension card + XMRS_BIT_LOW_JITTER, ///< this ref source has low jitter + 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 +}; + + + +/** + * @brief Bit masks associated with ::XMR_REF_STATUS_BITS + * + * Used with ::XMULTI_REF_STATUS::status. + * + * @see ::XMR_REF_STATUS_BITS + * + * @anchor XMR_REF_STATUS_BIT_MASKS @{ */ + +#define XMRS_MSK_NOT_SUPP ( 1UL << XMRS_BIT_NOT_SUPP ) ///< See ::XMRS_BIT_NOT_SUPP +#define XMRS_MSK_NO_CONN ( 1UL << XMRS_BIT_NO_CONN ) ///< See ::XMRS_BIT_NO_CONN +#define XMRS_MSK_NO_SIGNAL ( 1UL << XMRS_BIT_NO_SIGNAL ) ///< See ::XMRS_BIT_NO_SIGNAL +#define XMRS_MSK_IS_MASTER ( 1UL << XMRS_BIT_IS_MASTER ) ///< See ::XMRS_BIT_IS_MASTER +#define XMRS_MSK_IS_LOCKED ( 1UL << XMRS_BIT_IS_LOCKED ) ///< See ::XMRS_BIT_IS_LOCKED +#define XMRS_MSK_IS_ACCURATE ( 1UL << XMRS_BIT_IS_ACCURATE ) ///< See ::XMRS_BIT_IS_ACCURATE +#define XMRS_MSK_NOT_SETTLED ( 1UL << XMRS_BIT_NOT_SETTLED ) ///< See ::XMRS_BIT_NOT_SETTLED +#define XMRS_MSK_NOT_PHASE_LOCKED ( 1UL << XMRS_BIT_NOT_PHASE_LOCKED ) ///< See ::XMRS_BIT_NOT_PHASE_LOCKED +#define XMRS_MSK_NUM_SRC_EXC ( 1UL << XMRS_BIT_NUM_SRC_EXC ) ///< See ::XMRS_BIT_NUM_SRC_EXC +#define XMRS_MSK_IS_EXTERNAL ( 1UL << XMRS_BIT_IS_EXTERNAL ) ///< See ::XMRS_BIT_IS_EXTERNAL +#define XMRS_MSK_LOW_JITTER ( 1UL << XMRS_BIT_LOW_JITTER ) ///< See ::XMRS_BIT_LOW_JITTER +#define XMRS_MSK_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 */ + + + +/** + * @brief XMRS status bit name strings + * + * @see ::XMR_REF_STATUS_BITS + */ +#define MBG_XMRS_STATUS_STRS \ +{ \ + "Ref type not supported", \ + "No connection", \ + "No signal", \ + "Is master", \ + "Is locked", \ + "Is accurate", \ + "Not settled", \ + "Phase not locked", \ + "Number sources exceeds limit", \ + "Is external", \ + "Low jitter", \ + "ITU Limit violated", \ + "TRS Limit violated" \ +} + + + +/* + * An initializer for a ::XMULTI_REF_STATUS variable + * with status invalid / not used + */ +#define XMULTI_REF_STATUS_INVALID \ +{ \ + { (uint8_t) MULTI_REF_NONE, 0 }, /* id; instance 0 ? */ \ + XMRS_MSK_NO_CONN | XMRS_MSK_NO_SIGNAL, /* status */ \ + { 0 }, /* offset */ \ + 0 /* reserved */ \ +} + + + +/** + * @brief General info on supported XMR sources and instances + * + * @note This structure is only supported if ::GPS_HAS_XMRS_MULT_INSTC + * is set in ::RECEIVER_INFO::features. + * + * The field ::XMULTI_REF_INSTANCES::n_xmr_settings reports the maximum number + * of entries that can be held by the input source table provided by this device. + * The input source table entry with the lowest index has the highest priority, + * and values 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1 can be used as index + * when reading ::XMULTI_REF_INFO_IDX or ::XMULTI_REF_STATUS_IDX from the device, + * or when writing ::XMULTI_REF_SETTINGS_IDX to the device to configure + * the priority/order of input sources. + * + * An input source table entry is empty if ::XMULTI_REF_ID::type is set to + * ::MULTI_REF_NONE in ::XMULTI_REF_SETTINGS::id, and accordingly + * in ::XMULTI_REF_STATUS::id. + * + * The array ::XMULTI_REF_INSTANCES::n_inst reports how many instances are supported + * for every known reference type. For example, if 2 PPS input signals were supported + * then ::XMULTI_REF_INSTANCES::n_inst[::MULTI_REF_PPS] was set to 2. Even though + * this array can hold up to ::MAX_N_MULTI_REF_TYPES entries, the number entries + * which are actually used is ::N_MULTI_REF, according to the number of known + * reference signal types, which is less or equal than ::MAX_N_MULTI_REF_TYPES. + */ +typedef struct +{ + uint32_t flags; ///< See ::XMR_INST_FLAG_BIT_MASKS + uint16_t n_xmr_settings; ///< number of ::XMULTI_REF_INFO_IDX or ::XMULTI_REF_STATUS_IDX which can be retrieved + uint8_t slot_id; ///< ID of the slot in which this device is installed, 0 or up to 15, if multiple slots not supported + uint8_t reserved; ///< reserved, don't use, currently always 0 + uint8_t n_inst[MAX_N_MULTI_REF_TYPES]; ///< the number of supported instances of each input signal type + +} XMULTI_REF_INSTANCES; + +#define _mbg_swab_xmulti_ref_instances( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab16( &(_p)->n_xmr_settings ); \ +} while ( 0 ) + + + +/** + * @brief Extended information about the reference source of an instance type. + */ +typedef struct +{ + uint8_t integrated [MAX_N_MULTI_REF_TYPES]; ///< See ::SYS_REF_SRC_INTEGRATED + uint8_t peripheral [MAX_N_MULTI_REF_TYPES]; ///< See ::SYS_REF_SRC_PERIPHERAL + uint8_t expansion [MAX_N_MULTI_REF_TYPES]; ///< See ::SYS_REF_SRC_EXPANSION + uint8_t autarkic [MAX_N_MULTI_REF_TYPES]; ///< See ::SYS_REF_SRC_AUTARKIC + uint8_t reserved_1 [MAX_N_MULTI_REF_TYPES]; + uint8_t reserved_2 [MAX_N_MULTI_REF_TYPES]; + uint8_t reserved_3 [MAX_N_MULTI_REF_TYPES]; + uint8_t reserved_4 [MAX_N_MULTI_REF_TYPES]; + +} XMULTI_EXT_REF_INSTANCES; + +#define _mbg_swab_xmulti_ext_ref_instances( _p ) \ +do \ +{ \ +} while ( 0 ) + + + +/** + * @brief Enumeration of flag bits used with XMULTI_REF instances + * + * @see ::XMR_INST_FLAG_BIT_MASKS + */ +enum XMR_INST_FLAGS +{ + /// @brief Indicate that the ::MULTI_REF_NONE pseude-type is supported is supported. + /// + /// This flag indicates that configuration programs may set + /// ::XMULTI_REF_ID::type to ::MULTI_REF_NONE in ::XMULTI_REF_SETTINGS::id + /// for unused priority levels, and that this will be reflected in + /// ::XMULTI_REF_STATUS::id accordingly. With some older firmware versions + /// this was not supported. + XMRIF_BIT_MRF_NONE_SUPP, + + 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. + + XMRIF_BIT_EXT_REF_INSTANCES_SUPP, ///< Supports ::XMULTI_EXT_REF_INSTANCES structure. + XMRIF_BIT_NOT_CONFIGURABLE, ///< ::XMULTI_REF_SETTINGS cannot be configured. + XMRIF_BIT_NO_STATUS, ///< No status, no stats at all. NOTHING!!! + + N_XMRIF_BITS ///< Number of known flag bits. +}; + + +/** + * @brief Bit masks associated with ::XMR_INST_FLAGS + * + * Used with ::XMULTI_REF_INSTANCES::flags. + * + * @see ::XMR_INST_FLAGS + */ +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_GNSS_BIAS_SUPP = ( 1UL << XMRIF_BIT_GNSS_BIAS_SUPP ), ///< See ::XMRIF_BIT_GNSS_BIAS_SUPP + XMRIF_MSK_EXT_REF_INSTANCES_SUPP = ( 1UL << XMRIF_BIT_EXT_REF_INSTANCES_SUPP ), ///< See ::XMRIF_BIT_EXT_REF_INSTANCES_SUPP + XMRIF_MSK_NOT_CONFIGURABLE = ( 1UL << XMRIF_BIT_NOT_CONFIGURABLE ), ///< See ::XMRIF_BIT_NOT_CONFIGURABLE + XMRIF_MSK_NO_STATUS = ( 1UL << XMRIF_BIT_NO_STATUS ) ///< See ::XMRIF_BIT_NO_STATUS +}; + + + +/** + * @brief XMR holdover interval, or elapsed holdover time, in [s] + */ +typedef uint32_t XMR_HOLDOVER_INTV; + +#define _mbg_swab_xmr_holdover_intv( _p ) \ + _mbg_swab32( _p ) + + + +/** + * @brief A code used to indicate that a input source table index is unspecified + */ +#define XMR_PRIO_LVL_UNSPEC -1 + + + +/** + * @brief XMR holdover status + * + * Only supported if ::XMRIF_MSK_HOLDOVER_STATUS_SUPP is set in ::XMULTI_REF_INSTANCES::flags + * + * Reports the current holdover status including the elapsed holdover time + * and the currently active holdover interval, as well as the indices of the + * current and next XMR time source. + * + * The flag ::XMR_HLDOVR_MSK_IN_HOLDOVER is set if holdover mode is currently active. + * + * The fields ::XMR_HOLDOVER_STATUS::curr_prio and ::XMR_HOLDOVER_STATUS::nxt_prio + * specify the current or next priority level which can be in the range + * 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, or ::XMR_PRIO_LVL_UNSPEC if the + * index is undefined, e.g. because no input source is available to which can + * be switched after the holdover interval. + * + * The ::XMR_HOLDOVER_STATUS::mode field indicates the current XMR/holdover mode + * which is usually ::XMR_HLDOVR_AUTONOMOUS. However, in certain applications + * XMR switching is controlled remotely, in which case ::XMR_HOLDOVER_STATUS::mode + * is set to ::XMR_HLDOVR_REMOTE. + * + * If the device is in remote mode and needs to switch XMR sources then mode changes + * to ::XMR_HLDOVR_PRE_AUTONOMOUS, and the ::XMR_HOLDOVER_STATUS::remote_watchdog + * starts to count down. If the watchdog expires before a remote switch command + * has been received the device switches to ::XMR_HLDOVR_AUTONOMOUS. + */ +typedef struct xmr_holdover_status_s +{ + uint8_t mode; ///< XMR/holdover mode, see ::XMR_HOLDOVER_STATUS_MODES + int8_t curr_prio; ///< current priority level, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC + int8_t nxt_prio; ///< next priority level after holdover, 0..::XMULTI_REF_INSTANCES::n_xmr_settings, or ::XMR_PRIO_LVL_UNSPEC + uint8_t remote_watchdog; ///< counts down in ::XMR_HLDOVR_PRE_AUTONOMOUS mode + uint32_t time_offset_ns; ///< estimated time offset in holdover operation + XMR_HOLDOVER_INTV elapsed; ///< elapsed time in holdover mode, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set + XMR_HOLDOVER_INTV interval; ///< current holdover interval, only valid if ::XMR_HLDOVR_MSK_IN_HOLDOVER is set + uint32_t flags; ///< holdover status flags, see ::XMR_HOLDOVER_STATUS_FLAG_MASKS + +} XMR_HOLDOVER_STATUS; + +#define _mbg_swab_xmr_holdover_status( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->mode ); \ + _mbg_swab8( &(_p)->curr_prio ); \ + _mbg_swab8( &(_p)->nxt_prio ); \ + _mbg_swab8( &(_p)->remote_watchdog ); \ + _mbg_swab32( &(_p)->time_offset_ns ); \ + _mbg_swab_xmr_holdover_intv( &(_p)->elapsed ); \ + _mbg_swab_xmr_holdover_intv( &(_p)->interval ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + + +/** + * @brief XMR holdover status modes + * + * Used with ::XMR_HOLDOVER_STATUS::mode. + * + * @see ::XMR_HOLDOVER_STATUS_MODE_NAMES + */ +enum XMR_HOLDOVER_STATUS_MODES +{ + XMR_HLDOVR_AUTONOMOUS, ///< autonomous mode, XMR sources are selected automatically by the device + XMR_HLDOVR_PRE_AUTONOMOUS, ///< going to switch to autonomous mode when ::XMR_HOLDOVER_STATUS::remote_watchdog reaches 0 + XMR_HLDOVR_REMOTE, ///< remote mode, XMR switching done by external command/control + N_XMR_HOLDOVER_STATUS_MODES ///< the number of known modes +}; + + +/** + * @brief String initializers for XMR holdover status mode + * + * @see ::XMR_HOLDOVER_STATUS_MODES + */ +#define XMR_HOLDOVER_STATUS_MODE_NAMES \ +{ \ + "Autonomous", \ + "Pre-Autonomous", \ + "Remote" \ +} + + + +/** + * @brief XMR holdover status flag bits + * + * Used to define ::XMR_HOLDOVER_STATUS_FLAG_MASKS. + */ +enum XMR_HOLDOVER_STATUS_FLAG_BITS +{ + XMR_HLDOVR_BIT_IN_HOLDOVER, ///< the device is currently in holdover mode + XMR_HLDOVR_BIT_TRANSITION_ENBD, ///< timebase is in transition (being slewed) after sources have been switched + XMR_HLDOVR_BIT_IN_TRANSITION, ///< transition is currently active, slewing in progress + XMR_HLDOVR_BIT_TIME_OFFS_VALID, ///< values in field ::XMR_HOLDOVER_STATUS::time_offset_ns are valid + N_XMR_HOLDOVER_STATUS_FLAG_BITS ///< the number of known status flags +}; + + +/** + * @brief XMR holdover status flag masks + * + * Used with ::XMR_HOLDOVER_STATUS::flags. + */ +enum XMR_HOLDOVER_STATUS_FLAG_MASKS +{ + XMR_HLDOVR_MSK_IN_HOLDOVER = ( 1UL << XMR_HLDOVR_BIT_IN_HOLDOVER ), ///< See ::XMR_HLDOVR_BIT_IN_HOLDOVER + XMR_HLDOVR_MSK_TRANSITION_ENBD = ( 1UL << XMR_HLDOVR_BIT_TRANSITION_ENBD ), ///< See ::XMR_HLDOVR_BIT_TRANSITION_ENBD + XMR_HLDOVR_MSK_IN_TRANSITION = ( 1UL << XMR_HLDOVR_BIT_IN_TRANSITION ), ///< See ::XMR_HLDOVR_BIT_IN_TRANSITION + XMR_HLDOVR_MSK_TIME_OFFS_VALID = ( 1UL << XMR_HLDOVR_BIT_TIME_OFFS_VALID ) ///< See ::XMR_HLDOVR_BIT_TIME_OFFS_VALID +}; + + + +/** + * @brief XMR source feature flag bits + * + * Used to define ::XMR_EXT_SRC_FEAT_FLAG_MSKS + */ +enum XMR_EXT_SRC_FEAT_FLAG_BITS +{ + XMR_EXT_SRC_FEAT_FLAG_BIT_STATS, ///< XMR source provides ::XMR_STATS. + XMR_EXT_SRC_FEAT_FLAG_BIT_METRICS, ///< XMR source provides ::XMR_METRICS. + XMR_EXT_SRC_FEAT_FLAG_BIT_COASTING, ///< XMR source supports coasting mode. + XMR_EXT_SRC_FEAT_FLAG_BIT_ADV_METRICS, ///< XMR source supports advanced XMR QL metrics configuration, see ::XMR_QL_LIMITS. + ///< If this feature is not available, ::XMR_METRICS can not be configured. + N_XMR_EXT_SRC_FEAT_FLAG_BITS +}; + + + +/** + * @brief XMR source feature flag bit masks + * + * Used with ::XMR_EXT_SRC_INFO::feat_flags. + * + * @see ::XMR_EXT_SRC_FEAT_FLAG_BITS + */ +enum XMR_EXT_SRC_FEAT_FLAG_MSKS +{ + XMR_EXT_SRC_FEAT_FLAG_MSK_STATS = ( 1UL << XMR_EXT_SRC_FEAT_FLAG_BIT_STATS ), ///< See ::XMR_EXT_SRC_FEAT_FLAG_BIT_STATS. + XMR_EXT_SRC_FEAT_FLAG_MSK_METRICS = ( 1UL << XMR_EXT_SRC_FEAT_FLAG_BIT_METRICS ), ///< See ::XMR_EXT_SRC_FEAT_FLAG_BIT_METRICS. + XMR_EXT_SRC_FEAT_FLAG_MSK_COASTING = ( 1UL << XMR_EXT_SRC_FEAT_FLAG_BIT_COASTING ), ///< See ::XMR_EXT_SRC_FEAT_FLAG_BIT_COASTING. + XMR_EXT_SRC_FEAT_FLAG_MSK_ADV_METRICS = ( 1UL << XMR_EXT_SRC_FEAT_FLAG_BIT_ADV_METRICS ) ///< See ::XMR_EXT_SRC_FEAT_FLAG_BIT_ADV_METRICS. +}; + + + +typedef struct +{ + uint16_t supp_flags; ///< Indicates which flags are supported by ::XMULTI_REF_SETTINGS::flags, see ::XMR_SETTINGS_FLAG_MSKS. + uint16_t feat_flags; ///< See ::XMR_EXT_SRC_FEAT_FLAG_MSKS. + uint32_t reserved_0; + +} XMR_EXT_SRC_INFO; + +#define _mbg_swab_xmr_ext_src_info( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->supp_flags ); \ + _mbg_swab16( &(_p)->feat_flags ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ +} while ( 0 ) + + + +typedef struct +{ + uint16_t idx; // + XMR_EXT_SRC_INFO info; // + +} XMR_EXT_SRC_INFO_IDX; // + +#define _mbg_swab_xmr_ext_src_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmr_ext_src_info( &(_p)->info ); \ +} while ( 0 ) + + + +/** + * @brief XMR statistics for a particular source + * + * This structure is only provided by an XMR source which has + * ::XMR_EXT_SRC_FEAT_FLAG_MSK_STATS set in ::XMR_EXT_SRC_INFO::feat_flags. + * + * @see ::XMR_STATS_IDX + * @see ::XMR_EXT_SRC_INFO::feat_flags + * @see ::XMR_EXT_SRC_FEAT_FLAG_MSK_STATS + */ +typedef struct xmr_stats_s +{ + uint32_t timestamp; ///< time stamp when the record was taken, %UTC, seconds since 1970 + NANO_TIME last_mue; ///< mean value (mue) of prev. interval + NANO_TIME last_sigma; ///< standard deviation (sigma) of prev. interval + NANO_TIME last_max; ///< maximum value within interval + NANO_TIME last_min; ///< minimum value within interval + NANO_TIME reserved_0; ///< currently reserved, unused, always 0 + NANO_TIME step_comp_val; ///< current step compensation value + NANO_TIME auto_bias; ///< current time automatic bias compensation + uint32_t reserved_1; ///< currently reserved, unused, always 0 + uint32_t reserved_2; ///< currently reserved, unused, always 0 + uint32_t flags; ///< See ::XMR_STATS_FLAGS_MSKS + +} XMR_STATS; + +#define _mbg_swab_xmr_stats( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->timestamp ); \ + _mbg_swab_nano_time( &(_p)->last_mue ); \ + _mbg_swab_nano_time( &(_p)->last_sigma ); \ + _mbg_swab_nano_time( &(_p)->last_max ); \ + _mbg_swab_nano_time( &(_p)->last_min ); \ + _mbg_swab_nano_time( &(_p)->reserved_0 ); \ + _mbg_swab_nano_time( &(_p)->step_comp_val ); \ + _mbg_swab_nano_time( &(_p)->auto_bias ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of bits used to define ::XMR_STATS_FLAGS_MSKS + * + * @see ::XMR_STATS_FLAGS_MSKS + */ +enum XMR_STATS_FLAGS_BITS +{ + XMR_STATS_FLAG_BIT_STEP_DETECTED, ///< A time step was detected at the input source + XMR_STATS_FLAG_BIT_STEP_COMPENSATED, ///< A time step was compensated at the input source + XMR_STATS_FLAG_BIT_AUTO_BIAS_VALID, ///< The value in ::XMR_STATS::auto_bias is valid + N_XMR_STATS_FLAGS_BITS +}; + + + +/** + * @brief Flag bit masks used with ::XMR_STATS::flags + * + * @see ::XMR_STATS_FLAGS_BITS + */ +enum XMR_STATS_FLAGS_MSKS +{ + XMR_STATS_FLAG_MSK_STEP_DETECTED = ( 1UL << XMR_STATS_FLAG_BIT_STEP_DETECTED ), ///< See ::XMR_STATS_FLAG_BIT_STEP_DETECTED + XMR_STATS_FLAG_MSK_STEP_COMPENSATED = ( 1UL << XMR_STATS_FLAG_BIT_STEP_COMPENSATED ), ///< See ::XMR_STATS_FLAG_BIT_STEP_COMPENSATED + XMR_STATS_FLAG_MSK_AUTO_BIAS_VALID = ( 1UL << XMR_STATS_FLAG_BIT_AUTO_BIAS_VALID ) ///< See ::XMR_STATS_FLAG_BIT_AUTO_BIAS_VALID +}; + + + +/** + * @brief String initializers for XMR Stats Flags + * + * @see ::XMR_STATS_FLAGS_MSKS + */ +#define DEFAULT_XMR_STATS_FLAG_NAMES \ +{ \ + "Step Detected", \ + "Step Compensated", \ + "Auto BIAS valid" \ +} + + + +/** + * @brief XMR statistics for a particular source, with index + * + * @see ::XMR_STATS + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< The priority level index, 0..::XMULTI_REF_INSTANCES::n_xmr_settings-1, 0 == highest. + XMR_STATS stats; ///< XMR statistics of the particular source. + +} XMR_STATS_IDX; + +#define _mbg_swab_xmr_stats_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmr_stats( &(_p)->stats ); \ +} while ( 0 ) + + + +#define MAX_XMR_METRICS 20 + +typedef struct +{ + uint32_t timestamp; + uint32_t flags; ///< idx bit set if mtie[idx] is valid + uint8_t mtie_scale; ///< scale factors of MTIE + uint8_t tdev_scale; ///< scale factors of TDEV + uint16_t reserved_0; ///< currently unused + uint32_t reserved_1; ///< currently unused + uint32_t reserved_2; ///< currently unused + uint32_t mtie[MAX_XMR_METRICS]; ///< mtie scaled 32 bit fixed point unsigned + uint32_t tdev[MAX_XMR_METRICS]; ///< tdev scaled 32 bit fixed point unsigned + +} XMR_METRICS; + +#define _mbg_swab_xmr_metrics( _p ) \ +do \ +{ \ + int i; \ + \ + _mbg_swab32( &(_p)->timestamp ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab8( &(_p)->mtie_scale ); \ + _mbg_swab8( &(_p)->tdev_scale ); \ + _mbg_swab16( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + \ + for ( i = 0; i < MAX_XMR_METRICS; i++ ) \ + _mbg_swab32( &(_p)->mtie[i] ); \ + \ + for ( i = 0; i < MAX_XMR_METRICS; i++ ) \ + _mbg_swab32( &(_p)->tdev[i] ); \ + \ +} while ( 0 ) + + + +// conversion factor scaled FPU32 to double +#define _fpu32_to_double_fac( _x ) ( 1.0 / ( 4294967296.0 * ( _x ) ) ) + + + +/** + * @brief XMR timing metrics for a particular source, with index + * + * @see ::XMR_METRICS + */ +typedef struct +{ + uint16_t idx; + XMR_METRICS metrics; + +} XMR_METRICS_IDX; + +#define _mbg_swab_xmr_metrics_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_xmr_metrics( &(_p)->metrics ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of ITU limit masks + * + * Used for detection of ::XMR_METRICS mask violation. + * + * @see ::ITU_LIMIT_MASKS + * @see ::XMR_METRICS + */ +enum ITU_LIMITS +{ + ITU_LIMIT_NONE, + ITU_LIMIT_G811_PRC, + ITU_LIMIT_G823_SSU, + ITU_LIMIT_G823_SEC, + ITU_LIMIT_G8272_PRTC, + ITU_LIMIT_G82721_EPRTC, + N_ITU_LIMITS +} ; + + + +/** + * @brief Enumeration of ITU limit masks + * + * Used for detection of ::XMR_METRICS mask violation. + * + * @see ::ITU_LIMITS + * @see ::XMR_METRICS + */ +enum ITU_LIMIT_MASKS +{ + MSK_ITU_LIMIT_NONE = ( 1UL << ITU_LIMIT_NONE ), + MSK_ITU_LIMIT_G811_PRC = ( 1UL << ITU_LIMIT_G811_PRC ), + MSK_ITU_LIMIT_G823_SSU = ( 1UL << ITU_LIMIT_G823_SSU ), + MSK_ITU_LIMIT_G823_SEC = ( 1UL << ITU_LIMIT_G823_SEC ), + MSK_ITU_LIMIT_G8272_PRTC = ( 1UL << ITU_LIMIT_G8272_PRTC ), + MSK_ITU_LIMIT_G82721_EPRTC = ( 1UL << ITU_LIMIT_G82721_EPRTC ) +}; + + + +/** + * @brief String initializers for ITU limit masks + * + * Used for detection of ::XMR_METRICS mask violation. + * + * @see ::ITU_LIMITS + * @see ::XMR_METRICS + */ +#define ITU_LIMIT_SHORT_STRS \ +{ \ + "None", \ + "G811 (PRC)", \ + "G823 (SSU)", \ + "G823 (SEC)", \ + "G8272 (PRTC)", \ + "G82721 (ePRTC)" \ +} + + + +/** + * @brief Supported limits for qualtity metrics + * + * @see ::XMR_METRICS + */ +typedef struct +{ + uint32_t supp_ql_masks; ///< see :ITU_LIMIT_MASKS. Masks apply to all sources! + uint32_t reserved_0; + uint32_t reserved_1; + uint32_t reserved_2; + +} XMR_QL_LIMITS; + +#define _mbg_swab_xmr_ql_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_ql_masks ); \ +} while ( 0 ) + + + +typedef struct +{ + uint8_t ql_mask; ///< see :ITU_LIMIT_MASKS + uint8_t hysteresis; ///< hysteresis (percent) between yellow and red alarm + uint16_t reserved_0; + uint32_t reserved_1; + +} XMR_QL_SETTINGS; + +#define _mbg_swab_xmr_ql_settings( _p ) \ +do \ +{ \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t idx; + XMR_QL_SETTINGS settings; + +} XMR_QL_SETTINGS_IDX; + +#define _mbg_swab_xmr_ql_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_xmr_ql_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** @} defgroup group_multi_ref_ext */ + +/** @} defgroup group_multi_ref_all */ + + +/** + * @defgroup group_gpio GPIO port configuration stuff + * + * @note This is only supported if ::GPS_HAS_GPIO is set + * in the ::RECEIVER_INFO::features mask. + * + * @{ */ + + +/** + * @brief General GPIO config info to be read from a device + * + * Used to query from a device how many GPIO ports are supported + * by the device, then index 0..::MBG_GPIO_CFG_LIMITS::num_io-1 + * configuration or status records can be read from or written to + * the device. + */ +typedef struct +{ + uint32_t num_io; ///< number of supported GPIO ports + uint32_t reserved; ///< reserved, currently always 0 + uint32_t flags; ///< See ::MBG_GPIO_CFG_LIMIT_FLAG_MASKS + +} MBG_GPIO_CFG_LIMITS; + +#define _mbg_swab_mbg_gpio_cfg_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->num_io ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief GPIO limits flag bits used to define ::MBG_GPIO_CFG_LIMIT_FLAG_MASKS + * + * @see ::MBG_GPIO_CFG_LIMIT_FLAG_MASKS + */ +enum MBG_GPIO_CFG_LIMIT_FLAG_BITS +{ + MBG_GPIO_CFG_LIMIT_FLAG_BIT_STATUS_SUPP, ///< indicates that ::MBG_GPIO_STATUS is supported + N_MBG_GPIO_CFG_LIMIT_FLAG_BITS +}; + + + +/** + * @brief GPIO limits flag masks associated with ::MBG_GPIO_CFG_LIMIT_FLAG_BITS + * + * Used with ::MBG_GPIO_CFG_LIMITS::flags + * + * @see ::MBG_GPIO_CFG_LIMIT_FLAG_BITS + */ +enum MBG_GPIO_CFG_LIMIT_FLAG_MASKS +{ + MBG_GPIO_CFG_LIMIT_FLAG_MASK_STATUS_SUPP = ( 1UL << MBG_GPIO_CFG_LIMIT_FLAG_BIT_STATUS_SUPP ), ///< See ::MBG_GPIO_CFG_LIMIT_FLAG_BIT_STATUS_SUPP +}; + + + +/** + * @brief Enumeration of GPIO types + * + * Usually a specific GPIO port can only be either an input + * or an output, and supports only a single signal type. + * This is due to hardware limitations, i.e. input or output + * circuitry required for the given signal. + * + * @see ::DEFAULT_GPIO_TYPES_SHORT_STRS + */ +enum MBG_GPIO_TYPES +{ + MBG_GPIO_TYPE_FREQ_IN, ///< Variable frequency input, freq == 0 if input not used + MBG_GPIO_TYPE_FREQ_OUT, ///< Variable frequency output + MBG_GPIO_TYPE_FIXED_FREQ_OUT, ///< Fixed frequency output + MBG_GPIO_TYPE_BITS_IN, ///< Framed data stream input + MBG_GPIO_TYPE_BITS_OUT, ///< Framed data stream output + MBG_GPIO_TYPE_VIDEO_OUT, ///< Video signal output (PAL, NTSC, ...) + MBG_GPIO_TYPE_VIDEO_SYNC_OUT, ///< Video sync signal output (H-Sync, V-Sync, ...) + MBG_GPIO_TYPE_STUDIO_CLOCK_OUT, ///< Studio clock output + MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT, ///< Digital Audio output (DARS, ...) + MBG_GPIO_TYPE_VIDEO_IN, ///< Video signal output (PAL, NTSC, ...) + MBG_GPIO_TYPE_LTC_OUT, ///< Linear Timecode output + N_MBG_GPIO_TYPES ///< Number of known types +}; + + + +#define DEFAULT_GPIO_TYPES_SHORT_STRS \ +{ \ + "Freq. In", \ + "Freq. Out", \ + "Fixed Freq Out", \ + "BITS In", \ + "BITS Out", \ + "Video Out", \ + "Video Sync Out", \ + "Studio Clock Out", \ + "Digital Audio Out", \ + "Video In", \ + "LTC Out" \ +} + + + +/** + * @brief Enumeration of known signal shapes + * + * Used to specify the signal shape of an input or output + * frequency signal. + * + * @see ::MBG_GPIO_SIGNAL_SHAPE_MASKS + * @see ::DEFAULT_GPIO_SIGNAL_SHAPE_NAMES + */ +enum MBG_GPIO_SIGNAL_SHAPES +{ + MBG_GPIO_SIGNAL_SHAPE_UNSPECIFIED, ///< unknown or unspecified signal shape + MBG_GPIO_SIGNAL_SHAPE_SINE, ///< sine wave + MBG_GPIO_SIGNAL_SHAPE_SQUARE, ///< square wave + N_MBG_GPIO_SIGNAL_SHAPES ///< number of known signal shapes +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_SIGNAL_SHAPES + * + * Used e.g. with ::MBG_GPIO_FREQ_IN_SUPP::supp_shapes, + * ::MBG_GPIO_FREQ_OUT_SUPP::supp_shapes, + * and ::MBG_GPIO_FIXED_FREQ_OUT_SUPP::supp_shapes. + * + * @see ::MBG_GPIO_SIGNAL_SHAPES + */ +enum MBG_GPIO_SIGNAL_SHAPE_MASKS +{ + MBG_GPIO_SIGNAL_SHAPE_MSK_UNSPECIFIED = ( 1UL << MBG_GPIO_SIGNAL_SHAPE_UNSPECIFIED ), ///< See ::MBG_GPIO_SIGNAL_SHAPE_UNSPECIFIED + MBG_GPIO_SIGNAL_SHAPE_MSK_SINE = ( 1UL << MBG_GPIO_SIGNAL_SHAPE_SINE ), ///< See ::MBG_GPIO_SIGNAL_SHAPE_SINE + MBG_GPIO_SIGNAL_SHAPE_MSK_SQUARE = ( 1UL << MBG_GPIO_SIGNAL_SHAPE_SQUARE ) ///< See ::MBG_GPIO_SIGNAL_SHAPE_SQUARE +}; + + + +/** + * @brief String initializers for GPIO signal shapes + * + * @see ::MBG_GPIO_SIGNAL_SHAPES + */ +#define DEFAULT_GPIO_SIGNAL_SHAPE_NAMES \ +{ \ + "(unspec. shape)", \ + "Sine wave", \ + "Rectangle pulse" \ +} + + + +/** + * @brief A structure used to specify a variable frequency + * + * Used to specify a variable frequency for GPIO input or output + */ +typedef struct +{ + uint32_t hz; ///< integral number [Hz] + uint32_t frac; ///< fractional part, binary (0x80000000 --> 0.5, 0xFFFFFFFF --> 0.9999999...) + +} MBG_GPIO_FREQ; + +#define _mbg_swab_mbg_gpio_freq( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->hz ); \ + _mbg_swab32( &(_p)->frac); \ +} while ( 0 ) + + + +/** + * @brief Configuration of a GPIO variable frequency input + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_FREQ_IN + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + MBG_GPIO_FREQ freq; ///< frequency in range ::MBG_GPIO_FREQ_IN_SUPP::freq_min..::MBG_GPIO_FREQ_IN_SUPP::freq_max, or 0 if input is not used + uint32_t csc_limit; ///< max. cycle slip [1/1000 cycle units], see ::MBG_GPIO_FREQ_IN_SUPP::csc_limit_max + uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES + uint32_t reserved; ///< reserved, currently always 0 + uint32_t flags; ///< reserved, currently always 0 + +} MBG_GPIO_FREQ_IN_SETTINGS; + +#define _mbg_swab_mbg_gpio_freq_in_settings( _p ) \ +do \ +{ \ + _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \ + _mbg_swab32( &(_p)->csc_limit ); \ + _mbg_swab32( &(_p)->shape ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Supported options for a variable frequency GPIO input + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_FREQ_IN + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t freq_min; ///< minimum output frequency [Hz] + uint32_t freq_max; ///< maximum output frequency [Hz] + uint32_t csc_limit_max; ///< 1/1000 units of the signal period, limited due to 10 ns sampling interval, see ::MBG_GPIO_FREQ_IN_SETTINGS::csc_limit //##++++++++++++++++ + uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS + uint32_t supp_limits; ///< supported ITU limit masks for BITS signal see ::ITU_LIMIT_MASKS + uint32_t flags; ///< reserved, currently always 0 + +} MBG_GPIO_FREQ_IN_SUPP; + +#define _mbg_swab_mbg_gpio_freq_in_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->freq_min ); \ + _mbg_swab32( &(_p)->freq_max ); \ + _mbg_swab32( &(_p)->csc_limit_max ); \ + _mbg_swab32( &(_p)->supp_shapes ); \ + _mbg_swab32( &(_p)->supp_limits ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Configuration of a GPIO variable frequency output + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_FREQ_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + MBG_GPIO_FREQ freq; ///< frequency, see ::MBG_GPIO_FREQ_OUT_SUPP::freq_min and ::MBG_GPIO_FREQ_OUT_SUPP::freq_max + int32_t milli_phase; ///< phase [1/1000 degree units], see ::MBG_GPIO_FREQ_OUT_SUPP::milli_phase_max + uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES + uint32_t reserved; ///< reserved, currently always 0 + uint32_t flags; ///< reserved, currently always 0 + +} MBG_GPIO_FREQ_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_freq_out_settings( _p ) \ +do \ +{ \ + _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \ + _mbg_swab32( &(_p)->milli_phase ); \ + _mbg_swab32( &(_p)->shape ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Supported options for a variable frequency GPIO output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_FREQ_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t freq_min; ///< minimum output frequency [Hz], see ::MBG_GPIO_FREQ_OUT_SETTINGS::freq + uint32_t freq_max; ///< maximum output frequency [Hz], see ::MBG_GPIO_FREQ_OUT_SETTINGS::freq + uint32_t freq_resolution; ///< frequency resolution [Hz], unspecified if 0 + uint32_t milli_phase_max; ///< max. abs. milli_phase, see ::MBG_GPIO_FREQ_OUT_SETTINGS::milli_phase + uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS + uint32_t reserved; ///< reserved, currently always 0 + uint32_t flags; ///< reserved, currently always 0 + +} MBG_GPIO_FREQ_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_freq_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->freq_min ); \ + _mbg_swab32( &(_p)->freq_max ); \ + _mbg_swab32( &(_p)->freq_resolution ); \ + _mbg_swab32( &(_p)->milli_phase_max ); \ + _mbg_swab32( &(_p)->supp_shapes ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of predefined fixed frequencies + * + * @see ::MBG_GPIO_FIXED_FREQ_MASKS + * @see ::MBG_GPIO_FIXED_FREQ_STRS + */ +enum MBG_GPIO_FIXED_FREQS +{ + MBG_GPIO_FIXED_FREQ_8kHz, ///< 8 kHz + MBG_GPIO_FIXED_FREQ_48kHz, ///< 48 kHz + MBG_GPIO_FIXED_FREQ_1MHz, ///< 1 MHz + MBG_GPIO_FIXED_FREQ_1544kHz, ///< 1.544 MHz + MBG_GPIO_FIXED_FREQ_2048kHz, ///< 2.048 MHz + MBG_GPIO_FIXED_FREQ_5MHz, ///< 5 MHz + MBG_GPIO_FIXED_FREQ_10MHz, ///< 10 MHz + MBG_GPIO_FIXED_FREQ_19440kHz, ///< 19.44 MHz + N_MBG_GPIO_FIXED_FREQ ///< number of predefined fixed frequencies +}; + + +/** + * @brief Bit masks associated with ::MBG_GPIO_FIXED_FREQS + * + * @see ::MBG_GPIO_FIXED_FREQS + * @see ::MBG_GPIO_FIXED_FREQ_STRS + */ +enum MBG_GPIO_FIXED_FREQ_MASKS +{ + MSK_MBG_GPIO_FIXED_FREQ_8kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_8kHz ), ///< See ::MBG_GPIO_FIXED_FREQ_8kHz + MSK_MBG_GPIO_FIXED_FREQ_48kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_48kHz ), ///< See ::MBG_GPIO_FIXED_FREQ_48kHz + MSK_MBG_GPIO_FIXED_FREQ_1MHz = ( 1UL << MBG_GPIO_FIXED_FREQ_1MHz ), ///< See ::MBG_GPIO_FIXED_FREQ_1MHz + MSK_MBG_GPIO_FIXED_FREQ_1544kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_1544kHz ), ///< See ::MBG_GPIO_FIXED_FREQ_1544kHz + MSK_MBG_GPIO_FIXED_FREQ_2048kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_2048kHz ), ///< See ::MBG_GPIO_FIXED_FREQ_2048kHz + MSK_MBG_GPIO_FIXED_FREQ_5MHz = ( 1UL << MBG_GPIO_FIXED_FREQ_5MHz ), ///< See ::MBG_GPIO_FIXED_FREQ_5MHz + MSK_MBG_GPIO_FIXED_FREQ_10MHz = ( 1UL << MBG_GPIO_FIXED_FREQ_10MHz ), ///< See ::MBG_GPIO_FIXED_FREQ_10MHz + MSK_MBG_GPIO_FIXED_FREQ_19440kHz = ( 1UL << MBG_GPIO_FIXED_FREQ_19440kHz ) ///< See ::MBG_GPIO_FIXED_FREQ_19440kHz +}; + + +/** + * @brief Initializers for an array of GPIO fixed frequency name strings + * + * @see ::MBG_GPIO_FIXED_FREQS + * @see ::MBG_GPIO_FIXED_FREQ_MASKS + */ +#define MBG_GPIO_FIXED_FREQ_STRS \ +{ \ + "8 kHz", \ + "48 kHz", \ + "1 MHz", \ + "1544 kHz", \ + "2048 kHz", \ + "5 MHz", \ + "10 MHz", \ + "19440 kHz" \ +} + + + +/** + * @brief Configuration of a GPIO fixed frequency output + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_FIXED_FREQ_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t freq_idx; ///< fixed frequency index, see ::MBG_GPIO_FIXED_FREQS + uint32_t shape; ///< selected signal shape, see ::MBG_GPIO_SIGNAL_SHAPES + uint32_t reserved; ///< reserved, currently always 0 + uint32_t flags; ///< reserved, currently always 0 + +} MBG_GPIO_FIXED_FREQ_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_fixed_freq_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->freq_idx ); \ + _mbg_swab32( &(_p)->shape ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Supported options for a fixed frequency output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_FIXED_FREQ_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_freq; ///< bit mask of supported fixed frequencies, see ::MBG_GPIO_FIXED_FREQ_MASKS + uint32_t supp_shapes; ///< bit mask of supported signal shapes, see ::MBG_GPIO_SIGNAL_SHAPE_MASKS + uint32_t reserved; ///< reserved, currently always 0 + uint32_t supp_flags; ///< reserved, currently always 0 + +} MBG_GPIO_FIXED_FREQ_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_fixed_freq_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_freq ); \ + _mbg_swab32( &(_p)->supp_shapes ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of BITS signal formats + * + * Used with ::MBG_GPIO_BITS_IN_SETTINGS::format and ::MBG_GPIO_BITS_OUT_SETTINGS::format + * + * @see ::MBG_GPIO_BITS_FORMAT_MASKS + */ +enum MBG_GPIO_BITS_FORMATS +{ + MBG_GPIO_BITS_E1_FRAMED, ///< 2.048 MBit + MBG_GPIO_BITS_T1_FRAMED, ///< 1.544 MBit + MBG_GPIO_BITS_E1_TIMING, ///< 2.048 MHz + MBG_GPIO_BITS_T1_TIMING, ///< 2.048 MHz + N_MBG_GPIO_BITS_FORMATS ///< number of defined formats +}; + + +/** + * @brief Bit masks associated with ::MBG_GPIO_BITS_FORMATS + * + * Used with ::MBG_GPIO_BITS_IN_SUPP::supp_fmts and ::MBG_GPIO_BITS_OUT_SUPP::supp_fmts. + * + * @see ::MBG_GPIO_BITS_FORMATS + */ +enum MBG_GPIO_BITS_FORMAT_MASKS +{ + MSK_MBG_GPIO_BITS_E1_FRAMED = ( 1UL << MBG_GPIO_BITS_E1_FRAMED ), ///< See ::MBG_GPIO_BITS_E1_FRAMED + MSK_MBG_GPIO_BITS_T1_FRAMED = ( 1UL << MBG_GPIO_BITS_T1_FRAMED ), ///< See ::MBG_GPIO_BITS_T1_FRAMED + MSK_MBG_GPIO_BITS_E1_TIMING = ( 1UL << MBG_GPIO_BITS_E1_TIMING ), ///< See ::MBG_GPIO_BITS_E1_TIMING + MSK_MBG_GPIO_BITS_T1_TIMING = ( 1UL << MBG_GPIO_BITS_T1_TIMING ) ///< See ::MBG_GPIO_BITS_T1_TIMING +}; + + +/** + * @brief Initializers for an array of GPIO bit format strings + * + * @see ::MBG_GPIO_BITS_FORMATS + * @see ::MBG_GPIO_BITS_FORMAT_MASKS + */ +#define MBG_GPIO_BITS_FORMAT_STRS \ +{ \ + "E1 Framed", \ + "T1 Framed", \ + "E1 Timing", \ + "T1 Timing" \ +} + + + +/** + * @brief Minimum and maximum known SSM values + * + * Values according to ITU G.704-1998 + * + * Used with ::MBG_GPIO_BITS_IN_SETTINGS::quality::e1.ssm + * and ::MBG_GPIO_BITS_OUT_SETTINGS::ssm. + */ +enum GPIO_SSM_VALS +{ + GPIO_SSM_UNKNOWN, ///< Quality unknown, existing synchronization network + GPIO_SSM_RSVD_1, ///< (reserved) + GPIO_SSM_G_811, ///< Rec. G.811 + GPIO_SSM_RSVD_3, ///< (reserved) + GPIO_SSM_SSU_A, ///< SSU-A + GPIO_SSM_RSVD_5, ///< (reserved) + GPIO_SSM_RSVD_6, ///< (reserved) + GPIO_SSM_RSVD_7, ///< (reserved) + GPIO_SSM_SSU_B, ///< SSU-B + GPIO_SSM_RSVD_9, ///< (reserved) + GPIO_SSM_RSVD_10, ///< (reserved) + GPIO_SSM_RSVD_SETS, ///< Synchronous Equipment Timing Source (SETS) + GPIO_SSM_RSVD_12, ///< (reserved) + GPIO_SSM_RSVD_13, ///< (reserved) + GPIO_SSM_RSVD_14, ///< (reserved) + GPIO_SSM_DONT_USE, ///< don't use + N_GPIO_SSM_VALS +}; + + + +/** + * @brief Minimum and maximum SA BITS groups + * + * Used with ::MBG_GPIO_BITS_IN_SETTINGS::quality::e1::sa_bits + * and ::MBG_GPIO_BITS_OUT_SETTINGS::sa_bits. + */ +enum GPIO_SA_BITS_GROUPS +{ + MIN_SA_BITS_GROUP = 4, + MAX_SA_BITS_GROUP = 8 +}; + + + +/** + * @brief Configuration of a GPIO as BITS input module + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_BITS_IN + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t format; ///< signal format, see ::MBG_GPIO_BITS_FORMATS + uint32_t reserved; ///< reserved, currently always 0 + uint32_t csc_limit; ///< max. cycle slip [1/1000 cycle units] + + union quality + { + struct e1 + { + uint8_t ssm; ///< minimum E1 SSM for acceptance, 0..::N_GPIO_SSM_VALS-1 + uint8_t sa_bits; ///< sa bits group carrying SSM, ::MIN_SA_BITS_GROUP..::MAX_SA_BITS_GROUP + uint16_t reserved; ///< reserved, currently always 0 + } e1; ///< used with E1 formats + + struct t1 + { + uint8_t min_boc; + uint8_t reserved_0; ///< reserved, currently always 0 + uint16_t reserved_1; ///< reserved, currently always 0 + } t1; ///< used with T1 formats + + uint32_t u32; ///< dummy to force at least 32 bit alignment + + } quality; + + uint32_t err_msk; ///< controls which types of error can be ignored, see ::MBG_GPIO_BITS_ERR_MASKS + uint32_t flags; ///< reserved, currently always 0 + +} MBG_GPIO_BITS_IN_SETTINGS; + +#define _mbg_swab_mbg_gpio_bits_in_settings( _p, _recv ) \ +do \ +{ \ + uint32_t f = (_p)->format; \ + if ( (_recv) ) \ + _mbg_swab32( &f); \ + _mbg_swab32( &(_p)->format ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->csc_limit ); \ + switch( f ) \ + { \ + case MBG_GPIO_BITS_E1_FRAMED : \ + case MBG_GPIO_BITS_E1_TIMING : \ + _mbg_swab8( &(_p)->quality.e1.ssm ); \ + _mbg_swab8( &(_p)->quality.e1.sa_bits ); \ + _mbg_swab16( &(_p)->quality.e1.reserved ); \ + break; \ + \ + case MBG_GPIO_BITS_T1_FRAMED : \ + case MBG_GPIO_BITS_T1_TIMING : \ + _mbg_swab8( &(_p)->quality.t1.min_boc ); \ + _mbg_swab8( &(_p)->quality.t1.reserved_0 ); \ + _mbg_swab16( &(_p)->quality.t1.reserved_1 ); \ + break; \ + \ + default: \ + break; \ + } \ + _mbg_swab32( &(_p)->err_msk ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of BITS input error conditions + */ +enum MBG_GPIO_BITS_ERRS +{ + MBG_GPIO_BITS_ERR_LOS, ///< loss of signal + MBG_GPIO_BITS_ERR_LOF, ///< loss of frame + N_MBG_GPIO_BITS_ERRS ///< number of known errors +}; + + +/** + * @brief Bit masks associated with BITS input error conditions + * + * Used with ::MBG_GPIO_BITS_IN_SETTINGS::err_msk + * + * @see ::MBG_GPIO_BITS_ERRS + */ +enum MBG_GPIO_BITS_ERR_MASKS +{ + MSK_MBG_GPIO_BITS_ERR_LOS = ( 1UL << MBG_GPIO_BITS_ERR_LOS ), ///< See ::MBG_GPIO_BITS_ERR_LOS + MSK_MBG_GPIO_BITS_ERR_LOF = ( 1UL << MBG_GPIO_BITS_ERR_LOF ) ///< See ::MBG_GPIO_BITS_ERR_LOF +}; + + + +/** + * @brief Supported options of a BITS GPIO input + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_BITS_IN + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS + uint32_t reserved; ///< reserved, currently always 0 + +} MBG_GPIO_BITS_IN_SUPP; + +#define _mbg_swab_mbg_gpio_bits_in_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_fmts ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + + + +/** + * @brief Configuration of a GPIO as BITS output module + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_BITS_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t format; ///< signal format, see ::MBG_GPIO_BITS_FORMATS + uint32_t flags; ///< flags for encoder control etc., see ::MBG_GPIO_BITS_OUT_FLAG_MASKS + uint8_t sa_bits; ///< number of SA bit group for E1 SSM, ::MIN_SA_BITS_GROUP..::MAX_SA_BITS_GROUP + uint8_t ssm; ///< ssm for E1 mode, 0..::N_GPIO_SSM_VALS-1 + uint8_t boc; ///< boc for T1 mode, 0..0x1F //##++++++++++++++ + uint8_t reserved_0; ///< reserved, currently always 0 + uint32_t reserved_1; ///< reserved, currently always 0 + uint32_t reserved_2; ///< reserved, currently always 0 + uint32_t reserved_3; ///< reserved, currently always 0 + +} MBG_GPIO_BITS_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_bits_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->format ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab8( &(_p)->sa_bits ); \ + _mbg_swab8( &(_p)->ssm ); \ + _mbg_swab8( &(_p)->boc ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of flags used with BITS type GPIO outputs + * + * @see ::MBG_GPIO_BITS_OUT_FLAG_MASKS + * @see ::MBG_GPIO_BITS_OUT_FLAG_STRS + */ +enum MBG_GPIO_BITS_OUT_FLAGS +{ + MBG_GPIO_BITS_OUT_FLAG_HDB3, ///< enable HDB3 encoding (E1 mode only) + MBG_GPIO_BITS_OUT_FLAG_B8ZS, ///< enable B8ZS encoding (T1 mode only) + N_MBG_GPIO_BITS_OUT_FLAGS ///< number of known flags +}; + + +/** + * @brief Bit masks associated with ::MBG_GPIO_BITS_OUT_FLAGS + * + * Used with ::MBG_GPIO_BITS_OUT_SETTINGS::flags + * + * @see ::MBG_GPIO_BITS_OUT_FLAGS + * @see ::MBG_GPIO_BITS_OUT_FLAG_STRS + */ +enum MBG_GPIO_BITS_OUT_FLAG_MASKS +{ + MSK_MBG_GPIO_BITS_OUT_FLAG_HDB3 = ( 1UL << MBG_GPIO_BITS_OUT_FLAG_HDB3 ), ///< See ::MBG_GPIO_BITS_OUT_FLAG_HDB3 + MSK_MBG_GPIO_BITS_OUT_FLAG_B8ZS = ( 1UL << MBG_GPIO_BITS_OUT_FLAG_B8ZS ) ///< See ::MBG_GPIO_BITS_OUT_FLAG_B8ZS +}; + + +/** + * @brief String initializers for an array of GPIO BITS out flags + * + * @see ::MBG_GPIO_BITS_OUT_FLAGS + * @see ::MBG_GPIO_BITS_OUT_FLAG_MASKS + */ +#define MBG_GPIO_BITS_OUT_FLAG_STRS \ +{ \ + "HDB3", \ + "B8ZS" \ +} + + +/** + * @brief Supported options of a BITS type GPIO output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_BITS_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_fmts; ///< bit mask of supported formats, see ::MBG_GPIO_BITS_FORMAT_MASKS + uint32_t supp_flags; ///< bit mask of supported flags, see ::MBG_GPIO_BITS_OUT_FLAG_MASKS + +} MBG_GPIO_BITS_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_bits_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_fmts ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of Video signal formats + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::format + * + * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS + */ +enum MBG_GPIO_VIDEO_FORMATS +{ + MBG_GPIO_VIDEO_FORMAT_OFF, ///< OFF + MBG_GPIO_VIDEO_SD_FORMAT_NTSC, ///< NTSC 525i + MBG_GPIO_VIDEO_SD_FORMAT_PAL, ///< PAL standard (Germany) 625i + MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz, ///< SMPTE296M-3 720p at 50 Hz + MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz, ///< SMPTE274M-6 1080i at 50 Hz + MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz, ///< SMPTE296M-1 720p at 59.94 Hz + MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz, ///< SMPTE274M-7 1080i at 59.94 Hz + MBG_GPIO_VIDEO_SD_FORMAT_PAL_M, ///< PAL M (Brazil) 525i + N_MBG_GPIO_VIDEO_FORMATS ///< number of defined video formats +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_FORMATS + * + * Used with ::MBG_GPIO_VIDEO_OUT_SUPP::supp_formats + * + * @see ::MBG_GPIO_VIDEO_FORMATS + */ +enum MBG_GPIO_VIDEO_FORMAT_MASKS +{ + MSK_MBG_GPIO_VIDEO_FORMAT_OFF = ( 1UL << MBG_GPIO_VIDEO_FORMAT_OFF ), ///< See ::MBG_GPIO_VIDEO_FORMAT_OFF + MSK_MBG_GPIO_VIDEO_SD_FORMAT_NTSC = ( 1UL << MBG_GPIO_VIDEO_SD_FORMAT_NTSC ), ///< See ::MBG_GPIO_VIDEO_SD_FORMAT_NTSC + MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL = ( 1UL << MBG_GPIO_VIDEO_SD_FORMAT_PAL ), ///< See ::MBG_GPIO_VIDEO_SD_FORMAT_PAL + MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz ), ///< See ::MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz + MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz ), ///< See ::MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz + MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz ), ///< See ::MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz + MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz = ( 1UL << MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz ), ///< See ::MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz + MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL_M = ( 1UL << MBG_GPIO_VIDEO_SD_FORMAT_PAL_M ) ///< See ::MBG_GPIO_VIDEO_SD_FORMAT_PAL_M +}; + + +/** + * @brief A combination of bit masks for SD video formats + * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS + */ +#define MBG_GPIO_VIDEO_SD_FORMATS ( MSK_MBG_GPIO_VIDEO_FORMAT_OFF | MSK_MBG_GPIO_VIDEO_SD_FORMAT_NTSC | MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL | \ + MSK_MBG_GPIO_VIDEO_SD_FORMAT_PAL_M ) + +/** + * @brief A combination of bit masks for HD video formats + * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS + */ +#define MBG_GPIO_VIDEO_HD_FORMATS ( MSK_MBG_GPIO_VIDEO_FORMAT_OFF | MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_50Hz | MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_50Hz | \ + MSK_MBG_GPIO_VIDEO_HD_FORMAT_720_P_59_94Hz | MSK_MBG_GPIO_VIDEO_HD_FORMAT_1080_I_59_94Hz ) + + + +/** + * @brief Initializers for an array of video format strings + * + * @see ::MBG_GPIO_VIDEO_FORMATS + * @see ::MBG_GPIO_VIDEO_FORMAT_MASKS + */ +#define MBG_GPIO_VIDEO_FORMAT_STRS \ +{ \ + "OFF", \ + "NTSC (525i)", \ + "PAL (625i)", \ + "720p 50 Hz", \ + "1080i 50 Hz", \ + "720p 59.94 Hz", \ + "1080i 59.94 Hz", \ + "PAL M (525i)" \ +} + + + +/** + * @brief Enumeration of flags used with video type GPIO outputs + */ +enum MBG_GPIO_VIDEO_OUT_FLAGS +{ + MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF, ///< if set, Out1: HD, Out2: SD + MBG_GPIO_VIDEO_OUT_HAS_TC_SD, ///< supports Time Code for SD Black Bursts + N_MBG_GPIO_VIDEO_OUT_FLAGS ///< number of known flags +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_OUT_FLAGS + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::flags + * + * @see ::MBG_GPIO_VIDEO_OUT_FLAGS + */ +enum MBG_GPIO_VIDEO_OUT_FLAG_MASKS +{ + MSK_MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF = ( 1UL << MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF ), ///< See ::MBG_GPIO_VIDEO_OUT_HAS_NO_FREE_CONF + MSK_MBG_GPIO_VIDEO_OUT_HAS_TC_SD = ( 1UL << MBG_GPIO_VIDEO_OUT_HAS_TC_SD ) ///< See ::MBG_GPIO_VIDEO_OUT_HAS_TC_SD +}; + + + +/** + * @brief Enumeration of epochs used with video type GPIO outputs + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::epoch, and used to + * define ::MBG_GPIO_VIDEO_EPOCH_MASKS + * + * @see ::MBG_GPIO_VIDEO_EPOCH_MASKS + * @see ::MBG_GPIO_VIDEO_EPOCH_STRS + */ +enum MBG_GPIO_VIDEO_EPOCHS +{ + SMPTE_TAI_EPOCH_1970, ///< 1970-01-01 00:00:00 + SMPTE_TAI_EPOCH_1958, ///< 1958-01-01 00:00:00 + SMPTE_UTC_EPOCH_1972, ///< 1972-01-01 00:00:00 + SMPTE_GPS_EPOCH_1980, ///< 1980-01-06 00:00:00 + N_MBG_GPIO_VIDEO_EPOCHS ///< number of known epochs +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_EPOCHS + * + * Used with :: MBG_GPIO_VIDEO_OUT_SUPP::supp_epochs + * + * @see ::MBG_GPIO_VIDEO_EPOCHS + */ +enum MBG_GPIO_VIDEO_EPOCH_MASKS +{ + MSK_SMPTE_TAI_EPOCH_1970 = ( 1UL << SMPTE_TAI_EPOCH_1970 ), ///< See ::SMPTE_TAI_EPOCH_1970 + MSK_SMPTE_TAI_EPOCH_1958 = ( 1UL << SMPTE_TAI_EPOCH_1958 ), ///< See ::SMPTE_TAI_EPOCH_1958 + MSK_SMPTE_UTC_EPOCH_1972 = ( 1UL << SMPTE_UTC_EPOCH_1972 ), ///< See ::SMPTE_UTC_EPOCH_1972 + MSK_SMPTE_GPS_EPOCH_1980 = ( 1UL << SMPTE_GPS_EPOCH_1980 ) ///< See ::SMPTE_GPS_EPOCH_1980 +}; + + + +/** + * @brief Initializers for an array of video epoch strings + * + * @see ::MBG_GPIO_VIDEO_EPOCHS + */ +#define MBG_GPIO_VIDEO_EPOCH_STRS \ +{ \ + "TAI D1970-01-01 T00:00:00", \ + "TAI D1958-01-01 T00:00:00", \ + "UTC D1972-01-01 T00:00:00", \ + "GPS D1980-01-06 T00:00:00" \ +} + + + +/** + * @brief Enumeration of time code modes used with video type GPIO outputs + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::tc_mode + * + */ +enum MBG_GPIO_VIDEO_TC_MODES +{ + MBG_GPIO_VIDEO_TC_MODE_NONE, ///< None + MBG_GPIO_VIDEO_TC_MODE_VITC, ///< Vertical Interval Time Code + N_MBG_GPIO_VIDEO_TC_MODES +}; + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_TC_MODES + * + * Used with ::MBG_GPIO_VIDEO_OUT_SETTINGS::tc_mode + * + */ +enum MBG_GPIO_VIDEO_TC_MODE_MASKS +{ + MSK_MBG_GPIO_VIDEO_TC_MODE_NONE = ( 1UL << MBG_GPIO_VIDEO_TC_MODE_NONE ), ///< See ::MBG_GPIO_VIDEO_TC_MODE_NONE + MSK_MBG_GPIO_VIDEO_TC_MODE_VITC = ( 1UL << MBG_GPIO_VIDEO_TC_MODE_VITC ) ///< See ::MBG_GPIO_VIDEO_TC_MODE_VITC +}; + + +/** + * @brief Initializers for an array of video time code modes + * + * @see ::MBG_GPIO_VIDEO_TC_MODES + */ +#define MBG_GPIO_VIDEO_TC_MODE_STRS \ +{ \ + "None", \ + "VITC" \ +} + + + +/** + * @brief Configuration of a GPIO as video output module + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_VIDEO_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t format; ///< video format, see ::MBG_GPIO_VIDEO_FORMATS + uint32_t flags; ///< flags, see ::MBG_GPIO_VIDEO_OUT_FLAG_MASKS + int32_t phase_offset; ///< Phase offset in [ns] + uint8_t epoch; ///< epoch, see ::MBG_GPIO_VIDEO_EPOCHS + + uint8_t tc_mode; ///< time code mode, see ::MBG_GPIO_VIDEO_TC_MODES + uint8_t tc_line0; ///< first time code line location, valid lines: 6-22 + uint8_t tc_line1; ///< second time code line location, valid lines: 6-22 + + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + +} MBG_GPIO_VIDEO_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_video_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->format ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->phase_offset ); \ + _mbg_swab8( &(_p)->epoch ); \ + _mbg_swab8( &(_p)->tc_mode ); \ + _mbg_swab8( &(_p)->tc_line0 ); \ + _mbg_swab8( &(_p)->tc_line1 ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ +} while ( 0 ) + + + +/** + * @brief Supported options of a video type GPIO output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_VIDEO_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_formats; ///< supported video formats, see ::MBG_GPIO_VIDEO_FORMAT_MASKS + uint32_t supp_flags; ///< supported flags, see ::MBG_GPIO_VIDEO_OUT_FLAG_MASKS + uint32_t supp_epochs; ///< supported epochs, see ::MBG_GPIO_VIDEO_EPOCH_MASKS + + uint8_t supp_tc_modes; ///< supported tc_modes, see ::MBG_GPIO_VIDEO_TC_MODE_MASKS + + uint8_t reserved0; ///< reserved, currently always 0 + uint8_t reserved2; ///< reserved, currently always 0 + uint16_t reserved3; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + +} MBG_GPIO_VIDEO_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_video_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_formats ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->supp_epochs ); \ + _mbg_swab8( &(_p)->supp_tc_modes ); \ + _mbg_swab8( &(_p)->reserved0 ); \ + _mbg_swab16( &(_p)->reserved2 ); \ + _mbg_swab16( &(_p)->reserved3 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of types used with video sync GPIO outputs + * Depends on configured video output + */ +enum MBG_GPIO_VIDEO_SYNC_TYPES +{ + MBG_GPIO_VIDEO_SYNC_TYPE_OFF, ///< Output Off + MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC, ///< SD horizontal sync + MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC, ///< SD vertical sync + MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME, ///< SD frame/field sync + MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK, ///< SD blanking interval + MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC, ///< HD horizontal sync + MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC, ///< HD vertical sync + MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME, ///< HD frame/field sync + MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK, ///< HD blanking interval + N_MBG_GPIO_VIDEO_SYNC_TYPES ///< number of known types +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_SYNC_TYPES + * + * Used with ::MBG_GPIO_VIDEO_SYNC_OUT_SUPP::supp_types + * + * @see ::MBG_GPIO_VIDEO_SYNC_TYPES + */ +enum MBG_GPIO_VIDEO_SYNC_TYPE_MASKS +{ + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_OFF = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_OFF ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME ), + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK = ( 1UL << MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK ) +}; + + + +/** + * @brief Initializers for an array of video sync output name strings + * + * @see ::MBG_GPIO_VIDEO_SYNC_TYPES + * @see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS + */ +#define MBG_GPIO_VIDEO_SYNC_OUT_STRS \ +{ \ + "OFF", \ + "SD H-Sync", \ + "SD V-Sync", \ + "SD Frame", \ + "SD Blank", \ + "HD H-Sync", \ + "HD V-Sync", \ + "HD Frame", \ + "HD Blank" \ +} + + + +/** + * @brief A combination of bit masks for SD video sync types + * @see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS + */ +#define MBG_GPIO_VIDEO_SYNC_SD_TYPES ( MSK_MBG_GPIO_VIDEO_SYNC_TYPE_OFF | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_HSYNC | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_VSYNC | \ + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_FRAME | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_SD_BLANK ) + +/** + * @brief A combination of bit masks for HD video sync types + * @see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS + */ +#define MBG_GPIO_VIDEO_SYNC_HD_TYPES ( MSK_MBG_GPIO_VIDEO_SYNC_TYPE_OFF | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_HSYNC | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_VSYNC | \ + MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_FRAME | MSK_MBG_GPIO_VIDEO_SYNC_TYPE_HD_BLANK ) + + + +/** + * @brief Configuration of a GPIO as sync output module + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t type; ///< sync type, see :: MBG_GPIO_SYNC_TYPES + uint32_t flags; ///< flags, currently always 0 + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + uint32_t reserved2; ///< reserved, currently always 0 + uint32_t reserved3; ///< reserved, currently always 0 + +} MBG_GPIO_VIDEO_SYNC_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_video_sync_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->type ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ + _mbg_swab32( &(_p)->reserved2 ); \ + _mbg_swab32( &(_p)->reserved3 ); \ +} while ( 0 ) + + + +/** + * @brief Supported options of a sync type GPIO output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_types; ///< supported types, see ::MBG_GPIO_VIDEO_SYNC_TYPE_MASKS + uint32_t supp_flags; ///< supported flags, currently always 0 + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + +} MBG_GPIO_VIDEO_SYNC_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_video_sync_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_types ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of studio clock base frequencies + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS::base_freq + * + * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS + */ +enum MBG_GPIO_STUDIO_CLOCK_BASE_FREQS +{ + MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ, ///< 32 kHz base frequency + MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ, ///< 44.1 kHz base frequency + MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ, ///< 48 kHz base frequency + N_MBG_GPIO_STUDIO_CLOCK_BASE_FREQS ///< number of defined base frequencies +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SUPP::supp_base_freqs + * + * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS + */ +enum MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS +{ + MSK_MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ = ( 1UL << MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ ), ///< See ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_32KHZ + MSK_MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ = ( 1UL << MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ ), ///< See ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_44_1KHZ + MSK_MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ = ( 1UL << MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ ) ///< See ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_48KHZ +}; + + + +/** + * @brief Initializers for an array of base frequencies of studio clock output name strings + * + * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS + * @see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS + */ +#define MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_STRS \ +{ \ + "32 kHz", \ + "44.1 kHz", \ + "48 kHz" \ +} + + + +/** + * @brief Enumeration of studio clock scales + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS::scale + * Multiply scale with base frequency + * + * @see ::MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS + */ +enum MBG_GPIO_STUDIO_CLOCK_SCALES +{ + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32, + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16, + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8, + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4, + MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2, + MBG_GPIO_STUDIO_CLOCK_SCALE_1, + MBG_GPIO_STUDIO_CLOCK_SCALE_2, + MBG_GPIO_STUDIO_CLOCK_SCALE_4, + MBG_GPIO_STUDIO_CLOCK_SCALE_8, + MBG_GPIO_STUDIO_CLOCK_SCALE_16, + MBG_GPIO_STUDIO_CLOCK_SCALE_32, + MBG_GPIO_STUDIO_CLOCK_SCALE_64, + MBG_GPIO_STUDIO_CLOCK_SCALE_128, + MBG_GPIO_STUDIO_CLOCK_SCALE_256, + MBG_GPIO_STUDIO_CLOCK_SCALE_512, + N_MBG_GPIO_STUDIO_CLOCK_SCALES ///< number of defined scales +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_STUDIO_CLOCK_SCALES + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SUPP::supp_scales[N_MBG_GPIO_STUDIO_CLOCK_BASE_FREQS] + * + * @see ::MBG_GPIO_STUDIO_CLOCK_SCALES + */ +enum MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS +{ + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_32 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_16 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_8 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_4 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_1_DIV_2 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_1 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_1 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_1 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_2 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_2 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_2 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_4 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_4 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_4 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_8 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_8 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_8 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_16 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_16 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_16 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_32 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_32 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_32 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_64 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_64 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_64 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_128 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_128 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_128 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_256 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_256 ), ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_256 + MSK_MBG_GPIO_STUDIO_CLOCK_SCALE_512 = ( 1U << MBG_GPIO_STUDIO_CLOCK_SCALE_512 ) ///< See ::MBG_GPIO_STUDIO_CLOCK_SCALE_512 +}; + + + +/** + * @brief Initializers for an array of scales of studio clock output name strings + * + * @see ::MBG_GPIO_STUDIO_CLOCK_SCALES + * @see ::MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS + */ +#define MBG_GPIO_STUDIO_CLOCK_SCALE_STRS \ +{ \ + "1/32", \ + "1/16", \ + "1/8", \ + "1/4", \ + "1/2", \ + "1", \ + "2", \ + "4", \ + "8", \ + "16", \ + "32", \ + "64", \ + "128", \ + "256", \ + "512" \ +} + + + +/** + * @brief Enumeration of flags used with studio clock type GPIO outputs + */ +enum MBG_GPIO_STUDIO_CLOCK_FLAGS +{ + MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED, ///< if set, enables output + N_MBG_GPIO_STUDIO_CLOCK_FLAGS ///< number of known flags +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_STUDIO_CLOCK_FLAGS + * + * Used with ::MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS::flags + * + * @see ::MBG_GPIO_STUDIO_CLOCK_FLAGS + */ +enum MBG_GPIO_STUDIO_CLOCK_FLAG_MASKS +{ + MSK_MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED = ( 1UL << MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED ) ///< See ::MBG_GPIO_STUDIO_CLOCK_OUTPUT_ENABLED +}; + + + +/** + * @brief Configuration of a GPIO as studio clock output module + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t base_freq; ///< base frequency, see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQS + uint32_t scale; ///< scale, see ::MBG_GPIO_STUDIO_CLOCK_SCALES + uint32_t flags; ///< flags, see ::MBG_GPIO_STUDIO_CLOCK_FLAGS + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + +} MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS; + +#define _mbg_swab_mbg_gpio_studio_clock_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->base_freq ); \ + _mbg_swab32( &(_p)->scale ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ +} while ( 0 ) + + + +#define MAX_SUPP_BASE_FREQUENCIES 8 ///< max. supported base frequencies for studio clock outputs + +/** + * @brief Configuration of a GPIO as studio clock output module + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint8_t supp_base_freqs; ///< supported base frequencies, see ::MBG_GPIO_STUDIO_CLOCK_BASE_FREQ_MASKS + uint8_t reserved0; ///< reserved, currently always 0 + uint16_t reserved1; ///< reserved, currently always 0 + uint16_t supp_scales[MAX_SUPP_BASE_FREQUENCIES]; ///< supported scales for each base frequency, see ::MBG_GPIO_STUDIO_CLOCK_SCALE_MASKS + uint32_t supp_flags; ///< supported flags, see::MBG_GPIO_STUDIO_CLOCK_FLAG_MASKS + uint32_t reserved2; ///< reserved, currently always 0 + +} MBG_GPIO_STUDIO_CLOCK_OUT_SUPP; + +#define _mbg_swab_mbg_gpio_studio_clock_out_supp( _p ) \ +do \ +{ \ + uint8_t idx; \ + _mbg_swab8( &(_p)->supp_base_freqs ); \ + _mbg_swab8( &(_p)->reserved0 ); \ + _mbg_swab16( &(_p)->reserved1 ); \ + for( idx = 0; idx < MAX_SUPP_BASE_FREQUENCIES; idx++ ) \ + _mbg_swab16( &(_p)->supp_scales[idx] ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved2 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of types used with GPIO type digital audio outputs + * + * Used with ::MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS::type, and to + * define ::MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS + * + * @see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS + * @see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_STRS + */ +enum MBG_GPIO_DIGITAL_AUDIO_TYPES +{ + MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF, + MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS, ///< DARS + N_MBG_GPIO_DIGITAL_AUDIO_TYPES ///< number of known types +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_DIGITAL_AUDIO_TYPES + * + * Used with :: MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT_SUPP::supp_types + * + * @see ::MBG_GPIO_DIGITAL_AUDIO_TYPES + */ +enum MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS +{ + MSK_MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF = ( 1UL << MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF ), ///< See ::MBG_GPIO_DIGITAL_AUDIO_TYPE_OFF + MSK_MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS = ( 1UL << MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS ) ///< See ::MBG_GPIO_DIGITAL_AUDIO_TYPE_DARS +}; + + + +/** + * @brief Initializers for an array of video epoch strings + * + * @see ::MBG_GPIO_VIDEO_EPOCHS + */ +#define MBG_GPIO_DIGITAL_AUDIO_TYPE_STRS \ +{ \ + "OFF", \ + "DARS" \ +} + + + +/** + * @brief Enumeration of flags used with GPIO type digital audio outputs + */ +enum MBG_GPIO_DIGITAL_AUDIO_FLAGS +{ + MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG, ///< reserved + N_MBG_GPIO_DIGITAL_AUDIO_FLAGS ///< number of known flags +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_DIGITAL_AUDIO_FLAGS + * + * Used with ::MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS::flags + * + * @see ::MBG_GPIO_DIGITAL_AUDIO_FLAGS + */ +enum MBG_GPIO_DIGITAL_AUDIO_FLAG_MASKS +{ + MSK_MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG = ( 1UL << MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG ) ///< See ::MBG_GPIO_DIGITAL_AUDIO_RESERVED_FLAG +}; + + + +/** + * @brief Configuration of a GPIO digital audio output + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t type; ///< digital audio type, see ::MBG_GPIO_DIGITAL_AUDIO_TYPES + uint32_t flags; ///< reserved, currently always 0 + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + uint32_t reserved2; ///< reserved, currently always 0 + +} MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS; + + + +#define _mbg_swab_mbg_gpio_digital_audio_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->type ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ + _mbg_swab32( &(_p)->reserved2 ); \ +} while ( 0 ) + + + +/** + * @brief Supported options for digital audio output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_types; ///< supported digital audio types, see ::MBG_GPIO_DIGITAL_AUDIO_TYPE_MASKS + uint32_t supp_flags; ///< reserved, currently always 0 + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + uint32_t reserved2; ///< reserved, currently always 0 + +} MBG_GPIO_DIGITAL_AUDIO_OUT_SUPP; + + + +#define _mbg_swab_mbg_gpio_digital_audio_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_types ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ + _mbg_swab32( &(_p)->reserved2 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of physical video input signal sources + * + * Video can be received over a single or differential signals + * + * @see MBG_GPIO_VIDEO_IN_SETTINGS + */ +enum MBG_GPIO_VIDEO_IN_SIGNAL_SRCS +{ + MBG_GPIO_VIDEO_IN_SIGNAL_SRC_SES, ///< single-ended signal video input + MBG_GPIO_VIDEO_IN_SIGNAL_SRC_DIFFERENTIAL, ///< differential signal line video input + N_MBG_GPIO_VIDEO_IN_SIGNAL_SRCS ///< number of possible signal sources +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_VIDEO_IN_SIGNAL_SRCS + * + * Used with ::MBG_GPIO_VIDEO_IN_SETTINGS::tc_mode + * + */ +enum MBG_GPIO_VIDEO_IN_SIGNAL_SRC_MASKS +{ + MSK_MBG_GPIO_VIDEO_IN_SIGNAL_SRC_SES = ( 1UL << MBG_GPIO_VIDEO_IN_SIGNAL_SRC_SES ), ///< See ::MBG_GPIO_VIDEO_IN_SIGNAL_SRC_SES + MSK_MBG_GPIO_VIDEO_IN_SIGNAL_SRC_DIFFERENTIAL = ( 1UL << MBG_GPIO_VIDEO_IN_SIGNAL_SRC_DIFFERENTIAL ) ///< See ::MBG_GPIO_VIDEO_IN_SIGNAL_SRC_DIFFERENTIAL +}; + + + + +/** + * @brief Initializers for an array of video signal input source strings + * + * @see ::MBG_GPIO_VIDEO_IN_SIGNAL_SRCS + * @see ::MBG_GPIO_VIDEO_IN_SIGNAL_SRC_MASKS + */ +#define MBG_GPIO_VIDEO_IN_SIGNAL_SRC_STRS \ +{ \ + "Single-ended signal input", \ + "Differential signal input" \ +} + + + +/** + * @brief Configuration of a GPIO as video input module + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS + * + * @see ::MBG_GPIO_TYPE_VIDEO_IN + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t format; ///< video format, see ::MBG_GPIO_VIDEO_FORMATS + + uint8_t epoch; ///< epoch, see ::MBG_GPIO_VIDEO_EPOCHS + uint8_t signal_src; ///< video input signal source, see ::MBG_GPIO_VIDEO_IN_SIGNAL_SRCS + uint8_t tc_mode; ///< time code mode, see ::MBG_GPIO_VIDEO_TC_MODES + uint8_t tc_line; ///< time code line location, valid lines: 6-22 + + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + uint32_t reserved2; ///< reserved, currently always 0 +} MBG_GPIO_VIDEO_IN_SETTINGS; + + + +#define _mbg_swab_mbg_gpio_video_in_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->format ); \ + _mbg_swab8( &(_p)->epoch ); \ + _mbg_swab8( &(_p)->signal_src ); \ + _mbg_swab8( &(_p)->tc_mode ); \ + _mbg_swab8( &(_p)->tc_line ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ + _mbg_swab32( &(_p)->reserved2 ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t supp_formats; ///< supported video formats, see ::MBG_GPIO_VIDEO_FORMAT_MASKS + uint32_t supp_epochs; ///< supported epochs, see ::MBG_GPIO_VIDEO_EPOCH_MASKS + + uint32_t supp_signal_srcs; ///< video input signal sources, see ::MBG_GPIO_VIDEO_IN_SIGNAL_SRC_MASKS + uint32_t supp_tc_modes; ///< time code mode, see ::MBG_GPIO_VIDEO_TC_MODE_MASKS + + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + uint32_t reserved2; ///< reserved, currently always 0 + +} MBG_GPIO_VIDEO_IN_SUPP; + + + +#define _mbg_swab_mbg_gpio_video_in_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_formats ); \ + _mbg_swab32( &(_p)->supp_epochs ); \ + _mbg_swab32( &(_p)->supp_signal_srcs ); \ + _mbg_swab32( &(_p)->supp_tc_modes ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ + _mbg_swab32( &(_p)->reserved2 ); \ + _mbg_swab32( &(_p)->reserved3 ); \ +} while ( 0 ) + + +/** + * @brief Enumeration of types used with GPIO type LTC outputs + * + * Used with ::MBG_GPIO_LTC_OUT_SETTINGS::type, and to + * define ::MBG_GPIO_LTC_OUT_TYPE_MASKS + * + * @see ::MBG_GPIO_LTC_OUT_TYPE_MASKS + * @see ::MBG_GPIO_LTC_OUT_TYPE_STRS + */ +enum MBG_GPIO_LTC_OUT_TYPES +{ + MBG_GPIO_LTC_OUT_OFF, + MBG_GPIO_LTC_OUT_TYPE_24FPS_23_976Hz, + MBG_GPIO_LTC_OUT_TYPE_24FPS, + MBG_GPIO_LTC_OUT_TYPE_25FPS, + MBG_GPIO_LTC_OUT_TYPE_30FPS, + MBG_GPIO_LTC_OUT_TYPE_30FPS_DROP_FRAME, + N_MBG_GPIO_LTC_OUT_TYPES ///< number of known types +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_LTC_OUT_TYPES + * + * Used with :: MBG_GPIO_TYPE_LTC_OUT_SUPP::supp_types + * + * @see ::MBG_GPIO_LTC_OUT_TYPES + */ +enum MBG_GPIO_LTC_OUT_TYPE_MASKS +{ + MSK_MBG_GPIO_LTC_OUT_OFF = ( 1UL << MBG_GPIO_LTC_OUT_OFF ), ///< See ::MBG_GPIO_LTC_OUT_OFF + MSK_MBG_GPIO_LTC_OUT_TYPE_24FPS_23_976Hz = ( 1UL << MBG_GPIO_LTC_OUT_TYPE_24FPS_23_976Hz ), ///< See ::MBG_GPIO_LTC_OUT_TYPE_24FPS_23_976Hz + MSK_MBG_GPIO_LTC_OUT_TYPE_24FPS = ( 1UL << MBG_GPIO_LTC_OUT_TYPE_24FPS ), ///< See ::MBG_GPIO_LTC_OUT_TYPE_24FPS + MSK_MBG_GPIO_LTC_OUT_TYPE_25FPS = ( 1UL << MBG_GPIO_LTC_OUT_TYPE_25FPS ), ///< See ::MBG_GPIO_LTC_OUT_TYPE_25FPS + MSK_MBG_GPIO_LTC_OUT_TYPE_30FPS = ( 1UL << MBG_GPIO_LTC_OUT_TYPE_30FPS ), ///< See ::MBG_GPIO_LTC_OUT_TYPE_30FPS + MSK_MBG_GPIO_LTC_OUT_TYPE_30FPS_DROP_FRAME = ( 1UL << MBG_GPIO_LTC_OUT_TYPE_30FPS_DROP_FRAME ) ///< See ::MBG_GPIO_LTC_OUT_TYPE_30FPS_DROP_FRAME +}; + +/** + * @brief Initializers for an array of ltc out strings + * + * @see ::MBG_GPIO_LTC_OUT_TYPES + */ +#define MBG_GPIO_LTC_OUT_TYPE_STRS \ +{ \ + "OFF", \ + "LTC 24FPS / 23.976Hz", \ + "LTC 24FPS", \ + "LTC 25FPS", \ + "LTC 30FPS", \ + "LTC 30FPS Drop Frame" \ +} + +/** + * @brief Enumeration of flags used with GPIO type LTC outputs + */ +enum MBG_GPIO_LTC_OUT_FLAGS +{ + MBG_GPIO_LTC_OUT_RESERVED_FLAG, ///< reserved + N_MBG_GPIO_LTC_OUT_FLAGS ///< number of known flags +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_LTC_OUT_FLAGS + * + * Used with ::MBG_GPIO_LTC_OUT_SETTINGS::flags + * + * @see ::MBG_GPIO_LTC_OUT_FLAGS + */ +enum MBG_GPIO_LTC_OUT_FLAG_MASKS +{ + MSK_MBG_GPIO_LTC_OUT_RESERVED_FLAG = ( 1UL << MBG_GPIO_LTC_OUT_RESERVED_FLAG ) ///< See ::MBG_GPIO_LTC_OUT_RESERVED_FLAG +}; + + + +/** + * @brief Configuration of a GPIO LTC output + * + * Used as sub-structure of ::MBG_GPIO_SETTINGS. + * + * @see ::MBG_GPIO_TYPE_LTC_OUT + * @see ::MBG_GPIO_SETTINGS + */ +typedef struct +{ + uint32_t type; ///< LTC type, see ::MBG_GPIO_LTC_OUT_TYPES + uint32_t flags; ///< reserved, currently always 0 + uint32_t reserved0; ///< reserved, currently always 0 + uint32_t reserved1; ///< reserved, currently always 0 + uint32_t reserved2; ///< reserved, currently always 0 + +} MBG_GPIO_LTC_OUT_SETTINGS; + + + +#define _mbg_swab_mbg_gpio_ltc_out_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->type ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved0 ); \ + _mbg_swab32( &(_p)->reserved1 ); \ + _mbg_swab32( &(_p)->reserved2 ); \ +} while ( 0 ) + + + +/** + * @brief Supported options for LTC output + * + * Used as sub-structure of ::MBG_GPIO_LIMITS. + * + * @see ::MBG_GPIO_TYPE_LTC_OUT + * @see ::MBG_GPIO_LIMITS + */ +typedef struct +{ + uint32_t supp_types; ///< Supported LTC types, see ::MBG_GPIO_LTC_OUT_TYPE_MASKS. + uint32_t supp_flags; ///< Reserved, currently always 0. + uint32_t reserved_0; ///< Reserved, currently always 0. + uint32_t reserved_1; ///< Reserved, currently always 0. + uint32_t reserved_2; ///< Reserved, currently always 0. + +} MBG_GPIO_LTC_OUT_SUPP; + + +#define _mbg_swab_mbg_gpio_ltc_out_supp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_types ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of general flags used with a GPIO + * + * @see ::MBG_GPIO_FLAG_MASKS + */ +enum MBG_GPIO_FLAGS +{ + MBG_GPIO_DEPENDS_ON_ASS_IO_IDX, ///< indicates that this output depends on GPIO with ::MBG_GPIO_SETTINGS::ass_io_idx and may not be configured independently + MBG_GPIO_PORT_INVISIBLE, ///< gpio is used internally and should not be displayed by config apps + N_MBG_GPIO_FLAGS ///< number of known flags +}; + + + +/** + * @brief Bit masks associated with ::MBG_GPIO_FLAGS. + * + * Used with ::MBG_GPIO_LIMITS::supp_flags and ::MBG_GPIO_SETTINGS::flags. + * + * @see ::MBG_GPIO_FLAGS + */ +enum MBG_GPIO_FLAG_MASKS +{ + MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX = ( 1UL << MBG_GPIO_DEPENDS_ON_ASS_IO_IDX ), ///< See ::MBG_GPIO_DEPENDS_ON_ASS_IO_IDX + MSK_MBG_GPIO_PORT_INVISIBLE = ( 1UL << MBG_GPIO_PORT_INVISIBLE ) ///< See ::MBG_GPIO_PORT_INVISIBLE +}; + + + +/** + * @brief A generic structure used to hold the settings of a GPIO port. + */ +typedef struct +{ + uint32_t type; ///< GPIO type, see ::MBG_GPIO_TYPES. + + uint16_t reserved_1; ///< Reserved, currently always 0. + uint8_t reserved_2; ///< Reserved, currently always 0. + uint8_t ass_io_idx; ///< Associated GPIO index, only valid if ::MSK_MBG_GPIO_DEPENDS_ON_ASS_IO_IDX is set in flags field. + + uint32_t flags; ///< Flags, see ::MBG_GPIO_FLAG_MASKS. + + /// @brief Settings depending on the GPIO @a #type, see ::MBG_GPIO_TYPES. + union + { + uint32_t b[6]; ///< Just to indicate the size of this union. + MBG_GPIO_FREQ_IN_SETTINGS freq_in; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_IN + MBG_GPIO_FREQ_OUT_SETTINGS freq_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_OUT + MBG_GPIO_FIXED_FREQ_OUT_SETTINGS ff_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT + MBG_GPIO_BITS_IN_SETTINGS bits_in; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_IN + MBG_GPIO_BITS_OUT_SETTINGS bits_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_OUT + MBG_GPIO_VIDEO_OUT_SETTINGS video_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_OUT + MBG_GPIO_VIDEO_SYNC_OUT_SETTINGS video_sync_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT + MBG_GPIO_STUDIO_CLOCK_OUT_SETTINGS studio_clk_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT + MBG_GPIO_DIGITAL_AUDIO_OUT_SETTINGS digital_audio_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT + MBG_GPIO_VIDEO_IN_SETTINGS video_in; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_IN + MBG_GPIO_LTC_OUT_SETTINGS ltc_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_LTC_OUT + } u; + +} MBG_GPIO_SETTINGS; + +#define _mbg_swab_mbg_gpio_settings( _p, _recv ) \ +do \ +{ \ + uint32_t t = (_p)->type; \ + if ( (_recv) ) \ + _mbg_swab32( &t ); \ + _mbg_swab32( &(_p)->type ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab8( &(_p)->reserved_2 ); \ + _mbg_swab8( &(_p)->ass_io_idx ); \ + _mbg_swab32( &(_p)->flags ); \ + switch( t ) \ + { \ + case MBG_GPIO_TYPE_FREQ_IN : _mbg_swab_mbg_gpio_freq_in_settings( &(_p)->u.freq_in ); break; \ + case MBG_GPIO_TYPE_FREQ_OUT : _mbg_swab_mbg_gpio_freq_out_settings( &(_p)->u.freq_out ); break; \ + case MBG_GPIO_TYPE_FIXED_FREQ_OUT : _mbg_swab_mbg_gpio_fixed_freq_out_settings( &(_p)->u.ff_out ); break; \ + case MBG_GPIO_TYPE_BITS_IN : _mbg_swab_mbg_gpio_bits_in_settings( &(_p)->u.bits_in, (_recv) ); break; \ + case MBG_GPIO_TYPE_BITS_OUT : _mbg_swab_mbg_gpio_bits_out_settings( &(_p)->u.bits_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_OUT : _mbg_swab_mbg_gpio_video_out_settings( &(_p)->u.video_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_SYNC_OUT : _mbg_swab_mbg_gpio_video_sync_out_settings( &(_p)->u.video_sync_out ); break; \ + case MBG_GPIO_TYPE_STUDIO_CLOCK_OUT : _mbg_swab_mbg_gpio_studio_clock_out_settings( &(_p)->u.studio_clk_out ); break; \ + case MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT : _mbg_swab_mbg_gpio_digital_audio_out_settings( &(_p)->u.digital_audio_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_IN : _mbg_swab_mbg_gpio_video_in_settings( &(_p)->u.video_in ); break; \ + case MBG_GPIO_TYPE_LTC_OUT : _mbg_swab_mbg_gpio_ltc_out_settings( &(_p)->u.ltc_out ); break; \ + default : break; \ + } \ +} while ( 0 ) + + + +/** + * @brief The current settings of a GPIO port, plus port index. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; ///< GPIO port index, 0..::MBG_GPIO_CFG_LIMITS::num_io-1. + MBG_GPIO_SETTINGS settings; ///< Current settings + +} MBG_GPIO_SETTINGS_IDX; + +#define _mbg_swab_mbg_gpio_settings_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_mbg_gpio_settings( &(_p)->settings, (_recv ) ); \ +} while ( 0 ) + + + +/** + * @brief A generic structure used to specify the limits of a GPIO port. + */ +typedef struct +{ + uint32_t type; ///< GPIO type, see ::MBG_GPIO_TYPES + uint32_t reserved; ///< reserved, currently always 0 + uint32_t supp_flags; ///< supported flags, see ::MBG_GPIO_FLAG_MASKS + + /// Limits depending on the GPIO type, see ::MBG_GPIO_TYPES. + union + { + uint32_t b[7]; ///< Just to indicate the size of this union. + MBG_GPIO_FREQ_IN_SUPP freq_in; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_IN + MBG_GPIO_FREQ_OUT_SUPP freq_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FREQ_OUT + MBG_GPIO_FIXED_FREQ_OUT_SUPP ff_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_FIXED_FREQ_OUT + MBG_GPIO_BITS_IN_SUPP bits_in; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_IN + MBG_GPIO_BITS_OUT_SUPP bits_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_BITS_OUT + MBG_GPIO_VIDEO_OUT_SUPP video_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_OUT + MBG_GPIO_VIDEO_SYNC_OUT_SUPP video_sync_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_SYNC_OUT + MBG_GPIO_STUDIO_CLOCK_OUT_SUPP studio_clk_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_STUDIO_CLOCK_OUT + MBG_GPIO_DIGITAL_AUDIO_OUT_SUPP digital_audio_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT + MBG_GPIO_VIDEO_IN_SUPP video_in; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_VIDEO_IN + MBG_GPIO_LTC_OUT_SUPP ltc_out; ///< If ::MBG_GPIO_SETTINGS::type is ::MBG_GPIO_TYPE_LTC_OUT + } u; + +} MBG_GPIO_LIMITS; + +#define _mbg_swab_mbg_gpio_limits( _p, _recv ) \ +do \ +{ \ + uint32_t t = (_p)->type; \ + if ( (_recv) ) \ + _mbg_swab32( &t ); \ + _mbg_swab32( &(_p)->type ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + switch( t ) \ + { \ + case MBG_GPIO_TYPE_FREQ_IN : _mbg_swab_mbg_gpio_freq_in_supp( &(_p)->u.freq_in ); break; \ + case MBG_GPIO_TYPE_FREQ_OUT : _mbg_swab_mbg_gpio_freq_out_supp( &(_p)->u.freq_out ); break; \ + case MBG_GPIO_TYPE_FIXED_FREQ_OUT : _mbg_swab_mbg_gpio_fixed_freq_out_supp( &(_p)->u.ff_out ); break; \ + case MBG_GPIO_TYPE_BITS_IN : _mbg_swab_mbg_gpio_bits_in_supp( &(_p)->u.bits_in ); break; \ + case MBG_GPIO_TYPE_BITS_OUT : _mbg_swab_mbg_gpio_bits_out_supp( &(_p)->u.bits_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_OUT : _mbg_swab_mbg_gpio_video_out_supp( &(_p)->u.video_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_SYNC_OUT : _mbg_swab_mbg_gpio_video_sync_out_supp( &(_p)->u.video_sync_out ); break; \ + case MBG_GPIO_TYPE_STUDIO_CLOCK_OUT : _mbg_swab_mbg_gpio_studio_clock_out_supp( &(_p)->u.studio_clk_out ); break; \ + case MBG_GPIO_TYPE_DIGITAL_AUDIO_OUT : _mbg_swab_mbg_gpio_digital_audio_out_supp( &(_p)->u.digital_audio_out ); break; \ + case MBG_GPIO_TYPE_VIDEO_IN : _mbg_swab_mbg_gpio_video_in_supp( &(_p)->u.video_in ); break; \ + case MBG_GPIO_TYPE_LTC_OUT : _mbg_swab_mbg_gpio_ltc_out_supp( &(_p)->u.ltc_out ); break; \ + default : break; \ + } \ +} while ( 0 ) + + + +/** + * @brief The current settings and limits of a GPIO port. + */ +typedef struct +{ + MBG_GPIO_SETTINGS settings; ///< Current settings. + MBG_GPIO_LIMITS limits; ///< Limits of this GPIO port. + +} MBG_GPIO_INFO; + + +#define _mbg_swab_mbg_gpio_info( _p, _recv ) \ +do \ +{ \ + _mbg_swab_mbg_gpio_settings( &(_p)->settings, (_recv) ); \ + _mbg_swab_mbg_gpio_limits( &(_p)->limits, (_recv) ); \ +} while ( 0 ) + + +/** + * @brief The current settings and limits of a GPIO port, plus port index. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; ///< Port index, 0..::MBG_GPIO_CFG_LIMITS::num_io-1. + MBG_GPIO_INFO info; ///< Limits and current settings of this GPIO port. + +} MBG_GPIO_INFO_IDX; + +#define _mbg_swab_mbg_gpio_info_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_mbg_gpio_info( &(_p)->info, (_recv) ); \ +} while ( 0 ) + + + +/** + * @brief Status information on a single GPIO port + */ +typedef struct +{ + uint8_t port_state; ///< See ::MBG_GPIO_PORT_STATES. + uint8_t reserved_0; ///< Reserved, currently unused and always 0. + uint16_t reserved_1; ///< Reserved, currently unused and always 0. + uint32_t reserved_2; ///< Reserved, currently unused and always 0. + uint32_t reserved_3; ///< Reserved, currently unused and always 0. + +} MBG_GPIO_STATUS; + +#define _mbg_swab_mbg_gpio_status( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->port_state ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief Status information on a specific GPIO port + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< GPIO port index, 0..::MBG_GPIO_CFG_LIMITS::num_io-1. + MBG_GPIO_STATUS status; ///< Status information. + +} MBG_GPIO_STATUS_IDX; + +#define _mbg_swab_mbg_gpio_status_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_gpio_status( &(_p)->status ); \ +} while ( 0 ) + + + +/** + * @brief GPIO port states + * + * Used with ::MBG_GPIO_STATUS::port_state + * + * @see ::DEFAULT_GPIO_PORT_STATE_NAMES + */ +enum MBG_GPIO_PORT_STATES +{ + MBG_GPIO_PORT_UNUSED, ///< configured as unused input + MBG_GPIO_PORT_OUTPUT_ENBD, ///< configured output signal enabled + MBG_GPIO_INPUT_SIG_AVAIL, ///< input signal is available + N_MBG_GPIO_PORT_STATES ///< number of known port states +}; + + + +/** + * @brief String initializers for GPIO port state names + * + * @see ::MBG_GPIO_PORT_STATES + */ +#define DEFAULT_GPIO_PORT_STATE_NAMES \ +{ \ + "unused", \ + "output enabled", \ + "input signal available" \ +} + + +/** @} defgroup group_gpio */ + + + +/** + * @defgroup group_havequick HaveQuick definitions + * + * @note This is only supported if the ::GPS_HAS_HAVEQUICK bit is set + * in the ::RECEIVER_INFO::features mask. + * + * @{ */ + + +/** + * @brief Enumeration of HaveQuick formats + * + * @see ::HAVEQUICK_SETTINGS::format + * @see ::HAVEQUICK_FORMAT_MASKS + */ +enum HAVEQUICK_FORMATS +{ + HQ_FMT_STANAG4246_1, + HQ_FMT_STANAG4246_2, + HQ_FMT_STANAG4246_PTTI, + HQ_FMT_STANAG4372_SATURN_1, + HQ_FMT_STANAG4372_SATURN_2, + HQ_FMT_STANAG4430_EXTD, + N_HQ_FMT ///< number of known formats +}; + + +/** + * @brief Bit masks associated with the enumerated HaveQuick formats + * + * @see ::HAVEQUICK_INFO::supp_formats + * @see ::HAVEQUICK_FORMATS + */ +enum HAVEQUICK_FORMAT_MASKS +{ + HQ_MSK_STANAG4246_1 = ( 1UL << HQ_FMT_STANAG4246_1 ), ///< See ::HQ_FMT_STANAG4246_1 + HQ_MSK_STANAG4246_2 = ( 1UL << HQ_FMT_STANAG4246_2 ), ///< See ::HQ_FMT_STANAG4246_2 + HQ_MSK_STANAG4246_PTTI = ( 1UL << HQ_FMT_STANAG4246_PTTI ), ///< See ::HQ_FMT_STANAG4246_PTTI + HQ_MSK_STANAG4372_SATURN_1 = ( 1UL << HQ_FMT_STANAG4372_SATURN_1 ), ///< See ::HQ_FMT_STANAG4372_SATURN_1 + HQ_MSK_STANAG4372_SATURN_2 = ( 1UL << HQ_FMT_STANAG4372_SATURN_2 ), ///< See ::HQ_FMT_STANAG4372_SATURN_2 + HQ_MSK_STANAG4430_EXTD = ( 1UL << HQ_FMT_STANAG4430_EXTD ) ///< See ::HQ_FMT_STANAG4430_EXTD +}; + +/* + * String initializers for each Havequick format + */ +#define HQ_FMT_NAME_STANAG4246_1 "STANAG4246 1" +#define HQ_FMT_NAME_STANAG4246_2 "STANAG4246 2" +#define HQ_FMT_NAME_STANAG4246_PTTI "STANAG4246 PTTI" +#define HQ_FMT_NAME_STANAG4372_SATURN_1 "STANAG4372 SATURN 1" +#define HQ_FMT_NAME_STANAG4372_SATURN_2 "STANAG4372 SATURN 2" +#define HQ_FMT_NAME_STANAG4430_EXTD "STANAG4430 EXTD" + +#define HQ_FMT_SHRT_NAME_STANAG4246_1 "STG4246 1" +#define HQ_FMT_SHRT_NAME_STANAG4246_2 "STG4246 2" +#define HQ_FMT_SHRT_NAME_STANAG4246_PTTI "STG4246 PTTI" +#define HQ_FMT_SHRT_NAME_STANAG4372_SATURN_1 "STG4372 SATURN1" +#define HQ_FMT_SHRT_NAME_STANAG4372_SATURN_2 "STG4372 SATURN2" +#define HQ_FMT_SHRT_NAME_STANAG4430_EXTD "STG4430 EXTD" + +/* + * The definition below can be used to initialize + * an array of ::N_HQ_FMT name strings. + */ +#define DEFAULT_HQ_FMT_NAMES \ +{ \ + HQ_FMT_NAME_STANAG4246_1, \ + HQ_FMT_NAME_STANAG4246_2, \ + HQ_FMT_NAME_STANAG4246_PTTI, \ + HQ_FMT_NAME_STANAG4372_SATURN_1, \ + HQ_FMT_NAME_STANAG4372_SATURN_2, \ + HQ_FMT_NAME_STANAG4430_EXTD \ +} + +#define DEFAULT_HQ_SHRT_FMT_NAMES \ +{ \ + HQ_FMT_SHRT_NAME_STANAG4246_1, \ + HQ_FMT_SHRT_NAME_STANAG4246_2, \ + HQ_FMT_SHRT_NAME_STANAG4246_PTTI, \ + HQ_FMT_SHRT_NAME_STANAG4372_SATURN_1, \ + HQ_FMT_SHRT_NAME_STANAG4372_SATURN_2, \ + HQ_FMT_SHRT_NAME_STANAG4430_EXTD \ +} + + + +/** + * @brief Configuration settings for a HaveQuick input or output + */ +typedef struct +{ + uint16_t format; ///< See ::HAVEQUICK_FORMATS + uint16_t flags; ///< See ::HAVEQUICK_FLAG_MASKS + int32_t offset; ///< Tx: unused, Rx: offset of incoming time in [s] + uint32_t reserved_0; ///< reserved, currently always 0 + uint32_t reserved_1; ///< reserved, currently always 0 + +} HAVEQUICK_SETTINGS; + +#define _mbg_swab_havequick_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->format ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab32( &(_p)->offset ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ +} while ( 0 ) + +/** + * @brief Current settings and capabilities of a HaveQuick input or output + */ +typedef struct +{ + HAVEQUICK_SETTINGS settings; ///< current settings + uint32_t supp_formats; ///< See ::HAVEQUICK_FORMAT_MASKS + uint16_t supp_flags; ///< mask of flags supported in settings, see ::HAVEQUICK_FLAG_MASKS + uint16_t reserved; ///< reserved, currently always 0 + +} HAVEQUICK_INFO; + +#define _mbg_swab_havequick_info( _p ) \ +do \ +{ \ + _mbg_swab_havequick_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_formats ); \ + _mbg_swab16( &(_p)->supp_flags ); \ + _mbg_swab16( &(_p)->reserved ); \ +} while ( 0 ) + + +/** + * @brief Known HaveQuick control flags + * + * @see ::HAVEQUICK_FLAG_MASKS + */ +enum HAVEQUICK_FLAG_BITS +{ + HQ_FLAG_TX_GEN_LOCAL_TIME, + HQ_FLAG_SIGNAL_INVERTED, + HQ_FLAG_USE_EXT_PPS, + N_HQ_FLAG_BITS +}; + + +/** + * @brief Bit masks associated with HaveQuick control flags + * + * @see ::HAVEQUICK_SETTINGS::flags + * @see ::HAVEQUICK_INFO::supp_flags + * @see ::HAVEQUICK_FLAG_BITS + */ +enum HAVEQUICK_FLAG_MASKS +{ + HQ_MSK_TX_GEN_LOCAL_TIME = ( 1UL << HQ_FLAG_TX_GEN_LOCAL_TIME ), ///< See ::HQ_FLAG_TX_GEN_LOCAL_TIME + HQ_MSK_SIGNAL_INVERTED = ( 1UL << HQ_FLAG_SIGNAL_INVERTED ), ///< See ::HQ_FLAG_SIGNAL_INVERTED + HQ_MSK_USE_EXT_PPS = ( 1UL << HQ_FLAG_USE_EXT_PPS ) ///< See ::HQ_FLAG_USE_EXT_PPS +}; + +/** @} defgroup group_havequick */ + + + +/** + * @defgroup group_evt_log Event logging support + * + * @note This is only available if ::GPS_HAS_EVT_LOG is set in ::RECEIVER_INFO::features. + * + * @{ */ + +/** + * @brief Number of event log entries that can be stored and yet have been saved + */ +typedef struct +{ + uint32_t used; ///< current number of saved log entries + uint32_t max; ///< max number of log entries which can be saved + +} MBG_NUM_EVT_LOG_ENTRIES; + +#define _mbg_swab_mbg_num_evt_log_entries( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->used ); \ + _mbg_swab32( &(_p)->max ); \ +} while ( 0 ) + + +typedef uint16_t MBG_EVT_CODE; +#define _mbg_swab_evt_code( _p ) _mbg_swab16( _p ) + +typedef uint16_t MBG_EVT_INFO; +#define _mbg_swab_evt_info( _p ) _mbg_swab16( _p ) + +/** + * @brief An event log entry + */ +typedef struct +{ + uint32_t time; ///< like time_t, seconds since 1970 + MBG_EVT_CODE code; ///< event ID or'ed with severity level, see @ref MBG_EVENT_CODES + MBG_EVT_INFO info; ///< optional event info, depending on event ID + +} MBG_EVT_LOG_ENTRY; + +#define _mbg_swab_mbg_evt_log_entry( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->time ); \ + _mbg_swab_evt_code( &(_p)->code ); \ + _mbg_swab_evt_info( &(_p)->info ); \ +} while ( 0 ) + + +// ::MBG_EVT_LOG_ENTRY::code is a combination of some bits used for the ID, +// plus some bits used for the severity/level. The sum of bits must not +// exceed (8 * sizeof ::MBG_EVT_LOG_ENTRY::code): + +#define MBG_EVT_ID_BITS 13 +#define MBG_EVT_LVL_BITS 3 + +#define MBG_EVT_ID_MASK ( (MBG_EVT_CODE) ( 1UL << MBG_EVT_ID_BITS ) - 1 ) +#define MBG_EVT_LVL_MASK ( (MBG_EVT_CODE) ( 1UL << MBG_EVT_LVL_BITS ) - 1 ) + + +// Combine an ID and Level to a code which can be stored +// in the code field: +#define _mbg_mk_evt_code( _id, _lvl ) \ + ( (MBG_EVT_CODE) ( (MBG_EVT_CODE)(_id) | ( (MBG_EVT_CODE)(_lvl) << MBG_EVT_ID_BITS ) ) ) + +// Extract the event ID from the code field: +#define _mbg_get_evt_id( _code ) \ + ( (_code) & MBG_EVT_ID_MASK ) + +// Extract the severity level from the code field: +#define _mbg_get_evt_lvl( _code ) \ + ( ( (_code) >> MBG_EVT_ID_BITS ) & MBG_EVT_LVL_MASK ) + + +/** + * @brief Enumeration of event IDs + * + * @see @ref MBG_EVENT_CODES + * @see @ref MBG_EVT_ID_BITS + * @see @ref MBG_EVT_LVL_BITS + */ +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_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 + MBG_EVT_ID_NTP_STATE_SYNC, ///< NTP is sync + MBG_EVT_ID_NTP_STATE_NOT_SYNC, ///< NTP not sync + MBG_EVT_ID_FW_OSV, ///< Firmware has been set to OSV + 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 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_UFU_PROGRESS "UFU is being transferred..." +#define ENG_EVT_ID_NAME_DATABASE_CONNECTED "Database(s) connected" +#define ENG_EVT_ID_NAME_NTP_STATE_SYNC "NTP state: Sync to system peer" +#define ENG_EVT_ID_NAME_NTP_STATE_NOT_SYNC "NTP state: Not sync" +#define ENG_EVT_ID_NAME_FW_OSV "Firmware set to OSV" + + +#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_UFU_PROGRESS, \ + ENG_EVT_ID_NAME_DATABASE_CONNECTED, \ + ENG_EVT_ID_NAME_NTP_STATE_SYNC, \ + ENG_EVT_ID_NAME_FW_OSV \ +} + + + +/** + * @brief Enumeration of event severity levels + * + * @see @ref MBG_EVENT_CODES + * @see @ref MBG_EVT_ID_BITS + * @see @ref MBG_EVT_LVL_BITS + */ +enum MBG_EVT_LVLS +{ + MBG_EVT_LVL_NONE, + MBG_EVT_LVL_DEBUG, + MBG_EVT_LVL_INFO, + MBG_EVT_LVL_WARN, + MBG_EVT_LVL_ERR, + MBG_EVT_LVL_CRIT, + N_MBG_EVT_LVL +}; + + +#define ENG_EVT_LVL_NAME_NONE "None" +#define ENG_EVT_LVL_NAME_DEBUG "Debug" +#define ENG_EVT_LVL_NAME_INFO "Info" +#define ENG_EVT_LVL_NAME_WARN "Warn" +#define ENG_EVT_LVL_NAME_ERR "Err" +#define ENG_EVT_LVL_NAME_CRIT "Crit." + + +#define MBG_EVT_LVL_NAMES_ENG \ +{ \ + ENG_EVT_LVL_NAME_NONE, \ + ENG_EVT_LVL_NAME_DEBUG, \ + ENG_EVT_LVL_NAME_INFO, \ + ENG_EVT_LVL_NAME_WARN, \ + ENG_EVT_LVL_NAME_ERR, \ + ENG_EVT_LVL_NAME_CRIT \ +} + + +/** + * @brief Predefined event codes with associated severity levels + * + * @see ::MBG_EVT_IDS + * @see ::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_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 ) +#define MBG_EVT_FW_ACTIVATED _mbg_mk_evt_code( MBG_EVT_ID_FW_ACTIVATED, MBG_EVT_LVL_INFO ) +#define MBG_EVT_DATABASE_CONNECTED _mbg_mk_evt_code( MBG_EVT_ID_DATABASE_CONNTECTED, MBG_EVT_LVL_INFO ) +#define MBG_EVT_NTP_STATE_SYNC _mbg_mk_evt_code( MBG_EVT_ID_NTP_STATE_SYNC, MBG_EVT_LVL_INFO ) +#define MBG_EVT_NTP_STATE_NOT_SYNC _mbg_mk_evt_code( MBG_EVT_ID_NTP_STATE_NOT_SYNC, MBG_EVT_LVL_WARN ) +#define MBG_EVT_FW_OSV _mbg_mk_evt_code( MBG_EVT_ID_FW_OSV, MBG_EVT_LVL_INFO ) + +/** @} anchor MBG_EVENT_CODES */ + +/** @} defgroup group_evt_log */ + + + +/** + * @defgroup group_ims IMS support + * + * @note This is only supported if ::GPS_HAS_IMS is set in ::RECEIVER_INFO::features. + * + * @{ */ + +/** + * @brief Generic state of an IMS device + */ +typedef struct mbg_ims_state_s +{ + uint8_t chassis_id; ///< chassis ID, 0 if installed on the backplane + uint8_t slot_id; ///< slot number on the chassis + uint16_t num_sensors; ///< number of sensors provided by the device + uint32_t reserved; ///< reserved, currently always 0 + uint32_t flags; ///< See ::MBG_IMS_STATE_FLAG_MASKS + +} MBG_IMS_STATE; + +#define _mbg_swab_mbg_ims_state( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->num_sensors ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of bits used to define ::MBG_IMS_STATE_FLAG_MASKS + * + * @see ::MBG_IMS_STATE_FLAG_MASKS + */ +enum MBG_IMS_STATE_FLAG_BITS +{ + MBG_IMS_STATE_FLAG_BIT_HAS_FDM, ///< device supports FDM API + N_MBG_IMS_STATE_FLAG_BITS +}; + + +/** + * @brief Bit masks used with ::MBG_IMS_STATE::flags + * + * @see ::MBG_IMS_STATE_FLAG_BITS + */ +enum MBG_IMS_STATE_FLAG_MASKS +{ + MBG_IMS_STATE_FLAG_MSK_HAS_FDM = ( 1UL << MBG_IMS_STATE_FLAG_BIT_HAS_FDM ) ///< See ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM +}; + + + +/** + * @brief Generic state of an IMS sensor + */ +typedef struct mbg_ims_sensor_state_s +{ + uint16_t type; ///< sensor type, see ::MBG_IMS_SENSORS + uint16_t idx; ///< index of the sensor of this type + int32_t val; ///< sensor value, in units according to the type + int16_t exp; ///< 10s exponent of the sensor value + uint16_t reserved; ///< currently unused, always 0 + uint32_t flags; ///< currently unused, always 0 + +} MBG_IMS_SENSOR_STATE; + +#define _mbg_swab_mbg_ims_sensor_state( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->type ); \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab32( &(_p)->val ); \ + _mbg_swab16( &(_p)->exp ); \ + _mbg_swab16( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + +/** + * @brief Generic state of an IMS sensor, with sensor index + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; ///< sensor index, 0..::MBG_IMS_STATE::num_sensors-1 + MBG_IMS_SENSOR_STATE state; ///< sensor state + +} MBG_IMS_SENSOR_STATE_IDX; + +#define _mbg_swab_mbg_ims_sensor_state_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_mbg_ims_sensor_state( &(_p)->state ); \ +} while ( 0 ) + + + +/** + * @brief IMS sensor types + * + * Used with ::MBG_IMS_SENSOR_STATE::type + */ +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 + 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 +}; + + + +/** + * @brief IMS sensor state flags for voltage + * + * Used with ::MBG_IMS_SENSOR_STATE::flags in case ::MBG_IMS_SENSOR_STATE::type + * is ::MBG_IMS_SENSOR_VOLTAGE. + */ +enum MBG_IMS_SENSOR_STATE_FLAG_MASK_VOLTAGE +{ + MBG_IMS_SENSOR_VOLTAGE_OUT_ENB = 0x01, ///< output is enabled + MBG_IMS_SENSOR_VOLTAGE_OUT_OVR = 0x02 ///< output overload +}; + + +/** + * @brief IMS sensor state flags for PLL + * + * Used with ::MBG_IMS_SENSOR_STATE::flags in case ::MBG_IMS_SENSOR_STATE::type + * is ::MBG_IMS_SENSOR_PLL. + */ +enum MBG_IMS_SENSOR_STATE_FLAG_MASK_PLL +{ + MBG_IMS_SENSOR_PLL_LOCKED = 0x01 ///< PLL is locked +}; + + + +/** + * @brief DAC limit specs + */ +typedef struct +{ + int32_t dac_val_min; ///< min. possible DAC Value, positive or negative + int32_t dac_val_max; ///< max. possible DAC Value, positive or negative + + int32_t u_min; ///< min. possible real voltage range [mV], positive or negative, depending on ::MBG_DAC_SPECS::dac_val_min + int32_t u_max; ///< max. possible real voltage range [mV], positive or negative, depending on ::MBG_DAC_SPECS::dac_val_max + + uint32_t reserved_0; ///< reserved, currently always 0 + uint32_t reserved_1; ///< reserved, currently always 0 + +} MBG_DAC_SPECS; + +#define _mbg_swab_mbg_dac_specs( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->dac_val_min ); \ + _mbg_swab32( &(_p)->dac_val_max ); \ + _mbg_swab32( &(_p)->u_min ); \ + _mbg_swab32( &(_p)->u_max ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ +} while ( 0 ) + + + +/** + * @brief Output state of FDM device. + * + * @note This is only supported if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags + */ +typedef struct mbg_ims_fdm_output_state_s +{ + int32_t dac_val; ///< current DAC value, positive or negative + uint32_t mode; ///< current output mode, see ::MBG_IMS_FDM_OUTPUT_MODES + + MBG_DAC_SPECS dac_specs; ///< DAC specific limits + + uint32_t reserved_0; ///< reserved, currently always 0 + uint32_t reserved_1; ///< reserved, currently always 0 + +} MBG_IMS_FDM_OUTPUT_STATE; + +#define _mbg_swab_mbg_ims_fdm_output_state( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->dac_val ); \ + _mbg_swab32( &(_p)->mode ); \ + _mbg_swab_mbg_dac_specs( &(_p)->dac_specs ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ +} while ( 0 ) + + + +/** + * @brief Output state of FDM device plus index. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_IMS_FDM_OUTPUT_STATE state; + +} MBG_IMS_FDM_OUTPUT_STATE_IDX; + +#define _mbg_swab_mbg_ims_fdm_output_state_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_mbg_ims_fdm_output_state( &(_p)->state ); \ +} while ( 0 ) + + + +/** + * @brief Output settings of FDM device + * + * @note This is only supported if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags + */ +typedef struct +{ + uint32_t mode; ///< mode, see ::MBG_IMS_FDM_OUTPUT_MODES + uint32_t reserved; ///< reserved, currently always 0 + +} MBG_IMS_FDM_OUTPUT_SETTINGS; + +#define _mbg_swab_mbg_ims_fdm_output_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->mode ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + + +/** + * @brief Output settings for FDM devices plus index. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_IMS_FDM_OUTPUT_SETTINGS settings; + +} MBG_IMS_FDM_OUTPUT_SETTINGS_IDX; + +#define _mbg_swab_mbg_ims_fdm_output_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_mbg_ims_fdm_output_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Specific output settings and limits. + */ +typedef struct mbg_ims_fdm_output_info_s +{ + MBG_IMS_FDM_OUTPUT_SETTINGS settings; ///< current settings + uint32_t supp_modes; ///< supported modes, see ::MBG_IMS_FDM_OUTPUT_MODE_MASKS + MBG_DAC_SPECS dac_specs; ///< DAC specific limits + +} MBG_IMS_FDM_OUTPUT_INFO; + +#define _mbg_swab_mbg_ims_fdm_output_info( _p ) \ +do \ +{ \ + _mbg_swab_mbg_ims_fdm_output_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_modes ); \ + _mbg_swab_mbg_dac_specs( &(_p)->dac_specs ); \ +} while ( 0 ) + + + +/** + * @brief Specific output settings and limits, plus index. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_IMS_FDM_OUTPUT_INFO info; + +} MBG_IMS_FDM_OUTPUT_INFO_IDX; + +#define _mbg_swab_mbg_ims_fdm_output_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_mbg_ims_fdm_output_info( &(_p)->info ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of known output modes + * + * Used with ::MBG_IMS_FDM_OUTPUT_STATE::mode + * + * @see ::MBG_IMS_FDM_OUTPUT_MODE_MASKS + */ +enum MBG_IMS_FDM_OUTPUT_MODES +{ + MBG_IMS_FDM_OUTPUT_MODE_FD, ///< Analog output reflects frequency deviation + MBG_IMS_FDM_OUTPUT_MODE_TD, ///< Analog output reflects time deviation + N_MBG_IMS_FDM_OUTPUT_MODES ///< Number of known output modes +}; + + + +/** + * @brief Bit masks used with ::MBG_IMS_FDM_OUTPUT_STATE::mode + * + * @see ::MBG_IMS_FDM_OUTPUT_MODES + */ +enum MBG_IMS_FDM_OUTPUT_MODE_MASKS +{ + MBG_IMS_FDM_OUTPUT_MODE_MSK_FD = ( 1UL << MBG_IMS_FDM_OUTPUT_MODE_FD ), ///< See ::MBG_IMS_FDM_OUTPUT_MODE_FD + MBG_IMS_FDM_OUTPUT_MODE_MSK_TD = ( 1UL << MBG_IMS_FDM_OUTPUT_MODE_TD ) ///< See ::MBG_IMS_FDM_OUTPUT_MODE_TD +}; + + + +/** + * @brief A generic structure used to specify FDM limits + */ +typedef struct mbg_ims_fdm_limits_s +{ + uint8_t n_outputs; ///< number of outputs per module + uint8_t reserved_0; ///< reserved, currently always 0 + uint16_t reserved_1; ///< reserved, currently always 0 + + uint32_t fd_neg_limit; ///< min. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units + uint32_t fd_pos_limit; ///< max. frequency deviation limit, 1/::MBG_IMS_FDM_LIMITS::fd_scale Hz units + uint32_t fd_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::fd_neg_limit and ::MBG_IMS_FDM_LIMITS::fd_pos_limit + + uint32_t td_neg_limit; ///< min. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units + uint32_t td_pos_limit; ///< max. time deviation limit, 1/::MBG_IMS_FDM_LIMITS::td_scale s units + uint32_t td_scale; ///< scale for ::MBG_IMS_FDM_LIMITS::td_neg_limit and ::MBG_IMS_FDM_LIMITS::td_pos_limit + + uint32_t reserved_2; ///< reserved, currently always 0 + +} MBG_IMS_FDM_LIMITS; + +#define _mbg_swab_mbg_ims_fdm_limits( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->n_outputs ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + \ + _mbg_swab32( &(_p)->fd_neg_limit ); \ + _mbg_swab32( &(_p)->fd_pos_limit ); \ + _mbg_swab32( &(_p)->fd_scale ); \ + \ + _mbg_swab32( &(_p)->td_neg_limit ); \ + _mbg_swab32( &(_p)->td_pos_limit ); \ + _mbg_swab32( &(_p)->td_scale ); \ + \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +/** + * @brief State of FDM device + * + * @note This is only supported if ::MBG_IMS_STATE_FLAG_MSK_HAS_FDM is set in ::MBG_IMS_STATE::flags. + * + */ +typedef struct mbg_ims_fdm_state_s +{ + MBG_GPIO_FREQ freq; ///< Current frequency + + NANO_TIME_64 t_ref; ///< Current reference time + NANO_TIME_64 t_plt; ///< Current power line time + NANO_TIME_64 t_sync; ///< Last sync Time (reference time) + + uint32_t line_freq; ///< Nominal line frequency, see ::MBG_IMS_FDM_LINE_FREQS + uint32_t flags; ///< Flags, see ::MBG_IMS_FDM_STATE_FLAG_MASKS + uint32_t reserved; ///< Reserved, currently always 0 + +} MBG_IMS_FDM_STATE; + +#define _mbg_swab_mbg_ims_fdm_state( _p ) \ +do \ +{ \ + _mbg_swab_mbg_gpio_freq( &(_p)->freq ); \ + _mbg_swab_nano_time_64( &(_p)->t_ref ); \ + _mbg_swab_nano_time_64( &(_p)->t_plt ); \ + _mbg_swab_nano_time_64( &(_p)->t_sync ); \ + _mbg_swab32( &(_p)->line_freq ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration known line frequencies + * + * Used with ::MBG_IMS_FDM_STATE::line_freq + * + * @see ::MBG_IMS_FDM_LINE_FREQ_MASKS + */ +enum MBG_IMS_FDM_LINE_FREQS +{ + MBG_IMS_FDM_LINE_FREQ_AUTO, ///< Auto detect line frequency + MBG_IMS_FDM_LINE_FREQ_50HZ, ///< 50Hz line frequency + MBG_IMS_FDM_LINE_FREQ_60HZ, ///< 60Hz line frequency + N_MBG_IMS_FDM_LINE_FREQS ///< number of known line frequencies +}; + + +/** + * @brief Bit masks corresponding to defined line frequencies + * + * @see ::MBG_IMS_FDM_LINE_FREQS + */ +enum MBG_IMS_FDM_LINE_FREQ_MASKS +{ + MBG_IMS_FDM_LINE_FREQ_MSK_AUTO = ( 1UL << MBG_IMS_FDM_LINE_FREQ_AUTO ), ///< See ::MBG_IMS_FDM_LINE_FREQ_AUTO + MBG_IMS_FDM_LINE_FREQ_MSK_50HZ = ( 1UL << MBG_IMS_FDM_LINE_FREQ_50HZ ), ///< See ::MBG_IMS_FDM_LINE_FREQ_50HZ + MBG_IMS_FDM_LINE_FREQ_MSK_60HZ = ( 1UL << MBG_IMS_FDM_LINE_FREQ_60HZ ) ///< See ::MBG_IMS_FDM_LINE_FREQ_60HZ +}; + + +/** + * @brief Initializers for an array of line freq. name strings + * + * @see ::MBG_IMS_FDM_LINE_FREQS + */ +#define MBG_IMS_FDM_LINE_FREQ_STRS \ +{ \ + "Auto", \ + "50 Hz", \ + "60 Hz", \ +} + + +/** + * @brief Enumeration of flag bits used to define ::MBG_IMS_FDM_STATE_FLAG_MASKS + */ +enum MBG_IMS_FDM_STATE_FLAG_BITS +{ + MBG_IMS_FDM_STATE_FLAG_BIT_SYNC_AFTER_RESET, ///< if sync'ed after reset + MBG_IMS_FDM_STATE_FLAG_BIT_PLT_IS_LOCKED, ///< Power Line Time is locked + MBG_IMS_FDM_STATE_FLAG_BIT_FD_OVERFLOW, ///< Frequency deviation overflow occurred + MBG_IMS_FDM_STATE_FLAG_BIT_TD_OVERFLOW, ///< Time deviation overflow occurred + N_MBG_IMS_FDM_STATE_FLAG_BITS ///< number of known state flag bits +}; + + +/** + * @brief Bit masks used with ::MBG_IMS_FDM_STATE::flags + * + * @see ::MBG_IMS_FDM_STATE_FLAG_BITS + */ +enum MBG_IMS_FDM_STATE_FLAG_MASKS +{ + MBG_IMS_FDM_STATE_FLAG_MSK_SYNC_AFTER_RESET = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_SYNC_AFTER_RESET ), ///< See ::MBG_IMS_FDM_STATE_FLAG_BIT_SYNC_AFTER_RESET + MBG_IMS_FDM_STATE_FLAG_MSK_PLT_IS_LOCKED = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_PLT_IS_LOCKED ), ///< See ::MBG_IMS_FDM_STATE_FLAG_BIT_PLT_IS_LOCKED + MBG_IMS_FDM_STATE_FLAG_MSK_FD_OVERFLOW = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_FD_OVERFLOW ), ///< See ::MBG_IMS_FDM_STATE_FLAG_BIT_FD_OVERFLOW + MBG_IMS_FDM_STATE_FLAG_MSK_TD_OVERFLOW = ( 1UL << MBG_IMS_FDM_STATE_FLAG_BIT_TD_OVERFLOW ) ///< See ::MBG_IMS_FDM_STATE_FLAG_BIT_TD_OVERFLOW +}; + + + +/** + * @brief FDM device settings + * + * @note This is only supported if ::MBG_IMS_STATE_FLAG_BIT_HAS_FDM is set in ::MBG_IMS_STATE::flags. + * + */ +typedef struct +{ + uint32_t fd_neg_limit; ///< min. frequency deviation limit in 1 mHz steps + uint32_t fd_pos_limit; ///< max. frequency deviation limit in 1 mHz steps + + uint32_t td_neg_limit; ///< min. time deviation limit in 1 ms steps + uint32_t td_pos_limit; ///< max. time deviation limit in 1 ms steps + + uint32_t line_freq; ///< nominal line frequency, see ::MBG_IMS_FDM_LINE_FREQS + uint32_t reserved; ///< reserved, currently always 0 + +} MBG_IMS_FDM_SETTINGS; + +#define _mbg_swab_mbg_ims_fdm_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->fd_neg_limit ); \ + _mbg_swab32( &(_p)->fd_pos_limit ); \ + _mbg_swab32( &(_p)->td_neg_limit ); \ + _mbg_swab32( &(_p)->td_pos_limit ); \ + _mbg_swab32( &(_p)->line_freq ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + + + +/** + * @brief IMS FDM flags + * + * @see ::MBG_IMS_FDM_FLAG_MASKS + */ +enum MBG_IMS_FDM_FLAGS +{ + MBG_IMS_FDM_FLAG_CAN_SET_TDEV, ///< Device supports command GPS_FDM_SET_TD + N_MBG_IMS_FDM_FLAGS ///< Number of known FDM flags +}; + + + +/** + * @brief IMS FDM flag masks + * + * @see ::MBG_IMS_FDM_FLAGS + */ +enum MBG_IMS_FDM_FLAG_MASKS +{ + MBG_IMS_FDM_FLAG_MASK_CAN_SET_TDEV = ( 1UL << MBG_IMS_FDM_FLAG_CAN_SET_TDEV ) ///< See ::MBG_IMS_FDM_FLAG_CAN_SET_TDEV +}; + + + +/** + * @brief Specific FDM settings and limits. + */ +typedef struct mbg_ims_fdm_info_s +{ + MBG_IMS_FDM_SETTINGS settings; + uint32_t supp_line_freqs; ///< Bit mask of supported line frequencies, see ::MBG_IMS_FDM_LINE_FREQ_MASKS + uint32_t reserved; ///< Reserved, currently always 0 + uint32_t flags; ///< Flags, see ::MBG_IMS_FDM_FLAG_MASKS + +} MBG_IMS_FDM_INFO; + +#define _mbg_swab_mbg_ims_fdm_info( _p ) \ +do \ +{ \ + _mbg_swab_mbg_ims_fdm_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_line_freqs ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + +/** @} defgroup group_ims */ + + + +/** + * @defgroup group_generic_io Generic I/O support. + * + * The definitions below are used with the GENERIC_IO API. + * + * This API is <b>NOT</b> supported by all devices, it depends on + * the type of the device, and the firmware version. The macro + * _pcps_has_generic_io() or the corresponding function + * mbg_dev_has_generic_io() should be used by applications to + * check whether a particular bus-level device supports this. + * + * @{ */ + +typedef uint16_t GEN_IO_INFO_TYPE; + +#define _mbg_swab_gen_io_info_type( _p ) \ + _mbg_swab16( _p ) + + + +/** + * @brief The data structure used with the ::PCPS_GEN_IO_GET_INFO command + * + * Used to determine how many data sets of a specific type are supported + * by the device. + */ +typedef struct +{ + GEN_IO_INFO_TYPE type; // see ::PCPS_GEN_IO_TYPES + uint16_t num; // supported number of data sets of the specified type + +} GEN_IO_INFO; + +#define _mbg_swab_gen_io_info( _p ) \ +do \ +{ \ + _mbg_swab_gen_io_info_type( &(_p)->type ); \ + _mbg_swab16( &(_p)->num ); \ +} while ( 0 ) + + + +/** + * @brief Data types used with ::GEN_IO_INFO::type + * + * The first type specifier, ::PCPS_GEN_IO_GET_INFO, can + * be used to find out which of the other data types are + * supported, and how many data sets of the specified type + * are supported by a device. + */ +enum PCPS_GEN_IO_TYPES +{ + PCPS_GEN_IO_GET_INFO, ///< ::GEN_IO_INFO (read only) + PCPS_GEN_IO_CAL_REC_IRIG_RX_COMP, ///< ::CAL_REC_IRIG_RX_COMP (read/write) + N_PCPS_GEN_IO_TYPE ///< number of known types +}; + +/** @} defgroup group_generic_io */ + + + +typedef uint16_t ROM_CSUM; /* The ROM checksum */ +typedef uint16_t RCV_TIMEOUT; /* [min] (only if ::HAS_RCV_TIMEOUT) */ +typedef uint16_t IGNORE_LOCK; /* (only if ::GPS_HAS_IGNORE_LOCK) */ + +/* + * Originally ::IGNORE_LOG above has been a boolean value (equal or + * not equal 0) which was evaluated the same way for all ports. + * + * Due to special firmware requirements it has been changed to a + * bit maskable property in order to be able to specify the behaviour + * for individual ports. + * + * In order to keep compatibility with older versions the LSB is used + * to specify ignore_lock for all ports. The next higher bits are used + * to specify ignore_lock for an individual port, where the bit position + * depends on the port number, e.g. 0x02 for COM0, 0x04 for COM1, etc. + * The macros below can be used to simplify the code: + */ + +/* return a bit mask depending on the port number */ +#define IGNORE_LOCK_FOR_ALL_PORTS 0x01 + +#define _ignore_lock_for_all_ports() ( IGNORE_LOCK_FOR_ALL_PORTS ) + +#define _ignore_lock_for_port( _n ) ( 0x02 << (_n) ) + +/* check if all ports are ignore_lock'ed */ +#define _is_ignore_lock_all_ports( _il ) ( (_il) & IGNORE_LOCK_FOR_ALL_PORTS ) + +/* check if a specific port is ignore_lock'ed */ +#define _is_ignore_lock_for_port( _il, _n ) \ + ( (_il) & ( _ignore_lock_for_port(_n) | IGNORE_LOCK_FOR_ALL_PORTS ) ) + + + +/** + * @defgroup group_scu Definitions used with SCU devices + * + * The structures below are used with the SCU multiplexer board + * in a redundant system. + * + * @see ::GPS_MODEL_IS_SCU + * + * @{ */ + +typedef struct +{ + uint32_t hw_id; ///< hardware identification + uint32_t fw_id; ///< firmware identification + uint16_t flags; ///< reserved currently 0 + uint8_t clk0_info; ///< reference clock 0 type + uint8_t clk1_info; ///< reference clock 1 type + uint16_t epld_status; ///< EPLD status word, see ::SCU_STAT_MASKS + uint16_t epld_control; ///< EPLD control word, see ::SCU_CTRL_MASKS + +} SCU_STAT_INFO; + +#define _mbg_swab_scu_stat_info( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->hw_id ); \ + _mbg_swab32( &(_p)->fw_id ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab8( &(_p)->clk0_info ); \ + _mbg_swab8( &(_p)->clk1_info ); \ + _mbg_swab16( &(_p)->epld_status ); \ + _mbg_swab16( &(_p)->epld_control ); \ +} while ( 0 ) + + + +typedef struct +{ + uint16_t epld_control_mask; ///< control mask, determines which bit is to be changed, see ::SCU_CTRL_MASKS + uint16_t epld_control_value; ///< control value, determines value of bits to be changed, see ::SCU_CTRL_MASKS + uint32_t flags; ///< reserved, currently 0 + +} SCU_STAT_SETTINGS; + +#define _mbg_swab_scu_stat_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->epld_control_mask ); \ + _mbg_swab16( &(_p)->epld_control_value ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Bit masks used to check the SCU EPLD status + * + * Used with ::SCU_STAT_INFO::epld_status + */ +enum SCU_STAT_MASKS +{ + MSK_EPLD_STAT_TS1 = 0x0001, ///< state of time sync signal clk_1 + MSK_EPLD_STAT_TS2 = 0x0002, ///< state of time sync signal clk_2 + MSK_EPLD_STAT_TL_ERROR = 0x0004, ///< state of time limit error input + MSK_EPLD_STAT_PSU1_OK = 0x0008, ///< state of power supply 1 monitoring input + MSK_EPLD_STAT_PSU2_OK = 0x0010, ///< state of power supply 2 monitoring input + MSK_EPLD_STAT_AUTO = 0x0020, ///< AUTOMATIC/REMOTE or MANUAL Mode + MSK_EPLD_STAT_SEL = 0x0040, ///< select bit for output MUX, ( clk_1 = 0 ) + MSK_EPLD_STAT_ENA = 0x0080, ///< enable Bit for output MUX, set if enabled + MSK_EPLD_STAT_HAS_LAN = 0x0100, ///< indicates that the device has a network interface + MSK_EPLD_STAT_RESERVED0 = 0x0200, ///< reserved, DO NOT USE! + MSK_EPLD_STAT_RESERVED1 = 0x0400, ///< reserved, DO NOT USE! + MSK_EPLD_STAT_HAS_4_PSUS = 0x0800, ///< indicates 4 power supplies instead of 2 + MSK_EPLD_STAT_PSU3_OK = 0x1000, ///< state of power supply 3 monitoring input + MSK_EPLD_STAT_PSU4_OK = 0x2000, ///< state of power supply 4 monitoring input + MSK_EPLD_STAT_ACO = 0x4000, ///< Access control override bit + MSK_EPLD_STAT_WDOG_OK = 0x8000 ///< WDT_OK set to zero if watchdog expired +}; + + + +/** + * @brief Bit masks used to control the SCU EPLD + * + * Used with ::SCU_STAT_INFO::epld_control, ::SCU_STAT_SETTINGS::epld_control_mask, + * and ::SCU_STAT_SETTINGS::epld_control_value. + */ +enum SCU_CTRL_MASKS +{ + MSK_EPLD_CTL_DISB_SERIAL = 0x0001, ///< disable serial output on error + MSK_EPLD_CTL_DISB_PPS = 0x0002, ///< disable PPS output on error + MSK_EPLD_CTL_DISB_10MHZ = 0x0004, ///< disable 10 MHz output on error + + MSK_EPLD_CNTL_SEL_REM = 0x0800, ///< remote select for output MUX (clk_1 = 0) + MSK_EPLD_CNTL_DIS_REM = 0x1000, ///< remote disable for output MUX + MSK_EPLD_CNTL_REMOTE = 0x2000, ///< must be set to enable remote operation + MSK_EPLD_CNTL_SEL_SNMP = 0x4000, ///< select clk for comm. (clk1 = 0) + MSK_EPLD_CNTL_ENA_SNMP = 0x8000, ///< connect COM0 channels to XPORT +}; + + + +/** + * @brief Definitions for ::SCU_STAT_INFO::clk0_info and ::SCU_STAT_INFO::clk1_info + * + * Can be used to determine the reference clock type connected to the SCU input channels. + */ +enum SCU_CLK_INFO_TYPES +{ + SCU_CLK_INFO_GPS, ///< ref. clock is GPS receiver + SCU_CLK_INFO_DCF_PZF, ///< ref. clock is DCF77 PZF receiver + SCU_CLK_INFO_DCF_AM, ///< ref. clock is DCF77 AM receiver + SCU_CLK_INFO_TCR, ///< ref. clock is IRIG time code receiver + N_SCU_CLK_INFO ///< number of known types +}; + +/** @} defgroup group_scu */ + + + +/*------------------------------------------------------------------------*/ + +#define REMOTE 0x10 +#define BOOT 0x20 + +/** + * @brief Satellite receiver modes of operation. + * + * @note Some of the code combinations are deprecated with recent + * satellite receivers. However, this doesn't matter since the mode + * is just read from the receiver. + */ +enum RECEIVER_MODES +{ + TRACK = ( 0x01 ), + AUTO_166 = ( 0x02 ), + WARM_166 = ( 0x03 | BOOT ), + COLD_166 = ( 0x04 | BOOT ), + AUTO_BC = ( 0x05 | REMOTE ), + WARM_BC = ( 0x06 | REMOTE | BOOT ), + COLD_BC = ( 0x07 | REMOTE | BOOT ), + UPDA_166 = ( 0x08 | BOOT ), + UPDA_BC = ( 0x09 | REMOTE | BOOT ) +}; + + + +typedef int16_t DAC_VAL; + +#define _mbg_swab_dac_val( _p ) \ + _mbg_swab16( _p ) + + + +/** + * @brief Satellite receiver status information + */ +typedef struct stat_info_s +{ + uint16_t mode; ///< Mode of operation, see ::RECEIVER_MODES + uint16_t good_svs; ///< Numb. of satellites that can currently be received and used + uint16_t svs_in_view; ///< Numb. of satellites that should be visible above the horizon + DAC_VAL dac_val; ///< Oscillator fine DAC value + DAC_VAL dac_cal; ///< Oscillator calibration DAC value ( see ::OSC_DAC_RANGE, ::OSC_DAC_BIAS ) + +} STAT_INFO; + +#define _mbg_swab_stat_info( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->mode ); \ + _mbg_swab16( &(_p)->good_svs ); \ + _mbg_swab16( &(_p)->svs_in_view ); \ + _mbg_swab_dac_val( &(_p)->dac_val ); \ + _mbg_swab_dac_val( &(_p)->dac_cal ); \ +} while ( 0 ) + + +#define OSC_DAC_RANGE 4096UL +#define OSC_DAC_BIAS ( OSC_DAC_RANGE / 2 ) + + + +/** + * @brief Bit masks for a legacy GPS SV status. + * + * Used with ::SV_INFO::stat_flags. + */ +enum SV_STAT_FLAG_MASKS +{ + SV_EXISTS = 0x0001, ///< The SV exists physically. + SV_IS_IN_VIEW = 0x0002, ///< SV should be visible at this moment. + SV_CAN_BE_RECEIVED = 0x0004, ///< SV can be tracked. + SV_MIGHT_BE_USED = 0x0008 ///< SV might be used. +}; + +/** + * @brief A combination of ::SV_STAT_FLAG_MASKS indicating an SV is "good". + * + * Used with ::SV_INFO::stat_flags. + */ +#define SV_IS_GOOD ( SV_EXISTS | SV_IS_IN_VIEW | SV_CAN_BE_RECEIVED | SV_MIGHT_BE_USED ) + + + +/** + * @brief A legacy satellite info structure. + * + * Used with pure GPS receivers. Newer GNSS receivers should + * support the ::GNSS_SV_STATUS structure. + * + * @see ::GNSS_SV_STATUS + */ +typedef struct sv_info_s +{ + SVNO svno; ///< The satellite number, ::MIN_SVNO_GPS...::MAX_SVNO_GPS. + int16_t stat_flags; ///< See ::SV_STAT_FLAG_MASKS. + int16_t elev; ///< Elevetion of the satellite [degrees]. + int16_t azim; ///< Azimuth of the satellite [degrees]. + int16_t doppler; ///< Doppler frequency of the satellite [Hz]. + int32_t est_dly; ///< Estimated signal propagation delay [100 ns units]. + int32_t cap_dly; ///< Measured signal propagation delay [100 ns units]. + +} SV_INFO; + + + +/** + * @brief Information on usage of a receiver channel. + * + * Used with pure GPS receivers. + * + * @note Very old GPS receivers which supported only 5 channels + * provided the ::CHANNEL_5 structure instead. + * + * @see ::CHANNEL_5 + */ +typedef struct +{ + int8_t num; ///< The receiver channel index, starting at 0. + int8_t svno; ///< The satellite number, ::MIN_SVNO_GPS...::MAX_SVNO_GPS. + int16_t doppler; ///< Doppler frequency of the satellite [Hz]. + int16_t elev; ///< Elevetion of the satellite [degrees]. + int16_t status; ///< 1: synchronized to data stream from satellite, else 0. + +} CHANNEL; + + + +/** + * @brief Information on usage of a receiver channel. + * + * Very old GPS receivers which supported only 5 channels + * provided this structure instead of the ::CHANNEL structure. + * + * @see ::CHANNEL + */ +typedef struct +{ + int8_t num; ///< The receiver channel index, starting at 0. + int8_t svno; ///< The satellite number, ::MIN_SVNO_GPS...::MAX_SVNO_GPS. + int16_t status; ///< 1: synchronized to data stream from satellite, else 0. + +} CHANNEL_5; + + + +/** + * @brief An enumeration of known satellite navigation systems + * + * @see ::MBG_GNSS_TYPE_MASKS + * @see ::GNSS_TYPE_STRS + */ +enum MBG_GNSS_TYPES +{ + GNSS_TYPE_GPS, ///< GPS, United States + GNSS_TYPE_GLONASS, ///< GLONASS, Russia + GNSS_TYPE_BEIDOU, ///< BEIDOU, China + 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 Zenith Satellite System + N_GNSS_TYPES ///< Number of defined codes +}; + + +/** + * @brief Bit masks associated with ::MBG_GNSS_TYPES + * + * @see ::MBG_GNSS_TYPES + */ +enum MBG_GNSS_TYPE_MASKS +{ + MBG_GNSS_TYPE_MSK_GPS = ( 1UL << GNSS_TYPE_GPS ), ///< See ::GNSS_TYPE_GPS + MBG_GNSS_TYPE_MSK_GLONASS = ( 1UL << GNSS_TYPE_GLONASS ), ///< See ::GNSS_TYPE_GLONASS + MBG_GNSS_TYPE_MSK_BEIDOU = ( 1UL << GNSS_TYPE_BEIDOU ), ///< See ::GNSS_TYPE_BEIDOU + MBG_GNSS_TYPE_MSK_GALILEO = ( 1UL << GNSS_TYPE_GALILEO ), ///< See ::GNSS_TYPE_GALILEO + MBG_GNSS_TYPE_MSK_WAAS = ( 1UL << GNSS_TYPE_WAAS ), ///< See ::GNSS_TYPE_WAAS + MBG_GNSS_TYPE_MSK_EGNOS = ( 1UL << GNSS_TYPE_EGNOS ), ///< See ::GNSS_TYPE_EGNOS + MBG_GNSS_TYPE_MSK_QZSS = ( 1UL << GNSS_TYPE_QZSS ) ///< See ::GNSS_TYPE_QZSS +}; + + +/** + * @brief Name strings for the the known satellite navigation systems + * + * @see ::MBG_GNSS_TYPES + */ +#define GNSS_TYPE_STRS \ +{ \ + "GPS", \ + "GLONASS", \ + "BEIDOU", \ + "GALILEO", \ + "WAAS", \ + "EGNOS", \ + "QZSS" \ +} + + +#define N_GNSS_MODE_PRIO 8 + +/** + * @brief GNSS mode settings + * + * @see ::MBG_GNSS_TYPES + */ +typedef struct +{ + uint32_t gnss_set; ///< bit mask of currently used GNSS systems, see ::MBG_GNSS_TYPE_MASKS + uint8_t prio[N_GNSS_MODE_PRIO]; ///< See ::MBG_GNSS_TYPES, unused fields set to 0xFF, idx 0 is highest prio + uint32_t flags; ///< unused, currently always 0 (should be named MBG_GNSS_MODE_SETTINGS_FLAG_MASKS) + +} MBG_GNSS_MODE_SETTINGS; + +#define _mbg_swab_mbg_gnss_mode_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->gnss_set ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_GNSS_MODE_SETTINGS settings; ///< Current GNSS mode settings + uint32_t supp_gnss_types; ///< Bit masks of supported GNSS types, see ::MBG_GNSS_TYPE_MASKS + uint16_t flags; ///< See ::MBG_GNSS_MODE_INFO_FLAG_MASKS + uint16_t n_sv_status; ///< Number of ::GNSS_SV_STATUS_IDX structures that can be read (only if ::MBG_GNSS_FLAG_MSK_HAS_SV_STATUS) + +} MBG_GNSS_MODE_INFO; + +#define _mbg_swab_mbg_gnss_mode_info( _p ) \ +do \ +{ \ + _mbg_swab_mbg_gnss_mode_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_gnss_types ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab16( &(_p)->n_sv_status ); \ +} while ( 0 ) + + +/** + * @brief Flag bits used to define ::MBG_GNSS_MODE_INFO_FLAG_MASKS + * + * @see ::MBG_GNSS_MODE_INFO_FLAG_MASKS + */ +enum MBG_GNSS_MODE_INFO_FLAG_BITS +{ + MBG_GNSS_FLAG_EXCLUSIVE, ///< Only one of the supported GNSS systems can be used at the same time + MBG_GNSS_FLAG_HAS_PRIORITY, ///< Priority can be configured using the ::MBG_GNSS_MODE_SETTINGS::prio field + MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER, ///< The ::GNSS_SAT_INFO_IDX structure is supported by the device + MBG_GNSS_FLAG_HAS_SV_STATUS, ///< The ::GNSS_SV_STATUS_IDX structure is supported by the device + MBG_GNSS_FLAG_IS_MULTIBAND, ///< Indicates, that the receiver is a multiband receiver and therefore + ///< supports usage of any combination of GNSS types (even more than 3 types) + N_MBG_GNSS_FLAGS +}; + + +/** + * @brief Flag masks used with ::MBG_GNSS_MODE_INFO::flags + * + * @see ::MBG_GNSS_MODE_INFO_FLAG_BITS + */ +enum MBG_GNSS_MODE_INFO_FLAG_MASKS +{ + MBG_GNSS_FLAG_MSK_EXCLUSIVE = ( 1UL << MBG_GNSS_FLAG_EXCLUSIVE ), ///< See ::MBG_GNSS_FLAG_EXCLUSIVE + MBG_GNSS_FLAG_MSK_HAS_PRIORITY = ( 1UL << MBG_GNSS_FLAG_HAS_PRIORITY ), ///< See ::MBG_GNSS_FLAG_HAS_PRIORITY + MBG_GNSS_FLAG_MSK_SAT_INFO_IDX_SUPP_SER = ( 1UL << MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER ), ///< See ::MBG_GNSS_FLAG_SAT_INFO_IDX_SUPP_SER + MBG_GNSS_FLAG_MSK_HAS_SV_STATUS = ( 1UL << MBG_GNSS_FLAG_HAS_SV_STATUS ), ///< See ::MBG_GNSS_FLAG_HAS_SV_STATUS + MBG_GNSS_FLAG_MSK_IS_MULTIBAND = ( 1UL << MBG_GNSS_FLAG_IS_MULTIBAND ) ///< See ::MBG_GNSS_FLAG_IS_MULTIBAND +}; + + +#define MAX_USED_SATS 32 + +/** + * @brief Satellite information for a particular GNSS type. + */ +typedef struct gnss_sat_info_s +{ + uint8_t gnss_type; ///< GNSS type as enumerated in ::MBG_GNSS_TYPES + uint8_t reserved; ///< Reserved, currently always 0 + uint16_t good_svs; ///< Num. of satellites that can currently be received and used + uint16_t svs_in_view; ///< Num. of satellites that should be visible above the horizon + uint8_t svs[MAX_USED_SATS]; ///< IDs of the satellites actually used for navigation, 0 == not used + +} GNSS_SAT_INFO; + +#define _mbg_swab_gnss_sat_info( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->good_svs ); \ + _mbg_swab16( &(_p)->svs_in_view ); \ +} while ( 0 ) + + + +/** + * @brief One of several sets of satellite information for a particular GNSS type. + * + * + */ +typedef struct +{ + /// @brief GNSS system type index according to ::MBG_GNSS_MODE_INFO::supp_gnss_types. + /// + /// I.e., idx 0 corresponds to the GNSS system for which the least significant + /// bit is set in ::MBG_GNSS_MODE_INFO::supp_gnss_types, idx 1 corresponds to + /// GNSS system for which the next higher bit is set, etc. + /// + /// @note This must ***not*** necessarily match the sequence + /// of the ::MBG_GNSS_TYPES enumeration. + MBG_MSG_IDX idx; + + GNSS_SAT_INFO gnss_sat_info; ///< See ::GNSS_SAT_INFO + +} GNSS_SAT_INFO_IDX; + +#define _mbg_swab_gnss_sat_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_gnss_sat_info( &(_p)->gnss_sat_info ); \ +} while ( 0 ) + + + +/** + * @defgroup group_gnss_sv_status GNSS Satellite Status + * + * @note These structures and associated types are only supported by a device + * if ::MBG_GNSS_FLAG_MSK_HAS_SV_STATUS is set // ::FIXME + * + * @{ */ + +/** + * @brief Detailed GNSS satellite status + * + * @note Pure GPS receivers may only support the ::SV_INFO structure. + * + * @see ::GNSS_SV_STATUS_IDX + * @see ::SV_INFO + * @see @ref group_gnss_sv_stat_flags + */ +typedef struct gnss_sv_status_s +{ + uint8_t gnss_type; ///< GNSS type as enumerated in ::MBG_GNSS_TYPES + uint8_t svno; ///< Satellite number, see ::TODO + uint8_t cn_ratio; ///< Carrier-to-noise ratio [dbHz] + int8_t elev; ///< Elevation [deg], range: -90..90 deg + + int16_t azim; ///< Azimuth [deg], range: 0..360 deg + int16_t pr_residual; ///< Pseudo range residual [m] + + uint32_t stat_flags; ///< see @ref group_gnss_sv_stat_flags + +} GNSS_SV_STATUS; + +#define _mbg_swab_gnss_sv_status( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->gnss_type ); \ + _mbg_swab8( &(_p)->svno ); \ + _mbg_swab8( &(_p)->cn_ratio ); \ + _mbg_swab8( &(_p)->elev ); \ + _mbg_swab16( &(_p)->azim ); \ + _mbg_swab16( &(_p)->pr_residual ); \ + _mbg_swab32( &(_p)->stat_flags ); \ +} while ( 0 ) + + + +/** + * @defgroup group_gnss_sv_stat_flags GNSS status flags encoding + * + * Used with ::GNSS_SV_STATUS::stat_flags. + * + * @{ */ + +/// Bits 0 to 2 are a 3 bit quality indicator, see ::GNSS_SV_STAT_QUALITY_INDS +#define _gnss_sv_stat_quality_ind( __stat_flags ) \ + ( (uint8_t) ( (__stat_flags) & 0x00000007UL ) ) + +/// Bit 3 is set if the SV is actually used for navigation +#define _gnss_sv_stat_sv_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00000008UL ) != 0 ) + +/// Bits 4 and 5 are a 2 bit health code, see ::GNSS_SV_STAT_HEALTH_CODES +#define _gnss_sv_stat_health_code( __stat_flags ) \ + ( (uint8_t) ( ( (__stat_flags) & 0x00000030UL ) >> 4 ) ) + +/// Bit 6 is set if differential correction is available for this SV +#define _gnss_sv_stat_diff_corr( __stat_flags ) \ + ( ( (__stat_flags) & 0x00000040UL ) != 0 ) + +/// Bit 7 is set if carrier smoothed pseudorange is used for this SV +#define _gnss_sv_stat_smoothed( __stat_flags ) \ + ( ( (__stat_flags) & 0x00000080UL ) != 0 ) + +/// Bits 8 to 10 are a 3 bit code indicating the orbit source, see ::GNSS_SV_STAT_ORBIT_SOURCES +#define _gnss_sv_stat_orbit_src( __stat_flags ) \ + ( (uint8_t) ( ( (__stat_flags) & 0x00000700UL ) >> 8 ) ) + +/// Bit 11 is set if ephemeris parameters are available for this SV +#define _gnss_sv_stat_eph_avail( __stat_flags ) \ + ( ( (__stat_flags) & 0x00000800UL ) != 0 ) + +/// Bit 12 is set if almanac parameters are available for this SV +#define _gnss_sv_stat_alm_avail( __stat_flags ) \ + ( ( (__stat_flags) & 0x00001000UL ) != 0 ) + +/// Bit 13 is set if AssistNow Offline data is available for this SV +#define _gnss_sv_stat_ano_avail( __stat_flags ) \ + ( ( (__stat_flags) & 0x00002000UL ) != 0 ) + +/// Bit 14 is set if AssistNow Autonomous data is available for this SV +#define _gnss_sv_stat_aop_avail( __stat_flags ) \ + ( ( (__stat_flags) & 0x00004000UL ) != 0 ) + +/// Bit 15 is reserved. + +/// Bit 16 is set if SBAS corrections have been used for this SV +#define _gnss_sv_stat_sbas_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00010000UL ) != 0 ) + +/// Bit 17 is set if RTCM corrections have been used for this SV +#define _gnss_sv_stat_rtcm_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00020000UL ) != 0 ) + +/// Bits 18 and 19 are reserved. + +/// Bit 20 is set if pseudorange corrections have been used for this SV +#define _gnss_sv_stat_pr_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00100000UL ) != 0 ) + +/// Bit 21 is set if carrier range corrections have been used for this SV +#define _gnss_sv_stat_cr_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00200000UL ) != 0 ) + +/// Bit 22 is set if range rate (doppler) corrections have been used for this SV +#define _gnss_sv_stat_do_corr_used( __stat_flags ) \ + ( ( (__stat_flags) & 0x00400000UL ) != 0 ) + +/// Bits 23 to 31 are reserved. +/// +/// However, we use the MSB (bit 31) here as a private extension +/// to indicate that the satellite can be received on two frequencies, +/// and the ionosphere correction is derived from the dual frequency +/// observation. +/// See ::_gnss_sv_stat_dual_freq +#define GNSS_SV_STAT_DUAL_FREQ_MSK 0x80000000UL + +#define _gnss_sv_stat_dual_freq( __stat_flags ) \ + ( ( (__stat_flags) & GNSS_SV_STAT_DUAL_FREQ_MSK ) != 0 ) + +/** @} defgroup group_gnss_sv_stat_flags */ + + +/** + * @brief Quality indicators used with ::GNSS_SV_STATUS::stat_flags + * + * @see ::_gnss_sv_stat_quality_ind + */ +enum GNSS_SV_STAT_QUALITY_INDS +{ + GNSS_SV_STAT_NO_SIGNAL, ///< No signal + GNSS_SV_STAT_SEARCHING, ///< Searching signal + GNSS_SV_STAT_ACQUIRED, ///< Signal acquired + GNSS_SV_STAT_UNUSABLE, ///< Signal detected but unusable + GNSS_SV_STAT_CODE_LOCKED, ///< Code locked and time synchronized + GNSS_SV_STAT_CODE_CARRIER_LOCKED, ///< Code and carrier locked, and time synchronized + GNSS_SV_STAT_CODE_CARRIER_LOCKED_2, ///< Code and carrier locked, and time synchronized + GNSS_SV_STAT_CODE_CARRIER_LOCKED_3 ///< Code and carrier locked, and time synchronized +}; + + +/** + * @brief Health indicators used with ::GNSS_SV_STATUS::stat_flags + * + * @see ::_gnss_sv_stat_health_code + */ +enum GNSS_SV_STAT_HEALTH_CODES +{ + GNSS_SV_STAT_HEALTH_UNKNOWN, ///< Health status unknown + GNSS_SV_STAT_HEALTH_OK, ///< Healthy + GNSS_SV_STAT_HEALTH_NOT_OK ///< Unhealthy +}; + + +/** + * @brief Orbit source codes used with ::GNSS_SV_STATUS::stat_flags + * + * @see ::_gnss_sv_stat_orbit_src + */ +enum GNSS_SV_STAT_ORBIT_SOURCES +{ + GNSS_SV_STAT_ORBIT_SRC_UNKNOWN, ///< Orbit source unknown + GNSS_SV_STAT_ORBIT_SRC_EPH, ///< Ephemeris data used for orbit + GNSS_SV_STAT_ORBIT_SRC_ALM, ///< Almanac data used for orbit + GNSS_SV_STAT_ORBIT_SRC_ASSN_OFFL, ///< AssistNow Offline orbit is used + GNSS_SV_STAT_ORBIT_SRC_ASSN_AUTO, ///< AssistNow Autonomous orbit is used + GNSS_SV_STAT_ORBIT_OTHER_1, ///< Other orbit information is used + GNSS_SV_STAT_ORBIT_OTHER_2, ///< Other orbit information is used + GNSS_SV_STAT_ORBIT_OTHER_3 ///< Other orbit information is used +}; + + + +/** + * @brief Detailed GNSS satellite status, plus index + * + * @see ::GNSS_SV_STATUS + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; ///< Range 0..::MBG_GNSS_MODE_INFO::n_sv_status-1 + GNSS_SV_STATUS gnss_sv_status; + +} GNSS_SV_STATUS_IDX; + +#define _mbg_swab_gnss_sv_status_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_gnss_sv_status( &(_p)->gnss_sv_status ); \ +} while ( 0 ) + + +/** @} defgroup group_gnss_sv_status */ + + + +#ifndef _IDENT_DEFINED + + typedef union + { + char c[16]; // as string which may NOT be terminated + int16_t wrd[8]; + uint32_t lw[4]; + } IDENT; + + #define _IDENT_DEFINED +#endif + +#define _mbg_swab_ident( _p ) \ +do \ +{ \ + int i; \ + for ( i = 0; i < 4; i++ ) \ + _mbg_swab32( &(_p)->lw[i] ); \ +} while ( 0 ) + + + +/** + * @brief A data type used to configure the length of an antenna cable [m] + */ +typedef uint16_t ANT_CABLE_LEN; + +#define _mbg_swab_ant_cable_len( _p ) _mbg_swab16( _p ) + + + +/** + * @defgroup group_net_cfg Network configuration stuff + * + * @{ */ + +/** + * @defgroup group_net_basic_types Basic network parameter types + * + * @{ */ + +/** + * @brief The MAC address of a network interface + */ +typedef struct mbg_mac_addr_s +{ + uint8_t b[6]; + +} MBG_MAC_ADDR; + +#define _mbg_swab_mbg_mac_addr( _p ) \ + _nop_macro_fnc() + + + +/** + * @brief An IPv4 address + */ +typedef uint32_t IP4_ADDR; + +#define _mbg_swab_ip4_addr( _p ) \ + _mbg_swab32( _p ) + + + +/** @brief The number of bits used for an IPv6 address */ +#define IP6_ADDR_BITS 128 + +/** @brief The number of bytes used for an IPv6 address */ +#define IP6_ADDR_BYTES ( IP6_ADDR_BITS / 8 ) // == 16 + +/** + * @brief An IPv6 address + */ +typedef struct +{ + uint8_t b[IP6_ADDR_BYTES]; ///< bytes holding the address bits (not the string notation), b[0] == LSBs + +} IP6_ADDR; + +#define _mbg_swab_ip6_addr( _p ) _nop_macro_fnc() + + + +/** + * @brief An IPv6 address plus number of netmask bits + */ +typedef struct +{ + IP6_ADDR addr; ///< bit mask of the bytes holding the address bits, b[0] == LSBs + uint8_t prefix; ///< Number of subnet mask bits for CIDR notation, e.g. 24 for /24 + uint8_t reserved[3]; ///< Reserved, alignment, currently 0 + +} IP6_ADDR_CIDR; + + + +/** @brief The max number of chars required for an IPv6 address string */ +#define MAX_IP6_ADDR_STR_LEN 43 ///< e.g. 2001:0db8:85a3:08d3:1319:8a2e:0370:7344/128 + +/** @brief Buffer size required to store an IPv6 address string */ +#define IP6_ADDR_STR_SIZE ( MAX_IP6_ADDR_STR_LEN + 1 ) ///< ::MAX_IP6_ADDR_STR_LEN + terminating 0 + +/** @brief A buffer for an IPv6 address string */ +typedef char IP6_ADDR_STR[IP6_ADDR_STR_SIZE]; + + + +/** + * @brief Possible IPv6 Multicast Scopes + * + * If the first (most significant) byte of an IPv6 address is 0xFF this + * indicates that the address is a multicast address, and in this case + * the second byte determines the scope for which the specified address + * is valid. These scope ID numbers are assigned in RFC 7346 which + * supersedes RFC 4291. + * + * @see ::IPV6_MULTICAST_SCOPE_NAME_TABLE_ENTRIES + */ +enum IPV6_MULTICAST_SCOPES +{ + IPV6_MULTICAST_SCOPE_INTF_LOCAL = 0x01, ///< Interface-Local scope + IPV6_MULTICAST_SCOPE_LINK_LOCAL, ///< Link-Local scope + IPV6_MULTICAST_SCOPE_REALM_LOCAL, ///< Realm-Local scope + IPV6_MULTICAST_SCOPE_ADMIN_LOCAL, ///< Admin-Local scope + IPV6_MULTICAST_SCOPE_SITE_LOCAL, ///< Site-Local scope + IPV6_MULTICAST_SCOPE_ORGA_LOCAL = 0x08, ///< Organization-Local scope + IPV6_MULTICAST_SCOPE_GLOBAL_SCOPE = 0x0E ///< Global scope +}; + + +/** + * @brief Name strings for IPv6 multicast scopes + * + * This can e.g. be used to initialize an array of ::MBG_CODE_NAME_TABLE_ENTRY elements. + * + * @see ::IPV6_MULTICAST_SCOPES + */ +#define IPV6_MULTICAST_SCOPE_NAME_TABLE_ENTRIES \ +{ \ + { IPV6_MULTICAST_SCOPE_INTF_LOCAL, "FF01 - Interface-Local Scope" }, \ + { IPV6_MULTICAST_SCOPE_LINK_LOCAL, "FF02 - Link-Local Scope" }, \ + { IPV6_MULTICAST_SCOPE_REALM_LOCAL, "FF03 - Realm-Local Scope" }, \ + { IPV6_MULTICAST_SCOPE_ADMIN_LOCAL, "FF04 - Admin-Local Scope" }, \ + { IPV6_MULTICAST_SCOPE_SITE_LOCAL, "FF05 - Site-Local Scope" }, \ + { IPV6_MULTICAST_SCOPE_ORGA_LOCAL, "FF08 - Organization-Local Scope" }, \ + { IPV6_MULTICAST_SCOPE_GLOBAL_SCOPE, "FF0E - Global Scope" }, \ + { 0, NULL } \ +} + + + +/** + * @brief The maximum length of a fully qualified host/domain domain name (FQDN) + * + * In theory each single component (host name, domain name, top level domain name) + * of a FQDN can have up to 63 characters, but the overall length is limited to + * 255 characters (see RFC-1123). We specify one more character for the trailing 0. + */ +#define MBG_MAX_HOSTNAME_LEN 256 + + +/** + * @brief A buffer for a fully qualified domain name (FQDN) or a numeric IP address string + */ +typedef char MBG_HOSTNAME[MBG_MAX_HOSTNAME_LEN]; ///< ASCIIZ format + +#define _mbg_swab_mbg_host_name( _p ) _nop_macro_fnc() + + +/** @} defgroup group_net_basic_types */ + + + +/** + * @brief The maximum length of an interface name + * + * We use an extra name here for the Meinberg-specific structures + * to avoid a name clash with system definitions, e.g. Linux systems + * define IFNAMSIZ usually as 16 in linux/if.h. + */ +#define MBG_IFNAMSIZ 16 + + +/** + * @brief Hardware type for identification of physical interfaces + * + */ +enum MBG_NET_HW_TYPES +{ + MBG_NET_HW_TYPE_UNKNOWN, + MBG_ARPHRD_ETHER, + N_MBG_NET_HW_TYPES +}; + + +/** + * @defgroup group_vlan_cfg Definitions used with VLAN configuration + * + * @{ */ + +/** + * @brief VLAN configuration + * + * @note This is a combination of a VLAN ID number plus a VLAN priority code. + */ +typedef uint16_t MBG_VLAN_CFG; + +#define _mbg_swab_mbg_vlan_cfg( _p ) _mbg_swab16( _p ) + +#define VLAN_ID_BITS 12 ///< number of bits to hold the ID +#define N_VLAN_ID ( 1 << VLAN_ID_BITS ) ///< number of ID values +#define MIN_VLAN_ID 0 ///< minimum ID value +#define MAX_VLAN_ID ( N_VLAN_ID - 1 ) ///< maximum ID value + +// vlan_id = ( vlan_cfg >> VLAN_ID_SHIFT ) & VLAN_ID_MSK +#define VLAN_ID_SHIFT 0 +#define VLAN_ID_MSK ( ( 1 << VLAN_ID_BITS ) - 1 ) + + +#define VLAN_PRIORITY_BITS 3 ///< number of bits to hold priority +#define N_VLAN_PRIORITY ( 1 << VLAN_PRIORITY_BITS ) ///< number of priority values +#define MIN_VLAN_PRIORITY 0 ///< minimum priority +#define MAX_VLAN_PRIORITY ( N_VLAN_PRIORITY - 1 ) ///< maximum priority + +// vlan_priority = ( vlan_cfg >> VLAN_PRIORITY_SHIFT ) & VLAN_PRIORITY_MSK +#define VLAN_PRIORITY_SHIFT ( ( 8 * sizeof( MBG_VLAN_CFG ) ) - VLAN_PRIORITY_BITS ) +#define VLAN_PRIORITY_MSK ( ( 1 << VLAN_PRIORITY_BITS ) - 1 ) + +/** + * @brief Macros used to encode/decode packed vlan_cfg variables + */ +#define _decode_vlan_id( _cfg ) ( ( (_cfg) >> VLAN_ID_SHIFT ) & VLAN_ID_MSK ) +#define _decode_vlan_priority( _cfg ) ( ( (_cfg) >> VLAN_PRIORITY_SHIFT ) & VLAN_PRIORITY_MSK ) +#define _encode_vlan_cfg( _id, _prty ) ( ( (_id) << VLAN_ID_SHIFT ) | ( (_prty) << VLAN_PRIORITY_SHIFT ) ) + +/** @} defgroup group_vlan_cfg */ + + + +/** + * @defgroup group_ip4_cfg Simple IPv4-only configuration or status + * + * This is only supported if the flag ::GPS_HAS_LAN_IP4 is set + * in ::RECEIVER_INFO::features. + * @see @ref group_ext_net_cfg Extended network configuration and status + * + * @{ */ + +/** + * @brief Settings of an IPv4-only network interface + */ +typedef struct +{ + IP4_ADDR ip_addr; ///< the IP address + IP4_ADDR netmask; ///< the network mask + IP4_ADDR broad_addr; ///< the broadcast address + IP4_ADDR gateway; ///< the default gateway + uint16_t flags; ///< See ::MBG_IP4_FLAG_MASKS + MBG_VLAN_CFG vlan_cfg; ///< VLAN configuration + +} IP4_SETTINGS; + +#define _mbg_swab_ip4_settings( _p ) \ +do \ +{ \ + _mbg_swab_ip4_addr( &(_p)->ip_addr ); \ + _mbg_swab_ip4_addr( &(_p)->netmask ); \ + _mbg_swab_ip4_addr( &(_p)->broad_addr ); \ + _mbg_swab_ip4_addr( &(_p)->gateway ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab_mbg_vlan_cfg( &(_p)->vlan_cfg ); \ +} while ( 0 ) + + + +/** + * @brief Simple LAN interface information + * + * This structure can be obtained from a device + * to check the capabilities of the device. + * + * It is only supported if the flag ::GPS_HAS_LAN_IP4 is set + * in ::RECEIVER_INFO::features. + * + * @see @ref group_ext_net_cfg Extended network configuration and status + */ +typedef struct +{ + uint16_t type; ///< type of LAN interface, see ::LAN_IF_TYPES + MBG_MAC_ADDR mac_addr; ///< MAC address + uint16_t ver_code; ///< version number (hex) + char ver_str[GPS_ID_STR_SIZE]; ///< version string + char sernum[GPS_ID_STR_SIZE]; ///< serial number + uint32_t rsvd_0; ///< reserved, currently always 0 + uint16_t flags; ///< See ::MBG_IP4_FLAG_MASKS + uint16_t rsvd_1; ///< reserved, currently always 0 + +} LAN_IF_INFO; + +#define _mbg_swab_lan_if_info( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->type ); \ + _mbg_swab16( &(_p)->ver_code ); \ + _mbg_swab32( &(_p)->rsvd_0 ); \ + _mbg_swab16( &(_p)->flags ); \ + _mbg_swab16( &(_p)->rsvd_1 ); \ +} while ( 0 ) + + +/** + * @brief Codes used with ::LAN_IF_INFO::type + */ +enum LAN_IF_TYPES +{ + LAN_IF_TYPE_XPORT, ///< LAN interface on an XPORT, superseded by RSC devices + LAN_IF_TYPE_PTP, ///< LAN interface is a special PTP interface + LAN_IF_TYPE_RSC, ///< RSC device, supersedes XPORT + N_LAN_IF_TYPE ///< number of defined LAN interface types +}; + + +/** + * @brief Enumeration of flag bits used with ::IP4_SETTINGS::flags and ::LAN_IF_INFO::flags + * + * @see ::MBG_IP4_FLAG_MASKS + */ +enum MBG_IP4_FLAG_BITS +{ + /// In ::LAN_IF_INFO::flags this reports if DHCP is supported by the device. + /// If supported then it can also be used with ::IP4_SETTINGS::flags to enable + /// or disable DHCP for the network interface. + IP4_BIT_DHCP, + + /// Only used with ::IP4_SETTINGS::flags. Set if port link has been established. + IP4_BIT_LINK, + + /// In ::LAN_IF_INFO::flags this reports if VLAN is supported by the device. + /// If supported then it can also be used with ::IP4_SETTINGS::flags to enable + /// or disable VLAN for the network interface. + IP4_BIT_VLAN, + + N_IP4_BIT ///< number of defined flag bits +}; + + +/** + * @brief Bit masks used with ::IP4_SETTINGS::flags and ::LAN_IF_INFO::flags + * + * @see ::MBG_IP4_FLAG_BITS + */ +enum MBG_IP4_FLAG_MASKS +{ + IP4_MSK_DHCP = ( 1UL << IP4_BIT_DHCP ), ///< See ::IP4_BIT_DHCP + IP4_MSK_LINK = ( 1UL << IP4_BIT_LINK ), ///< See ::IP4_BIT_LINK + IP4_MSK_VLAN = ( 1UL << IP4_BIT_VLAN ), ///< See ::IP4_BIT_VLAN +}; + +/** @} defgroup group_ip4_cfg */ + + + +/** + * @defgroup group_ext_net_cfg_types Types used for extended network configuration and status + * + * @{ */ + +/** + * @brief Enumeration of types used with ::MBG_IP_ADDR::type + */ +enum MBG_IP_ADDR_TYPES +{ + MBG_IP_ADDR_TYPE_UNKNOWN, + MBG_IP_ADDR_TYPE_IP4, + MBG_IP_ADDR_TYPE_IP6, + N_MBG_IP_ADDR_TYPES +}; + +/* + * Default initializers for English mode string names. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_IP_ADDR_TYPE_STR_ENG_UNKNOWN "unknown" +#define MBG_IP_ADDR_TYPE_STR_ENG_IP4 "IPv4" +#define MBG_IP_ADDR_TYPE_STR_ENG_IP6 "IPv6" + +#define MBG_IP_ADDR_TYPE_NAMES_ENG \ +{ \ + MBG_IP_ADDR_TYPE_STR_ENG_UNKNOWN, \ + MBG_IP_ADDR_TYPE_STR_ENG_IP4, \ + MBG_IP_ADDR_TYPE_STR_ENG_IP6 \ +} + + +/** + * @brief Feature flag bits used to define ::MBG_NET_GLB_CFG_INFO_MASKS + * + * @see ::MBG_NET_GLB_CFG_INFO_MASKS + */ +enum MBG_NET_GLB_CFG_INFO_FLAGS +{ + MBG_NET_GLB_SUPP_STAGE_2, ///< Supports commands which have been added in stage 2 + MBG_NET_GLB_SUPP_BONDING, ///< Supports bonding + 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 +}; + + +/** + * @brief Flag masks used with ::MBG_NET_GLB_CFG_INFO::feat_flags + * + * @see ::MBG_NET_GLB_CFG_INFO_FLAGS + */ +enum MBG_NET_GLB_CFG_INFO_MASKS +{ + MBG_NET_GLB_SUPP_STAGE_2_MASK = (1UL << MBG_NET_GLB_SUPP_STAGE_2), ///< See ::MBG_NET_GLB_SUPP_STAGE_2 + MBG_NET_GLB_SUPP_BONDING_MASK = (1UL << MBG_NET_GLB_SUPP_BONDING), ///< See ::MBG_NET_GLB_SUPP_BONDING + 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 +}; + + + +/** + * @brief Network interface link speed mode enumeration + * + * @see @ref MBG_NET_INTF_LINK_SPEED_MODE_MASKS + */ +enum MBG_NET_INTF_LINK_SPEED_MODES +{ + MBG_NET_INTF_LINK_SPEED_MODE_UNKNOWN, ///< Unknown speed mode + MBG_NET_INTF_LINK_SPEED_MODE_10_T_HALF, ///< 10baseT Half Duplex (10 MBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10_T_FULL, ///< 10baseT Full Duplex (10 MBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_100_T_HALF, ///< 100baseT Half Duplex (100 MBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_100_T_FULL, ///< 100baseT Full Duplex (100 MBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_1000_T_HALF, ///< 1000baseT Half Duplex (1 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_1000_T_FULL, ///< 1000baseT Full Duplex (1 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_1000_KX_FULL, ///< 1000baseKX Full Duplex (1 GBit/s) + + MBG_NET_INTF_LINK_SPEED_MODE_2500_X_FULL, ///< 2500baseX Full Duplex (2.5 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10000_T_FULL, ///< 10000baseT Full Duplex (10 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10000_KX4_FULL, ///< 10000baseKX4 Full Duplex (10 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10000_KR_FULL, ///< 10000baseKR Full Duplex (10 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_10000_R_FEC, ///< 10000baseR FEC (forward error correction) (10 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_20000_MLD2_FULL, ///< 20000baseMLD2 Full Duplex (20 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_20000_KR2_FULL, ///< 20000baseKR2 Full Duplex (20 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_40000_KR4_FULL, ///< 40000baseKR4 Full Duplex (40 GBit/s) + + MBG_NET_INTF_LINK_SPEED_MODE_40000_CR4_FULL, ///< 40000baseCR4 Full Duplex (40 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_40000_SR4_FULL, ///< 40000baseSR4 Full Duplex (40 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_40000_LR4_FULL, ///< 40000baseLR4 Full Duplex (40 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_56000_KR4_FULL, ///< 56000baseKR4 Full Duplex (56 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_56000_CR4_FULL, ///< 56000baseCR4 Full Duplex (56 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_56000_SR4_FULL, ///< 56000baseSR4 Full Duplex (56 GBit/s) + MBG_NET_INTF_LINK_SPEED_MODE_56000_LR4_FULL, ///< 56000baseLR4 Full Duplex (56 GBit/s) + + N_MBG_NET_INTF_LINK_SPEED_MODES +}; + + + +/** + * @brief Network interface link speed mode masks + * + * @see ::MBG_NET_INTF_LINK_SPEED_MODES + * + * @anchor MBG_NET_INTF_LINK_SPEED_MODE_MASKS @{ */ + +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_UNKNOWN ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_UNKNOWN ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_UNKNOWN +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_HALF ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10_T_HALF ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_10_T_HALF +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10_T_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_10_T_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_HALF ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_100_T_HALF ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_100_T_HALF +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_100_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_100_T_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_100_T_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_1000_T_HALF ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_1000_T_HALF ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_1000_T_HALF +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_1000_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_1000_T_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_1000_T_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_1000_KX_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_1000_KX_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_1000_KX_FULL + +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_2500_X_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_2500_X_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_2500_X_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_T_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_T_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_10000_T_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_KX4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_KX4_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_10000_KX4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_KR_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_KR_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_10000_KR_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_10000_R_FEC ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_10000_R_FEC ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_10000_R_FEC +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_20000_MLD2_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_20000_MLD2_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_20000_MLD2_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_20000_KR2_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_20000_KR2_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_20000_KR2_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_KR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_KR4_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_40000_KR4_FULL + +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_CR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_CR4_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_40000_CR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_SR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_SR4_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_40000_SR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_40000_LR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_40000_LR4_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_40000_LR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_KR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_KR4_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_56000_KR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_CR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_CR4_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_56000_CR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_SR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_SR4_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_56000_SR4_FULL +#define MBG_NET_INTF_LINK_SPEED_MODE_MASK_56000_LR4_FULL ( 1UL << MBG_NET_INTF_LINK_SPEED_MODE_56000_LR4_FULL ) ///< See ::MBG_NET_INTF_LINK_SPEED_MODE_56000_LR4_FULL + +/** @} anchor MBG_NET_INTF_LINK_SPEED_MODE_MASKS */ + + + +/** + * @brief Network interface link speeds [Mb/s] + * + * @see @ref MBG_NET_INTF_LINK_SPEED_MODE_MASKS + */ +enum MBG_NET_INTF_LINK_SPEEDS +{ + MBG_NET_INTF_LINK_SPEED_UNKNOWN = 0UL, + MBG_NET_INTF_LINK_SPEED_10 = 10UL, + MBG_NET_INTF_LINK_SPEED_100 = 100UL, + MBG_NET_INTF_LINK_SPEED_1000 = 1000UL, + MBG_NET_INTF_LINK_SPEED_2500 = 2500UL, + MBG_NET_INTF_LINK_SPEED_10000 = 10000UL, + MBG_NET_INTF_LINK_SPEED_20000 = 20000UL, + MBG_NET_INTF_LINK_SPEED_40000 = 40000UL, + MBG_NET_INTF_LINK_SPEED_56000 = 56000UL +}; + + + +/** + * @brief Network interface link port types + * + * @see ::MBG_NET_INTF_LINK_PORT_TYPE_MASKS + */ +enum MBG_NET_INTF_LINK_PORT_TYPES +{ + MBG_NET_INTF_LINK_PORT_TYPE_UNKNOWN, ///< Unknown port type + MBG_NET_INTF_LINK_PORT_TYPE_TP, ///< Twisted Pair (TP) copper cable + MBG_NET_INTF_LINK_PORT_TYPE_FIBRE, ///< Fibre Optic (FO) cable + MBG_NET_INTF_LINK_PORT_TYPE_BNC, ///< Coaxial BNC cable + MBG_NET_INTF_LINK_PORT_TYPE_AUI, ///< Attachment Unit Interface (AUI), externel transceiver + MBG_NET_INTF_LINK_PORT_TYPE_MII, ///< Media Independent Interface (MII), external receiver + MBG_NET_INTF_LINK_PORT_TYPE_DA, ///< Direct attach SFP+ connection + N_MBG_NET_INTF_LINK_PORT_TYPES +}; + + + +/** + * @brief Network interface link port masks + * + * @see ::MBG_NET_INTF_LINK_PORT_TYPES + */ +enum MBG_NET_INTF_LINK_PORT_TYPE_MASKS +{ + MBG_NET_INTF_LINK_PORT_TYPE_MASK_UNKNOWN = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_UNKNOWN ), ///< See ::MBG_NET_INTF_LINK_PORT_TYPE_UNKNOWN + MBG_NET_INTF_LINK_PORT_TYPE_MASK_TP = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_TP ), ///< See ::MBG_NET_INTF_LINK_PORT_TYPE_TP + MBG_NET_INTF_LINK_PORT_TYPE_MASK_FIBRE = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_FIBRE ), ///< See ::MBG_NET_INTF_LINK_PORT_TYPE_FIBRE + MBG_NET_INTF_LINK_PORT_TYPE_MASK_BNC = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_BNC ), ///< See ::MBG_NET_INTF_LINK_PORT_TYPE_BNC + MBG_NET_INTF_LINK_PORT_TYPE_MASK_AUI = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_AUI ), ///< See ::MBG_NET_INTF_LINK_PORT_TYPE_AUI + MBG_NET_INTF_LINK_PORT_TYPE_MASK_MII = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_MII ), ///< See ::MBG_NET_INTF_LINK_PORT_TYPE_MII + MBG_NET_INTF_LINK_PORT_TYPE_MASK_DA = ( 1UL << MBG_NET_INTF_LINK_PORT_TYPE_DA ) ///< See ::MBG_NET_INTF_LINK_PORT_TYPE_DA +}; + + + +/** + * @brief Initializers for network interface link port type long strings + * + * @see ::MBG_NET_INTF_LINK_PORT_TYPES + */ +#define MBG_NET_INTF_LINK_PORT_TYPE_LONG_STRS \ +{ \ + "Unknown", \ + "Twisted Pair", \ + "Fibre Optic", \ + "Coaxial BNC", \ + "Attachment Unit Interface", \ + "Media Independent Interface", \ + "Direct Attach SFP+" \ +} + + +/** + * @brief Initializers for network interface link port type short strings + * + * @see ::MBG_NET_INTF_LINK_PORT_TYPES + */ +#define MBG_NET_INTF_LINK_PORT_TYPE_SHORT_STRS \ +{ \ + "Unknown", \ + "TP", \ + "FO", \ + "BNC", \ + "AUI", \ + "MII", \ + "DA" \ +} + + +/** + * @brief Network interface link state bits + * + * @see @ref MBG_NET_INTF_LINK_STATE_MASKS + * + * @note See official Linux kernel documentation + * https://www.kernel.org/doc/Documentation/networking/operstates.txt + * for states below and explanations. Windows supports this in nearly the same way + * using similar names struct IP_ADAPTER_ADDRESSES which is explained at + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058%28v=vs.85%29.aspx + */ +enum MBG_NET_INTF_LINK_STATE_BITS +{ + MBG_NET_INTF_LINK_STATE_BIT_UP, + MBG_NET_INTF_LINK_STATE_BIT_RUNNING, + MBG_NET_INTF_LINK_STATE_BIT_LOWER_UP, + MBG_NET_INTF_LINK_STATE_BIT_DORMANT, + MBG_NET_INTF_LINK_STATE_BIT_BROADCAST, + MBG_NET_INTF_LINK_STATE_BIT_MULTICAST, + MBG_NET_INTF_LINK_STATE_BIT_ALL_MULTI, + MBG_NET_INTF_LINK_STATE_BIT_DEBUG, + + MBG_NET_INTF_LINK_STATE_BIT_LOOPBACK, + MBG_NET_INTF_LINK_STATE_BIT_POINT_TO_POINT, + MBG_NET_INTF_LINK_STATE_BIT_NO_ARP, + MBG_NET_INTF_LINK_STATE_BIT_PROMISC, + MBG_NET_INTF_LINK_STATE_BIT_MASTER, + MBG_NET_INTF_LINK_STATE_BIT_SLAVE, + MBG_NET_INTF_LINK_STATE_BIT_PORT_SEL, + MBG_NET_INTF_LINK_STATE_BIT_AUTO_MEDIA, + + MBG_NET_INTF_LINK_STATE_BIT_ECHO, + MBG_NET_INTF_LINK_STATE_BIT_DYNAMIC, + MBG_NET_INTF_LINK_STATE_BIT_NO_TRAILERS, + + N_MBG_NET_INTF_LINK_STATE_BITS +}; + + + +/** + * @brief Network interface link state masks + * + * @see ::MBG_NET_INTF_LINK_STATE_BITS (reclined to Linux' if.h, Windows is similiar) + * + * @anchor MBG_NET_INTF_LINK_STATE_MASKS @{ */ + +#define MBG_NET_INTF_LINK_STATE_MASK_UP ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_UP ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_UP +#define MBG_NET_INTF_LINK_STATE_MASK_RUNNING ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_RUNNING ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_RUNNING +#define MBG_NET_INTF_LINK_STATE_MASK_LOWER_UP ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_LOWER_UP ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_LOWER_UP +#define MBG_NET_INTF_LINK_STATE_MASK_DORMANT ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_DORMANT ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_DORMANT +#define MBG_NET_INTF_LINK_STATE_MASK_BROADCAST ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_BROADCAST ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_BROADCAST +#define MBG_NET_INTF_LINK_STATE_MASK_MULTICAST ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_MULTICAST ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_MULTICAST +#define MBG_NET_INTF_LINK_STATE_MASK_ALL_MULTI ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_ALL_MULTI ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_ALL_MULTI +#define MBG_NET_INTF_LINK_STATE_MASK_DEBUG ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_DEBUG ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_DEBUG + +#define MBG_NET_INTF_LINK_STATE_MASK_LOOPBACK ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_LOOPBACK ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_LOOPBACK +#define MBG_NET_INTF_LINK_STATE_MASK_POINT_TO_POINT ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_POINT_TO_POINT ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_POINT_TO_POINT +#define MBG_NET_INTF_LINK_STATE_MASK_NO_ARP ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_NO_ARP ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_NO_ARP +#define MBG_NET_INTF_LINK_STATE_MASK_PROMISC ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_PROMISC ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_PROMISC +#define MBG_NET_INTF_LINK_STATE_MASK_MASTER ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_MASTER ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_MASTER +#define MBG_NET_INTF_LINK_STATE_MASK_SLAVE ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_SLAVE ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_SLAVE +#define MBG_NET_INTF_LINK_STATE_MASK_PORT_SEL ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_PORT_SEL ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_PORT_SEL +#define MBG_NET_INTF_LINK_STATE_MASK_AUTO_MEDIA ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_AUTO_MEDIA ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_AUTO_MEDIA + +#define MBG_NET_INTF_LINK_STATE_MASK_ECHO ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_ECHO ) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_ECHO +#define MBG_NET_INTF_LINK_STATE_MASK_DYNAMIC ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_DYNAMIC) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_DYNAMIC +#define MBG_NET_INTF_LINK_STATE_MASK_NO_TRAILERS ( 1UL << MBG_NET_INTF_LINK_STATE_BIT_NO_TRAILERS) ///< See ::MBG_NET_INTF_LINK_STATE_BIT_NO_TRAILERS + +/** @} anchor MBG_NET_INTF_LINK_STATE_MASKS */ + + + +/** + * @brief Network interface link option bits + * + * @see ::MBG_NET_INTF_LINK_OPT_MASKS + */ +enum MBG_NET_INTF_LINK_OPTS +{ + MBG_NET_INTF_LINK_OPT_CAN_SET_MAC, + MBG_NET_INTF_LINK_OPT_CAN_SYNCE_IN, + MBG_NET_INTF_LINK_OPT_CAN_SYNCE_OUT, + MBG_NET_INTF_LINK_OPT_CAN_AUTONEG, + MBG_NET_INTF_LINK_OPT_CAN_NTP_HW_TS, + MBG_NET_INTF_LINK_OPT_CAN_PTP_HW_TS, + MBG_NET_INTF_LINK_OPT_HAS_NTP_LIC, ///< Indicates, that the physical interface has a license for number of NTP clients + MBG_NET_INTF_LINK_OPT_HAS_PTP_LIC, ///< Indicates, that the physical interface has a license for number of PTP clients + MBG_NET_INTF_LINK_OPT_HAS_SYNCE_STATUS, + N_MBG_NET_INTF_LINK_OPTS +}; + + + +/** + * @brief Network interface link option masks + * + * @see ::MBG_NET_INTF_LINK_OPTS + */ +enum MBG_NET_INTF_LINK_OPT_MASKS +{ + MBG_NET_INTF_LINK_OPT_MASK_CAN_SET_MAC = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_SET_MAC ), ///< See ::MBG_NET_INTF_LINK_OPT_CAN_SET_MAC + MBG_NET_INTF_LINK_OPT_MASK_CAN_SYNCE_IN = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_SYNCE_IN ), ///< See ::MBG_NET_INTF_LINK_OPT_CAN_SYNCE_IN + MBG_NET_INTF_LINK_OPT_MASK_CAN_SYNCE_OUT = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_SYNCE_OUT ), ///< See ::MBG_NET_INTF_LINK_OPT_CAN_SYNCE_OUT + MBG_NET_INTF_LINK_OPT_MASK_CAN_AUTONEG = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_AUTONEG ), ///< See ::MBG_NET_INTF_LINK_OPT_CAN_AUTONEG + MBG_NET_INTF_LINK_OPT_MASK_CAN_NTP_HW_TS = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_NTP_HW_TS ), ///< See ::MBG_NET_INTF_LINK_OPT_CAN_NTP_HW_TS + MBG_NET_INTF_LINK_OPT_MASK_CAN_PTP_HW_TS = ( 1UL << MBG_NET_INTF_LINK_OPT_CAN_PTP_HW_TS ), ///< See ::MBG_NET_INTF_LINK_OPT_CAN_PTP_HW_TS + MBG_NET_INTF_LINK_OPT_MASK_HAS_NTP_LIC = ( 1UL << MBG_NET_INTF_LINK_OPT_HAS_NTP_LIC ), ///< See ::MBG_NET_INTF_LINK_OPT_HAS_NTP_LIC + MBG_NET_INTF_LINK_OPT_MASK_HAS_PTP_LIC = ( 1UL << MBG_NET_INTF_LINK_OPT_HAS_PTP_LIC ), ///< See ::MBG_NET_INTF_LINK_OPT_HAS_PTP_LIC + MBG_NET_INTF_LINK_OPT_MASK_HAS_SYNCE_STATUS = ( 1UL << MBG_NET_INTF_LINK_OPT_HAS_SYNCE_STATUS ) ///< See ::MBG_NET_INTF_LINK_OPT_HAS_SYNCE_STATUS +}; + + + +/** + * @brief Network interface link bonding mode + * + * Used with ::MBG_NET_INTF_LINK_SETTINGS::bond_mode + * + * @note if_bonding.h contains bonding modes under Linux, found no hint under Windows. + * BUT: Something similiar (concerning naming) can be configured under Windows + * via GUI in device manager, if supported. + */ +enum MBG_NET_INTF_LINK_BOND_MODES +{ + MBG_NET_INTF_LINK_BOND_MODE_ROUNDROBIN, + MBG_NET_INTF_LINK_BOND_MODE_ACTIVEBACKUP, + MBG_NET_INTF_LINK_BOND_MODE_XOR, + MBG_NET_INTF_LINK_BOND_MODE_BROADCAST, + MBG_NET_INTF_LINK_BOND_MODE_8023AD, + MBG_NET_INTF_LINK_BOND_MODE_TLB, + MBG_NET_INTF_LINK_BOND_MODE_ALB, + N_MBG_NET_INTF_LINK_BOND_MODES +}; + + + +/** + * @brief Network interface link bonding mode masks + * + * @see ::MBG_NET_INTF_LINK_BOND_MODES + */ +enum MBG_NET_INTF_LINK_BOND_MODE_MASKS +{ + MBG_NET_INTF_LINK_BOND_MODE_MASK_ROUNDROBIN = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_ROUNDROBIN ), ///< See ::MBG_NET_INTF_LINK_BOND_MODE_ROUNDROBIN + MBG_NET_INTF_LINK_BOND_MODE_MASK_ACTIVEBACKUP = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_ACTIVEBACKUP ), ///< See ::MBG_NET_INTF_LINK_BOND_MODE_ACTIVEBACKUP + MBG_NET_INTF_LINK_BOND_MODE_MASK_XOR = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_XOR ), ///< See ::MBG_NET_INTF_LINK_BOND_MODE_XOR + MBG_NET_INTF_LINK_BOND_MODE_MASK_BROADCAST = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_BROADCAST ), ///< See ::MBG_NET_INTF_LINK_BOND_MODE_BROADCAST + MBG_NET_INTF_LINK_BOND_MODE_MASK_8023AD = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_8023AD ), ///< See ::MBG_NET_INTF_LINK_BOND_MODE_8023AD + MBG_NET_INTF_LINK_BOND_MODE_MASK_TLB = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_TLB ), ///< See ::MBG_NET_INTF_LINK_BOND_MODE_TLB + MBG_NET_INTF_LINK_BOND_MODE_MASK_ALB = ( 1UL << MBG_NET_INTF_LINK_BOND_MODE_ALB ), ///< See ::MBG_NET_INTF_LINK_BOND_MODE_ALB +}; + + + +/** + * @brief Network interface link bonding mode name strings + * + * @see ::MBG_NET_INTF_LINK_BOND_MODES + */ +#define MBG_NET_INTF_LINK_BOND_MODE_STRS \ +{ \ + "Round Robin", \ + "Active Backup", \ + "XOR", \ + "Broadcast", \ + "802.3ad (LACP)", \ + "TLB", \ + "ALB" \ +} + + + +/** + * @brief Network interface link bonding states + * + * Used with ::MBG_NET_INTF_LINK_SETTINGS::bond_state + */ +enum MBG_NET_INTF_LINK_BOND_STATES +{ + MBG_NET_INTF_LINK_BOND_STATE_ACTIVE, + MBG_NET_INTF_LINK_BOND_STATE_BACKUP, + N_MBG_NET_INTF_LINK_BOND_STATES +}; + + +/** + * @brief Network interface link type bits + * + * Used with ::MBG_NET_INTF_LINK_SETTINGS::type + * + * @see ::MBG_NET_INTF_LINK_TYPE_MASKS + */ +enum MBG_NET_INTF_LINK_TYPES +{ + MBG_NET_INTF_LINK_TYPE_PHYS, ///< Real physical network interface + MBG_NET_INTF_LINK_TYPE_VLAN, ///< VLAN interface, assigned to physical interface + MBG_NET_INTF_LINK_TYPE_BOND, ///< Bonding interface, which acts as bonding master + N_MBG_NET_INTF_LINK_TYPE_BITS +}; + + +/** + * @brief Network interface link type masks + * + * Used with ::MBG_NET_INTF_LINK_INFO::supp_types + * + * @see ::MBG_NET_INTF_LINK_TYPES + */ +enum MBG_NET_INTF_LINK_TYPE_MASKS +{ + MBG_NET_INTF_LINK_TYPE_MASK_PHYS = ( 1UL << MBG_NET_INTF_LINK_TYPE_PHYS ), ///< See ::MBG_NET_INTF_LINK_TYPE_PHYS + MBG_NET_INTF_LINK_TYPE_MASK_VLAN = ( 1UL << MBG_NET_INTF_LINK_TYPE_VLAN ), ///< See ::MBG_NET_INTF_LINK_TYPE_VLAN + MBG_NET_INTF_LINK_TYPE_MASK_BOND = ( 1UL << MBG_NET_INTF_LINK_TYPE_BOND ) ///< See ::MBG_NET_INTF_LINK_TYPE_BOND +}; + + +/** + * @brief Network interface address bits + * + * @see ::MBG_NET_INTF_ADDR_MASKS + * + * Used with ::MBG_NET_INTF_ADDR_INFO::supp_flags and ::MBG_NET_INTF_ADDR_SETTINGS::flags + */ +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 +}; + + + +/** + * @brief Network interface address masks + * + * @see ::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_AUTOCONF = ( 1UL << MBG_NET_INTF_ADDR_BIT_AUTOCONF ) ///< See ::MBG_NET_INTF_ADDR_BIT_AUTOCONF +}; + + +enum MBG_NET_INTF_ROUTE_TYPES +{ + MBG_NET_INTF_ROUTE_TYPE_UNKNOWN, + MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY, + MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY, + MBG_NET_INTF_ROUTE_TYPE_DEST_ADDR, + N_MBG_NET_INTF_ROUTE_TYPES +}; + +/** @} defgroup group_ext_net_cfg_types */ + + + +/** + * @defgroup group_ext_net_cfg Extended network configuration and status + * + * This is only supported if the flag ::GPS_HAS_NET_CFG is set + * in ::RECEIVER_INFO::features. + * + * @{ */ + +/** + * @brief Global network configuration settings + */ +typedef struct +{ + MBG_HOSTNAME hostname; ///< hostname, eventually FQDN including domain name + + uint8_t num_intf_link; ///< number of detected/configured physical network interfaces (links), see ::MBG_NET_INTF_LINK_INFO_IDX + uint8_t num_intf_addr; ///< number of configured interface addresses, see ::MBG_NET_INTF_ADDR_INFO_IDX + uint8_t num_dns_srvr; ///< number of configured DNS servers, see ::MBG_IP_ADDR_IDX + uint8_t num_dns_srch_dom; ///< number of configured DNS search domains, see ::MBG_NET_NAME_IDX + uint8_t num_intf_route; ///< number of configured interface routes, see ::MBG_NET_INTF_ROUTE_INFO_IDX + + uint8_t reserved; ///< currently reserved, always 0 + uint16_t flags; ///< currently reserved, always 0 + +} MBG_NET_GLB_CFG_SETTINGS; + +#define _mbg_swab_net_glb_cfg_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + +/** + * @brief Global current network settings and supported features + */ +typedef struct +{ + MBG_NET_GLB_CFG_SETTINGS glb_settings; + uint16_t n_supp_intf_link; ///< max. number of supported physical network interfaces (links), see ::MBG_NET_INTF_LINK_SETTINGS_IDX, ::MBG_NET_INTF_LINK_INFO_IDX + uint16_t n_supp_intf_addr; ///< max. number of supported interface addresses, see ::MBG_NET_INTF_ADDR_SETTINGS_IDX, ::MBG_NET_INTF_ADDR_INFO_IDX + uint16_t n_supp_dns_srvr; ///< max. number of supported DNS server addresses, using ::MBG_IP_ADDR_IDX records + uint16_t n_supp_dns_srch_dom; ///< max. number of supported DNS search domain records, using ::MBG_NET_NAME_IDX records + uint16_t n_supp_intf_route; ///< max. number of supported interface routes, see ::MBG_NET_INTF_ROUTE_SETTINGS_IDX, ::MBG_NET_INTF_ROUTE_INFO_IDX + uint16_t max_hostname_len; ///< max. length of hostname including trailing 0; if set to 0, max. length is 256 (see rfc1123) + uint32_t reserved_1; ///< currently reserved, always 0 + uint32_t reserved_2; ///< currently reserved, always 0 + uint32_t feat_flags; ///< Feature flags, see ::MBG_NET_GLB_CFG_INFO_MASKS + uint32_t flags_2; ///< currently reserved, always 0 + +} MBG_NET_GLB_CFG_INFO; + +#define _mbg_swab_net_glb_cfg_info( _p ) \ +do \ +{ \ + _mbg_swab_net_glb_cfg_settings( &(_p)->glb_settings ); \ + _mbg_swab16( &(_p)->n_supp_intf_link ); \ + _mbg_swab16( &(_p)->n_supp_intf_addr ); \ + _mbg_swab16( &(_p)->n_supp_dns_srvr ); \ + _mbg_swab16( &(_p)->n_supp_dns_srch_dom ); \ + _mbg_swab16( &(_p)->n_supp_intf_route ); \ + _mbg_swab16( &(_p)->max_hostname_len ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->feat_flags ); \ + _mbg_swab32( &(_p)->flags_2 ); \ +} while ( 0 ) + + + +/** + * @brief An IPv4 or IPv6 network address + */ +typedef struct mbg_ip_addr_s +{ + uint8_t type; ///< See ::MBG_IP_ADDR_TYPES + uint8_t reserved_1; ///< reserved, currently always 0 @todo Do we need this as scope indicator? + uint16_t reserved_2; ///< reserved, currently always 0 + + union u_addr + { + IP4_ADDR ip4_addr; ///< IPv4 address if ::MBG_IP_ADDR::type == MBG_IP_ADDR_TYPE_IP4 + IP6_ADDR ip6_addr; ///< IPv6 address if ::MBG_IP_ADDR::type == MBG_IP_ADDR_TYPE_IP6 + } u_addr; + +} MBG_IP_ADDR; + +#define _mbg_swab_ip_addr( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->type ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + \ + switch ( (_p)->type ) \ + { \ + case MBG_IP_ADDR_TYPE_IP4: \ + _mbg_swab_ip4_addr( &(_p)->u_addr.ip4_addr ); \ + break; \ + \ + case MBG_IP_ADDR_TYPE_IP6: \ + _mbg_swab_ip6_addr( &(_p)->u_addr.ip6_addr ); \ + break; \ + } \ + \ +} while ( 0 ) + + + +/** + * @brief An IPv4 or IPv6 network address, plus index + */ +typedef struct +{ + MBG_MSG_IDX idx; + MBG_IP_ADDR addr; ///< network address + +} MBG_IP_ADDR_IDX; + +#define _mbg_swab_ip_addr_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ip_addr( &(_p)->addr ); \ +} while ( 0 ) + + +/** + * @brief An IPv4 or IPv6 network address plus UDP or TCP port number + */ +typedef struct +{ + MBG_IP_ADDR addr; ///< See ::MBG_IP_ADDR + + uint16_t port; ///< UDP or TCP port + uint16_t flags; ///< currently always 0 + //##+++++ TODO should the flags field indicate if the port is UDP and/or TCP? + +} MBG_IP_ADDR_PORT; + +#define _mbg_swab_ip_addr_port( _p ) \ +do \ +{ \ + _mbg_swab_ip_addr( &(_p)->addr ); \ + _mbg_swab16( &(_p)->port ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Network host or domain name + */ +typedef struct +{ + MBG_HOSTNAME name; + +} MBG_NET_NAME; + +#define _mbg_swab_net_name( _p ) \ +do \ +{ \ + _mbg_swab_mbg_host_name( &(_p)->name ); \ +} while ( 0 ) + + + +/** + * @brief Network host or domain name, plus index + */ +typedef struct +{ + MBG_MSG_IDX idx; + MBG_NET_NAME net_name; + +} MBG_NET_NAME_IDX; + +#define _mbg_swab_net_name_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_name( &(_p)->net_name ); \ +} while ( 0 ) + + +enum MBG_NET_INTF_SYNC_E_FLAGS +{ + MBG_NET_INTF_SYNC_E_FLAG_SYNC_E_ACTIVE, ///< Indicates, whether SyncE is activated + MBG_NET_INTF_SYNC_E_FLAG_SYNC_E_AUTO_QL, ///< Indicates, whether the quality level is determined automatically, + ///< otherwise, the fixed input/output SSMs are being used + N_MBG_NET_INTF_SYNC_E_FLAGS + +}; + + +enum MBG_NET_INTF_SYNC_E_FLAG_MASKS +{ + MBG_NET_INTF_SYNC_E_FLAG_MASK_SYNC_E_ACTIVE = ( 1UL << MBG_NET_INTF_SYNC_E_FLAG_SYNC_E_ACTIVE ), ///< See ::MBG_NET_INTF_SYNC_E_FLAG_SYNC_E_ACTIVE + MBG_NET_INTF_SYNC_E_FLAG_MASK_SYNC_E_AUTO_QL = ( 1UL << MBG_NET_INTF_SYNC_E_FLAG_SYNC_E_AUTO_QL ) ///< See ::MBG_NET_INTF_SYNC_E_FLAG_SYNC_E_AUTO_QL + +}; + + +typedef struct +{ + uint8_t flags; ///< SyncE flags, see ::MBG_NET_INTF_SYNC_E_FLAG_MASKS + uint8_t min_input_ssm; ///< minimum accepted SSM-QL as synchronization input + uint8_t fixed_input_ssm; ///< assumed SSM value for SyncE input (0xFF if taken from network) + ///< or currently incoming SSM in status structs + uint8_t fixed_output_ssm; ///< Fixed SSM output override + + uint8_t current_output_ssm; ///< current quality level for SyncE output (automatically assigned or fixed) + ///< or currently outgoing SSM in status structs + uint8_t sdh_net_opt; ///< SDH network option, see ::SDH_NETWORK_OPTIONS and ::MBG_NET_INTF_LINK_INFO::supp_sdh_net_opts + uint8_t gb_copper_mode; ///< GBit link copper mode, see ::GBIT_LINK_COPPER_MODES and ::MBG_NET_INTF_LINK_INFO::supp_gb_copper_modes + uint8_t local_priority; ///< user defined priority value (0-255) + +} MBG_NET_INTF_SYNC_E_SETTINGS; + + +/** + * @brief Physical network interface link specific settings + */ +typedef struct +{ + char name[MBG_IFNAMSIZ]; ///< Interface name + MBG_MAC_ADDR mac_addr; ///< Physical hardware address + MBG_MAC_ADDR broadcast; ///< Physical broadcast address + + uint32_t if_index; ///< Interface index assigned by the kernel + uint32_t common_if_index; ///< Common interface index assigned by the lib (associated with the MAC address), + ///< Valid if ::MBG_NET_INTF_LINK_SETTINGS::type is ::MBG_NET_INTF_LINK_TYPE_PHYS + uint32_t ass_if_index; ///< Interface index of the associated physical interface link, + ///< Valid if ::MBG_NET_INTF_LINK_SETTINGS::type is ::MBG_NET_INTF_LINK_TYPE_VLAN + + uint32_t reserved_1; ///< Reserved, currently 0 + uint32_t states; ///< see @ref MBG_NET_INTF_LINK_STATE_MASKS + + uint32_t hw_type; ///< Hardware type of interface (see ::MBG_NET_HW_TYPES) + uint32_t mtu; ///< Max. packet size in bytes + uint32_t txqlen; ///< Transmission queue length (number of packets) + uint32_t speed; ///< Link speed in MBit/s + + uint8_t type; ///< See ::MBG_NET_INTF_LINK_TYPES + uint8_t duplex; ///< Duplex mode, half (0) or full (1) + uint8_t autoneg; ///< Indicates, whether autonegotiation is enabled or disabled + uint8_t port_type; ///< See ::MBG_NET_INTF_LINK_PORT_TYPES + + uint8_t bond_mode; ///< Bonding mode, see ::MBG_NET_INTF_LINK_BOND_MODES + ///< Valid if ::MBG_NET_INTF_LINK_STATE_MASK_MASTER is set in ::MBG_NET_INTF_LINK_SETTINGS::states + uint8_t bond_state; ///< Status of this interface in the bonding group, see ::MBG_NET_INTF_LINK_BOND_STATES + ///< Valid if MBG_NET_INTF_LINK_STATE_MASK_SLAVE is set in ::MBG_NET_INTF_LINK_SETTINGS::states + uint16_t bond_idx; ///< Interface index of the bonding master link, see ::MBG_NET_INTF_LINK_SETTINGS::if_index + ///< Valid, if MBG_NET_INTF_LINK_STATE_MASK_SLAVE is set in ::MBG_NET_INTF_LINK_SETTINGS::states + + uint16_t vlan_cfg; ///< VLAN configuration options, see ::MBG_VLAN_CFG + ///< Valid if ::MBG_NET_INTF_LINK_SETTINGS::type is ::MBG_NET_INTF_LINK_TYPE_VLAN + uint16_t reserved_2; ///< Reserved, currently 0 + + MBG_NET_INTF_SYNC_E_SETTINGS sync_e; ///< SyncE settings for this port, only valid if ::MBG_NET_INTF_LINK_OPT_MASK_CAN_SYNCE_IN or + ///< ::MBG_NET_INTF_LINK_OPT_MASK_CAN_SYNCE_OUT is set in ::MBG_NET_INTF_LINK_INFO::supp_opts + ///< For network status structs, this can also be the SyncE status, if ::MBG_NET_INTF_LINK_OPT_HAS_SYNCE_STATUS + ///< is set in ::MBG_NET_INTF_LINK_INFO::supp_opts + +} MBG_NET_INTF_LINK_SETTINGS; + +#define _mbg_swab_net_intf_link_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->if_index ); \ + _mbg_swab32( &(_p)->common_if_index ); \ + _mbg_swab32( &(_p)->ass_if_index ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->states ); \ + _mbg_swab32( &(_p)->hw_type ); \ + _mbg_swab32( &(_p)->mtu ); \ + _mbg_swab32( &(_p)->txqlen ); \ + _mbg_swab32( &(_p)->speed ); \ + _mbg_swab16( &(_p)->bond_idx ); \ + _mbg_swab16( &(_p)->vlan_cfg ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief Link (physical interface) specific settings, plus index + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_NET_GLB_CFG_INFO::n_supp_intf_link-1. + MBG_NET_INTF_LINK_SETTINGS settings; + +} MBG_NET_INTF_LINK_SETTINGS_IDX; + +#define _mbg_swab_net_intf_link_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_link_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Link (physical interface) specific settings, flags and supported features + */ +typedef struct +{ + MBG_NET_INTF_LINK_SETTINGS link_settings; ///< See ::MBG_NET_INTF_LINK_SETTINGS + uint16_t supp_sdh_net_opts; ///< supported SDH network options for SyncE, see ::SDH_NETWORK_OPTION_MASKS + uint16_t supp_gb_copper_modes; ///< supported GBit link copper modes for SyncE, see ::GBIT_LINK_COPPER_MODE_MASKS + uint32_t supp_states; ///< see @ref MBG_NET_INTF_LINK_STATE_MASKS + uint32_t supp_types; ///< See ::MBG_NET_INTF_LINK_TYPE_MASKS + uint32_t supp_speed_modes; ///< see @ref MBG_NET_INTF_LINK_SPEED_MODE_MASKS + uint32_t supp_port_types; ///< See ::MBG_NET_INTF_LINK_PORT_TYPE_MASKS + uint32_t supp_opts; ///< See ::MBG_NET_INTF_LINK_OPT_MASKS + uint32_t supp_bond_modes; ///< See ::MBG_NET_INTF_LINK_BOND_MODE_MASKS + uint16_t lic_ntp_clients; ///< number of supported NTP clients, only valid if ::MBG_NET_INTF_LINK_OPT_MASK_HAS_NTP_LIC + uint16_t lic_ptp_clients; ///< number of supported PTP clients, only valid if ::MBG_NET_INTF_LINK_OPT_MASK_HAS_PTP_LIC + uint32_t reserved_1; + uint32_t reserved_2; + uint32_t reserved_3; +} MBG_NET_INTF_LINK_INFO; + +#define _mbg_swab_net_intf_link_info( _p ) \ +do \ +{ \ + _mbg_swab_net_intf_link_settings( &(_p)->link_settings ); \ + _mbg_swab16( &(_p)->supp_sdh_net_opts ); \ + _mbg_swab16( &(_p)->supp_gb_copper_mds ); \ + _mbg_swab32( &(_p)->supp_states ); \ + _mbg_swab32( &(_p)->supp_types ); \ + _mbg_swab32( &(_p)->supp_speed_modes ); \ + _mbg_swab32( &(_p)->supp_port_types ); \ + _mbg_swab32( &(_p)->supp_opts ); \ + _mbg_swab32( &(_p)->supp_bond_modes ); \ + _mbg_swab16( &(_p)->lic_ntp_clients ); \ + _mbg_swab16( &(_p)->lic_ptp_clients ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief Query MBG_NET_INTF_LINK_INFO by its index + */ +typedef struct mbg_net_intf_link_info_idx_s +{ + MBG_MSG_IDX idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_link-1. + MBG_NET_INTF_LINK_INFO info; ///< See ::MBG_NET_INTF_LINK_INFO. + +} MBG_NET_INTF_LINK_INFO_IDX; + +#define _mbg_swab_net_intf_link_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_link_info( &(_p)->info ); \ +} while ( 0 ) + + +/** + * @brief Network interface address specific settings, flags and supported features + * + * @note Use if_index to identify uniquely its associated network link. + */ +typedef struct +{ + char label[MBG_IFNAMSIZ]; ///< Interface label + + uint32_t addr_index; ///< Index of the address on the physical interface it is assigned to + uint32_t ass_if_index; ///< Index of the associated interface link, see ::MBG_NET_INTF_LINK_SETTINGS::if_index + + uint32_t flags; ///< See ::MBG_NET_INTF_ADDR_MASKS + + MBG_IP_ADDR ip; ///< IP address associated with this interface + MBG_IP_ADDR broadcast; ///< Broadcast address associated with this interface + + uint8_t prefix_bits; ///< Number of subnet mask bits for CIDR notation, e.g. 24 for /24 + uint8_t reserved_1; ///< Reserved, currently 0 + uint16_t reserved_2; ///< Reserved, currently 0 + + uint32_t reserved_3; ///< Reserved, currently 0 + uint32_t reserved_4; ///< Reserved, currently 0 + uint32_t reserved_5; ///< Reserved, currently 0 + +} MBG_NET_INTF_ADDR_SETTINGS; + +#define _mbg_swab_net_intf_addr_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->addr_index ); \ + _mbg_swab32( &(_p)->ass_if_index ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab_ip_addr( &(_p)->ip ); \ + _mbg_swab_ip_addr( &(_p)->broadcast ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->reserved_5 ); \ +} while ( 0 ) + + +/** + * @brief Query MBG_NET_INTF_ADDR_SETTINGS by its index + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_addr-1. + MBG_NET_INTF_ADDR_SETTINGS settings; ///< See ::MBG_NET_INTF_ADDR_SETTINGS. + +} MBG_NET_INTF_ADDR_SETTINGS_IDX; + +#define _mbg_swab_net_intf_addr_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_addr_settings( &(_p)->settings ); \ +} while ( 0 ) + + +/** + * @brief Network interface address specific settings, flags and supported features + */ +typedef struct +{ + MBG_NET_INTF_ADDR_SETTINGS addr_settings; ///< See ::MBG_NET_INTF_ADDR_SETTINGS + uint32_t supp_flags; ///< See ::MBG_NET_INTF_ADDR_MASKS + uint32_t reserved_1; ///< Reserved, currently 0 + uint32_t reserved_2; ///< Reserved, currently 0 + +} MBG_NET_INTF_ADDR_INFO; + +#define _mbg_swab_net_intf_addr_info( _p ) \ +do \ +{ \ + _mbg_swab_net_intf_addr_settings( &(_p)->addr_settings ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + +/** + * @brief Query MBG_NET_INTF_ADDR_INFO by its index + */ +typedef struct mbg_net_intf_addr_info_idx_s +{ + MBG_MSG_IDX idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_addr-1. + MBG_NET_INTF_ADDR_INFO info; ///< See ::MBG_NET_INTF_ADDR_INFO. + +} MBG_NET_INTF_ADDR_INFO_IDX; + +#define _mbg_swab_net_intf_addr_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_addr_info( &(_p)->info ); \ +} while ( 0 ) + + +/** + * @brief Network interface route specific settings + * + * @note Use link_mac and ass_addr_idx to identify the associated network address and network link (via address) + */ +typedef struct +{ + uint8_t type; ///< Type of the route entry, see ::MBG_NET_INTF_ROUTE_TYPES + uint8_t reserved_1; ///< Reserved, currently 0 + uint16_t reserved_2; ///< Reserved, currently 0 + + MBG_IP_ADDR gateway; ///< Gateway IP address, only used if type is + ///< ::MBG_NET_INTF_ROUTE_TYPE_DEFAULT_GATEWAY or ::MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY + MBG_IP_ADDR dst; ///< Destination IP address, only used if ::MBG_NET_INTF_ROUTE_SETTINGS::type is + ///< ::MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY or ::MBG_NET_INTF_ROUTE_TYPE_DEST_ADDR + uint8_t dst_prefix_bits; ///< Prefix Bits for the destination address + + uint32_t ass_if_index; ///< Index of the associated interface link, see ::MBG_NET_INTF_LINK_SETTINGS::if_index + uint32_t ass_addr_index; ///< Index of the associated interface address, see ::MBG_NET_INTF_ADDR_SETTINGS::addr_index, + ///< Valid if ::MBG_NET_INTF_ROUTE_SETTINGS::type is ::MBG_NET_INTF_ROUTE_TYPE_DEST_GATEWAY or ::MBG_NET_INTF_ROUTE_TYPE_DEST_ADDR + + uint32_t reserved_3; ///< Reserved, currently 0 + uint32_t reserved_4; ///< Reserved, currently 0 + uint32_t reserved_5; ///< Reserved, currently 0 + +} MBG_NET_INTF_ROUTE_SETTINGS; + +#define _mbg_swab_net_intf_route_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab_ip_addr( &(_p)->gateway ); \ + _mbg_swab_ip_addr( &(_p)->dst ); \ + _mbg_swab32( &(_p)->ass_if_index ); \ + _mbg_swab32( &(_p)->ass_addr_index ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->reserved_5 ); \ +} while ( 0 ) + + +/** + * @brief Query MBG_NET_INTF_ROUTE_SETTINGS by its index + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_route-1. + MBG_NET_INTF_ROUTE_SETTINGS settings; ///< See ::MBG_NET_INTF_ROUTE_SETTINGS. + +} MBG_NET_INTF_ROUTE_SETTINGS_IDX; + +#define _mbg_swab_net_intf_route_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_route_settings( &(_p)->settings ); \ +} while ( 0 ) + + +/** + * @brief Network interface address specific settings + */ +typedef struct +{ + MBG_NET_INTF_ROUTE_SETTINGS route_settings; ///< See ::MBG_NET_INTF_ROUTE_SETTINGS + uint32_t reserved_1; ///< Reserved, currently 0 + uint32_t reserved_2; ///< Reserved, currently 0 + uint32_t reserved_3; ///< Reserved, currently 0 + uint32_t reserved_4; ///< Reserved, currently 0 +} MBG_NET_INTF_ROUTE_INFO; + +#define _mbg_swab_net_intf_route_info( _p ) \ +do \ +{ \ + _mbg_swab_net_intf_route_settings( &(_p)->route_settings ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ +} while ( 0 ) + + +/** + * @brief Query MBG_NET_INTF_ROUTE_INFO by its index + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_NET_GLB_CFG_SETTINGS::num_intf_route-1. + MBG_NET_INTF_ROUTE_INFO info; ///< See ::MBG_NET_INTF_ROUTE_INFO. + +} MBG_NET_INTF_ROUTE_INFO_IDX; + +#define _mbg_swab_net_intf_route_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_net_intf_route_info( &(_p)->info ); \ +} while ( 0 ) + + +/** @} defgroup group_ext_net_cfg */ + +/** @} defgroup group_net_cfg */ + + + + + +/** + * @defgroup group_ucap_net User Captures via Network + * + * @note Group for the user capture via network feature + * Only supported if ::MBG_XFEATURE_UCAP_NET is set in extended features + * Corresponding GPS commands are ::GPS_UCAP_NET_GLB_INFO and ::GPS_UCAP_NET_RECV_INFO_IDX + * + * @{ */ + + +#define MBG_UCAP_NET_DEFAULT_UDP_PORT 50815 + +/** + * @brief Transfer mode for user captures via network + * + * @see ::MBG_UCAP_NET_TRANSF_MODE_MASKS + * + * Used with ::MBG_UCAP_NET_RECV_SETTINGS::mode + */ +enum MBG_UCAP_NET_TRANSF_MODE +{ + MBG_UCAP_NET_TRANSF_MODE_UNKNOWN, ///< Unknown transfer mode + MBG_UCAP_NET_TRANSF_MODE_ON_REQ, ///< User captures will be transferred on request only + MBG_UCAP_NET_TRANSF_MODE_AUTO, ///< User captures are being transferred automatically + N_MBG_UCAP_NET_TRANSF_MODES +}; + + +/** + * @brief Masks for transfer mode used with ::MBG_UCAP_NET_GLB_INFO::supp_modes + * + * @see ::MBG_UCAP_NET_TRANSF_MODE + */ +enum MBG_UCAP_NET_TRANSF_MODE_MASKS +{ + MBG_UCAP_NET_TRANSF_MODE_MASK_UNKNOWN = ( 1UL << MBG_UCAP_NET_TRANSF_MODE_UNKNOWN ), ///< See ::MBG_UCAP_NET_TRANSF_MODE_UNKNOWN + MBG_UCAP_NET_TRANSF_MODE_MASK_ON_REQ = ( 1UL << MBG_UCAP_NET_TRANSF_MODE_ON_REQ ), ///< See ::MBG_UCAP_NET_TRANSF_MODE_ON_REQ + MBG_UCAP_NET_TRANSF_MODE_MASK_AUTO = ( 1UL << MBG_UCAP_NET_TRANSF_MODE_AUTO ) ///< See ::MBG_UCAP_NET_TRANSF_MODE_AUTO +}; + + + +/** + * @brief Transfer protocol for user captures via network + * + * @see ::MBG_UCAP_NET_TRANSF_PROTO_MASKS + * + * Used with ::MBG_UCAP_NET_RECV_SETTINGS::proto + */ +enum MBG_UCAP_NET_TRANSF_PROTO +{ + MBG_UCAP_NET_TRANSF_PROTO_UNKNOWN, ///< Unknown transfer mode + MBG_UCAP_NET_TRANSF_PROTO_UDP, ///< User captures are transferred via UDP + N_MBG_UCAP_NET_TRANSF_PROTOS +}; + + +/** + * @brief Masks for transfer protocol used with ::MBG_UCAP_NET_GLB_INFO::supp_protos + * + * @see ::MBG_UCAP_NET_TRANSF_PROTO + */ +enum MBG_UCAP_NET_TRANSF_PROTO_MASKS +{ + MBG_UCAP_NET_TRANSF_PROTO_MASK_UNKNOWN = ( 1UL << MBG_UCAP_NET_TRANSF_PROTO_UNKNOWN ), ///< See ::MBG_UCAP_NET_TRANSF_PROTO_UNKNOWN + MBG_UCAP_NET_TRANSF_PROTO_MASK_UDP = ( 1UL << MBG_UCAP_NET_TRANSF_PROTO_UDP ) ///< See ::MBG_UCAP_NET_TRANSF_PROTO_UDP +}; + + + +/** + * @brief Supported flags for user captures via network + * + * @see ::MBG_UCAP_NET_SUPP_FLAG_MASKS + */ +enum MBG_UCAP_NET_SUPP_FLAGS +{ + MBG_UCAP_NET_SUPP_FLAG_IPV6, + N_MBG_UCAP_NET_SUPP_FLAGS +}; + + +/** + * @brief Masks for supported flags used with ::MBG_UCAP_NET_GLB_INFO::supp_flags + * + * @see ::MBG_UCAP_NET_TRANSF_PROTO + */ +enum MBG_UCAP_NET_SUPP_FLAG_MASKS +{ + MBG_UCAP_NET_SUPP_FLAG_MASK_IPV6 = ( 1UL << MBG_UCAP_NET_SUPP_FLAG_IPV6 ) ///< See ::MBG_UCAP_NET_SUPP_FLAG_IPV6 +}; + + +/** + * @brief Global settings for user captures via network + * + * @note This structure shall be used to set the current global settings of a device + * with GPS command ::GPS_UCAP_NET_GLB_INFO. + */ +typedef struct +{ + uint32_t num_recvs; ///< Number of configured network receivers, see ::MBG_UCAP_NET_RECV_INFO_IDX + uint32_t reserved_0; ///< Reserved, currently always 0 + uint32_t reserved_1; ///< Reserved, currently always 0 + uint32_t reserved_2; ///< Reserved, currently always 0 + +} MBG_UCAP_NET_GLB_SETTINGS; + + +#define _mbg_swab_ucap_net_glb_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->num_recvs ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +/** + * @brief Global settings, features and flags for user captures via network + * + * @note This structure shall be used to read the current global settings from a device + * with GPS command ::GPS_UCAP_NET_GLB_INFO. + */ +typedef struct +{ + MBG_UCAP_NET_GLB_SETTINGS settings; ///< See ::MBG_UCAP_NET_GLB_SETTINGS + + uint32_t n_supp_recvs; ///< Number of supported network receivers, see ::MBG_UCAP_NET_RECV_INFO_IDX + uint32_t supp_modes; ///< Supported transfer modes, see ::MBG_UCAP_NET_TRANSF_MODE_MASKS + uint32_t supp_protos; ///< Supported transfer protocols, see ::MBG_UCAP_NET_TRANSF_PROTO_MASKS + uint32_t reserved_0; ///< Reserved, currently always 0 + uint32_t reserved_1; ///< Reserved, currently always 0 + uint32_t supp_flags; ///< Supported flags, see ::MBG_UCAP_NET_SUPP_FLAG_MASKS + +} MBG_UCAP_NET_GLB_INFO; + + +#define _mbg_swab_ucap_net_glb_info( _p ) \ +do \ +{ \ + _mbg_swab_ucap_net_glb_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->n_supp_recvs ); \ + _mbg_swab32( &(_p)->supp_modes ); \ + _mbg_swab32( &(_p)->supp_protos ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + + +/** + * @brief Settings for receivers of user captures via network + */ +typedef struct +{ + uint8_t mode; ///< Transfer mode, see ::MBG_UCAP_NET_TRANSF_MODE + uint8_t proto; ///< Transfer protocol, see ::MBG_UCAP_NET_TRANSF_PROTO + uint16_t reserved_1; ///< Reserved, currently always 0 + + uint32_t reserved_2; ///< Reserved, currently always 0 + uint32_t reserved_3; ///< Reserved, currently always 0 + uint32_t ucaps; ///< Bit mask for active user captures + + MBG_IP_ADDR_PORT addr; ///< Destination IP and port address of the network receiver, see ::MBG_IP_ADDR_PORT + +} MBG_UCAP_NET_RECV_SETTINGS; + + +#define _mbg_swab_ucap_net_recv_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->ucaps ); \ + _mbg_swab_ip_addr_port( &(_p)->addr ); \ +} while ( 0 ) + + + +/** + * @brief Settings for receivers of user captures via network + * + * @note This structure shall be used to write the settings to the device + * with GPS command ::GPS_UCAP_NET_RECV_INFO_IDX. + * This can be done for index 0 to ::MBG_UCAP_NET_GLB_SETTINGS::num_recvs-1. + * + * @see ::MBG_UCAP_NET_RECV_SETTINGS + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_UCAP_NET_GLB_SETTINGS::num_recvs-1. + MBG_UCAP_NET_RECV_SETTINGS settings; ///< See ::MBG_UCAP_NET_RECV_SETTINGS. + +} MBG_UCAP_NET_RECV_SETTINGS_IDX; + + +#define _mbg_swab_ucap_net_recv_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ucap_net_recv_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Settings, features and flags for receivers of user captures via network + */ +typedef struct +{ + MBG_UCAP_NET_RECV_SETTINGS settings; ///< See ::MBG_UCAP_NET_RECV_SETTINGS + + uint32_t reserved_0; ///< Reserved, currently always 0 + uint32_t reserved_1; ///< Reserved, currently always 0 + uint32_t reserved_2; ///< Reserved, currently always 0 + uint32_t reserved_3; ///< Reserved, currently always 0 + +} MBG_UCAP_NET_RECV_INFO; + + +#define _mbg_swab_ucap_net_recv_info( _p ) \ +do \ +{ \ + _mbg_swab_ucap_net_recv_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief Settings, features and flags for receivers of user captures via network + * + * @note This structure shall be used to read the current settings from the device + * with GPS command ::GPS_UCAP_NET_RECV_INFO_IDX. + * This can be done for index 0 to ::MBG_UCAP_NET_GLB_SETTINGS::num_recvs-1. + * + * @see ::MBG_UCAP_NET_RECV_INFO + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_UCAP_NET_GLB_INFO::n_supp_recvs-1. + MBG_UCAP_NET_RECV_INFO info; ///< See ::MBG_UCAP_NET_RECV_INFO. + +} MBG_UCAP_NET_RECV_INFO_IDX; + + +#define _mbg_swab_ucap_net_recv_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ucap_net_recv_info( &(_p)->info ); \ +} while ( 0 ) + +/** @} defgroup ext_ucap */ + + + +/** + * @defgroup group_ptp Definitions used with PTP/IEEE1588 + * + * @{ */ + +/** + * @brief Enumeration of protocols possibly used with PTP + * + * @see ::PTP_NW_PROT_MASKS + */ +enum PTP_NW_PROTS +{ + PTP_NW_PROT_RESERVED, ///< reserved + PTP_NW_PROT_UDP_IPV4, ///< IPv4 + PTP_NW_PROT_UDP_IPV6, ///< IPv6 + PTP_NW_PROT_IEEE_802_3, ///< Ethernet (raw layer 2) + PTP_NW_PROT_DEVICE_NET, ///< DeviceNet + PTP_NW_PROT_CONTROL_NET, ///< ControlNet + PTP_NW_PROT_PROFINET, ///< ProfiNet + N_PTP_NW_PROT ///< number of defined protocols +}; + + +/** + * @brief Bit masks for enumerated protocols possibly used with PTP + * + * @see ::PTP_NW_PROTS + */ +enum PTP_NW_PROT_MASKS +{ + PTP_NW_PROT_MSK_RESERVED = ( 1UL << PTP_NW_PROT_RESERVED ), ///< See ::PTP_NW_PROT_RESERVED + PTP_NW_PROT_MSK_UDP_IPV4 = ( 1UL << PTP_NW_PROT_UDP_IPV4 ), ///< See ::PTP_NW_PROT_UDP_IPV4 + PTP_NW_PROT_MSK_UDP_IPV6 = ( 1UL << PTP_NW_PROT_UDP_IPV6 ), ///< See ::PTP_NW_PROT_UDP_IPV6 + PTP_NW_PROT_MSK_IEEE_802_3 = ( 1UL << PTP_NW_PROT_IEEE_802_3 ), ///< See ::PTP_NW_PROT_IEEE_802_3 + PTP_NW_PROT_MSK_DEVICE_NET = ( 1UL << PTP_NW_PROT_DEVICE_NET ), ///< See ::PTP_NW_PROT_DEVICE_NET + PTP_NW_PROT_MSK_CONTROL_NET = ( 1UL << PTP_NW_PROT_CONTROL_NET ), ///< See ::PTP_NW_PROT_CONTROL_NET + PTP_NW_PROT_MSK_PROFINET = ( 1UL << PTP_NW_PROT_PROFINET ) ///< See ::PTP_NW_PROT_PROFINET +}; + + + +/** + * @brief Name strings for the protocols possibly used with PTP + * + * @see ::PTP_NW_PROTS + */ +#define PTP_NW_PROT_STRS \ +{ \ + "Reserved", \ + "UDP/IPv4 (L3)", \ + "UDP/IPv6 (L3)", \ + "IEEE 802.3 (L2)", \ + "DeviceNet", \ + "ControlNet", \ + "PROFINET" \ +} + + +/** + * @brief Short name strings for the protocols possibly used with PTP + * + * @see ::PTP_NW_PROTS + */ +#define PTP_NW_PROT_STRS_SHORT \ +{ \ + "RSV", \ + "IP4", \ + "IP6", \ + "ETH", \ + "DN", \ + "CN", \ + "PN" \ +} + + +/** + * @brief Possible states of a PTP port + */ +enum PTP_PORT_STATES +{ + PTP_PORT_STATE_UNINITIALIZED, ///< uninitialized + PTP_PORT_STATE_INITIALIZING, ///< currently initializing + PTP_PORT_STATE_FAULTY, ///< faulty + PTP_PORT_STATE_DISABLED, ///< disabled + PTP_PORT_STATE_LISTENING, ///< listening for PTP packets + PTP_PORT_STATE_PRE_MASTER, ///< going to become master + PTP_PORT_STATE_MASTER, ///< master + PTP_PORT_STATE_PASSIVE, ///< passive + PTP_PORT_STATE_UNCALIBRATED, ///< uncalibrated + PTP_PORT_STATE_SLAVE, ///< slave + N_PTP_PORT_STATE ///< number of defined port states +}; + + +#define PTP_PORT_ST_STR_UNINITIALIZED "Uninitialized" +#define PTP_PORT_ST_STR_INITIALIZED "Initializing" +#define PTP_PORT_ST_STR_FAULTY "Faulty" +#define PTP_PORT_ST_STR_DISABLED "Disabled" +#define PTP_PORT_ST_STR_LISTENING "Listening" +#define PTP_PORT_ST_STR_PREMASTER "Pre-Master" +#define PTP_PORT_ST_STR_MASTER "Master" +#define PTP_PORT_ST_STR_PASSIVE "Passive" +#define PTP_PORT_ST_STR_UNCALIBRATED "Uncalibrated" +#define PTP_PORT_ST_STR_SLAVE "Slave" + + +/** + * @brief Name strings for the PTP port states + */ +#define PTP_PORT_STATE_STRS \ +{ \ + PTP_PORT_ST_STR_UNINITIALIZED, \ + PTP_PORT_ST_STR_INITIALIZED, \ + PTP_PORT_ST_STR_FAULTY, \ + PTP_PORT_ST_STR_DISABLED, \ + PTP_PORT_ST_STR_LISTENING, \ + PTP_PORT_ST_STR_PREMASTER, \ + PTP_PORT_ST_STR_MASTER, \ + PTP_PORT_ST_STR_PASSIVE, \ + PTP_PORT_ST_STR_UNCALIBRATED, \ + PTP_PORT_ST_STR_SLAVE \ +} + + +/** + * @brief An entry for a table of parameters which can not be accessed by an enumerated index + */ +typedef struct +{ + uint8_t value; ///< the parameter value + const char *name; ///< the parameter name + +} PTP_TABLE; + + + +/** + * @brief An enumeration of PTP delay mechanisms + * + * @note This is different than the numeric values specified + * in the published specs for IEEE1588. In addition, the specs + * define code 0x14 for "disabled". + * + * @see ::PTP_DELAY_MECH_MASKS + * @see ::PTP_DELAY_MECH_NAMES + */ +enum PTP_DELAY_MECHS +{ + PTP_DELAY_MECH_E2E, ///< End-to-End (in PTP2 specs: 0x01) + PTP_DELAY_MECH_P2P, ///< Peer-to-Peer (in PTP2 specs: 0x02) + N_PTP_DELAY_MECH ///< number of defined delay mechanisms +}; + + +/** + * @brief Bit masks associated with enumerated PTP delay mechanisms + * + * @see ::PTP_DELAY_MECH_MASKS + */ +enum PTP_DELAY_MECH_MASKS +{ + PTP_DELAY_MECH_MSK_E2E = ( 1UL << PTP_DELAY_MECH_E2E ), ///< See ::PTP_DELAY_MECH_E2E + PTP_DELAY_MECH_MSK_P2P = ( 1UL << PTP_DELAY_MECH_P2P ) ///< See ::PTP_DELAY_MECH_P2P +}; + + +#define PTP_DELAY_MECH_NAME_E2E "E2E" +#define PTP_DELAY_MECH_NAME_P2P "P2P" + +/** + * @brief Name strings for the PTP delay mechanisms + * + * @see ::PTP_DELAY_MECHS + */ +#define PTP_DELAY_MECH_NAMES \ +{ \ + PTP_DELAY_MECH_NAME_E2E, \ + PTP_DELAY_MECH_NAME_P2P \ +} + + + +/** + * @brief An enumeration of accuracy classes used with PTP + * + * @note This enumeration does not start at 0 but with a bias + * specified by ::PTP_CLOCK_ACCURACY_NUM_BIAS. + * + * @see ::PTP_CLOCK_ACCURACY_STRS + */ +enum PTP_CLOCK_ACCURACIES +{ + PTP_CLOCK_ACCURACY_NUM_BIAS = 0x20, + PTP_CLOCK_ACCURACY_25ns = PTP_CLOCK_ACCURACY_NUM_BIAS, + PTP_CLOCK_ACCURACY_100ns, + PTP_CLOCK_ACCURACY_250ns, + PTP_CLOCK_ACCURACY_1us, + PTP_CLOCK_ACCURACY_2_5us, + PTP_CLOCK_ACCURACY_10us, + PTP_CLOCK_ACCURACY_25us, + PTP_CLOCK_ACCURACY_100us, + PTP_CLOCK_ACCURACY_250us, + PTP_CLOCK_ACCURACY_1ms, + PTP_CLOCK_ACCURACY_2_5ms, + PTP_CLOCK_ACCURACY_10ms, + PTP_CLOCK_ACCURACY_25ms, + PTP_CLOCK_ACCURACY_100ms, + PTP_CLOCK_ACCURACY_250ms, + PTP_CLOCK_ACCURACY_1s, + PTP_CLOCK_ACCURACY_10s, + PTP_CLOCK_ACCURACY_MORE_10s, + PTP_CLOCK_ACCURACY_RESERVED_1, + PTP_CLOCK_ACCURACY_RESERVED_2, + PTP_CLOCK_ACCURACY_RESERVED_3, + PTP_CLOCK_ACCURACY_RESERVED_4, + N_PTP_CLOCK_ACCURACY + //##++++ TODO: Add a code for 0xFE (unknown), or eventually + // redesign the lookup of associated strings completely. +}; + + +/** + * @brief Name strings for PTP accuracy classes + * + * @note The enumeration does not start at 0 but with a bias + * specified by ::PTP_CLOCK_ACCURACY_NUM_BIAS, so this bias needs + * to be accounted for when accessing a string table. + * + * @see ::PTP_CLOCK_ACCURACIES + */ +#define PTP_CLOCK_ACCURACY_STRS \ +{ \ + "< 25 ns", \ + "< 100 ns", \ + "< 250 ns", \ + "< 1 us", \ + "< 2.5 us", \ + "< 10 us", \ + "< 25 us", \ + "< 100 us", \ + "< 250 us", \ + "< 1 ms", \ + "< 2.5 ms", \ + "< 10 ms", \ + "< 25 ms", \ + "< 100 ms", \ + "< 250 ms", \ + "< 1 s", \ + "< 10 s", \ + "more than 10 s", \ + "reserved_1", \ + "reserved_2", \ + "reserved_3", \ + "reserved_4" \ +} + + + +/** + * @brief Codes to specify the type of a time source used with PTP + * + * @see ::PTP_TIME_SOURCE_TABLE + */ +enum PTP_TIME_SOURCES +{ + PTP_TIME_SOURCE_ATOMIC_CLOCK = 0x10, + PTP_TIME_SOURCE_GPS = 0x20, + PTP_TIME_SOURCE_TERRESTRIAL_RADIO = 0x30, + PTP_TIME_SOURCE_PTP = 0x40, + PTP_TIME_SOURCE_NTP = 0x50, + PTP_TIME_SOURCE_HAND_SET = 0x60, + PTP_TIME_SOURCE_OTHER = 0x90, + PTP_TIME_SOURCE_INTERNAL_OSCILLATOR = 0xA0 +}; + + + +/** + * @brief A table of PTP time source codes plus associated name strings + * + * @see ::PTP_TIME_SOURCES + */ +#define PTP_TIME_SOURCE_TABLE \ +{ \ + { PTP_TIME_SOURCE_ATOMIC_CLOCK, "Atomic Clock" }, \ + { PTP_TIME_SOURCE_GPS, "GPS" }, \ + { PTP_TIME_SOURCE_TERRESTRIAL_RADIO, "Terrestrial Radio" }, \ + { PTP_TIME_SOURCE_PTP, "PTP" }, \ + { PTP_TIME_SOURCE_NTP, "NTP" }, \ + { PTP_TIME_SOURCE_HAND_SET, "HAND SET" }, \ + { PTP_TIME_SOURCE_OTHER, "OTHER" }, \ + { PTP_TIME_SOURCE_INTERNAL_OSCILLATOR, "Internal Oscillator" }, \ + { 0, NULL } \ +} + + +/** + * @brief An enumeration of roles which can be taken by a PTP node + * + * A role in this context specifies a certain mode of operation. + * Depending on its specification a devices may not be able to take + * each of the specified roles. + * + * @note: A device in MULTICAST_AUTO role can be either master or slave, + * so the port state needs to be checked to determine the current + * mode of operation. + * + * @see ::PTP_ROLE_MASKS + * @see ::PTP_ROLE_STRS + * @see ::PTP_ROLE_STRS_SHORT + */ +enum PTP_ROLES +{ + PTP_ROLE_MULTICAST_SLAVE, ///< slave in multicast mode + PTP_ROLE_UNICAST_SLAVE, ///< slave in unicast mode + PTP_ROLE_MULTICAST_MASTER, ///< multicast master + PTP_ROLE_UNICAST_MASTER, ///< unicast master + PTP_ROLE_MULTICAST_AUTO, ///< multicast master or slave (auto selection) + 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, ///< 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 +}; + + +/** + * @brief Bit mask associated with ::PTP_ROLES + * + * A role in this context specifies a certain mode of operation. + * Depending on its specification a devices may not be able to take + * each of the specified roles. + * + * @note: A device in MULTICAST_AUTO role can be either master or slave, + * so the port state needs to be checked to determine the current + * mode of operation. + * + * @see ::PTP_ROLES + * @see ::get_supp_ptp_role_mask + */ +enum PTP_ROLE_MASKS +{ + PTP_ROLE_MSK_MULTICAST_SLAVE = ( 1UL << PTP_ROLE_MULTICAST_SLAVE ), ///< See ::PTP_ROLE_MULTICAST_SLAVE + PTP_ROLE_MSK_UNICAST_SLAVE = ( 1UL << PTP_ROLE_UNICAST_SLAVE ), ///< See ::PTP_ROLE_UNICAST_SLAVE + PTP_ROLE_MSK_MULTICAST_MASTER = ( 1UL << PTP_ROLE_MULTICAST_MASTER ), ///< See ::PTP_ROLE_MULTICAST_MASTER + PTP_ROLE_MSK_UNICAST_MASTER = ( 1UL << PTP_ROLE_UNICAST_MASTER ), ///< See ::PTP_ROLE_UNICAST_MASTER + PTP_ROLE_MSK_MULTICAST_AUTO = ( 1UL << PTP_ROLE_MULTICAST_AUTO ), ///< See ::PTP_ROLE_MULTICAST_AUTO + PTP_ROLE_MSK_BOTH_MASTER = ( 1UL << PTP_ROLE_BOTH_MASTER ), ///< See ::PTP_ROLE_BOTH_MASTER + PTP_ROLE_MSK_NTP_SERVER = ( 1UL << PTP_ROLE_NTP_SERVER ), ///< See ::PTP_ROLE_NTP_SERVER + PTP_ROLE_MSK_NTP_CLIENT = ( 1UL << PTP_ROLE_NTP_CLIENT ), ///< See ::PTP_ROLE_NTP_CLIENT + PTP_ROLE_MSK_TIME_MONITOR = ( 1UL << PTP_ROLE_TIME_MONITOR ), ///< See ::PTP_ROLE_TIME_MONITOR + PTP_ROLE_MSK_V1_MASTER = ( 1UL << PTP_ROLE_V1_MASTER ), ///< See ::PTP_ROLE_MULTICAST_MASTER + PTP_ROLE_MSK_V1_SLAVE = ( 1UL << PTP_ROLE_V1_SLAVE ) ///< See ::PTP_ROLE_UNICAST_SLAVE +}; + + +#define PTP_ROLE_MSK_SLAVES ( PTP_ROLE_MSK_MULTICAST_SLAVE \ + | PTP_ROLE_MSK_UNICAST_SLAVE \ + | PTP_ROLE_MSK_MULTICAST_AUTO ) + +#define PTP_ROLE_MSK_MASTERS ( PTP_ROLE_MSK_MULTICAST_MASTER \ + | PTP_ROLE_MSK_UNICAST_MASTER \ + | PTP_ROLE_MSK_MULTICAST_AUTO \ + | PTP_ROLE_BOTH_MASTER ) + + +/** + * @brief Name strings for defined PTP roles + * + * @see ::PTP_ROLES + * @see ::PTP_ROLE_STRS_SHORT + */ +#define PTP_ROLE_STRS \ +{ \ + "Multicast Slave", \ + "Unicast Slave", \ + "Multicast Master", \ + "Unicast Master", \ + "Multicast (Auto)", \ + "UC+MC Master", \ + "NTP Server", \ + "NTP Client", \ + "Sync Monitor", \ + "V1 Master", \ + "V1 Slave" \ +} + + +/** + * @brief Short name strings for defined PTP roles + * + * @see ::PTP_ROLES + * @see ::PTP_ROLE_STRS + */ +#define PTP_ROLE_STRS_SHORT \ +{ \ + "MCS", \ + "UCS", \ + "MCM", \ + "UCM", \ + "MCA", \ + "UMM", \ + "NSV", \ + "NCL", \ + "MON", \ + "V1M", \ + "V1S" \ +} + + +/** + * @brief A PTP clock identity + * + * @note This usually consists of a 6 byte MAC address with + * 2 fixed bytes inserted, or all ones as wildcard. + */ +typedef struct ptp_clock_id_s +{ + uint8_t b[8]; + +} PTP_CLOCK_ID; + +#define _mbg_swab_ptp_clock_id( _p ) _nop_macro_fnc() // nothing to swap + +#define PTP_CLOCK_ID_WILDCARD { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } } + + +/** + * @brief A PTP port ID + */ +typedef uint16_t PTP_PORT_ID; + +#define _mbg_swab_ptp_port_id( _p ) _mbg_swab16( _p ) + +#define PTP_PORT_ID_WILDCARD 0xFFFF + + +/** + * @brief A PTP port identity + * + * @note For further information, see IEEE 1588-2008, chapter 5.3.5 + * + * @see ::PTP_CLOCK_ID + * @see ::PTP_PORT_ID + */ +typedef struct +{ + PTP_CLOCK_ID clock_identity; + PTP_PORT_ID port_number; + +} PTP_PORT_IDENTITY; + + +#define _mbg_swab_ptp_port_identity( _p ) \ +{ \ + _mbg_swab_ptp_clock_id( &(_p)->clock_identity ); \ + _mbg_swab_ptp_port_id( &(_p)->port_number ); \ +} + + +/** + * @brief A PTP port identity + * + * @note For further information, see IEEE 1588-2008, chapter 5.3.5 + * + * @see ::PTP_CLOCK_ID + * @see ::PTP_PORT_ID + */ +typedef struct ptp_ng_port_identity_s +{ + PTP_CLOCK_ID clock_identity; + PTP_PORT_ID port_number; + uint16_t reserved_1; + uint32_t reserved_2; +} PTP_NG_PORT_IDENTITY; + + +#define _mbg_swab_ptp_ng_port_identity( _p ) \ +{ \ + _mbg_swab_ptp_clock_id( &(_p)->clock_identity ); \ + _mbg_swab_ptp_port_id( &(_p)->port_number ); \ +} + + +/** + * @brief PTP clock quality + * + * @note For further information, see IEEE 1588-2008, chapter 5.3.7 + */ +typedef struct +{ + uint8_t clock_class; ///< PTP clock class representing the current sync status + int8_t clock_accuracy; ///< See ::PTP_CLOCK_ACCURACIES + uint16_t log_variance; ///< PTP offset scaled log variance representing the time stability + +} PTP_CLOCK_QUALITY; + + +#define _mbg_swab_ptp_clock_quality( _p ) \ +{ \ + _mbg_swab8( &(_p)->clock_class ); \ + _mbg_swab8( &(_p)->clock_accuracy ); \ + _mbg_swab16( &(_p)->log_variance ); \ +} + + +/** + * @brief PTP time interval + * + * @note For further information, see IEEE 1588-2008, chapter 5.3.2 + */ +typedef struct +{ + int64_t scaled_nanoseconds; + +} PTP_TIME_INTERVAL; + + +#define _mbg_swab_ptp_time_interval( _p ) \ +{ \ + _mbg_swab64( &(_p)->scaled_nanoseconds ); \ +} + + + +/** + * @brief PTP packet timestamp seconds field. + * + * PTP timestamps used in network packets use an 48 bit (i.e. 6 bytes) only + * seconds fields, so a conversion is required whenever such a seconds field + * is to be read or written. + * + * In the PTP specs this is referenced as @a UInteger48. + * + * This is defined as a structure with an array member to avoid + * potential problems when passing the address as a reference, + * e.g. sizeof( *p ). + * + * @see ::PTP_PKT_TSTAMP + */ +typedef struct +{ + uint8_t b[6]; + +} PTP_PKT_TSTAMP_SECS; + + + +/** + * @brief PTP packet timestamp nanoseconds field. + * + * @see ::PTP_PKT_TSTAMP + */ +typedef uint32_t PTP_PKT_TSTAMP_NSECS; + + + +/** + * @brief PTP packet timestamp. + */ +typedef struct +{ + PTP_PKT_TSTAMP_SECS secs; + PTP_PKT_TSTAMP_NSECS nsecs; + +} PTP_PKT_TSTAMP; + + + +/** + * @brief Data type to store daylight saving flags in TLVs. + * + * @see ::PTP_TLV_DST_FLAG_MSKS + */ +typedef uint8_t PTP_TLV_DST_FLAGS; + + + +/** + * @brief Data type to store leap second flags in TLVs. + * + * @see ::PTP_TLV_LS_FLAG_MSKS + */ +typedef uint8_t PTP_TLV_LS_FLAGS; + + + +/** + * @brief Data type to store time offsets of whole seconds in TLVs. + */ +typedef int32_t PTP_TLV_TIME_OFFS; + + + +/** + * @brief An enumeration of time scales used with PTP + * + * @note The standard time scale used by PTP is TAI, which is a linear time scale. + * The protocol provides a %UTC offset to be able to convert TAI to compute %UTC, which + * can observe leap seconds. For the arbitrary time scale the %UTC offset is unspecified, + * so arbitrary time can be %UTC, or something else. + * + * @see ::PTP_TIMESCALE_NAMES + * @see ::PTP_TIMESCALE_NAMES_SHORT + */ +enum PTP_TIME_SCALES +{ + PTP_TIMESCALE_PTP, ///< PTP default, TAI + PTP_TIMESCALE_ARB, ///< arbitrary time scale, maybe %UTC + N_PTP_TIMESCALE +}; + + +/** + * @brief Name strings for the PTP time scales + */ +#define PTP_TIMESCALE_NAME_PTP "PTP Standard (TAI)" +#define PTP_TIMESCALE_NAME_ARB "Arbitrary" + +/** + * @brief Short name strings for the PTP time scales + */ +#define PTP_TIMESCALE_NAME_PTP_SHORT "PTP" +#define PTP_TIMESCALE_NAME_ARB_SHORT "Arb" + + +/** + * @brief A table of name strings for the PTP time scales + * + * @see ::PTP_TIME_SCALES + * @see ::PTP_TIMESCALE_NAMES_SHORT + */ +#define PTP_TIMESCALE_NAMES \ +{ \ + PTP_TIMESCALE_NAME_PTP, \ + PTP_TIMESCALE_NAME_ARB \ +} + +/** + * @brief A table of short name strings for the PTP time scales + * + * @see ::PTP_TIME_SCALES + * @see ::PTP_TIMESCALE_NAMES + */ +#define PTP_TIMESCALE_NAMES_SHORT \ +{ \ + PTP_TIMESCALE_NAME_PTP_SHORT, \ + PTP_TIMESCALE_NAME_ARB_SHORT \ +} + + + +/** + * @brief A structure to used to read the status of the PTP protocol stack + */ +typedef struct +{ + uint16_t nw_prot; ///< one of the enumerated protocols, see ::PTP_NW_PROTS + uint8_t ptp_prot_version; ///< PTP protocol version, 1, or 2, usually 2 for v2 + uint8_t port_state; ///< one of the enumerated port states, see ::PTP_PORT_STATES + uint32_t flags; ///< See ::PTP_STATE_FLAGS + NANO_TIME offset; ///< estimated time offset from the upstream time source + NANO_TIME path_delay; + NANO_TIME mean_path_delay; + NANO_TIME delay_asymmetry; + + PTP_CLOCK_ID gm_id; ///< identifier ot the upstream time source + + uint16_t clock_offset_scaled_log_variance; + uint8_t clock_class; + uint8_t clock_accuracy; ///< See ::PTP_CLOCK_ACCURACIES + + uint32_t tsu_secs; ///< current seconds value of time stamp unit + uint32_t reserved_2; ///< reserved, currently always 0 + + uint8_t domain_number; ///< the PTP clock domain number, 0:3 + uint8_t time_source; ///< See ::PTP_TIME_SOURCES + uint8_t delay_mech; ///< See ::PTP_DELAY_MECHS + int8_t log_delay_req_intv; + + int16_t utc_offset; ///< %UTC offset observed against TAI + DAC_VAL osc_dac_cal; ///< disciplination value of the oscillator + + uint8_t parent_clock_class; ///< clock class of the parent node + uint8_t parent_clock_accuracy; ///< clock accuracy of the parent node, see ::PTP_CLOCK_ACCURACIES + + uint16_t reserved_3; ///< reserved, currently always 0 + +} PTP_STATE; + +#define _mbg_swab_ptp_state( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->nw_prot ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab_nano_time( &(_p)->offset ); \ + _mbg_swab_nano_time( &(_p)->path_delay ); \ + _mbg_swab_nano_time( &(_p)->mean_path_delay ); \ + _mbg_swab_nano_time( &(_p)->delay_asymmetry ); \ + _mbg_swab_ptp_clock_id( &(_p)->gm_id ); \ + _mbg_swab16( &(_p)->clock_offset_scaled_log_variance ); \ + _mbg_swab32( &(_p)->tsu_secs ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab16( &(_p)->utc_offset ); \ + _mbg_swab_dac_val( &(_p)->osc_dac_cal ); \ + _mbg_swab16( &(_p)->reserved_3 ); \ +} while ( 0 ) + + +/** + * @brief Flags bits used with PTP_STATE::flags + * + * @see ::PTP_STATE_FLAG_MASKS + */ +enum PTP_STATE_FLAGS +{ + PTP_FLAG_SLAVE_ONLY, ///< the port can only be slave + PTP_FLAG_IS_SLAVE, ///< the port is currently slave + PTP_FLAG_TIMESCALE_IS_PTP, ///< the timescale is PTP standard, not arbitrary + PTP_FLAG_LS_ANN, ///< a leap second is being announced + PTP_FLAG_LS_ANN_NEG, ///< the announced leap second is negative + PTP_FLAG_IS_UNICAST, ///< the port currently operates in unicast mode + PTP_FLAG_UTC_VALID, ///< %UTC parameters are valid + PTP_FLAG_ONE_STEP, ///< One-Step Clock active + N_PTP_STATE_FLAGS ///< the number of defined flag bits +}; + +/** + * @brief Flags masks used with PTP_STATE::flags + * + * @see ::PTP_STATE_FLAGS + */ +enum PTP_STATE_FLAG_MASKS +{ + PTP_FLAG_MSK_SLAVE_ONLY = ( 1UL << PTP_FLAG_SLAVE_ONLY ), ///< See ::PTP_FLAG_SLAVE_ONLY + PTP_FLAG_MSK_IS_SLAVE = ( 1UL << PTP_FLAG_IS_SLAVE ), ///< See ::PTP_FLAG_IS_SLAVE + PTP_FLAG_MSK_TIMESCALE_IS_PTP = ( 1UL << PTP_FLAG_TIMESCALE_IS_PTP ), ///< See ::PTP_FLAG_TIMESCALE_IS_PTP + PTP_FLAG_MSK_LS_ANN = ( 1UL << PTP_FLAG_LS_ANN ), ///< See ::PTP_FLAG_LS_ANN + PTP_FLAG_MSK_LS_ANN_NEG = ( 1UL << PTP_FLAG_LS_ANN_NEG ), ///< See ::PTP_FLAG_LS_ANN_NEG + PTP_FLAG_MSK_IS_UNICAST = ( 1UL << PTP_FLAG_IS_UNICAST ), ///< See ::PTP_FLAG_IS_UNICAST + PTP_FLAG_MSK_UTC_VALID = ( 1UL << PTP_FLAG_UTC_VALID ), ///< See ::PTP_FLAG_UTC_VALID + PTP_FLAG_MSK_ONE_STEP = ( 1UL << PTP_FLAG_ONE_STEP ) ///< See ::PTP_FLAG_ONE_STEP +}; + + + +/** + * @brief A structure used to configure a PTP port + */ +typedef struct +{ + uint16_t nw_prot; ///< See ::PTP_NW_PROTS + uint8_t selected_presets; ///< selected PTP presets, see ::PTP_PRESETS + uint8_t domain_number; ///< the PTP clock domain number, 0:3 + + uint8_t delay_mech; ///< See ::PTP_DELAY_MECHS + uint8_t ptp_role; ///< one of the supported PTP roles, see ::PTP_ROLES + uint8_t priority_1; ///< priority 1 + uint8_t priority_2; ///< priority 2 + + uint8_t dflt_clk_class_unsync_cold; // 6:255 + uint8_t dflt_clk_class_unsync_warm; // 6:255 + uint8_t dflt_clk_class_sync_cold; // 6:255 + uint8_t dflt_clk_class_sync_warm; // 6:255 + + uint8_t ann_rcpt_timeout; ///< announce msg. receipt timeout, see ::PTP_ANN_RCPT_TIMEOUT_LIMITS + uint8_t opt_ext; ///< optional configuration extension, see ::PTP_OPT_EXTS + int16_t sync_intv; ///< log2 of the sync interval [s] + + int16_t ann_intv; ///< log2 of the announce interval [s] + int16_t delay_req_intv; ///< log2 of the delay request interval [s] + + 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] + + 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; + +#define _mbg_swab_ptp_cfg_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->nw_prot ); \ + _mbg_swab16( &(_p)->sync_intv ); \ + _mbg_swab16( &(_p)->ann_intv ); \ + _mbg_swab16( &(_p)->delay_req_intv ); \ + _mbg_swab32( &(_p)->upper_bound ); \ + _mbg_swab32( &(_p)->lower_bound ); \ + _mbg_swab16( &(_p)->delay_asymmetry ); \ + _mbg_swab16( &(_p)->flags_ex ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Possible values for PTP_CFG_SETTINGS::ann_rcpt_timeout + */ +enum PTP_ANN_RCPT_TIMEOUT_LIMITS +{ + PTP_ANN_RCPT_TIMEOUT_MIN = 2, + PTP_ANN_RCPT_TIMEOUT_MAX = 8, + DEFAULT_PTP_ANN_RCPT_TIMEOUT = 3 +}; + + + +/** + * @brief A structure to used to query the current configuration and capabilities of a PTP port + */ +typedef struct +{ + PTP_CFG_SETTINGS settings; ///< the current configuration + + 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 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] + int16_t ann_intv_min; ///< log2 of minimum announce interval [s] + int16_t ann_intv_max; ///< log2 of maximum announce interval [s] + int16_t delay_req_intv_min; ///< log2 of minimum delay request interval [s] + int16_t delay_req_intv_max; ///< log2 of maximum delay request interval [s] + + uint32_t supp_flags; ///< a bit mask of supported features, see @ref PTP_CFG_FLAG_MASKS + uint32_t supp_nw_prot; ///< a bit mask of supported network protocols, see ::PTP_NW_PROT_MASKS + uint32_t supp_opt_ext; ///< a bit mask of supported optional extensions, see ::PTP_OPT_EXT_MASKS + uint32_t supp_delay_mech; ///< a bit mask of supported delay mechanisms, see ::PTP_DELAY_MECH_MASKS + +} PTP_CFG_INFO; + +#define _mbg_swab_ptp_cfg_info( _p ) \ +do \ +{ \ + _mbg_swab_ptp_cfg_settings( &(_p)->settings ); \ + _mbg_swab16( &(_p)->supp_flags_ex ); \ + _mbg_swab16( &(_p)->sync_intv_min ); \ + _mbg_swab16( &(_p)->sync_intv_max ); \ + _mbg_swab16( &(_p)->ann_intv_min ); \ + _mbg_swab16( &(_p)->ann_intv_max ); \ + _mbg_swab16( &(_p)->delay_req_intv_min ); \ + _mbg_swab16( &(_p)->delay_req_intv_max ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->supp_nw_prot ); \ + _mbg_swab32( &(_p)->supp_opt_ext ); \ + _mbg_swab32( &(_p)->supp_delay_mech ); \ +} while ( 0 ) + + + +/** + * @brief 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_MASKS + */ +enum PTP_CFG_FLAGS +{ + PTP_CFG_TIME_SCALE_IS_PTP, ///< [R/W] time scale is PTP/TAI, else arbitrary + PTP_CFG_V1_HW_COMPAT, ///< [R/W] maybe required for certain NIC chips, not used by Meinberg + PTP_CFG_CAN_BE_UNICAST_SLAVE, ///< [R/-] supports unicast slave role, see ::PTP_ROLE_UNICAST_SLAVE + PTP_CFG_CAN_BE_MULTICAST_MASTER, ///< [R/-] supports multicast master role, see ::PTP_ROLE_MULTICAST_MASTER + PTP_CFG_CAN_BE_UNICAST_MASTER, ///< [R/-] supports unicast master, see ::PTP_ROLE_UNICAST_MASTER + PTP_CFG_CAN_BE_MULTICAST_AUTO, ///< [R/-] can automatically become multicast master or slave, see ::PTP_CFG_CAN_BE_MULTICAST_AUTO + PTP_CFG_SUPP_UTC_VALID, ///< [R/-] ::PTP_FLAG_UTC_VALID bit in ::PTP_STATE::flags is supported + PTP_CFG_CAN_BE_BOTH_MASTER, ///< [R/-] supports unicast and multicast master role at the same time, see ::PTP_CFG_CAN_BE_BOTH_MASTER + + PTP_CFG_HYBRID_MASTER, ///< [R/W] supports hybrid mode in master roles + PTP_CFG_HYBRID_SLAVE, ///< [R/W] supports hybrid mode in slave roles + PTP_CFG_ONE_STEP_MASTER, ///< [R/W] supports one-step mode in master roles + PTP_CFG_MNGMNT_MSGS_DISB, ///< [R/W] supports disabling of PTP management messages + PTP_CFG_SUPP_MCAST_SLAVE_FLAG, ///< [R/-] indicates that ::PTP_CFG_CAN_BE_MULTICAST_SLAVE flag is supported and can be checked + PTP_CFG_CAN_BE_MULTICAST_SLAVE, ///< [R/-] if ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG bit set, indicates if multicast slave role is supported + PTP_CFG_ONE_STEP_L2, ///< [R/-] supports the combination of One-Step and Layer2 mode + PTP_CFG_ONE_STEP_P2P, ///< [R/-] supports the combination of One-Step and P2P Delay Mechanism + + PTP_CFG_TSU_RESET, ///< [R/-] supports TSU reset via register cmd + PTP_CFG_NTP_HW_TS_MASTER, ///< [R/-] supports the NTP HW time stamping in Master mode + PTP_CFG_NTP_HW_TS_SLAVE, ///< [R/-] supports the NTP HW time stamping in Slave mode + PTP_CFG_SYNCE_MASTER, ///< [R/-] Hardware supports Synchronous Ethernet Out + PTP_CFG_SYNCE_SLAVE, ///< [R/-] Hardware supports Synchronous Ethernet In + PTP_CFG_HAS_MUX, ///< [R/-] Hardware supports multiplexed signal outputs + PTP_CFG_CAN_BE_TIME_MONITOR, ///< [R/-] can be Monitoring device for external PTP or NTP devices //### TODO Shouldn't this be an XFEATURE flag? + PTP_CFG_HAS_STATISTICS, ///< [R/-] ::MBG_PTP_STATISTICS_INFO can be queried + + PTP_CFG_CAN_BE_V1_MASTER, ///< [R/-] supports PTPv1 MASTER role + PTP_CFG_CAN_BE_V1_SLAVE, ///< [R/-] supports PTPv1 SLAVE role + PTP_CFG_HAS_V2_COMMON_DATASETS, ///< [R/-] PTPv2 common dataset structures (see IEEE1588-2008, chapter 8.2) can be queried + PTP_CFG_HAS_V1_COMMON_DATASETS, ///< [R/-] PTPv1 common dataset structures can be queried + 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 + * + * @see ::PTP_CFG_INFO::supp_flags + * @see ::PTP_CFG_SETTINGS::flags + * @see ::PTP_CFG_FLAGS + * + * @anchor PTP_CFG_FLAG_MASKS + * + * @{ */ + +#define PTP_CFG_MSK_TIME_SCALE_IS_PTP ( 1UL << PTP_CFG_TIME_SCALE_IS_PTP ) ///< See ::PTP_CFG_TIME_SCALE_IS_PTP +#define PTP_CFG_MSK_V1_HW_COMPAT ( 1UL << PTP_CFG_V1_HW_COMPAT ) ///< See ::PTP_CFG_V1_HW_COMPAT +#define PTP_CFG_MSK_CAN_BE_UNICAST_SLAVE ( 1UL << PTP_CFG_CAN_BE_UNICAST_SLAVE ) ///< See ::PTP_CFG_CAN_BE_UNICAST_SLAVE +#define PTP_CFG_MSK_CAN_BE_MULTICAST_MASTER ( 1UL << PTP_CFG_CAN_BE_MULTICAST_MASTER ) ///< See ::PTP_CFG_CAN_BE_MULTICAST_MASTER +#define PTP_CFG_MSK_CAN_BE_UNICAST_MASTER ( 1UL << PTP_CFG_CAN_BE_UNICAST_MASTER ) ///< See ::PTP_CFG_CAN_BE_UNICAST_MASTER +#define PTP_CFG_MSK_CAN_BE_MULTICAST_AUTO ( 1UL << PTP_CFG_CAN_BE_MULTICAST_AUTO ) ///< See ::PTP_CFG_CAN_BE_MULTICAST_AUTO +#define PTP_CFG_MSK_SUPP_UTC_VALID ( 1UL << PTP_CFG_SUPP_UTC_VALID ) ///< See ::PTP_CFG_SUPP_UTC_VALID +#define PTP_CFG_MSK_CAN_BE_BOTH_MASTER ( 1UL << PTP_CFG_CAN_BE_BOTH_MASTER ) ///< See ::PTP_CFG_CAN_BE_BOTH_MASTER + +#define PTP_CFG_MSK_HYBRID_MASTER ( 1UL << PTP_CFG_HYBRID_MASTER ) ///< See ::PTP_CFG_HYBRID_MASTER +#define PTP_CFG_MSK_HYBRID_SLAVE ( 1UL << PTP_CFG_HYBRID_SLAVE ) ///< See ::PTP_CFG_HYBRID_SLAVE +#define PTP_CFG_MSK_ONE_STEP_MASTER ( 1UL << PTP_CFG_ONE_STEP_MASTER ) ///< See ::PTP_CFG_ONE_STEP_MASTER +#define PTP_CFG_MSK_MNGMNT_MSGS_DISB ( 1UL << PTP_CFG_MNGMNT_MSGS_DISB ) ///< See ::PTP_CFG_MNGMNT_MSGS_DISB +#define PTP_CFG_MSK_SUPP_MCAST_SLAVE_FLAG ( 1UL << PTP_CFG_SUPP_MCAST_SLAVE_FLAG ) ///< See ::PTP_CFG_SUPP_MCAST_SLAVE_FLAG +#define PTP_CFG_MSK_CAN_BE_MULTICAST_SLAVE ( 1UL << PTP_CFG_CAN_BE_MULTICAST_SLAVE ) ///< See ::PTP_CFG_CAN_BE_MULTICAST_SLAVE +#define PTP_CFG_MSK_ONE_STEP_L2 ( 1UL << PTP_CFG_ONE_STEP_L2 ) ///< See ::PTP_CFG_ONE_STEP_L2 +#define PTP_CFG_MSK_ONE_STEP_P2P ( 1UL << PTP_CFG_ONE_STEP_P2P ) ///< See ::PTP_CFG_ONE_STEP_P2P + +#define PTP_CFG_MSK_TSU_RESET ( 1UL << PTP_CFG_TSU_RESET ) ///< See ::PTP_CFG_TSU_RESET +#define PTP_CFG_MSK_NTP_HW_TS_MASTER ( 1UL << PTP_CFG_NTP_HW_TS_MASTER ) ///< See ::PTP_CFG_NTP_HW_TS_MASTER +#define PTP_CFG_MSK_NTP_HW_TS_SLAVE ( 1UL << PTP_CFG_NTP_HW_TS_SLAVE) ///< See ::PTP_CFG_NTP_HW_TS_SLAVE +#define PTP_CFG_MSK_SYNCE_MASTER ( 1UL << PTP_CFG_SYNCE_MASTER ) ///< See ::PTP_CFG_SYNCE_MASTER +#define PTP_CFG_MSK_SYNCE_SLAVE ( 1UL << PTP_CFG_SYNCE_SLAVE ) ///< See ::PTP_CFG_SYNCE_SLAVE +#define PTP_CFG_MSK_HAS_MUX ( 1UL << PTP_CFG_HAS_MUX ) ///< See ::PTP_CFG_HAS_MUX +#define PTP_CFG_MSK_CAN_BE_TIME_MONITOR ( 1UL << PTP_CFG_CAN_BE_TIME_MONITOR ) ///< See ::PTP_CFG_CAN_BE_TIME_MONITOR +#define PTP_CFG_MSK_HAS_STATISTICS ( 1UL << PTP_CFG_HAS_STATISTICS ) ///< See ::PTP_CFG_HAS_STATISTICS + +#define PTP_CFG_MSK_CAN_BE_V1_MASTER ( 1UL << PTP_CFG_CAN_BE_V1_MASTER ) ///< See ::PTP_CFG_CAN_BE_V1_MASTER +#define PTP_CFG_MSK_CAN_BE_V1_SLAVE ( 1UL << PTP_CFG_CAN_BE_V1_SLAVE ) ///< See ::PTP_CFG_CAN_BE_V1_SLAVE +#define PTP_CFG_MSK_HAS_V2_COMMON_DATASETS ( 1UL << PTP_CFG_HAS_V2_COMMON_DATASETS ) ///< See ::PTP_CFG_HAS_V2_COMMON_DATASETS +#define PTP_CFG_MSK_HAS_V1_COMMON_DATASETS ( 1UL << PTP_CFG_HAS_V1_COMMON_DATASETS ) ///< See ::PTP_CFG_HAS_V1_COMMON_DATASETS +#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 + 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 + +/** @} 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 ) + + + +/** + * @brief Register in TSU-GbE FPGA to determine board features of the current TSU board revision + */ +typedef uint16_t PTP_HW_FEATURES; + + + +/** + * @brief Bits used to define ::PTP_HW_FEAT_MASKS + */ +enum PTP_HW_FEAT_BITS +{ + PTP_FEAT_SYNCE_EXT_MUX, ///< [R] supports SyncE and external signal multiplexer + N_PTP_HW_FEAT ///< the number of defined features +}; + + +// TODO fix comment linkage +/** + * @brief Bit masks used with ::PTP_HW_FEATURES + * + * @see ::PTP_HW_FEAT_BITS + */ +enum PTP_HW_FEAT_MASKS +{ + PTP_HW_FEAT_MSK_SYNCE_EXT_MUX = ( 1UL << PTP_FEAT_SYNCE_EXT_MUX ) ///< See ::PTP_FEAT_SYNCE_EXT_MUX +}; + + + +/** + * @brief Known optional PTP protocol extensions, see ::PTP_CFG_SETTINGS::opt_ext + * + * @see ::PTP_OPT_EXT_MASKS + */ +enum PTP_OPT_EXTS +{ + PTP_OPT_EXT_NONE, ///< no extension used + PTP_OPT_EXT_POWER, ///< IEEE C37.238-2011 profile extension + PTP_OPT_EXT_TELECOM, ///< ITU-T G.8265.1 profile extension + PTP_OPT_EXT_TELECOM_PHASE, ///< ITU-T G.8275.1 profile extension + PTP_OPT_EXT_SMPTE, ///< SMPTE ST 2059-2 profile extension + PTP_OPT_EXT_8021AS, ///< IEEE 802.1AS profile extension + PTP_OPT_EXT_6185093, ///< IEC/IEEE FDIS 61850-9-3 Power Utility profile extension + PTP_OPT_EXT_TELECOM_PTS, ///< ITU-T G.8275.2 profile extension + PTP_OPT_EXT_C37238_2017, ///< IEEE C37.238-2017 profile extension + N_PTP_OPT_EXT ///< number of known optional extensions +}; + + +/** + * @brief Flag masks used with ::PTP_CFG_INFO::supp_opt_ext + * + * @see ::PTP_OPT_EXTS + */ +enum PTP_OPT_EXT_MASKS +{ + PTP_MSK_OPT_EXT_NONE = ( 1UL << PTP_OPT_EXT_NONE ), ///< this is actually not used, see ::PTP_OPT_EXT_NONE + PTP_MSK_OPT_EXT_POWER = ( 1UL << PTP_OPT_EXT_POWER ), ///< See ::PTP_OPT_EXT_POWER + PTP_MSK_OPT_EXT_TELECOM = ( 1UL << PTP_OPT_EXT_TELECOM ), ///< See ::PTP_OPT_EXT_TELECOM + PTP_MSK_OPT_EXT_TELECOM_PHASE = ( 1UL << PTP_OPT_EXT_TELECOM_PHASE ), ///< See ::PTP_OPT_EXT_TELECOM_PHASE + PTP_MSK_OPT_EXT_SMPTE = ( 1UL << PTP_OPT_EXT_SMPTE ), ///< See ::PTP_OPT_EXT_SMPTE + PTP_MSK_OPT_EXT_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_C37238_2017 = ( 1UL << PTP_OPT_EXT_C37238_2017 ) ///< See ::PTP_MSK_OPT_EXT_C37238_2017 +}; + + + +/** + * @brief Enumeration of PTP cfg presets used with ::PTP_CFG_SETTINGS::selected_presets + * + * This can be used by configuration programs to determine + * the last recently selected presets. + * + * @see ::PTP_PRESETS_STRS + * @see ::PTP_PRESETS_MASKS + */ +enum PTP_PRESETS +{ + PTP_PRESETS_CUSTOM, ///< customizable, always supported + PTP_PRESETS_DFLT_E2E, ///< pure IEEE1588-2008 (PTPv2) with E2E + PTP_PRESETS_DFLT_P2P, ///< pure IEEE1588-2008 (PTPv2) with P2P + PTP_PRESETS_POWER, ///< IEEE C37.238 profile extension, only if ::PTP_MSK_OPT_EXT_POWER is set + PTP_PRESETS_TELECOM, ///< ITU-T G.8265.1 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM is set + PTP_PRESETS_TELECOM_PHASE, ///< ITU-T G.8275.1 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM_PHASE is set + PTP_PRESETS_SMPTE, ///< SMPTE ST 2059-2 profile extension, only if ::PTP_MSK_OPT_EXT_SMPTE is set + PTP_PRESETS_AES67, ///< AES67 media profile + PTP_PRESETS_8021AS, ///< IEEE 802.1AS -like profile, only if ::PTP_MSK_OPT_EXT_8021AS is set + PTP_PRESETS_6185093, ///< IEC/IEEE FDIS 61850-9-3, only if ::PTP_MSK_OPT_EXT_6185093 is set + PTP_PRESETS_TELECOM_PTS, ///< ITU-T G.8275.2 profile extension, only if ::PTP_MSK_OPT_EXT_TELECOM_PTS is set + PTP_PRESETS_DOCSIS_31, ///< only if ::PTP_MSK_OPT_EXT_TELECOM_PHASE is set + PTP_PRESETS_C37238_2017, ///< only if ::PTP_MSK_OPT_EXT_C37238_2017 is set + N_PTP_PRESETS ///< number of supported presets +}; + + +/** + * @brief Flag masks used with ::PTP_CFG_INFO::supp_opt_ext + * + * @see ::PTP_PRESETS + */ +enum PTP_PRESETS_MASKS +{ + PTP_MSK_PRESETS_CUSTOM = ( 1UL << PTP_PRESETS_CUSTOM ), ///< See ::PTP_PRESETS_CUSTOM + PTP_MSK_PRESETS_DFLT_E2E = ( 1UL << PTP_PRESETS_DFLT_E2E ), ///< See ::PTP_PRESETS_DFLT_E2E + PTP_MSK_PRESETS_DFLT_P2P = ( 1UL << PTP_PRESETS_DFLT_P2P ), ///< See ::PTP_PRESETS_DFLT_P2P + PTP_MSK_PRESETS_POWER = ( 1UL << PTP_PRESETS_POWER ), ///< See ::PTP_PRESETS_POWER + PTP_MSK_PRESETS_TELECOM = ( 1UL << PTP_PRESETS_TELECOM ), ///< See ::PTP_PRESETS_TELECOM + PTP_MSK_PRESETS_TELECOM_PHASE = ( 1UL << PTP_PRESETS_TELECOM_PHASE ), ///< See ::PTP_PRESETS_TELECOM_PHASE + PTP_MSK_PRESETS_SMPTE = ( 1UL << PTP_PRESETS_SMPTE ), ///< See ::PTP_PRESETS_SMPTE + PTP_MSK_PRESETS_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_C37238_2017 = ( 1UL << PTP_PRESETS_C37238_2017) ///< See ::PTP_PRESETS_C37238_2017 + +}; + + +/** + * @brief Name strings for defined PTP presets + * + * @see ::PTP_PRESETS + */ +#define PTP_PRESETS_STRS \ +{ \ + "Custom", \ + "Default E2E IEEE1588-2008", \ + "Default P2P IEEE1588-2008", \ + "Power IEEE C37.238-2011", \ + "Telecom ITU-T G.8265.1", \ + "Telecom ITU-T G.8275.1", \ + "SMPTE ST 2059-2", \ + "AES67 Media", \ + "IEEE 802.1AS", \ + "Utility IEC 61850-9-3", \ + "Telecom ITU-T G.8275.2", \ + "DOCSIS 3.1", \ + "Power IEEE C37.238-2017" \ +} + + + +/** + * @brief Additional parameters for Power Profile + */ +#define PTP_POWER_PROFILE_GM_ID_MIN 3 +#define PTP_POWER_PROFILE_GM_ID_MAX 255 + +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 grandmaster_id_2017; ///< Grandmaster ID defined in C.37.2017 is now 16 Bits + TZDL tzdl; + +} PTP_POWER_PROFILE_CFG; + +#define _mbg_swab_ptp_power_profile_cfg( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->network_incaccuracy ); \ + _mbg_swab8( &(_p)->grandmaster_id ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab16( &(_p)->grandmaster_id_2017 ); \ + _mbg_swab_tzdl( &(_p)->tzdl ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +#if defined( _PRELIMINARY_CODE ) + +// TODO: These definitions are preliminary and maybe subject to changes. + +/** + * @brief SMPTE System Frame Rates according to SMPTE ST 2059-2 + * + * @see ::TODO + */ +enum SMPTE_SYSTEM_FRAME_RATES +{ + SMPTE_23_98HZ, + SMPTE_24HZ, + SMPTE_25HZ, + SMPTE_29_97HZ, + SMPTE_50HZ, + SMPTE_59_94HZ, + N_SMPTE_SYSTEM_FRAME_RATES +}; + + +#define SMPTE_SYSTEM_FRAME_RATE_STR \ +{ \ + "24Hz (23.98)", \ + "24Hz", \ + "25Hz", \ + "30Hz (29.97)", \ + "50Hz", \ + "60Hz (59.94)" \ +} + + +#define SMPTE_FRAME_RATE_NUM \ +{ \ + 24000, \ + 24000, \ + 25000, \ + 30000, \ + 50000, \ + 60000, \ +} + +#define SMPTE_FRAME_RATE_DENUM \ +{ \ + 1001, \ + 1000, \ + 1000, \ + 1001, \ + 1000, \ + 1001, \ +} + + +/** + * @brief Additional parameters for SMPTE ST 2059-2 profile + * + * This stucture holds the synchronization metadata required for the SMPTE profile. + * This structure is only used for internal storage of the data. The data is + * distributed through a network by using management messages and the dedicated + * organization extension TLV defined in the SMPTE profile. + */ +typedef struct +{ + /// @brief Default system frame rate. + /// + /// Default video frame rate of the slave system as a lowest term rational. + /// The data type shall be composed of a pair of unsigned Int32 values coded + /// in big-endian form where the first shall be the numerator and the second + /// shall be the denominator. The denominator shall be the smallest value + /// that represents the frame rate denominator + /// For example, 29.97 Hz: (30000/1001) or 25 Hz: (25/1). + uint32_t defaultSystemFrameRateNum; + + /// @brief The denominator associated with @a #defaultSystemFrameRateNum. + uint32_t defaultSystemFrameRateDenum; + + /// @brief Master locking status + /// + /// Complementary information to clockClass (0: Not in use, 1: Free Run, + /// 2: Cold Locking, 3: Warm Locking, 4: Locked) + uint8_t masterLockingStatus; + + /// @brief Time Address Flags + /// + /// Indicates the intended ST 12-1 flags. + /// Bit 0: Drop frame (0: Non-drop-frame, 1: Drop-frame) + /// Bit 1: Color Frame Identification (0: Not in use, 1: In use) + /// Bits 2-7: Reserved + uint8_t timeAddressFlags; + + uint8_t reserved_1; + uint8_t reserved_2; + + /// @brief Current local offset. + /// + /// Offset in seconds of Local Time from grandmaster PTP time. For example, + /// if Local Time is Eastern Standard Time (North America) %UTC-5 and the + /// number of leap seconds is 35, the value will be -18035 (decimal). + int32_t currentLocalOffset; + + /// @brief Jump seconds. + /// + /// The size of the next discontinuity, in seconds, of Local Time. A value + /// of zero indicates that no discontinuity is expected. A positive value + /// indicates that the discontinuity will cause @a #currentLocalOffset to increase. + int32_t jumpSeconds; + + /// @brief Time of next jump. + /// + /// The value of the seconds portion of the grandmaster PTP time at the time + /// that the next discontinuity of the @a #currentLocalOffset will occur. The + /// discontinuity occurs at the start of the second indicated. + PTP_PKT_TSTAMP_SECS timeOfNextJump; + + /// @brief Time of next jam. + /// + /// The value of the seconds portion of the PTP time corresponding to the next + /// scheduled occurrence of the Daily Jam. If no Daily Jam is scheduled, the + /// value of @a #timeOfNextJam shall be zero. + PTP_PKT_TSTAMP_SECS timeOfNextJam; + + /// @brief Time of previous jam. + /// + /// The value of the seconds portion of the PTP time corresponding to the + /// previous occurrence of the Daily Jam. + PTP_PKT_TSTAMP_SECS timeOfPreviousJam; + + uint8_t reserved_3; + uint8_t reserved_4; + uint32_t reserved_5; + + /// @brief Previous jam local offset. + /// + /// The value of @a #currentLocalOffset at the previous daily jam time. + /// If a discontinuity of Local Time occurs at the jam time, this parameter + /// reflects the offset after the discontinuity. + PTP_TLV_TIME_OFFS previousJamLocalOffset; + + PTP_TLV_DST_FLAGS daylightSaving; ///< Daylight saving flags, see ::PTP_TLV_DST_FLAG_MSKS. + + PTP_TLV_LS_FLAGS leapSecondJump; ///< Leap second flags, see ::PTP_TLV_LS_FLAG_MSKS. + + uint8_t reserved_6; + uint8_t reserved_7; + + uint32_t reserved_8; + uint32_t reserved_9; + uint32_t reserved_10; + +} 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 ) + + + +/** + * @brief Additional parameters for Telecom8275.1 profile + */ +typedef struct +{ + uint8_t use_alternate_multicast_address; + uint8_t reserved_1; + uint8_t reserved_2; + uint8_t reserved_3; + uint32_t reserved_4; + +} PTP_TELECOMG8275_PROFILE_CFG; + +#define _mbg_swab_ptp_telecom8275_profile_cfg( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->use_alternate_multicast_mac_address ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab8( &(_p)->reserved_2 ); \ + _mbg_swab8( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ +} while ( 0 ) + + + +/** + * @brief A type which holds one of the ITU-T SSM codes + * + * @see ::ITU_SSM_CODES + */ +typedef uint16_t ITU_SSM_CODE; + + + +/** + * @brief ITU-T SSM codes acc. to Recommendation G.781 + * + * @see ::ITU_SSM_CODE + */ +enum ITU_SSM_CODES +{ + ITU_SSM_CODE_STU_UKN, + ITU_SSM_CODE_PRS, + ITU_SSM_CODE_PRC, + ITU_SSM_CODE_INV3, + ITU_SSM_CODE_SSU_A_TNC, + ITU_SSM_CODE_INV5, + ITU_SSM_CODE_INV6, + ITU_SSM_CODE_ST2, + ITU_SSM_CODE_SSU_B, + ITU_SSM_CODE_INV9, + ITU_SSM_CODE_ST3, + ITU_SSM_CODE_SEC, + ITU_SSM_CODE_SMC, + ITU_SSM_CODE_ST3E, + ITU_SSM_CODE_PROV, + ITU_SSM_CODE_DNU_DUS, + N_ITU_SSM_CODES +}; + + +#define N_SSM_CODES_OPTION_1 5 +#define N_SSM_CODES_OPTION_2 9 + + +/** + * @brief Name strings for SSM codes, network option I + * + * @see ::ITU_SSM_CODES + */ +#define ITU_SSM_CODE_OPT_1_STRS \ +{ \ + "", \ + "", \ + "QL-PRC", \ + "", \ + "QL-SSU-A", \ + "", \ + "", \ + "", \ + "QL-SSU-B", \ + "", \ + "", \ + "QL-SEC", \ + "", \ + "", \ + "", \ + "QL-DNU" \ +} + + + +/** + * @brief Name strings for SSM codes, network option II + * + * @see ::ITU_SSM_CODES + */ +#define ITU_SSM_CODE_OPT_2_STRS \ +{ \ + "QL-STU", \ + "QL-PRS", \ + "", \ + "", \ + "QL-TNC", \ + "", \ + "", \ + "QL-ST2", \ + "", \ + "", \ + "QL-ST3", \ + "", \ + "QL-SMC", \ + "QL-ST3E", \ + "QL-PROV", \ + "QL-DUS" \ +} + + + +/** + * @brief Name strings for SSM codes, option I and II combined + * + * @see ::ITU_SSM_CODES + */ +#define ITU_SSM_CODE_STRS_COMBINED \ +{ \ + "QL-STU/UKN", \ + "QL-PRS", \ + "QL-PRC", \ + "QL-INV3", \ + "QL-SSU-A/TNC", \ + "QL-INV5", \ + "QL-INV6", \ + "QL-ST2", \ + "QL-SSU-B", \ + "QL-INV9", \ + "QL-EEC2/ST3", \ + "QL-EEC1/SEC", \ + "QL-SMC", \ + "QL-ST3E", \ + "QL-PROV", \ + "QL-DNU/DUS", \ +} + + + +/** + * @brief Maximum T1 SSM only quality levels + * + * @see ::T1_SSM_QLVL + * @see ::T1_SSM_QLVL_STRS + * @see ::T1_SSM_QLVL_ARRAY + */ +#define MAX_T1_SSM_QLVL 8 + + + +/** + * @brief T1 SSM only quality level (6 bit encoded) + * + * @see ::MAX_T1_SSM_QLVL + * @see ::T1_SSM_QLVL_STRS + * @see ::T1_SSM_QLVL_ARRAY + */ +enum T1_SSM_QLVL +{ + T1_SSM_QLVL_ST1_TRACE = 2, + T1_SSM_QLVL_SYNC_TRACE_UNKNOWN = 4, + T1_SSM_QLVL_ST2_TRACE = 6, + T1_SSM_QLVL_ST3_TRACE = 8, + T1_SSM_QLVL_SONET_MIN_CLOCK_TRACE = 17, + T1_SSM_QLVL_ST4_TRACE = 20, + T1_SSM_QLVL_DNU_FOR_SYNC = 24, + T1_SSM_QLVL_RESERVED = 32 +}; + + + +/** + * @brief T1 SSM only quality level array + * + * @see ::MAX_T1_SSM_QLVL + * @see ::T1_SSM_QLVL_STRS + * @see ::T1_SSM_QLVL + */ +#define T1_SSM_QLVL_ARRAY \ +{ \ + T1_SSM_QLVL_ST1_TRACE, \ + T1_SSM_QLVL_SYNC_TRACE_UNKNOWN, \ + T1_SSM_QLVL_ST2_TRACE, \ + T1_SSM_QLVL_ST3_TRACE, \ + T1_SSM_QLVL_SONET_MIN_CLOCK_TRACE, \ + T1_SSM_QLVL_ST4_TRACE, \ + T1_SSM_QLVL_DNU_FOR_SYNC, \ + T1_SSM_QLVL_RESERVED \ +} + + + +/** + * @brief Name strings for T1 SSM quality levels + * + * @see ::MAX_T1_SSM_QLVL + * @see ::T1_SSM_QLVL + * @see ::T1_SSM_QLVL_ARRAY + */ +#define T1_SSM_QLVL_STRS \ +{ \ + "Stratum 1 traceable", \ + "Synchronized traceability unknown", \ + "Stratum 2 traceable", \ + "Stratum 3 traceable", \ + "SONET minimum clock traceable", \ + "Stratum 4 traceable", \ + "Do not use for sync", \ + "Reserved for network sync" \ +} + + + +/** + * @brief SDH network options + * + * @see ::SDH_NETWORK_OPTION_MASKS + */ +enum SDH_NETWORK_OPTIONS +{ + SDH_NETWORK_OPTION_1, + SDH_NETWORK_OPTION_2, + N_SDH_NETWORK_OPTIONS + +}; + + + +/** + * @brief Flag masks used with :: MBG_NET_INTF_LINK_INFO::supp_sdh_net_opts + * + * @see ::SDH_NETWORK_OPTIONS + */ +enum SDH_NETWORK_OPTION_MASKS +{ + SDH_NETWORK_OPTION_1_MSK = ( 1UL << SDH_NETWORK_OPTION_1 ), ///< See ::SDH_NETWORK_OPTION_1 + SDH_NETWORK_OPTION_2_MSK = ( 1UL << SDH_NETWORK_OPTION_2 ), ///< See ::SDH_NETWORK_OPTION_2 +}; + + + +/** + * @brief Name strings for SDH network options + * + * @see ::SDH_NETWORK_OPTIONS + */ +#define SDH_NETWORK_OPTION_STRS \ +{ \ + "SDH Network Opt. 1", \ + "SDH Network Opt. 2", \ +} + + +/** + * @brief Link modes for SyncE on a 1000BASE-T interface. + * + * @see ::GBIT_LINK_COPPER_MODE_MASKS + */ +enum GBIT_LINK_COPPER_MODES +{ + GBIT_LINK_COPPER_AUTO, // valid if synce is disabled + GBIT_LINK_COPPER_FORCE_SYNCE_AUTO, + GBIT_LINK_COPPER_FORCE_OR_IS_MASTER, // Used in both structures, settings and status + GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE, // Used in both structures, settings and status + GBIT_LINK_COPPER_PREFER_MASTER, + GBIT_LINK_COPPER_PREFER_SLAVE, + N_GBIT_LINK_COPPER_MODES +}; + + + +/** + * @brief Flag masks used with ::MBG_NET_INTF_LINK_INFO::supp_gb_copper_modes. + * + * @see ::GBIT_LINK_COPPER_MODES + */ +enum GBIT_LINK_COPPER_MODE_MASKS +{ + GBIT_LINK_COPPER_AUTO_MSK = ( 1UL << GBIT_LINK_COPPER_AUTO ), ///< See ::GBIT_LINK_COPPER_AUTO_MSK + GBIT_LINK_COPPER_FORCE_SYNCE_AUTO_MSK = ( 1UL << GBIT_LINK_COPPER_FORCE_SYNCE_AUTO ), ///< See ::GBIT_LINK_COPPER_FORCE_SYNCE_AUTO + GBIT_LINK_COPPER_FORCE_OR_IS_MASTER_MSK = ( 1UL << GBIT_LINK_COPPER_FORCE_OR_IS_MASTER ), ///< See ::GBIT_LINK_COPPER_FORCE_OR_IS_MASTER + GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE_MSK = ( 1UL << GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE ), ///< See ::GBIT_LINK_COPPER_FORCE_OR_IS_SLAVE + GBIT_LINK_COPPER_PREFER_MASTER_MSK = ( 1UL << GBIT_LINK_COPPER_PREFER_MASTER ), ///< See ::GBIT_LINK_COPPER_PREFER_MASTER + GBIT_LINK_COPPER_PREFER_SLAVE_MSK = ( 1UL << GBIT_LINK_COPPER_PREFER_SLAVE ) ///< See ::GBIT_LINK_COPPER_PREFER_SLAVE +}; + + + +//##++++ TODO: shouldn't this be merged with MBG_NET_LINK_ROLE_BITS / MBG_NET_LINK_ROLE_MASKS? +/** + * @brief Link status for SyncE on a 1000BASE-T interface + * + * @see ::TODO + */ +enum GBIT_LINK_STATUS +{ + GBIT_LINK_COPPER_IS_MASTER, ///< GBIT Link is currently clock master + GBIT_LINK_COPPER_IS_SLAVE, ///< GBIT Link is currently clock slave + GBIT_LINK_COPPER_CFG_FAULT, ///< GBIT Link has a configruation fault (conflict with link partner + GBIT_LINK_COPPER_IS_FE, ///< Link is running on Fast Ethernet (no MASTER/SLAVE decision) + GBIT_LINK_DOWN, ///< Currently no link + GBIT_LINK_FIBER, ///< GBIT Linkup on SFP interface + N_GBIT_LINK_STATUS +}; + + +#define GBIT_LINK_STATUS_STRS \ +{ \ + "MASTER (1000BASE-T)", \ + "SLAVE (1000BASE-T)", \ + "CFG FAULT", \ + "AUTO (100BASE-TX)", \ + "LINK DOWN", \ + "AUTO (SFP LINK UP)", \ +} + +#else // !defined( _PRELIMINARY_CODE ), dummy declarations + +typedef int PTP_SMPTE_PROFILE_CFG; +typedef int PTP_TELECOMG8275_PROFILE_CFG; +typedef int ITU_SSM_CODE; + +#endif // defined( _PRELIMINARY_CODE ) + + + +/** + * @brief Limits to be considered when specifying PTP unicast masters + */ +typedef struct +{ + uint16_t n_supp_master; ///< number of unicast masters which can be specified + int16_t sync_intv_min; ///< log2 of minimum sync interval [s] + int16_t sync_intv_max; ///< log2 of maximum sync interval [s] + int16_t ann_intv_min; ///< log2 of minimum announce interval [s] + int16_t ann_intv_max; ///< log2 of maximum announce interval [s] + int16_t delay_req_intv_min; ///< log2 of minimum delay request interval [s] + int16_t delay_req_intv_max; ///< log2 of maximum delay request interval [s] + uint16_t reserved_0; ///< reserved, currently always 0 + uint32_t supp_flags; ///< a bit mask indicating which flags are supported + uint32_t reserved_1; ///< reserved, currently always 0 + +} PTP_UC_MASTER_CFG_LIMITS; + +#define _mbg_swab_ptp_uc_master_cfg_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->n_supp_master ); \ + _mbg_swab16( &(_p)->sync_intv_min ); \ + _mbg_swab16( &(_p)->sync_intv_max ); \ + _mbg_swab16( &(_p)->ann_intv_min ); \ + _mbg_swab16( &(_p)->ann_intv_max ); \ + _mbg_swab16( &(_p)->delay_req_intv_min ); \ + _mbg_swab16( &(_p)->delay_req_intv_max ); \ + _mbg_swab16( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ +} while ( 0 ) + + + +/** + * @brief Configuration settings specifiying how to query a PTP unicast master + * + * This structure is used on a unicast slave to specify the settings of + * a unicast master polled by the slave. The number of unicast masters + * which can be specified depends on the capabilities of the slave device + * and is returned in ::PTP_UC_MASTER_CFG_LIMITS::n_supp_master. + * + * The structure ::PTP_UC_MASTER_SETTINGS_IDX should be sent to the device + * to save the configuration. + */ +typedef struct +{ + MBG_HOSTNAME gm_host; ///< Hostname or IP address of the grandmaster. + PTP_CLOCK_ID gm_clock_id; ///< Clock ID of the master port, or ::PTP_CLOCK_ID_WILDCARD. + PTP_PORT_ID gm_port_id; ///< Target port ID of the master port (e.g. 135) or ::PTP_PORT_ID_WILDCARD. + int16_t sync_intv; ///< Sync interval [log2 s]. + int16_t ann_intv; ///< Announce interval [log2 s]. + int16_t delay_req_intv; ///< Delay request interval [log2 s]. + int32_t fix_offset; ///< Constant time offset to be compensated [ns]. + uint16_t message_duration; ///< Time period until master stops sending messages [s]. + uint16_t reserved_0; ///< Reserved, currently always 0. + uint32_t reserved_1; ///< Reserved, currently always 0. + uint32_t flags; ///< Reserved, currently always 0. + +} PTP_UC_MASTER_SETTINGS; + +#define _mbg_swab_ptp_uc_master_settings( _p ) \ +do \ +{ \ + _mbg_swab_ptp_clock_id( &(_p)->gm_clock_id ); \ + _mbg_swab_ptp_port_id( &(_p)->gm_port_id ); \ + _mbg_swab16( &(_p)->sync_intv ); \ + _mbg_swab16( &(_p)->ann_intv ); \ + _mbg_swab16( &(_p)->delay_req_intv ); \ + _mbg_swab32( &(_p)->fix_offset ); \ + _mbg_swab16( &(_p)->message_duration ); \ + _mbg_swab16( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Unicast PTP master message duration limits + * + * Each unicast PTP master sends messages to a unicast slave only + * for a given interval as requested by the particular slave, which + * is called message duration. + * These symbols define the minimum and maximum message duration + * configured on a slave for a specific unicast master, i.e. for + * PTP_UC_MASTER_SETTINGS::message_duration. The values are defined + * in the PTP v2 standard. + */ +enum PTP_UC_MSG_DURATION_LIMITS +{ + PTP_UC_MSG_DURATION_MIN = 10, ///< minimum message duration [s] + PTP_UC_MSG_DURATION_MAX = 1000 ///< maximum message duration [s] +}; + + + +/** + * @brief Configuration settings for a specific PTP unicast master + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; ///< index, 0..PTP_UC_MASTER_CFG_LIMITS::n_supp_master-1 + PTP_UC_MASTER_SETTINGS settings; ///< specification for the unicast master with that index + +} PTP_UC_MASTER_SETTINGS_IDX; + +#define _mbg_swab_ptp_uc_master_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of a unicast master + * + * This structure is used with a PTP unicast slave device to specify + * a PTP unicast master which can be queried by the slave device. + */ +typedef struct +{ + PTP_UC_MASTER_SETTINGS settings; ///< current settings + uint32_t reserved; ///< reserved, currently always 0 + uint32_t flags; ///< reserved, currently always 0 + +} PTP_UC_MASTER_INFO; + +#define _mbg_swab_ptp_uc_master_info( _p ) \ +do \ +{ \ + _mbg_swab_ptp_uc_master_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of a specific unicast master + * + * This structure is used with a PTP unicast slave device to specify + * a PTP unicast master which can be queried by the slave device. + * + * This structure should be read from the device to retrieve the + * current settings and capabilities. The number of supported + * configuration records is PTP_UC_MASTER_CFG_LIMITS::n_supp_master. + * + * @note The ::PTP_UC_MASTER_SETTINGS_IDX structure should be send back + * to the device to save the configuration. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; ///< index, 0..PTP_UC_MASTER_CFG_LIMITS::n_supp_master-1 + PTP_UC_MASTER_INFO info; ///< capabilities and current settings + +} PTP_UC_MASTER_INFO_IDX; + +#define _mbg_swab_ptp_uc_master_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_uc_master_info( &(_p)->info ); \ +} while ( 0 ) + + + +typedef struct +{ + uint32_t counter_cfg; + uint32_t flags; + uint32_t reserved_1; + uint32_t reserved_2; + +} MBG_PTP_STATISTICS_SETTINGS; + + + +typedef struct +{ + MBG_PTP_STATISTICS_SETTINGS settings; + uint32_t supp_flags; ///< Supported settings, currently 0 + uint32_t reserved_1; + +} MBG_PTP_STATISTICS_INFO; + + + +typedef struct +{ + uint32_t status; ///< Status word flags (use PacketCounterStat_e) + uint32_t rx; ///< Overall RX packet counter + uint32_t rxPerSec; ///< Overall RX packet counter + uint32_t tx; ///< Overall TX packet counter + uint32_t txPerSec; ///< Overall TX packet counter + + /// @brief Invalid RX packet counter. + /// + /// Indicates one of the following issues: wrong PTP version, wrong domain number, + /// message from self, message from other BC port, multicast message in unicast mode + /// or message extraction error (size error or inconsistent format). + uint32_t errorRx; + uint32_t announceMsgRx; ///< Accepted Announce message RX counter + uint32_t announceMsgPerSecRx; ///< Accepted Announce message RX counter + uint32_t announceMsgTx; ///< Announce message TX counter + uint32_t announceMsgPerSecTx; ///< Announce message TX counter + uint32_t syncMsgRx; ///< Accepted Sync message RX counter + uint32_t syncMsgPerSecRx; ///< Accepted Sync message RX counter + uint32_t syncMsgTx; ///< Sync message TX counter + uint32_t syncMsgPerSecTx; ///< Sync message TX counter + uint32_t followUpMsgRx; ///< Accepted Follow-up message RX counter + uint32_t followUpMsgPerSecRx; ///< Accepted Follow-up message RX counter + uint32_t followUpMsgTx; ///< Follow-up message TX counter + uint32_t followUpMsgPerSecTx; ///< Follow-up message TX counter + uint32_t dlyReqMsgRx; ///< Accepted Delay request message RX counter + uint32_t dlyReqMsgPerSecRx; ///< Accepted Delay request message RX counter + uint32_t dlyReqMsgTx; ///< Delay request message TX counter + uint32_t dlyReqMsgPerSecTx; ///< Delay request message TX counter + uint32_t dlyRespMsgRx; ///< Accepted Delay response message RX counter + uint32_t dlyRespMsgPerSecRx; ///< Accepted Delay response message RX counter + uint32_t dlyRespMsgTx; ///< Delay response message TX counter + uint32_t dlyRespMsgPerSecTx; ///< Delay response message TX counter + uint32_t pDlyReqMsgRx; ///< Accepted PDelay Request message RX counter + uint32_t pDlyReqMsgPerSecRx; ///< Accepted PDelay Request message RX counter + uint32_t pDlyReqMsgTx; ///< PDelay Request message TX counter + uint32_t pDlyReqMsgPerSecTx; ///< PDelay Request message TX counter + uint32_t pDlyRespMsgRx; ///< Accepted PDelay Response message RX counter + uint32_t pDlyRespMsgPerSecRx; ///< Accepted PDelay Response message RX counter + uint32_t pDlyRespMsgTx; ///< PDelay Response message TX counter + uint32_t pDlyRespMsgPerSecTx; ///< PDelay Response message TX counter + uint32_t pDlyFollowUpRx; ///< Accepted PDelay Follow-Up message RX counter + uint32_t pDlyFollowUpPerSecRx; ///< Accepted PDelay Follow-Up message RX counter + uint32_t pDlyFollowUpTx; ///< PDelay Follow-Up message TX counter + uint32_t pDlyFollowUpPerSecTx; ///< PDelay Follow-Up message TX counter + uint32_t signallingRx; ///< Accepted Signalling message RX counter + uint32_t signallingPerSecRx; ///< Accepted Signalling message RX counter + uint32_t signallingTx; ///< Signalling message TX counter + uint32_t signallingPerSecTx; ///< Signalling message TX counter + uint32_t mgmtRx; ///< Accepted Management message RX counter + uint32_t mgmtPerSecRx; ///< Accepted Management message RX counter + uint32_t mgmtTx; ///< Management message TX counter + uint32_t mgmtPerSecTx; ///< Management message TX counter + uint32_t mgmtErr; ///< Management error counter (RX) + uint32_t annReceptTout; ///< Announce receipt timeout count + + uint32_t numUcConn; ///< Number of current Unicast client connections + uint32_t maxNumUcConn; ///< Maximum Number of Unicast client connections (due to licence or CPU performance) + uint32_t numMsgPerSec; ///< Number of all messages per second (TX/RX) + uint32_t maxMsgPerSec; ///< Max. allowed number of all messages per second in Multicast/Hybrid mode (due to licence or CPU performance) + +} MBG_PTP_STATISTICS_STATUS; + + + +enum PTP_V1_COMM_IDS +{ + V1_PTP_CLOSED, + V1_PTP_ETHER, + /* reserved */ + V1_PTP_FFBUS = 4, + V1_PTP_PROFIBUS, + V1_PTP_LON, + V1_PTP_DNET, + V1_PTP_SDS, + V1_PTP_CONTROLNET, + V1_PTP_CANOPEN, + /* reserved */ + V1_PTP_IEEE1394 = 243, + V1_PTP_IEEE802_11A, + V1_PTP_IEEE_WIRELESS, + V1_PTP_INFINIBAND, + V1_PTP_BLUETOOTH, + V1_PTP_IEEE802_15_1, + V1_PTP_IEEE1451_3, + V1_PTP_IEEE1451_5, + V1_PTP_USB, + V1_PTP_ISA, + V1_PTP_PCI, + V1_PTP_VXI, + V1_PTP_DEFAULT +}; + + + +#define PTP_CODE_STRING_LENGTH 4 +#define PTP_SUBDOMAIN_NAME_LENGTH 16 + + +/** + * @brief PTPv1 UUID structure used in ::MBG_PTP_V1_DEFAULT_DATASET + * + * @see ::MBG_PTP_V1_DEFAULT_DATASET + */ +typedef struct +{ + uint8_t communication_technology; + uint8_t reserved_1; + uint16_t reserved_2; + PTP_CLOCK_ID clock_uuid; + PTP_PORT_ID port_id; + uint16_t reserved_3; + +} PTP_V1_UUID; + + +#define _mbg_swab_ptp_v1_uuid( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab_ptp_clock_id( &(_p)->clock_uuid ); \ + _mbg_swab_ptp_port_id( &(_p)->port_id ); \ + _mbg_swab16( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 default dataset flags + * + * @see ::PTP_V1_DEFAULT_DATASET_FLAGS_MASKS + */ +enum PTP_V1_DEFAULT_DATASET_FLAGS +{ + V1_DFLT_CLK_FOLLOWUP_CAPABLE, + V1_DFLT_PREFERRED, + V1_DFLT_INITIALIZABLE, + V1_DFLT_EXT_TIMING, + V1_DFLT_IS_BC +}; + + + +/** + * @brief PTPv1 default dataset flag masks used with ::MBG_PTP_V1_DEFAULT_DATASET::flags + * + * @see ::PTP_V1_DEFAULT_DATASET_FLAGS + */ +enum PTP_V1_DEFAULT_DATASET_FLAGS_MASKS +{ + V1_DFLT_MSK_CLK_FOLLOWUP_CAPABLE = ( 1UL << V1_DFLT_CLK_FOLLOWUP_CAPABLE ), ///< See ::V1_DFLT_CLK_FOLLOWUP_CAPABLE + V1_DFLT_MSK_PREFERRED = ( 1UL << V1_DFLT_PREFERRED ), ///< See ::V1_DFLT_PREFERRED + V1_DFLT_MSK_INITIALIZABLE = ( 1UL << V1_DFLT_INITIALIZABLE ), ///< See ::V1_DFLT_INITIALIZABLE + V1_DFLT_MSK_EXT_TIMING = ( 1UL << V1_DFLT_EXT_TIMING), ///< See ::V1_DFLT_EXT_TIMING + V1_DFLT_MSK_IS_BC = ( 1UL << V1_DFLT_IS_BC ) ///< See ::V1_DFLT_IS_BC +}; + + +/** + * @brief PTPv1 default dataset containing global information about the device + * + * @see ::PTP_V1_UUID + */ +typedef struct { + PTP_V1_UUID uuid; + uint8_t clock_stratum; + uint8_t clock_identifier[PTP_CODE_STRING_LENGTH]; + uint16_t clock_variance; + int8_t sync_interval; + uint8_t subdomain_name[PTP_SUBDOMAIN_NAME_LENGTH]; + uint16_t number_ports; + uint16_t number_foreign_records; + uint32_t flags; + +} MBG_PTP_V1_DEFAULT_DATASET; + + +#define _mbg_swab_ptp_v1_default_dataset( _p ) \ +do \ +{ \ + _mbg_swab_ptp_v1_uuid( &(_p)->uuid ); \ + _mbg_swab16( &(_p)->clock_variance ); \ + _mbg_swab16( &(_p)->number_ports ); \ + _mbg_swab16( &(_p)->number_foreign_records ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 current dataset containing information about the synchronization status of the device + */ +typedef struct +{ + uint16_t steps_removed; + uint16_t reserved_1; + NANO_TIME offset_from_master; + NANO_TIME one_way_delay; + +} MBG_PTP_V1_CURRENT_DATASET; + + +#define _mbg_swab_ptp_v1_current_dataset( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->steps_removed ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab_nano_time( &(_p)->offset_from_master ); \ + _mbg_swab_nano_time( &(_p)->one_way_delay ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 parent dataset flags + * + * @see ::PTP_V1_PARENT_DATASET_FLAGS_MASKS + */ +enum PTP_V1_PARENT_DATASET_FLAGS +{ + V1_PARENT_FOLLOWUP_CAPABLE, + V1_PARENT_EXT_TIMING, + V1_PARENT_STATS, + V1_PARENT_UTC_REASONABLE, + V1_PARENT_GM_PREFERRED, + V1_PARENT_GM_IS_BC +}; + + + +/** + * @brief PTPv1 parent dataset flag masks used with ::MBG_PTP_V1_PARENT_DATASET::flags + * + * @see ::PTP_V1_PARENT_DATASET_FLAGS + */ +enum PTP_V1_PARENT_DATASET_FLAGS_MASKS +{ + V1_PARENT_MSK_FOLLOWUP_CAPABLE = ( 1UL << V1_PARENT_FOLLOWUP_CAPABLE ), ///< See ::V1_PARENT_FOLLOWUP_CAPABLE + V1_PARENT_MSK_EXT_TIMING = ( 1UL << V1_PARENT_EXT_TIMING ), ///< See ::V1_PARENT_EXT_TIMING + V1_PARENT_MSK_STATS = ( 1UL << V1_PARENT_STATS ), ///< See ::V1_PARENT_STATS + V1_PARENT_MSK_UTC_REASONABLE = ( 1UL << V1_PARENT_UTC_REASONABLE ), ///< See ::V1_PARENT_UTC_REASONABLE + V1_PARENT_MSK_GM_PREFERRED = ( 1UL << V1_PARENT_GM_PREFERRED ), ///< See ::V1_PARENT_GM_PREFERRED + V1_PARENT_MSK_GM_IS_BC = ( 1UL << V1_PARENT_GM_IS_BC ) ///< See ::V1_PARENT_GM_IS_BC +}; + + + +/** + * @brief PTPv1 parent dataset containing information about the master (parent) of the device + * + * @see ::PTP_V1_UUID + */ +typedef struct +{ + PTP_V1_UUID uuid; + uint16_t parent_last_sync_sequence_number; + int16_t parent_variance; + int16_t observed_variance; + uint16_t reserved_1; + int32_t observed_drift; + PTP_V1_UUID grandmaster_uuid; + uint8_t grandmaster_stratum; + uint8_t grandmaster_identifier[PTP_CODE_STRING_LENGTH]; + int16_t grandmaster_variance; + uint16_t grandmaster_sequence_number; + uint16_t reserved_2; + uint32_t flags; ///< See ::PTP_V1_PARENT_DATASET_FLAGS_MASKS + +} MBG_PTP_V1_PARENT_DATASET; + + +#define _mbg_swab_ptp_v1_parent_dataset( _p ) \ +do \ +{ \ + _mbg_swab_ptp_v1_uuid( &(_p)->uuid ); \ + _mbg_swab16( &(_p)->parent_last_sync_sequence_number ); \ + _mbg_swab16( &(_p)->parent_variance ); \ + _mbg_swab16( &(_p)->observed_variance ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->observed_drift ); \ + _mbg_swab_ptp_v1_uuid( &(_p)->grandmaster_uuid ); \ + _mbg_swab16( &(_p)->grandmaster_variance ); \ + _mbg_swab16( &(_p)->grandmaster_sequence_number ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 time drop dataset flags + * + * @see ::PTP_V1_TIME_PROP_DATASET_FLAGS_MASKS + */ +enum PTP_V1_TIME_PROP_DATASET_DATASET_FLAGS +{ + V1_TPROP_LEAP_59, + V1_TPROP_LEAP_61 +}; + + + +/** + * @brief PTPv1 time drop dataset flag masks used with ::MBG_PTP_V1_TIME_PROPERTIES_DATASET::flags + * + * @see ::PTP_V1_TIME_PROP_DATASET_DATASET_FLAGS + */ +enum PTP_V1_TIME_PROP_DATASET_FLAGS_MASKS +{ + V1_TPROP_MSK_LEAP_59 = ( 1UL << V1_TPROP_LEAP_59 ), ///< See ::V1_TPROP_LEAP_59 + V1_TPROP_MSK_LEAP_61 = ( 1UL << V1_TPROP_LEAP_61 ) ///< See ::V1_TPROP_LEAP_61 +}; + + + +/** + * @brief PTPv1 time drop dataset + * + */ +typedef struct +{ + int16_t current_utc_offset; + uint16_t epoch_number; + uint32_t flags; ///< See ::PTP_V1_TIME_PROP_DATASET_FLAGS_MASKS + +} MBG_PTP_V1_TIME_PROPERTIES_DATASET; + + +#define _mbg_swab_ptp_v1_time_properties_dataset( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->current_utc_offset ); \ + _mbg_swab16( &(_p)->epoch_number ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief PTPv1 port dataset flags + * + * @see ::PTP_V1_PORT_DATASET_FLAGS_MASKS + */ +enum PTP_V1_PORT_DATASET_DATASET_FLAGS +{ + V1_PORT_DATASET_BURST_ENB, +}; + + + +/** + * @brief PTPv1 port dataset flag masks used with ::MBG_PTP_V1_PORT_DATASET::flags + * + * @see ::PTP_V1_PORT_DATASET_DATASET_FLAGS + */ +enum PTP_V1_PORT_DATASET_FLAGS_MASKS +{ + V1_PORT_DATASET_MSK_BURST_ENB = ( 1UL << V1_PORT_DATASET_BURST_ENB ), ///< See ::V1_PORT_DATASET_BURST_ENB +}; + + + +/** + * @brief PTPv1 port dataset containing information about the appropriate port of the device + * + * @see ::PTP_V1_UUID + */ +typedef struct +{ + uint8_t port_state; + uint8_t reserved_1; + uint16_t last_sync_event_sequence_number; + uint16_t last_general_event_sequence_number; + uint16_t reserved_2; + uint32_t subdomain_address; + uint16_t event_port_address; + uint16_t general_port_address; + PTP_V1_UUID uuid; + uint32_t flags; +} MBG_PTP_V1_PORT_DATASET; + + +#define _mbg_swab_ptp_v1_port_dataset( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->last_sync_event_sequence_number ); \ + _mbg_swab16( &(_p)->last_general_event_sequence_number ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->subdomain_address ); \ + _mbg_swab16( &(_p)->event_port_address ); \ + _mbg_swab16( &(_p)->general_port_address ); \ + _mbg_swab_ptp_v1_uuid( &(_p)->uuid ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Index structure for PTPv1 port dataset + * + * @note Port datasets with index 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports-1 can be queried from a device. + * + * @see ::MBG_PTP_V1_PORT_DATASET + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< Index of the port dataset, 0..::MBG_PTP_V1_DEFAULT_DATASET::number_ports-1. + MBG_PTP_V1_PORT_DATASET port_dataset; ///< See ::MBG_PTP_V1_PORT_DATASET. + +} MBG_PTP_V1_PORT_DATASET_IDX; + + +#define _mbg_swab_ptp_v1_port_dataset_idx( _p ) \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ptp_v1_port_dataset( &(_p)->port_dataset ); \ +} + + +#define OMIT_PTPV2 1 + +#if !OMIT_PTPV2 + +/** + * @brief Flags structure for the PTPv2 default dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.1 and 15.5.3.3.1 + * + * @see ::MBG_PTP_V2_DEFAULT_DATASET + */ +typedef struct +{ + uint8_t two_step : 1; ///< indicates, whether the clock is a two-step clock + uint8_t slave_only : 1; ///< indicates, whether the clock is a slave-only clock + uint8_t reserved : 6; ///< reserved, currently always 0 + +} MBG_PTP_V2_DEFAULT_DATASET_FLAGS; + +#define _mbg_swab_ptp_v2_default_dataset_flags( _p ) \ + _nop_macro_fnc() + + +/** + * @brief PTPv2 default dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.1 and 15.5.3.3.1 + * + * @see ::MBG_PTP_V2_DEFAULT_DATASET_FLAGS + * @see ::PTP_CLOCK_QUALITY + * @see ::PTP_CLOCK_ID + */ +typedef struct +{ + MBG_PTP_V2_DEFAULT_DATASET_FLAGS flags; ///< flags field, see ::MBG_PTP_V2_DEFAULT_DATASET_FLAGS + uint8_t reserved_1; ///< reserved, currently always 0 + uint16_t number_ports; ///< number of PTP ports on the device + uint8_t priority_1; ///< priority 1 attribute for the local clock + PTP_CLOCK_QUALITY clock_quality; ///< quality of the local clock, see ::PTP_CLOCK_QUALITY + uint8_t priority_2; ///< priority 2 attribute for the local clock + PTP_CLOCK_ID clock_identity; ///< identity of the local clock, see ::PTP_CLOCK_ID + uint8_t domain_number; ///< domain attribute of the local clock + uint8_t reserved_2; ///< reserved, currently always 0 + +} MBG_PTP_V2_DEFAULT_DATASET; + + +#define _mbg_swab_ptp_v2_default_dataset( _p ) \ +{ \ + _mbg_swab_ptp_v2_default_dataset_flags( &(_p)->flags ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab16( &(_p)->number_ports ); \ + _mbg_swab8( &(_p)->priority_1 ); \ + _mbg_swab_ptp_clock_quality( &(_p)->clock_quality ); \ + _mbg_swab8( &(_p)->priority_2 ); \ + _mbg_swab_ptp_clock_id( &(_p)->clock_identity ); \ + _mbg_swab8( &(_p)->domain_number ); \ + _mbg_swab8( &(_p)->reserved_2 ); \ +} + +#endif // OMIT_PTPV2 + + + +/** + * @brief Flags for the PTPv2 NG default dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.1 and 15.5.3.3.1 + * + * @see ::MBG_PTP_V2_DEFAULT_DATASET + */ +enum MBG_PTP_V2_NG_DFLT_DS_FLAGS +{ + MBG_PTP_V2_NG_DFLT_DS_FLAG_TWO_STEP, + MBG_PTP_V2_NG_DFLT_DS_FLAG_SLAVE_ONLY, + N_MBG_PTP_V2_NG_DFLT_DS_FLAGS + +}; + +enum MBG_PTP_V2_NG_DFLT_DS_FLAG_MASKS +{ + MBG_PTP_V2_NG_DFLT_DS_FLAG_MSK_TWO_STEP = ( 1UL << MBG_PTP_V2_NG_DFLT_DS_FLAG_TWO_STEP), + MBG_PTP_V2_NG_DFLT_DS_FLAG_MSK_SLAVE_ONLY = ( 1UL << MBG_PTP_V2_NG_DFLT_DS_FLAG_SLAVE_ONLY) +}; + +/** + * @brief PTPv2 default dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.1 and 15.5.3.3.1 + * + * @see ::MBG_PTP_V2_DEFAULT_DATASET_FLAGS + * @see ::PTP_CLOCK_QUALITY + * @see ::PTP_CLOCK_ID + */ +typedef struct mbg_ptp_v2_ng_default_dataset_s +{ + uint8_t flags; ///< flags field, see ::MBG_PTP_V2_NG_DFLT_DS_FLAGS + uint8_t reserved_1; ///< reserved, currently always 0 + uint16_t number_ports; ///< number of PTP ports on the device + PTP_CLOCK_QUALITY clock_quality; ///< quality of the local clock, see ::PTP_CLOCK_QUALITY + uint8_t priority_1; ///< priority 1 attribute for the local clock + uint8_t priority_2; ///< priority 2 attribute for the local clock + uint8_t domain_number; ///< domain attribute of the local clock + uint8_t reserved_2; ///< reserved, currently always 0 + uint32_t reserved_3; + PTP_CLOCK_ID clock_identity; ///< identity of the local clock, see ::PTP_CLOCK_ID + +} MBG_PTP_V2_NG_DEFAULT_DATASET; + + +#define _mbg_swab_ptp_v2_ng_default_dataset( _p ) \ +{ \ + _mbg_swab16( &(_p)->number_ports ); \ + _mbg_swab_ptp_clock_quality( &(_p)->clock_quality ); \ + _mbg_swab_ptp_clock_id( &(_p)->clock_identity ); \ +} + + +/** + * @brief PTPv2 current dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.2 and 15.5.3.4.1 + * + * @see ::PTP_TIME_INTERVAL + */ +typedef struct +{ + uint16_t steps_removed; ///< number of communication paths between local clock and grandmaster + PTP_TIME_INTERVAL offset_from_master; ///< current time difference between master and slave, see ::PTP_TIME_INTERVAL + PTP_TIME_INTERVAL mean_path_delay; ///< current mean propagation time between master and slave, see ::PTP_TIME_INTERVAL + +} MBG_PTP_V2_CURRENT_DATASET; + + +#define _mbg_swab_ptp_v2_current_dataset( _p ) \ +{ \ + _mbg_swab16( &(_p)->steps_removed ); \ + _mbg_swab_ptp_time_interval( &(_p)->offset_from_master ); \ + _mbg_swab_ptp_time_interval( &(_p)->mean_path_delay ); \ +} + + + +/** + * @brief PTPv2 current dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.2 and 15.5.3.4.1 + * + * @see ::PTP_TIME_INTERVAL + */ +typedef struct mbg_ptp_v2_ng_current_dataset_s +{ + PTP_TIME_INTERVAL offset_from_master; ///< current time difference between master and slave, see ::PTP_TIME_INTERVAL + PTP_TIME_INTERVAL mean_path_delay; ///< current mean propagation time between master and slave, see ::PTP_TIME_INTERVAL + uint16_t steps_removed; ///< number of communication paths between local clock and grandmaster + uint16_t reserved_1; + uint32_t reserved_2; +} MBG_PTP_V2_NG_CURRENT_DATASET; + + +#define _mbg_swab_ptp_v2_ng_current_dataset( _p ) \ +{ \ + _mbg_swab_ptp_time_interval( &(_p)->offset_from_master ); \ + _mbg_swab_ptp_time_interval( &(_p)->mean_path_delay ); \ + _mbg_swab16( &(_p)->steps_removed ); \ +} + + + +#if !OMIT_PTPV2 + +/** + * @brief Flags structure for the PTPv2 parent dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.3.3 and 15.5.3.5.1.2 + * + * @see ::MBG_PTP_V2_PARENT_DATASET + */ +typedef struct +{ + uint8_t parent_stats : 1; ///< indicates whether the variance and change rate values are valid + uint8_t reserved : 7; ///< reserved, currently always 0 + +} MBG_PTP_V2_PARENT_DATASET_FLAGS; + +#define _mbg_swab_ptp_v2_parent_dataset_flags( _p )\ + _nop_macro_fnc() + + +/** + * @brief PTPv2 parent dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.3 and 15.5.3.5.1 + * + * @see ::PTP_PORT_IDENTITY + * @see ::MBG_PTP_V2_PARENT_DATASET_FLAGS + * @see ::PTP_CLOCK_QUALITY + * @see ::PTP_CLOCK_ID + */ +typedef struct +{ + PTP_PORT_IDENTITY parent_port_identity; ///< Identity of the master port, that issues the sync messages, see ::PTP_PORT_IDENTITY + MBG_PTP_V2_PARENT_DATASET_FLAGS flags; ///< Flags field, see ::MBG_PTP_V2_PARENT_DATASET_FLAGS + uint8_t reserved; ///< Reserved, currently always 0 + uint16_t parent_log_variance; ///< Estimate of the PTP variance of the parent clock. Only valid if + ///< ::MBG_PTP_V2_PARENT_DATASET_FLAGS::parent_stats is set in ::MBG_PTP_V2_PARENT_DATASET::flags. + int32_t parent_phase_change_rate; ///< Estimate of the phase change rate of the parent clock. Only valid if + ///< ::MBG_PTP_V2_PARENT_DATASET_FLAGS::parent_stats is set in ::MBG_PTP_V2_PARENT_DATASET::flags. + uint8_t grandmaster_priority_1; ///< Priority 1 attribute of the grandmaster clock. + PTP_CLOCK_QUALITY grandmaster_clock_quality; ///< Quality of the grandmaster clock, see ::PTP_CLOCK_QUALITY. + uint8_t grandmaster_priority_2; ///< Priority 2 attribute of the grandmaster clock. + PTP_CLOCK_ID grandmaster_identity; ///< Identity of the grandmaster clock, see ::PTP_CLOCK_ID. + +} MBG_PTP_V2_PARENT_DATASET; + + +#define _mbg_swab_ptp_v2_parent_dataset( _p ) \ +{ \ + _mbg_swab_ptp_port_identity( &(_p)->parent_port_identity ); \ + _mbg_swab_ptp_v2_parent_dataset_flags( &(_p)->flags ); \ + _mbg_swab8( &(_p)->reserved ); \ + _mbg_swab16( &(_p)->parent_log_variance ); \ + _mbg_swab32( &(_p)->parent_phase_change_rate ); \ + _mbg_swab8( &(_p)->grandmaster_priority_1 ); \ + _mbg_swab_ptp_clock_quality( &(_p)->grandmaster_clock_quality ); \ + _mbg_swab8( &(_p)->grandmaster_priority_2 ); \ + _mbg_swab_ptp_clock_id( &(_p)->grandmaster_identity ); \ +} + +#endif // !OMIT_PTPV2 + + + +/** + * @brief Flags structure for the PTPv2 NG parent dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.3.3 and 15.5.3.5.1.2 + * + * @see ::MBG_PTP_V2_NG_PARENT_DATASET + */ +enum MBG_PTP_V2_NG_PARENT_DATASET_FLAGS +{ + MBG_PTP_V2_NG_PARENT_DS_FLAG_PARENT_STATS, + N_MBG_PTP_V2_NG_PARENT_DS_FLAGS +}; + +enum MBG_PTP_V2_NG_PARENT_DATASET_FLAG_MASKS +{ + MBG_PTP_V2_NG_PARENT_DS_FLAG_MSK_PARENT_STATS = ( 1UL << MBG_PTP_V2_NG_PARENT_DS_FLAG_PARENT_STATS), +}; + +/** + * @brief PTPv2 NG parent dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.3 and 15.5.3.5.1 + * + * @see ::PTP_NG_PORT_IDENTITY + * @see ::MBG_PTP_V2_NG_PARENT_DATASET_FLAGS + * @see ::PTP_CLOCK_QUALITY + * @see ::PTP_CLOCK_ID + */ +typedef struct mbg_ptp_v2_ng_parent_dataset_s +{ + PTP_NG_PORT_IDENTITY parent_port_identity; ///< Identity of the master port, that issues the sync messages, see ::PTP_NG_PORT_IDENTITY. + uint8_t flags; ///< Flags field, see ::MBG_PTP_V2_NG_PARENT_DATASET_FLAGS. + uint8_t reserved_1; ///< Reserved, currently always 0. + uint16_t parent_log_variance; ///< Estimate of the PTP variance of the parent clock, only valid if + ///< ::MBG_PTP_V2_NG_PARENT_DS_FLAG_MSK_PARENT_STATS is set. + int32_t parent_phase_change_rate; ///< Estimate of the phase change rate of the parent clock, only valid if + ///< ::MBG_PTP_V2_NG_PARENT_DS_FLAG_MSK_PARENT_STATS is set. + PTP_CLOCK_QUALITY grandmaster_clock_quality; ///< Quality of the grandmaster clock, see ::PTP_CLOCK_QUALITY. + uint8_t grandmaster_priority_1; ///< Priority 1 attribute of the grandmaster clock. + uint8_t grandmaster_priority_2; ///< Priority 2 attribute of the grandmaster clock. + uint16_t reserved_2; + PTP_CLOCK_ID grandmaster_identity; ///< Identity of the grandmaster clock, see ::PTP_CLOCK_ID. + +} MBG_PTP_V2_NG_PARENT_DATASET; + + +#define _mbg_swab_ptp_v2_ng_parent_dataset( _p ) \ +{ \ + _mbg_swab_ptp_ng_port_identity( &(_p)->parent_port_identity ); \ + _mbg_swab16( &(_p)->parent_log_variance ); \ + _mbg_swab32( &(_p)->parent_phase_change_rate ); \ + _mbg_swab_ptp_clock_quality( &(_p)->grandmaster_clock_quality ); \ + _mbg_swab_ptp_clock_id( &(_p)->grandmaster_identity ); \ +} + + +#if !OMIT_PTPV2 + +/** + * @brief Flags structure for the PTPv2 time properties dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.4 and 15.5.3.6.1 + * + * @see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET + */ +typedef struct +{ + uint8_t leap_61 : 1; ///< set, if the last minute of the current %UTC day has 61 seconds + uint8_t leap_59 : 1; ///< set, if the last minute of the current %UTC day has 59 seconds + uint8_t utc_offset_valid : 1; ///< set, if the current %UTC offset is known to be correct + uint8_t ptp_timescale : 1; ///< set, if the timescale of the grandmaster clock is PTP + uint8_t time_traceable : 1; ///< set, if timescale and %UTC offset are traceable to a primary reference + uint8_t frequency_traceable : 1; ///< set, if the frequency determining the timescale is traceable to a primary reference + uint8_t reserved : 2; ///< reserved, currently always 0 + +} MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS; + + +#define _mbg_swab_ptp_v2_time_properties_dataset_flags( _p ) \ + _nop_macro_fnc() + + + +/** + * @brief PTPv2 time properties dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.4 and 15.5.3.6.1 + * + * @see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS + */ +typedef struct +{ + int16_t current_utc_offset; ///< offset between TAI and %UTC in seconds + MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS flags; ///< flags field, see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS + uint8_t time_source; ///< source of time used by the grandmaster clock, see ::PTP_TIME_SOURCES + +} MBG_PTP_V2_TIME_PROPERTIES_DATASET; + + +#define _mbg_swab_ptp_v2_time_properties_dataset( _p ) \ +{ \ + _mbg_swab16( &(_p)->current_utc_offset ); \ + _mbg_swab_ptp_v2_time_properties_dataset_flags( &(_p)->flags ); \ + _mbg_swab8( &(_p)->time_source ); \ +} + +#endif // !OMIT_PTPV2 + + +enum MBG_PTP_V2_NG_TIME_PROPERTIES_DATASET_FLAGS +{ + MBG_PTP_V2_NG_TPROP_DS_FLAG_LEAP_61, + MBG_PTP_V2_NG_TPROP_DS_FLAG_LEAP_59, + MBG_PTP_V2_NG_TPROP_DS_FLAG_UTC_OFFSET_VALID, + MBG_PTP_V2_NG_TPROP_DS_FLAG_PTP_TIMESCALE, + MBG_PTP_V2_NG_TPROP_DS_FLAG_TIME_TRACEABLE, + MBG_PTP_V2_NG_TPROP_DS_FLAG_FREQUENCY_TRACEABLE, + N_MBG_PTP_V2_NG_TPROP_DS_FLAGS +}; + +enum MBG_PTP_V2_NG_TIME_PROPERTIES_DATASET_FLAG_MASKS +{ + MBG_PTP_V2_NG_TPROP_DS_FLAG_MSK_LEAP_61 = ( 1UL << MBG_PTP_V2_NG_TPROP_DS_FLAG_LEAP_61), + MBG_PTP_V2_NG_TPROP_DS_FLAG_MSK_LEAP_59 = ( 1UL << MBG_PTP_V2_NG_TPROP_DS_FLAG_LEAP_59), + MBG_PTP_V2_NG_TPROP_DS_FLAG_MSK_UTC_OFFSET_VALID = ( 1UL << MBG_PTP_V2_NG_TPROP_DS_FLAG_UTC_OFFSET_VALID), + MBG_PTP_V2_NG_TPROP_DS_FLAG_MSK_PTP_TIMESCALE = ( 1UL << MBG_PTP_V2_NG_TPROP_DS_FLAG_PTP_TIMESCALE), + MBG_PTP_V2_NG_TPROP_DS_FLAG_MSK_TIME_TRACEABLE = ( 1UL << MBG_PTP_V2_NG_TPROP_DS_FLAG_TIME_TRACEABLE), + MBG_PTP_V2_NG_TPROP_DS_FLAG_MSK_FREQUENCY_TRACEABLE = ( 1UL << MBG_PTP_V2_NG_TPROP_DS_FLAG_FREQUENCY_TRACEABLE) +}; + + +/** + * @brief PTPv2 time properties dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.4 and 15.5.3.6.1 + * + * @see ::MBG_PTP_V2_TIME_PROPERTIES_DATASET_FLAGS + */ +typedef struct mbg_ptp_v2_ng_time_properties_dataset_s +{ + int16_t current_utc_offset; ///< offset between TAI and %UTC in seconds + uint8_t flags; ///< flags field, see ::MBG_PTP_V2_NG_TIME_PROPERTIES_DATASET_FLAGS + uint8_t time_source; ///< source of time used by the grandmaster clock, see ::PTP_TIME_SOURCES + uint32_t reserved; +} MBG_PTP_V2_NG_TIME_PROPERTIES_DATASET; + + +#define _mbg_swab_ptp_v2_ng_time_properties_dataset( _p ) \ +{ \ + _mbg_swab16( &(_p)->current_utc_offset ); \ +} + + +#if !OMIT_PTPV2 + +/** + * @brief PTPv2 port dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.5 and 15.5.3.7.1 + * + * @see ::PTP_PORT_IDENTITY + * @see ::PTP_TIME_INTERVAL + * @see ::MBG_PTP_V2_PORT_DATASET_IDX + */ +typedef struct +{ + PTP_PORT_IDENTITY port_identity; ///< identity of the local port, see ::PTP_PORT_IDENTITY + uint8_t port_state; ///< state of the protocol engine associated with this port, see ::PTP_PORT_STATES + int8_t log_min_delay_req_interval; ///< minimum delay request interval for this port + PTP_TIME_INTERVAL peer_mean_path_delay; ///< estimate of the current one-way propagation delay on the link, only valid if P2P is used, see ::PTP_TIME_INTERVAL + int8_t log_announce_interval; ///< announce interval to be used by this port + uint8_t announce_receipt_timeout; ///< shall be an integral multiple of ::MBG_PTP_V2_PORT_DATASET::log_announce_interval + int8_t log_sync_interval; ///< mean sync interval to be used for multicast messages + uint8_t delay_mechanism; ///< propagation delay measuring option, see ::PTP_DELAY_MECHS + int8_t log_min_pdelay_req_interval; ///< minimum peer delay request interval for this port + uint8_t version_number : 4; ///< PTP version in use on the port + uint8_t reserved : 4; ///< reserved, currently always 0 + +} MBG_PTP_V2_PORT_DATASET; + + +#define _mbg_swab_ptp_v2_port_dataset( _p ) \ +{ \ + _mbg_swab_ptp_port_identity( &(_p)->port_identity ); \ + _mbg_swab8( &(_p)->port_state ); \ + _mbg_swab8( &(_p)->log_min_delay_req_interval ); \ + _mbg_swab_ptp_time_interval( &(_p)->peer_mean_path_delay ); \ + _mbg_swab8( &(_p)->log_announce_interval ); \ + _mbg_swab8( &(_p)->announce_receipt_timeout ); \ + _mbg_swab8( &(_p)->log_sync_interval ); \ + _mbg_swab8( &(_p)->delay_mechanism ); \ + _mbg_swab8( &(_p)->log_min_pdelay_req_interval ); \ +} + +#endif // !OMIT_PTPV2 + + +typedef struct +{ + int8_t ann_intv; + int8_t sync_intv; + int8_t del_req_intv; + int8_t pdel_req_intv; + +} MBG_PTP_NG_INTV_CFG; + + +#define _mbg_swab_ptp_ng_intv_cfg( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->ann_intv ); \ + _mbg_swab8( &(_p)->sync_intv ); \ + _mbg_swab8( &(_p)->del_req_intv ); \ + _mbg_swab8( &(_p)->pdel_req_intv ); \ +} while ( 0 ) + + +/** + * @brief PTPv2 port dataset + * + * @note For further information, see IEEE 1588-2008, chapters 8.2.5 and 15.5.3.7.1 + * + * @see ::PTP_PORT_IDENTITY + * @see ::PTP_TIME_INTERVAL + * @see ::MBG_PTP_V2_PORT_DATASET_IDX + */ +typedef struct mbg_ptp_v2_ng_port_dataset_s +{ + PTP_TIME_INTERVAL peer_mean_path_delay; ///< estimate of the current one-way propagation delay on the link, only valid if P2P is used, see ::PTP_TIME_INTERVAL + PTP_NG_PORT_IDENTITY port_identity; ///< identity of the local port, see ::PTP_PORT_IDENTITY + MBG_PTP_NG_INTV_CFG intvs; ///< interval settings for this port, see ::MBG_PTP_NG_INTV_CFG + uint8_t port_state; ///< state of the protocol engine associated with this port, see ::PTP_PORT_STATES + uint8_t announce_receipt_timeout; ///< shall be an integral multiple of ::MBG_PTP_V2_PORT_DATASET::log_announce_interval + uint8_t delay_mechanism; ///< propagation delay measuring option, see ::PTP_DELAY_MECHS + uint8_t version_number; ///< PTP version in use on the port + +} MBG_PTP_V2_NG_PORT_DATASET; + + +#define _mbg_swab_ptp_v2_ng_port_dataset( _p ) \ +{ \ + _mbg_swab_ptp_time_interval( &(_p)->peer_mean_path_delay ); \ + _mbg_swab_ptp_ng_port_identity( &(_p)->port_identity ); \ + _mbg_swab_ptp_ng_intv_cfg( &(_p)->intvs ); \ +} + + +#if !OMIT_PTPV2 + +/** + * @brief Index structure for PTPv2 port dataset + * + * @note Port dataset with index 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports-1 can be queried from a device. + * + * @see ::MBG_PTP_V2_PORT_DATASET + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< Index of the port dataset, 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports-1. + MBG_PTP_V2_PORT_DATASET port_dataset; ///< See ::MBG_PTP_V2_PORT_DATASET. + +} MBG_PTP_V2_PORT_DATASET_IDX; + + +#define _mbg_swab_ptp_v2_port_dataset_idx( _p ) \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_ptp_v2_port_dataset( &(_p)->port_dataset ); \ +} + +#endif // !OMIT_PTPV2 + + +/** + * @brief Index structure for PTPv2 port dataset + * + * @note Port dataset with index 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1 can be queried from a device + * + * @see ::MBG_PTP_V2_PORT_DATASET + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; ///< Index of the port dataset, 0..::MBG_PTP_V2_DEFAULT_DATASET::number_ports - 1 + uint32_t reserved; + MBG_PTP_V2_NG_PORT_DATASET port_dataset; ///< See ::MBG_PTP_V2_PORT_DATASET + +} MBG_PTP_V2_NG_PORT_DATASET_IDX; + + +/** + * @defgroup group_ptp_ng Next gen structures and definitions used with PTP/IEEE1588 + * + * @{ */ + +typedef char PTP_INTF[MBG_IFNAMSIZ]; ///< interface name (IPv4/L2) or IPv6 address of logical interface linked to this config + + +/** + * @brief PTP version flags + * + * @see ::PTP_NG_VERSION_MASKS + */ +enum PTP_NG_VERSION_FLAGS +{ + PTP_NG_VERSION_1 = 0, + PTP_NG_VERSION_2, + PTP_NG_VERSION_2_1, + N_PTP_NG_VERSIONS +}; + + +/** + * @brief PTP version flag masks used with ::MBG_PTP_NG_GLB_INFO::supp_versions + * + * @see ::PTP_NG_VERSION_FLAGS + */ +enum PTP_NG_VERSION_MASKS +{ + PTP_NG_VERSION_1_MSK = ( 1UL << PTP_NG_VERSION_1 ), ///< See ::PTP_NG_VERSION_1 + PTP_NG_VERSION_2_MSK = ( 1UL << PTP_NG_VERSION_2 ), ///< See ::PTP_NG_VERSION_2 + PTP_NG_VERSION_2_1_MSK = ( 1UL << PTP_NG_VERSION_2_1 ) ///< See ::PTP_NG_VERSION_2_1 +}; + + +#define PTP_NG_VERSION_STRS \ +{ \ + "PTPv1", \ + "PTPv2", \ + "PTPv2.1" \ +} + + +enum MBG_PTP_NG_FLAGS +{ + MBG_PTP_NG_FLAG_ARB_TIMESCALE, ///< Use arbitrary timescale instead of default PTP (TAI) timescale + MBG_PTP_NG_FLAG_V1_HW_COMPATIBILITY, ///< V1 hardware compatibility is used (fill Sync Message with padding bytes) + MBG_PTP_NG_FLAG_BOUNDARY_CLOCK, ///< Indicates, that an instance is part of a boundary clock setup + MBG_PTP_NG_FLAG_SW_TSTAMPING, ///< No hardware timestamps are used + MBG_PTP_NG_FLAG_MANAGEMENT, ///< PTP Management Messages are enabled + MBG_PTP_NG_FLAG_NO_CLK_ADJ, ///< No Adjustment of the hardware clock in slave mode (measurement only) + MBG_PTP_NG_FLAG_PATH_TRACE, ///< Use path trace TLV + MBG_PTP_NG_FLAG_CUSTOM_PORT_ID, ///< A user-defined CLOCK IDENTITY is used for this PTP instance + MBG_PTP_NG_FLAG_FIXED_QUALITY, ///< A user-defined set of fixed BMCA parameters is configured + MBG_PTP_NG_FLAG_AUTHENTICATION, ///< Use authentication as used in PTP v2.1 + MBG_PTP_NG_FLAG_DELAY_ASYMMETRY, ///< Delay asymmetry configuration is supported + MBG_PTP_NG_FLAG_GLB_CLOCK_ID, ///< Use system-wide clock ID for all instances, otherwise use one ID per phys port + MBG_PTP_NG_FLAG_SERVO_SETTINGS, ///< User-defined servo settings, see ::MBG_PTP_NG_SERVO_SETTINGS + MBG_PTP_NG_FLAG_HYBRID_MODE, ///< Use hybrid mode (DelReq. in unicast) + MBG_PTP_NG_FLAG_PKT_CNTRS, ///< Indicates, that an instance supplies packet counters, see ::MBG_PTP_NG_INSTC_PKT_CNTRS + MBG_PTP_NG_FLAG_MIN_GM_CLK_QUALITY, ///< User-defined set of minimum clock quality parameters for synchronization + MBG_PTP_NG_FLAG_DISABLED, ///< Indicates, that an instance is temporarily disabled + N_MBG_PTP_NG_FLAGS +}; + + +enum MBG_PTP_NG_FLAG_MASKS +{ + MBG_PTP_NG_FLAG_ARB_TIMESCALE_MSK = ( 1UL << MBG_PTP_NG_FLAG_ARB_TIMESCALE ), ///< See ::MBG_PTP_NG_FLAG_ARB_TIMESCALE + MBG_PTP_NG_FLAG_V1_HW_COMPATIBILITY_MSK = ( 1UL << MBG_PTP_NG_FLAG_V1_HW_COMPATIBILITY ), ///< See ::MBG_PTP_NG_FLAG_V1_HW_COMPATIBILITY + MBG_PTP_NG_FLAG_BOUNDARY_CLOCK_MSK = ( 1UL << MBG_PTP_NG_FLAG_BOUNDARY_CLOCK ), ///< See ::MBG_PTP_NG_FLAG_BOUNDARY_CLOCK + MBG_PTP_NG_FLAG_SW_TSTAMPING_MSK = ( 1UL << MBG_PTP_NG_FLAG_SW_TSTAMPING ), ///< See ::MBG_PTP_NG_FLAG_SW_TSTAMPING + MBG_PTP_NG_FLAG_MANAGEMENT_MSK = ( 1UL << MBG_PTP_NG_FLAG_MANAGEMENT ), ///< See ::MBG_PTP_NG_FLAG_MANAGEMENT + MBG_PTP_NG_FLAG_NO_CLK_ADJ_MSK = ( 1UL << MBG_PTP_NG_FLAG_NO_CLK_ADJ ), ///< See ::MBG_PTP_NG_FLAG_NO_CLK_ADJ + MBG_PTP_NG_FLAG_PATH_TRACE_MSK = ( 1UL << MBG_PTP_NG_FLAG_PATH_TRACE ), ///< See ::MBG_PTP_NG_FLAG_PATH_TRACE + MBG_PTP_NG_FLAG_CUSTOM_PORT_ID_MSK = ( 1UL << MBG_PTP_NG_FLAG_CUSTOM_PORT_ID ), ///< See ::MBG_PTP_NG_FLAG_CUSTOM_PORT_ID + MBG_PTP_NG_FLAG_FIXED_QUALITY_MSK = ( 1UL << MBG_PTP_NG_FLAG_FIXED_QUALITY ), ///< See ::MBG_PTP_NG_FLAG_FIXED_QUALITY + MBG_PTP_NG_FLAG_AUTHENTICATION_MSK = ( 1UL << MBG_PTP_NG_FLAG_AUTHENTICATION ), ///< See ::MBG_PTP_NG_FLAG_AUTHENTICATION + MBG_PTP_NG_FLAG_DELAY_ASYMMETRY_MSK = ( 1UL << MBG_PTP_NG_FLAG_DELAY_ASYMMETRY ), ///< See ::MBG_PTP_NG_FLAG_DELAY_ASYMMETRY + MBG_PTP_NG_FLAG_GLB_CLOCK_ID_MSK = ( 1UL << MBG_PTP_NG_FLAG_GLB_CLOCK_ID ), ///< See ::MBG_PTP_NG_FLAG_GLB_CLOCK_ID + MBG_PTP_NG_FLAG_SERVO_SETTINGS_MSK = ( 1UL << MBG_PTP_NG_FLAG_SERVO_SETTINGS ), ///< See ::MBG_PTP_NG_FLAG_SERVO_SETTINGS + MBG_PTP_NG_FLAG_HYBRID_MODE_MSK = ( 1UL << MBG_PTP_NG_FLAG_HYBRID_MODE ), ///< See ::MBG_PTP_NG_FLAG_HYBRID_MODE + MBG_PTP_NG_FLAG_PKT_CNTRS_MSK = ( 1UL << MBG_PTP_NG_FLAG_PKT_CNTRS ), ///< See ::MBG_PTP_NG_FLAG_PKT_CNTRS + MBG_PTP_NG_FLAG_MIN_GM_CLK_QUALITY_MSK = ( 1UL << MBG_PTP_NG_FLAG_MIN_GM_CLK_QUALITY ), ///< See ::MBG_PTP_NG_FLAG_MIN_GM_CLK_QUALITY + MBG_PTP_NG_FLAG_DISABLED_MSK = ( 1UL << MBG_PTP_NG_FLAG_DISABLED ) ///< See ::MBG_PTP_NG_FLAG_DISABLED +}; + + +enum MBG_PTP_NG_V1_FLAGS +{ + MBG_PTP_NG_V1_FLAG_PREFERRED, ///< Set preferred flag in PTPv1 stack + MBG_PTP_NG_V1_FLAG_INITIALIZABLE, ///< Set initializable flag in PTPv1 stack + MBG_PTP_NG_V1_FLAG_EXT_TIMING, ///< Set external timing flag in PTPv1 stack + N_MBG_PTP_NG_V1_FLAGS +}; + + +enum MBG_PTP_NG_V1_FLAG_MASKS +{ + MBG_PTP_NG_V1_FLAG_PREFERRED_MSK = ( 1UL << MBG_PTP_NG_V1_FLAG_PREFERRED ), ///< See ::MBG_PTP_NG_V1_FLAG_PREFERRED + MBG_PTP_NG_V1_FLAG_INITIALIZABLE_MSK = ( 1UL << MBG_PTP_NG_V1_FLAG_INITIALIZABLE ), ///< See ::MBG_PTP_NG_V1_FLAG_INITIALIZABLE + MBG_PTP_NG_V1_FLAG_EXT_TIMING_MSK = ( 1UL << MBG_PTP_NG_V1_FLAG_EXT_TIMING ) ///< See ::MBG_PTP_NG_V1_FLAG_EXT_TIMING +}; + + +/** + * @brief Pre-defined alternate time offset indicators + */ +enum MBG_PTP_NG_ATOIS +{ + MBG_PTP_NG_ATOI_UTC, ///< %UTC (Coordinated Universal Time), meaning an almost empty ATOI (minimum requirement for C37.238-2011). + MBG_PTP_NG_ATOI_CUSTOM, ///< Custom, manually configured ATOI stored as ::TZDL structure. + MBG_PTP_NG_ATOI_CET_CEST, ///< CET/CEST (Central European (Summer) Time). + N_MBG_PTP_NG_ATOIS +}; + + +enum MBG_PTP_NG_ATOI_MASKS +{ + MBG_PTP_NG_ATOI_UTC_MSK = ( 1UL << MBG_PTP_NG_ATOI_UTC ), ///< See ::MBG_PTP_NG_ATOI_UTC + MBG_PTP_NG_ATOI_CUSTOM_MSK = ( 1UL << MBG_PTP_NG_ATOI_CUSTOM ), ///< See ::MBG_PTP_NG_ATOI_CUSTOM + MBG_PTP_NG_ATOI_CET_CEST_MSK = ( 1UL << MBG_PTP_NG_ATOI_CET_CEST ) ///< See ::MBG_PTP_NG_ATOI_CET_CEST +}; + + +#define MBG_PTP_NG_ATOI_SHORT_NAMES \ +{ \ + "UTC", \ + "Custom", \ + "CET/CEST" \ +} + + +#define MBG_PTP_NG_ATOI_NAMES \ +{ \ + "UTC (Coordinated Universal Time)", \ + "Custom", \ + "CET/CEST (Central European [Summer] Time)" \ +} + + + +/** + * @brief Predefined time scales for PTP SMPTE jam event times. + * + * Used with ::MBG_PTP_NG_SMPTE_20592_SETTINGS::event_timescale, + * and to define ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_MASKS. + * + * This is only relevant for the way the ***configuration is stored***, + * and the effective time sent in the SMPTE TLV has to be calculated + * by the appropriate time scale conversion. + * + * @see ::MBG_PTP_NG_SMPTE_20592_SETTINGS::event_timescale + * @see ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_MASKS + */ +enum MBG_PTP_NG_SMPTE_EVT_TIMESCALES +{ + /// @brief Time scale refers to local time. + /// + /// If the local time scale is used to configure the daily jam + /// then the jam occurs at exactly the same time, e.g. always + /// at 2 o'clock according to the configured time zone, regardless + /// whether DST is in effect, or not, and it is not affected by + /// another leap second that might be inserted at some point + /// during operation. + MBG_PTP_NG_SMPTE_EVT_TIMESCALE_LOCAL_TIME, + + /// @brief Time scale refers to %UTC. + /// + /// If %UTC is used for the configuration then the jam always occurs + /// at exactly the same %UTC time, which is not affected by another + /// leap second that might be inserted at some point during operation. + /// + /// However, the local time when the jam occurs depends on the + /// local time zone offset, and on the DST status of the + /// configured time zone. + /// + /// For example, if 3 o'clock %UTC has been configured and the + /// local time zone is CET/CEST (i.e. %UTC+1h/%UTC+2h), + /// the jam occurs at 4 o'clock while DST is not in effect, + /// and at 5 o'clock if DST is in effect. + MBG_PTP_NG_SMPTE_EVT_TIMESCALE_UTC, + + /// @brief Time scale refers to TAI. + /// + /// If the jam times are configured using the TAI time scale, + /// the effective local time sent in the SMPTE TLV depends on + /// the local time zone offset and DST status just as for + /// ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_UTC, but in addition + /// changes whenefer the TAI/%UTC offset changes due to + /// a leap second. + MBG_PTP_NG_SMPTE_EVT_TIMESCALE_TAI, + + /// @brief Time scale refers to GPS system time. + /// + /// Basically the same behavior as with ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_TAI, + /// except that an additional constant offset ::GPS_SEC_BIAS has to be + /// taken into account. + MBG_PTP_NG_SMPTE_EVT_TIMESCALE_GPS, + + ///< The number of predefined SMPTE event time scales. + N_MBG_PTP_NG_SMPTE_EVT_TIMESCALES +}; + + + +/** + * @brief Bit masks of predefined time scales for PTP SMPTE jam event times. + * + * Used with ::MBG_PTP_NG_GLB_INFO::supp_smpte_tscales. + * + * @see ::MBG_PTP_NG_SMPTE_EVT_TIMESCALES + */ +enum MBG_PTP_NG_SMPTE_EVT_TIMESCALE_MASKS +{ + MBG_PTP_NG_SMPTE_EVT_TIMESCALE_LOCAL_TIME_MSK = ( 1UL << MBG_PTP_NG_SMPTE_EVT_TIMESCALE_LOCAL_TIME ), ///< See ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_LOCAL_TIME. + MBG_PTP_NG_SMPTE_EVT_TIMESCALE_UTC_MSK = ( 1UL << MBG_PTP_NG_SMPTE_EVT_TIMESCALE_UTC ), ///< See ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_UTC. + MBG_PTP_NG_SMPTE_EVT_TIMESCALE_TAI_MSK = ( 1UL << MBG_PTP_NG_SMPTE_EVT_TIMESCALE_TAI ), ///< See ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_TAI. + MBG_PTP_NG_SMPTE_EVT_TIMESCALE_GPS_MSK = ( 1UL << MBG_PTP_NG_SMPTE_EVT_TIMESCALE_GPS ) ///< See ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_GPS. +}; + + +#define MBG_PTP_NG_SMPTE_EVT_TIMESCALE_STRS \ +{ \ + "PTP (TAI)", \ + "UTC", \ + "Local Time", \ + "GPS" \ +} + + +typedef struct +{ + uint16_t num_instances; ///< Number of currently configured PTP instances. + uint16_t num_uc_masters; ///< Total number of currently configured unicast masters. + uint32_t flags; ///< Current flags, see ::MBG_PTP_NG_FLAG_MASKS. + + uint32_t reserved_2[6]; ///< Reserved, currently always 0. + +} MBG_PTP_NG_GLB_SETTINGS; + + +#define _mbg_swab_ptp_ng_glb_settings( _p ) \ +{ \ + _mbg_swab16( &(_p)->num_instances ); \ + _mbg_swab16( &(_p)->num_uc_masters ); \ + _mbg_swab32( &(_p)->flags ); \ +} + + + +typedef struct mbg_ptp_ng_glb_info_s +{ + MBG_PTP_NG_GLB_SETTINGS settings; ///< The current global configuration for this firmware. + + PTP_CLOCK_ID system_clock_id; ///< System-wide global clock ID, which can be used by all instances. + ///< Only supp., if ::MBG_PTP_NG_FLAG_GLB_CLOCK_ID_MSK is set in ::MBG_PTP_NG_GLB_INFO::supp_flags. + ///< Only used, if ::MBG_PTP_NG_FLAG_GLB_CLOCK_ID_MSK is set in ::MBG_PTP_NG_GLB_SETTINGS::flags. + + uint16_t num_timestampers; ///< Total number of hardware timestampers for this firmware. + uint16_t max_instances; ///< Maximum number of PTP instances (software) for this firmware. + + uint16_t max_uc_masters; ///< Maximum number of uncast masters that can be configured in total for this firmware. + uint16_t max_instc_uc_masters; ///< Maximum number of unicast masters per instance. + + uint32_t supp_protocols; ///< Bitmask of supported network protocols, see ::PTP_NW_PROT_MASKS. + uint32_t supp_delay_mechs; ///< Bit mask of supported delay mechanisms, see ::PTP_DELAY_MECH_MASKS. + uint32_t supp_profiles; ///< Bit mask of supported PTP profiles, see ::PTP_PRESETS: + uint32_t supp_versions; ///< Bit mask of supported PTP protocol versions, see ::PTP_NG_VERSION_MASKS. + uint32_t supp_roles; ///< Bit mask of supported PTP roles, see ::PTP_ROLE_MASKS. + uint32_t supp_flags; ///< Bit mask of supported flags, see ::MBG_PTP_NG_FLAG_MASKS. + uint32_t supp_v1_flags; ///< Bit mask of supported PTPv1 flags, see ::MBG_PTP_NG_V1_FLAG_MASKS. + uint32_t supp_atois; ///< Bit mask of supported Alternate Time Offset Indicators (ATOIs), see ::MBG_PTP_NG_ATOI_MASKS. + + MBG_PTP_NG_INTV_CFG intvs_min; ///< log2 of minimum intervals [s] + MBG_PTP_NG_INTV_CFG intvs_max; ///< log2 of maximum intervals [s] + + uint16_t max_atois; ///< Maximum number of ATOIs that may be used in parallel, see ::MBG_PTP_NG_ATOI_MASKS. + uint16_t supp_smpte_tscales; ///< Bit mask of supported SMPTE event timescales, see ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_MASKS. + uint32_t reserved_2[7]; ///< Reserved, currently always 0. + +} MBG_PTP_NG_GLB_INFO; + + +#define _mbg_swab_ptp_ng_glb_info( _p ) \ +{ \ + _mbg_swab_ptp_ng_glb_settings( &(_p)->settings ); \ + _mbg_swab16( &(_p)->num_timestampers ); \ + _mbg_swab16( &(_p)->max_instances ); \ + _mbg_swab16( &(_p)->max_uc_masters ); \ + _mbg_swab16( &(_p)->max_instc_uc_masters ); \ + _mbg_swab32( &(_p)->supp_protocols ); \ + _mbg_swab32( &(_p)->supp_delay_mechs ); \ + _mbg_swab32( &(_p)->supp_profiles ); \ + _mbg_swab32( &(_p)->supp_versions ); \ + _mbg_swab32( &(_p)->supp_roles ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->supp_v1_flags ); \ + _mbg_swab32( &(_p)->supp_atois ); \ + _mbg_swab_ptp_ng_intv_cfg( &(_p)->intvs_min ); \ + _mbg_swab_ptp_ng_intv_cfg( &(_p)->intvs_max ); \ + _mbg_swab16( &(_p)->max_atois ); \ +} + + +typedef struct +{ + uint16_t sec_h; ///< Seconds (47:32) + uint16_t reserved_1; + uint32_t reserved_2; + uint32_t sec_l; ///< Seconds (31:0) + uint32_t nsec; ///< Nanoseconds + +} MBG_PTP_NG_TIMESTAMP; + + +#define _mbg_swab_ptp_ng_timestamp( _p ) \ +{ \ + _mbg_swab16( &(_p)->sec_h ); \ + _mbg_swab32( &(_p)->sec_l ); \ + _mbg_swab32( &(_p)->nsec ); \ +} + + +/** + * @brief PTP timestamper modes + * + * @see ::PTP_NG_TSTAMPER_MODE_MASKS + */ +enum PTP_NG_TSTAMPER_MODES +{ + PTP_NG_TSTAMPER_MODE_ALL, ///< Timestamp all incoming packets. + PTP_NG_TSTAMPER_MODE_NTP, ///< Timestamp only NTP packets. + PTP_NG_TSTAMPER_MODE_PTP_V1, ///< Timestamp only PTPv1 packets. + PTP_NG_TSTAMPER_MODE_PTP_V2, ///< Timestamp only PTPv2 (+2.1) packets. + N_PTP_NG_TSTAMPER_MODES +}; + + +/** + * @brief PTP timestamper mode masks used with ::MBG_PTP_NG_TSTAMPER_INFO::supp_modes + * + * @see ::PTP_NG_TSTAMPER_MODES + */ +enum PTP_NG_TSTAMPER_MODE_MASKS +{ + PTP_NG_TSTAMPER_MODE_ALL_MSK = ( 1UL << PTP_NG_TSTAMPER_MODE_ALL ), ///< See ::PTP_NG_TSTAMPER_MODE_ALL + PTP_NG_TSTAMPER_MODE_NTP_MSK = ( 1UL << PTP_NG_TSTAMPER_MODE_NTP ), ///< See ::PTP_NG_TSTAMPER_MODE_NTP + PTP_NG_TSTAMPER_MODE_PTP_V1_MSK = ( 1UL << PTP_NG_TSTAMPER_MODE_PTP_V1 ), ///< See ::PTP_NG_TSTAMPER_MODE_PTP_V1 + PTP_NG_TSTAMPER_MODE_PTP_V2_MSK = ( 1UL << PTP_NG_TSTAMPER_MODE_PTP_V2 ) ///< See ::PTP_NG_TSTAMPER_MODE_PTP_V2 +}; + + +#define PTP_NG_TSTAMPER_MODE_STRS \ +{ \ + "All", \ + "NTP", \ + "PTPv1", \ + "PTPv2" \ +} + + +/** + * @brief PTP timestamper flags + * + * @see ::PTP_NG_TSTAMPER_FLAG_MASKS + */ +enum PTP_NG_TSTAMPER_FLAGS +{ + PTP_NG_TSTAMPER_FLAG_ONE_STEP, ///< timestamp in one-step mode + PTP_NG_TSTAMPER_FLAG_PACKET_GENERATOR, ///< use packet generator to timestamp packets in hardware + PTP_NG_TSTAMPER_FLAG_HYBRID_MODE, ///< use hybrid mode (DelReq. in unicast), only when packet generator is enabled; + ///< otherwise hybrid mode can be enabled/disabled per software instance + PTP_NG_TSTAMPER_FLAG_ALL_DOMAINS, ///< timestamp PTP packets in all domains + PTP_NG_TSTAMPER_FLAG_ALL_PROTOCOLS, ///< timestamp PTP packets of all protocols + PTP_NG_TSTAMPER_FLAG_ALL_IPV6_SCOPES, ///< timestamp PTP packets in all IPv6 multicast scopes + PTP_NG_TSTAMPER_FLAG_SUPP_MULTIPLE_INSTCS, ///< timestamper supports multiple instances (VLANs), not configurable + PTP_NG_TSTAMPER_FLAG_SUPP_P2P_ONE_STEP, ///< timestamper supports P2P one-step mode, not configurable + N_PTP_NG_TSTAMPER_FLAGS +}; + + +/** + * @brief PTP timestamper flag masks used with ::MBG_PTP_NG_TSTAMPER_SETTINGS::flags and ::MBG_PTP_NG_TSTAMPER_INFO::supp_flags + * + * @see ::PTP_NG_TSTAMPER_FLAGS + */ +enum PTP_NG_TSTAMPER_FLAG_MASKS +{ + PTP_NG_TSTAMPER_FLAG_ONE_STEP_MSK = ( 1UL << PTP_NG_TSTAMPER_FLAG_ONE_STEP ), ///< See ::PTP_NG_TSTAMPER_FLAG_ONE_STEP + PTP_NG_TSTAMPER_FLAG_PACKET_GENERATOR_MSK = ( 1UL << PTP_NG_TSTAMPER_FLAG_PACKET_GENERATOR ), ///< See ::PTP_NG_TSTAMPER_FLAG_PACKET_GENERATOR + PTP_NG_TSTAMPER_FLAG_HYBRID_MODE_MSK = ( 1UL << PTP_NG_TSTAMPER_FLAG_HYBRID_MODE ), ///< See ::PTP_NG_TSTAMPER_FLAG_HYBRID_MODE + PTP_NG_TSTAMPER_FLAG_ALL_DOMAINS_MSK = ( 1UL << PTP_NG_TSTAMPER_FLAG_ALL_DOMAINS ), ///< See ::PTP_NG_TSTAMPER_FLAG_ALL_DOMAINS + PTP_NG_TSTAMPER_FLAG_ALL_PROTOCOLS_MSK = ( 1UL << PTP_NG_TSTAMPER_FLAG_ALL_PROTOCOLS ), ///< See ::PTP_NG_TSTAMPER_FLAG_ALL_PROTOCOLS + PTP_NG_TSTAMPER_FLAG_ALL_IPV6_SCOPES_MSK = ( 1UL << PTP_NG_TSTAMPER_FLAG_ALL_IPV6_SCOPES ), ///< See ::PTP_NG_TSTAMPER_FLAG_ALL_IPV6_SCOPES + PTP_NG_TSTAMPER_FLAG_SUPP_MULTIPLE_INSTCS_MSK = ( 1UL << PTP_NG_TSTAMPER_FLAG_SUPP_MULTIPLE_INSTCS ), ///< See ::PTP_NG_TSTAMPER_FLAG_SUPP_MULTIPLE_INSTCS + PTP_NG_TSTAMPER_FLAG_SUPP_P2P_ONE_STEP_MSK = ( 1UL << PTP_NG_TSTAMPER_FLAG_SUPP_P2P_ONE_STEP ) ///< See ::PTP_NG_TSTAMPER_FLAG_SUPP_P2P_ONE_STEP +}; + + +typedef struct mbg_ptp_ng_tstamper_settings_s +{ + uint8_t mode; ///< timestamper mode, see ::PTP_NG_TSTAMPER_MODES + uint8_t protocol; ///< current protocol, see ::PTP_NW_PROTS + uint8_t domain; ///< current PTPv2 domain number (0..255) + uint8_t ipv6_multicast_scope; ///< One of the ::IPV6_MULTICAST_SCOPES used for PTP IPv6 multicast. + + uint32_t flags; ///< See ::PTP_NG_TSTAMPER_FLAG_MASKS + + uint32_t reserved_2[6]; ///< reserved, currently always 0 + +} MBG_PTP_NG_TSTAMPER_SETTINGS; + + +#define _mbg_swab_ptp_ng_tstamper_settings( _p ) \ +{ \ + _mbg_swab32( &(_p)->flags ); \ +} + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t reserved; ///< padding for 8-byte alignment, some settings contain int64_t + MBG_PTP_NG_TSTAMPER_SETTINGS settings; + +} MBG_PTP_NG_TSTAMPER_SETTINGS_IDX; + + +#define _mbg_swab_ptp_ng_tstamper_settings_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_ng_tstamper_settings( &(_p)->settings ); \ +} + + +typedef struct mbg_ptp_ng_tstamper_info_s +{ + MBG_PTP_NG_TSTAMPER_SETTINGS settings; + + PTP_INTF phys_intf; ///< the physical interface name this timestamper belongs to + uint32_t supp_modes; ///< bitmask of supported timestamper modes, see ::PTP_NG_TSTAMPER_MODE_MASKS + uint32_t supp_protocols; ///< bitmask of supported network protocols, see ::PTP_NW_PROT_MASKS + uint32_t supp_roles; ///< bitmask of supported PTP roles on this timestamper, see ::PTP_ROLE_MASKS + uint32_t supp_flags; ///< bitmask of supported features, see ::PTP_NG_TSTAMPER_FLAG_MASKS + uint32_t max_ptp_packets; ///< Maximum number of PTP generated packets per second + uint32_t max_ntp_packets; ///< Maximum number of NTP generated packets per second + uint16_t max_ptp_uc_slaves; ///< Maximum number of PTP Unicast slaves + uint16_t reserved_1; ///< reserved, currently always 0 + + uint32_t reserved_2[5]; ///< reserved, currently always 0 + +} MBG_PTP_NG_TSTAMPER_INFO; + + +#define _mbg_swab_ptp_ng_tstamper_info( _p ) \ +{ \ + _mbg_swab_ptp_ng_tstamper_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_modes ); \ + _mbg_swab32( &(_p)->supp_protocols ); \ + _mbg_swab32( &(_p)->supp_roles ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t reserved; ///< padding for 8-byte alignment, some settings contain int64_t + MBG_PTP_NG_TSTAMPER_INFO info; + +} MBG_PTP_NG_TSTAMPER_INFO_IDX; + + +#define _mbg_swab_ptp_ng_tstamper_info_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_ng_tstamper_info( &(_p)->info ); \ +} + + +typedef struct mbg_ptp_ng_tstamper_status_s +{ + MBG_PTP_NG_TIMESTAMP current_time; ///< current tstamper time + PTP_TIME_INTERVAL offset_from_int_ref; ///< current offset between tstamper time and internal reference + uint8_t utilization; ///< current resource utilization (msg/sec) in % + uint8_t reserved_1[7]; ///< reserved, currently always 0 + + uint32_t reserved_2[12]; ///< reserved, currently always 0 + +} MBG_PTP_NG_TSTAMPER_STATUS; + + +#define _mbg_swab_ptp_ng_tstamper_status( _p ) \ +{ \ + _mbg_swab_ptp_ng_timestamp( &(_p)->current_time ); \ + _mbg_swab_ptp_time_interval( &(_p)->offset_from_int_ref ); \ +} + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t reserved; ///< padding for 8-byte alignment, some settings contain int64_t + MBG_PTP_NG_TSTAMPER_STATUS status; + +} MBG_PTP_NG_TSTAMPER_STATUS_IDX; + + +#define _mbg_swab_ptp_ng_tstamper_status_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_ng_tstamper_status( &(_p)->status ); \ +} + + +enum MBG_PTP_NG_SERVO_FLAGS +{ + MBG_PTP_NG_SERVO_FLAG_USE_IIR_FILTER, ///< TODO: Please add describing comment + MBG_PTP_NG_SERVO_FLAG_USE_SPIKE_FILTER, ///< TODO: Please add describing comment + MBG_PTP_NG_SERVO_FLAG_USE_SAMPLE_RATE_CONVERTER, ///< TODO: Please add describing comment + MBG_PTP_NG_SERVO_FLAG_COLD_START, ///< PTP stack starts with a default drift value + N_MBG_PTP_NG_SERVO_FLAGS +}; + + +enum MBG_PTP_NG_SERVO_FLAG_MASKS +{ + MBG_PTP_NG_SERVO_FLAG_USE_IIR_FILTER_MSK = (1UL << MBG_PTP_NG_SERVO_FLAG_USE_IIR_FILTER), ///< See ::MBG_PTP_NG_SERVO_FLAG_USE_IIR_FILTER + MBG_PTP_NG_SERVO_FLAG_USE_SPIKE_FILTER_MSK = (1UL << MBG_PTP_NG_SERVO_FLAG_USE_SPIKE_FILTER), ///< See ::MBG_PTP_NG_SERVO_FLAG_USE_SPIKE_FILTER + MBG_PTP_NG_SERVO_FLAG_USE_SAMPLE_RATE_CONVERTER_MSK = (1UL << MBG_PTP_NG_SERVO_FLAG_USE_SAMPLE_RATE_CONVERTER), ///< See ::MBG_PTP_NG_SERVO_FLAG_USE_SAMPLE_RATE_CONVERTER + MBG_PTP_NG_SERVO_FLAG_COLD_START_MSK = (1UL << MBG_PTP_NG_SERVO_FLAG_COLD_START), ///< See ::MBG_PTP_NG_SERVO_FLAG_COLD_START +}; + + +typedef struct +{ + int64_t inbound_delta_rate_max; ///< TODO: Please add describing comment + int64_t inbound_anti_windup_max; ///< TODO: Please add describing comment + int64_t outbound_delta_rate_max; ///< TODO: Please add describing comment + int64_t outbound_anti_windup_max; ///< TODO: Please add describing comment + + uint8_t reserved_1; ///< reserved, currently always 0 + int8_t lucky_packet_flt_depth; ///< TODO: Please add describing comment + uint16_t lucky_packet_median; ///< TODO: Please add describing comment + uint32_t flags; ///< See ::MBG_PTP_NG_SERVO_FLAG_MASKS + + uint32_t outbound_pi_k; ///< TODO: Please add describing comment + uint32_t outbound_pi_t; ///< TODO: Please add describing comment + + uint16_t iir_m2s_smin; ///< TODO: Please add describing comment + uint16_t iir_path_smin; ///< TODO: Please add describing comment + int8_t iir_log_adj_prd; ///< TODO: Please add describing comment + int8_t iir_log_adj_gain; ///< TODO: Please add describing comment + uint16_t reserved_2; ///< reserved, currently always 0 + + uint32_t inbound_pi_k; ///< TODO: Please add describing comment + uint32_t inbound_pi_t; ///< TODO: Please add describing comment + + int32_t boundary; ///< Sync Boundary in scaledNs [65536000] -> 1 microsecond + int32_t change_epoch_boundary; ///< Max epoch jump in scaledNs before hard time step is done [32768000000000] -> 0.5 sec + + uint8_t adjust_interval; ///< -8..+8 + uint8_t reserved_3; ///< reserved, currently always 0 + uint16_t reserved_4; ///< reserved, currently always 0 + uint32_t reserved_5; ///< reserved, currently always 0 + + uint32_t reserved_6[4]; ///< reserved, currently always 0 + +} MBG_PTP_NG_SERVO_SETTINGS; + + +#define _mbg_swab_ptp_ng_servo_settings( _p ) \ +{ \ + _mbg_swab64( &(_p)->inbound_delta_rate_max ); \ + _mbg_swab64( &(_p)->inbound_anti_windup_max ); \ + _mbg_swab64( &(_p)->outbound_delta_rate_max ); \ + _mbg_swab64( &(_p)->outbound_anti_windup_max ); \ + _mbg_swab16( &(_p)->lucky_packet_median ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->outbound_pi_k ); \ + _mbg_swab32( &(_p)->outbound_pi_t ); \ + _mbg_swab16( &(_p)->iir_m2s_smin ); \ + _mbg_swab16( &(_p)->iir_path_smin ); \ + _mbg_swab32( &(_p)->inbound_pi_k ); \ + _mbg_swab32( &(_p)->inbound_pi_t ); \ + _mbg_swab32( &(_p)->boundary ); \ + _mbg_swab32( &(_p)->change_epoch_boundary ); \ +} + + +typedef struct +{ + uint8_t clk_class_never_sync; ///< Fixed clock class if clock is free running, 0 means automatic + uint8_t clk_class_sync; ///< Fixed clock class if clock is synced, 0 means automatic + uint8_t clk_class_holdover; ///< Fixed clock class if clock is in holdover, 0 means automatic + uint8_t time_source; ///< Fixed PTP Time Source, 0 means automatic + uint8_t clk_accuracy; ///< Fixed clock accuracy, 0 means automatic + + uint8_t reserved_1; ///< Fixed clock accuracy, 0 means automatic + uint16_t fixed_clk_variance; ///< Fixed clock variance, 0 means automatic + + uint32_t reserved_2[4]; ///< reserved, currently always 0 + +} MBG_PTP_NG_FIXED_CLK_QLTY; + + +#define _mbg_swab_ptp_ng_fixed_clk_qlty( _p ) \ +{ \ + _mbg_swab16( &(_p)->fixed_clk_variance ); \ +} + + + +/** + * @brief Additional parameters for PTP Power Profile + */ +typedef struct +{ + uint32_t gm_time_incaccuracy; ///< Pre-defined GM time inaccuracy from master [ns] + uint32_t network_time_incaccuracy; ///< Configurable network inaccuracy from master [ns] + + uint8_t grandmaster_id; ///< [::PTP_POWER_PROFILE_GM_ID_MIN..::PTP_POWER_PROFILE_GM_ID_MAX] + uint8_t reserved[7]; ///< reserved, currently always 0 + +} MBG_PTP_NG_C37238_2011_SETTINGS; + + +#define _mbg_swab_ptp_ng_c37238_2011_settings( _p ) \ +{ \ + _mbg_swab32( &(_p)->gm_time_incaccuracy ); \ + _mbg_swab32( &(_p)->network_time_incaccuracy ); \ +} + + +typedef struct +{ + uint32_t total_inaccuracy; ///< Total inaccuracy in [ns] + uint16_t grandmaster_id; ///< Full 16 Bit Grandmaster ID + uint16_t reserved_1; ///< reserved, currently always 0 + +} MBG_PTP_NG_C37238_2017_SETTINGS; + + +#define _mbg_swab_ptp_ng_c37238_2017_settings( _p ) \ +{ \ + _mbg_swab32( &(_p)->total_inaccuracy ); \ + _mbg_swab16( &(_p)->grandmaster_id ); \ +} + + +/** + * @brief SMPTE System Frame Rates according to SMPTE ST 2059-2 + * + */ +enum MBG_PTP_NG_SMPTE_FRAME_RATES +{ + MBG_PTP_NG_SMPTE_FRAME_RATE_23_98HZ, + MBG_PTP_NG_SMPTE_FRAME_RATE_24HZ, + MBG_PTP_NG_SMPTE_FRAME_RATE_25HZ, + MBG_PTP_NG_SMPTE_FRAME_RATE_29_97HZ, + MBG_PTP_NG_SMPTE_FRAME_RATE_50HZ, + MBG_PTP_NG_SMPTE_FRAME_RATE_59_94HZ, + N_MBG_PTP_NG_SMPTE_FRAME_RATES +}; + + +#define MBG_PTP_NG_SMPTE_FRAME_RATE_STR \ +{ \ + "23.98 Hz", \ + "24 Hz", \ + "25 Hz", \ + "29.97 Hz", \ + "50 Hz", \ + "59.94 Hz" \ +} + + +#define MBG_PTP_NG_SMPTE_FRAME_RATE_NUM \ +{ \ + 24000, \ + 24000, \ + 25000, \ + 30000, \ + 50000, \ + 60000 \ +} + + +#define MBG_PTP_NG_SMPTE_FRAME_RATE_DENUM \ +{ \ + 1001, \ + 1000, \ + 1000, \ + 1001, \ + 1000, \ + 1001 \ +} + + +/** + * @brief SMPTE Time Address Flags according to SMPTE ST 2059-2 + * + */ +enum MBG_PTP_NG_SMPTE_TIME_ADDR_FLAGS +{ + MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_DROP_FRAME, + MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_COLOR_FRAME, + N_MBG_PTP_NG_SMPTE_TIME_ADDR_FLAGS +}; + + +enum MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_MASKS +{ + MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_DROP_FRAME_MSK = ( 1UL << MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_DROP_FRAME ), ///< See ::MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_DROP_FRAME + MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_COLOR_FRAME_MSK = ( 1UL << MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_COLOR_FRAME ) ///< See ::MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_COLOR_FRAME +}; + + +/** + * @brief SMPTE jam modes. + * + * Used with ::MBG_PTP_NG_SMPTE_20592_SETTINGS::next_jam_mode, which determines + * how to interpret the value in ::MBG_PTP_NG_SMPTE_20592_SETTINGS::jam_event. + */ +enum MBG_PTP_NG_SMPTE_JAM_MODES +{ + /// @brief Jam mode is disabled. + MBG_PTP_NG_SMPTE_JAM_MODE_DISABLED, + + /// @brief Daily jam at the specified seconds since midnight. + /// + /// The variable ::MBG_PTP_NG_SMPTE_20592_SETTINGS::jam_event + /// contains the number of seconds since midnight when the + /// jam is to occur. + /// The code in ::MBG_PTP_NG_SMPTE_20592_SETTINGS::event_timescale + /// indicates which time scale 'midnight' refers to. The default + /// timescale should be ::MBG_PTP_NG_SMPTE_EVT_TIMESCALE_LOCAL_TIME. + /// See ::MBG_PTP_NG_SMPTE_EVT_TIMESCALES. + MBG_PTP_NG_SMPTE_JAM_MODE_DAILY, + + /// @brief Next jam at the specified next absolute time. + /// + /// The variable ::MBG_PTP_NG_SMPTE_20592_SETTINGS::jam_event + /// contains the absolute time in POSIX time_t-like format when + /// the jam is to occur. + /// The code in ::MBG_PTP_NG_SMPTE_20592_SETTINGS::event_timescale + /// indicates the time scale associated with the time stamp. + /// See ::MBG_PTP_NG_SMPTE_EVT_TIMESCALES. + MBG_PTP_NG_SMPTE_JAM_MODE_SINGLE, + + /// @brief Next jam occurs when the local time is stepped. + /// + /// The variable ::MBG_PTP_NG_SMPTE_20592_SETTINGS::jam_event + /// contains the absolute time in POSIX time_t-like format when + /// the jam is to occur, and this time should match + /// ::MBG_PTP_NG_SMPTE_20592_STATUS::time_of_next_jump. + MBG_PTP_NG_SMPTE_JAM_MODE_NEXT_DISCONT_ON_LOCAL_TIME_CHANGE, + + N_MBG_PTP_NG_SMPTE_JAM_MODES ///< The number of known PTP SMPTE jam modes. +}; + + +#define MBG_PTP_NG_SMPTE_JAM_MODE_STRS \ +{ \ + "Disabled", \ + "Daily Jam Event", \ + "Single Jam Event", \ + "Next discontinuity in Local Time" \ +} + + +/** + * @brief Additional parameters for SMPTE ST 2059-2 profile + * + * This stucture holds the configuration for PTP NG SMPTE profile. + * The status can not be represented by this structure, because it does not contain jam and jump times + */ +typedef struct +{ + uint32_t default_frame_rate_num; ///< See ::MBG_PTP_NG_SMPTE_FRAME_RATES and ::MBG_PTP_NG_SMPTE_FRAME_RATE_NUM. + uint32_t default_frame_rate_denum; ///< See ::MBG_PTP_NG_SMPTE_FRAME_RATES and ::MBG_PTP_NG_SMPTE_FRAME_RATE_DENUM. + + uint32_t time_address_flags; ///< See ::MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_MASKS. + uint16_t reserved; ///< Reserved, currently always 0. + uint8_t next_jam_mode; ///< See ::MBG_PTP_NG_SMPTE_JAM_MODES. + uint8_t event_timescale; ///< See ::MBG_PTP_NG_SMPTE_EVT_TIMESCALES. + + /// @brief Jam event time configuration. + /// + /// Depending on the values of #next_jam_mode (see ::MBG_PTP_NG_SMPTE_JAM_MODES) + /// and #event_timescale (see ::MBG_PTP_NG_SMPTE_EVT_TIMESCALES), + /// this field can contain an absolute time for a single jam event, + /// or a number of seconds since midnight indicating when the + /// daily jam is to occur. + /// + /// The jam time sent in the SMPTE TLVs has to be calculated + /// according to these settings. + int64_t jam_event; + +} MBG_PTP_NG_SMPTE_20592_SETTINGS; + + +#define _mbg_swab_ptp_ng_smpte_20592_settings( _p ) \ +{ \ + _mbg_swab32( &(_p)->default_frame_rate_num ); \ + _mbg_swab32( &(_p)->default_frame_rate_denum ); \ + _mbg_swab32( &(_p)->time_address_flags ); \ + _mbg_swab64( &(_p)->jam_event ); \ +} + + + +enum MBG_PTP_NG_82751_FLAGS +{ + MBG_PTP_NG_82751_FLAG_USE_ALT_MC_ADDRESS, ///< Use Alternative (non-forwardable) multicast address + MBG_PTP_NG_82751_FLAG_PORT_NOT_SLAVE, ///< PTP Instance cannot become a SLAVE + N_MBG_PTP_NG_82751_FLAGS +}; + + +enum MBG_PTP_NG_82751_FLAG_MSKS +{ + MBG_PTP_NG_82751_FLAG_USE_ALT_MC_ADDRESS_MSK = (1UL << MBG_PTP_NG_82751_FLAG_USE_ALT_MC_ADDRESS), ///< See ::MBG_PTP_NG_82751_FLAG_USE_ALT_MC_ADDRESS + MBG_PTP_NG_82751_FLAG_PORT_NOT_SLAVE_MSK = (1UL << MBG_PTP_NG_82751_FLAG_PORT_NOT_SLAVE) ///< See ::MBG_PTP_NG_82751_FLAG_PORT_NOT_SLAVE +}; + + +/** + * @brief Additional parameters for Telecom8275.1 profile + */ +typedef struct +{ + uint8_t port_local_priority; ///< TODO: Please add describing comment + uint8_t default_local_priority; ///< TODO: Please add describing comment + uint16_t reserved; ///< reserved, currently always 0 + + uint32_t flags; ///< Bitmask used with ::MBG_PTP_NG_82751_FLAG_MSKS + +} MBG_PTP_NG_TELECOM_G82751_SETTINGS; + + +#define _mbg_swab_ptp_ng_telecom_g82751_settings( _p ) \ +{ \ + _mbg_swab32( &(_p)->flags ); \ +} + + +/** + * @brief Large Scaled nanoseconds structure (96 bit integer). + * This format is only used by 802.1as. + */ +typedef struct +{ + int64_t ns_l; + int32_t ns_h; + int32_t reserved; // used for alignment +} MBG_PTP_NG_LARGE_SCALED_NS; + + +enum MBG_PTP_NG_8021AS_FLAGS +{ + MBG_PTP_NG_8021AS_FLAG_AS_CAPABLE, ///< this time-aware system and the time-aware system at the other end of the link attached to this port can interoperate with each other via IEEE 802.1AS + N_MBG_PTP_NG_8021AS_FLAGS +}; + + +enum MBG_PTP_NG_8021AS_FLAG_MSKS +{ + MBG_PTP_NG_8021AS_FLAG_AS_CAPABLE_MSK = (1UL << MBG_PTP_NG_8021AS_FLAG_AS_CAPABLE), ///< See ::MBG_PTP_NG_8021AS_FLAG_AS_CAPABLE +}; + + +/** + * @brief Additional parameters for IEEE 802.1AS profile + * TODO: Shall this really be settings or rather status? + */ +typedef struct +{ + PTP_TIME_INTERVAL port_neighbor_prop_delay_thresh; ///< Propagation time threshold, above which a port is not considered capable of participating in the IEEE 802.1AS protocol. + int64_t port_last_gm_phase_change; ///< Current phase difference (offset) to the current GM (in slave and passive state) on the current port. + ///< Will be used as @a last_gm_phase_change after this clock becomes GM. + MBG_PTP_NG_LARGE_SCALED_NS last_gm_phase_change; ///< Global last phase change of the clockSource/GM. Is changed whenever the time base changes. + PTP_NG_PORT_IDENTITY port_as_neighbor; ///< PortId of the current @a asCapable neighbor, only if @a asCapable is true. + int32_t port_last_gm_freq_change; ///< Current frequency rate ratio to the current GM (in slave and passive state). + ///< Will be used as lastGmFreqChange after this clock becomes GM. + int32_t cumulative_scaled_rate_offset; ///< Ratio of the frequency of the clockSource/GM to the frequency of the local clock (rateRatio * 1.0) * (2^41). + int32_t last_gm_freq_change; ///< (rateRatio * 2^41) Fractional frequency offset of the current clockSource/GM to the last clockSource/GM. + ///< Changes whenever the time base changes. + int32_t port_neighbor_rate_ratio; ///< Current rate ratio to the port neighbor in scaled ratio (rateRatio * 2^41). + uint16_t gm_time_base_indicator; ///< Used to identify the time base. If this clock acts as GM, it has to be managed + ///< via shared mem., equivalent to clockSourceTimeBaseIndicator. + uint16_t reserved_1; + uint32_t flags; ///< See ::MBG_PTP_NG_8021AS_FLAGS. + uint32_t reserved_2[2]; + +} MBG_PTP_NG_IEEE_8021AS_SETTINGS; + + + +typedef union +{ + char u[128]; + + MBG_PTP_NG_C37238_2011_SETTINGS c37238_2011; ///< Power Profile C37.238-2011 + MBG_PTP_NG_C37238_2017_SETTINGS c37238_2017; ///< Power Profile C37.238-2017 + MBG_PTP_NG_SMPTE_20592_SETTINGS smpte_20592; ///< SMPTE Profile ST 2059-2 + MBG_PTP_NG_TELECOM_G82751_SETTINGS g82751; ///< Telecom Profile ITU-T. G.8275.1 + MBG_PTP_NG_IEEE_8021AS_SETTINGS ieee8021as; ///< IEEE 802.1AS Profile + +} MBG_PTP_NG_PROFILE_SETTINGS_U; + + +#define _mbg_swab_ptp_ng_profile_settings_u( _profile, _p ) \ +do \ +{ \ + switch ( (_profile) ) \ + { \ + case PTP_PRESETS_POWER: \ + _mbg_swab_ptp_ng_c37238_2011_settings( &(_p)->c37238_2011 ); \ + break; \ + \ + case PTP_PRESETS_C37238_2017: \ + _mbg_swab_ptp_ng_c37238_2017_settings( &(_p)->c37238_2017 ); \ + break; \ + \ + case PTP_PRESETS_SMPTE: \ + _mbg_swab_ptp_ng_smpte_20592_settings( &(_p)->smpte_20592 ); \ + break; \ + \ + case PTP_PRESETS_TELECOM_PHASE: \ + _mbg_swab_ptp_ng_telecom_g82751_settings( &(_p)->g82751 ); \ + break; \ + \ + default: break; \ + } \ +} while ( 0 ) + + + +/** + * @brief A name of a local time zone which can be longer than used in::TZDL. + */ +typedef char MBG_PTP_NG_ATOI_TZ_NAME[12]; + + + +/** + * @brief A structure used to configure a PTP instance. + */ +typedef struct mbg_ptp_ng_instc_settings_s +{ + uint32_t tstamper_idx; ///< Index of the timestamper that is active for this config running on interface @a #intf_label. + uint16_t assigned_port_id; ///< Port ID for this instance. Read-only for user interfaces, must be assigned by the managing process. + uint16_t reserved_1; ///< Reserved, currently always 0. + + PTP_INTF intf_label; ///< Interface name (IPv4/L2) or IPv6 address of logical/VLAN interface linked to this config. + + PTP_PORT_IDENTITY custom_port_id; ///< Overwrite port ID of this PTP port with global clock ID and suitable port ID. + ///< Only used if ::MBG_PTP_NG_FLAG_CUSTOM_PORT_ID_MSK is set in @a #flags. + uint16_t reserved_2; ///< Reserved, currently always 0. + uint8_t log_severity; ///< Sets the log level of the PTP Stack. Range from 0 (errors only) to 4. + uint8_t dsf; ///< Differentiated service field (IPv4) for PTP event messages -> 6 bit (MSB) DSCP, 2 bit ECN. + uint8_t ipv6_multicast_scope; ///< One of the ::IPV6_MULTICAST_SCOPES used for PTP IPv6 multicast. + uint8_t role; ///< One of the supported PTP roles, see ::PTP_ROLES. + + uint8_t profile; ///< Selected PTP preset or profile, see ::PTP_PRESETS. + uint8_t domain_number; ///< The PTP clock domain number, 0..255. + uint8_t reserved_4[6]; ///< Reserved, currently always 0. + + uint8_t delay_mech; ///< See ::PTP_DELAY_MECHS. + uint8_t protocol; ///< See ::PTP_NW_PROTS. + uint8_t priority_1; ///< Default DS priority 1. + uint8_t priority_2; ///< Default DS priority 2. + MBG_PTP_NG_INTV_CFG intvs; ///< Interval settings for this PTP instance. + + uint8_t min_gm_clk_class; ///< Minimum acceptable GM clock class for clock adjustment in slave mode, 0 means accept all. + uint8_t min_gm_clk_accuracy; ///< Minimum acceptable GM clock accuracy for clock adjustment in slave mode, 0 means accept all. + uint16_t min_gm_clk_variance; ///< Minimum acceptable GM clock variance for clock adjustment in slave mode, 0 means accept all. + uint8_t multicast_ttl; ///< Sets the multicast TTL value in IPv4 or multicast hop count in IPv6. 1..255, default 5. + uint8_t unicast_ttl; ///< Sets the unicast TTL value in IPv4 or unicast hop count in IPv6. 1..255, default 128. + uint8_t ann_rcpt_timeout; ///< Announce msg. receipt timeout, see ::PTP_ANN_RCPT_TIMEOUT_LIMITS. + uint8_t v1_clock_stratum; ///< Clock stratum parameter for PTPv1 stack + + char v1_subdomain_name[PTP_SUBDOMAIN_NAME_LENGTH]; ///< Subdomain string for PTPv1 stack. + + uint32_t upper_bound; ///< Sync. state set to uncalibrated if above this limit [ns], default 0 (ignored). + uint32_t lower_bound; ///< Sync. state set to slave if below this limit [ns], default 0 (ignored). + + int32_t fast_locking_boundary; ///< Determines if fast locking is used after a master was selected or changed [ns], in slave mode only. + int32_t delay_asymmetry; ///< Used to compensate asymmetries [ns], default 0. + + MBG_PTP_NG_FIXED_CLK_QLTY fixed_quality; ///< Fixed Clock Quality as manual override used in BMCA. + ///< Only used if ::MBG_PTP_NG_FLAG_FIXED_QUALITY_MSK is set in @a #flags. + MBG_PTP_NG_SERVO_SETTINGS servo_settings; ///< PTP Clock Servo Settings used in slave mode to adjust TSU time. + MBG_PTP_NG_PROFILE_SETTINGS_U profile_settings; ///< Union that includes all profile specific parameters. + ///< The profile type to be used is determined by the @a #profile parameter. + + uint32_t atois; ///< Activated ATOI TLVs, see ::MBG_PTP_NG_GLB_INFO::max_atois and ::MBG_PTP_NG_ATOI_MASKS + uint32_t flags; ///< See ::MBG_PTP_NG_FLAG_MASKS. + + TZDL custom_atoi; ///< Alternate Time Offset Indicator, used to derive local time + ///< from the TAI time of the grandmaster. + MBG_PTP_NG_ATOI_TZ_NAME names[2]; ///< Local time zone names for DST off and DST on. + ///< Can be longer than the names in ::TZDL @a #custom_atoi. + + uint32_t v1_flags; ///< See ::MBG_PTP_NG_V1_FLAG_MASKS. + uint32_t reserved_5[3]; ///< Reserved, currently always 0. + + char alias[32]; ///< A configurable, descriptive name for the PTP instance, just informational. + +} MBG_PTP_NG_INSTC_SETTINGS; + + +#define _mbg_swab_ptp_ng_instc_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->tstamper_idx ); \ + _mbg_swab16( &(_p)->assigned_port_id ); \ + _mbg_swab_ptp_port_identity( &(_p)->custom_port_id ); \ + _mbg_swab_ptp_ng_intv_cfg( &(_p)->intvs ); \ + _mbg_swab16( &(_p)->min_gm_clk_variance ); \ + _mbg_swab32( &(_p)->upper_bound ); \ + _mbg_swab32( &(_p)->lower_bound ); \ + _mbg_swab32( &(_p)->fast_locking_boundary ); \ + _mbg_swab32( &(_p)->delay_asymmetry ); \ + _mbg_swab_ptp_ng_fixed_clk_qlty( &(_p)->fixed_quality ); \ + _mbg_swab_ptp_ng_servo_settings( &(_p)->servo_settings ); \ + _mbg_swab_ptp_ng_profile_settings_u( (_p)->profile, &(_p)->profile_settings ); \ + _mbg_swab32( &(_p)->atois ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab_tzdl( &(_p)->custom_atoi ); \ + _mbg_swab32( &(_p)->v1_flags ); \ +} \ +while(0) + + + +/** + * @brief ::TODO + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t reserved; ///< Padding for 8-byte alignment, some settings contain int64_t. + + MBG_PTP_NG_INSTC_SETTINGS settings; + +} MBG_PTP_NG_INSTC_SETTINGS_IDX; + + +#define _mbg_swab_ptp_ng_instc_settings_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_ng_instc_settings( &(_p)->settings ); \ +} + + +/** + * @brief A structure to used to query the current configuration of a PTP Instance + */ +typedef struct mbg_ptp_ng_instc_info_s +{ + MBG_PTP_NG_INSTC_SETTINGS settings; ///< The current configuration. + + uint32_t reserved[4]; ///< Reserved, currently always 0 + +} MBG_PTP_NG_INSTC_INFO; + + +#define _mbg_swab_ptp_ng_instc_info( _p ) \ +{ \ + _mbg_swab_ptp_ng_instc_settings( &(_p)->settings ); \ +} + + +/** + * @brief + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t reserved; ///< Padding for 8-byte alignment, some settings contain int64_t. + + MBG_PTP_NG_INSTC_INFO info; + +} MBG_PTP_NG_INSTC_INFO_IDX; + + +#define _mbg_swab_ptp_ng_instc_info_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_ng_instc_info( &(_p)->info ); \ +} + +typedef struct +{ + int64_t min; + int64_t mean; + int64_t median; + int64_t stdDev; +} MBG_PTP_NG_PKT_STATS; + + +#define _mbg_swab_ptp_ng_pkt_stats( _p ) \ +{ \ + _mbg_swab64( &(_p)->min ); \ + _mbg_swab64( &(_p)->mean ); \ + _mbg_swab64( &(_p)->median ); \ + _mbg_swab64( &(_p)->stdDev ); \ +} + + +#define MAX_MBG_PTP_NG_ATOI_STATUS 3 + + +typedef struct +{ + uint8_t key; ///< An index number, see ::MBG_PTP_NG_ATOIS. + uint8_t reserved_1; ///< Reserved, currently always 0. + PTP_PKT_TSTAMP_SECS time_of_next_jump; ///< Time when the next discontinuity will occur, in seconds. + + PTP_TLV_TIME_OFFS current_offset; ///< Offset of the current time scale, in seconds. + PTP_TLV_TIME_OFFS jump_seconds; ///< Size of next discontinuity, in seconds. + + MBG_PTP_NG_ATOI_TZ_NAME display_name; ///< Name of the ATOI timezone. + uint8_t flags; ///< Reserved, currently always 0. + uint8_t reserved_2[3]; ///< Reserved, currently always 0. + +} MBG_PTP_NG_ATOI_STATUS; + + +#define _mbg_swab_ptp_ng_atoi_status( _p ) \ +{ \ + _mbg_swab32( &(_p)->current_offset ); \ + _mbg_swab32( &(_p)->jump_seconds ); \ +} + + +enum MBG_PTP_NG_SMPTE_MASTER_LOCKING_STATUS +{ + MBG_PTP_NG_SMPTE_MASTER_NOT_IN_USE, + MBG_PTP_NG_SMPTE_MASTER_FREE_RUN, + MBG_PTP_NG_SMPTE_MASTER_COLD_LOCKING, + MBG_PTP_NG_SMPTE_MASTER_WARM_LOCKING, + MBG_PTP_NG_SMPTE_MASTER_LOCKED, + N_MBG_PTP_NG_SMPTE_MASTER_LOCKING_STATUS +}; + + +#define MBG_PTP_NG_SMPTE_MASTER_LOCKING_STATUS_STRS \ +{ \ + "Not in use", \ + "Free Run", \ + "Cold Locking", \ + "Warm Locking", \ + "Locked" \ +} + + +typedef struct +{ + uint32_t system_frame_rate_num; ///< See ::MBG_PTP_NG_SMPTE_FRAME_RATES and ::MBG_PTP_NG_SMPTE_FRAME_RATE_NUM. + uint32_t system_frame_rate_denum; ///< See ::MBG_PTP_NG_SMPTE_FRAME_RATES and ::MBG_PTP_NG_SMPTE_FRAME_RATE_DENUM. + + uint32_t time_address_flags; ///< See ::MBG_PTP_NG_SMPTE_TIME_ADDR_FLAG_MASKS. + uint8_t master_locking_status; ///< See ::MBG_PTP_NG_SMPTE_MASTER_LOCKING_STATUS. + PTP_TLV_DST_FLAGS daylight_saving; ///< Daylight saving flags, see ::PTP_TLV_DST_FLAG_MSKS. + PTP_TLV_LS_FLAGS leap_second_jump; ///< Leap second Flags, see ::PTP_TLV_LS_FLAG_MSKS. + uint8_t reserved_1; ///< Reserved, currently always 0 + + /// @brief Offset in seconds of Local Time from grandmaster PTP time. + /// + /// For example, if Local Time is Eastern Standard Time (North America) %UTC-5 and the + /// number of leap seconds is 37, the value will be -18037 s. + PTP_TLV_TIME_OFFS current_local_offset; + + /// @brief The size of the next discontinuity in local time, in seconds. + /// + /// A value of 0 indicates that no discontinuity is expected. A positive value + /// indicates that the discontinuity will increase the @a #current_local_offset. + PTP_TLV_TIME_OFFS jump_seconds; + + /// @brief Time at which the next discontinuity of the @a #current_local_offset will occur. + /// + /// Refers to the second portion of the grandmaster PTP time. + /// The discontinuity occurs at the start of the second indicated. + /// If no discontinuity has been scheduled, the value is 0. + PTP_PKT_TSTAMP_SECS time_of_next_jump; + + /// @brief Time at which the next daily jam is to occur. + /// + /// Refers to the second portion of the grandmaster PTP time. + /// If no daily jam has been scheduled, the value is 0. + PTP_PKT_TSTAMP_SECS time_of_next_jam; + + /// @brief Time at which the previous daily jam occurred. + /// + /// Refers to the second portion of the grandmaster PTP time. + /// If the time of the previous jam is unknown, the value is 0. + PTP_PKT_TSTAMP_SECS time_of_previous_jam; + + /// @brief Reserved, currently always 0. + uint16_t reserved_2; + + /// @brief Local time offset at the previous daily jam. + /// + /// The value of @a #current_local_offset at the previous daily jam time. + /// If a discontinuity of local time occurs at the jam time, this parameter + /// reflects the offset after the discontinuity. + PTP_TLV_TIME_OFFS previous_jam_local_offset; + +} MBG_PTP_NG_SMPTE_20592_STATUS; + + +#define _mbg_swab_ptp_ng_smpte_20592_status( _p ) \ +{ \ + _mbg_swab32( &(_p)->system_frame_rate_num ); \ + _mbg_swab32( &(_p)->system_frame_rate_denum ); \ + _mbg_swab32( &(_p)->time_address_flags ); \ + _mbg_swab32( &(_p)->current_local_offset ); \ + _mbg_swab32( &(_p)->jump_seconds ); \ + _mbg_swab32( &(_p)->previous_jam_local_offset ); \ +} + + + +/** + * @brief Daylight saving flags used in PTP TLVs. + * + * Used with ::PTP_TLV_DST_FLAGS. + */ +enum PTP_TLV_DST_FLAG_MSKS +{ + PTP_TLV_DST_FLAG_DST = 0x01, ///< Bit 0: DST currently in effect. + PTP_TLV_DST_FLAG_DST_AT_NEXT_JMP = 0x02, ///< Bit 1: DST in effect at next discontinuity. + PTP_TLV_DST_FLAG_DST_AT_PRV_JAM = 0x04 ///< Bit 2: DST in effect at previous jam time. + // Other bits are reserved. +}; + + + +/** + * @brief Leap second flags used in PTP TLVs. + * + * Used with ::PTP_TLV_LS_FLAGS. + */ +enum PTP_TLV_LS_FLAG_MSKS +{ + PTP_TLV_LS_FLAG_LEAP_SEC = 0x01 ///< Bit 0: Next discontinuity due to leap second. + // Other bits are reserved. +}; + + + +typedef union +{ + char u[128]; + + MBG_PTP_NG_C37238_2011_SETTINGS c37238_2011; ///< Power Profile C37.238-2011 + MBG_PTP_NG_C37238_2017_SETTINGS c37238_2017; ///< Power Profile C37.238-2017 + MBG_PTP_NG_SMPTE_20592_STATUS smpte_20592; ///< SMPTE Profile ST 2059-2 + MBG_PTP_NG_TELECOM_G82751_SETTINGS g82751; ///< Telecom Profile ITU-T. G.8275.1 + MBG_PTP_NG_IEEE_8021AS_SETTINGS ieee8021as; ///< IEEE 802.1AS Profile + +} MBG_PTP_NG_PROFILE_STATUS_U; + + +#define _mbg_swab_ptp_ng_profile_status_u( _profile, _p ) \ +do \ +{ \ + switch ( (_profile) ) \ + { \ + case PTP_PRESETS_POWER: \ + _mbg_swab_ptp_ng_c37238_2011_settings( &(_p)->c37238_2011 ); \ + break; \ + \ + case PTP_PRESETS_C37238_2017: \ + _mbg_swab_ptp_ng_c37238_2017_settings( &(_p)->c37238_2017 ); \ + break; \ + \ + case PTP_PRESETS_SMPTE: \ + _mbg_swab_ptp_ng_smpte_20592_status( &(_p)->smpte_20592 ); \ + break; \ + \ + case PTP_PRESETS_TELECOM_PHASE: \ + _mbg_swab_ptp_ng_telecom_g82751_settings( &(_p)->g82751 ); \ + break; \ + \ + default: break; \ + } \ +} while ( 0 ) + + +enum MBG_PTP_NG_INSTC_STATUS_FLAGS +{ + MBG_PTP_NG_INSTC_STATUS_FLAG_STACK_NOT_RUNNING, ///< Indicates, that the PTP stack for this instance is not running + MBG_PTP_NG_INSTC_STATUS_FLAG_M2S_DELAY_VALID, + MBG_PTP_NG_INSTC_STATUS_FLAG_S2M_DELAY_VALID, + + N_MBG_PTP_NG_INSTC_STATUS_FLAGS +}; + + + +enum MBG_PTP_NG_INSTC_STATUS_FLAG_MASKS +{ + MBG_PTP_NG_INSTC_STATUS_FLAG_STACK_NOT_RUNNING_MSK = (1UL << MBG_PTP_NG_INSTC_STATUS_FLAG_STACK_NOT_RUNNING), ///< See ::MBG_PTP_NG_INSTC_STATUS_FLAG_STACK_NOT_RUNNING + MBG_PTP_NG_INSTC_STATUS_FLAG_M2S_DELAY_VALID_MSK = (1UL << MBG_PTP_NG_INSTC_STATUS_FLAG_M2S_DELAY_VALID), ///< See ::MBG_PTP_NG_INSTC_STATUS_FLAG_M2S_DELAY_VALID + MBG_PTP_NG_INSTC_STATUS_FLAG_S2M_DELAY_VALID_MSK = (1UL << MBG_PTP_NG_INSTC_STATUS_FLAG_S2M_DELAY_VALID), ///< See ::MBG_PTP_NG_INSTC_STATUS_FLAG_S2M_DELAY_VALID +}; + + +/** + * @brief A structure used to read the status of a PTP instance + */ +typedef struct mbg_ptp_ng_instc_status_s +{ + MBG_PTP_NG_PKT_STATS m2s_delay; ///< current statistics of the Master to Slave delay + MBG_PTP_NG_PKT_STATS s2m_delay; ///< current statistics of the Slave to Master delay + uint16_t num_uc_slaves; ///< current number of unicast slaves in unicast master mode + uint8_t utilization; ///< current resource utilization (msg/sec) in % + uint8_t profile; ///< Selected PTP preset or profile, see ::PTP_PRESETS. + uint8_t num_atois; ///< number of valid atois status, see #atoi_status + uint8_t protocol; ///< current network protocol, see ::PTP_NW_PROTS + uint8_t reserved_1[2]; ///< reserved, currently always 0 + MBG_PTP_V2_NG_DEFAULT_DATASET default_ds; ///< the default dataset of the PTP instance + MBG_PTP_V2_NG_CURRENT_DATASET current_ds; ///< the current dataset of the PTP instance + MBG_PTP_V2_NG_PARENT_DATASET parent_ds; ///< the parent dataset of the PTP instance + MBG_PTP_V2_NG_TIME_PROPERTIES_DATASET time_properties_ds; ///< the time properties dataset of the PTP instance + MBG_PTP_V2_NG_PORT_DATASET port_ds; ///< the port dataset of the PTP instance + MBG_PTP_NG_PROFILE_STATUS_U profile_status; ///< Union that includes all profile specific parameters; the profile is selected with the #profile parameter. + MBG_PTP_NG_ATOI_STATUS atoi_status[MAX_MBG_PTP_NG_ATOI_STATUS]; ///< current status of available ATOIs + uint32_t flags; ///< See ::MBG_PTP_NG_INSTC_STATUS_FLAG_MASKS + uint32_t reserved_2[3]; ///< reserved, currently always 0 + +} MBG_PTP_NG_INSTC_STATUS; + + +#define _mbg_swab_ptp_ng_instc_status( _p ) \ +{ \ + unsigned i; \ + _mbg_swab_ptp_ng_pkt_stats( &(_p)->m2s_delay ); \ + _mbg_swab_ptp_ng_pkt_stats( &(_p)->s2m_delay ); \ + _mbg_swab16( &(_p)->num_uc_slaves ); \ + _mbg_swab_ptp_v2_ng_default_dataset( &(_p)->default_ds ); \ + _mbg_swab_ptp_v2_ng_current_dataset( &(_p)->current_ds ); \ + _mbg_swab_ptp_v2_ng_parent_dataset( &(_p)->parent_ds ); \ + _mbg_swab_ptp_v2_ng_time_properties_dataset( &(_p)->time_properties_ds ); \ + _mbg_swab_ptp_v2_ng_port_dataset( &(_p)->port_ds ); \ + _mbg_swab_ptp_ng_profile_status_u( (_p)->profile, &(_p)->profile_status ); \ + for ( i = 0; i < MAX_MBG_PTP_NG_ATOI_STATUS; ++i) \ + _mbg_swab_ptp_ng_atoi_status( &(_p)->atoi_status[i] ); \ + _mbg_swab32( &(_p)->flags ); \ +} + + +/** + * @brief + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t reserved; ///< padding for 8-byte alignment, some settings contain int64_t + + MBG_PTP_NG_INSTC_STATUS status; + +} MBG_PTP_NG_INSTC_STATUS_IDX; + + +#define _mbg_swab_ptp_ng_instc_status_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_ng_instc_status( &(_p)->status ); \ +} + + +typedef struct mbg_ptp_ng_instc_pkt_cntrs_s +{ + uint32_t rx_all; ///< overall Rx packet counter + uint32_t rx_announce; ///< Accepted Announce message Rx counter + uint32_t rx_sync; ///< Accepted Sync message Rx counter + uint32_t rx_follow_up; ///< Accepted Follow-up message Rx counter + uint32_t rx_delay_req; ///< Accepted Delay request message Rx counter + uint32_t rx_delay_resp; ///< Accepted Delay response message Rx counter + uint32_t rx_pdelay_req; ///< Accepted PDelay Request message Rx counter + uint32_t rx_pdelay_resp; ///< Accepted PDelay Response message Rx counter + uint32_t rx_pdelay_follow_up; ///< Accepted PDelay Follow-Up message Rx counter + uint32_t rx_signalling; ///< Accepted Signalling message Rx counter + uint32_t rx_management; ///< Accepted Management message Rx counter + uint32_t rx_management_err; ///< Management error counter (rx) + + uint32_t tx_all; ///< overall Tx packet counter + uint32_t tx_announce; ///< Announce message Tx counter + uint32_t tx_sync; ///< Sync message Tx counter + uint32_t tx_follow_up; ///< Follow-up message Tx counter + uint32_t tx_delay_req; ///< Delay request message Tx counter + uint32_t tx_delay_resp; ///< Delay response message Tx counter + uint32_t tx_pdelay_req; ///< PDelay Request message Tx counter + uint32_t tx_pdelay_resp; ///< PDelay Response message Tx counter + uint32_t tx_pdelay_follow_up; ///< PDelay Follow-Up message Tx counter + uint32_t tx_signalling; ///< Signalling message Tx counter + uint32_t tx_management; ///< Management message Tx counter + uint32_t reserved_1; ///< Reserved, currently always 0 + + uint32_t ann_receipt_timeout; ///< Announce receipt timeout counter + uint32_t reserved_2; ///< Reserved, currently always 0 + + // The following counters (msg/second counter) are represented in + // fixed point format. The lower 8 bit represent digits after the + // radix (comma), the higher 24 bits digits before it. That's a + // scaling factor of 1/(2^8). To display the number in decimal + // notation use: + // printf("%d.%d", rxPerSec >> 8, ((rxPerSec & 0xFF) * 100) >> 8) + uint32_t rx_all_per_sec; ///< overall Rx msg/second + uint32_t rx_announce_per_sec; ///< Accepted Announce msg Rx msg/second + uint32_t rx_sync_per_sec; ///< Accepted Sync msg Rx msg/second + uint32_t rx_follow_up_per_sec; ///< Accepted Follow-up msg Rx msg/second + uint32_t rx_delay_req_per_sec; ///< Accepted Delay request msg Rx msg/second + uint32_t rx_delay_resp_per_sec; ///< Accepted Delay response msg Rx msg/second + uint32_t rx_pdelay_req_per_sec; ///< Accepted PDelay Request msg Rx msg/second + uint32_t rx_pdelay_resp_per_sec; ///< Accepted PDelay Response msg Rx msg/second + uint32_t rx_pdelay_follow_up_per_sec; ///< Accepted PDelay Follow-Up msg Rx msg/sec. + uint32_t rx_signalling_per_sec; ///< Accepted Signalling msg Rx msg/second + uint32_t rx_management_per_sec; ///< Accepted Management msg Rx msg/second + uint32_t reserved_3; ///< Reserved, currently always 0 + + uint32_t tx_all_per_sec; ///< overall Tx msg/second + uint32_t tx_announce_per_sec; ///< Announce msg Tx msg/second + uint32_t tx_sync_per_sec; ///< Sync msg Tx msg/second + uint32_t tx_follow_up_per_sec; ///< Follow-up msg Tx msg/second + uint32_t tx_delay_req_per_sec; ///< Delay request msg Tx msg/second + uint32_t tx_delay_resp_per_sec; ///< Delay response msg Tx msg/second + uint32_t tx_pdelay_req_per_sec; ///< PDelay Request msg Tx msg/second + uint32_t tx_pdelay_resp_per_sec; ///< PDelay Response msg Tx msg/second + uint32_t tx_pdelay_follow_up_per_sec; ///< PDelay Follow-Up msg Tx msg/second + uint32_t tx_signalling_per_sec; ///< Signalling msg Tx msg/second + uint32_t tx_management_per_sec; ///< Management msg Tx msg/second + uint32_t reserved_4; ///< Reserved, currently always 0 + +} MBG_PTP_NG_INSTC_PKT_CNTRS; + + +#define _mbg_swab_ptp_ng_instc_pkt_cntrs( _p ) \ +{ \ + _mbg_swab32( &(_p)->rx_all ); \ + _mbg_swab32( &(_p)->rx_announce ); \ + _mbg_swab32( &(_p)->rx_sync ); \ + _mbg_swab32( &(_p)->rx_follow_up ); \ + _mbg_swab32( &(_p)->rx_delay_req ); \ + _mbg_swab32( &(_p)->rx_delay_resp ); \ + _mbg_swab32( &(_p)->rx_pdelay_req ); \ + _mbg_swab32( &(_p)->rx_pdelay_resp ); \ + _mbg_swab32( &(_p)->rx_pdelay_follow_up ); \ + _mbg_swab32( &(_p)->rx_signalling ); \ + _mbg_swab32( &(_p)->rx_management ); \ + _mbg_swab32( &(_p)->rx_management_err ); \ + \ + _mbg_swab32( &(_p)->tx_all ); \ + _mbg_swab32( &(_p)->tx_announce ); \ + _mbg_swab32( &(_p)->tx_sync ); \ + _mbg_swab32( &(_p)->tx_follow_up ); \ + _mbg_swab32( &(_p)->tx_delay_req ); \ + _mbg_swab32( &(_p)->tx_delay_resp ); \ + _mbg_swab32( &(_p)->tx_pdelay_req ); \ + _mbg_swab32( &(_p)->tx_pdelay_resp ); \ + _mbg_swab32( &(_p)->tx_pdelay_follow_up ); \ + _mbg_swab32( &(_p)->tx_signalling ); \ + _mbg_swab32( &(_p)->tx_management ); \ + \ + _mbg_swab32( &(_p)->ann_receipt_timeout ); \ + \ + _mbg_swab32( &(_p)->rx_all_per_sec ); \ + _mbg_swab32( &(_p)->rx_announce_per_sec ); \ + _mbg_swab32( &(_p)->rx_sync_per_sec ); \ + _mbg_swab32( &(_p)->rx_follow_up_per_sec ); \ + _mbg_swab32( &(_p)->rx_delay_req_per_sec ); \ + _mbg_swab32( &(_p)->rx_delay_resp_per_sec ); \ + _mbg_swab32( &(_p)->rx_pdelay_req_per_sec ); \ + _mbg_swab32( &(_p)->rx_pdelay_resp_per_sec ); \ + _mbg_swab32( &(_p)->rx_pdelay_follow_up_per_sec ); \ + _mbg_swab32( &(_p)->rx_signalling_per_sec ); \ + _mbg_swab32( &(_p)->rx_management_per_sec ); \ + \ + _mbg_swab32( &(_p)->tx_all_per_sec ); \ + _mbg_swab32( &(_p)->tx_announce_per_sec ); \ + _mbg_swab32( &(_p)->tx_sync_per_sec ); \ + _mbg_swab32( &(_p)->tx_follow_up_per_sec ); \ + _mbg_swab32( &(_p)->tx_delay_req_per_sec ); \ + _mbg_swab32( &(_p)->tx_delay_resp_per_sec ); \ + _mbg_swab32( &(_p)->tx_pdelay_req_per_sec ); \ + _mbg_swab32( &(_p)->tx_pdelay_resp_per_sec ); \ + _mbg_swab32( &(_p)->tx_pdelay_follow_up_per_sec ); \ + _mbg_swab32( &(_p)->tx_signalling_per_sec ); \ + _mbg_swab32( &(_p)->tx_management_per_sec ); \ +} + + +/** + * @brief + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t reserved; ///< padding for 8-byte alignment, some settings contain int64_t + + MBG_PTP_NG_INSTC_PKT_CNTRS cntrs; + +} MBG_PTP_NG_INSTC_PKT_CNTRS_IDX; + + +#define _mbg_swab_ptp_ng_instc_pkt_cntrs_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_ng_instc_pkt_cntrs( &(_p)->cntrs ); \ +} + + +/** + * @brief A structure used to read the status of a unicast slave of an instance running in unicast master mode + * @see ::MBG_PTP_NG_INSTC_STATUS::num_uc_slaves + */ +typedef struct mbg_ptp_ng_uc_slave_status_s +{ + uint8_t addr[IP6_ADDR_BYTES]; ///< IPv4, IPv6 or MAC address + ///< Depending on the appropriate ::MBG_PTP_NG_INSTC_SETTINGS::protocol + + MBG_PTP_NG_INTV_CFG intvs; ///< Granted message intervals + uint32_t ann_duration; ///< Remaining announce message duration + + uint32_t sync_duration; ///< Remaining sync message duration + uint32_t resp_duration; ///< Remaining delay reponse duration + + uint32_t reserved_4[8]; ///< reserved, currently always 0 + +} MBG_PTP_NG_UC_SLAVE_STATUS; + + +#define _mbg_swab_ptp_ng_uc_slave_status( _p ) \ +{ \ + _mbg_swab_ptp_ng_intv_cfg( &(_p)->intvs ); \ + _mbg_swab32( &(_p)->ann_duration ); \ + _mbg_swab32( &(_p)->sync_duration ); \ + _mbg_swab32( &(_p)->resp_duration ); \ +} + + +/** + * @brief + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t instc_idx; + + MBG_PTP_NG_UC_SLAVE_STATUS status; + +} MBG_PTP_NG_UC_SLAVE_STATUS_IDX; + + +#define _mbg_swab_ptp_ng_uc_slave_status_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab32( &(_p)->instc_idx ); \ + _mbg_swab_ptp_ng_uc_slave_status( &(_p)->status ); \ +} + + +/** + * @brief Configuration settings specifiying how to query a PTP unicast master + * + * This structure is used on a unicast slave to specify the settings of + * a unicast master polled by the slave. The number of unicast masters + * which can be specified depends on the capabilities of the slave device + * and is returned in ::MBG_PTP_NG_GLB_INFO::max_uc_masters. + */ +typedef struct mbg_ptp_ng_uc_master_settings_s +{ + uint32_t instc_idx; ///< Index of the PTP instance this master belongs to + uint32_t reserved_1; ///< reserved, currently always 0. + + uint8_t grantor_addr[IP6_ADDR_BYTES]; ///< IPv4, IPv6 or MAC address of the grandmaster, depending on + ///< the associated ::MBG_PTP_NG_INSTC_SETTINGS::protocol value. + + PTP_PORT_IDENTITY gm_port_identity; ///< Specified port identity of master port, or ::PTP_CLOCK_ID_WILDCARD and ::PTP_PORT_ID_WILDCARD. + MBG_PTP_NG_INTV_CFG intvs; ///< Intervals to be requested by the Slave instance for this master. + uint16_t message_duration; ///< Subscription period [s]. + + uint32_t reserved_3[4]; ///< Reserved, currently always 0. + +} MBG_PTP_NG_UC_MASTER_SETTINGS; + + +#define _mbg_swab_ptp_ng_uc_master_settings( _p ) \ +{ \ + _mbg_swab32( &(_p)->instc_idx ); \ + _mbg_swab_ptp_port_identity( &(_p)->gm_port_identity ); \ + _mbg_swab_ptp_ng_intv_cfg( &(_p)->intvs ); \ + _mbg_swab16( &(_p)->message_duration ); \ +} + + +/** + * @brief Configuration settings for a specific PTP unicast master + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t reserved; ///< padding for 8-byte alignment, some settings contain int64_t + + MBG_PTP_NG_UC_MASTER_SETTINGS settings; + +} MBG_PTP_NG_UC_MASTER_SETTINGS_IDX; + + +#define _mbg_swab_ptp_ng_uc_master_settings_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_ng_uc_master_settings( &(_p)->settings ); \ +} + + +/** + * @brief Current settings and general capabilities of a unicast master + * + * This structure is used with a PTP unicast slave device to specify + * a PTP unicast master which can be queried by the slave device. + */ +typedef struct mbg_ptp_ng_uc_master_info_s +{ + MBG_PTP_NG_UC_MASTER_SETTINGS settings; + + uint32_t reserved[4]; ///< reserved, currently always 0 + +} MBG_PTP_NG_UC_MASTER_INFO; + + +#define _mbg_swab_ptp_ng_uc_master_info( _p ) \ +{ \ + _mbg_swab_ptp_ng_uc_master_settings( &(_p)->settings ); \ +} + + +/** + * @brief Current settings and general capabilities of a specific unicast master + * + * This structure is used with a PTP unicast slave device to specify + * a PTP unicast master which can be queried by the slave device. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + uint32_t reserved; ///< padding for 8-byte alignment, some settings contain int64_t + + MBG_PTP_NG_UC_MASTER_INFO info; + +} MBG_PTP_NG_UC_MASTER_INFO_IDX; + + +#define _mbg_swab_ptp_ng_uc_master_info_idx( _p ) \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ptp_ng_uc_master_info( &(_p)->info ); \ +} + + +/** @} defgroup group_ptp_ng */ + +/** @} defgroup group_ptp */ + + + +/** + * @defgroup group_ntp Definitions used with NTP + * + * @{ */ + + +/** + * @brief Enumeration of known NTP roles + * + * @see ::NTP_GLB_SETTINGS::ntp_role + */ +enum NTP_ROLES +{ + NTP_ROLE_NONE = 0, ///< NTP services disabled + NTP_ROLE_CLIENT, ///< NTP client + NTP_ROLE_SERVER, ///< NTP server + NTP_ROLE_CLIENT_SERVER, ///< both NTP client and server + N_NTP_ROLES ///< number of supported roles +}; + + +/** + * @brief Flag masks associated with NTP roles + * + * @see ::NTP_GLB_INFO::supp_ntp_roles + */ +enum NTP_ROLE_MASKS +{ + NTP_MSK_ROLE_NONE = ( 1UL << NTP_ROLE_NONE ), ///< See ::NTP_ROLE_NONE + NTP_MSK_ROLE_CLIENT = ( 1UL << NTP_ROLE_CLIENT ), ///< See ::NTP_ROLE_CLIENT + NTP_MSK_ROLE_SERVER = ( 1UL << NTP_ROLE_SERVER ), ///< See ::NTP_ROLE_SERVER + NTP_MSK_ROLE_CLIENT_SERVER = ( 1UL << NTP_ROLE_CLIENT_SERVER ), ///< See ::NTP_ROLE_CLIENT_SERVER +}; + + +/** + * @brief Enumeration of global NTP flags + * + * @see @ref NTP_FLAG_MASKS + */ +enum NTP_FLAGS +{ + NTP_IPV4, ///< NTP via IPv4/UDP + NTP_IPV6, ///< NTP via IPv6/UDP + NTP_SYMM_KEYS, ///< support symmetric key authentication (MD5) + NTP_AUTOKEY, ///< include authentication fields encrypted using the autokey scheme + NTP_BURST, ///< send a burst of eight packets at each polling cycle + NTP_IBURST, ///< send a burst of eight packets at the first polling cycle + NTP_NO_SELECT, ///< marks a server as not to be selected for time synchronization + NTP_PREEMPT, ///< specifies the association as preemptable rather than the default persistent + NTP_PREFER, ///< marks a server as preferred peer for time synchronization + NTP_TRUE, ///< force the association to assume truechimer status; always survive the selection and clustering algorithms + NTP_BROADCAST, ///< transmission via broadcast, point to multipoint + NTP_MULTICAST, ///< transmission via multicast, point to multipoint + NTP_MANYCAST, ///< transmission via manycast, point to multipoint + NTP_POOL, ///< peer shall be treated as a pool server + NTP_PEER, ///< specifies a symmetric-active association should be used with this server + NTP_BROADCASTCLIENT, ///< receive broadcast messages on all interfaces + NTP_MULTICASTCLIENT, ///< receive messages from the given multicast group + NTP_MANYCASTCLIENT, ///< manycast shall be used on the given multicast address to discover peers + NTP_RESTRICTIONS, ///< NTP supports restrictions + NTP_DISCARD, ///< NTP supports "discard" rate limiting + NTP_REFCLOCKS, ///< NTP supports refclocks + NTP_STATISTICS, ///< NTP supports statistics (e.g. clockstats, loopstats, etc...) + NTP_MISCELLANEOUS, ///< NTP supports misc options (e.g. tinker, driftfile, orphan mode, etc...) + NTP_TRUSTED_KEYS, ///< NTP supports specifying trusted symmetric keys + NTP_FIXED_REFCLOCKS, ///< NTP refclocks not configurable + NTP_ADD_CONF, ///< Supports additional NTP configuration (i.e. via script) + N_NTP_FLAGS +}; + + + +/** + * @brief Flag masks associated with ::NTP_FLAGS + * + * Used with ::NTP_GLB_INFO::supp_flags, ::NTP_GLB_SETTINGS::flags, NTP_CLNT_MODE_INFO::supp_flags, + * ::NTP_CLNT_MODE_INFO::supp_peer_flags, ::NTP_CLNT_MODE_SETTINGS::flags, ::NTP_PEER_SETTINGS::flags, + * ::NTP_SRV_MODE_SETTINGS::flags, and ::NTP_SRV_MODE_INFO::supp_flags. + * + * @todo We may need structures to configure symmetric keys, and autokey certificates. + * + * @see ::NTP_FLAGS + * + * @anchor NTP_FLAG_MASKS @{ */ + +#define NTP_MSK_IPV4 ( 1UL << NTP_IPV4 ) ///< See ::NTP_IPV4 +#define NTP_MSK_IPV6 ( 1UL << NTP_IPV6 ) ///< See ::NTP_IPV6 +#define NTP_MSK_SYMM_KEYS ( 1UL << NTP_SYMM_KEYS ) ///< See ::NTP_SYMM_KEYS; if set, ::NTP_SYMM_KEY_LIMITS can be queried +#define NTP_MSK_AUTOKEY ( 1UL << NTP_AUTOKEY ) ///< See ::NTP_AUTOKEY +#define NTP_MSK_BURST ( 1UL << NTP_BURST ) ///< See ::NTP_BURST +#define NTP_MSK_IBURST ( 1UL << NTP_IBURST ) ///< See ::NTP_IBURST +#define NTP_MSK_NO_SELECT ( 1UL << NTP_NO_SELECT ) ///< See ::NTP_NO_SELECT +#define NTP_MSK_PREEMPT ( 1UL << NTP_PREEMPT ) ///< See ::NTP_PREEMPT +#define NTP_MSK_PREFER ( 1UL << NTP_PREFER ) ///< See ::NTP_PREFER +#define NTP_MSK_TRUE ( 1UL << NTP_TRUE ) ///< See ::NTP_TRUE +#define NTP_MSK_BROADCAST ( 1UL << NTP_BROADCAST ) ///< See ::NTP_BROADCAST +#define NTP_MSK_MULTICAST ( 1UL << NTP_MULTICAST ) ///< See ::NTP_MULTICAST +#define NTP_MSK_MANYCAST ( 1UL << NTP_MANYCAST ) ///< See ::NTP_MANYCAST +#define NTP_MSK_POOL ( 1UL << NTP_POOL ) ///< See ::NTP_POOL +#define NTP_MSK_PEER ( 1UL << NTP_PEER ) ///< See ::NTP_PEER +#define NTP_MSK_BROADCASTCLIENT ( 1UL << NTP_BROADCASTCLIENT) ///< See ::NTP_BROADCASTCLIENT +#define NTP_MSK_MULTICASTCLIENT ( 1UL << NTP_MULTICASTCLIENT) ///< See ::NTP_MULTICASTCLIENT +#define NTP_MSK_MANYCASTCLIENT ( 1UL << NTP_MANYCASTCLIENT) ///< See ::NTP_MANYCASTCLIENT +#define NTP_MSK_RESTRICTIONS ( 1UL << NTP_RESTRICTIONS ) ///< See ::NTP_RESTRICTIONS +#define NTP_MSK_DISCARD ( 1UL << NTP_DISCARD ) ///< See ::NTP_DISCARD +#define NTP_MSK_REFCLOCKS ( 1UL << NTP_REFCLOCKS ) ///< See ::NTP_REFCLOCKS +#define NTP_MSK_STATISTICS ( 1UL << NTP_STATISTICS ) ///< See ::NTP_STATISTICS; if set, ::NTP_STATS_GLB_INFO can be queried +#define NTP_MSK_MISCELLANEOUS ( 1UL << NTP_MISCELLANEOUS ) ///< See ::NTP_MISCELLANEOUS +#define NTP_MSK_TRUSTED_KEYS ( 1UL << NTP_TRUSTED_KEYS ) ///< See ::NTP_TRUSTED_KEYS +#define NTP_MSK_FIXED_REFCLOCKS ( 1UL << NTP_FIXED_REFCLOCKS ) ///< See ::NTP_FIXED_REFCLOCKS +#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) + * + * This structure should be sent to an NTP device to configure global settings + */ +typedef struct +{ + uint8_t ntp_role; ///< one of the supported NTP roles, see ::NTP_ROLES + uint8_t num_symm_keys; ///< number of configured symm keys + uint8_t num_trusted_keys; ///< number of activated symm keys + uint8_t reserved_1; ///< reserved, currently 0 + + uint32_t reserved_2; ///< reserved, currently 0 + uint32_t reserved_3; ///< reserved, currently 0 + + uint32_t flags; ///< NTP flags, see @ref NTP_FLAG_MASKS + +} NTP_GLB_SETTINGS; + +#define _mbg_swab_ntp_glb_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + +/** + * @brief Global configuration info of an NTP device (client/server) + * + * This structure can be used to determine possible configurations of an NTP device + */ +typedef struct +{ + NTP_GLB_SETTINGS settings; ///< current configuration settings + + uint8_t max_symm_keys; ///< number of available symm keys that can be generated, see ::NTP_SYMM_KEY_INFO_IDX + uint8_t max_trusted_keys; ///< number of available trusted keys, see ::NTP_TRUSTED_KEY_INFO_IDX + + uint16_t reserved_2; ///< reserved, currently 0 + uint32_t reserved_3; ///< reserved, currently 0 + + uint32_t supp_ntp_roles; ///< supported NTP roles, see ::NTP_ROLE_MASKS + uint32_t supp_flags; ///< supported NTP flags, see @ref NTP_FLAG_MASKS + +} NTP_GLB_INFO; + +#define _mbg_swab_ntp_glb_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_glb_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_ntp_roles ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + +#if defined( _PRELIMINARY_CODE ) + +/** + * @brief Enumeration of supported NTP restriction types/keywords + * + * Used with ::NTP_RESTR::type + * + * @see https://www.eecis.udel.edu/~mills/ntp/html/accopt.html#restrict + * @see ::NTP_RESTR_TYPE_MSKS + */ +enum NTP_RESTR_TYPES +{ + NTP_RESTR_TYPE_DEFAULT, + NTP_RESTR_TYPE_SOURCE, + NTP_RESTR_TYPE_ADDRESS, + N_NTP_RESTR_TYPES +}; + + + +/** + * @brief Bit masks associated with ::NTP_RESTR_TYPES + * + * Used with ::NTP_RESTR_LIMITS::supp_types + * + * @see ::NTP_RESTR_TYPES + */ +enum NTP_RESTR_TYPE_MSKS +{ + NTP_RESTR_TYPE_MSK_DEFAULT = ( 1UL << NTP_RESTR_TYPE_DEFAULT ), ///< See ::NTP_RESTR_TYPE_DEFAULT + NTP_RESTR_TYPE_MSK_SOURCE = ( 1UL << NTP_RESTR_TYPE_SOURCE ), ///< See ::NTP_RESTR_TYPE_SOURCE + NTP_RESTR_TYPE_MSK_ADDRESS = ( 1UL << NTP_RESTR_TYPE_ADDRESS ) ///< See ::NTP_RESTR_TYPE_ADDRESS +}; + + + +/** + * @brief Enumeration of supported NTP restriction flags + * + * Used to define ::NTP_RESTR_FLAG_MSKS + * + * @see https://www.eecis.udel.edu/~mills/ntp/html/accopt.html#restrict + * @see ::NTP_RESTR_FLAG_MSKS + */ +enum NTP_RESTR_FLAGS +{ + NTP_RESTR_FLAG_FLAKE, + NTP_RESTR_FLAG_IGNORE, + NTP_RESTR_FLAG_KOD, + NTP_RESTR_FLAG_LIMITED, + NTP_RESTR_FLAG_LOWPRIOTRAP, + NTP_RESTR_FLAG_MSSNTP, + NTP_RESTR_FLAG_NOMODIFY, + NTP_RESTR_FLAG_NOQUERY, + NTP_RESTR_FLAG_NOPEER, + NTP_RESTR_FLAG_NOSERVE, + NTP_RESTR_FLAG_NOTRAP, + NTP_RESTR_FLAG_NOTRUST, + NTP_RESTR_FLAG_NTPPORT, + NTP_RESTR_FLAG_VERSION, + NTP_RESTR_FLAG_IPV4, ///< This default restriction only applies to IPv4 + NTP_RESTR_FLAG_IPV6, ///< This default restriction only applies to IPv6 + N_NTP_RESTR_FLAGS +}; + + + +/** + * @brief Flag masks associated with ::NTP_RESTR_FLAGS + * + * Used with ::NTP_RESTR::flags and ::NTP_RESTR_LIMITS::supp_flags + * + * @see ::NTP_RESTR_FLAGS + */ +enum NTP_RESTR_FLAG_MSKS +{ + NTP_RESTR_FLAG_MSK_FLAKE = ( 1UL << NTP_RESTR_FLAG_FLAKE ), ///< See ::NTP_RESTR_FLAG_FLAKE + NTP_RESTR_FLAG_MSK_IGNORE = ( 1UL << NTP_RESTR_FLAG_IGNORE ), ///< See ::NTP_RESTR_FLAG_IGNORE + NTP_RESTR_FLAG_MSK_KOD = ( 1UL << NTP_RESTR_FLAG_KOD ), ///< See ::NTP_RESTR_FLAG_KOD + NTP_RESTR_FLAG_MSK_LIMITED = ( 1UL << NTP_RESTR_FLAG_LIMITED ), ///< See ::NTP_RESTR_FLAG_LIMITED + NTP_RESTR_FLAG_MSK_LOWPRIOTRAP = ( 1UL << NTP_RESTR_FLAG_LOWPRIOTRAP ),///< See ::NTP_RESTR_FLAG_LOWPRIOTRAP + NTP_RESTR_FLAG_MSK_MSSNTP = ( 1UL << NTP_RESTR_FLAG_MSSNTP ), ///< See ::NTP_RESTR_FLAG_MSSNTP + NTP_RESTR_FLAG_MSK_NOMODIFY = ( 1UL << NTP_RESTR_FLAG_NOMODIFY ), ///< See ::NTP_RESTR_FLAG_NOMODIFY + NTP_RESTR_FLAG_MSK_NOQUERY = ( 1UL << NTP_RESTR_FLAG_NOQUERY ), ///< See ::NTP_RESTR_FLAG_NOQUERY + NTP_RESTR_FLAG_MSK_NOPEER = ( 1UL << NTP_RESTR_FLAG_NOPEER ), ///< See ::NTP_RESTR_FLAG_NOPEER + NTP_RESTR_FLAG_MSK_NOSERVE = ( 1UL << NTP_RESTR_FLAG_NOSERVE ), ///< See ::NTP_RESTR_FLAG_NOSERVE + NTP_RESTR_FLAG_MSK_NOTRAP = ( 1UL << NTP_RESTR_FLAG_NOTRAP ), ///< See ::NTP_RESTR_FLAG_NOTRAP + NTP_RESTR_FLAG_MSK_NOTRUST = ( 1UL << NTP_RESTR_FLAG_NOTRUST ), ///< See ::NTP_RESTR_FLAG_NOTRUST + NTP_RESTR_FLAG_MSK_NTPPORT = ( 1UL << NTP_RESTR_FLAG_NTPPORT ), ///< See ::NTP_RESTR_FLAG_NTPPORT + NTP_RESTR_FLAG_MSK_VERSION = ( 1UL << NTP_RESTR_FLAG_VERSION ), ///< See ::NTP_RESTR_FLAG_VERSION + NTP_RESTR_FLAG_MSK_IPV4 = ( 1UL << NTP_RESTR_FLAG_IPV4 ), ///< See ::NTP_RESTR_FLAG_IPV4 + NTP_RESTR_FLAG_MSK_IPV6 = ( 1UL << NTP_RESTR_FLAG_IPV6 ) ///< See ::NTP_RESTR_FLAG_IPV6 +}; + + + +/** + * @brief General NTP restriction limits to be read from a device + * + * Used to query from a device how many NTP restrictions are supported + * by the device, then index 0..::NTP_RESTR_LIMITS::cur_restrs-1 + * restriction records can be read from a device. A maximum of + * ::NTP_RESTR_LIMITS::max_restrs can be configured at all. + */ +typedef struct +{ + uint16_t max_restrs; ///< Number of maximum supported restrictions + uint16_t cur_restrs; ///< Number of currently configured restrictions + uint32_t supp_types; ///< Supported restriction types, see ::NTP_RESTR_TYPE_MSKS + uint32_t supp_flags; ///< Supported restriction flags, see ::NTP_RESTR_FLAG_MSKS + uint32_t reserved; ///< Future use + +} NTP_RESTR_LIMITS; + +#define _mbg_swab_ntp_restr_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->max_restrs ); \ + _mbg_swab16( &(_p)->cur_restrs ); \ + _mbg_swab32( &(_p)->supp_types ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + +/** + * @brief NTP restriction + * + * Structure contains all flags and information needed for a valid NTP restriction + * as described in the manual pages at ntp.org. + */ +typedef struct +{ + uint8_t type; ///< Restriction type, see ::NTP_RESTR_TYPES + uint8_t reserved_1; ///< Future use + uint16_t reserved_2; ///< Future use + uint32_t flags; ///< Restriction flags, see ::NTP_RESTR_FLAG_MSKS + + MBG_HOSTNAME addr; ///< Used if ::NTP_RESTR::type == ::NTP_RESTR_TYPE_ADDRESS. + ///< Can contain a hostname, or an IPv4 or IPv6 address + ///< with or without CIDR extension (e.g. 172.16.0.0/16). +} NTP_RESTR; + +#define _mbg_swab_ntp_restr( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab_ntp_restr_discard( &(_p)->u.discard ); \ +} while ( 0 ) + + + +/** + * @brief NTP restriction, plus index + * + * @see ::NTP_RESTR + */ +typedef struct +{ + uint32_t idx; + NTP_RESTR restr; + +} NTP_RESTR_IDX; + +#define _mbg_swab_ntp_restr_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ntp_restr( &(_p)->restr ); \ +} while ( 0 ) + + + +/** + * @brief General NTP "discard" rate limiting limits to be read from a device + * + * Used to query from a device what range of values is supported + * for the NTP "discard" rate limiting configuration. + */ +typedef struct +{ + uint8_t avg_min; ///< Minimum value for avg + uint8_t avg_max; ///< Maximum value for avg + uint8_t min_min; ///< Minimum value for min + uint8_t min_max; ///< Maximum value for min + uint16_t monitor_min; ///< Maximum value for min + uint16_t monitor_max; ///< Maximum value for min + + uint32_t reserved; ///< Future use + +} NTP_DISCARD_LIMITS; + +#define _mbg_swab_ntp_discard_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->monitor_min ); \ + _mbg_swab16( &(_p)->monitor_max ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + + + +/** + * @brief NTP "discard" rate limiting settings as described at ntp.org. + */ +typedef struct +{ + uint8_t avg; ///< Specify the minimum average interpacket spacing in log2 s. + uint8_t min; ///< Specify the minimum interpacket spacing (guard time) in seconds. + uint16_t monitor; ///< ### TODO Which is the unit of this field? + uint32_t reserved; ///< Possible future use + +} NTP_DISCARD_SETTINGS; + +#define _mbg_swab_ntp_discard_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->monitor ); \ + _mbg_swab32( &(_p)->reserved ); \ +} while ( 0 ) + + +/** + * @brief Enumeration of 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 + * + * Used with ::NTP_REFCLK_CFG_SETTINGS::type + * + * @see https://www.eecis.udel.edu/~mills/ntp/html/refclock.html + * @see ::NTP_REFCLK_TYPE_MSKS + */ +enum NTP_REFCLK_TYPES +{ + NTP_REFCLK_TYPE_LOCAL, ///< NTP local clock + NTP_REFCLK_TYPE_TRUETIME, ///< NTP Truetime driver + NTP_REFCLK_TYPE_PARSE, ///< NTP parse driver + NTP_REFCLK_TYPE_NMEA, ///< NTP NMEA driver + NTP_REFCLK_TYPE_PPS, ///< NTP atom driver (standalone PPS) + NTP_REFCLK_TYPE_SHM, ///< NTP shared memory driver + N_NTP_REFCLK_TYPES +}; + + + +/** + * @brief Bit masks associated with ::NTP_REFCLK_TYPES + * + * Used with ::NTP_REFCLK_CFG_INFO::supp_refclk_types + * + * @see ::NTP_REFCLK_TYPES + */ +enum NTP_REFCLK_TYPE_MSKS +{ + NTP_REFCLK_TYPE_MSK_LOCAL = ( 1UL << NTP_REFCLK_TYPE_LOCAL ), ///< See ::NTP_REFCLK_TYPE_LOCAL + NTP_REFCLK_TYPE_MSK_TRUETIME = ( 1UL << NTP_REFCLK_TYPE_TRUETIME ), ///< See ::NTP_REFCLK_TYPE_TRUETIME + NTP_REFCLK_TYPE_MSK_PARSE = ( 1UL << NTP_REFCLK_TYPE_PARSE ), ///< See ::NTP_REFCLK_TYPE_PARSE + NTP_REFCLK_TYPE_MSK_NMEA = ( 1UL << NTP_REFCLK_TYPE_NMEA ), ///< See ::NTP_REFCLK_TYPE_NMEA + NTP_REFCLK_TYPE_MSK_PPS = ( 1UL << NTP_REFCLK_TYPE_PPS ), ///< See ::NTP_REFCLK_TYPE_PPS + NTP_REFCLK_TYPE_MSK_SHM = ( 1UL << NTP_REFCLK_TYPE_SHM ) ///< See ::NTP_REFCLK_TYPE_SHM +}; + + +/** + * @brief Numbers related to the "fudge" flags used with ntpd's refclock interface. + * + * Used with ::NTP_REFCLK_CFG_SETTINGS::drv_flags_enable + * and ::NTP_REFCLK_CFG_SETTINGS::drv_flags_value. + * + * The refclock interface provided by @a ntpd supports a number of flags + * (flag1..flag4) which can be "fudged" in @a ntp.conf to control specific + * features of a particular refclock driver, e.g.: + * "fudge 127.127.8.0 flag1 1" + * + * Which feature is controlled by which flag depends on the refclock + * driver type, so usually each flag has a different meaning for + * different refclock types. + * + * There are different cases to be distinguished: + * + * - If a flag is not specified at all in @a ntp.conf then + * the controlled feature is enabled or disabled + * according to the driver's default settings. + * + * - If a flag is specified as '0' or '1' in @a ntp.conf then + * the controlled feature is enabled or disabled + * according to the value of the flag. + * + * Thus, the bit mask in ::NTP_REFCLK_CFG_SETTINGS::drv_flags_enable + * controls if the associated fudge flag should be specified in ntp.conf, + * and if it is specified then the associated bit in + * ::NTP_REFCLK_CFG_SETTINGS::drv_flags_value controls if the fudge flag + * is set to 0 or 1. + * + * @anchor NTP_FUDGE_FLAG_NUMBERS @{ */ + +#define NTP_MIN_REFCLOCK_FUDGE_FLAG 1 ///< minimum refclock fudge flag number, associated with bit 0 +#define N_NTP_REFCLOCK_FUDGE_FLAGS 4 ///< the number of supported fudge flags + +/** @} anchor NTP_FUDGE_FLAG_NUMBERS */ + + +/** + * @brief NTP refclock specific settings + * + * Used to configure a NTP refclock. + */ +typedef struct +{ + uint8_t type; ///< See ::NTP_REFCLK_TYPES + uint8_t instance; ///< Refclock instance of the specified type. Usually up to 4 instances of the same type are supported by ntpd. + uint8_t mode; ///< Driver specific "mode" ::FIXME Flag to enable "mode"? + int8_t stratum; ///< Stratum number to be fudged; -1 if unspecified and thus default is to be used + + int8_t refid[4]; ///< Reference id used by driver ::FIXME Flag to enable "refid"? + + uint8_t minpoll; ///< Minimum polling interval, [log2 seconds], 0 if unused/unspecified + uint8_t maxpoll; ///< Maximum polling interval, [log2 seconds], 0 if unused/unspecified + uint8_t reserved_1; ///< Future use + uint8_t reserved_2; ///< Future use + + NANO_TIME_64 time1; ///< Driver specific + NANO_TIME_64 time2; ///< Driver specific + + uint16_t drv_flags_enable; ///< Enable/disable driver specific flags, see @ref NTP_FUDGE_FLAG_NUMBERS + uint16_t drv_flags_value; ///< 0 or 1, if (drv_flags_enable & x) == 1, see @ref NTP_FUDGE_FLAG_NUMBERS + + uint32_t flags; ///< See @ref NTP_FLAG_MASKS. Only flags specified in ::FIXME can be used here. + + uint32_t reserved_3; ///< Future use + +} NTP_REFCLK_CFG_SETTINGS; + +#define _mbg_swab_ntp_refclk_cfg_settings( _p ) \ +do \ +{ \ + _mbg_swab_nano_time_64( &(_p)->time1 ); \ + _mbg_swab_nano_time_64( &(_p)->time2 ); \ + _mbg_swab16( &(_p)->drv_flags_enable ); \ + _mbg_swab16( &(_p)->drv_flags_value ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief NTP refclock settings index + * + * @see ::NTP_REFCLK_CFG_SETTINGS + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + NTP_REFCLK_CFG_SETTINGS settings; ///< See ::NTP_REFCLK_CFG_SETTINGS + +} NTP_REFCLK_CFG_SETTINGS_IDX; + +#define _mbg_swab_ntp_refclk_cfg_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _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 an NTP refclock configuration + * and get to know its overall supported refclocks. + */ +typedef struct +{ + NTP_REFCLK_CFG_SETTINGS settings; ///< See ::NTP_REFCLK_CFG_SETTINGS + + 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; + +#define _mbg_swab_ntp_refclk_cfg_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_refclk_cfg_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_refclk_types ); \ +} while ( 0 ) + + + +/** + * @brief NTP refclock info, with index + * + * @see ::NTP_REFCLK_CFG_INFO + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + NTP_REFCLK_CFG_INFO info; + +} NTP_REFCLK_CFG_INFO_IDX; + +#define _mbg_swab_ntp_refclk_cfg_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ntp_refclk_cfg_info( &(_p)->info ); \ +} while ( 0 ) + + +enum NTP_SYMM_KEY_FLAGS +{ + NTP_SYMM_KEY_WHITELIST, ///< The device supports whitelisting for symmetric keys + N_NTP_SYMM_KEY_FLAGS +}; + + +enum NTP_SYMM_KEY_FLAG_MASKS +{ + NTP_SYMM_KEY_WHITELIST_MSK = ( 1UL << NTP_SYMM_KEY_WHITELIST ) ///< See ::NTP_SYMM_KEY_WHITELIST +}; + + +/** + * @brief Enumeration of NTP supported symmetric key hashing algorithms + * + * @see ::NTP_SYMM_KEY_HASH_MASKS + * + * @note Support of external libraries (e.g.: OpenSSL) may be needed for + * some hashing algorithms. + */ +enum NTP_SYMM_KEY_HASHES +{ + NTP_SYMM_KEY_HASH_MD5, ///< NTP supports MD5 as key hashing algorithm + NTP_SYMM_KEY_HASH_SHA1, ///< NTP supports SHA1 as key hashing algorithm + N_NTP_SYMM_KEY_HASHES +}; + + + +/** + * @brief Flag masks associated with ::NTP_SYMM_KEY_HASHES + * + * @see ::NTP_SYMM_KEY_HASHES + */ +enum NTP_SYMM_KEY_HASH_MASKS +{ + NTP_SYMM_KEY_HASH_MSK_MD5 = ( 1UL << NTP_SYMM_KEY_HASH_MD5 ), ///< See ::NTP_SYMM_KEY_HASH_MD5 + NTP_SYMM_KEY_HASH_MSK_SHA1 = ( 1UL << NTP_SYMM_KEY_HASH_SHA1 ), ///< See ::NTP_SYMM_KEY_HASH_SHA1 +}; + + +/** + * @brief Name strings for defined NTP symm key hashes + * + * @see ::NTP_SYMM_KEY_HASHES + */ +#define NTP_SYMM_KEY_HASHES_STRS \ +{ \ + "MD5", \ + "SHA1" \ +} + + + +/** + * @brief General NTP symmetric key limits to be read from a device + * + * ::NTP_SYMM_KEY_LIMITS::supp_hashes specifies supported hashing algorithms + * to create keys with. See ::NTP_SYMM_KEY_HASH_MASKS. Structure can be queried + * if ::NTP_MSK_SYMM_KEYS is set in ::NTP_GLB_INFO::supp_flags + */ +typedef struct +{ + uint16_t supp_hashes; ///< See ::NTP_SYMM_KEY_HASH_MASKS + uint16_t supp_flags; ///< See ::NTP_SYMM_KEY_FLAG_MASKS + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + uint32_t reserved_4; ///< Future use + +} NTP_SYMM_KEY_LIMITS; + +#define _mbg_swab_ntp_symm_key_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->supp_hashes ); \ + _mbg_swab16( &(_p)->supp_flags ); \ +} while ( 0 ) + + + +/// Maximum length of a symmetric key. 128 byte was chosen to be +/// prepared for hash algorithms like SHA256, SH384, up to SHA512. +#define N_NTP_SYMM_KEY_LEN 128 + +/// Maximum number of whitelist entries which can be assigned to one key in +/// order to limit its usage +#define NTP_SYMM_KEY_WHITELIST_LEN 8 + + + +/** + * @brief NTP symmetric key specific settings + * + * This structure is used to configure a symmetric key for NTP. + */ +typedef struct +{ + uint16_t id; ///< Configurable key id (1..65534) + uint8_t hash; ///< See ::NTP_SYMM_KEY_HASHES + uint8_t reserved_1; ///< Future use + + uint16_t reserved_2; ///< Future use + uint8_t num_whitelist_entries; ///< Number of configured whitelist entries + ///< only valid if ::NTP_SYMM_KEY_WHITELIST_MSK is set in ::NTP_SYMM_KEY_LIMITS::supp_flags + uint8_t reserved_3; ///< Future use + + uint8_t key[N_NTP_SYMM_KEY_LEN]; ///< Hashed phrase, see ::N_NTP_SYMM_KEY_LEN + + MBG_IP_ADDR whitelist_entries[NTP_SYMM_KEY_WHITELIST_LEN]; ///< Whitelist of ip addresses see ::NTP_SYMM_KEY_WHITELIST_LEN + ///< may only be used if ::NTP_SYMM_KEY_WHITELIST_MSK is set in ::NTP_SYMM_KEY_LIMITS::supp_flags + +} NTP_SYMM_KEY_SETTINGS; + +#define _mbg_swab_ntp_symm_key_settings( _p ) \ +do \ +{ \ + unsigned i; \ + \ + _mbg_swab16( &(_p)->id ); \ + \ + for ( i = 0; i < NTP_SYMM_KEY_WHITELIST_LEN; ++i) \ + _mbg_swab_ip_addr( &(_p)->whitelist_entries[i] ); \ +} while ( 0 ) + + + +/** + * @brief NTP symmetric key settings, with index + * + * @see ::NTP_SYMM_KEY_SETTINGS + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + NTP_SYMM_KEY_SETTINGS settings; + +} NTP_SYMM_KEY_SETTINGS_IDX; + +#define _mbg_swab_ntp_symm_key_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ntp_symm_key_settings( &(_p)->settings ); \ +} while ( 0 ) + + +/** + * @brief NTP symmkey info + * + * This structure is used to query a symmetric key for NTP. + */ +typedef struct +{ + NTP_SYMM_KEY_SETTINGS settings; + + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + uint32_t reserved_4; ///< Future use + +} NTP_SYMM_KEY_INFO; + +#define _mbg_swab_ntp_symm_key_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_symm_key_settings( &(_p)->settings ); \ +} while ( 0 ) + + +/** + * @brief NTP symm key info, with index + * + * @see ::NTP_SYMM_KEY_INFO + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + NTP_SYMM_KEY_INFO info; + +} NTP_SYMM_KEY_INFO_IDX; + +#define _mbg_swab_ntp_symm_key_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ntp_symm_key_info( &(_p)->info ); \ +} while ( 0 ) + + +/** + * @brief NTP trusted key settings + * + * This structure is used to configure a trusted symmetric key for NTP. + */ +typedef struct +{ + uint16_t id; ///< Configurable key id (1..65534) + uint16_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + +} NTP_TRUSTED_KEY_SETTINGS; + +#define _mbg_swab_ntp_trusted_key_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->id ); \ +} while ( 0 ) + + +/** + * @brief NTP trusted key settings, with index + * + * @see ::NTP_TRUSTED_KEY_SETTINGS + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + NTP_TRUSTED_KEY_SETTINGS settings; + +} NTP_TRUSTED_KEY_SETTINGS_IDX; + +#define _mbg_swab_ntp_trusted_key_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ntp_trusted_key_settings( &(_p)->settings ); \ +} while ( 0 ) + +/** + * @brief NTP trusted key info + * + * This structure is used to query a trusted symmetric key for NTP. + */ +typedef struct +{ + NTP_TRUSTED_KEY_SETTINGS settings; + + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + uint32_t reserved_4; ///< Future use + +} NTP_TRUSTED_KEY_INFO; + +#define _mbg_swab_ntp_trusted_key_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_trusted_key_settings( &(_p)->settings ); \ +} while ( 0 ) + + +/** + * @brief NTP trusted key info, with index + * + * @see ::NTP_TRUSTED_KEY_INFO + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + NTP_TRUSTED_KEY_INFO info; + +} NTP_TRUSTED_KEY_INFO_IDX; + +#define _mbg_swab_ntp_trusted_key_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ntp_trusted_key_info( &(_p)->info ); \ +} while ( 0 ) + + +/** + * @brief Enumeration of NTP supported (various) misc options + * + * @see ::NTP_MISC_MSKS + */ +enum NTP_MISC_FLAGS +{ + NTP_MISC_FLAG_DRIFTFILE, ///< NTP supports driftfile + NTP_MISC_FLAG_ORPHAN_MODE, ///< NTP supports orphan mode + NTP_MISC_FLAG_LEAPFILE, ///< NTP supports leapfile + N_NTP_MISC_FLAGS +}; + + + +/** + * @brief Flag masks associated with ::NTP_MISC_FLAGS + * + * @see ::NTP_MISC_FLAGS + */ +enum NTP_MISC_MSKS +{ + NTP_MISC_MSK_DRIFTFILE = ( 1UL << NTP_MISC_FLAG_DRIFTFILE ), ///< See ::NTP_MISC_FLAG_DRIFTFILE + NTP_MISC_MSK_ORPHAN_MODE = ( 1UL << NTP_MISC_FLAG_ORPHAN_MODE ), ///< See ::NTP_MISC_FLAG_ORPHAN_MODE + NTP_MISC_MSK_LEAPFILE = ( 1UL << NTP_MISC_FLAG_LEAPFILE ) ///< See ::NTP_MISC_FLAG_LEAPFILE +}; + + + +/** + * @brief General NTP misc limits to be read from a device + * + * This structure can be used to determine various NTP options + * and can be queried if ::NTP_MSK_MISCELLANEOUS bit is set in ::NTP_GLB_INFO::supp_flags. + */ +typedef struct +{ + uint32_t supp_flags; ///< See ::NTP_MISC_MSKS + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + +} NTP_MISC_LIMITS; + +#define _mbg_swab_ntp_misc_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + + +/** + * @brief NTP driftfile settings to be read from / written to a device + * + * If ::NTP_MISC_MSK_DRIFTFILE is set in ::NTP_MISC_LIMITS::supp_flags + * ::NTP_MISC_DRIFTFILE_SETTINGS can be read / written. + */ +typedef struct +{ + uint8_t enable; ///< Enable / disable writing a driftfile + uint8_t reserved_1; ///< Future use + uint16_t reserved_2; ///< Future use + +} NTP_MISC_DRIFTFILE_SETTINGS; + +#define _mbg_swab_ntp_misc_driftfile_settings( _p ) \ +do \ +{ \ +} while ( 0 ) + + +/** + * @brief Enumeration of NTP supported (various) misc options + * + * @see ::NTP_ORPHAN_MODE_MSK + */ +enum NTP_ORPHAN_MODE_FLAGS +{ + NTP_ORPHAN_MODE_FLAG_SUPP_DISABLE, ///< Orphan Mode support disabling + + N_NTP_ORPHAN_MODE_FLAGS +}; + + + +/** + * @brief Flag masks associated with ::NTP_ORPHAN_MODE_FLAGS + * + * @see ::NTP_ORPHAN_MODE_FLAGS + */ +enum NTP_ORPHAN_MODE_MSK +{ + NTP_ORPHAN_MODE_MSK_SUPP_DISABLE = ( 1UL << NTP_ORPHAN_MODE_FLAG_SUPP_DISABLE ) ///< See ::NTP_ORPHAN_MODE_FLAG_SUPP_DISABLE +}; + + +/** + * @brief NTP orphan mode settings to be read from / written to a device + * + * If ::NTP_MISC_MSK_ORPHAN_MODE is set in ::NTP_MISC_LIMITS::supp_flags + * ::NTP_MISC_ORPHAN_MODE_SETTINGS can be read / written. + */ +typedef struct +{ + uint8_t enable; ///< Generally enable / disable orphan mode + uint8_t mode; ///< Stratum level when no ref source available + uint16_t wait_time; ///< Time until stratum is degraded (orphan mode active) in seconds + + uint32_t reserved_2; ///< Future use + +} NTP_MISC_ORPHAN_MODE_SETTINGS; + +#define _mbg_swab_ntp_misc_orphan_mode_settings( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->enable ); \ + _mbg_swab8( &(_p)->mode ); \ + _mbg_swab16( &(_p)->wait_time ); \ +} while ( 0 ) + + +/** + * @brief NTP orphan mode info + * + */ +typedef struct +{ + NTP_MISC_ORPHAN_MODE_SETTINGS settings; ///< See ::NTP_MISC_ORPHAN_MODE_SETTINGS + + uint32_t supp_flags; ///< See ::NTP_ORPHAN_MODE_MSK + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + +} NTP_MISC_ORPHAN_MODE_INFO; + +#define _mbg_swab_ntp_misc_orphan_mode_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_misc_orphan_mode_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + +/** + * @brief NTP leapfile settings to be read from / written to a device + * + * If ::NTP_MISC_MSK_LEAPFILE is set in ::NTP_MISC_LIMITS::supp_flags + * ::NTP_MISC_LEAPFILE_SETTINGS can be read / written. + */ +typedef struct +{ + uint8_t enable; ///< Generally enable / disable leapfile + uint8_t reserved_1; ///< Stratum level when no ref source available + uint16_t reserved_2; ///< Future use + +} NTP_MISC_LEAPFILE_SETTINGS; + +#define _mbg_swab_ntp_misc_leapfile_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->reserved_2 ); \ +} while ( 0 ) + + +/** + * @brief Client settings of an NTP device + * + * This structure should be sent to an NTP client to configure client parameters + */ +typedef struct +{ + uint8_t num_peers; ///< number available peers + uint8_t reserved_1; ///< reserved, currently 0 + uint16_t reserved_2; ///< reserved, currently 0 + + uint32_t reserved_3; ///< reserved, currently 0 + + uint32_t flags; ///< NTP flags, see @ref NTP_FLAG_MASKS + +} NTP_CLNT_MODE_SETTINGS; + +#define _mbg_swab_ntp_clnt_mode_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Client settings info of an NTP device + * + * This structure can be used to determine possible NTP client settings and the current configuration + */ +typedef struct ntp_clnt_mode_info_s +{ + NTP_CLNT_MODE_SETTINGS settings; + + uint8_t n_supp_peers; ///< maximal number of configurable peers + uint8_t n_supp_pref_peers; ///< maximal number of configurable preferred ref sources + uint8_t poll_intv_min; ///< minimal supported NTP polling interval + uint8_t poll_intv_max; ///< maximal supported NTP polling interval + + uint32_t reserved_1; ///< reserved, currently 0 + uint32_t reserved_2; ///< reserved, currently 0 + + uint32_t supp_flags; ///< supported NTP flags, see @ref NTP_FLAG_MASKS + uint32_t supp_peer_flags; ///< supported NTP flags for peers, see @ref NTP_FLAG_MASKS + +} NTP_CLNT_MODE_INFO; + +#define _mbg_swab_ntp_clnt_mode_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_clnt_mode_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->supp_flags ); \ + _mbg_swab32( &(_p)->supp_peer_flags ); \ +} while ( 0 ) + + + +/** + * @brief General NTP peer settings limits to be read from a device + * + * Used to query from a device how many NTP associations are supported + * by the device, then index 0..::NTP_PEER_LIMITS::n_cur_peers-1 + * peer records can be read from a device. A maximum of + * ::NTP_PEER_LIMITS::n_supp_peers can be configured at all. + */ +typedef struct +{ + uint16_t n_supp_peers; ///< maximum number of configurable peers + uint16_t n_cur_peers; ///< current number of configured peers + + uint8_t poll_intv_min; ///< minimum supported NTP polling interval + uint8_t poll_intv_max; ///< maximum supported NTP polling interval + uint8_t reserved_1; ///< reserved, currently 0 + uint8_t reserved_2; ///< reserved, currently 0 + + uint32_t supp_assoc_types; ///< supported types of NTP associations + uint32_t reserved_3; ///< reserved, currently 0 + + uint32_t supp_flags_server; ///< supported flags for unicast associations + uint32_t supp_flags_peer; ///< supported flags for unicast symmetric-active assocations + uint32_t supp_flags_pool; ///< supported flags for unicast pool associations + uint32_t supp_flags_broadcast; ///< supported flags for broadcast associations + uint32_t supp_flags_multicast; ///< supported flags for multicast associations + uint32_t supp_flags_manycast; ///< supported flags for manycast associations + uint32_t supp_flags_broadcastclient; ///< supported flags for broadcast client associations + uint32_t supp_flags_multicastclient; ///< supported flags for multicast client associations + uint32_t supp_flags_manycastclient; ///< supported flags for manycast client associations + uint32_t reserved_4; ///< reserved, currently 0 + uint32_t reserved_5; ///< reserved, currently 0 + uint32_t reserved_6; ///< reserved, currently 0 + +} NTP_PEER_LIMITS; + +#define _mbg_swab_ntp_peer_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->n_supp_peers ); \ + _mbg_swab16( &(_p)->n_cur_peers ); \ + _mbg_swab32( &(_p)->supp_assoc_types ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->supp_flags_server ); \ + _mbg_swab32( &(_p)->supp_flags_peer ); \ + _mbg_swab32( &(_p)->supp_flags_pool ); \ + _mbg_swab32( &(_p)->supp_flags_broadcast ); \ + _mbg_swab32( &(_p)->supp_flags_multicast ); \ + _mbg_swab32( &(_p)->supp_flags_manycast ); \ + _mbg_swab32( &(_p)->supp_flags_broadcastclient ); \ + _mbg_swab32( &(_p)->supp_flags_multicastclient ); \ + _mbg_swab32( &(_p)->supp_flags_manycastclient ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->reserved_5 ); \ + _mbg_swab32( &(_p)->reserved_6 ); \ +} while ( 0 ) + + + +/** + * @brief Peer settings for NTP devices to configure an upload NTP server + * + * This structure should be read from the NTP client device to retrieve the + * current settings and capabilities. The number of supported peers is + * ::NTP_CLNT_MODE_INFO::n_supp_peers. + * + * @note The ::NTP_PEER_SETTINGS_IDX structure should be send back + * to the device to save the configuration. + */ +typedef struct +{ + MBG_HOSTNAME hostname; ///< hostname or IP address of the peer, not used + ///< when the NTP_BROADCASTCLIENT flag is set + + uint8_t min_poll; ///< minimal configurable NTP polling interval + uint8_t max_poll; ///< maximal configurable NTP polling interval + uint8_t ttl; ///< time-to-live to use with broadcast/multicast/manycast + uint8_t reserved_1; ///< reserved, currently 0 + + uint32_t key; ///< ID of the symmetric key used with this association, + ///< this must be in the range 1-65534, 0 = disabled + uint32_t reserved_3; ///< reserved, currently 0 + uint32_t reserved_4; ///< reserved, currently 0 + + uint32_t flags; ///< additional options configured, see @ref NTP_FLAG_MASKS + +} NTP_PEER_SETTINGS; + +#define _mbg_swab_ntp_peer_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->key ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Peer settings for NTP devices + * + * @see ::NTP_PEER_SETTINGS + */ +typedef struct ntp_peer_settings_idx_s +{ + MBG_MSG_IDX_32 idx; + NTP_PEER_SETTINGS peer_settings; + +} NTP_PEER_SETTINGS_IDX; + +#define _mbg_swab_ntp_peer_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ntp_peer_settings( &(_p)->peer_settings ); \ +} while ( 0 ) + + +/** + * @brief Server settings of an NTP device + * + * This structure should be sent to an NTP server to configure server parameters + */ +typedef struct +{ + uint8_t num_refclks; ///< number of available refclks @ref NTP_REFCLK_CFG_INFO + uint8_t reserved_1; ///< reserved, currently 0 + uint16_t reserved_2; ///< reserved, currently 0 + + uint32_t reserved_3; ///< reserved, currently 0 + + uint32_t flags; ///< NTP flags, see @ref NTP_FLAG_MASKS + +} NTP_SRV_MODE_SETTINGS; + +#define _mbg_swab_ntp_srv_mode_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + +/** + * @brief Server settings info of an NTP device + * + * This structure should be used to query an NTP server configuration from a device + */ +typedef struct ntp_srv_mode_info_s +{ + NTP_SRV_MODE_SETTINGS settings; + + uint8_t max_refclks; ///< number of supported refclks @ref NTP_REFCLK_CFG_INFO + uint8_t reserved_1; ///< reserved, currently 0 + uint16_t reserved_2; ///< reserved, currently 0 + + uint32_t reserved_3; ///< reserved, currently 0 + + uint32_t supp_flags; ///< supported NTP flags, see @ref NTP_FLAG_MASKS + +} NTP_SRV_MODE_INFO; + +#define _mbg_swab_ntp_srv_mode_info( _p ) \ +do \ +{ \ + _mbg_swab_ntp_srv_mode_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + +/** + * @brief Structure that represents a timestamp in NTP Short Format + * + * Maximal value for seconds is 65535. + * Resolution of fractions is 15 microseconds. + */ +typedef struct +{ + uint16_t seconds; + uint16_t fractions; + +} NTP_SHORT_TSTAMP; + +#define _mbg_swab_ntp_short_tstamp( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->seconds ); \ + _mbg_swab16( &(_p)->fractions ); \ +} + + + +/** + * @brief Structure that represents a timestamp in NTP Timestamp Format + */ +typedef struct +{ + uint32_t seconds; ///< seconds since NTP epoch, see ::NTP_SEC_BIAS + uint32_t fractions; ///< binary fractional part of a second, 0xFFFFFFFF -> 0.9999999... s (resolution 2^-32s =~ 233 ps) + +} NTP_TSTAMP; + +#define _mbg_swab_ntp_tstamp( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->seconds ); \ + _mbg_swab32( &(_p)->fractions ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of known NTP implementations + * + * Used with ::NTP_SYS_STATE::impl_type + */ +enum NTP_IMPL +{ + NTP_IMPL_UNKNOWN = 0, ///< Unknown NTP implementation + NTP_IMPL_NTPD, ///< Network Time Protocol daemon (ntpd) + NTP_IMPL_NTPDATE, ///< NTP client only (ntpdate) + NTP_IMPL_SNTP, ///< Simple Network Time Protocol (sntp) + NTP_IMPL_W32TIME, ///< Windows time service (w32time) + NTP_IMPL_MBGNTP, ///< Meinberg NTP implementation (mbgntp) + N_NTP_IMPLS +}; + +/* + * Default initializers for English leapsecond string names. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_IMPL_STR_ENG "Implemetation Type:" + +#define MBG_NTP_IMPL_STR_ENG_UNKNOWN "Unknown NTP implementation" +#define MBG_NTP_IMPL_STR_ENG_NTPD "Network Time Protocol daemon (ntpd)" +#define MBG_NTP_IMPL_STR_ENG_NTPDATE "NTP client only (ntpdate)" +#define MBG_NTP_IMPL_STR_ENG_SNTP "Simple Network Time Protocol (sntp)" +#define MBG_NTP_IMPL_STR_ENG_W32TIME "Windows time service (w32time)" +#define MBG_NTP_IMPL_STR_ENG_MBGNTP "Meinberg NTP implementation (mbgntp)" + + +#define MBG_NTP_IMPL_NAMES_ENG \ +{ \ + MBG_NTP_IMPL_STR_ENG_UNKNOWN, \ + MBG_NTP_IMPL_STR_ENG_NTPD, \ + MBG_NTP_IMPL_STR_ENG_NTPDATE, \ + MBG_NTP_IMPL_STR_ENG_SNTP, \ + MBG_NTP_IMPL_STR_ENG_W32TIME, \ + MBG_NTP_IMPL_STR_ENG_MBGNTP \ +} + + + +/** + * @brief Enumeration of CPU types using NTP + * + * Used with ::NTP_SYS_STATE::cpu_type + */ +enum NTP_CPU_TYPES +{ + NTP_CPU_TYPE_UNKNOWN = 0, + NTP_CPU_TYPE_X86, + NTP_CPU_TYPE_I386, + NTP_CPU_TYPE_I486, + NTP_CPU_TYPE_I586, + NTP_CPU_TYPE_I686, + NTP_CPU_TYPE_X64, + NTP_CPU_TYPE_X86_64, + NTP_CPU_TYPE_AMD64, + NTP_CPU_TYPE_SUN4U, + NTP_CPU_TYPE_ARM, + N_NTP_CPU_TYPES +}; + + + +/** + * @brief Name strings for known CPU types using NTP + * + * @see ::NTP_CPU_TYPES + */ +#define NTP_CPU_TYPES_STRS \ +{ \ + "Unknown", \ + "x86", \ + "i386", \ + "i486", \ + "i586", \ + "i686", \ + "x64", \ + "x86_64", \ + "amd64", \ + "sun4u", \ + "arm" \ +} + + + +/** + * @brief Enumeration of operating systems using NTP + * + * Used with ::NTP_SYS_STATE::system +*/ +enum NTP_SYSTEMS +{ + NTP_SYSTEM_UNKNOWN = 0, + NTP_SYSTEM_NONE, + NTP_SYSTEM_WINDOWS, + NTP_SYSTEM_LINUX, + NTP_SYSTEM_BSD, + NTP_SYSTEM_SOLARIS, + N_NTP_SYSTEMS +}; + + + +/** + * @brief Name strings for operating systens using NTP + * + * @see ::NTP_SYSTEMS + */ +#define NTP_SYSTEMS_STRS \ +{ \ + "Unknown", \ + "No OS", \ + "Windows", \ + "Linux", \ + "BSD", \ + "Solaris" \ +} + + + +/** + * @brief Enumeration of NTP leap indication bits + * + * Used with ::NTP_SYS_STATE::leap_ind + * + */ +enum NTP_LI_BITS +{ + NTP_LEAP_NONE = 0, ///< normal synchronized state + NTP_LEAP_ADD_SEC, ///< insert second after 23:59:59 of the current day + NTP_LEAP_DEL_SEC, ///< delete second 23:59:59 of the current day + NTP_LEAP_ALARM, ///< never synchronized + N_NTP_LI_BITS +}; + + + +/* + * Default initializers for English leapsecond string names. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_LEAP_STR_ENG "Leapsecond indication:" + +#define MBG_NTP_LEAP_STR_ENG_NONE "None" +#define MBG_NTP_LEAP_STR_ENG_ADD_SEC "Insert second" +#define MBG_NTP_LEAP_STR_ENG_DEL_SEC "Delete second" +#define MBG_NTP_LEAP_STR_ENG_ALARM "Alarm" + +#define MBG_NTP_LEAP_NAMES_ENG \ +{ \ + MBG_NTP_LEAP_STR_ENG_NONE, \ + MBG_NTP_LEAP_STR_ENG_ADD_SEC, \ + MBG_NTP_LEAP_STR_ENG_DEL_SEC, \ + MBG_NTP_LEAP_STR_ENG_ALARM \ +} + + + +/** + * @brief Enumeration of NTP synchronization source bits + * + * Used with ::NTP_SYS_STATE::sys_sync_src + * + */ +enum NTP_SYNC_SRC_BITS +{ + NTP_SYNC_SRC_UNSPEC = 0, ///< not yet synchronized + NTP_SYNC_SRC_PPS, ///< pulse-per-second signal (Cs, Ru, GPS, etc.) + NTP_SYNC_SRC_LF_RADIO, ///< VLF/LF radio (WWVB, DCF77, etc.) + NTP_SYNC_SRC_HF_RADIO, ///< MF/HF radio (WWV, etc.) + NTP_SYNC_SRC_UHF_RADIO, ///< VHF/UHF radio/satellite (GPS, Galileo, etc.) + NTP_SYNC_SRC_LOCAL, ///< local timecode (IRIG, LOCAL driver, etc.) + NTP_SYNC_SRC_NTP, ///< NTP + NTP_SYNC_SRC_OTHER, ///< other (IEEE 1588, openntp, crony, etc.) + NTP_SYNC_SRC_WRISTWATCH, ///< eyeball and wristwatch + NTP_SYNC_SRC_TELEPHONE, ///< telephone modem (ACTS, PTB, etc.) + N_NTP_SYNC_SRC_BITS +}; + + + +/* + * Default initializers for English sync source string names. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_SYNC_SRC_STR_ENG_LABEL "Sync Source:" + +#define MBG_NTP_SYNC_SRC_STR_ENG_UNSPEC "Not yet synchronized" +#define MBG_NTP_SYNC_SRC_STR_ENG_PPS "Pulse per second signal" +#define MBG_NTP_SYNC_SRC_STR_ENG_LF_RADIO "VLF/LF radio" +#define MBG_NTP_SYNC_SRC_STR_ENG_HF_RADIO "MF/HF radio" +#define MBG_NTP_SYNC_SRC_STR_ENG_UHF_RADIO "VHF/UHF radio/satellite" +#define MBG_NTP_SYNC_SRC_STR_ENG_LOCAL "local timecode" +#define MBG_NTP_SYNC_SRC_STR_ENG_NTP "NTP" +#define MBG_NTP_SYNC_SRC_STR_ENG_OTHER "other" +#define MBG_NTP_SYNC_SRC_STR_ENG_WRISTWATCH "eyeball and wristwatch" +#define MBG_NTP_SYNC_SRC_STR_ENG_TELEPHONE "telephone modem" + +#define MBG_NTP_SYNC_SRC_NAMES_ENG \ +{ \ + MBG_NTP_SYNC_SRC_STR_ENG_UNSPEC, \ + MBG_NTP_SYNC_SRC_STR_ENG_PPS, \ + MBG_NTP_SYNC_SRC_STR_ENG_LF_RADIO, \ + MBG_NTP_SYNC_SRC_STR_ENG_HF_RADIO, \ + MBG_NTP_SYNC_SRC_STR_ENG_UHF_RADIO, \ + MBG_NTP_SYNC_SRC_STR_ENG_LOCAL, \ + MBG_NTP_SYNC_SRC_STR_ENG_NTP, \ + MBG_NTP_SYNC_SRC_STR_ENG_OTHER, \ + MBG_NTP_SYNC_SRC_STR_ENG_WRISTWATCH, \ + MBG_NTP_SYNC_SRC_STR_ENG_TELEPHONE \ +} + + + +/** + * @brief Enumeration of NTP system event message bits + * + * Used with ::NTP_SYS_STATE::sys_rec_evt + * + */ +enum NTP_SYS_EVT_BITS +{ + NTP_SYS_EVT_UNSPEC = 0, ///< unspecified NTP event + NTP_SYS_EVT_FREQ_NOT_SET, ///< frequency file not available + NTP_SYS_EVT_FREQ_SET, ///< frequency set from frequency file + NTP_SYS_EVT_SPIKE_DETECT, ///< spike detected + NTP_SYS_EVT_FREQ_MODE, ///< initial frequency training mode + NTP_SYS_EVT_CLOCK_SYNC, ///< clock synchronized + NTP_SYS_EVT_RESTART, ///< program restart + NTP_SYS_EVT_PANIC_STOP, ///< clock error more than 600 s + NTP_SYS_EVT_NO_SYSTEM_PEER, ///< no system peer + NTP_SYS_EVT_LEAP_ARMED, ///< leap second armed from file or autokey + NTP_SYS_EVT_LEAP_DISARMED, ///< leap second disarmed + NTP_SYS_EVT_LEAP_EVENT, ///< leap event + NTP_SYS_EVT_CLOCK_STEP, ///< clock stepped + NTP_SYS_EVT_KERNEL, ///< kernel information message + NTP_SYS_EVT_TAI, ///< leapsecond values update from file + NTP_SYS_EVT_STALE_LS_VALUES, ///< new NIST leapseconds file needed + N_NTP_SYS_EVT_BITS +}; + + + +/* + * Default initializers for English sync source string names. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_SYS_EVT_STR_ENG_CNT_LABEL "System Event Counter:" +#define MBG_NTP_SYS_EVT_STR_ENG_MSG_LABEL "System Event Message:" + +#define MBG_NTP_SYS_EVT_STR_ENG_UNSPEC "Unspecified NTP event" +#define MBG_NTP_SYS_EVT_STR_ENG_FREQ_NOT_SET "Frequency file not available" +#define MBG_NTP_SYS_EVT_STR_ENG_FREQ_SET "Frequency set from frequency file" +#define MBG_NTP_SYS_EVT_STR_ENG_SPIKE_DETECT "Spike detected" +#define MBG_NTP_SYS_EVT_STR_ENG_FREQ_MODE "Initial frequency training mode" +#define MBG_NTP_SYS_EVT_STR_ENG_CLOCK_SYNC "Clock synchronized" +#define MBG_NTP_SYS_EVT_STR_ENG_RESTART "Program restart" +#define MBG_NTP_SYS_EVT_STR_ENG_PANIC_STOP "Clock error more than 600 s" +#define MBG_NTP_SYS_EVT_STR_ENG_NO_SYSTEM_PEER "No system peer" +#define MBG_NTP_SYS_EVT_STR_ENG_LEAP_ARMED "Leap second armed from file or autokey" +#define MBG_NTP_SYS_EVT_STR_ENG_LEAP_DISARMED "Leap second disarmed" +#define MBG_NTP_SYS_EVT_STR_ENG_LEAP_EVENT "Leap event" +#define MBG_NTP_SYS_EVT_STR_ENG_CLOCK_STEP "Clock stepped" +#define MBG_NTP_SYS_EVT_STR_ENG_KERNEL "Kernel information message" +#define MBG_NTP_SYS_EVT_STR_ENG_TAI "Leap second values update from file" +#define MBG_NTP_SYS_EVT_STR_ENG_STALE_LS_VALUES "New NIST leapseconds file needed" + + +#define MBG_NTP_SYS_EVT_NAMES_ENG \ +{ \ + MBG_NTP_SYS_EVT_STR_ENG_UNSPEC, \ + MBG_NTP_SYS_EVT_STR_ENG_FREQ_NOT_SET, \ + MBG_NTP_SYS_EVT_STR_ENG_FREQ_SET, \ + MBG_NTP_SYS_EVT_STR_ENG_SPIKE_DETECT, \ + MBG_NTP_SYS_EVT_STR_ENG_FREQ_MODE, \ + MBG_NTP_SYS_EVT_STR_ENG_CLOCK_SYNC, \ + MBG_NTP_SYS_EVT_STR_ENG_RESTART, \ + MBG_NTP_SYS_EVT_STR_ENG_PANIC_STOP, \ + MBG_NTP_SYS_EVT_STR_ENG_NO_SYSTEM_PEER, \ + MBG_NTP_SYS_EVT_STR_ENG_LEAP_ARMED, \ + MBG_NTP_SYS_EVT_STR_ENG_LEAP_DISARMED, \ + MBG_NTP_SYS_EVT_STR_ENG_LEAP_EVENT, \ + MBG_NTP_SYS_EVT_STR_ENG_CLOCK_STEP, \ + MBG_NTP_SYS_EVT_STR_ENG_KERNEL, \ + MBG_NTP_SYS_EVT_STR_ENG_TAI, \ + MBG_NTP_SYS_EVT_STR_ENG_STALE_LS_VALUES \ +} + + + +/** + * @brief Enumeration of supported NTP system state values + * + * @see ::NTP_SYS_STATE_SUPP_FLAG_MASKS + */ +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_SERVICE_STATE, ///< supports service state, see ::NTP_SYS_STATE::service_state + N_NTP_SYS_STATE_SUPP_FLAGS +}; + + + +/** + * @brief Flag masks for NTP_SYS_STATE_SUPP_FLAGS + * + * Used with ::NTP_SYS_STATE::supp_flags + * + * @see ::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_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 + * + * This structure can be requested from a monitoring program to determine the device system status + */ +typedef struct ntp_sys_state_s +{ + uint32_t supp_flags; ///< Supported NTP system state values, see ::NTP_SYS_STATE_SUPP_FLAG_MASKS + + uint8_t leap_ind; ///< Leap indicator, see ::NTP_LI_BITS + uint8_t sys_sync_src; ///< Current synchronization source, see ::NTP_SYNC_SRC_BITS + uint8_t sys_evt_cnt; ///< Number of events, since the last time the event code changed + uint8_t sys_rec_evt; ///< Most recent event message, see ::NTP_SYS_EVT_BITS + + uint8_t impl_type; ///< NTP implementation type, see ::NTP_IMPL + uint8_t major_version; ///< Major version number + uint8_t minor_version; ///< Minor version number + uint8_t micro_version; ///< Micro version number + + uint16_t patch_lvl; ///< Patch level number + uint8_t cpu_type; ///< Processor type, see ::NTP_CPU_TYPES + uint8_t system; ///< Operating system, see ::NTP_SYSTEMS + + uint8_t stratum; ///< Current stratum level of the system + int8_t precision; ///< Precision of the system clock (2^precision) + uint16_t sys_assoc; ///< Association ID of the current system peer, do not use NTP_SYS_STATE::sys_peer if this is supported + + int32_t root_delay; ///< [us] Total roundtrip delay to the system peer + int32_t root_disp; ///< [us] Total dispersion to the system peer + + MBG_IP_ADDR ref_id; ///< Reference ID of the current system peer, see ::MBG_IP_ADDR + + NTP_TSTAMP ref_time; ///< Last time the system time has been adjusted, see ::NTP_TSTAMP + NTP_TSTAMP sys_time; ///< Current system time, see ::NTP_TSTAMP + + uint16_t sys_peer; ///< Index of the current system peer + uint8_t poll; ///< Current polling interval for the system peer (tc) + uint8_t minpoll; ///< Minimal polling interval for the system peer (mintc) + + int64_t offset; ///< [ns] Combined offset to the system peer + + int32_t freq; ///< [ppb] Frequency offset relative to hardware clock + int32_t sys_jitter; ///< [us] Combined jitter of the system + int32_t clk_jitter; ///< [us] Jitter of the clock + int32_t clk_wander; ///< [ppb] Frequency wander of the clock + + 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 + + uint32_t reserved_3; ///< Reserved, currently always 0 + +} NTP_SYS_STATE; + +#define _mbg_swab_ntp_sys_state( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_flags ); \ + \ + _mbg_swab8( &(_p)->leap_ind ); \ + _mbg_swab8( &(_p)->sys_sync_src ); \ + _mbg_swab8( &(_p)->sys_evt_cnt ); \ + _mbg_swab8( &(_p)->sys_rec_evt ); \ + \ + _mbg_swab8( &(_p)->impl_type ); \ + _mbg_swab8( &(_p)->major_version ); \ + _mbg_swab8( &(_p)->minor_version ); \ + _mbg_swab8( &(_p)->micro_version ); \ + \ + _mbg_swab16( &(_p)->patch_lvl ); \ + _mbg_swab8( &(_p)->cpu_type ); \ + _mbg_swab8( &(_p)->system ); \ + \ + _mbg_swab8( &(_p)->stratum ); \ + _mbg_swab8( &(_p)->precision ); \ + _mbg_swab16( &(_p)->sys_assoc ); \ + \ + _mbg_swab32( &(_p)->root_delay ); \ + _mbg_swab32( &(_p)->root_disp ); \ + \ + _mbg_swab_ip_addr( &(_p)->ref_id ); \ + \ + _mbg_swab_ntp_tstamp( &(_p)->ref_time ); \ + _mbg_swab_ntp_tstamp( &(_p)->sys_time ); \ + \ + _mbg_swab16( &(_p)->sys_peer ); \ + _mbg_swab8( &(_p)->poll ); \ + _mbg_swab8( &(_p)->minpoll ); \ + \ + _mbg_swab64( &(_p)->offset ); \ + \ + _mbg_swab32( &(_p)->freq ); \ + _mbg_swab32( &(_p)->sys_jitter ); \ + _mbg_swab32( &(_p)->clk_jitter ); \ + _mbg_swab32( &(_p)->clk_wander ); \ + \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + \ +} while ( 0 ) + + + +/** + * @brief Enumeration of NTP mode bits + * + * Used with ::NTP_PEER_STATE::host_mode and ::NTP_PEER_STATE::peer_mode + * + */ +enum NTP_MODE_BITS +{ + NTP_MODE_RESERVED = 0, + NTP_MODE_SYMM_ACT, + NTP_MODE_SYMM_PASS, + NTP_MODE_CLIENT, + NTP_MODE_SERVER, + NTP_MODE_BROADCAST, + NTP_MODE_CONTROL, + NTP_MODE_PRIVATE, + N_NTP_MODE_BITS +}; + + + +/* + * Default initializers for English NTP peer mode string names. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_MODE_STR_ENG_HOST_LABEL "Host Mode:" +#define MBG_NTP_MODE_STR_ENG_PEER_LABEL "Peer Mode:" + +#define MBG_NTP_PEER_MODE_STR_ENG_RESERVED "Reserved" +#define MBG_NTP_PEER_MODE_STR_ENG_SYMM_ACT "Symm Act" +#define MBG_NTP_PEER_MODE_STR_ENG_SYMM_PASS "Symm Pass" +#define MBG_NTP_PEER_MODE_STR_ENG_CLIENT "Client" +#define MBG_NTP_PEER_MODE_STR_ENG_SERVER "Server" +#define MBG_NTP_PEER_MODE_STR_ENG_BROADCAST "Broadcast" +#define MBG_NTP_PEER_MODE_STR_ENG_CONTROL "Control" +#define MBG_NTP_PEER_MODE_STR_ENG_PRIVATE "Private" + +#define MBG_NTP_MODE_STAT_NAMES_ENG \ +{ \ + MBG_NTP_PEER_MODE_STR_ENG_RESERVED, \ + MBG_NTP_PEER_MODE_STR_ENG_SYMM_ACT, \ + MBG_NTP_PEER_MODE_STR_ENG_SYMM_PASS, \ + MBG_NTP_PEER_MODE_STR_ENG_CLIENT, \ + MBG_NTP_PEER_MODE_STR_ENG_SERVER, \ + MBG_NTP_PEER_MODE_STR_ENG_BROADCAST, \ + MBG_NTP_PEER_MODE_STR_ENG_CONTROL, \ + MBG_NTP_PEER_MODE_STR_ENG_PRIVATE \ +} + + + +/** + * @brief Enumeration of NTP peer reach status + * + * Used with ::NTP_PEER_STATE::peer_reach_stat + */ +enum NTP_REACH_STAT_BITS +{ + NTP_REACH_STAT_UNKNOWN = 0, ///< unknown reach status + NTP_REACH_STAT_NO_LINK, ///< no network connection + NTP_REACH_STAT_DNS_UNREACH, ///< DNS server could not be reached + NTP_REACH_STAT_DNS_UNRESOLVED, ///< DNS name could not be resolved + NTP_REACH_STAT_PEER_UNREACH, ///< peer could not be reached + NTP_REACH_STAT_PEER_NOT_SYNC, ///< peer is not sync (leap alarm, stratum 16) + NTP_REACH_STAT_PEER_BAD_QUALITY, ///< peer has bad quality (dispersion, ...) + NTP_REACH_STAT_OK, ///< reach status is fine + N_NTP_REACH_STAT_BITS +}; + + + +/* + * Default initializers for English reach status string names. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_PEER_REACH_STAT_STR_ENG_LABEL "Reach State:" + +#define MBG_NTP_PEER_REACH_STAT_STR_ENG_UNKNOWN "Unknown" +#define MBG_NTP_PEER_REACH_STAT_STR_ENG_NO_LINK "No link" +#define MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNREACH "DNS Server unreached" +#define MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNRESOLVED "DNS name not resolved" +#define MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_UNREACH "Peer not reached" +#define MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_NOT_SYNC "Peer not sync" +#define MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_BAD_QUALITY "Peer has bad quality" +#define MBG_NTP_PEER_REACH_STAT_STR_ENG_OK "Good" + +#define MBG_NTP_PEER_REACH_STAT_NAMES_ENG \ +{ \ + MBG_NTP_PEER_REACH_STAT_STR_ENG_UNKNOWN, \ + MBG_NTP_PEER_REACH_STAT_STR_ENG_NO_LINK, \ + MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNREACH, \ + MBG_NTP_PEER_REACH_STAT_STR_ENG_DNS_UNRESOLVED, \ + MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_UNREACH, \ + MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_NOT_SYNC, \ + MBG_NTP_PEER_REACH_STAT_STR_ENG_PEER_BAD_QUALITY, \ + MBG_NTP_PEER_REACH_STAT_STR_ENG_OK \ +} + + + +/** + * @brief Enumeration of NTP peer selection status + * + * Used with ::NTP_PEER_STATE::peer_sel_stat + * + */ +enum NTP_PEER_SEL_STATUS_BITS +{ + NTP_PEER_SEL_REJECT = 0, ///< discarded as not valid (TEST10-TEST13) + NTP_PEER_SEL_FALSETICK, ///< discarded by intersection algorithm + NTP_PEER_SEL_EXCESS, ///< discarded by table overflow (not used) + NTP_PEER_SEL_OUTLYER, ///< discarded by the cluster algorithm + NTP_PEER_SEL_CANDIDATE, ///< included by the combine algorithm + NTP_PEER_SEL_BACKUP, ///< backup (more than tos maxclock sources) + NTP_PEER_SEL_SYS_PEER, ///< system peer + NTP_PEER_SEL_PPS_PEER, ///< PPS peer (when the prefer peer is valid) + N_NTP_PEER_SEL_STATUS_BITS +}; + + + +/* + * Default initializers for English peer select status string names. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_LABEL "Selected Status:" + +#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_REJECT "Not valid" +#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_FALSETICK "Falsetick" +#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_EXCESS "Excess" +#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_OUTLYER "Outlyer" +#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_CANDIDATE "Candidate" +#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_BACKUP "Backup" +#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_SYS_PEER "System Peer" +#define MBG_NTP_PEER_SEL_STATUS_STR_ENG_PPS_PEER "PPS Peer" + +#define MBG_NTP_PEER_SEL_STATUS_NAMES_ENG \ +{ \ + MBG_NTP_PEER_SEL_STATUS_STR_ENG_REJECT, \ + MBG_NTP_PEER_SEL_STATUS_STR_ENG_FALSETICK, \ + MBG_NTP_PEER_SEL_STATUS_STR_ENG_EXCESS, \ + MBG_NTP_PEER_SEL_STATUS_STR_ENG_OUTLYER, \ + MBG_NTP_PEER_SEL_STATUS_STR_ENG_CANDIDATE, \ + MBG_NTP_PEER_SEL_STATUS_STR_ENG_BACKUP, \ + MBG_NTP_PEER_SEL_STATUS_STR_ENG_SYS_PEER, \ + MBG_NTP_PEER_SEL_STATUS_STR_ENG_PPS_PEER \ +} + + + +/** + * @brief Enumeration of NTP peer status codes + * + * @see ::NTP_PEER_STATUS_FLAG_MASKS + * + */ +enum NTP_PEER_STATUS_FLAGS +{ + NTP_PEER_STATUS_BCST = 0, ///< broadcast association + NTP_PEER_STATUS_REACH, ///< host reachable + NTP_PEER_STATUS_AUTHENB, ///< authentication enabled + NTP_PEER_STATUS_AUTH, ///< authentication ok + NTP_PEER_STATUS_CONFIG, ///< persistent association + N_NTP_PEER_STATUS_FLAGS +}; + + +/** + * @brief Flag masks for NTP_PEER_STATUS_FLAGS + * + * Used with ::NTP_PEER_STATE::peer_status_flags + * + * @see ::NTP_PEER_STATUS_FLAGS + */ +enum NTP_PEER_STATUS_FLAG_MASKS +{ + NTP_PEER_STATUS_BCST_MSK = ( 1UL << NTP_PEER_STATUS_BCST ), ///< See ::NTP_PEER_STATUS_BCST + NTP_PEER_STATUS_REACH_MSK = ( 1UL << NTP_PEER_STATUS_REACH ), ///< See ::NTP_PEER_STATUS_REACH + NTP_PEER_STATUS_AUTHENB_MSK = ( 1UL << NTP_PEER_STATUS_AUTHENB ), ///< See ::NTP_PEER_STATUS_AUTHENB + NTP_PEER_STATUS_AUTH_MSK = ( 1UL << NTP_PEER_STATUS_AUTH ), ///< See ::NTP_PEER_STATUS_AUTH + NTP_PEER_STATUS_CONFIG_MSK = ( 1UL << NTP_PEER_STATUS_CONFIG ), ///< See ::NTP_PEER_STATUS_CONFIG +}; + + +/* + * Default initializers for English peer status string names. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_PEER_STATUS_STR_ENG_LABEL "Peer Status:" + +#define MBG_NTP_PEER_STATUS_STR_ENG_BCST "Broadcast association" +#define MBG_NTP_PEER_STATUS_STR_ENG_REACH "Host reachable" +#define MBG_NTP_PEER_STATUS_STR_ENG_AUTHENB "Authentication enabled" +#define MBG_NTP_PEER_STATUS_STR_ENG_CONFIG "Persistant assosiation" + +#define MBG_NTP_PEER_STATUS_NAMES_ENG \ +{ \ + MBG_NTP_PEER_STATUS_STR_ENG_BCST, \ + MBG_NTP_PEER_STATUS_STR_ENG_REACH, \ + MBG_NTP_PEER_STATUS_STR_ENG_REACH, \ + MBG_NTP_PEER_STATUS_STR_ENG_AUTHENB, \ + MBG_NTP_PEER_STATUS_STR_ENG_CONFIG \ +} + + + +/** + * @brief Enumeration of NTP peer event message codes + * + * Used with ::NTP_PEER_STATE::peer_rec_evt + * + */ +enum NTP_PEER_EVT_BITS +{ + NTP_PEER_EVT_UNSPEC = 0, ///< unspecified NTP event + NTP_PEER_EVT_MOBILIZE, ///< association mobilized + NTP_PEER_EVT_DEMOBILIZE, ///< association demobilized + NTP_PEER_EVT_UNREACHABLE, ///< server unreachable + NTP_PEER_EVT_REACHABLE, ///< server reachable + NTP_PEER_EVT_RESTART, ///< association restart + NTP_PEER_EVT_NO_REPLY, ///< no server found (ntpdate mode) + NTP_PEER_EVT_RATE_EXCEEDED, ///< rate exceeded (kiss code RATE) + NTP_PEER_EVT_ACCESS_DENIED, ///< access denied (kiss code DENY) + NTP_PEER_EVT_LEAP_ARMED, ///< leap armed from server LI code + NTP_PEER_EVT_SYS_PEER, ///< become system peer + NTP_PEER_EVT_CLOCK_EVENT, ///< see clock status word + NTP_PEER_EVT_BAD_AUTH, ///< authentication failure + NTP_PEER_EVT_POPCORN, ///< popcorn spike suppressor + NTP_PEER_EVT_INTERLEAVE_MODE, ///< entering interleave mode + NTP_PEER_EVT_INTERLEAVE_ERROR, ///< interleave error (recovered) + N_NTP_PEER_EVT_BITS +}; + + + +/* + * Default initializers for English event message codes. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_PEER_EVT_STR_ENG_CNT_LABEL "Peer Event Counter:" +#define MBG_NTP_PEER_EVT_STR_ENG_MSG_LABEL "Peer Event Message:" + +#define MBG_NTP_PEER_EVT_STR_ENG_UNSPEC "Unspecified NTP event" +#define MBG_NTP_PEER_EVT_STR_ENG_MOBILIZE "Association mobilized" +#define MBG_NTP_PEER_EVT_STR_ENG_DEMOBILIZE "Association demobilized" +#define MBG_NTP_PEER_EVT_STR_ENG_UNREACHABLE "Server unreachable" +#define MBG_NTP_PEER_EVT_STR_ENG_REACHABLE "Server reachable" +#define MBG_NTP_PEER_EVT_STR_ENG_RESTART "Association restart" +#define MBG_NTP_PEER_EVT_STR_ENG_NO_REPLY "No server found" +#define MBG_NTP_PEER_EVT_STR_ENG_RATE_EXCEEDED "Rate exceeded" +#define MBG_NTP_PEER_EVT_STR_ENG_ACCESS_DENIED "Access denied" +#define MBG_NTP_PEER_EVT_STR_ENG_LEAP_ARMED "Leap second armed from LI code" +#define MBG_NTP_PEER_EVT_STR_ENG_SYS_PEER "Become system Peer" +#define MBG_NTP_PEER_EVT_STR_ENG_CLOCK_EVENT "Clock event" +#define MBG_NTP_PEER_EVT_STR_ENG_BAD_AUTH "Authentication failure" +#define MBG_NTP_PEER_EVT_STR_ENG_POPCORN "Popcorn Spike suspressor" +#define MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_MODE "Entering Interleave mode" +#define MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_ERROR "Interleave error" + + +#define MBG_NTP_PEER_EVT_NAMES_ENG \ +{ \ + MBG_NTP_PEER_EVT_STR_ENG_UNSPEC, \ + MBG_NTP_PEER_EVT_STR_ENG_MOBILIZE, \ + MBG_NTP_PEER_EVT_STR_ENG_DEMOBILIZE, \ + MBG_NTP_PEER_EVT_STR_ENG_UNREACHABLE, \ + MBG_NTP_PEER_EVT_STR_ENG_REACHABLE, \ + MBG_NTP_PEER_EVT_STR_ENG_RESTART, \ + MBG_NTP_PEER_EVT_STR_ENG_NO_REPLY, \ + MBG_NTP_PEER_EVT_STR_ENG_RATE_EXCEEDED, \ + MBG_NTP_PEER_EVT_STR_ENG_ACCESS_DENIED, \ + MBG_NTP_PEER_EVT_STR_ENG_LEAP_ARMED, \ + MBG_NTP_PEER_EVT_STR_ENG_SYS_PEER, \ + MBG_NTP_PEER_EVT_STR_ENG_CLOCK_EVENT, \ + MBG_NTP_PEER_EVT_STR_ENG_BAD_AUTH, \ + MBG_NTP_PEER_EVT_STR_ENG_POPCORN, \ + MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_MODE, \ + MBG_NTP_PEER_EVT_STR_ENG_INTERLEAVE_ERROR \ +} + + +/** + * @brief Enumeration of NTP flash status bit codes + * + * @see ::NTP_FLASH_STAT_FLAG_MASKS + * + */ +enum NTP_FLASH_STAT_FLAGS +{ + NTP_FLASH_STAT_PKT_DUP = 0, ///< duplicate packet + NTP_FLASH_STAT_PKT_BOGUS, ///< bogus packet + NTP_FLASH_STAT_PKT_UNSYNC, ///< server not synchronized + NTP_FLASH_STAT_PKT_DENIED, ///< access denied + NTP_FLASH_STAT_PKT_AUTH, ///< authentication failure + NTP_FLASH_STAT_PKT_STRATUM, ///< invalid leap or stratum + NTP_FLASH_STAT_PKT_HEADER, ///< header distance exceeded + NTP_FLASH_STAT_PKT_AUTOKEY, ///< Autokey sequence error + NTP_FLASH_STAT_PKT_CRYPTO, ///< Autokey protocol error + NTP_FLASH_STAT_PEER_STRATUM, ///< invalid header or stratum + NTP_FLASH_STAT_PEER_DIST, ///< distance threshold exceeded + NTP_FLASH_STAT_PEER_LOOP, ///< synchronization loop + NTP_FLASH_STAT_PEER_UNREACH, ///< unreachable or nonselect + N_NTP_FLASH_STAT_FLAGS +}; + + + +/** + * @brief Flag masks for ::NTP_FLASH_STAT_FLAGS + * + * Used with ::NTP_PEER_STATE::flash_stat_flags + * + * @see ::NTP_FLASH_STAT_FLAGS + */ +enum NTP_FLASH_STAT_FLAG_MASKS +{ + NTP_FLASH_STAT_PKT_DUP_MSK = ( 1UL << NTP_FLASH_STAT_PKT_DUP ), ///< See ::NTP_FLASH_STAT_PKT_DUP + NTP_FLASH_STAT_PKT_BOGUS_MSK = ( 1UL << NTP_FLASH_STAT_PKT_BOGUS ), ///< See ::NTP_FLASH_STAT_PKT_BOGUS + NTP_FLASH_STAT_PKT_UNSYNC_MSK = ( 1UL << NTP_FLASH_STAT_PKT_UNSYNC ), ///< See ::NTP_FLASH_STAT_PKT_UNSYNC + NTP_FLASH_STAT_PKT_DENIED_MSK = ( 1UL << NTP_FLASH_STAT_PKT_DENIED ), ///< See ::NTP_FLASH_STAT_PKT_DENIED + NTP_FLASH_STAT_PKT_AUTH_MSK = ( 1UL << NTP_FLASH_STAT_PKT_AUTH ), ///< See ::NTP_FLASH_STAT_PKT_AUTH + NTP_FLASH_STAT_PKT_STRATUM_MSK = ( 1UL << NTP_FLASH_STAT_PKT_STRATUM ), ///< See ::NTP_FLASH_STAT_PKT_STRATUM + NTP_FLASH_STAT_PKT_HEADER_MSK = ( 1UL << NTP_FLASH_STAT_PKT_HEADER ), ///< See ::NTP_FLASH_STAT_PKT_HEADER + NTP_FLASH_STAT_PKT_AUTOKEY_MSK = ( 1UL << NTP_FLASH_STAT_PKT_AUTOKEY ), ///< See ::NTP_FLASH_STAT_PKT_AUTOKEY + NTP_FLASH_STAT_PKT_CRYPTO_MSK = ( 1UL << NTP_FLASH_STAT_PKT_CRYPTO ), ///< See ::NTP_FLASH_STAT_PKT_CRYPTO + NTP_FLASH_STAT_PEER_STRATUM_MSK = ( 1UL << NTP_FLASH_STAT_PEER_STRATUM ), ///< See ::NTP_FLASH_STAT_PEER_STRATUM + NTP_FLASH_STAT_PEER_DIST_MSK = ( 1UL << NTP_FLASH_STAT_PEER_DIST ), ///< See ::NTP_FLASH_STAT_PEER_DIST + NTP_FLASH_STAT_PEER_LOOP_MSK = ( 1UL << NTP_FLASH_STAT_PEER_LOOP ), ///< See ::NTP_FLASH_STAT_PEER_LOOP + NTP_FLASH_STAT_PEER_UNREACH_MSK = ( 1UL << NTP_FLASH_STAT_PEER_UNREACH ), ///< See ::NTP_FLASH_STAT_PEER_UNREACH +}; + + + +/* + * Default initializers for English ntp flash state mask. Initializers + * for multi-language strings can be found in tmonlstr.h. + */ +#define MBG_NTP_FLASH_STR_ENG_LABEL "Flash Status:" + +#define MBG_NTP_FLASH_STR_ENG_PKT_DUP "Duplicate packet" +#define MBG_NTP_FLASH_STR_ENG_PKT_BOGUS "Bogus packet" +#define MBG_NTP_FLASH_STR_ENG_PKT_UNSYNC "Server not synchronized" +#define MBG_NTP_FLASH_STR_ENG_PKT_DENIED "Access denied" +#define MBG_NTP_FLASH_STR_ENG_PKT_AUTH "Authentication failure" +#define MBG_NTP_FLASH_STR_ENG_PKT_STRATUM "Invalid leap or stratum" +#define MBG_NTP_FLASH_STR_ENG_PKT_HEADER "Header distance exceeded" +#define MBG_NTP_FLASH_STR_ENG_PKT_AUTOKEY "Autokey sequence error" +#define MBG_NTP_FLASH_STR_ENG_PKT_CRYPTO "Autokey protocol error" +#define MBG_NTP_FLASH_STR_ENG_PEER_STRATUM "Invalid header or stratum" +#define MBG_NTP_FLASH_STR_ENG_PEER_DIST "Distance threshold exceeded" +#define MBG_NTP_FLASH_STR_ENG_PEER_LOOP "Synchronization loop" +#define MBG_NTP_FLASH_STR_ENG_PEER_UNREACH "Unreachable or nonselect" + + +#define MBG_NTP_FLASH_NAMES_ENG \ +{ \ + MBG_NTP_FLASH_STR_ENG_PKT_DUP, \ + MBG_NTP_FLASH_STR_ENG_PKT_BOGUS, \ + MBG_NTP_FLASH_STR_ENG_PKT_UNSYNC, \ + MBG_NTP_FLASH_STR_ENG_PKT_DENIED, \ + MBG_NTP_FLASH_STR_ENG_PKT_AUTH, \ + MBG_NTP_FLASH_STR_ENG_PKT_STRATUM, \ + MBG_NTP_FLASH_STR_ENG_PKT_HEADER, \ + MBG_NTP_FLASH_STR_ENG_PKT_AUTOKEY, \ + MBG_NTP_FLASH_STR_ENG_PKT_CRYPTO, \ + MBG_NTP_FLASH_STR_ENG_PEER_STRATUM, \ + MBG_NTP_FLASH_STR_ENG_PEER_DIST, \ + MBG_NTP_FLASH_STR_ENG_PEER_LOOP, \ + MBG_NTP_FLASH_STR_ENG_PEER_UNREACH \ +} + + + +/** + * @brief Enumeration of supported NTP peer state values + * + * @see ::NTP_PEER_STATE_SUPP_FLAG_MASKS + */ +enum NTP_PEER_STATE_SUPP_FLAGS +{ + NTP_PEER_STATE_SUPP_STD, ///< supports standard values of ::NTP_PEER_STATE, all fields except below and reserved + NTP_PEER_STATE_SUPP_ASS_ID, ///< supports association ID, see ::NTP_PEER_STATE::ass_id + NTP_PEER_STATE_SUPP_EVENTS, ///< supports peer state events (NTP_PEER_STATE::peer_evt_cnt, NTP_PEER_STATE::peer_rec_evt) + NTP_PEER_STATE_SUPP_REACH_STAT, ///< supports peer reach status, see ::NTP_PEER_STATE::peer_reach_stat + NTP_PEER_STATE_SUPP_PRECISION, ///< supports precision indication, see ::NTP_PEER_STATE::precision + NTP_PEER_STATE_SUPP_ROOT_DELAY, ///< supports root delay to syspeer, see ::NTP_PEER_STATE::root_delay + NTP_PEER_STATE_SUPP_ROOT_DISP, ///< supports root dispersion, see ::NTP_PEER_STATE::root_disp + NTP_PEER_STATE_SUPP_HEADWAY, ///< supports headway, see ::NTP_PEER_STATE::headway + NTP_PEER_STATE_SUPP_FLASH_STAT, ///< supports flash status word, see ::NTP_PEER_STATE::flash_stat_flags + NTP_PEER_STATE_SUPP_KEY_ID, ///< supports symmetric key id, see ::NTP_PEER_STATE::key_id + NTP_PEER_STATE_SUPP_DISP, ///< supports filter dispersion, see ::NTP_PEER_STATE::disp + NTP_PEER_STATE_SUPP_JITTER, ///< supports filter jitter, see ::NTP_PEER_STATE::jitter + NTP_PEER_STATE_SUPP_XLEAVE, ///< supports interleave delay, see ::NTP_PEER_STATE::xleave + N_NTP_PEER_STATE_SUPP_FLAGS +}; + + +/** + * @brief Flag masks for NTP_PEER_STATE_SUPP_FLAGS + * + * Used with ::NTP_PEER_STATE::supp_flags + * + * @see ::NTP_PEER_STATE_SUPP_FLAGS + */ +enum NTP_PEER_STATE_SUPP_FLAG_MASKS +{ + NTP_PEER_STATE_SUPP_STD_MSK = ( 1UL << NTP_PEER_STATE_SUPP_STD ), ///< See ::NTP_PEER_STATE_SUPP_STD + NTP_PEER_STATE_SUPP_ASS_ID_MSK = ( 1UL << NTP_PEER_STATE_SUPP_ASS_ID ), ///< See ::NTP_PEER_STATE_SUPP_ASS_ID + NTP_PEER_STATE_SUPP_EVENTS_MSK = ( 1UL << NTP_PEER_STATE_SUPP_EVENTS ), ///< See ::NTP_PEER_STATE_SUPP_EVENTS + NTP_PEER_STATE_SUPP_REACH_STAT_MSK = ( 1UL << NTP_PEER_STATE_SUPP_REACH_STAT ), ///< See ::NTP_PEER_STATE_SUPP_REACH_STAT + NTP_PEER_STATE_SUPP_PRECISION_MSK = ( 1UL << NTP_PEER_STATE_SUPP_PRECISION ), ///< See ::NTP_PEER_STATE_SUPP_PRECISION + NTP_PEER_STATE_SUPP_ROOT_DELAY_MSK = ( 1UL << NTP_PEER_STATE_SUPP_ROOT_DELAY ), ///< See ::NTP_PEER_STATE_SUPP_ROOT_DELAY + NTP_PEER_STATE_SUPP_ROOT_DISP_MSK = ( 1UL << NTP_PEER_STATE_SUPP_ROOT_DISP ), ///< See ::NTP_PEER_STATE_SUPP_ROOT_DISP + NTP_PEER_STATE_SUPP_HEADWAY_MSK = ( 1UL << NTP_PEER_STATE_SUPP_HEADWAY ), ///< See ::NTP_PEER_STATE_SUPP_HEADWAY + NTP_PEER_STATE_SUPP_FLASH_STAT_MSK = ( 1UL << NTP_PEER_STATE_SUPP_FLASH_STAT ), ///< See ::NTP_PEER_STATE_SUPP_FLASH_STAT + NTP_PEER_STATE_SUPP_KEY_ID_MSK = ( 1UL << NTP_PEER_STATE_SUPP_KEY_ID ), ///< See ::NTP_PEER_STATE_SUPP_KEY_ID + NTP_PEER_STATE_SUPP_DISP_MSK = ( 1UL << NTP_PEER_STATE_SUPP_DISP ), ///< See ::NTP_PEER_STATE_SUPP_DISP + NTP_PEER_STATE_SUPP_JITTER_MSK = ( 1UL << NTP_PEER_STATE_SUPP_JITTER ), ///< See ::NTP_PEER_STATE_SUPP_JITTER + NTP_PEER_STATE_SUPP_XLEAVE_MSK = ( 1UL << NTP_PEER_STATE_SUPP_XLEAVE ), ///< See ::NTP_PEER_STATE_SUPP_XLEAVE +}; + + + +/** + * @brief Structure that represents the status of an NTP peer + * + * This structure should be requested via ::NTP_PEER_STATE_IDX + * + * @see ::NTP_PEER_STATE_IDX + */ +typedef struct ntp_peer_state_s +{ + uint32_t supp_flags; ///< Supported NTP peer state values, see ::NTP_PEER_STATE_SUPP_FLAG_MASKS + + uint16_t ass_id; ///< Association ID of the peer + uint16_t peer_status_flags; ///< Peer status flags, see ::NTP_PEER_STATUS_FLAG_MASKS + + uint8_t leap_ind; ///< Leap indicator, see ::NTP_LI_BITS + uint8_t peer_sel_stat; ///< Current selection status of the peer, see ::NTP_PEER_SEL_STATUS_BITS + uint8_t peer_evt_cnt; ///< Number of events, since the last time the event code changed + uint8_t peer_rec_evt; ///< Most recent event message, see ::NTP_PEER_EVT_BITS + + uint8_t peer_reach_stat; ///< Current reach status of the peer, see ::NTP_REACH_STAT_BITS + uint8_t reserved_1; ///< Reserved, currently always 0 + uint16_t reserved_2; ///< Reserved, currently always 0 + + MBG_IP_ADDR_PORT src_addr; ///< Source address of the NTP peer, see ::MBG_IP_ADDR_PORT + MBG_IP_ADDR_PORT dst_addr; ///< Destination address of the NTP peer, see ::MBG_IP_ADDR_PORT + + uint8_t stratum; ///< Current stratum level of the NTP peer + int8_t precision; ///< Precision of the peer clock (2^precision) + uint16_t reserved_3; ///< Reserved, currently always 0 + + int32_t root_delay; ///< [us] Total roundtrip delay to the system peer of the NTP peer + int32_t root_disp; ///< [us] Total dispersion to the system peer of the NTP peer + + MBG_IP_ADDR ref_id; ///< Reference ID of the NTP peer, see ::MBG_IP_ADDR + + NTP_TSTAMP ref_time; ///< Last time the NTP peers time has been adjusted, see ::NTP_TSTAMP + NTP_TSTAMP rec_time; ///< Current system time of the NTP peer, see ::NTP_TSTAMP + + uint8_t reach; ///< Shift register for the last 8 polling intervals + uint8_t reserved_4; ///< Reserved, currently always 0 + uint16_t unreach; ///< Counter for the number of unsuccessful polling intervals + + uint8_t host_mode; ///< NTP mode of the requesting host, see ::NTP_MODE_BITS + uint8_t peer_mode; ///< NTP mode of the peer, see ::NTP_MODE_BITS + uint8_t host_poll; ///< Host NTP polling interval + uint8_t peer_poll; ///< Peer NTP polling interval + + uint8_t headway; ///< Indicator for the KoD packet, TODO: further investigation + uint8_t reserved_5; ///< Reserved, currently always 0 + uint16_t flash_stat_flags; ///< Flash status flags, see ::NTP_FLASH_STAT_FLAG_MASKS + + uint16_t key_id; ///< ID of symmetric authentication key + uint16_t reserved_6; ///< Reserved, currently always 0 + + int64_t offset; ///< [ns] filter offset to this NTP peer + int64_t delay; ///< [ns] filter delay to this NTP peer + + int32_t disp; ///< [us] filter dispersion of the NTP peer + int32_t jitter; ///< [us] filter jitter of the NTP peer + + uint32_t xleave; ///< [ns] interleave delay of the NTP peer + + uint8_t n_filter_values; ///< Number of filter values available, currently always 0 + uint8_t reserved_7; ///< Reserved, currently always 0 + uint16_t reserved_8; ///< Reserved, currently always 0 + + uint32_t reserved_9; ///< Reserved, currently always 0 + +} NTP_PEER_STATE, NTP_REFCLK_STATE; + + + +#define _mbg_swab_ntp_peer_state( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_flags ); \ + \ + _mbg_swab16( &(_p)->ass_id ); \ + _mbg_swab16( &(_p)->peer_status_flags ); \ + \ + _mbg_swab8( &(_p)->leap_ind ); \ + _mbg_swab8( &(_p)->peer_sel_stat ); \ + _mbg_swab8( &(_p)->peer_evt_cnt ); \ + _mbg_swab8( &(_p)->peer_rec_evt ); \ + \ + _mbg_swab8( &(_p)->peer_reach_stat ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + \ + _mbg_swab_ip_addr_port( &(_p)->src_addr ); \ + _mbg_swab_ip_addr_port( &(_p)->dst_addr ); \ + \ + _mbg_swab8( &(_p)->stratum ); \ + _mbg_swab8( &(_p)->precision ); \ + _mbg_swab16( &(_p)->reserved_3 ); \ + \ + _mbg_swab32( &(_p)->root_delay ); \ + _mbg_swab32( &(_p)->root_disp ); \ + \ + _mbg_swab_ip_addr( &(_p)->ref_id ); \ + \ + _mbg_swab_ntp_tstamp( &(_p)->ref_time ); \ + _mbg_swab_ntp_tstamp( &(_p)->rec_time ); \ + \ + _mbg_swab8( &(_p)->reach ); \ + _mbg_swab8( &(_p)->reserved_4 ); \ + _mbg_swab16( &(_p)->unreach ); \ + \ + _mbg_swab8( &(_p)->host_mode ); \ + _mbg_swab8( &(_p)->peer_mode ); \ + _mbg_swab8( &(_p)->host_poll ); \ + _mbg_swab8( &(_p)->peer_poll ); \ + \ + _mbg_swab8( &(_p)->headway ); \ + _mbg_swab8( &(_p)->reserved_5 ); \ + _mbg_swab16( &(_p)->flash_stat_flags ); \ + \ + _mbg_swab16( &(_p)->key_id ); \ + _mbg_swab16( &(_p)->reserved_6 ); \ + \ + _mbg_swab64( &(_p)->offset ); \ + _mbg_swab64( &(_p)->delay ); \ + \ + _mbg_swab32( &(_p)->disp ); \ + _mbg_swab32( &(_p)->jitter ); \ + \ + _mbg_swab32( &(_p)->xleave ); \ + \ + _mbg_swab8( &(_p)->n_filter_values ); \ + _mbg_swab8( &(_p)->reserved_7 ); \ + _mbg_swab16( &(_p)->reserved_8 ); \ + \ + _mbg_swab32( &(_p)->reserved_9 ); \ + \ +} while ( 0 ) + +#define _mbg_swab_ntp_refclk_state ( _p ) _mbg_swab_ntp_peer_state( _p ) + + +/** + * @brief Structure that contains an index value and the NTP peer state + * + * This structure can be requested by a monitoring program to observe the status of configured NTP peers + * + * @see ::NTP_PEER_STATE + */ +typedef struct ntp_peer_state_idx_s +{ + MBG_MSG_IDX_32 idx; ///< The index of the observed NTP peer + NTP_PEER_STATE peer_state; ///< Peer state, see ::NTP_PEER_STATE + +} NTP_PEER_STATE_IDX, NTP_REFCLK_STATE_IDX; + + +#define _mbg_swab_ntp_peer_state_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_ntp_peer_state( &(_p)->peer_state ); \ +} while ( 0 ) + + +#define _mbg_swab_ntp_refclk_state_idx( _p ) _mbg_swab_ntp_peer_state_idx( _p ) + + +/** @} defgroup group_ntp */ + + + +/** + * @defgroup group_lno Definitions used with LNO devices + * + * @{ */ + +#define MAX_LNO_OUTPUT 4 + +/** + * @brief LNO state + */ +typedef struct +{ + uint16_t sine_lvl[MAX_LNO_OUTPUT]; ///< signal levels at the outputs + + uint16_t max_sine_lvl; ///< max level of an output, e.g. 1024 + uint8_t n_outputs; ///< actual number of outputs [0..::MAX_LNO_OUTPUT-1] + uint8_t out_enb_state; ///< e.g. bit 0 is set if corresponding output 0 is enabled, etc. + + uint16_t reserved_0; ///< reserved, currently always 0 + uint16_t flags; ///< status flags, see ::LNO_STATE_FLAG_BITS + +} LNO_STATE; + +#define _mbg_swab_lno_state( _p ) \ +do \ +{ \ + int i; \ + \ + for ( i = 0; i < MAX_LNO_OUTPUT; i++ ) \ + _mbg_swab16( &(_p)->sine_lvl[i] ); \ + \ + _mbg_swab_16( &(_p)->max_sine_lvl ); \ + _mbg_swab_16( &(_p)->reserved_0 ); \ + _mbg_swab_16( &(_p)->flags ); \ +} while ( 0 ) + + +/** + * @brief Flags used with ::LNO_STATE::flags + */ +enum LNO_STATE_FLAG_BITS +{ + LNO_FLAG_BIT_PLL_LOCKED, ///< PLL is locked + N_LNO_FLAG_BIT ///< number of known bits +}; + +#define LNO_FLAG_PLL_LOCKED ( 1UL << LNO_FLAG_BIT_PLL_LOCKED ) + +/** @} defgroup group_lno */ + + + +/** + * @defgroup group_vst Definitions used with Versatile Storage + * + * Versatile storage is used to store binary data on a device where the storage + * device must not necessarily know about the data structure. It just stores + * a piece of data, and retrieves it on demand. + * + * The structures and associated API calls are only supported if the + * ::GPS_HAS_VST bit is set in ::RECEIVER_INFO::features. + * + * @{ */ + +/** + * @brief Known common VST data types + */ +enum VST_DATA_TYPES +{ + VST_DATA_TYPE_MAC_ADDR, //##++++++++++++ This is just an example. More to be added. + N_VST_DATA_TYPES +}; + + +/** + * @brief + */ +typedef struct +{ + uint16_t data_type; ///< data type identifier, see ::VST_DATA_TYPES for common types + uint16_t idx; ///< Index for several sets of the same type + uint16_t data_len; ///< length of the data set appended to the header + uint16_t reserved; ///< reserved, currently always 0 + +} VST_HEADER; + +#define _mbg_swab_vst_header( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->data_type ); \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab16( &(_p)->data_len ); \ + _mbg_swab16( &(_p)->reserved ); \ +} while ( 0 ) + +/** @} defgroup group_vst */ + + + +/** + * @defgroup group_shs Definitions used with SHS devices + * + * An SHS (Secure Hybrid System) device compares the times from 2 sources + * and eventually sets an alarm (warning and/or error) flag if the difference + * between the 2 time sources exceeds a configurable limit. + * + * These structures and associated definitions are used to query the SHS + * capabilities, configure the SHS device according to its capabilities, + * and query the SHS status. + * + * The structures and associated API calls are only supported if the + * ::GPS_HAS_SHS bit is set in ::RECEIVER_INFO::features. + * + * The ::SHS_INFO structure can be read to retrieve the capabilities and + * current settings of the device. The ::SHS_SETTINGS structure can then + * be set up according to the capabilities, and be written back to configure + * the device. + * + * If ::SHS_SETTINGS::err_limit and/or ::SHS_SETTINGS::warn_limit are + * not 0 then the SHS device checks if the time difference between the + * 2 clocks exceeds these limits and sets ::SHS_STATUS::shs_state + * as appropriate. + * + * If indicated by ::SHS_INFO::supp_flags the SHS device can also take + * certain actions if the time difference exceeds the error limit. + * If this happens then the same flags are set in ::SHS_STATUS::flags + * to indicate the action has been taken. + * + * @{ */ + +/** + * @brief Current configuration of an SHS controller + * + * @see ::SHS_INFO + * @see ::SHS_STATUS + */ +typedef struct +{ + NANO_TIME err_limit; ///< time difference limit above which an error is indicated + NANO_TIME warn_limit; ///< time difference limit above which a warning is indicated + uint32_t reserved; ///< reserved, currently always 0 + uint32_t flags; ///< See ::SHS_FLAG_MASKS + +} SHS_SETTINGS; + +#define _mbg_swab_shs_settings( _p ) \ +do \ +{ \ + _mbg_swab_nano_time( &(_p)->err_limit ); \ + _mbg_swab_nano_time( &(_p)->warn_limit ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Current SHS settings and general SHS capabilities + * + * @see ::SHS_SETTINGS + * @see ::SHS_STATUS + */ +typedef struct +{ + SHS_SETTINGS settings; ///< current configuration settings + NANO_TIME max_limit; ///< if not 0, the max. allowed value for ::SHS_SETTINGS::err_limit and ::SHS_SETTINGS::warn_limit + uint32_t reserved; ///< reserved, currently always 0 + uint32_t supp_flags; ///< indicates which flags are supported for ::SHS_SETTINGS::flags, see ::SHS_FLAG_MASKS + +} SHS_INFO; + +#define _mbg_swab_shs_info( _p ) \ +do \ +{ \ + _mbg_swab_shs_settings( &(_p)->settings ); \ + _mbg_swab_nano_time( &(_p)->max_limit ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Current SHS status + */ +typedef struct +{ + NANO_TIME time_diff; ///< Current time difference between the 2 clocks. + TM_GPS_STATUS_EXT clk_status_1; ///< Status of first clock. + TM_GPS_STATUS_EXT clk_status_2; ///< Status of second clock. + uint8_t shs_state; ///< See ::SHS_STATES. + uint8_t reserved_1; ///< Reserved, currently always 0. + uint16_t reserved_2; ///< Reserved, currently always 0. + uint32_t flags; ///< See ::SHS_FLAG_MASKS. + +} SHS_STATUS; + +#define _mbg_swab_shs_status( _p ) \ +do \ +{ \ + _mbg_swab_nano_time( &(_p)->time_diff ); \ + _mbg_swab32( &(_p)->clk_status_1 ); \ + _mbg_swab32( &(_p)->clk_status_2 ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief SHS configuration flag bits + * + * Codes used with ::SHS_STATUS::shs_state + */ +enum SHS_STATES +{ + SHS_STATE_DISABLED, ///< time difference not checked, eventually no limits configured + SHS_STATE_OK, ///< time difference OK, below warning limit + SHS_STATE_WARNING, ///< time difference exceeds warning limit + SHS_STATE_ERROR, ///< time difference exceeds error limit + SHS_STATE_FATAL, ///< one or both time sources disconnected + N_SHS_STATES +}; + + + +/** + * @brief SHS flag bits + * + * @see ::SHS_FLAG_MASKS + */ +enum SHS_FLAG_BITS +{ + SHS_FLAG_BIT_DISB_SERIAL, ///< disable serial output in state ::SHS_STATE_ERROR + SHS_FLAG_BIT_DISB_PPS, ///< disable PPS output in state ::SHS_STATE_ERROR + SHS_FLAG_BIT_DISB_10MHZ, ///< disable 10 MHz output in state ::SHS_STATE_ERROR + N_SHS_FLAG_BITS +}; + + +/** + * @brief SHS flag masks + * + * With ::SHS_INFO::supp_flags these flags indicate what is supported + * by the SHS controller, e.g. what action can be taken automatically. + * Each bit set in ::SHS_INFO::supp_flags can be set by a configuration + * tool in ::SHS_SETTINGS::flags to enable the associated feature. + * If a corresponding bit is set in ::SHS_STATUS::flags this means the + * associated feature has been enabled, e.g. an action has been taken. + * + * @see ::SHS_FLAG_BITS + */ +enum SHS_FLAG_MASKS +{ + SHS_FLAG_DISB_SERIAL = ( 1UL << SHS_FLAG_BIT_DISB_SERIAL ), ///< See ::SHS_FLAG_BIT_DISB_SERIAL + SHS_FLAG_DISB_PPS = ( 1UL << SHS_FLAG_BIT_DISB_PPS ), ///< See ::SHS_FLAG_BIT_DISB_PPS + SHS_FLAG_DISB_10MHZ = ( 1UL << SHS_FLAG_BIT_DISB_10MHZ ) ///< See ::SHS_FLAG_BIT_DISB_10MHZ +}; + +/** @} defgroup group_shs */ + + + +/** + * @defgroup group_xbp eXtended Binary Protocol definitions + * + * @note These structures are only supported if ::GPS_HAS_XBP is set + * in ::RECEIVER_INFO::features. + * + * @{ */ + +/** + * @brief An XBP port specifier + * + * Each controller can provide up to 255 ports with numbers 0..254. + * XBP port number ::XBP_PORT_RESERVED is reserved to mark unused ports. + */ +typedef uint8_t XBP_PORT; + + +/** + * @brief An identifier used to mark an XBP port unused + */ +#define XBP_PORT_RESERVED ( (XBP_PORT) -1 ) + + +/** + * @brief Maximum XBP bus/controller cascading level + * + * Should be 7 so the total size of ::XBP_ADDR is 8 bytes. + */ +#define MAX_XBP_CASC_LVL 7 + + +/** + * @brief An XBP address specifier + * + * A generic scheme to address devices connected to cascaded controllers. + */ +typedef struct xbp_addr_s +{ + uint8_t hop_count; ///< Used as index to the addr array + XBP_PORT addr[MAX_XBP_CASC_LVL]; ///< An array of port numbers on cascaded controllers + +} XBP_ADDR; + +#define _mbg_swab_xbp_addr( _p ) _nop_macro_fnc() // only single bytes + + + +/** + * @brief A structure used to report XBP features and limits + */ +typedef struct +{ + uint32_t features; ///< Mask of XBP features, see ::XBP_FEAT_MASKS + uint32_t flags; ///< XBP flags, currently not used + uint32_t reserved_0; ///< reserved, currently not used + uint32_t reserved_1; ///< reserved, currently not used + uint32_t reserved_2; ///< reserved, currently not used + uint32_t reserved_3; ///< reserved, currently not used + +} XBP_LIMITS; + +#define _mbg_swab_xbp_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->features ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of bits used to define ::XBP_FEAT_MASKS + */ +enum XBP_FEAT_BITS +{ + XBP_FEAT_BIT_NODES, ///< Supports ::XBP_NODE_LIMITS and associated structures + N_XBP_FEAT_BITS +}; + + +/** + * @brief XBP feature masks used with ::XBP_LIMITS::features + * + * @see ::XBP_FEAT_BITS + */ +enum XBP_FEAT_MASKS +{ + XBP_FEAT_MASK_NODES = ( 1UL << XBP_FEAT_BIT_NODES ) ///< See ::XBP_FEAT_BIT_NODES +}; + + + +/** + * @brief Information on available XBP nodes + * + * Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features. + */ +typedef struct +{ + uint32_t node_count; ///< Number of XBP nodes available in the system + uint32_t reserved_0; ///< Currently reserved, always 0 + uint32_t reserved_1; ///< Currently reserved, always 0 + // TODO: do we need additional fields here? + +} XBP_NODE_LIMITS; + +#define _mbg_swab_xbp_node_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->node_count ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ +} while ( 0 ) + + + +/** + * @brief Possible states of an XBP device + * + * Used with ::XBP_NODE_INFO::state. + */ +enum XBP_DEVICE_STATES +{ + XBP_DEVICE_STATE_UNKNOWN, + XBP_DEVICE_STATE_NOT_AVAILABLE, + XBP_DEVICE_STATE_INITIALIZING, + XBP_DEVICE_STATE_AVAILABLE, + XBP_DEVICE_STATE_DISCONNECTED, + XBP_DEVICE_STATE_OUTDATED, + N_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 + * + * Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features. + * The number of instances supported by a device is specified + * in ::XBP_NODE_LIMITS::node_count. + */ +typedef struct xbp_node_info_s +{ + XBP_ADDR addr; ///< The address of the specific node + + /// @brief ::RECEIVER_INFO of the device connected to this node. + /// + /// If no device is available then ::RECEIVER_INFO::model_code + /// is set to ::GPS_MODEL_UNKNOWN (== 0). + RECEIVER_INFO ri; + + 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; + +#define _mbg_swab_xbp_node_info( _p ) \ +do \ +{ \ + _mbg_swab_xbp_addr( &(_p)->addr ); \ + _mbg_swab_receiver_info( &(_p)->ri ); \ + _mbg_swab8( &(_p)->state ); \ + _mbg_swab8( &(_p)->slot_type ); \ + _mbg_swab8( &(_p)->slot_type_id ); \ + _mbg_swab8( &(_p)->reserved ); \ + _mbg_swab16( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Information on an XBP node with specific index + * + * Only supported if ::XBP_FEAT_MASK_NODES is set in ::XBP_LIMITS::features. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; ///< node index, 0..::XBP_NODE_LIMITS::node_count-1 + XBP_NODE_INFO node_info; ///< ::RECEIVER_INFO of the device behind this node + +} XBP_NODE_INFO_IDX; + +#define _mbg_swab_xbp_node_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_xbp_node_info( &(_p)->node_info ); \ +} while ( 0 ) + + +/** @} defgroup group_xbp */ + + + +/** + * @defgroup group_tlv_api Meinberg TLV API definitions + * + * @note These structures and definitions are only supported by a device + * if ::MBG_XFEATURE_TLV_API is set in the extended device features. + * + * @{ */ + + +/** + * @brief A data type used to hold a unique ID (UID) for a TLV transaction + */ +typedef uint32_t MBG_TLV_UID; + +#define _mbg_swab_tlv_uid( _p ) \ + _mbg_swab32( _p ) + + + +/** + * @brief A data type to hold one of the ::MBG_TLV_TYPES or ::MBG_TLV_FEAT_TYPES + * + * @see ::MBG_TLV_TYPES + * @see ::MBG_TLV_FEAT_TYPES + */ +typedef uint32_t MBG_TLV_TYPE; + +#define _mbg_swab_tlv_type( _p ) \ + _mbg_swab32( _p ) + + + +/** + * @defgroup group_tlv_feat Meinberg TLV feature definitions + * + * @{ */ + + +/** + * @brief The maximum number of TLV feature types. + * + * Warning: Changing this number breaks API compatibility! + * + * @see ::MBG_TLV_FEAT_TYPES + */ +#define MAX_MBG_TLV_FEAT_TYPES 128 //### TODO Is this sufficient? + + +/** + * @brief Enumeration of known TLV feature types. + * + * TLV feature types are used to specify the content of a binary TLV message + * so that the receiver knows how to interpret the content. + * + * Used with ::MBG_TLV_INFO::supp_tlv_feat and ::MBG_TLV_DATA::type. ### TODO + * + * @see ::MBG_TLV_FEAT_BUFFER + * @see ::MBG_TLV_FEAT_TYPE_NAMES + * @see ::MBG_TLV_TYPES + * @see ::MBG_TLV_TYPE + */ +enum MBG_TLV_FEAT_TYPES +{ + /// Expects two TLV types in order: + /// 1) ::MBG_TLV_TYPE_STR => Firmware version as string + /// 2) ::MBG_TLV_TYPE_FILE => Firmware file as data blob + MBG_TLV_FEAT_TYPE_FW_UPDATE, + + /// If the total bytes of aan announce message is 0, it is a diagnostics file + /// request. If the total bytes are not 0, TLV type ::MBG_TLV_TYPE_FILE + /// is expected and it should contain a file as data blob. + MBG_TLV_FEAT_TYPE_DIAG_FILE, + + /// Only used as action trigger on a remote site, expects no data. + MBG_TLV_FEAT_TYPE_FW_ROLLBACK, + + /// Expects two TLV types in order: + /// 1) ::MBG_TLV_TYPE_STR => Full qualified path including filename on target system + /// 2) ::MBG_TLV_TYPE_FILE => File as data blob + MBG_TLV_FEAT_TYPE_FILE_TRANSFER, + + /// 1) ::MBG_TLV_TYPE_STR => Command line call as string + MBG_TLV_FEAT_TYPE_EXEC_CMD, + + /// 1) ::MBG_TLV_TYPE_FILE => Encrypted license file as data blob + MBG_TLV_FEAT_TYPE_LICENSE_UPGRADE, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_LIMITS, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_LIMITS, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_PTPV2_IDX, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_PTPV2_IDX, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_NTP_IDX, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_NTP_IDX, + + /// Expects two TLV types in order: + /// 1) ::MBG_TLV_TYPE_STR => Full qualified path including filename on target system + MBG_TLV_FEAT_TYPE_FILE_REQUEST, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_PTPV1_IDX, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_PTPV1_IDX, + + /// 1) ::MBG_TLV_TYPE_BLOB => ::MBG_LICENSE_TIME_MONITOR_IDX, see @ref group_license_limits + MBG_TLV_FEAT_TYPE_LICENSE_TIME_MONITOR_IDX, + + /// 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, + + N_MBG_TLV_FEAT_TYPES + // NOTE If new TLV feature types are appended here then an appropriate + // name string has to be appended to ::MBG_TLV_FEAT_TYPE_NAMES, and care must + // be taken that ::N_MBG_TLV_FEAT_TYPES doesn't exceed ::MAX_MBG_TLV_FEAT_TYPES. +}; + + +/** + * @brief Names of TLV API features + * + * Can be used to initialize a string array of ::N_MBG_TLV_FEAT_TYPES entries, + * so the number of strings must correspond to ::N_MBG_TLV_FEAT_TYPES. + * + * @see ::MBG_TLV_FEAT_TYPES + */ +#define MBG_TLV_FEAT_TYPE_NAMES \ +{ \ + "TLV Firmware Update", \ + "TLV Diagnostics File", \ + "TLV Firmware Rollback", \ + "TLV File Transfer", \ + "TLV Execute Command", \ + "TLV License Upgrade", \ + "TLV License Limits", \ + "TLV License PTPV2", \ + "TLV License NTP", \ + "TLV File Request", \ + "TLV License PTPV1 IDX", \ + "TLV License Sync Monitor", \ + "TLV Sync Monitor Full Status", \ + "TLV Unified Firmware Update" \ +} + + + +/** + * @brief Array size required to store up to ::MAX_MBG_TLV_FEAT_TYPES bits + * + * The number of bytes required to store up to ::MAX_MBG_TLV_FEAT_TYPES + * feature bits in a byte array. + */ +#define MAX_MBG_TLV_FEAT_BYTES ( MAX_MBG_TLV_FEAT_TYPES / 8 ) + + +/** + * @brief A structure used to store a bit mask of supported TLV context types. + * + * Bit masks for up to ::MAX_MBG_TLV_FEAT_TYPES totally can be stored, + * but only ::N_MBG_TLV_FEAT_TYPES types are currently defined. + * The ::_set_tlv_feat_bit macro should be used by the firmware + * to set a bit mask in the buffer, and the ::check_tlv_feat_supp + * function should be used to implement API calls which test if an + * extended TLV context type is supported. + * + * @see ::_set_tlv_feat_bit + * @see ::check_tlv_feat_supp + */ +typedef struct +{ + uint8_t b[MAX_MBG_TLV_FEAT_BYTES]; + +} MBG_TLV_FEAT_BUFFER; + + + +/** + * @brief Set a TLV context type bit in a ::MBG_TLV_FEAT_BUFFER + * + * Should be used by the firmware only to set one of the ::MBG_TLV_FEAT_TYPES + * bits in an ::MBG_TLV_FEAT_BUFFER after power-up. + * + * @param[in] _tlv_feat_type One of the ::MBG_TLV_FEAT_TYPES + * @param[in] _tlv_feat_buffp Pointer to a ::MBG_TLV_FEAT_BUFFER + */ +#define _set_tlv_feat_bit( _tlv_feat_type, _tlv_feat_buffp ) \ + _set_array_bit( _tlv_feat_type, (_tlv_feat_buffp)->supp_tlv_feat.b, MAX_MBG_TLV_FEAT_BYTES ) + + +/** @} defgroup group_tlv_feat */ + + + +/** + * @brief A structure used to query current TLV capabilities + * + * This is only supported by a device if the ::MBG_XFEATURE_TLV_API bit + * is set in the extended device features. + */ +typedef struct +{ + uint32_t reserved; ///< Future use + uint32_t flags; ///< Future use + MBG_TLV_FEAT_BUFFER supp_tlv_feat; ///< A byte array of supported TLV feature bits, see ::MBG_TLV_FEAT_TYPES + +} MBG_TLV_INFO; + +#define _mbg_swab_tlv_info( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Enumeration of known TLV types + * + * Used with ::MBG_TLV_TYPE types, e.g. in ::MBG_TLV_HDR::tlv_type + * or ::MBG_TLV_DATA::type. + * + * @see ::MBG_TLV_FEAT_TYPES + * @see ::MBG_TLV_TYPE + */ +enum MBG_TLV_TYPES +{ + MBG_TLV_TYPE_STR, + MBG_TLV_TYPE_FILE, + MBG_TLV_TYPE_BLOB, ///< In fact, a file is also a blob but + ///< give the child a different name to avoid confusion. + ///< Use this for getting/setting fixed structures! + N_MBG_TLV_TYPES +}; + + + +/** + * @brief General TLV data structure + * + * Structure containing common, additional data required to send + * an announce message for following TLVs. + */ +typedef struct +{ + MBG_TLV_UID uid; ///< Unique ID identifying following TLVs, 0 if empty/not set. + MBG_TLV_TYPE type; ///< One of the ::MBG_TLV_TYPES or ::MBG_TLV_FEAT_TYPES depending on the type of message. + uint32_t total_bytes; ///< Number of all bytes including header(s) that are related to a TLV block transaction. + uint32_t reserved_1; ///< Reserved for future use + +} MBG_TLV_DATA; + +#define _mbg_swab_tlv_data( _p ) \ +do \ +{ \ + _mbg_swab_tlv_uid( &(_p)->uid ); \ + _mbg_swab_tlv_type( &(_p)->type ); \ + _mbg_swab32( &(_p)->total_bytes ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ +} while ( 0 ) + + + +/** + * @brief Structure containing state information while reading TLV data. + */ +typedef struct +{ + MBG_TLV_DATA data; ///< See ::MBG_TLV_DATA + uint32_t read_bytes; ///< Number of bytes read + uint32_t reserved_1; ///< Future use + +} MBG_TLV_RCV_STATE; + + + +/** + * @brief A structure initiating a TLV transfer + * + * ::MBG_TLV_ANNOUNCE should be sent first, before starting a + * TLV transfer, to inform the remote site about following TLVs. + * Following sequence of TLVs is not fixed and implementation + * dependent. + */ +typedef struct +{ + MBG_TLV_DATA data; ///< See ::MBG_TLV_DATA + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + +} MBG_TLV_ANNOUNCE; + +#define _mbg_swab_tlv_announce( _p ) \ +do \ +{ \ + _mbg_swab_tlv_data( &(_p)->data ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +#define MSG_TLV_MAX_VALUE_SIZE 480 + +/** + * @brief TLV header structure containing information on current TLV transaction + */ +typedef struct +{ + MBG_TLV_UID uid; ///< Unique source ID. See ::MBG_TLV_DATA::uid + MBG_TLV_UID tlv_type; ///< "Subtype" identifying current TLV, see ::MBG_TLV_TYPES + uint32_t cur_bytes; ///< Number of bytes in ::MBG_TLV::value + uint32_t trans_bytes; ///< Number of bytes transferred so far related to this TLV type. + uint32_t total_bytes; ///< Number of total bytes (size) of this TLV type without header. + ///< It is fixed and must not be changed during a TLV transaction. + uint32_t reserved_1; ///< Future use + uint32_t reserved_2; ///< Future use + uint32_t reserved_3; ///< Future use + +} MBG_TLV_HDR; + +#define _mbg_swab_tlv_header( _p ) \ +do \ +{ \ + _mbg_swab_tlv_uid( &(_p)->uid ); \ + _mbg_swab_tlv_type( &(_p)->tlv_type ); \ + _mbg_swab32( &(_p)->cur_bytes ); \ + _mbg_swab32( &(_p)->trans_bytes ); \ + _mbg_swab32( &(_p)->total_bytes ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ +} while ( 0 ) + + + +/** + * @brief TLV structure containing information on current TLV transaction and its current data. + */ +typedef struct +{ + MBG_TLV_HDR hdr; ///< See ::MBG_TLV_HDR + uint8_t value[MSG_TLV_MAX_VALUE_SIZE]; ///< See ::MSG_TLV_MAX_VALUE_SIZE + +} MBG_TLV; + +#define _mbg_swab_tlv( _p ) \ +do \ +{ \ + _mbg_swab_tlv_header( &(_p)->hdr ); \ +} while ( 0 ) + +/** @} defgroup group_tlv_api */ + + + +/** + * @defgroup group_gps_nav_data Definitions used with navigational data received from GPS satellites + * + * @note These structures and definitions are only supported by a device + * if ::GPS_MODEL_IS_GPS is set in the @ref GPS_BUILTIN_FEATURE_MASKS + * + * @{ */ + + +/** + * @brief Ephemeris parameters of one specific satellite + * + * Needed to compute the position of a satellite at a given time with + * high precision. Valid for an interval of 4 to 6 hours from start + * of transmission. + */ +typedef struct +{ + CSUM csum; ///< checksum of the remaining bytes + int16_t valid; ///< flag data are valid + + HEALTH health; ///< health indication of transmitting SV [---] + IOD IODC; ///< Issue Of Data, Clock + IOD IODE2; ///< Issue of Data, Ephemeris (Subframe 2) + IOD IODE3; ///< Issue of Data, Ephemeris (Subframe 3) + T_GPS tt; ///< time of transmission + T_GPS t0c; ///< Reference Time Clock [---] + T_GPS t0e; ///< Reference Time Ephemeris [---] + + double sqrt_A; ///< Square Root of semi-major Axis [sqrt(m)] + double e; ///< Eccentricity [---] + double M0; ///< +- Mean Anomaly at Ref. Time [rad] + double omega; ///< +- Argument of Perigee [rad] + double OMEGA0; ///< +- Longit. of Asc. Node of orbit plane [rad] + double OMEGADOT; ///< +- Rate of Right Ascension [rad/sec] + double deltan; ///< +- Mean Motion Diff. from computed value [rad/sec] + double i0; ///< +- Inclination Angle [rad] + double idot; ///< +- Rate of Inclination Angle [rad/sec] + double crc; ///< +- Cosine Corr. Term to Orbit Radius [m] + double crs; ///< +- Sine Corr. Term to Orbit Radius [m] + double cuc; ///< +- Cosine Corr. Term to Arg. of Latitude [rad] + double cus; ///< +- Sine Corr. Term to Arg. of Latitude [rad] + double cic; ///< +- Cosine Corr. Term to Inclination Angle [rad] + double cis; ///< +- Sine Corr. Term to Inclination Angle [rad] + + double af0; ///< +- Clock Correction Coefficient 0 [sec] + double af1; ///< +- Clock Correction Coefficient 1 [sec/sec] + double af2; ///< +- Clock Correction Coefficient 2 [sec/sec^2] + double tgd; ///< +- estimated group delay differential [sec] + + uint16_t URA; ///< predicted User Range Accuracy + + uint8_t L2code; ///< code on L2 channel [---] + uint8_t L2flag; ///< L2 P data flag [---] + +} EPH; + + + +/** + * @brief Almanac parameters of one specific satellite + * + * A reduced precision set of parameters used to check if a satellite + * is in view at a given time. Valid for an interval of more than 7 days + * from start of transmission. + */ +typedef struct +{ + CSUM csum; ///< checksum of the remaining bytes + int16_t valid; ///< flag data are valid + + HEALTH health; ///< [---] + T_GPS t0a; ///< Reference Time Almanac [sec] + + double sqrt_A; ///< Square Root of semi-major Axis [sqrt(m)] + double e; ///< Eccentricity [---] + + double M0; ///< +- Mean Anomaly at Ref. Time [rad] + double omega; ///< +- Argument of Perigee [rad] + double OMEGA0; ///< +- Longit. of Asc. Node of orbit plane [rad] + double OMEGADOT; ///< +- Rate of Right Ascension [rad/sec] + double deltai; ///< +- [rad] + double af0; ///< +- Clock Correction Coefficient 0 [sec] + double af1; ///< +- Clock Correction Coefficient 1 [sec/sec] + +} ALM; + + + +/** + * @brief Summary of configuration and health data of all satellites + */ +typedef struct +{ + CSUM csum; ///< checksum of the remaining bytes + int16_t valid; ///< flag data are valid + + T_GPS tot_51; ///< time of transmission, page 51 + T_GPS tot_63; ///< time of transmission, page 63 + T_GPS t0a; ///< complete reference time almanac + + CFG cfg[N_SVNO_GPS]; ///< 4 bit SV configuration code from page 63 + HEALTH health[N_SVNO_GPS]; ///< 6 bit SV health codes from pages 51, 63 + +} CFGH; + + + +/** + * @brief GPS %UTC correction parameters + * + * %UTC correction parameters basically as sent by the GPS satellites. + * + * The csum field is only used by the device firmware to check the + * consistency of the structure in non-volatile memory. + * + * The field labeled valid indicates if the parameter set is valid, i.e. + * if it contains data received from the satellites. + * + * t0t, A0 and A1 contain fractional correction parameters for the current + * GPS-%UTC time offset in addition to the whole seconds. This is evaluated + * by the receivers' firmware to convert GPS time to %UTC time. + * + * The delta_tls field contains the current full seconds offset between + * GPS time and %UTC, which corresponds to the number of leap seconds inserted + * into the %UTC time scale since GPS was put into operation in January 1980. + * + * delta_tlfs holds the number of "future" leap seconds, i.e. the %UTC offset + * after the next leap second event defined by WNlsf and DNt. + * + * The fields WNlsf and DNt specify the GPS week number and the day number + * in that week for the end of which a leap second has been scheduled. + * + * @note: The satellites transmit WNlsf only as a signed 8 bit value, so it + * can only define a point in time which is +/- 127 weeks off the current time. + * The firmware tries to expand this based on the current week number, but + * the result is ambiguous if the leap second occurs or occurred more + * than 127 weeks in the future or past. + * + * So the leap second date should <b>only</b> be evaluated and displayed + * in a user interface if the fields delta_tls and delta_tlsf have + * different values, in which case there is indeed a leap second announcement + * inside the +/- 127 week range. + */ +typedef struct +{ + CSUM csum; ///< Checksum of the remaining bytes. + int16_t valid; ///< Flag indicating %UTC parameters are valid. + + T_GPS t0t; ///< Reference Time of %UTC Parameters @a A0 and @a A1 [wn|sec]. + double A0; ///< +- Clock Correction Coefficient 0 [sec]. + double A1; ///< +- Clock Correction Coefficient 1 [sec/sec]. + + GPS_WNUM WNlsf; ///< Week number of nearest leap second, originally + ///< truncated to 8 bit, so the extended number can be + ///< ambiguous unless @a #delta_tls and @a #delta_tlsf + ///< differ, indicating that a leap second is actually + ///< being announced. + + GPS_DNUM DNt; ///< The day-of-week at the end of which a leap second occurs. + ///< Transmitted numbers in the range 1..7 rather than 0..6. + + int8_t delta_tls; ///< Current %UTC offset to GPS system time [sec]. + + int8_t delta_tlsf; ///< Future %UTC offset to GPS system time + ///< after next leap second transition [sec]. + +} UTC; + +#define _mbg_swab_utc_parm( _p ) \ +do \ +{ \ + _mbg_swab_csum( &(_p)->csum ); \ + _mbg_swab16( &(_p)->valid ); \ + _mbg_swab_t_gps( &(_p)->t0t ); \ + _mbg_swab_double( &(_p)->A0 ); \ + _mbg_swab_double( &(_p)->A1 ); \ + _mbg_swab16( &(_p)->WNlsf ); \ + _mbg_swab16( &(_p)->DNt ); \ +} while ( 0 ) + + + +/** + * @brief Ionospheric correction parameters + */ +typedef struct +{ + CSUM csum; ///< checksum of the remaining bytes + int16_t valid; ///< flag data are valid + + double alpha_0; ///< Ionosph. Corr. Coeff. Alpha 0 [sec] + double alpha_1; ///< Ionosph. Corr. Coeff. Alpha 1 [sec/deg] + double alpha_2; ///< Ionosph. Corr. Coeff. Alpha 2 [sec/deg^2] + double alpha_3; ///< Ionosph. Corr. Coeff. Alpha 3 [sec/deg^3] + + double beta_0; ///< Ionosph. Corr. Coeff. Beta 0 [sec] + double beta_1; ///< Ionosph. Corr. Coeff. Beta 1 [sec/deg] + double beta_2; ///< Ionosph. Corr. Coeff. Beta 2 [sec/deg^2] + double beta_3; ///< Ionosph. Corr. Coeff. Beta 3 [sec/deg^3] + +} IONO; + + + +/** + * @brief GPS ASCII message + */ +typedef struct +{ + CSUM csum; ///< checksum of the remaining bytes */ + int16_t valid; ///< flag data are valid + char s[23]; ///< 22 chars GPS ASCII message plus trailing zero + +} ASCII_MSG; + +/** @} defgroup group_gps_nav_data */ + + + +enum GPS_PLATFORMS +{ + GPS_PLATFORM_PORTABLE, + GPS_PLATFORM_FIXED, + GPS_PLATFORM_STATIONARY, + GPS_PLATFORM_PEDESTRIAN, + GPS_PLATFORM_AUTOMOTIVE, + GPS_PLATFORM_SEA, + GPS_PLATFORM_AIRBORNE_1G, + GPS_PLATFORM_AIRBORNE_2G, + GPS_PLATFORM_AIRBORNE_4G, + N_GPS_PLATFORMS +}; + + +#define GPS_PLATFORM_STRS \ +{ \ + "Portable ", \ + "Fixed ", \ + "Stationary ", \ + "Pedestrian ", \ + "Automotive ", \ + "Sea ", \ + "Airborne <1G", \ + "Airborne <2G", \ + "Airborne <4G" \ +} + + + +enum TIME_MODES +{ + TIME_MODE_DISABLED, + TIME_MODE_SURVEY_IN, + TIME_MODE_FIXED, + N_TIME_MODES +}; + + + +typedef struct +{ + uint32_t time_mode; + uint32_t survey_in_duration; + uint32_t survey_in_pos_var; + int32_t fixedPosX; // cm + int32_t fixedPosY; // cm + int32_t fixedPosZ; // cm + uint32_t fixedPosVar; // cm + uint32_t flags; // currently 0 + uint32_t reserved; // currently 0 + +} NAV_TIME_MODE_SETTINGS; + + + +/** + * Navigation Engine settings to set configuration + * parameters of a dynamic platform model. + */ +typedef struct +{ + uint8_t dynamic_platform; + uint8_t fix_mode; + int8_t min_elevation; + uint8_t static_hold_threshold; + int32_t fixed_altitude; + uint32_t fixed_altitude_variance; + uint32_t flags; // currently 0 + uint32_t reserved; // currently 0 + NAV_TIME_MODE_SETTINGS nav_time_mode_settings; + +} NAV_ENGINE_SETTINGS; + + + +/** + * @defgroup group_sys_ref Reference system configuration + * + * System-wide reference configuration as replacement for XMR to provide an + * improved global API for new meinbergOS systems. + * + * This API is only supported if ::MBG_XFEATURE_SYS_REF is set. + */ + +typedef struct mbg_sys_ref_limits_s +{ + uint32_t num_ref_srcs; ///< Number of reference sources supported by the system, see ::MBG_SYS_REF_SRC_INFO_IDX + uint8_t max_prios; + uint8_t reserved_1[3]; + + uint32_t reserved_2[14]; ///< Reserved, currently always 0 + +} MBG_SYS_REF_LIMITS; + + +#define _mbg_swab_sys_ref_limits( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->num_ref_srcs ); \ + _mbg_swab32( &(_p)->supp_ref_types ); \ +} while ( 0 ) + + +enum MBG_SYS_REF_SRC_FLAGS +{ + SYS_REF_SRC_FLAG_XMR_STATS_SUPP, ///< Indicates, whether XMR stats are supported, read-only + SYS_REF_SRC_FLAG_XMR_ADV_METRICS_SUPP, ///< Indicates, whether advanced XMR metrics are supported, read-only + ///< Refers to the adv. metrics XMR feature, see ::XMR_EXT_SRC_FEAT_FLAG_BIT_ADV_METRICS + SYS_REF_SRC_FLAG_XMR_COASTING_SUPP, ///< Indicates, whether XMR coasting is supported, read-only + N_SYS_REF_SRC_FLAGS +}; + + +enum MBG_SYS_REF_SRC_MASKS +{ + SYS_REF_SRC_MASK_XMR_STATS_SUPP = ( 1UL << SYS_REF_SRC_FLAG_XMR_STATS_SUPP ), ///< See ::SYS_REF_SRC_FLAG_XMR_STATS_SUPP + SYS_REF_SRC_MASK_XMR_ADV_METRICS_SUPP = ( 1UL << SYS_REF_SRC_FLAG_XMR_ADV_METRICS_SUPP ), ///< See ::SYS_REF_SRC_FLAG_XMR_ADV_METRICS_SUPP + SYS_REF_SRC_MASK_XMR_COASTING_SUPP = ( 1UL << SYS_REF_SRC_FLAG_XMR_COASTING_SUPP ) ///< See ::SYS_REF_SRC_FLAG_XMR_COASTING_SUPP +}; + + +enum MBG_SYS_REF_SRC_TYPES +{ + SYS_REF_SRC_INTEGRATED, ///< Integrated reference source, i.e. an SMA or BNC port on the module itself + SYS_REF_SRC_PERIPHERAL, ///< Peripheral reference source, i.e. a port on an MRI (expansion) module + ///< Can only be used, if the equivalent ::SYS_REF_SRC_EXPANSION is equipped + SYS_REF_SRC_EXPANSION, ///< Expansion reference source announced by peripheral modules (i.e. MRI) + ///< Can only be used, if the equivalent ::SYS_REF_SRC_PERIPHERAL has been announced by the clock module + SYS_REF_SRC_AUTARKIC, ///< Autarkic reference source measuring a distinct offset, i.e. an ESI or a PTP (HPS) module + N_SYS_REF_SRC_TYPES +}; + + +#define SYS_REF_SRC_PRIO_UNUSED 0xFF +#define SYS_REF_SRC_INFO_STR_LEN 32 + +#define SYS_REF_SRC_PRQ_UNQUANTIFIED (-1) + +typedef struct mbg_sys_ref_src_settings_s +{ + uint8_t prio; ///< Priority for this reference + ///< must be 0 .. ::MBG_SYS_REF_LIMITS::num_ref_srcs or ::SYS_REF_SRC_PRIO_UNUSED + uint8_t itu_mask; ///< Used mask for ::XMR_METRICS, see ::MBG_SYS_REF_SRC_INFO::supp_itu_masks, only valid if + ///< ::SYS_REF_SRC_MASK_XMR_ADV_METRICS_SUPP is set in ::MBG_SYS_REF_SRC_INFO::supp_flags + uint8_t hysteresis; ///< Hysteresis (percent) between yellow and red alarm for ::XMR_METRICS, only valid if + ///< ::SYS_REF_SRC_MASK_XMR_ADV_METRICS_SUPP is set in ::MBG_SYS_REF_SRC_INFO::supp_flags + uint8_t reserved; ///< Reserved, currently always 0 + + uint32_t xmr_flags; ///< See ::XMR_SETTINGS_FLAG_MSKS + + NANO_TIME bias; ///< time bias, e.g. path delay + NANO_TIME precision; ///< precision of the time source + + uint32_t ro_uid; ///< Read-Only unique ref source identifier. We desperately + ///< need it to not be index dependent when sending settings. + ///< Layout from MSB to LSB: + ///< 8 bit chassis Id - 8 bit slot ID - 8 bit ref type (::MULTI_REF_TYPES) - 8 bit instance number (::XMULTI_REF_INSTANCES::n_inst[ref type]) + + int8_t quantifier; ///< Source precision quantifier (PRQ) to minimize clock switching operations, see ::SYS_REF_SRC_PRQ_UNQUANTIFIED. + ///< The smaller the value the more important is this source in relation to other sources (priorities). + uint8_t reserved_1[3]; + + uint32_t reserved_2[8]; ///< Reserved, currently always 0 + +} MBG_SYS_REF_SRC_SETTINGS; + + +/** + * @brief Default initializer for ::MBG_SYS_REF_SRC_SETTINGS::quantifier and the corresponding ::MULTI_REF_TYPES + * in ::XMULTI_REF_INSTANCES::n_inst. Keep them in sync! + */ +#define SYS_REF_SRC_QUANTIFIERS \ +{ \ + 0, 1, 1, SYS_REF_SRC_PRQ_UNQUANTIFIED, \ + 4, 6, 2, SYS_REF_SRC_PRQ_UNQUANTIFIED, \ + 1, 3, 3, SYS_REF_SRC_PRQ_UNQUANTIFIED, \ + 6, 6, 0, 3, \ + 5, 2, SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED, \ + SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED, \ + SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED, \ + SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED, SYS_REF_SRC_PRQ_UNQUANTIFIED \ +} + + +#define __to_sys_ref_ro_uid(c, s, t, i) \ + (((uint32_t)(c) << 24) | \ + ((uint32_t)(s) << 16) | \ + ((uint32_t)(t) << 8) | \ + ((uint32_t)(i))) + + +#define _mbg_swab_sys_ref_src_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->xmr_flags ); \ + _mbg_swab_nano_time( &(_p)->bias ); \ + _mbg_swab_nano_time( &(_p)->precision ); \ + _mbg_swab32( &(_p)->ro_uid ); \ +} while ( 0 ) + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SYS_REF_SRC_SETTINGS settings; + +} MBG_SYS_REF_SRC_SETTINGS_IDX; + + +#define _mbg_swab_sys_ref_src_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_sys_ref_src_settings( &(_p)->settings ); \ +} while ( 0 ) + + +#define SYS_REF_SRC_PORT_UNKNOWN 0xFF + + +typedef struct mbg_sys_ref_src_info_s +{ + MBG_SYS_REF_SRC_SETTINGS settings; ///< See ::MBG_SYS_REF_SRC_SETTINGS + + uint8_t ref_type; ///< See ::MULTI_REF_TYPES + uint8_t conn_type; ///< See ::MBG_SYS_REF_SRC_TYPES + uint8_t clock_idx; ///< Index of the associated clock, if #conn_type is ::SYS_REF_SRC_PERIPHERAL, resp. ::SYS_REF_SRC_EXPANSION + 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 slot_type_id; ///< See ::XBP_NODE_INFO::slot_type_id, or ::MBG_OWN_EVENT_SLOT_TYPE_ID + uint8_t port_idx; ///< Index of the associated physical port (I/O port), or ::SYS_REF_SRC_PORT_UNKNOWN. + uint8_t inst_num; ///< Instance number of ref_type in slot. See ::XMULTI_REF_INSTANCES::n_inst + + char str[SYS_REF_SRC_INFO_STR_LEN]; ///< String for reference identification + + uint32_t supp_xmr_flags; ///< See ::XMR_SETTINGS_FLAG_MSKS + uint32_t supp_flags; ///< See ::MBG_SYS_REF_SRC_INFO::supp_flags and ::MBG_SYS_REF_SRC_MASKS + uint32_t supp_itu_masks; ///< See ::ITU_LIMIT_MASKS + uint32_t reserved_2[7]; ///< Reserved, currently always 0 + +} MBG_SYS_REF_SRC_INFO; + + +#define _mbg_swab_sys_ref_src_info( _p ) \ +do \ +{ \ + _mbg_swab_sys_ref_src_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_xmr_flags ); \ + _mbg_swab32( &(_p)->supp_itu_masks ); \ +} while ( 0 ) + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SYS_REF_SRC_INFO info; + +} MBG_SYS_REF_SRC_INFO_IDX; + + +#define _mbg_swab_sys_ref_src_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_sys_ref_src_info( &(_p)->info ); \ +} while ( 0 ) + + + +enum MBG_EST_TIME_QUALITY +{ + MBG_EST_TIME_QUALITY_RES_1, + MBG_EST_TIME_QUALITY_RES_2, + MBG_EST_TIME_QUALITY_RES_3, + MBG_EST_TIME_QUALITY_1ns, + MBG_EST_TIME_QUALITY_10ns, + MBG_EST_TIME_QUALITY_25ns, + MBG_EST_TIME_QUALITY_100ns, + MBG_EST_TIME_QUALITY_250ns, + MBG_EST_TIME_QUALITY_1us, + MBG_EST_TIME_QUALITY_2_5us, + MBG_EST_TIME_QUALITY_10us, + MBG_EST_TIME_QUALITY_25us, + MBG_EST_TIME_QUALITY_100us, + MBG_EST_TIME_QUALITY_250us, + MBG_EST_TIME_QUALITY_1ms, + MBG_EST_TIME_QUALITY_2_5ms, + MBG_EST_TIME_QUALITY_10ms, + MBG_EST_TIME_QUALITY_25ms, + MBG_EST_TIME_QUALITY_100ms, + MBG_EST_TIME_QUALITY_250ms, + MBG_EST_TIME_QUALITY_1s, + MBG_EST_TIME_QUALITY_10s, + MBG_EST_TIME_QUALITY_more_10s, + N_MBG_EST_TIME_QUALITYS +}; + + +#define MBG_EST_TIME_QUALITY_STRS \ +{ \ + "Unknown", \ + "Unknown", \ + "Unknown", \ + "1 ns", \ + "10 ns", \ + "25 ns", \ + "100 ns", \ + "250 ns", \ + "1 us", \ + "2.5 us", \ + "10 us", \ + "25 us", \ + "100 us", \ + "250 us", \ + "1 ms", \ + "2.5 ms", \ + "10 ms", \ + "25 ms", \ + "100 ms", \ + "250 ms", \ + "1 s", \ + "10 s", \ + "> 10 s" \ +} + + +typedef struct mbg_sys_ref_glb_status_s +{ + uint32_t master_idx; ///< Index of currently used reference source, see ::MBG_SYS_REF_SRC_INFO_IDX::idx + uint8_t ref_type; ///< Reference type of the currently used clock, see ::MULTI_REF_TYPES + uint8_t reserved_1[3]; ///< Reserved, currently always 0 + + XMR_HOLDOVER_STATUS holdover_status; ///< See ::XMR_HOLDOVER_STATUS, holdover status of currently used reference source + + uint8_t clock_idx; ///< Index of the currently used clock starting with 0, depends on #master_idx + uint8_t osc_type; ///< Oscillator type of the currently selected clock, see ::GPS_OSC_TYPES + TM_GPS_STATUS tm_gps_status; ///< Status flags from ::TM_GPS of the currently used clock, see ::TM_GPS_STATUS_BIT_MASKS + + uint8_t est_time_quality; ///< Current estimated time quality of the used clock, see ::MBG_EST_TIME_QUALITY + uint8_t reserved_2[3]; ///< Reserved, currently always 0 + uint16_t scaled_log_variance; ///< Current variance of the clock, depending on the oscillator type as defined in IEEE1588 + uint16_t reserved_3; ///< Reserved, currently always 0 + + UTC utc_parms; ///< %UTC offset, leap second information, etc., see ::UTC, + ///< TODO!!! can this be used? contains doubles + + uint32_t reserved_4[8]; ///< Reserved, currently always 0 + +} MBG_SYS_REF_GLB_STATUS; + + +#define _mbg_swab_sys_ref_glb_status( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->master_idx ); \ + _mbg_swab_xmr_holdover_status( &(_p)->holdover_status ); \ + _mbg_swab_tm_gps_status( &(_p)->tm_gps_status ); \ + _mbg_swab32( &(_p)->est_time_quality ); \ + _mbg_swab16( &(_p)->scaled_log_variance ); \ + _mbg_swab_utc_parm( &(_p)->utc_parms ); \ +} while ( 0 ) + + +enum MBG_SYS_REF_SRC_STATUS_SUPP_FLAGS +{ + SYS_REF_SRC_STATUS_SUPP_SSM, ///< Indicates, that ::MBG_SYS_REF_SRC_STATUS::ssm holds a valid value + SYS_REF_SRC_STATUS_SUPP_OUTAGE_CNT, ///< Indicates, that ::MBG_SYS_REF_SRC_STATUS::outage_cnt holds a valid value + SYS_REF_SRC_STATUS_SUPP_XMR_HOLDOVER, ///< Indicates, that ::MBG_SYS_REF_SRC_STATUS::xmr_holdover holds valid values + SYS_REF_SRC_STATUS_SUPP_XMR_STATS, ///< Indicates, that ::MBG_SYS_REF_SRC_STATUS::xmr_stats holds valid values + SYS_REF_SRC_STATUS_SUPP_XMR_METRICS, ///< Indicates, that ::MBG_SYS_REF_SRC_STATUS::xmr_metrics holds valid values + N_SYS_REF_SRC_STATUS_SUPP_FLAGS +}; + + +enum MBG_SYS_REF_SRC_STATUS_SUPP_MASKS +{ + SYS_REF_SRC_STATUS_SUPP_SSM_MASK = ( 1UL << SYS_REF_SRC_STATUS_SUPP_SSM ), ///< See ::SYS_REF_SRC_STATUS_SUPP_SSM + SYS_REF_SRC_STATUS_SUPP_OUTAGE_CNT_MASK = ( 1UL << SYS_REF_SRC_STATUS_SUPP_OUTAGE_CNT ), ///< See ::SYS_REF_SRC_STATUS_SUPP_OUTAGE_CNT + SYS_REF_SRC_STATUS_SUPP_XMR_HOLDOVER_MASK = ( 1UL << SYS_REF_SRC_STATUS_SUPP_XMR_HOLDOVER ), ///< See ::SYS_REF_SRC_STATUS_SUPP_XMR_HOLDOVER + SYS_REF_SRC_STATUS_SUPP_XMR_STATS_MASK = ( 1UL << SYS_REF_SRC_STATUS_SUPP_XMR_STATS ), ///< See ::SYS_REF_SRC_STATUS_SUPP_XMR_STATS + SYS_REF_SRC_STATUS_SUPP_XMR_METRICS_MASK = ( 1UL << SYS_REF_SRC_STATUS_SUPP_XMR_METRICS ) ///< See ::SYS_REF_SRC_STATUS_SUPP_XMR_METRICS +}; + + +typedef struct mbg_sys_ref_src_status_s +{ + char str[SYS_REF_SRC_INFO_STR_LEN]; ///< String for reference identification + + uint32_t xmr_status; ///< See @ref XMR_REF_STATUS_BIT_MASKS + + NANO_TIME offset; ///< time offset from main time base + + uint8_t ssm; ///< synchronization status message, only valid if ::SYS_REF_SRC_STATUS_SUPP_SSM_MASK is set + uint8_t prio; ///< Priority for this reference + uint8_t reserved[2]; ///< Reserved, currently always 0 + + uint32_t outage_cnt; ///< signal outage counter, incremented on loss of signal, only valid if ::SYS_REF_SRC_STATUS_SUPP_OUTAGE_CNT_MASK is set + + XMR_HOLDOVER_STATUS xmr_holdover; ///< See ::XMR_HOLDOVER_STATUS, only valid if ::SYS_REF_SRC_STATUS_SUPP_XMR_HOLDOVER_MASK is set + XMR_STATS xmr_stats; ///< See ::XMR_STATS, only valid if ::SYS_REF_SRC_STATUS_SUPP_XMR_STATS_MASK is set + XMR_METRICS xmr_metrics; ///< See ::XMR_METRICS, only valid if ::SYS_REF_SRC_STATUS_SUPP_XMR_METRICS_MASK is set + + uint32_t supp_flags; ///< See ::MBG_SYS_REF_SRC_STATUS_SUPP_MASKS + + uint32_t reserved_4[8]; ///< Reserved, currently always 0 + +} MBG_SYS_REF_SRC_STATUS; + + +#define _mbg_swab_sys_ref_src_status( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->xmr_status ); \ + _mbg_swab_nano_time( &(_p)->offset ); \ + _mbg_swab32( &(_p)->outage_cnt ); \ + _mbg_swab_xmr_holdover_status( &(_p)->xmr_holdover ); \ + _mbg_swab_xmr_stats( &(_p)->xmr_stats ); \ + _mbg_swab_xmr_metrics( &(_p)->xmr_metrics ); \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SYS_REF_SRC_STATUS status; + +} MBG_SYS_REF_SRC_STATUS_IDX; + + +#define _mbg_swab_sys_ref_src_status_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_sys_ref_src_status( &(_p)->status ); \ +} while ( 0 ) + + +/** @} defgroup group_sys_ref */ + + +/** + * @defgroup group_led_api Meinberg LED API definitions + * + * @note These structures and definitions are only supported by a device + * if ::MBG_XFEATURE_LED_API is set in the extended device features. + * + * @{ */ + + +/** + * @brief General LED info to be read from a device + * + * Used to query from a device how many LEDs are supported + * by the device, then index 0..::MBG_LED_LIMITS::num_leds-1 + * ::MBG_LED_INFO_IDX or ::MBG_LED_SETTINGS_IDX structures + * can be read from or written to the device. + * + * @see ::MBG_LED_SETTINGS_IDX + * @see ::MBG_LED_INFO_IDX + */ +typedef struct +{ + uint8_t num_leds; ///< Number of supported LEDs, see ::MBG_LED_SETTINGS_IDX::idx and ::MBG_LED_INFO_IDX::idx + uint8_t reserved_0; ///< Currently reserved, unused, always 0 + uint16_t reserved_1; ///< Currently reserved, unused, always 0 + uint32_t reserved_2; ///< Currently reserved, unused, always 0 + +} MBG_LED_LIMITS; + +#define _mbg_swab_mbg_led_limits( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->num_leds ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +/** + * @brief Possible modes of LEDs + * + * Used with ::MBG_LED_SETTINGS::mode + * + * @see ::MBG_LED_MODE_MASKS + */ +enum MBG_LED_MODES +{ + MBG_LED_MODE_OFF, + MBG_LED_MODE_ON, + MBG_LED_MODE_FLASH, + MBG_LED_MODE_FLASH_5S, + N_MBG_LED_MODES +}; + + + +/** + * @brief Bit masks associated with LED modes + * + * Used with ::MBG_LED_INFO::supp_modes + * + * @see ::MBG_LED_MODES + */ +enum MBG_LED_MODE_MASKS +{ + MBG_LED_MODE_MASK_OFF = ( 1UL << MBG_LED_MODE_OFF ), ///< See ::MBG_LED_MODE_OFF + MBG_LED_MODE_MASK_ON = ( 1UL << MBG_LED_MODE_ON ), ///< See ::MBG_LED_MODE_ON + MBG_LED_MODE_MASK_FLASH = ( 1UL << MBG_LED_MODE_FLASH ), ///< See ::MBG_LED_MODE_FLASH + MBG_LED_MODE_MASK_FLASH_5S = ( 1UL << MBG_LED_MODE_FLASH_5S ) ///< See ::MBG_LED_MODE_FLASH_5S +}; + + +/** + * @brief Names of LED modes + * + * Can be used to initialize a string array of ::N_MBG_LED_MODES entries, + * so the number of strings must correspond to ::N_MBG_LED_MODES. + * + * @see ::MBG_LED_MODES + * @see ::MBG_LED_MODE_MASKS + */ +#define MBG_LED_MODE_STRS \ +{ \ + "Off", \ + "On", \ + "Flash", \ + "Flash 5s" \ +} + + + +/** + * @brief Possible colors of LEDs + * + * Used with ::MBG_LED_SETTINGS::color + * + * @see ::MBG_LED_COLOR_MASKS + */ +enum MBG_LED_COLORS +{ + MBG_LED_COLOR_GREEN, + MBG_LED_COLOR_RED, + MBG_LED_COLOR_YELLOW, + MBG_LED_COLOR_BLUE, + N_MBG_LED_COLORS +}; + + + +/** + * @brief Bit masks of possible LED colors + * + * Used with ::MBG_LED_INFO::supp_colors + * + * @see ::MBG_LED_COLORS + */ +enum MBG_LED_COLOR_MASKS +{ + MBG_LED_COLOR_MASK_GREEN = ( 1UL << MBG_LED_COLOR_GREEN ), ///< See ::MBG_LED_COLOR_GREEN + MBG_LED_COLOR_MASK_RED = ( 1UL << MBG_LED_COLOR_RED ), ///< See ::MBG_LED_COLOR_RED + MBG_LED_COLOR_MASK_YELLOW = ( 1UL << MBG_LED_COLOR_YELLOW ), ///< See ::MBG_LED_COLOR_YELLOW + MBG_LED_COLOR_MASK_BLUE = ( 1UL << MBG_LED_COLOR_BLUE ) ///< See ::MBG_LED_COLOR_BLUE +}; + + + +/** + * @brief Names of LED colors + * + * Can be used to initialize a string array of ::N_MBG_LED_COLORS entries, + * so the number of strings must correspond to ::N_MBG_LED_COLORS. + * + * @see ::MBG_LED_COLORS + * @see ::MBG_LED_COLOR_MASKS + */ +#define MBG_LED_COLOR_STRS \ +{ \ + "Green", \ + "Red", \ + "Yellow", \ + "Blue" \ +} + + + +/** + * @brief Configuration settings for a single LED + * + * @see ::MBG_LED_SETTINGS_IDX + */ +typedef struct +{ + uint8_t mode; ///< LED mode, see ::MBG_LED_MODES + uint8_t color; ///< LED color, see ::MBG_LED_COLORS + uint16_t reserved; ///< Currently reserved, unused, always 0 + +} MBG_LED_SETTINGS; + +#define _mbg_swab_mbg_led_settings( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->mode ); \ + _mbg_swab8( &(_p)->color ); \ + _mbg_swab16( &(_p)->reserved ); \ +} while ( 0 ) + + + +/** + * @brief Configuration settings for a single LED, plus index + * + * @see ::MBG_LED_SETTINGS + * @see ::MBG_LED_LIMITS + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_LED_LIMITS::num_leds-1. + MBG_LED_SETTINGS settings; ///< LED settings. + +} MBG_LED_SETTINGS_IDX; + +#define _mbg_swab_mbg_led_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_led_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of an LED + * + * This structure should be read from the device to retrieve the + * current settings of an LED plus its capabilities, e.g. the + * supported modes, colors, etc. + * + * @see ::MBG_LED_INFO_IDX + */ +typedef struct +{ + MBG_LED_SETTINGS settings; ///< Current LED settings + uint32_t supp_modes; ///< Supported modes, see ::MBG_LED_MODE_MASKS + uint32_t supp_colors; ///< Supported colors, see ::MBG_LED_COLOR_MASKS + uint32_t reserved; ///< Currently reserved, unused, always 0 + uint32_t flags; ///< Currently reserved, unused, always 0 + +} MBG_LED_INFO; + +#define _mbg_swab_mbg_led_info( _p ) \ +do \ +{ \ + _mbg_swab_mbg_led_settings( &(_p)->settings ); \ + _mbg_swab32( &(_p)->supp_modes ); \ + _mbg_swab32( &(_p)->supp_colors ); \ + _mbg_swab32( &(_p)->reserved ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of an LED, plus index + * + * @see ::MBG_LED_INFO + * @see ::MBG_LED_LIMITS + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_LED_LIMITS::num_leds-1. + MBG_LED_INFO info; ///< LED info. + +} MBG_LED_INFO_IDX; + +#define _mbg_swab_mbg_led_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_led_info( &(_p)->info ); \ +} while ( 0 ) + +/** @} defgroup group_led_api */ + + + +/** + * @defgroup group_lne_api Definitions specific to LNE devices + * + * @note These structures and definitions are only supported by a device + * if ::MBG_XFEATURE_LNE_API is set in the extended device features. + * + * @{ */ + + +/** + * @brief General info to be read from an LNE device + * + * Used to query from a device e.g. how many LNE ports are provided + * by the device, then index 0..::MBG_LNE_LIMITS::num_ports-1 + * ::MBG_LNE_PORT_INFO_IDX or ::MBG_LNE_PORT_SETTINGS_IDX structures + * can be read from or written to the device. + * + * @see ::MBG_LNE_PORT_SETTINGS_IDX + * @see ::MBG_LNE_PORT_INFO_IDX + */ +typedef struct +{ + uint8_t num_ports; ///< Number of supported ports, see ::MBG_LNE_PORT_SETTINGS_IDX::idx and ::MBG_LNE_PORT_INFO_IDX::idx + uint8_t reserved_0; ///< Currently reserved, unused, always 0 + uint16_t reserved_1; ///< Currently reserved, unused, always 0 + uint32_t features; // ### TODO Mask of supported features, see ::MBG_LNE_FEAT_MASKS + ///< Currently reserved, unused, always 0 + uint32_t reserved_2; ///< Currently reserved, unused, always 0 + +} MBG_LNE_LIMITS; + +#define _mbg_swab_mbg_lne_limits( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->num_ports ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->features ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ +} while ( 0 ) + + + +#if 0 //### TODO //################# + +/** + * @brief LNE feature bits + * + * Used to define ::MBG_LNE_FEAT_MASKS + * + * @see ::MBG_LNE_FEAT_MASKS + */ +enum MBG_LNE_FEAT_BITS +{ + MBG_LNE_FEAT_BIT_SWITCH_PWR, ///< Power switching off all LNE ports at once supported, see ::MBG_LNE_PWR_STATE + N_MBG_LNE_FEAT_BITS +}; + + + +/** + * @brief LNE feature bit masks + * + * Used with ::MBG_LNE_LIMITS::features + * + * @see ::MBG_LNE_FEAT_BITS + */ +enum MBG_LNE_FEAT_MASKS +{ + MBG_LNE_FEAT_MASK_SWITCH_PWR = ( 1UL << MBG_LNE_FEAT_BIT_SWITCH_PWR ) ///< See ::MBG_LNE_FEAT_BIT_SWITCH_PWR +}; + +#endif + + + +/** + * @brief Configuration settings for a single LNE port + * + * @see ::MBG_LNE_PORT_SETTINGS_IDX + */ +typedef struct +{ + uint32_t reserved_0; ///< currently reserved, unused, always 0 + uint32_t reserved_1; ///< currently reserved, unused, always 0 + uint32_t reserved_2; ///< currently reserved, unused, always 0 + uint32_t flags; ///< currently reserved, unused, always 0 + +} MBG_LNE_PORT_SETTINGS; + +#define _mbg_swab_mbg_lne_port_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Configuration settings for a single LNE port, plus index + * + * @see ::MBG_LNE_PORT_SETTINGS + * @see ::MBG_LNE_LIMITS + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_LNE_LIMITS::num_ports-1. + MBG_LNE_PORT_SETTINGS settings; ///< LNE settings. + +} MBG_LNE_PORT_SETTINGS_IDX; + +#define _mbg_swab_mbg_lne_port_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_lne_port_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of an LNE port + * + * This structure should be read from the device to retrieve the + * current settings of an LNE port plus its capabilities, ### e.g. the + * supported modes, colors, etc. + * + * @see ::MBG_LNE_PORT_INFO_IDX + */ +typedef struct +{ + MBG_LNE_PORT_SETTINGS settings; ///< Current LNE port settings + MBG_MAC_ADDR mac_addr; ///< The MAC address assigned to this port + uint32_t reserved_0; ///< currently reserved, unused, always 0 + uint32_t reserved_1; ///< currently reserved, unused, always 0 + uint32_t reserved_2; ///< currently reserved, unused, always 0 + uint32_t flags; ///< See ::LNE_PORT_FLAG_MASKS + +} MBG_LNE_PORT_INFO; + +#define _mbg_swab_mbg_lne_port_info( _p ) \ +do \ +{ \ + _mbg_swab_mbg_lne_port_settings( &(_p)->settings ); \ + _mbg_swab_mbg_mac_addr( &(_p)->mac_addr ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Current settings and general capabilities of an LNE port, plus index + * + * @see ::MBG_LNE_PORT_INFO + * @see ::MBG_LNE_LIMITS + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0..::MBG_LED_LIMITS::num_leds-1. + MBG_LNE_PORT_INFO info; ///< LNE port info. + +} MBG_LNE_PORT_INFO_IDX; + +#define _mbg_swab_mbg_lne_port_info_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_mbg_lne_port_info( &(_p)->info ); \ +} while ( 0 ) + + + +/** + * @brief LNE port flag bits + * + * Used to define ::LNE_PORT_FLAG_MASKS + * + * @see ::LNE_PORT_FLAG_MASKS + */ +enum LNE_PORT_FLAG_BITS +{ + LNE_PORT_FLAG_BIT_IS_SFP, + N_LNE_PORT_FLAG_BITS +}; + + + +/** + * @brief LNE port flag bit masks + * + * Used with ::MBG_LNE_PORT_INFO::flags + * + * @see ::LNE_PORT_FLAG_BITS + */ +enum LNE_PORT_FLAG_MASKS +{ + LNE_PORT_FLAG_MASK_IS_SFP = ( 1UL << LNE_PORT_FLAG_BIT_IS_SFP ) ///< See ::LNE_PORT_FLAG_BIT_IS_SFP +}; + + +/** @} defgroup group_lne_api */ + + + +/** + * @defgroup group_pwr_ctl_api Definitions for power control API + * + * @note These structures and definitions are only supported by a device + * if ::MBG_XFEATURE_PWR_CTL_API is set in the extended device features. + * + * @{ */ + + +/** + * @brief Device power states + * + * Used with ::MBG_PWR_CTL::state. + */ +enum MBG_PWR_STATES +{ + MBG_PWR_STATE_OFF, + MBG_PWR_STATE_ON, + N_MBG_PWR_STATES +}; + + + +/** + * @brief Device power control + * + * Used to change or retrieve the power state of a device. + */ +typedef struct +{ + uint8_t state; ///< See ::MBG_PWR_STATES + uint8_t reserved_0; ///< Currently reserved, unused, always 0 + uint16_t reserved_1; ///< Currently reserved, unused, always 0 + +} MBG_PWR_CTL; + +#define _mbg_swab_mbg_pwr_ctl( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->state ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ +} while ( 0 ) + +/** @} defgroup group_pwr_ctl_api */ + + + + +/** + * @defgroup group_ext_sys_info Extended system information + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_EXT_SYS_INFO is set in the extended device features. + * + * @{ */ + + +/** + * @brief Bits used to define ::MBG_EXT_SYS_INFO_MSKS + * + * @see ::MBG_EXT_SYS_INFO_MSKS + */ +enum MBG_EXT_SYS_INFO_BITS +{ + MBG_EXT_SYS_INFO_BIT_SW_REV, + MBG_EXT_SYS_INFO_BIT_HW_REV, + MBG_EXT_SYS_INFO_BIT_OS_REV, + MBG_EXT_SYS_INFO_BIT_FPGA_REV, + MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV, + 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, + MBG_EXT_SYS_INFO_BIT_STATUS, ///< Bit to announce ::MBG_EXT_SYS_STATUS support + MBG_EXT_SYS_INFO_BIT_COMMIT_HASH, + MBG_EXT_SYS_INFO_BIT_OS_NAME, + N_MBG_EXT_SYS_INFO_BITS +}; + +/** + * @brief Bit masks of supported revision numbers + * + * Used with ::MBG_EXT_SYS_INFO::supp_members + * + * @see ::MBG_EXT_SYS_INFO_BITS + */ +enum MBG_EXT_SYS_INFO_MSKS +{ + MBG_EXT_SYS_INFO_MSK_SW_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_SW_REV ), ///< See ::MBG_EXT_SYS_INFO_BIT_SW_REV + MBG_EXT_SYS_INFO_MSK_HW_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_HW_REV ), ///< See ::MBG_EXT_SYS_INFO_BIT_HW_REV + MBG_EXT_SYS_INFO_MSK_OS_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_OS_REV ), ///< See ::MBG_EXT_SYS_INFO_BIT_OS_REV + MBG_EXT_SYS_INFO_MSK_FPGA_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_FPGA_REV ), ///< See ::MBG_EXT_SYS_INFO_BIT_FPGA_REV + MBG_EXT_SYS_INFO_MSK_CORE_MOD_REV = ( 1UL << MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV ), ///< See ::MBG_EXT_SYS_INFO_BIT_CORE_MOD_REV + 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 + MBG_EXT_SYS_INFO_MSK_STATUS = ( 1UL << MBG_EXT_SYS_INFO_BIT_STATUS ), ///< See ::MBG_EXT_SYS_INFO_BIT_STATUS + MBG_EXT_SYS_INFO_MSK_COMMIT_HASH = ( 1UL << MBG_EXT_SYS_INFO_BIT_COMMIT_HASH ), ///< See ::MBG_EXT_SYS_INFO_BIT_COMMIT_HASH + MBG_EXT_SYS_INFO_MSK_OS_NAME = ( 1UL << MBG_EXT_SYS_INFO_BIT_OS_NAME ) ///< See ::MBG_EXT_SYS_INFO_BIT_OS_NAME +}; + + +enum MBG_EXT_SYS_INFO_PROC_TYPES +{ + MBG_EXT_SYS_INFO_PROC_TYPE_NONE, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_A9, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_SAM3u, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_SAM3s, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_STM32F4, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_STM32F0, + MBG_EXT_SYS_INFO_PROC_TYPE_CORTEX_STM32F7, + N_MBG_EXT_SYS_INFO_PROC_TYPES +}; + +#define MBG_EXT_SYS_INFO_PROC_STRS \ +{ \ + "None", \ + "Cortex A9", \ + "Cortex SAM3u", \ + "Cortex SAM3s", \ + "Cortex STM32F4", \ + "Cortex STM32F0", \ + "Cortex STM32F7" \ +} + +enum MBG_EXT_SYS_INFO_FPGA_TYPES +{ + MBG_EXT_SYS_INFO_FPGA_TYPE_NONE, + MBG_EXT_SYS_INFO_FPGA_TYPE_CYCLONE5_SOC, ///< System on chip + MBG_EXT_SYS_INFO_FPGA_TYPE_CYCLONE5, ///< Stand alone FPGA + MBG_EXT_SYS_INFO_FPGA_TYPE_CYCLONE4GX15, + MBG_EXT_SYS_INFO_FPGA_TYPE_CYLCONE4CE22, + N_MBG_EXT_SYS_INFO_FPGA_TYPES +}; + +#define MBG_EXT_SYS_INFO_FPGA_STRS \ +{ \ + "None", \ + "Cyclone5 SoC", \ + "Cyclone5", \ + "Cyclone4GX15", \ + "Cyclone4CE22" \ +} + +enum MBG_EXT_SYS_INFO_CORE_MOD_TYPES +{ + MBG_EXT_SYS_INFO_CORE_MOD_TYPE_NONE, + MBG_EXT_SYS_INFO_CORE_MOD_TYPE_UBX_LEA_M8F, ///< u-blox GNSS module without Galileo support + MBG_EXT_SYS_INFO_CORE_MOD_TYPE_UBX_LEA_M8T, ///< u-blox GNSS module with Galileo support + N_MBG_EXT_SYS_INFO_CORE_MOD_TYPES +}; + +#define MBG_EXT_SYS_INFO_CORE_MOD_STRS \ +{ \ + "None", \ + "u-blox LEA-M8F", \ + "u-blox LEA-M8T" \ +} + +/* + * 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" \ +} + +/* + * OS target information are only relevant for updates. The unique combination + * of CPU and GEN defines a specific update for this kind of hardware (FPGA) and CPU + * model. This means all microSync single boards (MSSB) do have the same + * update file as CPU and hardware (FPGA) are always equal. + * Several variants (power, telecom, etc...) do effect the real board layout + * (connectors, etc..) but never the update file as long as CPU and GEN are + * equal. The variant member only is informational. + */ + +/// 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, + MBG_EXT_SYS_INFO_CPU_MSSB_USB_HOST, + N_MBG_EXT_SYS_INFO_CPUS +}; + +#define MBG_EXT_SYS_INFO_CPU_STRS \ +{ \ + "Unknown", \ + "HPS USB host", \ + "HPS USB device", \ + "microSync SB USB host" \ +} + +#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) + + +/** + * @defgroup group_os_target_codes OS target codes + * + * Status word, associated bit numbers and bit masks indicating + * whether certain data from the GPS satellites are + * available and valid. + * + * These bits defined are set in ::BVAR_STAT if the corresponding + * parameters are NOT valid and complete. + * + * @see ::MBG_EXT_SYS_INFO_CPUS + * @see ::MBG_OS_TARGET_CODE + * + * @{ */ + +/// - CPU 1 : HPS USB host +/// - Gen 1 : HPS100 +/// - Var 0 : Base (4 x LED, USB to serial, 2 x SMA, 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 (4 x LED, USB to serial, 2 x SMA, 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 (4 x LED, 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) + +/// - CPU 3 : microSync SB USB host +/// - Gen 1 : MSSB100 +/// - Var 0 : Base (10 MHz in, PPS in, 10 MHz sine out, 10 MHz out, +/// 4 x LED, RS232, USB to serial, USB, 4 x SFP, 2 x DFK PPO, +/// 2 x Optocoupler) +/// - Product(s) : microSyncHR, microSyncRX +#define MSSB_USB_HOST_G1_V0 __CPU_CODEC(MBG_EXT_SYS_INFO_CPU_MSSB_USB_HOST, 1, 0) + +/** @} defgroup group_os_target_codes */ + + + +/** + * @brief Meinberg OS release year offset. + * + * If ::MBG_EXT_SYS_INFO_MSK_OS_TYPE is set in ::MBG_EXT_SYS_INFO::supp_members + * then ::MBG_OS_YEAR_CONSTANT needs to be added to the major version code of ::MBG_EXT_SYS_INFO::sw_rev + * to get the meinbergOS release year (4 digits), and its minor version represents the release month (2 digits). + */ +#define MBG_OS_YEAR_CONSTANT 2000 + + +/** + * @brief Bit-coded CPU type information. + * + * - Bits 0..3: CPU Type + * - Bits 4..7: CPU generation + * - Bits 8..15: CPU variant (currently unused) + * + * @see @ref group_os_target_codes + */ +typedef uint16_t MBG_OS_TARGET_CODE; + + +typedef struct mbg_ext_sys_info_s +{ + uint32_t supp_members; ///< ::MBG_EXT_SYS_INFO_MSKS + + uint32_t sw_rev; + uint32_t hw_rev; + uint32_t os_rev; + uint32_t fpga_rev; + + uint16_t proc_type; ///< See ::MBG_EXT_SYS_INFO_PROC_TYPES + uint16_t fpga_type; ///< See ::MBG_EXT_SYS_INFO_FPGA_TYPES + uint16_t core_mod_type; ///< See ::MBG_EXT_SYS_INFO_CORE_MOD_TYPES + uint16_t 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. + uint8_t reserved_rev_3[3]; + + MBG_OS_TARGET_CODE os_target; ///< See @ref group_os_target_codes + + uint16_t reserved_rev_4; + uint32_t commit_hash; + char os_name[16]; + +} MBG_EXT_SYS_INFO; + +#define _mbg_swab_ext_sys_info( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab32( &(_p)->sw_rev ); \ + _mbg_swab32( &(_p)->hw_rev ); \ + _mbg_swab32( &(_p)->os_rev ); \ + _mbg_swab32( &(_p)->fpga_rev ); \ + _mbg_swab16( &(_p)->proc_type ); \ + _mbg_swab16( &(_p)->fpga_type ); \ + _mbg_swab16( &(_p)->core_mod_type ); \ + _mbg_swab16( &(_p)->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 ) + + +#define _mbg_encode_revision( _major, _minor, _patch ) \ + ( ( (_major) << 24) | ( (_minor) << 16 ) | (_patch) ) + + +#define _mbg_decode_revision( _rev, _major, _minor, _patch ) \ +{ \ + (_major) = ( (_rev) >> 24 ) & 0xff; \ + (_minor) = ( (_rev) >> 16 ) & 0xff; \ + (_patch) = (_rev) & 0xffff; \ +} + + +#define MBG_REVISION_RC_DEVEL ((uint8_t)(-1)) +#define MBG_REVISION_RC_DEVEL_STR "devel" + + +/** + * @brief Bits used to define ::MBG_EXT_SYS_STATUS_MSKS + * + * @see ::MBG_EXT_SYS_STATUS_MSKS + */ +enum MBG_EXT_SYS_STATUS_BITS +{ + MBG_EXT_SYS_STATUS_BIT_UPTIME, + MBG_EXT_SYS_STATUS_BIT_FREE_RAM, + MBG_EXT_SYS_STATUS_BIT_LOAD, + MBG_EXT_SYS_STATUS_BIT_FLAGS, + N_MBG_EXT_SYS_STATUS_BITS +}; + +/** + * @brief Bit masks of supported status values in ::MBG_EXT_SYS_STATUS + * + * Used with ::MBG_EXT_SYS_STATUS::supp_members + * + * @see ::MBG_EXT_SYS_STATUS_BITS + */ +enum MBG_EXT_SYS_STATUS_MSKS +{ + MBG_EXT_SYS_STATUS_MSK_UPTIME = ( 1UL << MBG_EXT_SYS_STATUS_BIT_UPTIME ), ///< See ::MBG_EXT_SYS_STATUS_BIT_UPTIME + MBG_EXT_SYS_STATUS_MSK_FREE_RAM = ( 1UL << MBG_EXT_SYS_STATUS_BIT_FREE_RAM ), ///< See ::MBG_EXT_SYS_STATUS_BIT_FREE_RAM + MBG_EXT_SYS_STATUS_MSK_LOAD = ( 1UL << MBG_EXT_SYS_STATUS_BIT_LOAD ), ///< See ::MBG_EXT_SYS_STATUS_BIT_LOAD + MBG_EXT_SYS_STATUS_MSK_FLAGS = ( 1UL << MBG_EXT_SYS_STATUS_BIT_FLAGS ) ///< See ::MBG_EXT_SYS_STATUS_BIT_FLAGS +}; + +/** + * @brief Bits used to define ::MBG_EXT_SYS_STATUS_FLAGS_MSKS + * + * @see ::MBG_EXT_SYS_STATUS_FLAGS_MSKS + */ + +enum MBG_EXT_SYS_STATUS_FLAGS_BITS +{ + MBG_EXT_SYS_STATUS_FLAG_BIT_CONFIG_CHANGED, ///< Indicates if runtime config is different to startup config + N_MBG_EXT_SYS_STATUS_FLAGS_BITS +}; + +/** + * @brief Bit masks of supported status flags in ::MBG_EXT_SYS_STATUS + * + * Used with ::MBG_EXT_SYS_STATUS::supp_flags + * + * @see ::MBG_EXT_SYS_STATUS_FLAGS_BITS + */ + +enum MBG_EXT_SYS_STATUS_FLAGS_MSKS +{ + MBG_EXT_SYS_STATUS_FLAG_MSK_CONFIG_CHANGED = ( 1UL << MBG_EXT_SYS_STATUS_FLAG_BIT_CONFIG_CHANGED ) ///< See ::MBG_EXT_SYS_STATUS_FLAG_BIT_CONFIG_CHANGED +}; + + +typedef struct mbg_ext_sys_status_s +{ + uint32_t supp_members; ///< Indicates, which members of this struct are supported, see ::MBG_EXT_SYS_STATUS_MSKS + uint32_t uptime; ///< Seconds since boot + + uint32_t free_ram; ///< Free RAM in MB + + uint16_t supp_flags; ///< Indicates, which flags are supported see ::MBG_EXT_SYS_STATUS_FLAGS_MSKS + uint16_t flags; ///< See ::MBG_EXT_SYS_STATUS_FLAGS_MSKS + + uint16_t load_1m; ///< Multiplied by 100 since original value is a double + uint16_t load_5m; ///< Multiplied by 100 since original value is a double + uint16_t load_15m; ///< Multiplied by 100 since original value is a double + uint16_t reserved_2; + + uint32_t reserved_3[10]; + +} MBG_EXT_SYS_STATUS; + +#define _mbg_swab_ext_sys_status( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab32( &(_p)->uptime ); \ + _mbg_swab32( &(_p)->free_ram ); \ + _mbg_swab16( &(_p)->load_1m ); \ + _mbg_swab16( &(_p)->load_5m ); \ + _mbg_swab16( &(_p)->load_15m ); \ +} while ( 0 ) + + + +/** @} defgroup group_ext_sys_info */ + + +/** + * @defgroup group_license_limits License information + * + * @note This is probably obsolete. + * + * @{ */ + + +#define MBG_MAX_LICENSES 32 + + +/** + * @brief General license information to be read from a device + * + * Used to query from a device how many and which different license types + * are supported. If a special type is supported (licenses[MBG_LICENSE_BASE_TYPES] > 0), its + * license specific information can be queried from 0..licenses[MBG_LICENSE_BASE_TYPES]-1 via + * its license specific [...]_IDX structures and TLV API command codes. + * See ::MBG_XFEATURE_TLV_API and ::MBG_TLV_FEAT_TYPES. + */ +typedef struct +{ + uint8_t licenses[MBG_MAX_LICENSES]; ///< To get the number of supported licenses + ///< of a specific type you need to access the array + ///< with the specififc license index defined at ::MBG_LICENSE_BASE_TYPES. +} MBG_LICENSE_LIMITS; + + +enum MBG_LICENSE_BASE_TYPES +{ + MBG_LICENSE_BASE_TYPE_PTPV2, + MBG_LICENSE_BASE_TYPE_NTP, + MBG_LICENSE_BASE_TYPE_PTPV1, + MBG_LICENSE_BASE_TYPE_TIME_MONITOR, + N_MBG_LICENSE_BASE_TYPES +}; + + +/** + * @brief Bits used to define ::MBG_LICENSE_BASE_MSKS + * + * @see ::MBG_LICENSE_BASE_MSKS + */ +enum MBG_LICENSE_BASE_FLAGS +{ + MBG_LICENSE_BASE_FLAG_SUPP_UPGRADE, ///< License supports upgrading / modifying + N_MBG_LICENSE_BASE_FLAGS +}; + + +/** + * @brief Bit masks of common supported base license flags + * + * Used with ::MBG_LICENSE_BASE::supp_flags + * + * @see ::MBG_LICENSE_BASE_FLAGS + */ +enum MBG_LICENSE_BASE_MSKS +{ + MBG_LICENSE_BASE_MSK_SUPP_UPGRADE = ( 1UL << MBG_LICENSE_BASE_FLAG_SUPP_UPGRADE ) ///< See ::MBG_LICENSE_BASE_FLAG_SUPP_UPGRADE +}; + + +/** + * @brief Common license information + * + * Should be part of each individual license type. + */ +typedef struct +{ + uint8_t type; ///< See ::MBG_LICENSE_BASE_TYPES + uint8_t reserved_1; ///< Reserved for future use, currently 0 + uint16_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t supp_flags; ///< See ::MBG_LICENSE_BASE_MSKS + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_BASE; + +#define _mbg_swab_license_base( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->supp_flags ); \ +} while ( 0 ) + + +/** + * @brief Bits used to define ::MBG_LICENSE_PTPV2_MEMBER_MSKS + * + * @see ::MBG_LICENSE_PTPV2_MEMBER_MSKS + */ +enum MBG_LICENSE_PTPV2_MEMBERS +{ + MBG_LICENSE_PTPV2_MEMBER_MAX_UCLIENTS, + MBG_LICENSE_PTPV2_MEMBER_MAX_MTRANS, + N_MBG_LICENSE_PTPV2_MEMBERS +}; + + +/** + * @brief Bit masks of PTPV2 license specific members + * + * Used with ::MBG_LICENSE_PTPV2::supp_members + * + * @see ::MBG_LICENSE_PTPV2_MEMBERS + */ +enum MBG_LICENSE_PTPV2_MEMBER_MSKS +{ + MBG_LICENSE_PTPV2_MEMBER_MSK_MAX_UCLIENTS = ( 1UL << MBG_LICENSE_PTPV2_MEMBER_MAX_UCLIENTS ), ///< See ::MBG_LICENSE_PTPV2_MEMBER_MAX_UCLIENTS + MBG_LICENSE_PTPV2_MEMBER_MSK_MAX_MTRANS = ( 1UL << MBG_LICENSE_PTPV2_MEMBER_MAX_MTRANS ) ///< See ::MBG_LICENSE_PTPV2_MEMBER_MAX_MTRANS +}; + + +/** + * @brief PTPV2 specific license information + * + */ +typedef struct +{ + MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE + uint32_t supp_members; ///< See ::MBG_LICENSE_PTPV2_MEMBER_MSKS + uint32_t reserved_1; ///< Reserved for future use, currently 0 + uint16_t max_uclients; ///< Maximal number of supported unicast clients. + uint16_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t max_mtrans; ///< Maximal number of supported multicast transactions per second. + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + uint32_t reserved_5; ///< Reserved for future use, currently 0 + uint32_t reserved_6; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_PTPV2; + +#define _mbg_swab_license_ptpv2( _p ) \ +do \ +{ \ + _mbg_swab_license_base( &(_p)->base ); \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab16( &(_p)->max_uclients ); \ + _mbg_swab32( &(_p)->max_mtrans ); \ +} while ( 0 ) + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_LICENSE_PTPV2 license; + +} MBG_LICENSE_PTPV2_IDX; + +#define _mbg_swab_license_ptpv2_idx( _p ) \ +do \ +{ \ + _mbg_swab_license_ptpv2( &(_p)->license ); \ + _mbg_swab32( &(_p)->idx ); \ +} while ( 0 ) + + +/** + * @brief Bits used to define ::MBG_LICENSE_NTP_MEMBER_MSKS + * + * @see ::MBG_LICENSE_NTP_MEMBER_MSKS + */ +enum MBG_LICENSE_NTP_MEMBERS +{ + MBG_LICENSE_NTP_MEMBER_MAX_RPS, + N_MBG_LICENSE_NTP_MEMBERS +}; + + +/** + * @brief Bit masks of NTP license specific members + * + * Used with ::MBG_LICENSE_NTP::supp_members + * + * @see ::MBG_LICENSE_PTPV2_MEMBERS + */ +enum MBG_LICENSE_NTP_MEMBER_MSKS +{ + MBG_LICENSE_NTP_MEMBER_MSK_MAX_RPS = ( 1UL << MBG_LICENSE_NTP_MEMBER_MAX_RPS ) ///< See ::MBG_LICENSE_NTP_MEMBER_MAX_RPS +}; + + +/** + * @brief NTP specific license information + */ +typedef struct +{ + MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE + uint32_t supp_members; ///< See ::MBG_LICENSE_NTP_MEMBER_MSKS + uint32_t max_rps; ///< Maximum number of supported NTP requests per second + uint32_t reserved_1; ///< Reserved for future use, currently 0 + uint32_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + uint32_t reserved_5; ///< Reserved for future use, currently 0 + uint32_t reserved_6; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_NTP; + +#define _mbg_swab_license_ntp( _p ) \ +do \ +{ \ + _mbg_swab_license_base( &(_p)->base ); \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab32( &(_p)->max_rps ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_LICENSE_NTP license; + +} MBG_LICENSE_NTP_IDX; + +#define _mbg_swab_license_ntp_idx( _p ) \ +do \ +{ \ + _mbg_swab_license_ntp( &(_p)->license ); \ + _mbg_swab32( &(_p)->idx ); \ +} while ( 0 ) + +/** + * @brief Bits used to define ::MBG_LICENSE_PTPV1_MEMBER_MSKS + * + * @see ::MBG_LICENSE_PTPV1_MEMBER_MSKS + */ +enum MBG_LICENSE_PTPV1_MEMBERS +{ + MBG_LICENSE_PTPV1_MEMBER_MAX_RPS, + N_MBG_LICENSE_PTPV1_MEMBERS +}; + + +/** + * @brief Bit masks of PTPV1 license specific members + * + * Used with ::MBG_LICENSE_PTPV1::supp_members + * + * @see ::MBG_LICENSE_PTPV2_MEMBERS + */ +enum MBG_LICENSE_PTPV1_MEMBER_MSKS +{ + MBG_LICENSE_PTPV1_MEMBER_MSK_MAX_RPS = ( 1UL << MBG_LICENSE_PTPV1_MEMBER_MAX_RPS ) ///< See ::MBG_LICENSE_PTPV1_MEMBER_MAX_RPS +}; + + +/** + * @brief NTP specific license information + */ +typedef struct +{ + MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE + uint32_t supp_members; ///< See ::MBG_LICENSE_PTPV1_MEMBER_MSKS + uint32_t max_rps; ///< Maximum number of supported PTPv1 delay requests per second + uint32_t reserved_1; ///< Reserved for future use, currently 0 + uint32_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + uint32_t reserved_5; ///< Reserved for future use, currently 0 + uint32_t reserved_6; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_PTPV1; + +#define _mbg_swab_license_ptpv1( _p ) \ +do \ +{ \ + _mbg_swab_license_base( &(_p)->base ); \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab32( &(_p)->max_rps ); \ +} while ( 0 ) + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_LICENSE_PTPV1 license; + +} MBG_LICENSE_PTPV1_IDX; + +#define _mbg_swab_license_ptpv1_idx( _p ) \ +do \ +{ \ + _mbg_swab_license_ptpv1( &(_p)->license ); \ + _mbg_swab32( &(_p)->idx ); \ +} while ( 0 ) + +/** + * @brief Bits used to define ::MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS + * + * @see ::MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS + */ +enum MBG_LICENSE_TIME_MONITOR_MEMBERS +{ + MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_PTPV2_CLIENTS, + MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_NTP_CLIENTS, + N_MBG_LICENSE_TIME_MONITOR_MEMBERS +}; + + +/** + * @brief Bit masks of Sync Monitor license specific members + * + * Used with ::MBG_LICENSE_TIME_MONITOR::supp_members + * + * @see ::MBG_LICENSE_TIME_MONITOR_MEMBERS + */ +enum MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS +{ + MBG_LICENSE_TIME_MONITOR_MEMBER_MSK_MAX_PTPV2_CLIENTS = ( 1UL << MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_PTPV2_CLIENTS ), ///< See ::MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_PTPV2_CLIENTS + MBG_LICENSE_TIME_MONITOR_MEMBER_MSK_MAX_NTP_CLIENTS = ( 1UL << MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_NTP_CLIENTS ) ///< See ::MBG_LICENSE_TIME_MONITOR_MEMBER_MAX_NTP_CLIENTS +}; + + +/** + * @brief Sync Monitor specific license information + * + */ +typedef struct +{ + MBG_LICENSE_BASE base; ///< See ::MBG_LICENSE_BASE + uint32_t supp_members; ///< See ::MBG_LICENSE_TIME_MONITOR_MEMBER_MSKS + uint32_t reserved_1; ///< Reserved for future use, currently 0 + uint16_t max_ptpv2_clients; ///< Maximum number of supported PTPv2 clients to be monitored + uint16_t max_ntp_clients; ///< Maximum number of supported NTP clients to be monitored + uint32_t reserved_2; ///< Reserved for future use, currently 0 + uint32_t reserved_3; ///< Reserved for future use, currently 0 + uint32_t reserved_4; ///< Reserved for future use, currently 0 + uint32_t reserved_5; ///< Reserved for future use, currently 0 + uint32_t reserved_6; ///< Reserved for future use, currently 0 + +} MBG_LICENSE_TIME_MONITOR; + +#define _mbg_swab_license_time_monitor( _p ) \ +do \ +{ \ + _mbg_swab_license_base( &(_p)->base ); \ + _mbg_swab32( &(_p)->supp_members ); \ + _mbg_swab16( &(_p)->max_ptpv2_clients ); \ + _mbg_swab16( &(_p)->max_ntp_clients ); \ +} while ( 0 ) + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_LICENSE_TIME_MONITOR license; + +} MBG_LICENSE_TIME_MONITOR_IDX; + +#define _mbg_swab_license_time_monitor_idx( _p ) \ +do \ +{ \ + _mbg_swab_license_time_monitor( &(_p)->license ); \ + _mbg_swab32( &(_p)->idx ); \ +} while ( 0 ) + +/** @} defgroup group_license_limits */ + + + +/** + * @defgroup group_clk_res_info Clock resolution info + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_CLK_RES_INFO is set in the extended device features. + * + * @{ */ + +/** + * @brief Clock resolution information + * + * @see @ref group_clk_res_info + */ +typedef struct +{ + uint32_t base_clk; ///< Base clock of the internal time base [MHz] + uint32_t num_clk_phase; ///< Number of multi-phase clock signals + uint32_t reserved_9; + uint32_t reserved_8; + uint32_t reserved_7; + uint32_t reserved_6; + uint32_t reserved_5; + uint32_t reserved_4; + uint32_t reserved_3; + uint32_t reserved_2; + uint32_t reserved_1; + uint32_t reserved_0; + +} MBG_CLK_RES_INFO; + +#define _mbg_swab_mbg_clk_res_info( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->base_clk ); \ + _mbg_swab32( &(_p)->num_clk_phase ); \ + _mbg_swab32( &(_p)->reserved_9 ); \ + _mbg_swab32( &(_p)->reserved_8 ); \ + _mbg_swab32( &(_p)->reserved_7 ); \ + _mbg_swab32( &(_p)->reserved_6 ); \ + _mbg_swab32( &(_p)->reserved_5 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_0 ); \ +} while ( 0 ) + +/** @} defgroup group_clk_res_info */ + + + +/** + * @brief Type of upcoming transaction sequence + * + * Used in combination with ::GPS_BEGIN_TRANSACTION and ::GPS_END_TRANSACTION + * to announce which type of transaction is going to be started. Thus the receiver + * can prepare for following actions. + */ +enum MBG_TRANSACTION_TYPES +{ + MBG_TRANSACTION_TYPE_NONE, + /* ### TODO FIXME + * Network transaction requires at least and as first command: + * - ::GPS_NET_GLB_CFG (::MBG_NET_GLB_CFG_INFO) + * Depending on ::MBG_NET_GLB_CFG_INFO::glb_settings and its num_[...] + * members there are a couple of index commands which should be handled in any order: + * - ::GPS_NET_DNS_SRVR (::MBG_IP_ADDR_IDX) + * - ::GPS_NET_DNS_SRCH_DOM (::MBG_NET_NAME_IDX) + * - ::GPS_NET_INTF_LINK_IDX (::MBG_NET_INTF_LINK_INFO_IDX) + * - ::GPS_NET_INTF_ADDR_IDX (::MBG_NET_INTF_ADDR_INFO_IDX) + * - ::GPS_NET_INTF_ROUTE_IDX (::MBG_NET_INTF_ROUTE_INFO_IDX) + */ + MBG_TRANSACTION_TYPE_NETWORK, + MBG_TRANSACTION_TYPE_PTP, + /* + * Commands in any order if supp. by ::MBG_SNMP_GLB_INFO::max_[...] + * and ::MBG_SNMP_GLB_INFO::supp_versions + * + * Should be used within ::MBG_TRANSACTION_TYPE_MONITORING but may also be + * used stand-alone. + * + * - ::GPS_SNMP_GLB_SETTINGS + * - ::GPS_SNMP_V12_SETTINGS_IDX + * - ::GPS_SNMP_V12_TRAP_SETTINGS_IDX + * - ::GPS_SNMP_V3_SETTINGS_IDX + * - ::GPS_SNMP_V3_TRAP_SETTINGS_IDX + */ + MBG_TRANSACTION_TYPE_MONITORING_SNMP, + /* + * NTP transaction requires at least and as first command: + * ::GPS_NTP_GLB_CFG + * Commands in any order if supp. by ::MBG_NTP_GLB_INFO + * and ::MBG_SNMP_GLB_INFO::supp_versions + * + * - ::GPS_NTP_REFCLK_CFG + * - ::GPS_NTP_MISC_LIMITS + * - ::GPS_NTP_MISC_ORPHAN_MODE + * - ::GPS_NTP_SYMM_KEY_LIMITS + * - ::GPS_NTP_SYMM_KEY_CFG + * - ::GPS_NTP_TRUSTED_KEY_CFG + * - ::GPS_NTP_CLNT_MODE_CFG + * - ::GPS_NTP_SRV_MODE_CFG + * - ::GPS_NTP_PEER_SETTINGS_IDX + * - ::GPS_NTP_SYS_STATE + * - ::GPS_NTP_PEER_STATE_IDX + */ + MBG_TRANSACTION_TYPE_NTP, + /* + * IO Port transaction used to read or write ALL_IO_PORT_INFO + * Commands related to this transaction: + * + * - ::GPS_IO_PORT_LIMITS + * - ::GPS_IO_PORT_SETTINGS_IDX + * - ::GPS_IO_PORT_INFO_IDX + * - ::GPS_IO_PORT_TYPE_INFO_IDX + * - ::GPS_IO_PORT_STATUS_IDX + */ + MBG_TRANSACTION_TYPE_IO_PORT, + /* + * Commands in any order if ::MBG_XFEATURE_MONITORING is set in + * ::MBG_XFEATURE_BUFFER. + * + * Transactions ::MBG_TRANSACTION_TYPE_MONITORING_SNMP and + * ::MBG_TRANSACTION_TYPE_EVENTS may also be opened within + * ::MBG_TRANSACTION_TYPE_MONITORING transaction. + * + * - ::GPS_MONITORING_LIMITS + * - ::GPS_MONITORING_STATUS + */ + MBG_TRANSACTION_TYPE_MONITORING, + /* + * Commands in any order if ::MBG_XFEATURE_MONITORING is set in + * ::MBG_XFEATURE_BUFFER. + * + * Should be used within ::MBG_TRANSACTION_TYPE_MONITORING but may also be + * used stand-alone. + * + * - ::GPS_EVENT_IDX + * - ::GPS_EVENT_STAT_IDX + */ + MBG_TRANSACTION_TYPE_EVENTS, + + /* + * 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, + + /* + * PTP next gen transaction is supported, + * if ::MBG_XFEATURE_PTP_NG is set in ::MBG_XFEATURE_BUFFER and + * (if used in a save function) requires at least and as first command: + * ::GPS_PTP_NG_GLB_INFO + * + * Other commands in any order + * + * - ::GPS_PTP_NG_GLB_INFO + * - ::GPS_PTP_NG_TSTAMPER_INFO_IDX + * - ::GPS_PTP_NG_INSTC_INFO_IDX + * - ::GPS_PTP_NG_INSTC_STATUS_IDX + * - ::GPS_PTP_NG_UC_MASTER_INFO_IDX + * - ::GPS_PTP_NG_UC_SLAVE_STATUS_IDX + */ + MBG_TRANSACTION_TYPE_PTP_NG, + + /* + * Sys ref API is supported, if ::MBG_XFEATURE_SYS_REF is set + * in ::MBG_XFEATURE_BUFFER and supports the following commands: + * + * - ::GPS_SYS_REF_LIMITS + * - ::GPS_SYS_REF_GLB_STATUS + * - ::GPS_SYS_REF_SRC_INFO_IDX + * - ::GPS_SYS_REF_SRC_STATUS_IDX + */ + MBG_TRANSACTION_TYPE_SYS_REF, + + MAX_MBG_TRANSACTION_TYPES +}; + + +#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 ) + + +/** + * @defgroup group_io_ports IO Port API + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_IO_PORTS is set in the extended device features. + * + * @{ */ + +/** + * @brief IO Port types + * + * Used with ::MBG_IO_PORT_TYPE_INFO::port_type and ::MBG_IO_PORT_SETTINGS::port_type + */ +enum MBG_IO_PORT_TYPES +{ + MBG_IO_PORT_TYPE_PPS, + MBG_IO_PORT_TYPE_10MHz, + MBG_IO_PORT_TYPE_2048KHz, + MBG_IO_PORT_TYPE_GPIO, + MBG_IO_PORT_TYPE_ETHERNET, + MBG_IO_PORT_TYPE_TERMINAL, + MBG_IO_PORT_TYPE_MULTI, + MBG_IO_PORT_TYPE_POUT, + 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, + MBG_IO_PORT_TYPE_SPST_RELAY, ///< Single-Pole Single-Throw Relay, two terminals which can be connected or disconnected + MBG_IO_PORT_TYPE_SPDT_RELAY, ///< Single-Pole Double-Throw Relay, common terminal connects to either of two others, never connecting to both at the same time + MBG_IO_PORT_TYPE_SYNTHESIZER, + N_MBG_IO_PORT_TYPES +}; + +/** + * @brief Port type to be used for an undefined/unassigned port + * + * Only use this for ::MBG_IO_PORT_SETTINGS::port_type + * if ::MBG_IO_PORT_SETTINGS::op_mode is ::MBG_IO_PORT_OP_MODE_NONE + */ +#define MBG_IO_PORT_TYPE_NONE ( (uint16_t) -1 ) + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_TYPES + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_TYPES entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_TYPES. + * + * @see ::MBG_IO_PORT_TYPES + */ +#define MBG_IO_PORT_TYPE_STRS \ +{ \ + "PPS", \ + "10 MHz", \ + "2048 KHz", \ + "GPIO", \ + "Ethernet", \ + "Terminal", \ + "Multi", \ + "Prog. Output", \ + "Switch", \ + "Timecode", \ + "Light", \ + "Antenna", \ + "UART", \ + "DCF77", \ + "Power", \ + "SPST Relay", \ + "SPDT Relay", \ + "Synthesizer" \ +} + + +/** + * @brief Port directions (input or output) + * + * @see ::MBG_IO_PORT_DIR_MSKS + */ +enum MBG_IO_PORT_DIRS +{ + MBG_IO_PORT_DIR_NONE = -1, ///< Only use this for ::MBG_IO_PORT_SETTINGS::direction if ::MBG_IO_PORT_SETTINGS::op_mode is ::MBG_IO_PORT_OP_MODE_NONE + MBG_IO_PORT_DIR_IN, ///< Port is input like PPS In + MBG_IO_PORT_DIR_OUT, ///< Port is output like 10Mhz + MBG_IO_PORT_DIR_IN_OUT, ///< Port can be in- & output in parallel like network port + N_MBG_IO_PORT_DIRS +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_DIRS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_DIRS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_DIRS. + * + * @see ::MBG_IO_PORT_DIRS + */ +#define MBG_IO_PORT_DIR_STRS \ +{ \ + "Input", \ + "Output", \ + "Input/Output" \ +} + + +/** + * @brief Bit masks of Meinberg I/O port directions + * + * Used with ::MBG_IO_PORT_TYPE_INFO::supp_dirs + * + * @see ::MBG_IO_PORT_DIRS + */ +enum MBG_IO_PORT_DIR_MSKS +{ + MBG_IO_PORT_MSK_DIR_IN = ( 1UL << MBG_IO_PORT_DIR_IN ), ///< See ::MBG_IO_PORT_DIR_IN + MBG_IO_PORT_MSK_DIR_OUT = ( 1UL << MBG_IO_PORT_DIR_OUT ), ///< See ::MBG_IO_PORT_DIR_OUT + MBG_IO_PORT_MSK_DIR_IN_OUT = ( 1UL << MBG_IO_PORT_DIR_IN_OUT ) ///< See ::MBG_IO_PORT_DIR_IN_OUT +}; + + +/** + * @brief Port type sources + * + * Configurable sources for an I/O port type + * + * @see ::MBG_IO_PORT_SRC_MSKS + */ +enum MBG_IO_PORT_SRCS +{ + MBG_IO_PORT_SRC_NONE = -1, ///< Only use this for ::MBG_IO_PORT_SETTINGS::source if ::MBG_IO_PORT_SETTINGS::op_mode is ::MBG_IO_PORT_OP_MODE_NONE + MBG_IO_PORT_SRC_STATIC, ///< Static, not configurable + MBG_IO_PORT_SRC_LOCAL, ///< Locally generated, e.g. on (carrier) board + MBG_IO_PORT_SRC_ASSOC_CLOCK, ///< Fixed (wired) clock from back plane (e.g. refclock 1 in M500 IMS) + MBG_IO_PORT_SRC_ACTIVE_CLOCK, ///< Switched clock from back plane (e.g. selected by RSC) + MBG_IO_PORT_SRC_CLK1, ///< Clock 1 fixed (CPU board only) + MBG_IO_PORT_SRC_CLK2, ///< Clock 2 fixed (CPU board only) + MBG_IO_PORT_SRC_ARC, ///< Any rate converter + MBG_IO_PORT_SRC_OSC, ///< Oscillator + MBG_IO_PORT_SRC_SYNCE, ///< SyncE + 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 +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_SRCS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_SRCS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_SRCS. + * + * @see ::MBG_IO_PORT_SRCS + */ +#define MBG_IO_PORT_SRC_STRS \ +{ \ + "Static", \ + "Locally generated", \ + "Associated clock", \ + "Active clock", \ + "Clock 1 fixed", \ + "Clock 2 fixed", \ + "Any rate converter", \ + "Oscillator", \ + "SyncE", \ + "Switch card", \ + "Configurable", \ + "External" \ +} + + +/** + * @brief Bit masks of Meinberg I/O port attitudes + * + * Used with ::MBG_IO_PORT_TYPE_INFO::supp_srcs + * + * @see ::MBG_IO_PORT_SRCS + */ +enum MBG_IO_PORT_SRC_MSKS +{ + MBG_IO_PORT_SRC_MSK_STATIC = (1UL << MBG_IO_PORT_SRC_STATIC), ///< See ::MBG_IO_PORT_SRC_STATIC + MBG_IO_PORT_SRC_MSK_LOCAL = (1UL << MBG_IO_PORT_SRC_LOCAL), ///< See ::MBG_IO_PORT_SRC_LOCAL + MBG_IO_PORT_SRC_MSK_ASSOC_CLOCK = (1UL << MBG_IO_PORT_SRC_ASSOC_CLOCK), ///< See ::MBG_IO_PORT_SRC_ASSOC_CLOCK + MBG_IO_PORT_SRC_MSK_ACTIVE_CLOCK = (1UL << MBG_IO_PORT_SRC_ACTIVE_CLOCK), ///< See ::MBG_IO_PORT_SRC_ACTIVE_CLOCK + MBG_IO_PORT_SRC_MSK_CLK1 = (1UL << MBG_IO_PORT_SRC_CLK1), ///< See ::MBG_IO_PORT_SRC_CLK1 + MBG_IO_PORT_SRC_MSK_CLK2 = (1UL << MBG_IO_PORT_SRC_CLK2), ///< See ::MBG_IO_PORT_SRC_CLK2 + MBG_IO_PORT_SRC_MSK_ARC = (1UL << MBG_IO_PORT_SRC_ARC), ///< See ::MBG_IO_PORT_SRC_ARC + MBG_IO_PORT_SRC_MSK_OSC = (1UL << MBG_IO_PORT_SRC_OSC), ///< See ::MBG_IO_PORT_SRC_OSC + MBG_IO_PORT_SRC_MSK_SYNCE = (1UL << MBG_IO_PORT_SRC_SYNCE), ///< See ::MBG_IO_PORT_SRC_SYNCE + 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 +}; + + +/** + * @brief Port connector types + * + * Used with ::MBG_IO_PORT_INFO::conn_type + * + */ +enum MBG_IO_PORT_CONN_TYPES +{ + MBG_IO_PORT_CONN_TYPE_SMA, + MBG_IO_PORT_CONN_TYPE_BNC, + MBG_IO_PORT_CONN_TYPE_DSUB25, + MBG_IO_PORT_CONN_TYPE_RJ45, + MBG_IO_PORT_CONN_TYPE_SFP, + MBG_IO_PORT_CONN_TYPE_USB_MICRO_B, + MBG_IO_PORT_CONN_TYPE_USB_A, + MBG_IO_PORT_CONN_TYPE_USB_B, + MBG_IO_PORT_CONN_TYPE_SMA_ANT, + MBG_IO_PORT_CONN_TYPE_RJ45_ETH, + MBG_IO_PORT_CONN_TYPE_2_PIN_DFK, + MBG_IO_PORT_CONN_TYPE_3_PIN_DFK, + MBG_IO_PORT_CONN_TYPE_16_PIN_DFK, + MBG_IO_PORT_CONN_TYPE_BNC_ISO, + MBG_IO_PORT_CONN_TYPE_DSUB9, + MBG_IO_PORT_CONN_TYPE_FIBRE_ST, + MBG_IO_PORT_CONN_TYPE_XHE_SPI, + MBG_IO_PORT_CONN_TYPE_LED_BUTTON, + MBG_IO_PORT_CONN_TYPE_QUAD_LED, + MBG_IO_PORT_CONN_TYPE_5_PIN_DFK, + MBG_IO_PORT_CONN_TYPE_SINGLE_LED, + 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, \ + 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, + * so the number of strings must correspond to ::N_MBG_IO_PORT_CONN_TYPES. + * + * @see ::MBG_IO_PORT_CONN_TYPES + */ +#define MBG_IO_PORT_CONN_TYPE_STRS \ +{ \ + "SMA", \ + "BNC", \ + "D-Sub 25", \ + "RJ45", \ + "SFP", \ + "USB Micro B", \ + "USB A", \ + "USB B", \ + "SMA Antenna", \ + "RJ45 Ethernet", \ + "DFK 2-Pin", \ + "DFK 3-Pin", \ + "DFK 16-Pin", \ + "BNC isolated", \ + "D-Sub 9", \ + "Fibre ST", \ + "XHE SPI", \ + "LED Button", \ + "Quad LED", \ + "DFK 5-Pin", \ + "Single LED" \ +} + + +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 Enumeration of known signal shapes/levels + * + * Used to specify the signal shape/level of an I/O port. + * + * @see ::MBG_IO_PORT_SHAPE_LEVEL_STRS + */ +enum MBG_IO_PORT_SHAPE_LEVELS +{ + 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 String initializers for I/O port shapes/levels + * + * @see ::MBG_IO_PORT_SHAPE_LEVELS + */ +#define MBG_IO_PORT_SHAPE_LEVEL_STRS \ +{ \ + "None", \ + "Sine wave", \ + "Rectangle Pulse" \ +} + + +/** + * @brief IO Port Limits + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef struct +{ + uint8_t num_ports; + uint8_t 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)->flags ); \ +} while ( 0 ) + + + +/** + * @brief Port Operation Bits + * + * Used with ::MBG_IO_PORT_SETTINGS::op_mode + * + * For now, there is a per port operation mode setting which + * is quite equal to ::ENABLE_FLAGS. + * + * @see ::MBG_IO_PORT_OP_MODE_MSKS + */ +enum MBG_IO_PORT_OP_MODE_BITS +{ + MBG_IO_PORT_OP_MODE_NONE = -1, ///< Current mode cannot be determined + MBG_IO_PORT_OP_MODE_DISABLED, ///< Disabled port + MBG_IO_PORT_OP_MODE_ALWAYS, ///< Always enable port + MBG_IO_PORT_OP_MODE_IF_SYNC_ONLY, ///< Enable port if sync only + MBG_IO_PORT_OP_MODE_AFTER_SYNC, ///< Always enable port after being sync once + 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 +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_OP_MODE_BITS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_OP_MODE_BITS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_OP_MODE_BITS. + * + * @see ::MBG_IO_PORT_OP_MODE_BITS + */ +#define MBG_IO_PORT_OP_MODE_STRS \ +{ \ + "Disabled", \ + "Always enabled", \ + "If sync only", \ + "Always after sync", \ + "Enabled", \ + "Passed through" \ +} + + + +/** + * @brief Masks for ::MBG_IO_PORT_OP_MODE_BITS + * + * Used with ::MBG_IO_PORT_INFO::supp_op_modes + * + * @see ::MBG_IO_PORT_OP_MODE_BITS + */ +enum MBG_IO_PORT_OP_MODE_MSKS +{ + MBG_IO_PORT_OP_MODE_MSK_DISABLED = (1UL << MBG_IO_PORT_OP_MODE_DISABLED), ///< See ::MBG_IO_PORT_OP_MODE_DISABLED + MBG_IO_PORT_OP_MODE_MSK_ALWAYS = (1UL << MBG_IO_PORT_OP_MODE_ALWAYS), ///< See ::MBG_IO_PORT_OP_MODE_ALWAYS + MBG_IO_PORT_OP_MODE_MSK_IF_SYNC_ONLY = (1UL << MBG_IO_PORT_OP_MODE_IF_SYNC_ONLY), ///< See ::MBG_IO_PORT_OP_MODE_IF_SYNC_ONLY + MBG_IO_PORT_OP_MODE_MSK_AFTER_SYNC = (1UL << MBG_IO_PORT_OP_MODE_AFTER_SYNC), ///< See ::MBG_IO_PORT_OP_MODE_AFTER_SYNC + 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 +}; + + +/** + * @brief Physical or logical group role bits + * + * Used with ::MBG_IO_PORT_STATUS::phys_grp_role, ::MBG_IO_PORT_STATUS::log_grp_role + * + * @see ::MBG_IO_PORT_GRP_ROLE_MSKS + */ +enum MBG_IO_PORT_GRP_ROLE_BITS +{ + MBG_IO_PORT_GRP_ROLE_NONE, ///< No group role, only possible if port is not assigned to any group + MBG_IO_PORT_GRP_ROLE_MASTER, ///< Master port in group, i.e. configurable port of LIU + MBG_IO_PORT_GRP_ROLE_SLAVE, ///< Slave port in group, i.e. non-configurable port of LIU + MBG_IO_PORT_GRP_ROLE_PASSIVE, ///< Passive port in group, i.e. passive port of network group (i.e. SFP or RJ45) + N_MBG_IO_PORT_GRP_ROLE_BITS +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_GRP_ROLE_BITS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_GRP_ROLE_BITS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_GRP_ROLE_BITS. + * + * @see ::MBG_IO_PORT_GRP_ROLE_BITS + */ +#define MBG_IO_PORT_GRP_ROLE_STRS \ +{ \ + "None", \ + "Master", \ + "Slave", \ + "Passive" \ +} + + +/** + * @brief Masks for ::MBG_IO_PORT_GRP_ROLE_BITS + * + * Used with ::MBG_IO_PORT_INFO::supp_phys_grp_roles + * + * @see ::MBG_IO_PORT_GRP_ROLE_BITS + */ +enum MBG_IO_PORT_GRP_ROLE_MSKS +{ + MBG_IO_PORT_GRP_ROLE_MSK_NONE = (1UL << MBG_IO_PORT_GRP_ROLE_NONE), ///< See ::MBG_IO_PORT_GRP_ROLE_NONE + MBG_IO_PORT_GRP_ROLE_MSK_MASTER = (1UL << MBG_IO_PORT_GRP_ROLE_MASTER), ///< See ::MBG_IO_PORT_GRP_ROLE_MASTER + MBG_IO_PORT_GRP_ROLE_MSK_SLAVE = (1UL << MBG_IO_PORT_GRP_ROLE_SLAVE), ///< See ::MBG_IO_PORT_GRP_ROLE_SLAVE + MBG_IO_PORT_GRP_ROLE_MSK_PASSIVE = (1UL << MBG_IO_PORT_GRP_ROLE_PASSIVE) ///< See ::MBG_IO_PORT_GRP_ROLE_PASSIVE +}; + + +/** + * @brief Supported members in ::MBG_IO_PORT_ANT_INFO and ::MBG_IO_PORT_ANT_SETTINGS + * + * Used with ::MBG_IO_PORT_ANT_INFO::supp_members + * + */ +enum MBG_IO_PORT_ANT_MEMBERS +{ + MBG_IO_PORT_ANT_MEMBER_GNSS, ///< Supports ::MBG_IO_PORT_ANT_INFO::gnss_info + ///< and ::MBG_IO_PORT_ANT_SETTINGS::gnss_settings. + MBG_IO_PORT_ANT_MEMBER_CAB_LEN, ///< Supports ::MBG_IO_PORT_ANT_SETTINGS::ant_cab_len. + MBG_IO_PORT_ANT_MEMBER_IGN_LOCK, ///< Supports ::MBG_IO_PORT_ANT_SETTINGS::ignore_lock. + MBG_IO_PORT_ANT_MEMBER_TR_DIST, ///< Supports ::MBG_IO_PORT_ANT_SETTINGS::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 ) + + +typedef struct +{ + IRIG_INFO irig_info; + +} MBG_IO_PORT_TIMECODE_INFO; + +#define _mbg_swab_io_port_timecode_info( _p ) \ +do \ +{ \ + _mbg_swab_irig_info( &(_p)->irig_info ); \ +} while ( 0 ) + +typedef struct +{ + IRIG_SETTINGS irig_settings; + MBG_REF_OFFS ref_offs; ///< Fix %UTC offset of incoming IRIG codde, only for inputs. + +} MBG_IO_PORT_TIMECODE_SETTINGS; + +#define _mbg_swab_io_port_timecode_settings( _p ) \ +do \ +{ \ + _mbg_swab_irig_settings( &(_p)->irig_settings ); \ + _mbg_swab_mbg_ref_offs( &(_p)->ref_offs ); \ +} while ( 0 ) + + +/** + * @brief IO Port Settings Union + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef union +{ + MBG_GPIO_SETTINGS gpio_settings; + POUT_SETTINGS pout_settings; + MBG_IO_PORT_TIMECODE_SETTINGS timecode_settings; + MBG_IO_PORT_ANT_SETTINGS ant_settings; + PORT_SETTINGS uart_settings; + SYNTH synth_settings; + +} MBG_IO_PORT_SETTINGS_U; + +#define _mbg_swab_io_port_settings_u( _type, _p, _recv ) \ +do \ +{ \ + switch ( (_type) ) \ + { \ + case MBG_IO_PORT_TYPE_GPIO: \ + _mbg_swab_mbg_gpio_settings( &(_p)->gpio_settings, (_recv) ); \ + break; \ + \ + case MBG_IO_PORT_TYPE_POUT: \ + if ( _recv ) \ + _mbg_swab_pout_settings_on_get( &(_p)->pout_settings ); \ + else _mbg_swab_pout_settings_on_set( &(_p)->pout_settings ); \ + break; \ + \ + case MBG_IO_PORT_TYPE_TIMECODE: \ + _mbg_swab_io_port_timecode_settings( &(_p)->timecode_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; \ + \ + case MBG_IO_PORT_TYPE_SYNTHESIZER: \ + _mbg_swab_synth( &(_p)->synth_settings ); \ + break; \ + \ + default: break; \ + } \ +} while ( 0 ) + + +#define MBG_IO_PORT_SETTINGS_MIN_SIZE 32 + + +/** + * @brief IO Port Settings + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef struct +{ + uint16_t port_type; ///< ::MBG_IO_PORT_TYPES + uint8_t direction; ///< ::MBG_IO_PORT_DIRS + uint8_t source; ///< ::MBG_IO_PORT_SRCS + uint8_t op_mode; ///< ::MBG_IO_PORT_OP_MODE_BITS + uint8_t 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 + + /* + * Struct members above represent minimum amount of data to be sent. + * See ::MBG_IO_PORT_SETTINGS_MIN_SIZE + */ + + MBG_IO_PORT_SETTINGS_U data; ///< Data union for settings' type + +} MBG_IO_PORT_SETTINGS; + +#define _mbg_swab_io_port_settings( _p, _recv ) \ +do \ +{ \ + uint16_t t = (_p)->port_type; \ + if ( (_recv) ) \ + _mbg_swab16( &t ); \ + _mbg_swab16( &(_p)->port_type ); \ + _mbg_swab_io_port_settings_u( t, &(_p)->data, (_recv) ); \ +} while ( 0 ) + + + + +/** + * @brief IO Port Settings Index + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + * + * Indexes from 0..::MBG_IO_PORT_LIMITS::num_ports - 1 are used + * to set ::MBG_IO_PORT_SETTINGS wrapped in ::MBG_IO_PORT_SETTINGS_IDX. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_IO_PORT_SETTINGS settings; + +} MBG_IO_PORT_SETTINGS_IDX; + +#define _mbg_swab_io_port_settings_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_io_port_settings( &(_p)->settings, (_recv) ); \ +} while ( 0 ) + + +#define MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE (MBG_IO_PORT_SETTINGS_MIN_SIZE + sizeof( uint32_t )) + + +#define MBG_IO_PORT_SETTINGS_IDX_SIZES \ +{ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_PPS */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_10MHz */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_2048KHz */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( MBG_GPIO_SETTINGS ), /* MBG_IO_PORT_TYPE_GPIO */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_ETHERNET */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_TERMINAL */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_MULTI */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( POUT_SETTINGS ), /* MBG_IO_PORT_TYPE_POUT */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SWITCH */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( MBG_IO_PORT_TIMECODE_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 */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SPST_RELAY */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SPDT_RELAY */ \ + MBG_IO_PORT_SETTINGS_IDX_MIN_SIZE + sizeof( SYNTH ) /* MBG_IO_PORT_TYPE_SYNTHESIZER */ \ +} + + +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 + MBG_IO_PORT_INFO_BIT_PASSED_THROUGH_CFG_NOT_SUPP ///< Indicates, that the output signal of this port (defined in (::MBG_IO_PORT_SETTINGS::data) + ///< can not be configured, if ::MBG_IO_PORT_SETTINGS::op_mode is set to ::MBG_IO_PORT_OP_MODE_PASSTHROUGH + +}; + + +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 + MBG_IO_PORT_INFO_MASK_PASSED_THROUGH_CFG_NOT_SUPP = ( 1UL << MBG_IO_PORT_INFO_BIT_PASSED_THROUGH_CFG_NOT_SUPP ) ///< See ::MBG_IO_PORT_INFO_BIT_PASSED_THROUGH_CFG_NOT_SUPP + +}; + + +#define MBG_NO_PHYS_GROUP 0xFF +#define MBG_NO_LOG_GROUP 0xFF +#define MBG_IO_PORT_STR_SIZE 16 + +/** + * @brief IO Port Info + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef struct +{ + uint8_t num_types; ///< See ::MBG_IO_PORT_TYPE_INFO + uint8_t conn_type; ///< See ::MBG_IO_PORT_CONN_TYPES + uint8_t 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 #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; + +#define _mbg_port_has_phys_group( _p ) ( ( _p )->phys_grp != MBG_NO_PHYS_GROUP ) + +#define _mbg_swab_io_port_info( _p, _recv ) \ +do \ +{ \ + _mbg_swab16( &(_p)->supp_op_modes ); \ + _mbg_swab16( &(_p)->supp_phys_grp_roles ); \ + _mbg_swab32( &(_p)->pols ); \ + _mbg_swab32( &(_p)->flags ); \ + _mbg_swab_io_port_settings( &(_p)->settings, (_recv) ); \ +} while ( 0 ) + + + +#define MBG_IO_PORT_INFO_MIN_SIZE ( 60 + MBG_IO_PORT_SETTINGS_MIN_SIZE ) + + +/** + * @brief IO Port Info Index + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + * + * Indexes from 0..::MBG_IO_PORT_LIMITS::num_ports - 1 are used + * to query ::MBG_IO_PORT_INFO wrapped in ::MBG_IO_PORT_INFO_IDX. + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_IO_PORT_INFO info; + +} MBG_IO_PORT_INFO_IDX; + +#define _mbg_swab_io_port_info_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_io_port_info( &(_p)->info, (_recv) ); \ +} while ( 0 ) + + + +#define MBG_IO_PORT_INFO_IDX_MIN_SIZE (MBG_IO_PORT_INFO_MIN_SIZE + sizeof( uint32_t )) + + +#define MBG_IO_PORT_INFO_IDX_SIZES \ +{ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_PPS */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_10MHz */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_2048KHz */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( MBG_GPIO_SETTINGS ), /* MBG_IO_PORT_TYPE_GPIO */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_ETHERNET */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_TERMINAL */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_MULTI */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( POUT_SETTINGS ), /* MBG_IO_PORT_TYPE_POUT */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SWITCH */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( MBG_IO_PORT_TIMECODE_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 */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SPST_RELAY */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SPDT_RELAY */ \ + MBG_IO_PORT_INFO_IDX_MIN_SIZE + sizeof( SYNTH ) /* MBG_IO_PORT_TYPE_SYNTHESIZER */ \ +} + + +/** + * @brief IO Port Type Info Union + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef union +{ + MBG_GPIO_LIMITS gpio_limits; + POUT_INFO pout_info; + MBG_IO_PORT_TIMECODE_INFO timecode_info; + PORT_INFO uart_info; + MBG_IO_PORT_ANT_INFO ant_info; + +} MBG_IO_PORT_TYPE_INFO_U; + +#define _mbg_swab_io_port_type_info_u( _type, _p, _recv ) \ +do \ +{ \ + switch ( (_type) ) \ + { \ + case MBG_IO_PORT_TYPE_GPIO: \ + _mbg_swab_mbg_gpio_limits( &(_p)->gpio_limits, (_recv) ); \ + break; \ + \ + case MBG_IO_PORT_TYPE_POUT: \ + _mbg_swab_pout_info_on_get( &(_p)->pout_info ); \ + break; \ + \ + case MBG_IO_PORT_TYPE_TIMECODE: \ + _mbg_swab_io_port_timecode_info( &(_p)->timecode_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 ) + + + +#define MBG_IO_PORT_TYPE_INFO_MIN_SIZE 32 + + +/** + * @brief IO Port Type Info + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_INFO_IDX + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + */ +typedef struct +{ + uint16_t port_type; ///< See ::MBG_IO_PORT_TYPES + uint16_t reserved_1; ///< Future use and padding, currently 0 + uint8_t supp_dirs; ///< See ::MBG_IO_PORT_DIR_MSKS + uint8_t pt_idx; ///< Index for this specific port type (e.g. 0 for PPO0, 1 for PPO1) + ///< especially interesting for passed through ports + 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 + + /* + * Struct members above represent minimum amount of data to be sent. + * See ::MBG_IO_PORT_TYPE_INFO_MIN_SIZE + */ + + MBG_IO_PORT_TYPE_INFO_U data; ///< Port type specific data + +} MBG_IO_PORT_TYPE_INFO; + +#define _mbg_swab_io_port_type_info( _p, _recv ) \ +do \ +{ \ + uint16_t t = (_p)->port_type; \ + if ( (_recv) ) \ + _mbg_swab16( &t ); \ + _mbg_swab16( &(_p)->port_type ); \ + _mbg_swab_io_port_type_info_u( t, &(_p)->data, (_recv) ); \ + _mbg_swab32( &(_p)->supp_srcs ); \ +} while ( 0 ) + + +#define MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE (MBG_IO_PORT_TYPE_INFO_MIN_SIZE + 2 * sizeof( uint32_t )) + + +#define MBG_IO_PORT_TYPE_INFO_IDX_SIZES \ +{ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_PPS */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_10MHz */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_2048KHz */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( MBG_GPIO_LIMITS ), /* MBG_IO_PORT_TYPE_GPIO */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_ETHERNET */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_TERMINAL */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_MULTI */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( POUT_INFO ), /* MBG_IO_PORT_TYPE_POUT */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SWITCH */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE + sizeof( MBG_IO_PORT_TIMECODE_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 */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SPST_RELAY */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE, /* MBG_IO_PORT_TYPE_SPDT_RELAY */ \ + MBG_IO_PORT_TYPE_INFO_IDX_MIN_SIZE /* MBG_IO_PORT_TYPE_SYNTHESIZER */ \ +} + + +/** + * @brief IO Port Type Info Index + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_STATUS + * @see ::MBG_IO_PORT_STATUS_IDX + * + * Indexes from 0..::MBG_IO_PORT_INFO::num_types - 1 are used + * to query ::MBG_IO_PORT_TYPE_INFO wrapped in ::MBG_IO_PORT_TYPE_INFO_IDX. + * + */ +typedef struct +{ + uint32_t port_idx; + uint32_t port_type_idx; + MBG_IO_PORT_TYPE_INFO info; + +} MBG_IO_PORT_TYPE_INFO_IDX; + +#define _mbg_swab_io_port_type_info_idx( _p, _recv ) \ +do \ +{ \ + _mbg_swab32( &(_p)->port_idx ); \ + _mbg_swab32( &(_p)->port_type_idx ); \ + _mbg_swab_io_port_type_info( &(_p)->info, (_recv) ); \ +} while ( 0 ) + + + +#define MAX_IO_PORT_STATUS_BITS 64 + + +/** + * @brief Port Status Bits + * + */ +enum MBG_IO_PORT_STATUS_BITS +{ + MBG_IO_PORT_STATUS_BIT_DISABLED, ///< See ::MBG_IO_PORT_OP_MODE_DISABLED. Other bits should be 0 in this case + MBG_IO_PORT_STATUS_BIT_CARRIER_DETECTED, ///< Port has physical carrier connection (e.g. BNC cable in case of BPE) + MBG_IO_PORT_STATUS_BIT_INPUT_SIGNAL_NEVER_AVAIL, ///< Input signal has NEVER been avail + MBG_IO_PORT_STATUS_BIT_INPUT_SIGNAL_AVAIL, ///< Input signal is avail right now + MBG_IO_PORT_STATUS_BIT_INPUT_SIGNAL_LOST, ///< Input signal is currently not avail, but has been avail before + MBG_IO_PORT_STATUS_BIT_SHORT_CIRCUIT, ///< Short circuit + 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 + MBG_IO_PORT_STATUS_BIT_TIME_VERIFYING, ///< Received time gets verified + MBG_IO_PORT_STATUS_BIT_TELEGRAM_INCONSISTENT, ///< Received time telegram is inconsistent + N_MBG_IO_PORT_STATUS_BITS +}; + + +/** + * @brief Strings descriptions for ::MBG_IO_PORT_STATUS_BITS + * + * Can be used to initialize a string array of ::N_MBG_IO_PORT_STATUS_BITS entries, + * so the number of strings must correspond to ::N_MBG_IO_PORT_STATUS_BITS. + * + * @see ::MBG_IO_PORT_STATUS_BITS + */ +#define MBG_IO_PORT_STATUS_STRS \ +{ \ + "Disabled", \ + "Carrier detected", \ + "Input signal has never been avail", \ + "Input signal is avail", \ + "Input signal is currently lost", \ + "Short circuit", \ + "Red", \ + "Green", \ + "Blue", \ + "Yellow", \ + "Time gets verified", \ + "Telegram inconsistent" \ +} + + +/** + * @brief Array size required to store all status bits + * + * The number of bytes required to store up to ::MAX_IO_PORT_STATUS_BITS + * feature bits in a byte array. + */ +#define MAX_IO_PORT_STATUS_BYTES ( MAX_IO_PORT_STATUS_BITS / 8 ) + + +/** + * @brief A structure used to store port status bits + * + * Up to ::MAX_IO_PORT_STATUS_BITS totally can be stored, but only + * ::N_MBG_IO_PORT_STATUS_BITS are currently defined. + * + * The ::_set_io_port_status_bit macro should be used by the firmware + * to set a status bit in the buffer, and the ::check_feat_supp_byte_array + * to check if a bit is set + * + * @see ::_set_io_port_status_bit + * @see ::check_feat_supp_byte_array + */ +typedef struct mbg_io_port_status_buffer_s +{ + uint8_t b[MAX_IO_PORT_STATUS_BYTES]; + +} MBG_IO_PORT_STATUS_BUFFER; + +#define _mbg_swab_io_port_status_buffer( _p ) \ + _nop_macro_fnc() + + + +/** + * @brief Set an port status bit in a ::MBG_IO_PORT_STATUS_BUFFER + * + * Should be used by the firmware only to set one of the ::N_MBG_IO_PORT_STATUS_BITS + * in an ::MBG_IO_PORT_STATUS_BUFFER after power-up. + * + * @param[in] _status_bit One of the ::MBG_IO_PORT_STATUS_BITS + * @param[in] _status_buffp Pointer to an ::MBG_IO_PORT_STATUS_BUFFER + */ +#define _set_io_port_status_bit( _status_bit, _status_buffp ) \ + _set_array_bit( _status_bit, (_status_buffp)->b, MAX_IO_PORT_STATUS_BYTES ) + + +/** + * @brief 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 Status + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS_IDX + * + */ +typedef struct +{ + MBG_IO_PORT_STATUS_BUFFER supp_stati; ///< Supported ::MBG_IO_PORT_STATUS_BITS in ::MBG_IO_PORT_STATUS_BUFFER + MBG_IO_PORT_STATUS_BUFFER status; ///< See ::MBG_IO_PORT_STATUS_BUFFER + + uint8_t 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 + + uint32_t reserved_2[4]; ///< Future use, currently 0 + +} MBG_IO_PORT_STATUS; + +#define _mbg_port_has_log_group( _p ) ( ( _p )->log_grp != MBG_NO_LOG_GROUP ) + +#define _mbg_swab_io_port_status( _p ) \ +do \ +{ \ + _mbg_swab_io_port_status_buffer( &(_p)->supp_stati ); \ + _mbg_swab_io_port_status_buffer( &(_p)->status ); \ +} while ( 0 ) + + + +/** + * @brief IO Port Status + * + * @see @ref group_io_ports + * @see ::MBG_IO_PORT_SETTINGS_U + * @see ::MBG_IO_PORT_LIMITS + * @see ::MBG_IO_PORT_SETTINGS + * @see ::MBG_IO_PORT_SETTINGS_IDX + * @see ::MBG_IO_PORT_TYPE_INFO + * @see ::MBG_IO_PORT_TYPE_INFO_U + * @see ::MBG_IO_PORT_TYPE_INFO_IDX + * @see ::MBG_IO_PORT_STATUS + * + * Indexes from 0..::MBG_IO_PORT_LIMITS::num_ports - 1 are used + * to query ::MBG_IO_PORT_TYPE_INFO wrapped in ::MBG_IO_PORT_TYPE_INFO_IDX. + * + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_IO_PORT_STATUS status; + +} MBG_IO_PORT_STATUS_IDX; + +#define _mbg_swab_io_port_status_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_io_port_status( &(_p)->status ); \ +} while ( 0 ) + + +/** @} defgroup group_io_ports */ + + + +/** + * @defgroup group_monitoring Monitoring / notification + * + * @note This structure and its definitions are only supported by a device + * if ::MBG_XFEATURE_MONITORING is set in the extended device features. + * + * TODO: Add proper Doxygen documentation + * + * @{ */ + + +#define MBG_MONITORING_STR_SIZE 32 + +enum MBG_MONITORING_TYPES +{ + MBG_MONITORING_TYPE_SNMP, + MBG_MONITORING_TYPE_EMAIL, + MBG_MONITORING_TYPE_SYSLOG, + MBG_MONITORING_TYPE_EVENTS, + N_MBG_MONITORING_TYPES +}; + +#define MBG_MONITORING_TYPE_STRS \ +{ \ + "SNMP", \ + "Email", \ + "Syslog", \ + "Events" \ +} + +enum MBG_MONITORING_TYPE_MSKS +{ + MBG_MONITORING_TYPE_MSK_SNMP = (1UL << MBG_MONITORING_TYPE_SNMP), + MBG_MONITORING_TYPE_MSK_EMAIL = (1UL << MBG_MONITORING_TYPE_EMAIL), + MBG_MONITORING_TYPE_MSK_SYSLOG = (1UL << MBG_MONITORING_TYPE_SYSLOG), + MBG_MONITORING_TYPE_MSK_EVENTS = (1UL << MBG_MONITORING_TYPE_EVENTS) +}; + + + +typedef struct +{ + uint16_t supp_types; ///< See ::MBG_MONITORING_TYPE_MSKS + uint16_t reserved_1; + uint32_t reserved_2[3]; + +} MBG_MONITORING_LIMITS; + +#define _mbg_swab_monitoring_limits( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->supp_types ); \ +} while ( 0 ) + + + +/* If ::MBG_MONITORING_TYPE_MSK_SNMP is set in ::MBG_MONITORING_LIMITS::supp_types */ + +enum MBG_SNMP_VERSIONS +{ + MBG_SNMP_VERSION_V1, + MBG_SNMP_VERSION_V2c, + MBG_SNMP_VERSION_V3, + N_MBG_SNMP_VERSIONS +}; + +#define MBG_SNMP_VERSION_STRS \ +{ \ + "Version 1", \ + "Version 2c", \ + "Version 3" \ +} + +enum MBG_SNMP_VERSION_MSKS +{ + MBG_SNMP_VERSION_MSK_V1 = (1UL << MBG_SNMP_VERSION_V1), + MBG_SNMP_VERSION_MSK_V2c = (1UL << MBG_SNMP_VERSION_V2c), + MBG_SNMP_VERSION_MSK_V3 = (1UL << MBG_SNMP_VERSION_V3) +}; + + +enum MBG_SNMP_FLAGS +{ + MBG_SNMP_SYSTEM_USER, + MBG_SNMP_ADD_CONF, ///< Supports additional SNMP configuration (i.e. via script) + MBG_SNMP_READ_ONLY, ///< Read/Write is not supported, SNMP can be used for monitoring, only + N_MBG_SNMP_FLAGS +}; + + +#define MBG_SNMP_FLAG_STRS \ +{ \ + "System user", \ + "Additional config", \ + "Read-Only" \ +} + + +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 + MBG_SNMP_READ_ONLY_MSK = ( 1UL << MBG_SNMP_READ_ONLY ) ///< See ::MBG_SNMP_READ_ONLY +}; + + +#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 +{ + uint8_t num_v12_settings; ///< Number of configured v1/v2 settings, see ::MBG_SNMP_V12_INFO_IDX + uint8_t num_v3_settings; ///< Number of configured v1/v2 trap receivers, see ::MBG_SNMP_V12_TRAP_INFO_IDX + uint8_t num_v12_trap_receivers; ///< Number of configured v3 settings, see ::MBG_SNMP_V3_INFO_IDX + uint8_t num_v3_trap_receivers; ///< Number of configured v3 trap receivers, see ::MBG_SNMP_V3_TRAP_INFO_IDX + uint16_t listening_port; ///< snmpd listening port, 161 by default + uint16_t reserved_1; + uint32_t reserved_2[3]; + char location[MBG_MONITORING_STR_SIZE]; + char contact[MBG_MONITORING_STR_SIZE]; + char name[MBG_MONITORING_STR_SIZE]; + char description[MBG_MONITORING_STR_SIZE]; + char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use + char reserved_4[MBG_MONITORING_STR_SIZE]; ///< Future use + +} MBG_SNMP_GLB_SETTINGS; + +#define _mbg_swab_snmp_glb_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->listening_port ); \ +} while ( 0 ) + + + +typedef struct mbg_snmp_glb_info_s +{ + MBG_SNMP_GLB_SETTINGS settings; + uint8_t supp_versions; ///< See ::MBG_SNMP_VERSION_MSKS + uint8_t max_v12_settings; ///< 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_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[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; + +#define _mbg_swab_snmp_glb_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_glb_settings( &(_p)->settings ); \ + _mbg_swab16( &(_p)->supp_flags ); \ +} while ( 0 ) + + + +enum MBG_SNMP_ACCESS_TYPES +{ + MBG_SNMP_ACCESS_TYPE_RO, + MBG_SNMP_ACCESS_TYPE_RW, + N_MBG_SNMP_ACCESS_TYPES +}; + + +#define MBG_SNMP_ACCESS_TYPE_STRS \ +{ \ + "Read-only", \ + "Read-write" \ +} + + + +typedef struct +{ + uint8_t version; ///< See ::MBG_SNMP_VERSIONS + uint8_t access_type; ///< See ::MBG_SNMP_ACCESS_TYPES, ignore in trap settings + uint8_t reserved_1[2]; + uint32_t reserved_2[3]; + char community[MBG_MONITORING_STR_SIZE]; + +} MBG_SNMP_V12_SETTINGS; + +#define _mbg_swab_snmp_v12_settings( _p ) \ +do \ +{ \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SNMP_V12_SETTINGS settings; + +} MBG_SNMP_V12_SETTINGS_IDX; + +#define _mbg_swab_snmp_v12_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v12_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct mbg_snmp_v12_info_s +{ + MBG_SNMP_V12_SETTINGS settings; + uint32_t reserved_1[4]; + +} MBG_SNMP_V12_INFO; + +#define _mbg_swab_snmp_v12_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v12_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SNMP_V12_INFO info; + +} MBG_SNMP_V12_INFO_IDX; + +#define _mbg_swab_snmp_v12_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v12_info( &(_p)->info ); \ +} while ( 0 ) + + + +typedef struct +{ + uint8_t timeout; ///< In seconds + uint8_t retries; + uint16_t reserved_1; + uint32_t reserved_2[3]; + char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use + char reserved_4[MBG_MONITORING_STR_SIZE]; ///< Future use + MBG_SNMP_V12_SETTINGS v12_settings; + MBG_HOSTNAME receiver_addr; + uint16_t dest_port; ///< receiver destination port, 162 by default + uint16_t reserved_5; + +} MBG_SNMP_V12_TRAP_SETTINGS; + +#define _mbg_swab_snmp_v12_trap_settings( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v12_settings( &(_p)->v12_settings ); \ + _mbg_swab16( &(_p)->dest_port ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SNMP_V12_TRAP_SETTINGS settings; + +} MBG_SNMP_V12_TRAP_SETTINGS_IDX; + +#define _mbg_swab_snmp_v12_trap_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v12_trap_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct mbg_snmp_v12_trap_info_s +{ + MBG_SNMP_V12_TRAP_SETTINGS settings; + uint32_t reserved_1[4]; + +} MBG_SNMP_V12_TRAP_INFO; + +#define _mbg_swab_snmp_v12_trap_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v12_trap_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SNMP_V12_TRAP_INFO info; + +} MBG_SNMP_V12_TRAP_INFO_IDX; + +#define _mbg_swab_snmp_v12_trap_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v12_trap_info( &(_p)->info ); \ +} while ( 0 ) + + + +enum MBG_SNMP_V3_SEC_LEVELS +{ + MBG_SNMP_V3_SEC_LEVEL_NO_AUTH_NO_PRIV, + MBG_SNMP_V3_SEC_LEVEL_AUTH_NO_PRIV, + MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV, + N_MBG_SNMP_V3_SEC_LEVELS +}; + +#define MBG_SNMP_V3_SEC_LEVEL_STRS \ +{ \ + "No auth no priv", \ + "Auth no priv", \ + "Auth priv" \ +} + + +enum MBG_SNMP_V3_AUTH_PROTOCOLS +{ + MBG_SNMP_V3_AUTH_PROTOCOL_NONE, + MBG_SNMP_V3_AUTH_PROTOCOL_MD5, + MBG_SNMP_V3_AUTH_PROTOCOL_SHA, + N_MBG_SNMP_V3_AUTH_PROTOCOLS +}; + +#define MBG_SNMP_V3_AUTH_PROTOCOL_STRS \ +{ \ + "None", \ + "MD5", \ + "SHA" \ +} + + +enum MBG_SNMP_V3_PRIV_PROTOCOLS +{ + MBG_SNMP_V3_PRIV_PROTOCOL_NONE, + MBG_SNMP_V3_PRIV_PROTOCOL_DES, + MBG_SNMP_V3_PRIV_PROTOCOL_AES, + N_MBG_SNMP_V3_PRIV_PROTOCOLS +}; + + +#define MBG_SNMP_V3_PRIV_PROTOCOL_STRS \ +{ \ + "None", \ + "DES", \ + "AES" \ +} + + + +typedef struct +{ + uint8_t access_type; ///< See ::MBG_SNMP_ACCESS_TYPES, ignore in trap settings + uint8_t sec_level; ///< See ::MBG_SNMP_V3_SEC_LEVELS + uint8_t auth_protocol; ///< See ::MBG_SNMP_V3_AUTH_PROTOCOLS if ::MBG_SNMP_V3_SETTINGS::sec_level + ///< is ::MBG_SNMP_V3_SEC_LEVEL_AUTH_NO_PRIV or ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV + uint8_t priv_protocol; ///< See ::MBG_SNMP_V3_PRIV_PROTOCOLS if ::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 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 + char reserved_3[MBG_MONITORING_STR_SIZE]; ///< Future use + char priv_passwd[MBG_MONITORING_STR_SIZE]; ///< Encryption passwd if ::MBG_SNMP_V3_SETTINGS::auth_protocol is ::MBG_SNMP_V3_SEC_LEVEL_AUTH_PRIV + uint32_t boots; ///< Number of system/deamon restarts -> Ignore + uint32_t time; ///< Timeticks since last "boots" event -> Ignore + uint32_t reserved_4[2]; + +} MBG_SNMP_V3_SETTINGS; + +#define _mbg_swab_snmp_v3_settings( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->boots ); \ + _mbg_swab32( &(_p)->time ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SNMP_V3_SETTINGS settings; + +} MBG_SNMP_V3_SETTINGS_IDX; + +#define _mbg_swab_snmp_v3_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v3_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct mbg_snmp_v3_info_s +{ + MBG_SNMP_V3_SETTINGS settings; + uint32_t reserved_1[4]; + +} MBG_SNMP_V3_INFO; + +#define _mbg_swab_snmp_v3_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v3_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SNMP_V3_INFO info; + +} MBG_SNMP_V3_INFO_IDX; + +#define _mbg_swab_snmp_v3_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v3_info( &(_p)->info ); \ +} while ( 0 ) + + + +typedef struct +{ + uint8_t timeout; ///< In seconds + uint8_t retries; + uint8_t reserved_1[2]; + uint32_t reserved_2[3]; + MBG_SNMP_V3_SETTINGS v3_settings; + MBG_HOSTNAME receiver_addr; + uint16_t dest_port; ///< receiver destination port, 162 by default + uint16_t reserved_3; + +} MBG_SNMP_V3_TRAP_SETTINGS; + +#define _mbg_swab_snmp_v3_trap_settings( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v3_settings( &(_p)->v3_settings ); \ + _mbg_swab16( &(_p)->dest_port ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SNMP_V3_TRAP_SETTINGS settings; + +} MBG_SNMP_V3_TRAP_SETTINGS_IDX; + +#define _mbg_swab_snmp_v3_trap_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v3_trap_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct mbg_snmp_v3_trap_info_s +{ + MBG_SNMP_V3_TRAP_SETTINGS settings; + uint32_t reserved_1[4]; + +} MBG_SNMP_V3_TRAP_INFO; + +#define _mbg_swab_snmp_v3_trap_info( _p ) \ +do \ +{ \ + _mbg_swab_snmp_v3_trap_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_SNMP_V3_TRAP_INFO info; + +} MBG_SNMP_V3_TRAP_INFO_IDX; + +#define _mbg_swab_snmp_v3_trap_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_snmp_v3_trap_info( &(_p)->info ); \ +} while ( 0 ) + + + +/* If ::MBG_MONITORING_TYPE_MSK_EVENTS is set in ::MBG_MONITORING_LIMITS::supp_types */ + + +enum MBG_EVENT_STR_FMTS +{ + MBG_EVENT_STR_FMT_JSON, + N_MBG_EVENT_STR_FMTS +}; + + +enum MBG_EVENT_STR_FMT_MSKS +{ + MBG_EVENT_STR_FMT_JSON_MSK = (1UL << MBG_EVENT_STR_FMT_JSON) +}; + + +#define MBG_EVENT_STR_FMT_STRS \ +{ \ + "JSON" \ +} + + +enum MBG_EVENT_DEV_IDS +{ + MBG_EVENT_DEV_ID_NONE, ///< No identifier added to the events + MBG_EVENT_DEV_ID_ALIAS, ///< Add alias from MBG_EVENT_GLB_SETTINGS as identifier to all events + MBG_EVENT_DEV_ID_SERNUM, ///< Add serial number as identifier to all events + N_MBG_EVENT_DEV_IDS +}; + + +enum MBG_EVENT_DEV_ID_MSKS +{ + MBG_EVENT_DEV_ID_NONE_MSK = ( 1UL << MBG_EVENT_DEV_ID_NONE ), ///< See ::MBG_EVENT_DEV_ID_NONE + MBG_EVENT_DEV_ID_ALIAS_MSK = ( 1UL << MBG_EVENT_DEV_ID_ALIAS ), ///< See ::MBG_EVENT_DEV_ID_ALIAS + MBG_EVENT_DEV_ID_SERNUM_MSK = ( 1UL << MBG_EVENT_DEV_ID_SERNUM ) ///< See ::MBG_EVENT_DEV_ID_SERNUM +}; + + +#define MBG_EVENT_DEV_ID_STRS \ +{ \ + "None", \ + "Alias", \ + "Serial Number" \ +} + + +enum MBG_EVENT_GLB_FLAGS +{ + MBG_EVENT_GLB_FLAG_FUE, ///< Forward unknown events. This is not relevant for mbgdevman + ///< that always gets all events. It's important for syslog, SNMP, email, etc.. + ///< to avoid that alarming systems react furious to unknown events. + N_MBG_EVENT_GLB_FLAGS +}; + + +enum MBG_EVENT_GLB_FLAG_MSKS +{ + MBG_EVENT_GLB_FLAG_FUE_MSK = ( 1UL << MBG_EVENT_GLB_FLAG_FUE ) ///< See ::MBG_EVENT_GLB_FLAG_FUE +}; + + +typedef struct +{ + uint8_t format; ///< See ::MBG_EVENT_STR_FMTS + uint8_t dev_id; ///< See ::MBG_EVENT_DEV_IDS + uint8_t flags; ///< See ::MBG_EVENT_GLB_FLAG_MSKS + uint8_t reserved_1[5]; + + char alias[16]; ///< Alias of this device, see ::MBG_EVENT_DEV_ID_ALIAS + + uint32_t reserved_3[4]; + +} MBG_EVENT_GLB_SETTINGS; + +#define _mbg_swab_event_glb_settings( _p ) \ +do \ +{ \ +} while ( 0 ) + + +typedef struct mbg_event_glb_info_s +{ + MBG_EVENT_GLB_SETTINGS settings; ///< See ::MBG_EVENT_GLB_SETTINGS + + uint16_t num_events; ///< Supported number of events. See ::MBG_EVENT_TYPES + uint16_t supp_formats; ///< Supported format (::MBG_EVENT_STR_FMTS) in ::MBG_EVENT_STATUS::data + uint16_t supp_dev_ids; ///< Supported dev ids (::MBG_EVENT_DEV_IDS) that can be added to each ::MBG_EVENT_STATUS::data + uint8_t supp_flags; ///< Supported global settings flags. See ::MBG_EVENT_GLB_FLAG_MSKS + uint8_t reserved_1; + + uint32_t reserved_2[3]; + +} MBG_EVENT_GLB_INFO; + +#define _mbg_swab_event_glb_info( _p ) \ +do \ +{ \ + _mbg_swab_event_glb_settings( (_p) ); \ + _mbg_swab16( &(_p)->num_events ); \ + _mbg_swab16( &(_p)->supp_formats ); \ + _mbg_swab16( &(_p)->supp_dev_ids ); \ +} while ( 0 ) + + + +enum MBG_EVENT_TYPES +{ + MBG_EVENT_TYPE_NTP_STATE, + MBG_EVENT_TYPE_HEARTBEAT, + MBG_EVENT_TYPE_RECEIVER_STATE, + MBG_EVENT_TYPE_LEAP_SECOND, + MBG_EVENT_TYPE_PTP_STATE, + MBG_EVENT_TYPE_SYSREF_MASTER_REF, + MBG_EVENT_TYPE_PS_STATE, + MBG_EVENT_TYPE_REBOOT, + MBG_EVENT_TYPE_MEMORY, + MBG_EVENT_TYPE_CPU_LOAD, + MBG_EVENT_TYPE_TEMPERATURE, + MBG_EVENT_TYPE_NW_LINK, + MBG_EVENT_TYPE_CONFIG, + MBG_EVENT_TYPE_LOGIN, + MBG_EVENT_TYPE_WATCHDOG, + N_MBG_EVENT_TYPES +}; + +#define MBG_EVENT_TYPE_STRS \ +{ \ + "NTP state", \ + "Heartbeat", \ + "Receiver state", \ + "Leap second", \ + "PTP state", \ + "Master reference changed", \ + "Power supply state", \ + "Reboot", \ + "Memory", \ + "CPU load", \ + "Temperature", \ + "Network link", \ + "Configuration", \ + "Login", \ + "Watchdog" \ +} + + +enum MBG_EVENT_SEVERITIES +{ + MBG_EVENT_SEVERITY_OK, + MBG_EVENT_SEVERITY_INFO, + MBG_EVENT_SEVERITY_WARNING, + MBG_EVENT_SEVERITY_ERROR, + MBG_EVENT_SEVERITY_CRITICAL, + N_MBG_EVENT_SEVERITIES +}; + +#define MBG_EVENT_SEVERITY_STRS \ +{ \ + "OK", \ + "Info", \ + "Warning", \ + "Error", \ + "Critical" \ +} + +typedef struct +{ + 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]; + +} MBG_EVENT_SETTINGS; + +#define _mbg_swab_event_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->triggers ); \ + _mbg_swab16( &(_p)->interval ); \ +} while ( 0 ) + + + +/** + * @brief Structure for monitoring event settings + * + * @see ::MBG_EVENT_INFO_IDX + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_EVENT_SETTINGS settings; + +} MBG_EVENT_SETTINGS_IDX; + +#define _mbg_swab_event_settings_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_event_settings( &(_p)->settings ); \ +} while ( 0 ) + + + +enum MBG_EVENT_SUPP_FLAGS +{ + MBG_EVENT_SUPP_FLAG_INTERVAL, ///< Event can be sent cyclically + N_MBG_EVENT_SUPP_FLAGS +}; + + +enum MBG_EVENT_SUPP_FLAG_MSKS +{ + MBG_EVENT_SUPP_FLAG_MSK_INTERVAL = ( 1UL << MBG_EVENT_SUPP_FLAG_INTERVAL ) +}; + + + +/** + * @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 +#define MBG_INV_EVENT_INST 0xFF ///< See ::MBG_EVENT_INFO::inst_idx + +/** @} defgroup group_mbg_event_info_indexes */ + + +typedef struct +{ + 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 reserved_1; + uint16_t reserved_2; + + uint8_t slot_type_id; ///< See ::XBP_NODE_INFO::slot_type_id, or ::MBG_OWN_EVENT_SLOT_TYPE_ID + uint8_t inst_idx; ///< Instance index since one port might have multiple instances of the same type. + ///< For example, PTP is hopefully capable to do so one day. + ///< Use ::MBG_INV_EVENT_INST to not show the instance number explicitly, + ///< e.g. you only have got one instance. + uint16_t supp_flags; ///< See ::MBG_EVENT_SUPP_FLAG_MSKS + uint16_t supp_triggers; ///< See ::MBG_MONITORING_TYPE_MSKS + uint16_t reserved_3; ///< Future use + + uint32_t reserved_4[8]; + +} MBG_EVENT_INFO; + +#define _mbg_swab_event_info( _p ) \ +do \ +{ \ + _mbg_swab_event_settings( &(_p)->settings ); \ + _mbg_swab16( &(_p)->type ); \ + _mbg_swab16( &(_p)->value_dict_entries ); \ + _mbg_swab16( &(_p)->supp_flags ); \ + _mbg_swab16( &(_p)->supp_triggers ); \ +} while ( 0 ) + + + +/** + * @brief Structure for monitoring event info + * + * @note idx represents the event type, see ::MBG_EVENT_TYPES + * Before requesting the struct, its availability should be checked + * in ::MBG_EVENT_GLB_INFO::num_events. + * + * @see ::MBG_EVENT_TYPES + * @see ::MBG_EVENT_GLB_INFO + */ +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_EVENT_INFO info; + +} MBG_EVENT_INFO_IDX; + +#define _mbg_swab_event_info_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_event_info( &(_p)->info ); \ +} while ( 0 ) + + +#define MBG_EVT_ST_MAX_DATA_LEN 480 + +typedef struct +{ + uint32_t last_changed; ///< Unix timestamp when this event state has been changed + uint32_t reserved_1[2]; ///< Future use + uint8_t severity; ///< See ::MBG_EVENT_SEVERITIES + uint8_t reserved_2[3]; ///< Future use + + uint8_t data[MBG_EVT_ST_MAX_DATA_LEN]; ///< The event value in the configured format, see ::MBG_EVENT_GLB_SETTINGS::format + +} MBG_EVENT_STATUS; + +#define _mbg_swab_event_status( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->last_changed ); \ +} while ( 0 ) + + + +typedef struct +{ + MBG_MSG_IDX_32 idx; + MBG_EVENT_STATUS status; + +} MBG_EVENT_STATUS_IDX; + +#define _mbg_swab_event_status_idx( _p ) \ +do \ +{ \ + _mbg_swab32( &(_p)->idx ); \ + _mbg_swab_event_status( &(_p)->status ); \ +} 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_info_s +{ + 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; + MBG_MSG_IDX_32 idx; + +} MBG_SYSLOG_SETTINGS_IDX; + +#define _mbg_swab_syslog_settings_idx( _p ) \ +do \ +{ \ + _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 + MBG_MSG_IDX_32 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_tainted_cfg Tainted config + * + * @note This structure and its definitions are only supported by a device + * 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 the config of a sub-feature changes, its counter in this structure + * is increased to indicate the config change. Thus, software can read this + * structure and request the changed config. Also used for push notifications. + * + * TODO Add proper Doxygen documentation + * + * @{ */ + + +#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_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, + MBG_TAINTED_CFG_PTP_NG, + MBG_TAINTED_CFG_SYS_REF, + MBG_TAINTED_CFG_TR_DIST, + 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 ) + +/** + * @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 _mbg_user_perms +{ + 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 + ///< ::GPS_SYS_REF_LIMITS + ///< ::GPS_SYS_REF_GLB_STATUS + ///< ::GPS_SYS_REF_SRC_INFO_IDX + ///< ::GPS_SYS_REF_SRC_STATUS_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_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 + ///< ::GPS_PTP_NG_GLB_INFO + ///< ::GPS_PTP_NG_TSTAMPER_INFO_IDX + ///< ::GPS_PTP_NG_INSTC_INFO_IDX + ///< ::GPS_PTP_NG_INSTC_STATUS_IDX + ///< ::GPS_PTP_NG_UC_MASTER_INFO_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_SVC_MGMT_INFO + ///< ::GPS_SVC_INFO_IDX + ///< ::GPS_SVC_STATUS_IDX + ///< ::GPS_SVC_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_user_scopes +{ + 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; + +/// @brief a combined permission mask to read configuration or status. +/// +/// In most cases the permission to read the configuration includes +/// the permission to read the status, anyway. +#define USER_SCOPE_CONFIG_OR_STATUS_READ_MSK \ + ( USER_SCOPE_CONFIG_READ_MSK | USER_SCOPE_STATUS_READ_MSK ) + + +#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 mbg_user_perm_buf_s +{ + 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 + USER_CFG_CAN_SHELL_SUDO, ///< The user is allowed to increase the privilege level by using sudo tool. + ///< Only relevant if user is allowed to use shell channel. + 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 + USER_CFG_CAN_SHELL_SUDO_MASK = ( 1UL << USER_CFG_CAN_SHELL_SUDO ) ///< See ::USER_CFG_CAN_SHELL_SUDO + +} MBG_USER_CFG_FLAG_MASKS; + + +#define MBG_MAX_USER_NAME_LEN 32 ///< See man page for 'useradd'. +#define MBG_MAX_USER_PASSWORD_LEN 128 + + +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[8]; ///< 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 +{ + MBG_MSG_IDX_32 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[8]; ///< 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 +{ + MBG_MSG_IDX_32 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 +{ + MBG_MSG_IDX_32 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_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 + +} MBG_SERVICE_CTL; + + +typedef struct +{ + char cmdline[MBG_SVC_CMD_LEN]; + uint8_t enabled; + uint8_t reserved_1[3]; + uint32_t reserved_2[3]; + +} MBG_SERVICE_SETTINGS; + + +#define _mbg_swab_svc_settings( _p ) do {} while ( 0 ) + + +typedef struct +{ + MBG_MSG_IDX_32 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 +{ + MBG_MSG_IDX_32 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 +{ + MBG_MSG_IDX_32 idx; + MBG_SERVICE_STATUS status; + +} MBG_SERVICE_STATUS_IDX; + + +#define _mbg_swab_svc_status_idx( _p ) \ +do \ +{ \ + _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. + * + * @{ */ + + +enum MBG_FW_GLB_FLAGS +{ + MBG_FW_GLB_FLAG_CAN_SET_OSV, ///< OSV is settable/changeable + N_MBG_FW_GLB_FLAGS +}; + + +enum MBG_FW_GLB_MSKS +{ + MBG_FW_GLB_MSK_CAN_SET_OSV = ( 1UL << MBG_FW_GLB_FLAG_CAN_SET_OSV ) ///< See ::MBG_FW_GLB_FLAG_CAN_SET_OSV +}; + + +typedef struct +{ + 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 + + uint8_t reserved_1[2]; + uint16_t flags; ///< See ::MBG_FW_GLB_MSKS + + uint32_t reserved_2[14]; + +} 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 +{ + MBG_MSG_IDX_32 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]; + 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 ) + + +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 model code of the firmware, 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 +}; + + +/** + * @brief Data used with UFU firmware flash command. + * + * @note Please note that, depending on the command, specific members in + * ::MBG_FW_UFU_FLASH_CMD are valid, all others should be zero and be ignored. + */ +typedef struct +{ + 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. + + /// @brief Database 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, + /// so a capable piece of software can fetch it via the 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 +{ + MBG_MSG_IDX_32 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 +{ + /// @brief 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 + + /// @brief Flag field indicating which ::MBG_DATABASE_MEMBER_MSKS are valid. + uint16_t supp_members; + + /// @brief Flag field which ::MBG_DATABASE_MEMBER_MSKS are configurable. + /// + /// Subset of ::MBG_DATABASE_INFO::supp_members. + uint16_t supp_cfgs; + + /// @brief Supported settings flags. + /// + /// 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 +{ + MBG_MSG_IDX_32 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_fcu_api FCU API + * + * @note These structures and definitions allow configuration + * and status monitoring of multiple power supplies and fans. + * Only supported if ::MBG_XFEATURE_FCU_API is set. + * The legacy device FCU_01 does ***not*** support this API. + * + * @{ */ + + +/** + * @brief The maximum number of power supply modules supported by the API. + * + * This is limited e.g. by the number of bits available + * in ::MBG_FCU_SETTINGS::installed_power_supplies. + * Existing FCU modules normally only support a much smaller + * number of power supplies. + */ +#define FCU_MAX_PSU_MODULES 16 +// NOTE Changing the numeric value breaks API compatibility. + + +/** + * @brief The maximum number of fan control modules supported by the API. + * + * This is limited e.g. by the number of bits available + * in ::MBG_FCU_SETTINGS::fan_units_to_disable. + * The number of fan modules supported by a particular FCU module + * is usually smaller. + */ +#define FCU_MAX_FAN_MODULES 16 +// NOTE Changing the numeric value breaks API compatibility. + + +/** + * @brief The maximum number of fan control lines per fan module. + * + * This is an arbitrary maximum number. + * Existing FCU modules normally only support a much smaller + * number of fan modules, e.g. 1 or 4, depending on the fan + * module hardware and the FCU model. + */ +#define FCU_MAX_FANS_CTRL_PER_MODULE 8 +// NOTE Changing the numeric value breaks API compatibility. + + + +/** + * @brief Configuration settings to be sent to an FCU module. + */ +typedef struct +{ + /// @brief Bit mask used to tell the FCU module which slot(s) + /// are known to have a power supply module is physically installed. + /// + /// This tells the FCU that power should be available from those slots, + /// and thus affects the status reported for a power supply slot, + /// i.e. "not available" vs. "OK" or "faulty". + uint16_t installed_power_supplies; + + /// @brief Bit mask of fan modules to be ***disabled*** by the FCU. + /// + /// By default, all fan modules are anyway enabled after + /// power-up, so the control program can explicitly disable + /// selected modules later, if preferred for some reason. + uint16_t fan_units_to_disable; + + uint16_t reserved_0; ///< Currently not used, should be set to 0. + uint16_t reserved_1; ///< Currently not used, should be set to 0. + + uint16_t reserved_2; ///< Currently not used, should be set to 0. + uint16_t reserved_3; ///< Currently not used, should be set to 0. + uint16_t reserved_4; ///< Currently not used, should be set to 0. + uint16_t reserved_5; ///< Currently not used, should be set to 0. + +} MBG_FCU_SETTINGS; + +#define _mbg_swab_fcu_settings( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->installed_power_supplies ); \ + _mbg_swab16( &(_p)->fan_units_to_disable ); \ + _mbg_swab16( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ + _mbg_swab16( &(_p)->reserved_2 ); \ + _mbg_swab16( &(_p)->reserved_3 ); \ + _mbg_swab16( &(_p)->reserved_4 ); \ + _mbg_swab16( &(_p)->reserved_5 ); \ +} while ( 0 ) + + + +/** + * @brief Info and current settings to be retrieved from an FCU module. + */ +typedef struct +{ + MBG_FCU_SETTINGS fcu_settings; ///< Current settings. + + /// @brief The number of power supply modules that can be + /// monitored by the particular FCU module. + /// + /// Must not exceed ::FCU_MAX_PSU_MODULES. + uint8_t n_psu_modules; + + /// @brief The number of fan modules that can be monitored + /// by the particular FCU module. + /// + /// Must no exceed ::FCU_MAX_FAN_MODULES. + uint8_t n_fan_modules; + + uint8_t reserved_0; ///< Currently not used, reserved. + uint8_t reserved_1; ///< Currently not used, reserved. + + uint32_t reserved_2; ///< Currently not used, reserved. + + /// @brief The number of fan control lines for each fan module. + /// + /// Some module types may have 1 fan with 1 control line, + /// there may be modules with several fans, each of which + /// has its own control line, and finally there may be modules + /// with several fans that share a single summary control line. + /// The FCU firmware can determine and report these values + /// depending on the hardware it is running on. + uint8_t fan_ctrls_per_module[FCU_MAX_FAN_MODULES]; + + uint32_t reserved_3; ///< Currently not used, reserved. + uint32_t reserved_4; ///< Currently not used, reserved. + uint32_t reserved_5; ///< Currently not used, reserved. + uint32_t reserved_6; ///< Currently not used, reserved. + +} MBG_FCU_INFO; + +#define _mbg_swab_fcu_info( _p ) \ +do \ +{ \ + _mbg_swab_fcu_settings( &(_p)->fcu_settings ); \ + _mbg_swab8( &(_p)->n_psu_modules ); \ + _mbg_swab8( &(_p)->n_fan_modules ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab8( &(_p)->reserved_1 ); \ + _mbg_swab32( &(_p)->reserved_2 ); \ + _mbg_swab32( &(_p)->reserved_3 ); \ + _mbg_swab32( &(_p)->reserved_4 ); \ + _mbg_swab32( &(_p)->reserved_5 ); \ + _mbg_swab32( &(_p)->reserved_6 ); \ +} while ( 0 ) + + + +/** + * @brief Power supply status information to be retrieved from an FCU module. + * + * ::MBG_FCU_INFO::n_psu_modules are supported by the FCU module, + * but how many and which power supply modules are actually + * monitored depends on the bit mask ::MBG_FCU_SETTINGS::installed_power_supplies + * that has been sent to the FCU module. + */ +typedef struct +{ + uint8_t status; ///< The status, see ::FCU_PSU_STAT_CODES. + uint8_t reserved_0; ///< Currently unused, reserved. + uint16_t reserved_1; ///< Currently unused, reserved. + +} MBG_FCU_PSU_STAT; + +#define _mbg_swab_fcu_psu_stat( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->status ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ +} while ( 0 ) + + + +/** + * @brief Power supply status codes used with ::MBG_FCU_PSU_STAT::status. + */ +enum FCU_PSU_STAT_CODES +{ + /// The bit mask in ::MBG_FCU_SETTINGS::installed_power_supplies + /// indicates there is no PSU module expected in this slot, and + /// the associated voltage sense line is low, es expected. + FCU_PSU_STAT_CODE_NOT_AVAIL, + + /// The bit mask in ::MBG_FCU_SETTINGS::installed_power_supplies + /// indicates there is no PSU module expected in this slot, but + /// the associated voltage sense line is anyway high, so obviously + /// a PSU module is installed which has not yet been registered. + FCU_PSU_STAT_CODE_UNREGISTERED, + + /// The bit mask in ::MBG_FCU_SETTINGS::installed_power_supplies + /// indicates there is a PSU module installed in this slot, and + /// the associated voltage sense line is high, so the PSU works + /// properly. + FCU_PSU_STAT_CODE_OK, + + /// The bit mask in ::MBG_FCU_SETTINGS::installed_power_supplies + /// indicates there is a PSU module installed in this slot, but + /// the associated voltage sense line is low, so the PSU is faulty + /// or has been removed. + FCU_PSU_STAT_CODE_FAIL, + + N_FCU_PSU_STAT_CODE ///< The number of known status codes. +}; + + + +/** + * @brief Power supply status information plus module index. + * + * Monitoring software should poll index 0...::MBG_FCU_INFO::n_psu_modules-1. + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0...::MBG_FCU_INFO::n_psu_modules-1. + MBG_FCU_PSU_STAT psu_stat; + +} MBG_FCU_PSU_STAT_IDX; + +#define _mbg_swab_fcu_psu_stat_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_fcu_psu_stat( &(_p)->psu_stat ); \ +} while ( 0 ) + + + +/** + * @brief Fan status information to be retrieved from an FCU module. + * + * ::MBG_FCU_INFO::n_fan_modules are supported by the FCU module, + * but how many fan modules with one or more control lines each + * are actually monitored depends on the FCU device and fan hardware. + */ +typedef struct +{ + /// @brief Indicates how many control lines are checked + /// + /// for the specified module, i.e. how many items + /// of @a #status contain relevant status information. + /// Should correspond to ::MBG_FCU_INFO::fan_ctrls_per_module. + uint8_t n_ctrls; + + uint8_t reserved_0; ///< Currently unused, reserved. + uint16_t reserved_1; ///< Currently unused, reserved. + + uint8_t status[FCU_MAX_FANS_CTRL_PER_MODULE]; ///< See ::FCU_FAN_STAT_CODES. + +} MBG_FCU_FAN_STAT; + +#define _mbg_swab_fcu_fan_stat( _p ) \ +do \ +{ \ + _mbg_swab8( &(_p)->n_ctrls ); \ + _mbg_swab8( &(_p)->reserved_0 ); \ + _mbg_swab16( &(_p)->reserved_1 ); \ +} while ( 0 ) + + + +/** + * @brief Fan status codes used with ::MBG_FCU_FAN_STAT::status. + */ +enum FCU_FAN_STAT_CODES +{ + FCU_FAN_STAT_CODE_NOT_AVAIL, ///< No fan installed at the control line of this unit. + FCU_FAN_STAT_CODE_DISABLED, ///< Fan installed but disabled. + FCU_FAN_STAT_CODE_OK, ///< Fan installed and working OK. + FCU_FAN_STAT_CODE_TURNED_OFF, ///< Fan turned off by frontpanel switch. + FCU_FAN_STAT_CODE_FAULTY, ///< Fan installed but fails. + N_FCU_FAN_STAT_CODE ///< The number of known status codes. +}; + + + +/** + * @brief Fan status information plus module index. + * + * Monitoring software should poll index 0...::MBG_FCU_INFO::n_fan_modules-1. + */ +typedef struct +{ + MBG_MSG_IDX idx; ///< 0...::MBG_FCU_INFO::n_fan_modules-1. + MBG_FCU_FAN_STAT fan_stat; + +} MBG_FCU_FAN_STAT_IDX; + +#define _mbg_swab_fcu_fan_stat_idx( _p ) \ +do \ +{ \ + _mbg_swab16( &(_p)->idx ); \ + _mbg_swab_fcu_fan_stat( &(_p)->fan_stat ); \ +} while ( 0 ) + + +/** @} defgroup group_fcu_api */ + + + +#if defined( _USING_BYTE_ALIGNMENT ) + #pragma pack() // set default alignment + #undef _USING_BYTE_ALIGNMENT +#endif + +/* End of header body */ + +#endif /* _GPSDEFS_H */ diff --git a/mbglib/common/mbgerror.c b/mbglib/common/mbgerror.c new file mode 100644 index 0000000..af2cd8f --- /dev/null +++ b/mbglib/common/mbgerror.c @@ -0,0 +1,1215 @@ + +/************************************************************************** + * + * $Id: mbgerror.c 1.13 2021/12/01 15:51:16 martin.burnicki REL_M $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Meinberg Library to communicate with USB devices from user space + * + * ----------------------------------------------------------------------- + * $Log: mbgerror.c $ + * Revision 1.13 2021/12/01 15:51:16 martin.burnicki + * New error code MBG_ERR_OP_NOT_SUPP for EOPNOTSUPP and ENOTSUP. + * Revision 1.12 2021/03/16 12:20:57 martin + * Updated some comments. + * Revision 1.11 2021/03/12 12:32:15 martin + * Updated some comments. + * Revision 1.10 2019/11/11 09:43:41 martin + * Tiny doxygen change. + * Revision 1.9 2019/08/26 15:15:10 martin + * Translate POSIX ENODATA to MBG_ERR_NO_DATA. + * Revision 1.8 2019/08/20 08:22:51 martin + * Translate win32 ERROR_FILE_NOT_FOUND to MBG_ERR_NO_ENTITY. + * Revision 1.7 2019/04/03 12:53:55 martin + * Use new code MBG_ERR_BAD_ADDR. + * Revision 1.6 2018/11/22 14:47:15 martin + * Support QNX target. + * New function mbg_win32_ntstatus_to_mbg(). + * Added and renamed static code conversion tables. + * Added and updated doxygen comments. + * Revision 1.5 2018/09/21 09:44:38 martin + * Renamed mbg_win32_last_err_to_mbg() to + * mbg_win32_sys_err_to_mbg(). + * Translate win32 error codes ERROR_BUFFER_OVERFLOW + * and ERROR_INSUFFICIENT_BUFFER. + * Updated some comments. + * Revision 1.4 2018/06/25 14:21:09Z 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. + * Mapped POSIX error ENOSPC to MBG_ERR_NO_SPACE, and EFAULT + * to MBG_ERR_INV_PARM. + * Mapped Windows WSA error codes WSAEFAULT and WSAEINVAL + * to MBG_ERR_INV_PARM. + * Renamed mbg_ioctl_err() to mbg_cond_err_msg(). + * New function mbg_cond_err_msg_info() which takes an optional + * info string which is printed if the error code to be checked + * is MBG_ERR_NOT_SUPP_BY_DEV. + * Fixed build in Windows kernel mode. + * Fixed syntax error in CVI-specific code. + * Quieted some compiler warnings. + * Revision 1.2 2016/08/05 12:25:44Z martin + * Added some functions. + * Revision 1.1 2014/03/07 12:08:14 martin + * Initial revision. + * + **************************************************************************/ + +#define _MBGERROR + #include <mbgerror.h> +#undef _MBGERROR + +#include <mbg_tgt.h> + +#if defined( MBG_TGT_WIN32 ) + + #if !defined( MBG_TGT_KERNEL ) + #include <errno.h> + #include <stdio.h> + + #define _MBG_TGT_HAS_POSIX_ERRNO 1 + #define _MBG_TGT_HAS_WIN32_ERR_API 1 + #else + #include <mbgddmsg.h> + + #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_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_QNX_NTO ) // QNX 6.x only, but not QNX 4.x + + #include <stdio.h> + #include <errno.h> + #include <string.h> + #include <netdb.h> + + #define _MBG_TGT_HAS_POSIX_ERRNO 1 + #define _MBG_TGT_HAS_POSIX_H_ERRNO 1 + +#elif defined( MBG_TGT_DOS ) + + #include <stdio.h> + #include <stdlib.h> + #include <stddef.h> + #include <errno.h> + + #define _MBG_TGT_HAS_POSIX_ERRNO 1 + #define _MBG_TGT_OMIT_SOCKET_ERRORS 1 // No network socket support by OS + +#endif + +#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 srch_errno; + int mapped_errno; + +} ERRNO_CNV_ENTRY; + + + +#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[] = +{ + { 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_BAD_ADDRESS }, // 14, Bad address (e.g. invalid address in a function argument). + // { ENOTBLK, }, // 15, Block device required (possibly not a POSIX error, but supported on 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( ENODATA ) + { ENODATA, MBG_ERR_NO_DATA }, // 61, No (more) data. +#endif +#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 (can't be stored). +#endif +#if defined( ENOTSOCK ) + { ENOTSOCK, MBG_ERR_NOT_A_SOCKET }, // 88, Socket operation on non-socket (file descriptor is not a socket). +#endif +#if defined( EOPNOTSUPP) + { EOPNOTSUPP, MBG_ERR_OP_NOT_SUPP }, // 95, Operation not supported. +#endif +#if defined( ENOTSUP) + { ENOTSUP, MBG_ERR_OP_NOT_SUPP }, // (On some systems same as EOPNOTSUPP, but may be different on other systems) +#endif +#if defined( ECONNRESET ) + { 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 + +}; // posix_errno_table + +#endif // defined( _MBG_TGT_HAS_POSIX_ERRNO ) + + + +#if defined( _MBG_TGT_HAS_POSIX_H_ERRNO ) + +static ERRNO_CNV_ENTRY posix_h_errno_table[] = +{ + // POSIX codes taken from Linux netdb.h + { HOST_NOT_FOUND, MBG_ERR_HOST_NOT_FOUND }, // The specified host is unknown. + // { NO_ADDRESS, }, // Usually same numeric value as NO_DATA. + // { NO_DATA, }, // The requested name is valid but does not have an IP address. + // { NO_RECOVERY, }, // A nonrecoverable name server error occurred. + // { TRY_AGAIN, }, // A temporary error occurred on an authoritative name server. Try again later. + { 0, 0 } // end-of-table identifier + +}; // posix_h_errno_table + +#endif // defined( _MBG_TGT_HAS_POSIX_H_ERRNO ) + + + +#if defined( MBG_TGT_CVI ) + +static ERRNO_CNV_ENTRY cvi_rs232_error_table[] = +{ + // { kRS_UnknownSysError, }, // Unknown system error. + // { kRS_InvalidPortNum, }, // In valid port number. + // { kRS_PortNotOpen, }, // Port is not open. + // { kRS_UnknownIOError, }, // Unknown I/O error. + // { kRS_InternalError, }, // Unexpected internal error. + // { kRS_NoPortFound, }, // No serial port found. + // { kRS_CanNotOpenPort, }, // Cannot open port. + // { kRS_NullPointerPassed, }, // A NULL pointer was passed when a non-NULL pointer was expected. + // { kRS_OutOfMemory, }, // Out of memory. + // { kRS_OutOfSystemResources, }, // Unable to allocate system resources. + // { kRS_InvalidParameter, }, // Invalid parameter. + // { kRS_InvalidBaudRate, }, // Invalid baud rate. + // { kRS_InvalidParity, }, // Invalid parity. + // { kRS_InvalidDataBits, }, // Invalid number of data bits. + // { kRS_InvalidStopBits, }, // Invalid number of stop bits. + // { kRS_BadFileHandle, }, // Bad file handle. + // { kRS_FileIOError, }, // File I/O error. + // { kRS_InvalidCount, }, // Invalid count; must be greater than or equal to 0. + // { kRS_InvalidIntLevel, }, // Invalid interrupt level. + // { kRS_IOTimeOut, }, // I/O operation timed out. + // { kRS_InvalidBreakTime, }, // Break time must be a positive value. + // { kRS_InvalidInQSize, }, // Requested input queue size must be 0 or greater. + // { kRS_InvalidOutQSize, }, // Requested output queue size must be 0 or greater. + // { kRS_GeneralIOFailure, }, // General I/O error. + // { kRS_InvalidBufferPointer, }, // Buffer parameter is NULL. + // { kRS_VISALibrariesMissing, }, // A necessary run-time library could not be found or loaded. + // { kRS_NoAckReceived, }, // Packet was sent, but no acknowledgment was received. + // { kRS_MaxRetriesBeforeSend, }, // Packet was not sent within retry limit. + // { kRS_MaxRetriesBeforeReceived, }, // Packet was not received within retry limit. + // { kRS_UnexpectedEOT, }, // End of transmission character encountered when start of data character expected. + // { kRS_CanNotReadPackNum, }, // Unable to read packet number. + // { kRS_InconsistentPackNum, }, // Inconsistent packet number. + // { kRS_CanNotReadPackData, }, // Unable to read packet data. + // { kRS_CanNotReadCheckSum, }, // Unable to read checksum. + // { kRS_CheckSumError, }, // Checksum received did not match computed checksum. + // { kRS_PackSizeGTInQ, }, // Packet size exceeds input queue size. + // { kRS_OpenFileError, }, // Error opening file. + // { kRS_ReadFileError, }, // Error reading file. + // { kRS_NoInitNegAck, }, // Did not receive initial negative acknowledgment character. + // { kRS_NoAckAfterEOT, }, // Did not receive acknowledgment after end of transmission character was sent. + // { kRS_WriteFileError, }, // Error writing to file. + // { kRS_NoSOHorEOT, }, // Did not receive either a start of data or end of transmission character when expected. + // { kRS_TransferCancelled, }, // Transfer was canceled because CAN ASCII character was received. + // { kRS_InvalidStartDelay, }, // Invalid start delay. + // { kRS_InvalidMaxTries, }, // Invalid maximum number of retries. + // { kRS_InvalidWaitPeriod, }, // Invalid wait period. + // { kRS_InvalidPacketSize, }, // Invalid packet size. + // { kRS_CanNotReadCRC, }, // Unable to read Cyclical Redundancy Check. + // { kRS_CRCError, }, // Cyclical Redundancy Check error. + { 0, 0 } // end-of-table identifier + +}; // cvi_rs232_error_table + +#endif // defined( MBG_TGT_CVI ) + + + +#if defined( MBG_TGT_WIN32 ) + +#if defined( MBG_TGT_KERNEL ) + +/** + * @brief Mappings of some NTSTATUS codes to Meinberg error codes. + * + * Kernel space Windows APIs use NTSTATUS codes as return values, + * which consist of several bit fields which also provide some severity + * and facility codes, similar to the message IDs used with text resources. + * The status codes and associated message texts are defined + * in the ntstatus.h file shipped with the various Windows DDKs. + * + * Please note that WIN32 user space API function return a different + * set of error codes on failure. See ::win32_sys_err_table. + * + * @see ::mbg_ioctl_to_ntstatus_table + * @see ::win32_kernel_status_table + * @see ::win32_sys_err_table + * @see ::win32_wsa_err_table + * @see @ref MBG_ERROR_CODES + */ +static ERRNO_CNV_ENTRY win32_kernel_status_table[] = +{ + { STATUS_INVALID_PARAMETER, MBG_ERR_INV_PARM, }, // 0xC000000DL, An invalid parameter was passed to a service or function. + { STATUS_INVALID_DEVICE_REQUEST, MBG_ERR_INV_DEV_REQUEST }, // 0xC0000010L, The specified request is not a valid operation for the target device. + { STATUS_DEVICE_BUSY, MBG_ERR_IRQ_UNSAFE }, // 0x80000011L, The device is currently busy. + { STATUS_NO_MEMORY, MBG_ERR_NO_MEM }, // 0xC0000017L, Not enough memory available to complete the specified operation. + { STATUS_NO_DATA_DETECTED, MBG_ERR_NOT_SUPP_BY_DEV }, // 0x80000022L, (normally used with tape access, but mis-used here) + { STATUS_ACCESS_DENIED, MBG_ERR_PERM }, // 0xC0000022L, A process has requested access to an object, but has not been granted those access rights. + { STATUS_IO_DEVICE_ERROR, MBG_ERR_IO }, // 0xC0000185L, The I/O device reported an I/O error. + + { STATUS_BUFFER_TOO_SMALL, MBG_ERR_BUFFER_TOO_SMALL }, // 0xC0000023L, The buffer is too small to contain the entry. No information has been written to the buffer. + // { STATUS_CANCELLED, }, // 0xC0000120L, The I/O request was canceled. + // { STATUS_DELETE_PENDING, }, // 0xC0000056L, A non close operation has been requested of a file object with a delete pending. + // { STATUS_DEVICE_CONFIGURATION_ERROR, }, // 0xC0000182L, The I/O device is configured incorrectly or the configuration parameters to the driver are incorrect. + { STATUS_DEVICE_NOT_READY, MBG_ERR_NOT_READY }, // 0xC00000A3L, The device (drive) is not ready for use. + // { STATUS_INSUFFICIENT_RESOURCES, }, // 0xC000009AL, Insufficient system resources exist to complete the API. + // { STATUS_MORE_PROCESSING_REQUIRED, }, // 0xC0000016L, The specified IRP cannot be disposed of because the I/O operation is not complete. + // { STATUS_NOT_IMPLEMENTED, }, // 0xC0000002L, The requested operation is not implemented. + // { STATUS_NOT_SUPPORTED, }, // 0xC00000BBL, The network request is not supported. + // { STATUS_NO_SUCH_DEVICE, }, // 0xC000000EL, A device which does not exist was specified. + // { STATUS_OBJECT_NAME_NOT_FOUND, }, // 0xC0000034L, Object Name not found. + // { STATUS_PENDING, }, // 0x00000103L, The operation that was requested is pending completion. + { STATUS_TIMEOUT, MBG_ERR_TIMEOUT }, // 0x00000102L, STATUS_TIMEOUT + // { STATUS_UNSUCCESSFUL, }, // 0xC0000001L, The requested operation was unsuccessful. + { 0, 0 } // end-of-table identifier + +}; // win32_kernel_status_table + + + +#if !_USE_WIN32_PRIVATE_STATUS_CODES + +/** + * @brief Windows IOCTL error conversion table. + * + * The IOCTL handler of a Meinberg kernel driver actually calls + * some Meinberg mbglib functions to access a device, and those + * functions normally return one of the @ref MBG_RETURN_CODES. + * + * However, when the Windows kernel calls the driver's IOCTL handler + * it expects an NTSTATUS code to be returned, so this table can be + * used in an IOCTL handler to map a Meinberg return code to a + * predefined NTSTATUS code that can be returned. + * + * To make things worse, Windows then remaps the NTSTATUS code to one + * of the WIN32 error codes when it passes the IOCTL results up to the + * user space function that submitted the IOCTL request. + * + * The user space function can then convert the returned code back + * to one of the @ref MBG_RETURN_CODES. + * + * For the mapping of NTSTATUS codes to WIN32 error codes + * done by Windows when it passes an IOCTL return code from kernel + * space to user space, see: + * https://support.microsoft.com/en-us/help/113996/info-mapping-nt-status-error-codes-to-win32-error-codes + * + * So care should be taken that the table entries here are defined + * such that in spite of the mnumerous conversions the same error code + * that was returned by a driver function is finally returned by the + * Meinberg user space API call. For example: + * + * - Driver function returns ::MBG_ERR_INV_PARM error. + * + * - Table ::mbg_ioctl_to_ntstatus_table is used to convert this to + * STATUS_INVALID_PARAMETER, which is returned by the IOCTL handler + * in kernel space. + * + * - Windows converts this to ERROR_INVALID_PARAMETER when it passes + * the error code up to user space. + * + * - The user space function uses ::win32_sys_err_table to convert this + * to a Meinberg error code, which again yields ::MBG_ERR_INV_PARM. + * + * @note It is possible to define custom NTSTATUS codes in kernel space, + * e.g. ((NTSTATUS) (0xC0000000 | 0x20000000 | 31)). + * Apparently, such custom error status codes are passed up to user space, + * and GetLastError() after the ioctl() call then returns a negative number, + * i.e. -31 for the example here. + * This had to be tested, though, and could be used to pass Meinberg error + * codes directly up to user space, without the need for a multiple conversion. + * However, there's no guarantee that this always works, and would still + * work in future Windows versions. + * + * @see ::win32_kernel_status_table + * @see ::win32_sys_err_table + * @see ::win32_wsa_err_table + * @see @ref MBG_ERROR_CODES + */ +static ERRNO_CNV_ENTRY mbg_ioctl_to_ntstatus_table[] = +{ + { MBG_ERR_INV_PARM, STATUS_INVALID_PARAMETER }, // ERROR_INVALID_PARAMETER + { MBG_ERR_INV_DEV_REQUEST, STATUS_INVALID_DEVICE_REQUEST }, // ERROR_BAD_COMMAND + { MBG_ERR_IRQ_UNSAFE, STATUS_DEVICE_BUSY }, // ERROR_BUSY + { MBG_ERR_NO_MEM, STATUS_NO_MEMORY }, // ERROR_NOT_ENOUGH_MEMORY + { MBG_ERR_NOT_SUPP_BY_DEV, STATUS_NO_DATA_DETECTED }, // ERROR_NO_DATA_DETECTED (mis-used here) + { MBG_ERR_PERM, STATUS_ACCESS_DENIED }, // ERROR_ACCESS_DENIED + { MBG_ERR_IO, STATUS_IO_DEVICE_ERROR }, // ERROR_IO_DEVICE + { 0, 0 } // end-of-table identifier + +}; // mbg_ioctl_to_ntstatus_table + +#endif // !_USE_WIN32_PRIVATE_STATUS_CODES + + +#else // Windows user space + +/** + * @brief Mappings of WIN32 error codes to Meinberg error codes. + * + * If a WIN32 user space API function encounters an error, + * the Windows GetLastError() function has to be called in + * most cases to retrieve an associated error code, which is + * a positive integer number. + * + * Existing error codes and associated message texts + * are defined in the WinError.h file shipped with the + * various SDKs and IDEs. + * + * Please note that Windows socket functions return a different + * set of error codes on failure, and WSAGetLastError() has to + * be called to retrieve the associated error code. + * See ::win32_wsa_err_table. + * + * @see ::win32_wsa_err_table + * @see ::mbg_ioctl_to_ntstatus_table + * @see ::win32_kernel_status_table + * @see @ref MBG_ERROR_CODES + */ +static ERRNO_CNV_ENTRY win32_sys_err_table[] = +{ + // Mappings for some Windows error codes defined in WinError.h + { ERROR_FILE_NOT_FOUND, MBG_ERR_NO_ENTITY }, // 2L: The system cannot find the file specified. + { 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, MBG_ERR_OVERFLOW }, // 111L: The file name is too long. + { ERROR_INSUFFICIENT_BUFFER, MBG_ERR_BUFFER_TOO_SMALL }, // 122L: The data area passed to a system call is too small. + { 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_sys_err_table + + + +/** + * @brief Mappings of Winsock error codes to Meinberg error codes. + * + * If a Windows socket (Winsock) function encounters an error, + * the Windows WSAGetLastError() function has to be called in + * most cases to retrieve an associated error code, which is + * a positive integer number. + * + * Existing error codes and associated message texts are + * defined in the Winsock2.h file shipped with the various + * SDKs and IDEs. + * + * Please note that the standard WIN32 API functions return a + * different set of error codes on failure, and GetLastError() + * has to be called to retrieve the associated error code. + * See ::win32_err_table. + * + * @see ::win32_sys_err_table + * @see ::mbg_ioctl_to_ntstatus_table + * @see ::win32_kernel_status_table + * @see @ref MBG_ERROR_CODES + */ +static ERRNO_CNV_ENTRY win32_wsa_err_table[] = +{ + { WSAEINTR, MBG_ERR_INTR }, // 10004L A blocking operation was interrupted by a call to WSACancelBlockingCall. + // { WSAEBADF // 10009L The file handle supplied is not valid. + // { WSAEACCES // 10013L An attempt was made to access a socket in a way forbidden by its access permissions. + { WSAEFAULT, MBG_ERR_BAD_ADDRESS }, // 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, 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. + // { WSAEDESTADDRREQ // 10039L A required address was omitted from an operation on a socket. + // { WSAEMSGSIZE // 10040L A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself. + // { WSAEPROTOTYPE // 10041L A protocol was specified in the socket function call that does not support the semantics of the socket type requested. + // { WSAENOPROTOOPT // 10042L An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call. + // { WSAEPROTONOSUPPORT // 10043L The requested protocol has not been configured into the system, or no implementation for it exists. + // { WSAESOCKTNOSUPPORT // 10044L The support for the specified socket type does not exist in this address family. + { WSAEOPNOTSUPP, MBG_ERR_OP_NOT_SUPP }, // 10045L The attempted operation is not supported for the type of object referenced. + // { WSAEPFNOSUPPORT // 10046L The protocol family has not been configured into the system or no implementation for it exists. + // { WSAEAFNOSUPPORT // 10047L An address incompatible with the requested protocol was used. + // { WSAEADDRINUSE // 10048L Only one usage of each socket address (protocol/network address/port) is normally permitted. + // { WSAEADDRNOTAVAIL // 10049L The requested address is not valid in its context. + // { WSAENETDOWN // 10050L A socket operation encountered a dead network. + // { WSAENETUNREACH // 10051L A socket operation was attempted to an unreachable network. + // { WSAENETRESET // 10052L The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress. + // { WSAECONNABORTED // 10053L An established connection was aborted by the software in your host machine. + { WSAECONNRESET, MBG_ERR_CONN_RESET }, // 10054L An existing connection was forcibly closed by the remote host. + // { WSAENOBUFS // 10055L An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. + // { WSAEISCONN // 10056L A connect request was made on an already connected socket. + // { WSAENOTCONN // 10057L A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. + // { WSAESHUTDOWN // 10058L A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call. + // { WSAETOOMANYREFS // 10059L Too many references to some kernel object. + // { WSAETIMEDOUT // 10060L A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. + // { WSAECONNREFUSED // 10061L No connection could be made because the target machine actively refused it. + // { WSAELOOP // 10062L Cannot translate name. + // { WSAENAMETOOLONG // 10063L Name component or name was too long. + // { WSAEHOSTDOWN // 10064L A socket operation failed because the destination host was down. + // { WSAEHOSTUNREACH // 10065L A socket operation was attempted to an unreachable host. + // { WSAENOTEMPTY // 10066L Cannot remove a directory that is not empty. + // { WSAEPROCLIM // 10067L A Windows Sockets implementation may have a limit on the number of applications that may use it simultaneously. + // { WSAEUSERS // 10068L Ran out of quota. + // { WSAEDQUOT // 10069L Ran out of disk quota. + // { WSAESTALE // 10070L File handle reference is no longer available. + // { WSAEREMOTE // 10071L Item is not available locally. + // { WSASYSNOTREADY // 10091L WSAStartup cannot function at this time because the underlying system it uses to provide network services is currently unavailable. + // { WSAVERNOTSUPPORTED // 10092L The Windows Sockets version requested is not supported. + { WSANOTINITIALISED, MBG_ERR_SOCK_INIT }, // 10093L Either the application has not called WSAStartup, or WSAStartup failed. + // { WSAEDISCON // 10101L Returned by WSARecv or WSARecvFrom to indicate the remote party has initiated a graceful shutdown sequence. + // { WSAENOMORE // 10102L No more results can be returned by WSALookupServiceNext. + // { WSAECANCELLED // 10103L A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. + // { WSAEINVALIDPROCTABLE // 10104L The procedure call table is invalid. + // { WSAEINVALIDPROVIDER // 10105L The requested service provider is invalid. + // { WSAEPROVIDERFAILEDINIT // 10106L The requested service provider could not be loaded or initialized. + // { WSASYSCALLFAILURE // 10107L A system call that should never fail has failed. + // { WSASERVICE_NOT_FOUND // 10108L No such service is known. The service cannot be found in the specified name space. + // { WSATYPE_NOT_FOUND // 10109L The specified class was not found. + // { WSA_E_NO_MORE // 10110L No more results can be returned by WSALookupServiceNext. + // { WSA_E_CANCELLED // 10111L A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. + // { WSAEREFUSED // 10112L A database query failed because it was actively refused. + { WSAHOST_NOT_FOUND, MBG_ERR_HOST_NOT_FOUND }, // 11001L No such host is known. + // { WSATRY_AGAIN // 11002L This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. + // { WSANO_RECOVERY // 11003L A non-recoverable error occurred during a database lookup. + // { WSANO_DATA // 11004L The requested name is valid, but no data of the requested type was found. + { 0, 0 } // end-of-table identifier + +}; // win32_wsa_err_table + +#endif // Windows user space + +#endif // defined( MBG_TGT_WIN32 ) + + + +static /*HDR*/ +/** + * @brief Lookup some error code in a conversion table. + * + * @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 @p dflt_val if original code not found in table. + */ +int lookup_tbl_errno( int srch_errno, const ERRNO_CNV_ENTRY tbl[], int dflt_val ) +{ + const ERRNO_CNV_ENTRY *p; + + for ( p = tbl; p->srch_errno || p->mapped_errno; p++ ) + if ( p->srch_errno == srch_errno ) + return p->mapped_errno; + + return dflt_val; + +} // 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, mbg_ioctl_to_ntstatus_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 + + + +/*HDR*/ +/** + * @brief Return an error string associated with the @ref MBG_ERROR_CODES. + * + * @param[in] mbg_errno One of the @ref MBG_ERROR_CODES. + * + * @return A constant string describing the error, or a generic string + * "Unknown error" for unknown error codes. + */ +const char *mbg_strerror( int mbg_errno ) +{ + static const MBG_CODE_NAME_TABLE_ENTRY tbl[] = MBG_ERR_STR_TABLE_ENG; + + const MBG_CODE_NAME_TABLE_ENTRY *p; + + for ( p = tbl; p->name; p++ ) + { + if ( mbg_errno == p->code ) + return p->name; + } + + return "Unknown error"; + +} // mbg_strerror + + + +#if !defined( _MBG_TGT_OMIT_ERR_MSG ) + +/*HDR*/ +/** + * @brief Check if a value is an error code and print an associated error message. + * + * @param[in] rc A positive number including ::MBG_SUCCESS, or one of the @ref MBG_ERROR_CODES. + * @param[in] what A string indicated what failed. + * + * @return @a true if @p rc represented an error code and a message has been printed, else @a false. + */ +bool mbg_cond_err_msg( int rc, const char *what ) +{ + return mbg_cond_err_msg_info( rc, what, NULL ); + +} // mbg_cond_err_msg + + + +/*HDR*/ +/** + * @brief Check if a value is a general or a "not supported" error code, and print an associated message. + * + * If @p rc contains an error code, an error message is printed. + * + * If the error code is ::MBG_ERR_NOT_SUPP_BY_DEV and the optional parameter + * string @p info is not @a NULL, a specific error message is generated. + * + * If @p rc contains a different error code, or the optional parameter + * string @p info is @a NULL, a generic error message is generated that + * includes the string from parameter @p what. + * + * @param[in] rc A positive number including ::MBG_SUCCESS, or one of the @ref MBG_ERROR_CODES. + * @param[in] what A string indicated what failed. + * @param[in] info An optional informational string telling what is not supported (may be @a NULL). + * + * @return @a true if @p rc represented any error code, and a message has been printed, else @a false. + */ +bool mbg_cond_err_msg_info( int rc, const char *what, const char *info ) +{ + if ( mbg_rc_is_error( rc ) ) + { + if ( info && ( rc == MBG_ERR_NOT_SUPP_BY_DEV ) ) + fprintf( stderr, "This device does not %s.\n", info ); + else + fprintf( stderr, "** %s failed: %s (rc: %i)\n", what, mbg_strerror( rc ), rc ); + + return true; + } + + return false; + +} // mbg_cond_err_msg_info + +#endif // !defined( _MBG_TGT_OMIT_ERR_MSG ) + + + +#if defined( MBG_TGT_CVI ) + +/*HDR*/ +/** + * @brief Translate an error code from the Labwindows/CVI RS-232 library to one of the @ref MBG_ERROR_CODES. + * + * @param[in] cvi_rc An error code returned by a CVI RS-232 library function. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + * + * @see http://zone.ni.com/reference/en-XX/help/370051V-01/cvi/libref/cvirs232_error_conditions/ + */ +int mbg_cvi_rs232_error_to_mbg( int cvi_rc, const char *info ) +{ + #if DEBUG + if ( info ) + fprintf( stderr, "%s, CVI RS-232 rc: %i\n", info, cvi_rc ); + #else + (void) info; // avoid compiler warning + #endif + + return ( cvi_rc < 0 ) ? lookup_tbl_errno( cvi_rc, cvi_rs232_error_table, MBG_ERR_UNKNOWN ) : MBG_SUCCESS; + +} // mbg_cvi_rs232_error_to_mbg + +#endif + + + +#if defined( MBG_TGT_WIN32 ) + +#if defined( MBG_TGT_KERNEL ) + +/*HDR*/ +/** + * @brief Translate a Windows NTSTATUS code to one of the @ref MBG_ERROR_CODES. + * + * @param[in] st One of the NTSTATUS codes defined in ntstatus.h. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ +int mbg_win32_ntstatus_to_mbg( NTSTATUS st, const char *info ) +{ + #if DEBUG + if ( info ) + _mbgddmsg_2( DEBUG, MBG_LOG_INFO, "%s, ntstatus: 0x%08lX\n", info, (long) st ); + #else + (void) info; // avoid compiler warning + #endif + + return lookup_tbl_errno( st, win32_kernel_status_table, MBG_ERR_UNKNOWN ); + +} // mbg_win32_ntstatus_to_mbg + + +#else // Windows user space + +/*HDR*/ +/** + * @brief Translate a Windows non-socket API return code to one of the @ref MBG_RETURN_CODES. + * + * @param[in] win32_sys_rc A Windows non-socket API error code as returned by @a GetLastError, or @a ERROR_SUCCESS. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_RETURN_CODES. + */ +int mbg_win32_sys_err_to_mbg( DWORD win32_sys_rc, const char *info ) +{ + int rc = MBG_SUCCESS; + + if ( win32_sys_rc == ERROR_SUCCESS ) + goto out; + + if ( win32_sys_rc & STATUS_CUSTOM_FLAG_MASK ) + { + // This is a user-defined error code or message ID, 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) ( win32_sys_rc & 0xFFFF ); + goto out; + } + +#if 0 // TODO FIXME + rc = (int) win32_sys_rc; + + if ( rc < 0 ) + { + // If the error code is negative, 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( win32_sys_rc, win32_sys_err_table, MBG_ERR_UNKNOWN ); + +out: + #if DEBUG + if ( info ) + fprintf( stderr, "%s, win32_sys_rc: 0x%08lX (%i) --> %i (%s)\n", + info, (long) win32_sys_rc, (int) win32_sys_rc, + rc, mbg_strerror( rc ) ); + #else + (void) info; // avoid compiler warning + #endif + + return rc; + +} // mbg_win32_sys_err_to_mbg + + + +/*HDR*/ +/** + * @brief Translate a Windows socket API error code to one of the @ref MBG_ERROR_CODES. + * + * @param[in] wsa_err A Windows socket API error code as returned by @a WSAGetLastError. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ +int mbg_win32_wsa_err_to_mbg( int wsa_err, const char *info ) +{ + #if DEBUG + if ( info ) + fprintf( stderr, "%s, wsa_err: %i\n", info, wsa_err ); + #else + (void) info; // avoid compiler warning + #endif + + // 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_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 defined( _MBG_TGT_HAS_POSIX_ERRNO ) + +/*HDR*/ +/** + * @brief Translate a POSIX errno error code to one of the @ref MBG_ERROR_CODES. + * + * @param[in] posix_errno A POSIX error code as usually defined in errno.h. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ +int mbg_posix_errno_to_mbg( int posix_errno, const char *info ) +{ + #if DEBUG && !defined( MBG_TGT_KERNEL ) + if ( info ) + fprintf( stderr, "%s: %s (errno: %i)\n", info, + strerror( posix_errno ), posix_errno ); + #else + (void) info; // avoid compiler warning + #endif + + return lookup_tbl_errno( posix_errno, posix_errno_table, MBG_ERR_UNKNOWN ); + +} // mbg_posix_errno_to_mbg + +#endif // defined( _MBG_TGT_HAS_POSIX_ERRNO ) + + + +#if defined( _MBG_TGT_HAS_POSIX_H_ERRNO ) + +/*HDR*/ +/** + * @brief Translate a POSIX h_errno error code to one of the @ref MBG_ERROR_CODES. + * + * This function is specific to translate error codes returned by + * @a gethostbyname and @a gethostbyaddr. In case of error these functions + * don't set @a errno but @a h_errno to a specific value. + * + * The functions @a gethostbyname and @a gethostbyaddr are obsolete, + * and @a getaddressinfo should be used preferably. + * + * @param[in] posix_h_errno An error code as usually defined in netdb.h. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ +int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info ) +{ + #if DEBUG && !defined( MBG_TGT_KERNEL ) + if ( info ) + fprintf( stderr, "%s: %s (h_errno: %i)\n", info, + hstrerror( posix_h_errno ), posix_h_errno ); + #else + (void) info; // avoid compiler warning + #endif + + return lookup_tbl_errno( posix_h_errno, posix_h_errno_table, MBG_ERR_UNKNOWN ); + +} // mbg_posix_h_errno_to_mbg + +#endif // defined( _MBG_TGT_HAS_POSIX_H_ERRNO ) + + + +#if !defined( _MBG_TGT_OMIT_LAST_ERROR ) + +/*HDR*/ +/** + * @brief Get and translate last error after non-socket function call. + * + * Retrieve the "last error" code after a non-socket function has been called + * and translate to one of the @ref MBG_ERROR_CODES. + * + * On POSIX systems the "last error" code is always stored in @a errno, but + * e.g. on Windows the "last error" code after a socket function + * has to be retrieved by calling @a WSAGetLastError, whereas the "last error" + * code from non-socket POSIX-like functions has to be retrieved + * by calling @a GetLastError. + * + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ +int mbg_get_last_error( const char *info ) +{ + #if defined( MBG_TGT_WIN32 ) + + // On Windows the "last error" code after a non-socket function + // ("Windows System Errors") has to be retrieved by calling GetLastError(), + // whereas the "last error" code from POSIX-like socket functions + // ("Windows Sockets Error Codes") has to be retrieved by calling + // WSAGetLastError(). + return mbg_win32_sys_err_to_mbg( GetLastError(), info ); + + #elif defined( MBG_TGT_POSIX ) + + // On POSIX systems the "last error" code is always stored in errno. + return mbg_posix_errno_to_mbg( errno, info ); + + #else + + // ### TODO #error This function is not supported for this target. + return mbg_posix_errno_to_mbg( errno, info ); + + #endif + +} // mbg_get_last_error + + + +#if !defined( _MBG_TGT_OMIT_SOCKET_ERRORS ) + +/*HDR*/ +/** + * @brief Get and translate last error after socket function call. + * + * Retrieve the "last error" code after a socket function has been called + * and translate to one of the @ref MBG_ERROR_CODES. + * + * On POSIX systems the "last error" code is always stored in @a errno, but + * e.g. on Windows the "last error" code after a socket function + * has to be retrieved by calling @a WSAGetLastError, whereas the "last error" + * code from non-socket POSIX-like functions is stored in @a errno as usual. + * + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ +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_UNKNOWN; + + #elif defined( MBG_TGT_WIN32 ) + + #if !defined( MBG_TGT_KERNEL ) + // On Windows the "last error" code after a POSIX-like socket + // function ("Windows Sockets Error Code") has to be retrieved + // by calling WSAGetLastError(), whereas the "last error" code + // after a non-socket function ("Windows System Errors") has + // to be retrieved by calling GetLastError(). + return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info ); + #else + return MBG_ERR_GENERIC; // TODO should we only work with NTSTATUS codes in kernel mode? + #endif + + #elif defined( MBG_TGT_POSIX ) + + // On POSIX systems the "last error" code is always stored in errno. + return mbg_posix_errno_to_mbg( errno, info ); + + #else + + #error This function is not supported for this target. + + #endif + +} // mbg_get_last_socket_error + + + +/*HDR*/ +/** + * @brief Retrieve and convert last error after gethostbyname(). + * + * This function is specific to retrieve and translate error codes + * returned by @a gethostbyname and @a gethostbyaddr. In case of error + * these functions don't set @a errno but @a h_errno on POSIX systems, + * but on Windows the error code can be retrieved by @a WSAGetLastError + * as usual. + * + * The functions @a gethostbyname and @a gethostbyaddr are obsolete, + * and @a getaddressinfo should be used preferably. + * + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ +int mbg_get_gethostbyname_error( const char *info ) +{ + #if defined( MBG_TGT_CVI ) + + #warning This needs to be implemented for CVI + return MBG_ERR_UNKNOWN; + + #elif defined( MBG_TGT_WIN32 ) + + #if !defined( MBG_TGT_KERNEL ) + return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info ); + #else + return MBG_ERR_GENERIC; + #endif + + #elif defined( MBG_TGT_POSIX ) + + return mbg_posix_h_errno_to_mbg( h_errno, info ); + + #else + + #error This function is not supported for this target. + + #endif + +} // mbg_get_gethostbyname_error + +#endif // !defined( _MBG_TGT_OMIT_SOCKET_ERRORS ) + +#endif // !defined( _MBG_TGT_OMIT_LAST_ERROR ) + + + +#if 0 // not yet finished +// error handler for getaddressinfo() +/* + * Handle specific error returned by getaddressinfo() + */ + /*HDR*/ +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_UNKNOWN; + + #elif defined( MBG_TGT_WIN32 ) + + return mbg_win32_wsa_err_to_mbg( WSAGetLastError(), info ); + + #elif defined( MBG_TGT_POSIX ) + + return mbg_posix_h_errno_to_mbg( h_errno, info ); + + #else + + return MBG_ERR_UNKNOWN; + + #endif + +} // mbg_get_gai_error + +#endif + + + +#if defined( USE_MBG_ZLIB ) + +/*HDR*/ +/** + * @brief Retrieve and convert last zlib internal error code. + * + * @param[in] zlib_error zlib internal error code. + * @param[in] info An optional informational text string, or @a NULL. + * @param[in] msg An optional zlib specific error msg, or @a NULL. + * Struct @a z_stream contains member msg. + * + * @return One of the @ref MBG_ERROR_CODES. + */ +int mbg_zlib_error_to_mbg( int zlib_error, const char *info, const char *msg ) +{ + #if DEBUG + if ( info && msg ) + fprintf( stderr, "%s: %s (zlib_error: %d)\n", info, + msg, zlib_error ); + #endif + + switch ( zlib_error ) + { + case Z_ERRNO: return mbg_get_last_error( info ); + case Z_MEM_ERROR: return MBG_ERR_NO_MEM; + /* + * All other zlib error codes are not specified any further. + * So, it's hard to guess what they mean and we return MBG_UNSPEC so far. + */ + default: + return MBG_ERR_UNKNOWN; + } + +} // mbg_zlib_error_to_mbg + +#endif // defined( USE_MBG_ZLIB ) + + diff --git a/mbglib/common/mbgerror.h b/mbglib/common/mbgerror.h new file mode 100644 index 0000000..fe97576 --- /dev/null +++ b/mbglib/common/mbgerror.h @@ -0,0 +1,980 @@ + +/************************************************************************** + * + * $Id: mbgerror.h 1.34 2021/12/01 15:51:25 martin.burnicki REL_M $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Common error codes used with Meinberg API calls. + * OS-specific error codes can be translated into these codes. + * + * ----------------------------------------------------------------------- + * $Log: mbgerror.h $ + * Revision 1.34 2021/12/01 15:51:25 martin.burnicki + * New error code MBG_ERR_OP_NOT_SUPP for EOPNOTSUPP and ENOTSUP. + * Revision 1.33 2021/11/03 16:57:02 martin.burnicki + * Added MBG_ERR_NOT_SUPP_BY_DRVR. + * Revision 1.32 2021/04/13 08:27:01 martin + * Updated some comments. + * Revision 1.31 2021/03/16 12:21:53 martin + * Updated some comments. + * Revision 1.30 2021/03/12 12:32:05 martin + * Updated some comments. + * Revision 1.29 2020/05/27 11:30:40 martin + * New NTP exit codes MBG_NTP_EXIT_FAIL_MEM and MBG_NTP_EXIT_FAIL_CRYPTO_API. + * Revision 1.28 2020/05/25 20:52:12 martin + * New NTP exit code MBG_NTP_EXIT_FAIL_TIMEOUT. + * Revision 1.27 2019/12/02 09:26:17 philipp + * Added MBG_ERR_NAME error code + * Revision 1.26 2019/11/11 10:10:10 martin + * Moved exit codes here that are used by NTP tools. + * Should be merged with other exit codes later. + * Revision 1.25 2019/10/09 09:31:04 philipp + * Added MBG_ERR_INV_USER and MBG_ERR_INV_GROUP + * Revision 1.24 2019/08/28 08:02:56 philipp + * Added error code MBG_ERR_IN_PROGRESS + * Revision 1.23 2019/08/26 15:14:34 martin + * Modified msg. text for MBG_ERR_NO_DATA. + * Revision 1.22 2019/08/20 08:20:04 martin + * Fixed build using mingw. + * Changed message text for MBG_ERR_ACCESS, which may also indicate that + * an exclusive resource is in use, not only that permissions are missing. + * Revision 1.21 2019/03/13 16:17:10 martin + * New code MBG_ERR_BAD_ADDRESS (for EFAULT). + * Revision 1.20 2019/03/13 09:44:30 martin + * Moved predefined program exit codes here. + * Revision 1.19 2019/02/08 10:42:56 martin + * Distinguish more detailed if an NTSTATUS replacement + * is required for a particular build environment. + * Revision 1.18 2018/11/22 11:25:56 martin + * New error code MBG_ERR_STR_SUBSTR merged from 1.15.1.x branch. + * Refactored surrogate definitions. + * Updated function prototypes. + * Revision 1.17 2018/09/21 09:49:57 martin + * Renamed MBG_ERR_FIFO to MBG_ERR_NO_DATA. + * Added strings for MBG_ERR_NO_DRIVER and MBG_ERR_DRV_VERSION. + * New code MBG_ERR_BUFFER_TOO_SMALL. + * MBG_ERR_OUTDATED error code added by philipp. + * Added some Windows stuff. + * Updated function prototypes. + * Revision 1.16 2018/06/25 14:26:38Z 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. + * Replaced old _mbg_err_to_os() macro by new inline functions + * mbg_errno_to_os() and mbg_ret_val_to_os(). + * Fixed build on Windows. + * Updated doxygen comments. + * Updated function prototypes. + * Revision 1.14 2017/05/10 15:21:39 martin + * Tiny cleanup. + * Revision 1.13 2017/02/28 15:23:14 gregoire + * error code MBG_ERR_INV_IDX added + * Revision 1.12 2017/01/10 15:54:56 philipp + * Fixed syntax error + * Revision 1.11 2017/01/10 14:26:31 philipp + * Added error MBG_ERR_NOT_CONFIGURED + * Revision 1.10 2016/12/16 12:40:33 thomas-b + * Added MBG_ERR_NO_SPACE + * Revision 1.9 2016/10/31 17:41:55 martin + * New error code MBG_ERR_DATA_FMT. + * Revision 1.8 2016/08/05 12:29:20 martin + * Re-enabled some symbols which have been commented out. + * Added new codes, and initializers for code/string conversion tables. + * Updated doxygen comments. + * Updated function prorotypes. + * Revision 1.7 2014/05/27 13:32:47Z martin + * Defined additional common error codes which can be + * translated from OS specific codes. + * Function prototypes from new module mbgerror.c. + * Comments in doxygen style. + * Revision 1.6 2012/10/02 18:42:26Z martin + * New codes MBG_ERR_N_POUT_EXCEEDS_SUPP and + * MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP. + * Modified comments for doxygen. + * Revision 1.5 2011/03/31 10:56:17 martin + * Added MBG_ERR_COPY_TO_USER and MBG_ERR_COPY_FROM_USER. + * Revision 1.4 2008/12/05 13:28:50 martin + * Added new code MBG_ERR_IRQ_UNSAFE. + * Revision 1.3 2008/02/26 14:50:14Z daniel + * Added codes: + * MBG_ERR_NOT_SUPP_ON_OS, MBG_ERR_LIB_NOT_COMPATIBLE, + * MBG_ERR_N_COM_EXCEEDS_SUPP, MBG_ERR_N_STR_EXCEEDS_SUPP + * Added doxygen compatible comments. + * Revision 1.2 2007/09/27 07:26:22Z martin + * Define STATUS_SUCCESS for Windows if not in kernel mode. + * Revision 1.1 2007/09/26 08:08:54Z martin + * Initial revision. + * + **************************************************************************/ + +#ifndef _MBGERROR_H +#define _MBGERROR_H + + +/* Other headers to be included */ + +#include <mbg_tgt.h> +#include <words.h> + +// We may need surrogate declarations for target-specific +// types that are used in common function prototypes. +// Without such declarations we'd get compiler errors +// on targets that don't have them. + +#if defined( MBG_TGT_WIN32 ) + + #if defined( MBG_TGT_KERNEL ) + + #define MBG_TGT_MISSING_DWORD 1 // Missing even in kernel space. + #define MBG_TGT_MISSING_NTSTATUS 0 // Available in kernel space + + #else // Windows user space + + #define MBG_TGT_MISSING_DWORD 0 // Available in user space. + + // Some (but not all) Windows build environments provide a + // bcrypt.h file which has a definition for NTSTATUS, so we + // use that if available to avoid duplicate / mismatching + // definitions in case an application uses bcrypt.h anyway. + #if !defined( MBG_TGT_HAS_BCRYPT_H ) // Unless already defined elsewhere. + #if defined( _MSC_VER ) && ( _MSC_VER >= 1500 ) // At least VS2008 has it. + #define MBG_TGT_HAS_BCRYPT_H 1 + #endif + + #if defined( MBG_TGT_MINGW ) // Mingw has it, too. + #define MBG_TGT_HAS_BCRYPT_H 1 + #endif + + #if !defined( MBG_TGT_HAS_BCRYPT_H ) // Other build environments may not have it. + #define MBG_TGT_HAS_BCRYPT_H 0 + #endif + #endif + + #if MBG_TGT_HAS_BCRYPT_H + #include <bcrypt.h> + #define MBG_TGT_MISSING_NTSTATUS 0 + #else + #define MBG_TGT_MISSING_NTSTATUS 1 + #endif + + #endif + +#else // Non-Windows targets. + + #define MBG_TGT_MISSING_DWORD 1 + #define MBG_TGT_MISSING_NTSTATUS 1 + +#endif + + +#ifdef _MBGERROR + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined( MBG_TGT_WIN32 ) + + #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 ) + +#define STATUS_SEVERITY_SUCCESS 0x0 +#define STATUS_SEVERITY_INFORMATIONAL 0x1 +#define STATUS_SEVERITY_WARNING 0x2 +#define STATUS_SEVERITY_ERROR 0x3 + +#define STATUS_SEVERITY_SHIFT_BITS 30 +#define STATUS_SEVERITY_SHIFT_MASK 0x03 + +#define STATUS_SEVERITY_SUCCESS_MASK ( STATUS_SEVERITY_SUCCESS << STATUS_SEVERITY_SHIFT_BITS ) +#define STATUS_SEVERITY_INFORMATIONAL_MASK ( STATUS_SEVERITY_INFORMATIONAL << STATUS_SEVERITY_SHIFT_BITS ) +#define STATUS_SEVERITY_WARNING_MASK ( STATUS_SEVERITY_WARNING << STATUS_SEVERITY_SHIFT_BITS ) +#define STATUS_SEVERITY_ERROR_MASK ( STATUS_SEVERITY_ERROR << STATUS_SEVERITY_SHIFT_BITS ) + +#define _get_win_msg_severity( _st ) ( ( (_st) >> STATUS_SEVERITY_SHIFT_BITS ) & STATUS_SEVERITY_SHIFT_MASK ) + + + +#define STATUS_CUSTOM_FLAG 0x1 + +#define STATUS_CUSTOM_FLAG_SHIFT_BITS 29 +#define STATUS_CUSTOM_FLAG_SHIFT_MASK 0x01 + +#define STATUS_CUSTOM_FLAG_MASK ( STATUS_CUSTOM_FLAG << STATUS_CUSTOM_FLAG_SHIFT_BITS ) + +#define _get_win_msg_custom_flag( _st ) ( ( (_st) >> STATUS_CUSTOM_FLAG_SHIFT_BITS ) & STATUS_CUSTOM_FLAG_SHIFT_MASK ) + +#define _win_msg_is_custom( _st ) ( _get_win_msg_custom_flag( _st ) != 0 ) + + +#define _mbg_msg_id_inf( num ) ((DWORD) ( STATUS_SEVERITY_INFORMATIONAL_MASK | STATUS_CUSTOM_FLAG_MASK | num ) ) +#define _mbg_msg_id_wrn( num ) ((DWORD) ( STATUS_SEVERITY_WARNING_MASK | STATUS_CUSTOM_FLAG_MASK | num ) ) +#define _mbg_msg_id_err( num ) ((DWORD) ( STATUS_SEVERITY_ERROR_MASK | STATUS_CUSTOM_FLAG_MASK | num ) ) + +#endif // defined( MBG_TGT_WIN32 ) + + + +#if MBG_TGT_MISSING_DWORD + typedef uint32_t DWORD; + #define DWORD DWORD +#endif + +#if MBG_TGT_MISSING_NTSTATUS + // We intentionally define an uncommon type to + // enforce build errors in case NTSTATUS is really + // used on targets that should not use it. + typedef int *NTSTATUS; + #define NTSTATUS NTSTATUS +#endif + + + +/** + * @defgroup MBG_RETURN_CODES Return codes used with Meinberg devices and drivers + * + * Appropriate error strings can be retrieved via the ::mbg_strerror function. + * + * @see ::MBG_ERR_STR_TABLE_ENG + * + * @{ */ + +/* FIXME TODO + * On 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 message IDs before the appropriate resource string + * can be retrieved. Actually this is done by taking the absolute number + * of an error code and have it or'ed with 0xE0000000 afterwards, e.g. + * ::MBG_ERR_GENERIC (-19) will yield Windows code 0xE0000013. + * * See ::_mbg_err_to_os + */ + +// NOTE: Some of these codes have to match codes which are defined in pcpsdefs.h +// and returned by the firmware of bus-level devices, so the definitions +// must *not* be renumbered. + +#define MBG_SUCCESS 0 ///< No error, has to match ::PCPS_SUCCESS. + + +/** + * @defgroup MBG_ERROR_CODES Error codes used with Meinberg devices and drivers + * + * @{ */ + +// 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). + + +// 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 has no valid time. +#define MBG_ERR_NO_DATA -24 ///< No (more) data to process, e.g. FIFO empty. +#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. + + +// Codes returned by the high level API functions +#define MBG_ERR_NO_MEM -27 ///< Failed to allocate memory. +#define MBG_ERR_CLAIM_RSRC -28 ///< Failed to claim port or mem resource. +#define MBG_ERR_DEV_NOT_SUPP -29 ///< 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 ///< Command or feature not supported by device. +// #define MBG_ERR_USB_ACCESS -32 ///< USB access failed (TODO This is B.S., we should return ***why***). +#define MBG_ERR_CYCLIC_TIMEOUT -33 ///< Cyclic event (IRQ, etc.) didn't occur in time. +#define MBG_ERR_NOT_SUPP_ON_OS -34 ///< Function is not supported on this operating system. +#define MBG_ERR_LIB_NOT_COMPATIBLE -35 ///< Installed shared library version not compatible with version used at build time. +#define MBG_ERR_N_COM_EXCEEDS_SUPP -36 ///< Number of COM ports of the device exceeds max. supported by driver. +#define MBG_ERR_N_STR_EXCEEDS_SUPP -37 ///< Number of string formats of the device exceeds max. supp. by driver. +#define MBG_ERR_IRQ_UNSAFE -38 ///< Enabled IRQ of bus-level device is unsafe with this firmware/ASIC version. +#define MBG_ERR_N_POUT_EXCEEDS_SUPP -39 ///< Num. prog. outputs of the device exceeds max. supp. by driver. + +// Legacy codes used with DOS TSRs only: +#define MBG_ERR_INV_INTNO -40 ///< Invalid interrupt number. +#define MBG_ERR_NO_DRIVER -41 ///< No driver could be found. +#define MBG_ERR_DRV_VERSION -42 ///< The driver is too old. + + +#define MBG_ERR_COPY_TO_USER -43 ///< Kernel driver failed to copy data from kernel to user space. +#define MBG_ERR_COPY_FROM_USER -44 ///< Kernel driver failed to copy data from use to kernel space. + + +// More codes returned by the driver's high level functions: +#define MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP -45 ///< Num. PTP unicast masters of the device exceeds max. supp. by driver. +#define MBG_ERR_N_GNSS_EXCEEDS_SUPP -46 ///< Num. of GNSS systems supp. by device exceeds max. supp. by driver. +#define MBG_ERR_N_GPIO_EXCEEDS_SUPP -47 ///< Num. of GPIO ports supp. by device exceeds max. supp. by driver. +#define MBG_ERR_N_XMR_EXCEEDS_SUPP -48 ///< Num. of XMR sources supp. by device exceeds max. supp. by driver. + +#define MBG_ERR_UNSPEC -60 ///< Unspecified error. + +#define MBG_ERR_HDR_CSUM -61 ///< Binary protocol header checksum error. +#define MBG_ERR_DATA_CSUM -62 ///< Binary protocol data checksum error. +#define MBG_ERR_RCVD_NACK -63 ///< Binary protocol received reply msg with a NACK code. +#define MBG_ERR_RCVD_NO_ACK -64 ///< Binary protocol received reply msg without expected ACK code. //### TODO +#define MBG_ERR_CONN_TYPE -65 ///< Binary protocol no valid/supported connection type specified. +#define MBG_ERR_BYTES_WRITTEN -66 ///< Binary protocol failed to write all bytes. +#define MBG_ERR_AUTH -67 ///< Binary protocol failed authentication. + +#define MBG_ERR_SOCK_INIT -68 ///< Socket interface not initialized, or failed to initialize. +#define MBG_ERR_INV_SOCK_FD -69 ///< Invalid socket when tried to open network socket. +#define MBG_ERR_NOT_A_SOCKET -70 ///< Socket descriptor is not a socket. +#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 ///< Input/output error. +#define MBG_ERR_INV_PARM -74 ///< Invalid parameter. +#define MBG_ERR_NO_DEV -75 ///< No such device, or 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 function call +#define MBG_ERR_ACCESS -80 ///< Access denied, e.g. to an object that is already in use, or in case of insufficient 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 +#define MBG_ERR_ENCRYPT -85 ///< encryption failed +#define MBG_ERR_DECRYPT -86 ///< decryption failed + +#define MBG_ERR_DISCONN -87 ///< connection closed by remote site / host +#define MBG_ERR_INV_CFG -88 ///< invalid/inconsistent configuration parameters read from device, see also ::MBG_ERR_CFG +#define MBG_ERR_RANGE -89 ///< input parameter was out of range + +#define MBG_ERR_INV_TLV_ANN_BYTES -90 ///< number of announced TLV bytes doesn't match number of transferred bytes +#define MBG_ERR_INV_TLV_SIZE -91 ///< ### TODO +#define MBG_ERR_INV_TLV_UID -92 ///< ### TODO + +#define MBG_ERR_EXIST -93 ///< File exists +#define MBG_ERR_DATA_SIZE -94 ///< the received data size toesn't match the expected data size +#define MBG_ERR_NO_ENTITY -95 ///< no such file or directory +#define MBG_ERR_ALREADY_ALLOC -96 ///< pointer already allocated when trying to allocate memory +#define MBG_ERR_HOST_NOT_FOUND -97 ///< host not found +#define MBG_ERR_CONN_RESET -98 ///< connection reset by peer +#define MBG_ERR_DATA_FMT -99 ///< invalid data format + +#define MBG_ERR_NO_SPACE -100 ///< insufficient disk space left on the device +#define MBG_ERR_NOT_CONFIGURED -101 ///< configuration option is not active/configured +#define MBG_ERR_INV_IDX -102 ///< invalid index value used + +#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 +#define MBG_ERR_BUFFER_TOO_SMALL -116 ///< Buffer is too small. + +#define MBG_ERR_OUTDATED -117 + +#define MBG_ERR_STR_SUBSTR -118 ///< Invalid substring in string +#define MBG_ERR_BAD_ADDRESS -119 ///< Bad Address (like POSIX EFAULT) + +#define MBG_ERR_IN_PROGRESS -120 ///< Long lasting operation in progress +#define MBG_ERR_INV_USER -121 ///< Invalid user +#define MBG_ERR_INV_GROUP -122 ///< Invalid group +#define MBG_ERR_NAME -123 ///< Invalid name + +#define MBG_ERR_NOT_SUPP_BY_DRVR -124 ///< Requested feature is not supported by the driver +#define MBG_ERR_OP_NOT_SUPP -125 ///< Requested operation is not supported + +// 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_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. + +/** @} anchor MBG_ERROR_CODES */ + +/** @} anchor 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_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" }, \ + { MBG_ERR_TIMEOUT, "Timeout" }, \ + { MBG_ERR_FW_ID, "Invalid firmware ID" }, \ + { MBG_ERR_NBYTES, "Unexpected number of data bytes for this API" }, \ + { MBG_ERR_INV_TIME, "The device has no valid time" }, \ + { MBG_ERR_NO_DATA, "No (more) data to process" }, \ + { MBG_ERR_NOT_READY, "Device not ready" }, \ + { MBG_ERR_INV_TYPE, "Unsupported data type" }, \ + { MBG_ERR_NO_MEM, "Memory allocation error" }, \ + { MBG_ERR_CLAIM_RSRC, "Faild to claim resources" }, \ + { MBG_ERR_DEV_NOT_SUPP, "Device not supported" }, \ + { MBG_ERR_INV_DEV_REQUEST, "Request not supported" }, \ + { MBG_ERR_NOT_SUPP_BY_DEV, "Not supported by device" }, \ + { MBG_ERR_CYCLIC_TIMEOUT, "Cyclic message timeout" }, \ + { MBG_ERR_NOT_SUPP_ON_OS, "Not supported by OS" }, \ + { MBG_ERR_LIB_NOT_COMPATIBLE, "Shared lib not compatible" }, \ + { MBG_ERR_N_COM_EXCEEDS_SUPP, "Num. COM ports exceeds supported" }, \ + { MBG_ERR_N_STR_EXCEEDS_SUPP, "Num. string formats exceeds supported" }, \ + { MBG_ERR_IRQ_UNSAFE, "Unsafe IRQ support" }, \ + { MBG_ERR_N_POUT_EXCEEDS_SUPP, "Num prog. outputs exceeds supported" }, \ + { MBG_ERR_INV_INTNO, "Invalid interrupt number" }, \ + { MBG_ERR_NO_DRIVER, "Driver not found" }, \ + { MBG_ERR_DRV_VERSION, "Driver too old" }, \ + { MBG_ERR_N_UC_MSTR_EXCEEDS_SUPP, "Num. PTP Unicast masters exceeds supported" }, \ + { MBG_ERR_N_GNSS_EXCEEDS_SUPP, "Num. GNSS systems exceeds supported" }, \ + { MBG_ERR_N_GPIO_EXCEEDS_SUPP, "Num. GPIO ports exceeds supported" }, \ + { MBG_ERR_N_XMR_EXCEEDS_SUPP, "Num. XMR sources exceeds supported" }, \ + { MBG_ERR_UNSPEC, "Unspecified error" }, \ + { MBG_ERR_HDR_CSUM, "Header checksum error" }, \ + { MBG_ERR_DATA_CSUM, "Data checksum error" }, \ + { MBG_ERR_RCVD_NACK, "Received NACK message" }, \ + { MBG_ERR_RCVD_NO_ACK, "Didn't receive ACK message" }, \ + { MBG_ERR_CONN_TYPE, "Invalid I/O connection type" }, \ + { MBG_ERR_BYTES_WRITTEN, "Failed to write all bytes" }, \ + { MBG_ERR_IO, "Input/output error" }, \ + { MBG_ERR_INV_PARM, "Invalid parameter passed to function" }, \ + { MBG_ERR_NO_DEV, "No such device, or attempted an inappropriate function." }, \ + { MBG_ERR_NOT_FOUND, "Specified item not found" }, \ + { MBG_ERR_OVERFLOW, "Buffer overflow" }, \ + { MBG_ERR_BUSY, "Device busy" }, \ + { MBG_ERR_INV_HANDLE, "Invalid handle" }, \ + { MBG_ERR_XBP_CASC_LVL, "Too many XBP cascading levels" }, \ + { MBG_ERR_ENCRYPT, "Encryption failed" }, \ + { MBG_ERR_DECRYPT, "Decryption failed" }, \ + { MBG_ERR_DISCONN, "Connection closed by remote site/host" }, \ + { MBG_ERR_INV_CFG, "Invalid/inconsistent configuration read from device" }, \ + { MBG_ERR_RANGE, "Input parameter was out of range" }, \ + { MBG_ERR_INV_TLV_ANN_BYTES, "TLV num of transferred bytes differs from num of announced bytes" }, \ + { MBG_ERR_INV_TLV_SIZE, "MBG_ERR_INV_TLV_SIZE" }, /* ### TODO */ \ + { MBG_ERR_INV_TLV_UID, "MBG_ERR_INV_TLV_UID" }, /* ### TODO */ \ + { MBG_ERR_DATA_SIZE, "Received data size mismatch" }, \ + { MBG_ERR_ALREADY_ALLOC, "Memory already allocated" }, \ + { MBG_ERR_DATA_FMT, "Invalid data format" }, \ + { 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" }, \ + { MBG_ERR_BUFFER_TOO_SMALL, "Data buffer too small" }, \ + { MBG_ERR_OUTDATED, "Software/Module is too old/outdated. Please update!" }, \ + { MBG_ERR_STR_SUBSTR, "Invalid substring in string" }, \ + { MBG_ERR_IN_PROGRESS, "Long lasting operation in progress" }, \ + { MBG_ERR_INV_USER, "Invalid user" }, \ + { MBG_ERR_INV_GROUP, "Invalid group" }, \ + { MBG_ERR_NAME, "Invalid name" }, \ + { MBG_ERR_NOT_SUPP_BY_DRVR, "Not supported by the driver" }, \ + { MBG_ERR_OP_NOT_SUPP, "Requested operation is not supported" } + + +/** + * @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_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" }, \ + { 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" }, \ + { MBG_ERR_BAD_ADDRESS, "Bad Address" } + +#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 */ \ +} + + + +#if defined( __mbg_inline ) + +static __mbg_inline +/** + * @brief Check if the code returned by a function indicates an error + * + * @param[in] rc One of the @ref MBG_RETURN_CODES + * + * @see ::mbg_rc_is_success + * @see @ref MBG_RETURN_CODES + */ +bool mbg_rc_is_error( int rc ) +{ + // 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 + * + * @param[in] rc One of the @ref MBG_RETURN_CODES + * + * @see ::mbg_rc_is_error + * @see @ref MBG_RETURN_CODES + */ +bool mbg_rc_is_success( int rc ) +{ + // There are functions which don't only return MBG_SUCCESS + // on success but some arbitrary positive number, e.g. the + // number of bytes sent. So success just means "not an error". + return !mbg_rc_is_error( rc ); + +} // mbg_rc_is_success + + + +static __mbg_inline +/** + * @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 + * + * @see ::mbg_rc_is_success + * @see @ref MBG_RETURN_CODES + */ +bool mbg_rc_is_success_or_err_perm( int rc ) +{ + return mbg_rc_is_success( rc ) || ( rc == MBG_ERR_PERM ); + +} // mbg_rc_is_success_or_err_perm + + +#else + + #define mbg_rc_is_error( _rc ) ( (_rc) < MBG_SUCCESS ) + #define mbg_rc_is_success( _rc ) ( !mbg_rc_is_error( _rc ) ) + + #define mbg_rc_is_success_or_err_perm( _rc ) ( mbg_rc_is_success( _rc ) || ( (_rc) == MBG_ERR_PERM ) ) + +#endif + + + +/** + * @brief Predefined exit codes returned by some tools. + * + * Should be merged with ::MBG_NTP_EXIT_CODES. + * + * @see ::MBG_NTP_EXIT_CODES + * @see ::MBG_NTP_EXIT_CODE_STRS + */ +enum MBG_EXIT_CODES +{ + MBG_EXIT_CODE_SUCCESS, ///< Requested action completed successfully. + MBG_EXIT_CODE_USAGE, ///< Unable to handle requested action, usage printed. + MBG_EXIT_CODE_NOT_SUPP, ///< Requested action not supported on the running OS. + MBG_EXIT_CODE_FAIL, ///< Action failed for specified device. + MBG_EXIT_CODE_INV_TIME, ///< Device has no valid time to set the system time with. + N_MBG_EXIT_CODES +}; + + + +/** + * @brief Predefined exit codes returned by some NTP tools. + * + * Should be merged with ::MBG_EXIT_CODES. + * + * @see ::MBG_NTP_EXIT_CODE_STRS + * @see ::MBG_EXIT_CODES + */ +enum MBG_NTP_EXIT_CODES +{ + MBG_NTP_EXIT_SUCCESS, // Success. + MBG_NTP_EXIT_FAIL_USAGE, // Usage printed, invalid parameter? + MBG_NTP_EXIT_FAIL_GENERIC, // General failure, unspecified. + MBG_NTP_EXIT_FAIL_DNS, // Host name lookup failed. + MBG_NTP_EXIT_FAIL_SOCKET, // Failed to open socket. + MBG_NTP_EXIT_FAIL_SEND, // Failed to send packet. + MBG_NTP_EXIT_FAIL_RECEIVE, // Failed to receive packet. + MBG_NTP_EXIT_FAIL_ENCRYPT, // Failed to encrypt a packet. + MBG_NTP_EXIT_FAIL_DECRYPT, // Failed to decrypt an encrypted packet. + MBG_NTP_EXIT_FAIL_CRYPT_NACK, // Failed because received a crypto NACK. + MBG_NTP_EXIT_FAIL_BIND, // Failed to bind to specific address or port. + MBG_NTP_EXIT_FAIL_TIMEOUT, // Timeout that shouldn't occur unless running at full speed. + MBG_NTP_EXIT_FAIL_MEM, // Out of memory. + MBG_NTP_EXIT_FAIL_CRYPTO_API, // Some crypto API call failed for unspecified reason. + N_MBG_NTP_EXIT_CODES +}; + + +/** + * @brief Info strings associated with predefined NTP tool exit codes. + * + * Should be merged with ::MBG_EXIT_CODES. + * + * @see ::MBG_NTP_EXIT_CODES + */ + +#define MBG_NTP_EXIT_CODE_STRS \ +{ \ + "Success", /* MBG_NTP_EXIT_OK */ \ + "Usage printed, e.g. invalid parameter.", /* MBG_NTP_EXIT_FAIL_USAGE */ \ + "Unspecified error.", /* MBG_NTP_EXIT_FAIL_GENERIC */ \ + "Host name lookup failed.", /* MBG_NTP_EXIT_FAIL_DNS */ \ + "Failed to open socket.", /* MBG_NTP_EXIT_FAIL_SOCKET */ \ + "Failed to send packet.", /* MBG_NTP_EXIT_FAIL_SEND */ \ + "Failed to receive packet.", /* MBG_NTP_EXIT_FAIL_RECEIVE */ \ + "Failed to encrypt a packet.", /* MBG_NTP_EXIT_FAIL_ENCRYPT */ \ + "Failed to decrypt an encrypted packet.", /* MBG_NTP_EXIT_FAIL_DECRYPT */ \ + "Received a crypto NACK.", /* MBG_NTP_EXIT_FAIL_CRYPT_NACK */ \ + "Failed to bind to specific address or port.", /* MBG_NTP_EXIT_FAIL_BIND */ \ + "Timeout.", /* MBG_NTP_EXIT_FAIL_TIMEOUT */ \ + "Unspecified crypto API error." /* MBG_NTP_EXIT_FAIL_CRYPTO_API */ \ +} + + + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* 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. + * + * @return A constant string describing the error, or a generic string + * "Unknown error" for unknown error codes. + */ + const char *mbg_strerror( int mbg_errno ) ; + + /** + * @brief Check if a value is an error code and print an associated error message. + * + * @param[in] rc A positive number including ::MBG_SUCCESS, or one of the @ref MBG_ERROR_CODES. + * @param[in] what A string indicated what failed. + * + * @return @a true if @p rc represented an error code and a message has been printed, else @a false. + */ + bool mbg_cond_err_msg( int rc, const char *what ) ; + + /** + * @brief Check if a value is a general or a "not supported" error code, and print an associated message. + * + * If @p rc contains an error code, an error message is printed. + * + * If the error code is ::MBG_ERR_NOT_SUPP_BY_DEV and the optional parameter + * string @p info is not @a NULL, a specific error message is generated. + * + * If @p rc contains a different error code, or the optional parameter + * string @p info is @a NULL, a generic error message is generated that + * includes the string from parameter @p what. + * + * @param[in] rc A positive number including ::MBG_SUCCESS, or one of the @ref MBG_ERROR_CODES. + * @param[in] what A string indicated what failed. + * @param[in] info An optional informational string telling what is not supported (may be @a NULL). + * + * @return @a true if @p rc represented any error code, and a message has been printed, else @a false. + */ + bool mbg_cond_err_msg_info( int rc, const char *what, const char *info ) ; + + /** + * @brief Translate an error code from the Labwindows/CVI RS-232 library to one of the @ref MBG_ERROR_CODES. + * + * @param[in] cvi_rc An error code returned by a CVI RS-232 library function. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + * + * @see http://zone.ni.com/reference/en-XX/help/370051V-01/cvi/libref/cvirs232_error_conditions/ + */ + int mbg_cvi_rs232_error_to_mbg( int cvi_rc, const char *info ) ; + + /** + * @brief Translate a Windows NTSTATUS code to one of the @ref MBG_ERROR_CODES. + * + * @param[in] st One of the NTSTATUS codes defined in ntstatus.h. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ + int mbg_win32_ntstatus_to_mbg( NTSTATUS st, const char *info ) ; + + /** + * @brief Translate a Windows non-socket API return code to one of the @ref MBG_RETURN_CODES. + * + * @param[in] win32_sys_rc A Windows non-socket API error code as returned by @a GetLastError, or @a ERROR_SUCCESS. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_RETURN_CODES. + */ + int mbg_win32_sys_err_to_mbg( DWORD win32_sys_rc, const char *info ) ; + + /** + * @brief Translate a Windows socket API error code to one of the @ref MBG_ERROR_CODES. + * + * @param[in] wsa_err A Windows socket API error code as returned by @a WSAGetLastError. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ + int mbg_win32_wsa_err_to_mbg( int wsa_err, const char *info ) ; + + /** + * @brief Translate a POSIX errno error code to one of the @ref MBG_ERROR_CODES. + * + * @param[in] posix_errno A POSIX error code as usually defined in errno.h. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ + int mbg_posix_errno_to_mbg( int posix_errno, const char *info ) ; + + /** + * @brief Translate a POSIX h_errno error code to one of the @ref MBG_ERROR_CODES. + * + * This function is specific to translate error codes returned by + * @a gethostbyname and @a gethostbyaddr. In case of error these functions + * don't set @a errno but @a h_errno to a specific value. + * + * The functions @a gethostbyname and @a gethostbyaddr are obsolete, + * and @a getaddressinfo should be used preferably. + * + * @param[in] posix_h_errno An error code as usually defined in netdb.h. + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ + int mbg_posix_h_errno_to_mbg( int posix_h_errno, const char *info ) ; + + /** + * @brief Get and translate last error after non-socket function call. + * + * Retrieve the "last error" code after a non-socket function has been called + * and translate to one of the @ref MBG_ERROR_CODES. + * + * On POSIX systems the "last error" code is always stored in @a errno, but + * e.g. on Windows the "last error" code after a socket function + * has to be retrieved by calling @a WSAGetLastError, whereas the "last error" + * code from non-socket POSIX-like functions has to be retrieved + * by calling @a GetLastError. + * + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ + int mbg_get_last_error( const char *info ) ; + + /** + * @brief Get and translate last error after socket function call. + * + * Retrieve the "last error" code after a socket function has been called + * and translate to one of the @ref MBG_ERROR_CODES. + * + * On POSIX systems the "last error" code is always stored in @a errno, but + * e.g. on Windows the "last error" code after a socket function + * has to be retrieved by calling @a WSAGetLastError, whereas the "last error" + * code from non-socket POSIX-like functions is stored in @a errno as usual. + * + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ + int mbg_get_last_socket_error( const char *info ) ; + + /** + * @brief Retrieve and convert last error after gethostbyname(). + * + * This function is specific to retrieve and translate error codes + * returned by @a gethostbyname and @a gethostbyaddr. In case of error + * these functions don't set @a errno but @a h_errno on POSIX systems, + * but on Windows the error code can be retrieved by @a WSAGetLastError + * as usual. + * + * The functions @a gethostbyname and @a gethostbyaddr are obsolete, + * and @a getaddressinfo should be used preferably. + * + * @param[in] info An optional informational text string, or @a NULL. + * + * @return One of the @ref MBG_ERROR_CODES. + */ + int mbg_get_gethostbyname_error( const char *info ) ; + + /** + * @brief Retrieve and convert last zlib internal error code. + * + * @param[in] zlib_error zlib internal error code. + * @param[in] info An optional informational text string, or @a NULL. + * @param[in] msg An optional zlib specific error msg, or @a NULL. + * Struct @a z_stream contains member msg. + * + * @return One of the @ref MBG_ERROR_CODES. + */ + int mbg_zlib_error_to_mbg( int zlib_error, const char *info, const char *msg ) ; + + +/* ----- function prototypes end ----- */ + + + +#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 + + +/* End of header body */ + +#undef _ext +#undef _DO_INIT + +#endif /* _MBGERROR_H */ diff --git a/mbglib/common/mbgtime.h b/mbglib/common/mbgtime.h new file mode 100644 index 0000000..a867f70 --- /dev/null +++ b/mbglib/common/mbgtime.h @@ -0,0 +1,1650 @@ + +/************************************************************************** + * + * $Id: mbgtime.h 1.47 2022/08/02 12:41:23 martin.burnicki REL_M $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Definitions and prototypes for mbgtime.c. + * + * ----------------------------------------------------------------------- + * $Log: mbgtime.h $ + * Revision 1.47 2022/08/02 12:41:23 martin.burnicki + * Fixed MJD_AT_NTP_EPOCH, which was erraneously the same + * as MJD_AT_POSIX_EPOCH. + * Revision 1.46 2021/03/16 12:20:48 martin + * Updated some comments. + * Revision 1.45 2021/03/12 12:32:51 martin + * Updated some comments. + * Revision 1.44 2021/03/11 16:08:01 martin + * Fixed some doxygen comments. + * Revision 1.43 2020/09/01 14:48:56 martin + * Fixed build with Borland C. + * Revision 1.42 2020/08/10 16:31:30Z martin + * Fixed 'long long' suffix for Windows builds. + * Revision 1.41 2019/11/27 11:21:39Z martin + * Renamed function n_days() to n_days_since_year_0() + * to make clearer what the function returns, and provided + * a backward-compatible inline function n_days(). + * Updated some doxygen comments. + * Revision 1.40 2019/11/27 11:14:39 martin + * Added definition POSIX_1970_INITIAL_DAY. + * Revision 1.39 2019/11/27 11:09:58 martin + * Added definitions of SMPTE epoch offsets from GPS epoch. + * Revision 1.38 2019/09/27 14:53:20 martin + * New define MONTHS_PER_YEAR. + * New types MBG_TIME32_T MBG_TIME32U_T. + * New inline function mbg_exp_year(). + * New inline functions normalize_gps_wn_dn() and de_normalize_gps_wn_dn(). + * New definitions for different types of leap second tables. + * New function is_valid_leap_second_date() and variants thereof. + * Updated function prototypes. + * Revision 1.37 2019/08/28 13:19:40 martin + * New structures MBG_TZ_INFO and MBG_LS_INFO which + * are used by some new functions in new module mbgtimex.c. + * Revision 1.36 2019/08/02 07:51:30 martin + * New type MBG_TIME64_T. + * Revision 1.35 2019/07/23 07:27:37 martin + * Added definition GPS_INITIAL_DAY. + * Revision 1.34 2019/07/19 08:39:19 martin + * Don't mark frac_sec_from_bin() as deprecated anymore. + * Revision 1.33 2019/07/19 07:49:22Z martin + * Modified dec_frac_to_bin_frac_{16,32} so that no compiler + * warning is emitted if a large data type is passed as an argument. + * Revision 1.32 2019/06/26 10:03:02Z martin + * Updated function prototypes. + * Revision 1.31 2019/02/06 10:08:09 martin + * Added symbol HNS_PER_MIN. + * Revision 1.30 2018/11/26 12:04:44Z martin + * Moved definition NTP_FRAC_PER_SEC here. + * Revision 1.29 2018/02/28 16:58:10 martin + * Removed reference to frac_sec_from_bin(). + * Revision 1.28 2018/01/15 18:18:49 martin + * Renamed symbol NSECS_PER_SEC to NSEC_PER_SEC. + * according to namings of similar symbols. + * Revision 1.27 2017/11/29 11:14:57 gregoire + * Added Multiplier MSEC_TO_NSEC_MULTIPLIER, MSEC_TO_USEC_MULTIPLIER. + * Revision 1.26 2017/11/16 13:33:46 philipp + * Added USEC_PER_SEC define. + * Revision 1.25 2017/08/15 15:48:59 martin + * Define NSECS_PER_SEC only if it hasn't been defined before. + * Revision 1.24 2017/07/04 14:02:25 martin + * Made definitions of some constants signed to avoid + * signed/unsigned compiler warnings. + * Moved some macros and inline functions for fraction + * conversion here. They are excluded from build in kernel + * mode, though, since some kernels don't support this properly. + * Moved some NANO_TIME- and NANO_TIME_64-related inline + * functions to new module nanotime.c. + * Renamed PCPS_HRT_BIN_FRAC_SCALE to MBG_FRAC32_UNITS_PER_SEC. + * Updated function prototypes. + * Doxygen stuff. + * Revision 1.23 2017/03/16 12:26:13 martin + * Updated function prototypes. + * Revision 1.22 2017/01/25 13:10:55 gregoire.diehl + * nano_time_64_to_double and double_to_nano_time_64 added + * Revision 1.21 2016/12/15 17:44:59Z martin + * Changed conditions to include time.h. + * Fixed spelling. + * Removed trailing spaces. + * Revision 1.20 2014/05/27 08:09:19 martin + * Added NTP_SEC_BIAS. + * Revision 1.19 2013/05/22 16:47:01 martin + * Added some useful macros. + * Revision 1.18 2012/10/02 18:51:11 martin + * Include <time.h> for WIN32 target and firmware only + * Fixed build on QNX, DOS, and FreeBSD. + * Revision 1.17 2010/08/06 13:03:03 martin + * Removed obsolete code. + * Revision 1.16 2010/07/16 10:22:07Z martin + * Moved definitions of HNS_PER_SEC and HNS_PER_MS here. + * Conditionally define FILETIME_1970. + * Defined MASK_CLOCK_T for ARM/Cortex. + * Revision 1.15 2009/10/23 09:55:21 martin + * Added MJD numbers for commonly used epochs. + * Revision 1.14 2009/08/12 10:28:12 daniel + * Added definition NSECS_PER_SEC. + * Revision 1.13 2009/06/12 13:31:44Z martin + * Fix build errors with arm-linux-gcc. + * Revision 1.12 2009/03/27 14:14:00 martin + * Cleanup for CVI. + * Revision 1.11 2009/03/13 09:30:06Z martin + * Include mystd.h in mbgtime.c rather than here. The bit type used + * here is now defined in words.h. + * Updated comments for GPS_SEC_BIAS. + * Revision 1.10 2008/12/11 10:45:41Z martin + * Added clock_t mask for gcc (GnuC). + * Revision 1.9 2006/08/25 09:33:46Z martin + * Updated function prototypes. + * Revision 1.8 2004/12/28 11:29:02Z martin + * Added macro _n_days. + * Updated function prototypes. + * Revision 1.7 2002/09/06 07:15:48Z martin + * Added MASK_CLOCK_T for Linux. + * Revision 1.6 2002/02/25 08:37:44 Andre + * definition MASK_CLOCK_T for ARM added + * Revision 1.5 2001/03/02 10:18:10Z MARTIN + * Added MASK_CLOCK_T for Watcom C. + * Revision 1.4 2000/09/15 07:57:53 MARTIN + * Removed outdated function prototypes. + * Revision 1.3 2000/07/21 14:05:18 MARTIN + * Defined some new constants. + * + **************************************************************************/ + +#ifndef _MBGTIME_H +#define _MBGTIME_H + + +/* Other headers to be included */ + +#include <gpsdefs.h> + +#if !defined( MBG_TGT_KERNEL ) || defined( MBG_TGT_WIN32 ) + #include <time.h> +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MBGTIME + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +/** + * @defgroup leap_second_fncs Meinberg leap second support functions + * + * By default, the date and time ***at the end of a leap second*** + * is referred to as <em>leap second date</em>. This is because: + * + * - At this point in time a new TAI offset comes into effect. + * + * - This is precise both in case of an inserted leap second (when the + * numbered seconds are counted 59, 60, 0) as well as for a deleted + * leap second (when the numbered seconds jump from 58 to 0, and + * there is no second numbered 59). + * + * - This complies with the leap second tables published by the + * International Earth Rotation and Reference Systems Service (IERS). + * + * So, for example, instead of 2016-12-31 23:59:59 we expect + * 2017-01-01 00:00:00 as a valid leap second date. + */ + +/** + * @defgroup leap_date_valid_fncs Meinberg functions that check if a leap second date is valid + * @ingroup leap_second_fncs + * + * For detailed hints, see @ref leap_second_fncs. + * + * Actually, only dates at the beginning of January or or July are + * considered valid leap second dates. There are several functions: + * + * @see ::is_valid_leap_second_date_tm A check function that expects a <em>struct tm</em> parameter. + * @see ::is_valid_leap_second_date_tm_gps A check function that expects a ::TM_GPS parameter. + * @see ::is_valid_leap_second_date A generic check function that expects day of month and month. + * + * @see @ref leap_second_fncs + */ + +/** + * @defgroup group_true_gps_wn_fncs Functions to determine a true leap second week number + * @ingroup leap_second_fncs + * + * The ::UTC::WNlsf field originally transmitted by the GPS satellites + * contains only the 8 LSBs of the full leap second week number, covering + * only a range of +/- ~128 weeks from the current week number. + * + * GPS receivers try to derive a full extended week number + * from this truncated week number. + * + * If the %UTC offset fields ::UTC::delta_tls and ::UTC::delta_tlsf + * are different, this means that a leap second is currently being + * announced, and thus the leap second week number is indeed in + * the range of +/- ~128 week of the current week, which means + * the week number can be unambiguously extended by the receiver. + * + * However, if ::UTC::delta_tls and ::UTC::delta_tlsf are the + * same, no leap second is announced, and it's not clear in + * which 256-week cycle the last leap second really occurred. + * These functions can be used to try to resolve this ambiguity, + * and, if possible, determine the true extended week number. + * + * The approach implemented here is based on a suggestion by + * Tom van Baak [[tvb@leapsecond.com]] on the leap seconds mailing + * list, and the fact that previous leap seconds were inserted only + * at the end of June/beginning of July, or end of December/beginning + * of January, and there are no plans to change this in the foreseeable + * future. + * + * The truncated week number is expanded for subsequent 256-week + * cycles, and if the extended week number and given day number + * yield a date that matches one of these well-known leap second + * dates, we have found the correct extended week number. + * + * A test has shown that there are unique results for 25 256-week + * cycles from 1980, i.e. until year 2099, if only leap seconds + * at the beginning of January or July are accepted. If the number of + * 256-week cycles is extended beyond 25 / year 2099, or if leap + * dates at the beginning of April or October are in addition taken + * into account, the results can be ambiguous, i.e. there + * can be more than one match. + * + * For example, both week numbers 1929 (0x0789, real week number) + * and 2185 (0x0889, off by 256 weeks) with correct day 7 yield + * the real leap second date 2017-01-01. + * + * @see ::mbg_find_true_gps_wn_lsf + * @see ::mbg_find_true_gps_wn_lsf_ex + * @see ::find_past_gps_wn_lsf_from_table + */ + + + +/** + * @defgroup group_timestamp_types Data types to store timestamps. + * + * Depending on the build and target environment, the original + * POSIX @a time_t type is usually 32 bits or 64 bits wide. + * If it is only 32 bits wide, timestamps will overflow in 2038. + * + * Using 64 bit types and associated time conversion functions + * avoid a rollover in 2038. + * + * Using a distinct 32 bit type can be useful for API calls which + * return 32 bit timestamps only, which may need to be mapped to + * an extended 64 bit range. + */ + +/** + * @brief A POSIX-like timestamp, 64 bits wide, signed. + * + * Negative numbers can represent times before the epoch. + * + * @ingroup group_timestamp_types + * @see @ref group_timestamp_types + */ +typedef int64_t MBG_TIME64_T; + + +/** + * @brief A POSIX-like timestamp, 32 bits wide, signed. + * + * Negative numbers can represent times before the epoch, + * but rolls over earlier than the unsigned type ::MBG_TIME32U_T. + * + * @ingroup group_timestamp_types + * @see @ref group_timestamp_types + */ +typedef int32_t MBG_TIME32_T; + + +/** + * @brief A POSIX-like timestamp, 32 bits wide, unsigned. + * + * No negative numbers, so times before the epoch + * can't be represented, but rolls over later + * than the signed type ::MBG_TIME32_T. + * + * @ingroup group_timestamp_types + * @see @ref group_timestamp_types + */ +typedef uint32_t MBG_TIME32U_T; + + + +/** + * @brief The number of days from 0000-01-01 until POSIX epoch 1970-01-01. + * + * The number of days as computed by ::n_days_since_year_0 for the + * POSIX time_t epoch, 1970-01-01, which was a Thursday. + * + * @see ::n_days_since_year_0 + */ +#define POSIX_1970_INITIAL_DAY 719162L + + + +/** + * @brief The number of days from 0000-01-01 until GPS epoch. + * + * The number of days as computed by ::n_days_since_year_0 for the + * date of the GPS epoch, 1980-01-06, which was a Sunday. + * + * @see ::n_days_since_year_0 + */ +#define GPS_INITIAL_DAY 722819L + + +/** + * @brief GPS epoch bias from ordinary POSIX time_t epoch. + * + * The POSIX time_t epoch is usually 1970-01-01 00:00:00, whereas + * the GPS epoch is 1980-01-06 00:00, so the difference is 10 years, + * plus 2 days due to leap years (1972 and 1976), plus the difference + * of the day-of-month (6 - 1), so:<br> + * + * time_t t = ( gps_week * ::SECS_PER_WEEK ) + sec_of_week + ::GPS_SEC_BIAS + */ +#define GPS_SEC_BIAS 315964800UL // ( ( ( 10UL * 365UL ) + 2 + 5 ) * SECS_PER_DAY ) + + +/** + * @brief NTP epoch bias from ordinary POSIX time_t epoch. + * + * The POSIX time_t epoch is usually 1970-01-01 00:00:00, whereas + * the NTP epoch is 1900-01-01 00:00:00, so the difference is + * a constant number of seconds:<br> + * + * time_t t = ntp_time - ::NTP_SEC_BIAS + */ +#define NTP_SEC_BIAS 2208988800UL + +#if !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + #define NTP_FRAC_PER_SEC (uint64_t) 4294967296.0 +#endif + + + +/** + * @defgroup group_smpte_epoch_offsets_gps Predefined SMPTE epoch offsets from GPS epoch + * + * With these constants, timestamps of the GPS time scale + * can be converted to a particular time scale used by SMPTE, + * e.g. to calculate a specific video frame number. + * + * @anchor MBG_SMPTE_EPOCH_OFFSETS + * @see ::MBG_GPIO_VIDEO_EPOCHS + * + * @{ */ + + +/** + * @brief SMPTE epoch offset from GPS to 1970-01-01T00:00:00 TAI. + * + * The total offset consists of the difference between GPS epoch + * and POSIX/UTC epoch (::GPS_SEC_BIAS), plus the constant offset + * between GPS time scale and TAI (::GPS_TAI_OFFSET). + * + * @note This is the standard epoch referred to + * by the PTP/IEEE1588 SMPTE extension. + * + * @see ::SMPTE_TAI_EPOCH_1970 + */ +#define SMPTE_GPS_OFFSET_TAI_1970 ( GPS_SEC_BIAS + GPS_TAI_OFFSET ) + + +/** + * @brief SMPTE epoch offset from GPS to 1958-01-01T00:00:00 TAI. + * + * The total offset consists of the difference between GPS epoch + * and POSIX/UTC epoch (::GPS_SEC_BIAS), plus 12 years since 1958, + * 3 of which were leap years that had an additional day, plus the + * constant offset between GPS time scale and TAI (::GPS_TAI_OFFSET). + * + * @note The TAI time scale didn't exist in 1958, and time scales were + * shifted/adjusted/aligned between 1958 and 1972, so this offset is just + * a hypothetic extrapolation into the past, which may be defined or + * implemented in different ways by different manufacturers or projects. + * + * @see ::SMPTE_TAI_EPOCH_1958 + */ +#define SMPTE_GPS_OFFSET_TAI_1958 ( GPS_SEC_BIAS + ( ( 12 * 365 + 3 ) * SECS_PER_DAY ) + GPS_TAI_OFFSET ) + + +/** + * @brief SMPTE epoch offset from GPS to 1972-01-01T00:00:00 UTC. + * + * The total offset consists of the difference between GPS epoch + * and POSIX/UTC epoch (::GPS_SEC_BIAS), minus 2 years until 1972, + * none of which were leap years that had an additional day. + * + * @see ::SMPTE_UTC_EPOCH_1972 + */ +#define SMPTE_GPS_OFFSET_UTC_1972 ( GPS_SEC_BIAS - ( ( 2 * 365 + 0 ) * SECS_PER_DAY ) ) + + +/** + * @brief SMPTE epoch offset from GPS to 1980-06-01T00:00:00 GPS. + * + * In this case the SMPTE epoch is the same as the GPS epoch, + * so the offset is 0. + * + * @see ::SMPTE_GPS_EPOCH_1980 + */ +#define SMPTE_GPS_OFFSET_GPS_1980 ( 0 ) + + +/** @} defgroup group_ptp_smpte_epoch_offsets_gps */ + + + +/** + * @defgroup group_mjd_numbers Modified Julian Day (MJD) numbers for some commonly used epochs + * + * To compute the MJD for a given date, just compute the days since epoch + * and add the constant number of days according to the epoch, e.g. for POSIX: + * + * current_unix_mjd = ( time( NULL ) / SECS_PER_DAY ) + MJD_AT_POSIX_EPOCH; + * + * @anchor MBG_MJD_NUMBERS + * + * @{ */ + +#define MJD_AT_GPS_EPOCH 44244UL ///< MJD at 1980-01-06 +#define MJD_AT_POSIX_EPOCH 40587UL ///< MJD at 1970-01-01 +#define MJD_AT_NTP_EPOCH 15020UL ///< MJD at 1900-01-01 + +/** @} defgroup group_mjd_numbers */ + + + +/** + * @brief The Windows FILETIME value at the usual POSIX epoch. + * + * The Windows @a FILETIME counts the number of 100 ns intervals + * since 1601-01-01, while the POSIX @a time_t epoch is usually + * (but not necessarily) 1970-01-01. + */ +#if !defined( FILETIME_1970 ) + // FILETIME represents a 64 bit number, so we need to defined the + // constant with an appendix depending on the compiler. + #if MBG_TGT_C99 || defined( __GNUC__ ) + // syntax introduced by C99 standard + #define FILETIME_1970 0x019db1ded53e8000ULL + #elif defined( MBG_TGT_WIN32 ) + // MSC-specific syntax + #define FILETIME_1970 0x019db1ded53e8000ui64 + #endif +#endif + + +#if defined( _C166 ) + #if _C166 >= 50 + #define MASK_CLOCK_T 0x7FFFFFFFL + #else + #define MASK_CLOCK_T 0x7FFF /* time.h not shipped with compiler */ + #endif +#endif + +#if defined( __WATCOMC__ ) + #define MASK_CLOCK_T 0x7FFFFFFFL +#endif + +#if defined( _CVI ) || defined( _CVI_ ) + #define MASK_CLOCK_T 0x7FFFFFFFL +#endif + +#if defined( _MSC_VER ) + #define MASK_CLOCK_T 0x7FFFFFFFL +#endif + +#if defined( __NETWARE_386__ ) + #define MASK_CLOCK_T 0x7FFFFFFFL +#endif + +#if defined( __ARM ) + #define MASK_CLOCK_T 0x7FFFFFFFL +#endif + +#if defined( __ARMCC_VERSION ) + #define MASK_CLOCK_T ( ( (ulong) (clock_t) -1 ) >> 1 ) +#endif + +#if defined( __GNUC__ ) + #if defined( __linux ) + #define MASK_CLOCK_T ( ( (ulong) (clock_t) -1 ) >> 1 ) + #else // Windows / MinGW + #define MASK_CLOCK_T 0x7FFFFFFFL + #endif +#endif + + +#if !defined( MASK_CLOCK_T ) + #if sizeof( clock_t ) == sizeof( short ) + #define MASK_CLOCK_T 0x7FFF + #elif sizeof( clock_t ) == sizeof( long ) + #define MASK_CLOCK_T 0x7FFFFFFFL + #endif +#endif + +typedef struct +{ + clock_t start; + clock_t stop; + short is_set; + +} TIMEOUT; + +#define MONTHS_PER_YEAR 12 + +#define DAYS_PER_WEEK 7 + +#define SECS_PER_MIN 60 +#define MINS_PER_HOUR 60 +#define HOURS_PER_DAY 24 +#define DAYS_PER_WEEK 7 + +#define MINS_PER_DAY ( MINS_PER_HOUR * HOURS_PER_DAY ) + +#define SECS_PER_HOUR 3600 +#define SECS_PER_DAY 86400L +#define SECS_PER_WEEK 604800L + +#define SEC100S_PER_SEC 100L +#define SEC100S_PER_MIN ( SEC100S_PER_SEC * SECS_PER_MIN ) +#define SEC100S_PER_HOUR ( SEC100S_PER_SEC * SECS_PER_HOUR ) +#define SEC100S_PER_DAY ( SEC100S_PER_SEC * SECS_PER_DAY ) + +#if !defined( MSEC_PER_SEC ) + #define MSEC_PER_SEC 1000L +#endif + +#define MSEC_PER_MIN ( MSEC_PER_SEC * SECS_PER_MIN ) +#define MSEC_PER_HOUR ( MSEC_PER_SEC * SECS_PER_HOUR ) +#define MSEC_PER_DAY ( MSEC_PER_SEC * SECS_PER_DAY ) + +#if !defined( USEC_PER_SEC ) + #define USEC_PER_SEC 1000000L +#endif + +#if !defined( NSEC_PER_SEC ) + #define NSEC_PER_SEC 1000000000L +#endif + +#if !defined( HNS_PER_SEC ) + #define HNS_PER_SEC 10000000L +#endif + +#if !defined( HNS_PER_MS ) + #define HNS_PER_MS 10000L +#endif + +#if !defined( HNS_PER_MIN ) + #define HNS_PER_MIN ( HNS_PER_SEC * SECS_PER_MIN ) +#endif + +#define MSEC_TO_NSEC_MULTIPLIER ( NSEC_PER_SEC / MSEC_PER_SEC ) +#define MSEC_TO_USEC_MULTIPLIER ( USEC_PER_SEC / MSEC_PER_SEC ) + + +/** + * @brief A table with the days of month + * + * First row is for standard years, second row is + * for leap years. + * + * @see DAYS_OF_MONTH_TABLE_INIT + */ +typedef char DAYS_OF_MONTH_TABLE[2][12]; + + +/** + * @brief An initializer for a ::DAYS_OF_MONTH_TABLE + */ +#define DAYS_OF_MONTH_TABLE_INIT \ +{ \ + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, \ + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } \ +} + + + + +_ext TM_GPS dhms; +_ext TM_GPS datum; + + +_ext const char *short_time_fmt +#ifdef _DO_INIT + = "%2i:%02i" +#endif +; + +_ext const char *time_fmt +#ifdef _DO_INIT + = "%2i:%02i:%02i" +#endif +; + +_ext const char *long_time_fmt +#ifdef _DO_INIT + = "%2i:%02i:%02i.%02i" +#endif +; + +_ext const char *date_fmt +#ifdef _DO_INIT + = "%2i.%02i.%04i" +#endif +; + +_ext const char *day_date_fmt +#ifdef _DO_INIT + = "%s, %2i.%02i.%04i" +#endif +; + +_ext const char *day_name_eng[] +#ifdef _DO_INIT + = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" } +#endif +; + +_ext const char *day_name_ger[] +#ifdef _DO_INIT + = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" } +#endif +; + +_ext const TM_GPS init_tm +#ifdef _DO_INIT + = { 1980, 1, 1, 0, 0, 0, 0, 0, 0, 0 } +#endif +; + + +_ext DAYS_OF_MONTH_TABLE days_of_month +#ifdef _DO_INIT + = DAYS_OF_MONTH_TABLE_INIT +#endif +; + + +// simplify call to n_days with structures +#define _n_days( _s ) \ + n_days_since_year_0( (_s)->mday, (_s)->month, (_s)->year ) + + +#define _is_leap_year( _y ) \ + ( ( ( ( (_y) % 4 ) == 0 ) && ( ( (_y) % 100 ) != 0 ) ) || ( ( (_y) % 400 ) == 0 ) ) + + +#define _get_days_of_month( _y, _m ) \ + days_of_month[ _is_leap_year( _y ) ][_m] + + + +static __mbg_inline /*HDR*/ +/** + * @brief Expand a 2-digit year-of-the-century to a full 4-digit year number. + * + * The resulting year number includes the century and is + * in the range [year_lim ... ( year_lim + 99 )]. + * + * @param[in] year The 2-digit year-of-the-century to be converted. + * + * @param[in] year_lim The smallest 4-digit year number to be returned. + * + * @return The resulting 4 digit year number including century. + */ +int mbg_exp_year( int year, int year_lim ) +{ + int lyear = year + year_lim - ( year_lim % 100 ); + + if ( lyear < year_lim ) + lyear += 100; + + return lyear; + +} // mbg_exp_year + + + +static __mbg_inline /*HDR*/ +/** + * @brief Normalize a GPS week number / day number pair. + * + * GPS navigation data may contain week number / day number pairs where + * the day number is in the range 1..7 rather than 0..6. For example, + * a known leap second date was sent with 1929|7 instead of 1930|0. + * + * To resolve this ambiguity in computations, this function can be used + * to normalize the wn|dn pair. + * + * The complementary function ::de_normalize_gps_wn_dn can be used + * to convert a wn|dn pair back to the common wn|dn format where the + * day number is in the range 1..7. + * + * @param[in,out] p_wn Address of a variable containing the week number. + * @param[in,out] p_dn Address of a variable containing the day number. + * + * @see ::de_normalize_gps_wn_dn + */ +void normalize_gps_wn_dn( GPS_WNUM *p_wn, GPS_DNUM *p_dn ) +{ + if ( *p_dn == 7 ) + { + *p_dn = 0; + (*p_wn)++; + } + +} // normalize_gps_wn_dn + + + +static __mbg_inline /*HDR*/ +/** + * @brief De-normalize a GPS week number / day number pair. + * + * GPS navigation data may contain week number / day number pairs where + * the day number is in the range 1..7 rather than 0..6. For example, + * a known leap second date was sent with 1929|7 instead of 1930|0. + * + * However, the function ::normalize_gps_wn_dn may have been called before + * to normalize the wn|dn pair to simplify computations. + * + * This function can be used to convert a wn|dn pair back to the common + * wn|dn format where the day number is in the range 1..7. + * + * @param[in,out] p_wn Address of a variable containing the week number. + * @param[in,out] p_dn Address of a variable containing the day number. + * + * @see ::normalize_gps_wn_dn + */ +void de_normalize_gps_wn_dn( GPS_WNUM *p_wn, GPS_DNUM *p_dn ) +{ + if ( *p_dn == 0 ) + { + *p_dn = 7; + (*p_wn)--; + } + +} // de_normalize_gps_wn_dn + + + +#if !defined( MBG_TGT_KERNEL ) + +/** + * @brief Data type used for intermediate results on 32 bit multiplications + * + * We need 64 bits for intermediate integer results to avoid a range overflow + * from 32 x 32 bit multiplications. On systems which don't support 64 bit types + * we use the "double" type as a workaround. + */ +#if defined( MBG_TGT_MISSING_64_BIT_TYPES ) + #define MBG_FRAC32_CONVERSION_TYPE double +#else + #define MBG_FRAC32_CONVERSION_TYPE int64_t +#endif + +/** + * @brief Constant used to convert e.g. ::PCPS_TIME_STAMP::frac values + * + * Max value of ::PCPS_TIME_STAMP::frac + 1, used for scaling + */ +#define MBG_FRAC32_UNITS_PER_SEC ( (MBG_FRAC32_CONVERSION_TYPE) 4294967296.0 ) // == 0x100000000 + + + +/** + * @brief DST on/off times pre-computed for a given year. + * + * Used like a cache to avoid redundant expensive computation + * of DST switching times for a given year inside an application. + * Not to be used for data exchange between devices. + * + * By default, switching times @a #t_on and @a #t_off are stored + * as local standard time (i.e. %UTC + @a #offs already applied) + * because this is most suitable for %UTC to local time conversions. + * + * However, for some cases (e.g. with PTP SMPTE) the switching + * times need to be compared to TAI times, so the function + * ::mbg_tz_info_to_tai can be used to convert the switching + * times to TAI. Care must be taken that the TAI switching times + * also need to be updated whenever a leap second event occurrs. + * + * @see ::mbg_set_tz_info_for_year + * @see ::mbg_set_tz_info_for_utc_time64_t + * @see ::mbg_tz_info_to_tai + */ +typedef struct +{ + MBG_TIME64_T t_on; ///< 'DST on' time, local standard time (default), or TAI. + MBG_TIME64_T t_off; ///< 'DST off' time, local standard time (default), or TAI. + int offs; ///< Offset to be added to %UTC to yield local standard time [sec]. + int offs_dl; ///< Additional offset to be added if daylight saving is in effect [sec]. + int year; ///< The year number for which @a #t_on and @a #t_off have been computed. + int auto_flag; ///< A flag indicating that @a #t_on and @a #t_off were computed by automatic rules. + int valid; ///< A flag indicating that the information in this structure has been set up. + +} MBG_TZ_INFO; + + + +/** + * @brief Current %UTC/TAI Offset And Leap Second Information. + * + * The stored information can be retrieved e.g. from the + * ::UTC data set transmitted by the GPS satellites, + * or from an NTP leap second file. + * + * @see ::mbg_set_ls_info_from_gps_utc + */ +typedef struct +{ + /// @brief Time of the nearest leap second, if available, in %UTC time scale. + /// Should match %UTC midnight at the end of the last day in June or December of a given year. + MBG_TIME64_T t64_ls_utc; + + /// @brief Time of the nearest leap second, if available, in TAI time scale. + /// Should be ahead of @a #t64_ls_utc by a number of leap seconds (~37 s in year 2019) + /// that have already been inserted in the past. + MBG_TIME64_T t64_ls_tai; + + /// @brief Number of seconds to be inserted into the %UTC time scale at the leap second transition. + /// This is 0 as long as no leap second announcement is currently available, +1 for a leap + /// second to be inserted, and -1 for a leap second to be deleted, which has yet never happened. + int ls_step; + + int offs_gps_utc; ///< Number of seconds the GPS system time is ahead of %UTC after the leap second transition. + + int offs_tai_utc; ///< Number of seconds TAI is ahead of %UTC after the leap second transition. + + int valid; ///< Indicates that the structure has been set up. + +} MBG_LS_INFO; + + + +/** + * @brief Entry of a leap second table providing timestamps and %UTC/TAI offsets. + * + * There are initializers that can be used to instantiate a table of entries. + * + * @see ::KNOWN_LEAP_SECOND_INFO_NTP + * @see ::KNOWN_LEAP_SECOND_INFO_POSIX + * @see ::LS_TABLE_ENTRY_GPS + */ +typedef struct +{ + /// Timestamp associated with ***the end*** of the leap second, + /// e.g. 2017-01-01 00:00:00 instead of 2016-12-31 23:59:59. + MBG_TIME64_T t_ls; + + /// Number of seconds that %UTC is ***behind*** TAI + /// after the given time. + int utc_tai_offs; + +} LS_TABLE_ENTRY; + + + +/** + * @brief Entry of a leap second table providing GPS timestamps and %UTC/GPS offsets. + * + * There is an initializer that can be used to instantiate a table of entries. + * + * ***Please note*** the table contains normalized wn|dn pairs like 1930|0, + * while the ::UTC info sent by the satellites could be 1929|7. So the wn|dn + * pairs from a GPS receiver should be normalized before being compared. + * + * @see ::KNOWN_LEAP_SECOND_INFO_GPS + * @see ::LS_TABLE_ENTRY + */ +typedef struct +{ + /// Extended GPS week number during which a leap second occurs. + GPS_WNUM wn; + + /// A day-of-week indicating when the leap second occurs. + /// Associated with ***the end*** of the leap second, + /// e.g. 2017-01-01 00:00:00 instead of 2016-12-31 23:59:59. + GPS_DNUM dn; + + /// Number of seconds that %UTC is ***behind*** GPS + /// after the given time. + int gps_tai_offs; + +} LS_TABLE_ENTRY_GPS; + + +#if defined( MBG_TGT_WIN32 ) && ( defined( _MSC_VER ) || defined( __BORLANDC__ ) ) + #define _ls_ntp_ts( _x ) ( _x ## i64 ) +#else + #define _ls_ntp_ts( _x ) ( _x ## LL ) +#endif + + +/** + * @brief Initializer for a table of known leap seconds, with NTP times. + * + * Can be used to initialize a table of ::LS_TABLE_ENTRY entries. + * Values have been copied and can be updated from an NTP leap second file. + * + * The table can be incomplete after another leap second has been scheduled, + * unless this initializer is updated. + * + * The first value is the number of seconds since the NTP epoch, 1900-01-01, + * and the second value indicates how many seconds %UTC is ***behind TAI*** + * after the given date. + * + * There is also an initializer which uses a POSIX time_t for the date, and + * another one where the date is specified by a GPS week number plus day number. + * + * @see ::LS_TABLE_ENTRY + * @see ::KNOWN_LEAP_SECOND_INFO_POSIX + * @see ::KNOWN_LEAP_SECOND_INFO_GPS + */ +#define KNOWN_LEAP_SECOND_INFO_NTP \ +{ \ + { _ls_ntp_ts( 2272060800 ), 10 }, /* 1 Jan 1972 */ \ + { _ls_ntp_ts( 2287785600 ), 11 }, /* 1 Jul 1972 */ \ + { _ls_ntp_ts( 2303683200 ), 12 }, /* 1 Jan 1973 */ \ + { _ls_ntp_ts( 2335219200 ), 13 }, /* 1 Jan 1974 */ \ + { _ls_ntp_ts( 2366755200 ), 14 }, /* 1 Jan 1975 */ \ + { _ls_ntp_ts( 2398291200 ), 15 }, /* 1 Jan 1976 */ \ + { _ls_ntp_ts( 2429913600 ), 16 }, /* 1 Jan 1977 */ \ + { _ls_ntp_ts( 2461449600 ), 17 }, /* 1 Jan 1978 */ \ + { _ls_ntp_ts( 2492985600 ), 18 }, /* 1 Jan 1979 */ \ + { _ls_ntp_ts( 2524521600 ), 19 }, /* 1 Jan 1980 */ \ + { _ls_ntp_ts( 2571782400 ), 20 }, /* 1 Jul 1981 */ \ + { _ls_ntp_ts( 2603318400 ), 21 }, /* 1 Jul 1982 */ \ + { _ls_ntp_ts( 2634854400 ), 22 }, /* 1 Jul 1983 */ \ + { _ls_ntp_ts( 2698012800 ), 23 }, /* 1 Jul 1985 */ \ + { _ls_ntp_ts( 2776982400 ), 24 }, /* 1 Jan 1988 */ \ + { _ls_ntp_ts( 2840140800 ), 25 }, /* 1 Jan 1990 */ \ + { _ls_ntp_ts( 2871676800 ), 26 }, /* 1 Jan 1991 */ \ + { _ls_ntp_ts( 2918937600 ), 27 }, /* 1 Jul 1992 */ \ + { _ls_ntp_ts( 2950473600 ), 28 }, /* 1 Jul 1993 */ \ + { _ls_ntp_ts( 2982009600 ), 29 }, /* 1 Jul 1994 */ \ + { _ls_ntp_ts( 3029443200 ), 30 }, /* 1 Jan 1996 */ \ + { _ls_ntp_ts( 3076704000 ), 31 }, /* 1 Jul 1997 */ \ + { _ls_ntp_ts( 3124137600 ), 32 }, /* 1 Jan 1999 */ \ + { _ls_ntp_ts( 3345062400 ), 33 }, /* 1 Jan 2006 */ \ + { _ls_ntp_ts( 3439756800 ), 34 }, /* 1 Jan 2009 */ \ + { _ls_ntp_ts( 3550089600 ), 35 }, /* 1 Jul 2012 */ \ + { _ls_ntp_ts( 3644697600 ), 36 }, /* 1 Jul 2015 */ \ + { _ls_ntp_ts( 3692217600 ), 37 }, /* 1 Jan 2017 */ \ + /* =============================== */ \ + /* If a new entry is added, don't */ \ + /* forget to update the tables */ \ + /* KNOWN_LEAP_SECOND_INFO_POSIX */ \ + /* and KNOWN_LEAP_SECOND_INFO_GPS */ \ + /* accordingly. */ \ + /* =============================== */ \ + { 0, 0 } /* end-of-table */ \ +} + + + +#define _ls_ntp_to_posix( _x ) ( _ls_ntp_ts( _x ) - NTP_SEC_BIAS ) + +/** + * @brief Initializer for a table of known leap seconds, with POSIX times. + * + * Can be used to initialize a table of ::LS_TABLE_ENTRY entries. Numeric + * values have been copied and can be updated from an NTP leap second file, + * and an appropriate macro is used to convert the NTP times to POSIX. + * + * The table can be incomplete after another leap second has been scheduled, + * unless this initializer is updated. + * + * The resulting first value is the number of seconds since the POSIX epoch, + * 1970-01-01, and the second value indicates how many seconds %UTC is + * ***behind TAI*** after the given date. + * + * There is also an initializer which uses an NTP time for the date, and + * another one where the date is specified by a GPS week number + * plus day number. + * + * @see ::LS_TABLE_ENTRY + * @see ::KNOWN_LEAP_SECOND_INFO_NTP + * @see ::KNOWN_LEAP_SECOND_INFO_GPS + */ +#define KNOWN_LEAP_SECOND_INFO_POSIX \ +{ \ + { _ls_ntp_to_posix( 2272060800 ), 10 }, /* 1 Jan 1972 */ \ + { _ls_ntp_to_posix( 2287785600 ), 11 }, /* 1 Jul 1972 */ \ + { _ls_ntp_to_posix( 2303683200 ), 12 }, /* 1 Jan 1973 */ \ + { _ls_ntp_to_posix( 2335219200 ), 13 }, /* 1 Jan 1974 */ \ + { _ls_ntp_to_posix( 2366755200 ), 14 }, /* 1 Jan 1975 */ \ + { _ls_ntp_to_posix( 2398291200 ), 15 }, /* 1 Jan 1976 */ \ + { _ls_ntp_to_posix( 2429913600 ), 16 }, /* 1 Jan 1977 */ \ + { _ls_ntp_to_posix( 2461449600 ), 17 }, /* 1 Jan 1978 */ \ + { _ls_ntp_to_posix( 2492985600 ), 18 }, /* 1 Jan 1979 */ \ + { _ls_ntp_to_posix( 2524521600 ), 19 }, /* 1 Jan 1980 */ \ + { _ls_ntp_to_posix( 2571782400 ), 20 }, /* 1 Jul 1981 */ \ + { _ls_ntp_to_posix( 2603318400 ), 21 }, /* 1 Jul 1982 */ \ + { _ls_ntp_to_posix( 2634854400 ), 22 }, /* 1 Jul 1983 */ \ + { _ls_ntp_to_posix( 2698012800 ), 23 }, /* 1 Jul 1985 */ \ + { _ls_ntp_to_posix( 2776982400 ), 24 }, /* 1 Jan 1988 */ \ + { _ls_ntp_to_posix( 2840140800 ), 25 }, /* 1 Jan 1990 */ \ + { _ls_ntp_to_posix( 2871676800 ), 26 }, /* 1 Jan 1991 */ \ + { _ls_ntp_to_posix( 2918937600 ), 27 }, /* 1 Jul 1992 */ \ + { _ls_ntp_to_posix( 2950473600 ), 28 }, /* 1 Jul 1993 */ \ + { _ls_ntp_to_posix( 2982009600 ), 29 }, /* 1 Jul 1994 */ \ + { _ls_ntp_to_posix( 3029443200 ), 30 }, /* 1 Jan 1996 */ \ + { _ls_ntp_to_posix( 3076704000 ), 31 }, /* 1 Jul 1997 */ \ + { _ls_ntp_to_posix( 3124137600 ), 32 }, /* 1 Jan 1999 */ \ + { _ls_ntp_to_posix( 3345062400 ), 33 }, /* 1 Jan 2006 */ \ + { _ls_ntp_to_posix( 3439756800 ), 34 }, /* 1 Jan 2009 */ \ + { _ls_ntp_to_posix( 3550089600 ), 35 }, /* 1 Jul 2012 */ \ + { _ls_ntp_to_posix( 3644697600 ), 36 }, /* 1 Jul 2015 */ \ + { _ls_ntp_to_posix( 3692217600 ), 37 }, /* 1 Jan 2017 */ \ + /* =================================================== */ \ + /* If a new entry is added, don't forget to update */ \ + /* the tables KNOWN_LEAP_SECOND_INFO_NTP and */ \ + /* KNOWN_LEAP_SECOND_INFO_GPS accordingly. */ \ + /* =================================================== */ \ + { 0, 0 } /* end-of-table */ \ +} + + + +#define _ls_ntp_to_gps( _x ) \ + ( ( _ls_ntp_ts( _x ) - NTP_SEC_BIAS - GPS_SEC_BIAS ) / SECS_PER_WEEK ), \ + ( ( ( _ls_ntp_ts( _x ) - NTP_SEC_BIAS - GPS_SEC_BIAS ) % SECS_PER_WEEK ) / SECS_PER_DAY ) + +#define _ls_utc_offs_to_gps( _x ) ( (_x) - GPS_TAI_OFFSET ) + +/** + * @brief Initializer for a table of known leap seconds, with GPS times. + * + * Can be used to initialize a table of ::LS_TABLE_ENTRY_GPS entries. Numeric + * values have been copied and can be updated from an NTP leap second file, + * and appropriate macros are used to convert the NTP times to GPS time. + * + * The table can be incomplete after another leap second has been scheduled, + * unless this initializer is updated. + * + * The resulting first value is an extended GPS week number, the second value + * is a day-of-week number, and the third value indicates how many seconds %UTC + * is ***behind GPS*** after the given date. + * + * ***Please note*** the resulting table does not include leap seconds before + * the GPS epoch, and it contains normalized wn|dn pairs like 1930|0, while + * the ::UTC info sent by the satellites could be 1929|7. So the dates from + * a GPS receiver should be normalized before being compared. + * + * There is also an initializer which uses an NTP time for the date, and + * another one where the date is specified by a POSIX time_t value. + * + * @see ::LS_TABLE_ENTRY + * @see ::KNOWN_LEAP_SECOND_INFO_NTP + * @see ::KNOWN_LEAP_SECOND_INFO_POSIX + */ +#define KNOWN_LEAP_SECOND_INFO_GPS \ +{ \ + { _ls_ntp_to_gps( 2571782400 ), _ls_utc_offs_to_gps( 20 ) }, /* 1 Jul 1981 */ \ + { _ls_ntp_to_gps( 2603318400 ), _ls_utc_offs_to_gps( 21 ) }, /* 1 Jul 1982 */ \ + { _ls_ntp_to_gps( 2634854400 ), _ls_utc_offs_to_gps( 22 ) }, /* 1 Jul 1983 */ \ + { _ls_ntp_to_gps( 2698012800 ), _ls_utc_offs_to_gps( 23 ) }, /* 1 Jul 1985 */ \ + { _ls_ntp_to_gps( 2776982400 ), _ls_utc_offs_to_gps( 24 ) }, /* 1 Jan 1988 */ \ + { _ls_ntp_to_gps( 2840140800 ), _ls_utc_offs_to_gps( 25 ) }, /* 1 Jan 1990 */ \ + { _ls_ntp_to_gps( 2871676800 ), _ls_utc_offs_to_gps( 26 ) }, /* 1 Jan 1991 */ \ + { _ls_ntp_to_gps( 2918937600 ), _ls_utc_offs_to_gps( 27 ) }, /* 1 Jul 1992 */ \ + { _ls_ntp_to_gps( 2950473600 ), _ls_utc_offs_to_gps( 28 ) }, /* 1 Jul 1993 */ \ + { _ls_ntp_to_gps( 2982009600 ), _ls_utc_offs_to_gps( 29 ) }, /* 1 Jul 1994 */ \ + { _ls_ntp_to_gps( 3029443200 ), _ls_utc_offs_to_gps( 30 ) }, /* 1 Jan 1996 */ \ + { _ls_ntp_to_gps( 3076704000 ), _ls_utc_offs_to_gps( 31 ) }, /* 1 Jul 1997 */ \ + { _ls_ntp_to_gps( 3124137600 ), _ls_utc_offs_to_gps( 32 ) }, /* 1 Jan 1999 */ \ + { _ls_ntp_to_gps( 3345062400 ), _ls_utc_offs_to_gps( 33 ) }, /* 1 Jan 2006 */ \ + { _ls_ntp_to_gps( 3439756800 ), _ls_utc_offs_to_gps( 34 ) }, /* 1 Jan 2009 */ \ + { _ls_ntp_to_gps( 3550089600 ), _ls_utc_offs_to_gps( 35 ) }, /* 1 Jul 2012 */ \ + { _ls_ntp_to_gps( 3644697600 ), _ls_utc_offs_to_gps( 36 ) }, /* 1 Jul 2015 */ \ + { _ls_ntp_to_gps( 3692217600 ), _ls_utc_offs_to_gps( 37 ) }, /* 1 Jan 2017 */ \ + /* ======================================================================== */ \ + /* If a new entry is added, don't forget to update the tables */ \ + /* KNOWN_LEAP_SECOND_INFO_NTP and KNOWN_LEAP_SECOND_INFO_POSIX */ \ + /* accordingly. */ \ + /* ======================================================================== */ \ + { 0, 0, 0 } /* end-of-tbl */ \ +} + + + +/** + * @brief Number of 256-week-cycles to check for true leap second week number. + * + * The number of 256-week-cycles to check in ::mbg_find_true_gps_wn_lsf + * or find_true_gps_wn_lsf (firmware version of the function), or when trying + * to resolve the ambiguity of the 8 bit truncated week number in ::UTC::WNlsf. + * + * According to some tests, the results are not ambiguous for 25 + * 256-week cycles after 1980 (i.e. until year 2099), if only + * leap second dates at the end of June / beginning of July or + * end of December / beginning of January are taken into account. + * + * @see ::mbg_find_true_gps_wn_lsf (Meinberg API) + * @see find_true_gps_wn_lsf (firmware version of ::mbg_find_true_gps_wn_lsf) + * @see ::ACCEPT_LS_APR_OCT + */ +#define N_GPS_WN_EPOCH 25 + + +#if !defined( ACCEPT_LS_APR_OCT ) + #define ACCEPT_LS_APR_OCT 0 + ///< Should be 0, otherwise ::mbg_find_true_gps_wn_lsf or + ///< find_true_gps_wn_lsf (firmware version of the function) + ///< may fail. + ///< See also ::N_GPS_WN_EPOCH +#endif + + + +/** + * @brief Convert a 16 bit binary fraction to a scaled decimal + * + * @param[in] bin The binary fraction + * @param[in] scale The scale factor + * + * @return The calculated number + * + * @see ::dec_frac_to_bin_frac_16 + * @see ::dec_frac_to_bin_frac_32 + * @see ::bin_frac_32_to_dec_frac + */ +static __mbg_inline /*HDR*/ +uint32_t bin_frac_16_to_dec_frac( uint16_t bin, uint32_t scale ) +{ + return (uint32_t) ( (MBG_FRAC32_CONVERSION_TYPE) bin * scale + / 0x10000UL ); + +} // bin_frac_16_to_dec_frac + + + +/** + * @brief Convert a 32 bit binary fraction to a scaled decimal + * + * @param[in] bin The binary fraction + * @param[in] scale The scale factor + * + * @return The calculated number + * + * @see ::dec_frac_to_bin_frac_32 + * @see ::dec_frac_to_bin_frac_16 + * @see ::bin_frac_16_to_dec_frac + */ +static __mbg_inline /*HDR*/ +uint32_t bin_frac_32_to_dec_frac( uint32_t bin, uint32_t scale ) +{ + return (uint32_t) ( (MBG_FRAC32_CONVERSION_TYPE) bin * scale + / MBG_FRAC32_UNITS_PER_SEC ); + +} // bin_frac_32_to_dec_frac + + + +#if !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + +// On targets which don't provide 64 bit data types +// MBG_FRAC32_CONVERSION_TYPE is defined as double, +// in which case the ">> 1" operation in the 2 functions +// below yields an "invalid use of floating point" error. +// This could probably be fixed by a different way of +// casting, at least for a partial expression. + +static __mbg_inline /*HDR*/ +uint16_t dec_frac_to_bin_frac_16( MBG_FRAC32_CONVERSION_TYPE dec, uint32_t scale ) +{ + return (uint16_t) ( ( ( dec * 0x20000 / scale ) + 1 ) >> 1 ); + +} // dec_frac_to_bin_frac_16 + + +static __mbg_inline /*HDR*/ +uint32_t dec_frac_to_bin_frac_32( MBG_FRAC32_CONVERSION_TYPE dec, uint32_t scale ) +{ + return (uint32_t) ( ( ( dec * MBG_FRAC32_UNITS_PER_SEC * 2 / scale ) + 1 ) >> 1 ); + +} // dec_frac_to_bin_frac_32 + +#endif // !defined( MBG_TGT_MISSING_64_BIT_TYPES ) + + + +#define bin_frac_32_to_msec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000L ) +#define bin_frac_32_to_usec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000000L ) +#define bin_frac_32_to_nsec( _bin ) bin_frac_32_to_dec_frac( (_bin), 1000000000L ) +#define bin_frac_16_to_msec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000L ) +#define bin_frac_16_to_usec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000000L ) +#define bin_frac_16_to_nsec( _bin ) bin_frac_16_to_dec_frac( (_bin), 1000000000L ) + + +#define msec_to_bin_frac_32( _msec ) dec_frac_to_bin_frac_32( (_msec), 1000L ) +#define usec_to_bin_frac_32( _usec ) dec_frac_to_bin_frac_32( (_usec), 1000000L ) +#define nsec_to_bin_frac_32( _nsec ) dec_frac_to_bin_frac_32( (_nsec), 1000000000L ) +#define msec_to_bin_frac_16( _msec ) dec_frac_to_bin_frac_16( (_msec), 1000L ) +#define usec_to_bin_frac_16( _usec ) dec_frac_to_bin_frac_16( (_usec), 1000000L ) +#define nsec_to_bin_frac_16( _nsec ) dec_frac_to_bin_frac_16( (_nsec), 1000000000L ) + + + +/** + * @brief Convert a binary fraction to a scaled decimal + * + * Convert a binary fraction (e.g. as in ::PCPS_TIME_STAMP::frac) + * to a decimal fraction, using a specified scale factor. Depending + * on the @p scale factor, the result can be milliseconds, microseconds, + * nanoseconds, or whatever. + * + * This function is actually just an alias for ::bin_frac_32_to_dec_frac, + * but has been introduced much erlier than the latter, and thus is kept + * for compatibility reasons. + * + * @param[in] b The binary fraction + * @param[in] scale The scale factor + * + * @return The calculated number + * + * @see ::bin_frac_32_to_dec_frac + */ +static __mbg_inline /*HDR*/ +uint32_t frac_sec_from_bin( uint32_t b, uint32_t scale ) +{ + return bin_frac_32_to_dec_frac( b, scale ); + +} // frac_sec_from_bin + + + +/** + * @brief Convert a binary fraction to "double" fractions + * + * Convert a binary fraction (e.g. of a second, as in ::PCPS_TIME_STAMP::frac) + * to a "double" with the units of seconds.<br> + * E.g. a 0xFFFFFFFF fraction yields 0.9999999999.... + * + * @note Excluded from build for kernel drivers which usually + * don't support floating point operations. + * + * @param[in] b The binary fraction + * + * @return The calculated fraction + * + * @see ::MBG_FRAC32_UNITS_PER_SEC + */ +static __mbg_inline /*HDR*/ +double dfrac_sec_from_bin( uint32_t b ) +{ + return (double) b / (double) MBG_FRAC32_UNITS_PER_SEC; + +} // dfrac_sec_from_bin + + + +static __mbg_inline /*HDR*/ +/** + * @brief Check if a particular date is a valid leap second date. + * + * This generic function expects a day of month, and a month. + * + * @param[in] mday The day of month of the date to be checked, range [1..31]. + * @param[in] month The month of the date to be checked, range [1..12]. + * + * @return @a true if considered valid, else @a false. + * + * @ingroup leap_date_valid_fncs + * @see @ref leap_date_valid_fncs + * @see ::is_valid_leap_second_date_tm_gps + * @see ::is_valid_leap_second_date_tm + */ +bool is_valid_leap_second_date( int mday, int month ) +{ + if ( mday != 1 ) + return false; + + if ( ( month == 1 ) || ( month == 7 ) ) // 1st of January or July + return true; + + #if ACCEPT_LS_APR_OCT + if ( ( month == 4 ) || ( month == 10 ) ) // 1st of April or October + return true; + #endif + + return false; + +} // is_valid_leap_second_date + + + +static __mbg_inline /*HDR*/ +/** + * @brief Check if a particular date in ::TM_GPS format is a valid leap second date. + * + * For detailed hints see @ref leap_date_valid_fncs and @ref leap_date_valid_fncs. + * + * This function expects a ::TM_GPS parameter and calls + * a generic function to actually check the date. + * + * @param[in] p_tm_gps The date to be checked, in ::TM_GPS format. + * + * @return @a true if considered valid, else @a false. + * + * @ingroup leap_date_valid_fncs + * @see @ref leap_date_valid_fncs + * @see ::is_valid_leap_second_date_tm + * @see ::is_valid_leap_second_date + */ +bool is_valid_leap_second_date_tm_gps( const TM_GPS *p_tm_gps ) +{ + return is_valid_leap_second_date( p_tm_gps->mday, p_tm_gps->month ); + +} // is_valid_leap_second_date_tm_gps + + + +static __mbg_inline /*HDR*/ +/** + * @brief Check if a particular date in <em>struct tm</em> format is a valid leap second date. + * + * We expect the date and time immediately ***after*** a leap second, + * i.e. when a new TAI offset becomes valid. For example, we expect + * 2017-01-01 00:00:00 instead of 2016-12-31 23:59:59. + * This should work for both inserted and deleted leap seconds. + * + * By default, only dates at the beginning of January or or July are + * considered valid. + * + * This function expects a <em>struct tm</em> parameter and calls + * a generic function to actually check the date. + * + * @param[in] p_tm The date to be checked, in <em>struct tm</em> format. + * + * @return @a true if considered valid, else @a false. + * + * @ingroup leap_date_valid_fncs + * @see @ref leap_date_valid_fncs + * @see ::is_valid_leap_second_date_tm_gps + * @see ::is_valid_leap_second_date + */ +bool is_valid_leap_second_date_tm( const struct tm *p_tm ) +{ + return is_valid_leap_second_date( p_tm->tm_mday, p_tm->tm_mon + 1 ); + +} // is_valid_leap_second_date_tm + + +#endif // !defined( MBG_TGT_KERNEL ) + + + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + + /** + * @brief Set a timeout object to specified interval + * + * @param[out] t The timeout object + * @param[in] clk The current time, in clock_t ticks + * @param[in] interval The interval until expiration, in clock_t ticks + */ + void set_timeout( TIMEOUT *t, clock_t clk, clock_t interval ) ; + + /** + * @brief Stretch a timeout specified in given timeout object + * + * @param[in,out] t The timeout object + * @param[in] interval The interval until expiration, in clock_t ticks + */ + void stretch_timeout( TIMEOUT *t, clock_t interval ) ; + + /** + * @brief Check if a timeout object has expired + * + * @param[in] t The timeout object + * @param[in] clk The current time, in clock_t ticks + * + * @return 1 if timeout expired, else 0 + */ + bit check_timeout( TIMEOUT *t, clock_t clk ) ; + + /** + * @brief Check if a ::TM_GPS structure contains a valid date and time + * + * @param[in] tm The date/time structure to be checked + * + * @return 0 if date/time is valid, else a negative number indicating + * which field was found invalid + */ + int err_tm( const TM_GPS *tm ) ; + + /** + * @brief Set the time in a ::TM_GPS structure to 00:00:00.000 + * + * @param[in,out] tm The date/time structure to be set + * + * @return Pointer to the ::TM_GPS structure that has been passed + */ + TM_GPS *clear_time( TM_GPS *tm ) ; + + /** + * @brief Convert second-of-week to day-of-week and time-of-day + * + * @param[in] wsec The second-of-week number to be converted. + * Must not be negative. + * @param[out] tm Address of a ::TM_GPS structure which takes + * the computed results. Updates the fields + * ::TM_GPS::hour, ::TM_GPS::min, ::TM_GPS::sec, + * and ::TM_GPS::wday in the range 0..6, with + * 0 = Sunday. + * + * @return Pointer to the ::TM_GPS structure that has been passed + * + * @see ::tm_to_wsec + * @see ::day_of_week_sun06 + */ + TM_GPS *wsec_to_tm( long wsec, TM_GPS *tm ) ; + + /** + * @brief Compute second-of-week from day-of-week and time-of-day + * + * @todo Specify input / output ranges + * + * @param[in] tm Address of a ::TM_GPS structure providing day-of-week and time-of-day + * + * @return The computed second-of-week number + * + * @see ::wsec_to_tm + */ + long tm_to_wsec( const TM_GPS *tm ) ; + + /** + * @brief Check if a specific year is a leap year + * + * @param[in] y The full year number + * + * @return != 0 if the year is a leap year, else 0 + */ + int is_leap_year( int y ) ; + + /** + * @brief Compute the day-of-year from a given date + * + * @param[in] day The day-of-month + * @param[in] month The month + * @param[in] year The full year number + * + * @return The computed day-of-year + */ + int day_of_year( int day, int month, int year ) ; + + /** + * @brief Compute a date from a given year and day-of-year + * + * @param[in] year The full year number + * @param[in] day_num Number of days from the beginning of that year, may be negative + * @param[out] tm Address of a ::TM_GPS structure which takes the computed results + */ + void date_of_year( int year, int day_num, TM_GPS *tm ) ; + + /** + * @brief Compute day-of-week for a given date. + * + * ATTENTION: The computed day-of-week is in the range 0..6, + * with 0 = Monday (!). + * + * In most cases the function ::day_of_week_sun06 is + * more suitable for applications. + * + * @param[in] day The day-of-month, 0..31 + * @param[in] month The month, 1..12 + * @param[in] year The full year number + * + * @return The computed day-of-week, 0..6, 0 = Monday (!) + * + * @see ::day_of_week_sun06 + * @see ::n_days_since_year_0 + */ + int day_of_week( int day, int month, int year ) ; + + /** + * @brief Compute day-of-week for a given date. + * + * The computed day-of-week is in the range 0..6, + * with 0 = Sunday, as expected by most applications. + * + * @param[in] day The day-of-month, 0..31 + * @param[in] month The month, 1..12 + * @param[in] year The full year number + * + * @return The computed day-of-week, 0..6, with 0 = Sunday. + * + * @see ::n_days_since_year_0 + * @see ::wsec_to_tm + */ + int day_of_week_sun06( int day, int month, int year ) ; + + /** + * @brief Update a year number by a number of days, accounting for leap years + * + * @param[in] day_num The number of days to evaluate + * @param[in] year The year number to start with + * + * @return The computed year number + */ + int days_to_years( long *day_num, int year ) ; + + /** + * @brief Compute number of days after Jan 1, 0000 for a given date + * + * @param[in] mday The day-of-month, [1..31] + * @param[in] month The month, [1..12]. + * @param[in] year The full year number, starting from year 0. + * + * @return The computed number of days + * + * @see ::day_of_week + */ + long n_days_since_year_0( int mday, int month, int year ) ; + + /** + * @brief Search a table of known past leap second dates for a specific week and day number. + * + * Optionally we return the latest week number we + * have found in the table, so an application can + * start there searching there for future potential + * leap second dates. + * + * @ingroup group_true_gps_wn_fncs + */ + int find_past_gps_wn_lsf_from_table( GPS_WNUM *p_wn, GPS_DNUM dn_t, int srch_all, GPS_WNUM *p_wn_last ) ; + + /** + * @brief Print time with hours, minutes, seconds to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ + int sprint_time( char *s, const TM_GPS *tm ) ; + + /** + * @brief Print time with hours, minutes to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ + int sprint_short_time( char *s, const TM_GPS *tm ) ; + + /** + * @brief Print date to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ + int sprint_date( char *s, const TM_GPS *tm ) ; + + /** + * @brief Print day-of-week and date to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ + int sprint_day_date( char *s, const TM_GPS *tm ) ; + + /** + * @brief Print day-of-week, date and time to a string + * + * @param[out] s Address of a string buffer to be filled + * @param[in] tm Address of a ::TM_GPS structure providing date and time + */ + int sprint_tm( char *s, const TM_GPS *tm ) ; + + /** + * @brief Extract a time from a string + * + * @param[in] s A time string in format hh:mm:ss + * @param[out] tm Address of a ::TM_GPS structure which takes the extracted time + */ + void sscan_time( const char *s, TM_GPS *tm ) ; + + /** + * @brief Extract a date from a string + * + * @param[in] s A date string in format dd.mm. or dd.mm.yyyy + * @param[out] tm Address of a ::TM_GPS structure which takes the extracted date + */ + void sscan_date( char *s, TM_GPS *tm ) ; + + +/* ----- function prototypes end ----- */ + + +static __mbg_inline /*HDR*/ +/** + * @brief Compute number of days after Jan 1, 0000 for a given date. + * + * @deprecated This function is deprecated. Use ::n_days_since_year_0 + * instead, which has a more meaningful name to avoid usage problems. + * + * @param[in] mday The day-of-month, [1..31] + * @param[in] month The month, [1..12]. + * @param[in] year The full year number, starting from year 0. + * + * @return The computed number of days + * + * @see ::day_of_week + */ +long _DEPRECATED_BY( "n_days_since_year_0" ) n_days( int mday, int month, int year ) +{ + return n_days_since_year_0( mday, month, year ); + +} // n_days + + +/* End of header body */ + + +#undef _ext +#undef _DO_INIT + +#ifdef __cplusplus +} +#endif + + +#endif /* _MBGTIME_H */ diff --git a/mbglib/common/str_util.c b/mbglib/common/str_util.c new file mode 100644 index 0000000..e83d291 --- /dev/null +++ b/mbglib/common/str_util.c @@ -0,0 +1,477 @@ + +/************************************************************************** + * + * $Id: str_util.c 1.13 2022/12/21 15:31:56 martin.burnicki REL_M $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Meinberg Library module providing portable, safe string functions. + * + * ----------------------------------------------------------------------- + * $Log: str_util.c $ + * Revision 1.13 2022/12/21 15:31:56 martin.burnicki + * Removed some obsolete _int_from_size_t() stuff. + * Fixed some other size_t/int mismatch. + * Revision 1.12 2022/08/26 15:01:49 martin.burnicki + * Updated a doxygen comment and fixed a typo in an older commit message. + * Revision 1.11 2021/03/22 11:28:52 martin + * Updated some comments. + * Revision 1.10 2021/03/16 12:20:37 martin + * Updated some comments. + * Revision 1.9 2021/03/12 12:32:24 martin + * Updated some comments. + * Revision 1.8 2021/03/12 11:00:26 martin + * Updated some doxygen comments. + * Revision 1.7 2019/11/27 10:37:33 martin + * Tiny code style fixes. + * Revision 1.6 2019/07/31 15:42:38 martin + * Doxygen changes. + * Revision 1.5 2018/08/23 13:07:16 martin + * Moved the snprintf() safety checks to new inline functions that + * can also be used called from specific kernel mode functions. + * Unified variable naming. + * More common __attribute__ syntax. + * Revision 1.4 2018/06/25 13:22:42 martin + * Many functions 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 + * New functions mbg_memcpy() and mbg_memcpy_reversed(). + * Moved string trim functions from cfg_util module here. + * Fixed some compiler warnings. + * Revision 1.1 2015/08/25 15:57:21 martin + * Initial revision. + * + **************************************************************************/ + +#define _STR_UTIL + #include <str_util.h> +#undef _STR_UTIL + +#include <stdio.h> +#include <string.h> + + +#if defined( MBG_TGT_WIN32 ) && !defined( MBG_TGT_CVI ) + #define mbg_vsnprintf _vsnprintf +#else + #define mbg_vsnprintf vsnprintf +#endif + + +#if defined( MBG_TGT_DOS ) + +static /*HDR*/ +// On DOS, we use the Borland C/C++ v3.1 compiler by default, which +// doesn't provide a vsnprintf() function, so we use a simple replacement +// here. Since we share most of the source code between several target +// systems, we assume that if our code works properly for other targets +// which really provide a vsnprintf() function, it also works properly +// on DOS. ;-) +int vsnprintf( char *s, size_t max_len, const char *fmt, va_list args ) +{ + (void) max_len; // Quiet compiler warning "not used". + + return vsprintf( s, fmt, args ); + +} // vsnprintf + +#endif + + + +/*HDR*/ +/** + * @brief A portable, safe implementation of vsnprintf(). + * + * Unfortunately, the behavior of @a vsnprintf and therefore also that + * of @a snprintf differs in detail in different build environments + * and runtime libraries. + * + * If the output exceeds the buffer size and thus is truncated, then:<br> + * + * - On Windows, a negative value is returned and maybe ***no*** + * terminating 0 is written to the output buffer, so the output string + * may not be terminated properly. + * + * - Some versions of glibc return the number of bytes that ***would*** + * have been written to the buffer ***if*** the buffer would have been + * large enough, instead of the true number of characters that have + * been written to the buffer. + * + * So subsequent calls like + * + * @code{.c} + n = snprintf( s, max_len, ... ); + n += snprintf( &s[n], max_len - n, ... ); + * @endcode + * + * may always work properly, or fail with buffer overruns or stack + * corruption depending on the build environment. + * This wrapper function takes care that strings are always terminated + * properly, and that the returned value always matches the number of + * characters really written to the string buffer, excluding the + * terminating 0. + * + * @note The @a size_t type parameter used to specify the buffer size + * can be larger (e.g. @a unsigned_long) than the @a int type returned + * by mostly all functions of the @a printf family. So if a very large + * buffer is specified, and a large number of characters (more than + * @a INT_MAX) are written to that buffer, how can an @a int type + * return the large number of characters written to the buffer? + * We also try to workaround this here. + * + * @param[out] s The string buffer to be filled. + * @param[in] max_len Size of the output buffer for a 0-terminated string. + * @param[in] fmt Format string according to subsequent parameters. + * @param[in] args Variable argument list in @a va_list format. + * + * @return The number of characters written to the output buffer, + * except the terminating 0. + * + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ +__attribute__( ( format( printf, 3, 0 ) ) ) +int vsnprintf_safe( char *s, ssize_t max_len, const char *fmt, va_list args ) +{ + int n; + + if ( !mbg_buffer_specs_valid( s, max_len ) ) + return 0; // Nothing to do anyway. + + n = mbg_vsnprintf( s, max_len, fmt, args ); + + // Do some common checks to avoid subsequent buffer overflows, etc. + return mbg_chk_snprint_results( n, s, max_len ); + +} // vsnprintf_safe + + + +/*HDR*/ +/** + * @brief A portable, safe implementation of snprintf(). + * + * For a detailed description see ::vsnprintf_safe. + * + * @param[out] s The string buffer to be filled. + * @param[in] max_len Size of the output buffer for a 0-terminated string. + * @param[in] fmt Format string according to subsequent parameters. + * @param[in] ... Variable argument list according to the @p fmt format string. + * + * @return The number of characters written to the output buffer, + * except the terminating 0. + * + * @see ::vsnprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ +__attribute__( ( format( printf, 3, 4 ) ) ) +int snprintf_safe( char *s, ssize_t max_len, const char *fmt, ... ) +{ + va_list args; + int len; + + va_start( args, fmt ); + len = vsnprintf_safe( s, max_len, fmt, args ); + va_end( args); + + return len; + +} // snprintf_safe + + + +static __mbg_inline /*HDR*/ +/* (explicitly excluded from doxygen) + * @brief A portable, safe implementation of a copy function. + * + * This is the basic function used to implemment ::strncpy_safe and + * ::sn_cpy_safe. This function takes care that the copied string + * is always terminated by 0, but any remaining buffer space + * is ***not*** filled up with '0' characters. + * + * @param[out] dst Pointer to the output buffer. + * @param[in] src Pointer to the input buffer. + * @param[in] n Number of characters to copy at most. + * @param[in,out] p_i Pointer to a counter variable. + * + * @return The number of characters written to the output buffer, + * except the terminating 0. + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ +int do_str_copy_safe( char *dst, const char *src, ssize_t n ) +{ + int i = 0; + + if ( n > 0 ) + { + for (;;) + { + *dst = *src; + + if ( *dst == 0 ) + break; // Just copied the terminating 0, done. + + if ( ( --n == 0 ) // No more space left in buffer. + || ( i == INT_MAX ) ) // Reached the limit we can handle. + { + *dst = 0; // Force terminating 0. + break; + } + + i++; // Count normal characters. + src++; + dst++; + } + } + + return i; + +} // do_str_copy_safe + + + +/*HDR*/ +/** + * @brief A portable, safe implementation of strncpy(). + * + * In the original implementation of @a strncpy, if the length of the + * string to be copied into the destination buffer exceeds the specified + * buffer length, the string in the output buffer is not 0-terminated. + * + * Our implementation always forces a proper termination by 0, but unlike + * the original implementation of @a strncpy, it does ***not*** fill the whole + * remaining buffer space with '0' characters. + * + * @param[out] dst Pointer to the output buffer. + * @param[in] src Pointer to the input buffer. + * @param[in] max_len Size of the output buffer for 0-terminated string. + * + * @return Pointer to the destination buffer. + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ +char *strncpy_safe( char *dst, const char *src, size_t max_len ) +{ + do_str_copy_safe( dst, src, max_len ); + + return dst; + +} // strncpy_safe + + + +/*HDR*/ +/** + * @brief A function to copy a string safely, returning the number of characters copied. + * + * This basically works like ::strncpy_safe but instead of a pointer to + * the destination buffer it returns the number of characters copied + * to the destination buffer. + * + * @param[out] dst Pointer to the output buffer. + * @param[in] max_len Size of the output buffer for 0-terminated string. + * @param[in] src Pointer to the input buffer. + * + * @return The number of characters written to the output buffer, + * except the terminating 0. + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_char_safe + */ +int sn_cpy_str_safe( char *dst, size_t max_len, const char *src ) +{ + int n = do_str_copy_safe( dst, src, max_len ); + + return n; + +} // sn_cpy_str_safe + + + +/*HDR*/ +/** + * @brief A function to copy a character safely to a string buffer. + * + * This basically works like ::sn_cpy_str_safe but expects a character + * to be copied to the destination buffer. Appends a terminating 0 to + * the string buffer and returns the number of characters copied to + * the destination buffer, usually 0 or 1. + * + * @param[out] dst Pointer to the output buffer. + * @param[in] max_len Size of the output buffer for 0-terminated string. + * @param[in] c Character to be copied to the destination buffer. + * + * @return The number of characters written to the output buffer, + * except the terminating 0. + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + */ +int sn_cpy_char_safe( char *dst, size_t max_len, char c ) +{ + int n; + char tmp_str[2]; + + tmp_str[0] = c; + tmp_str[1] = 0; + + n = do_str_copy_safe( dst, tmp_str, max_len ); + + return n; + +} // sn_cpy_char_safe + + + +/*HDR*/ +/** + * @brief Trim whitespace at the end of a string. + * + * @param[in,out] s The string to be trimmed. + */ +void trim_trailing_whitespace( char *s ) +{ + char *cp; + + // Set all trailing spaces to 0. + for ( cp = &s[strlen( s )]; cp > s; ) + { + --cp; + + if ( *cp >= ' ' ) + break; + + *cp = 0; + } + +} // trim_trailing_whitespace + + + +/*HDR*/ +/** + * @brief Trim whitespace at the beginning of a string. + * + * @param[in,out] s The string to be trimmed. + */ +void trim_leading_whitespace( char *s ) +{ + char *srcp; + char *dstp; + + // Search the first non-space character. + for ( srcp = s; *srcp; srcp++ ) + if ( *srcp > ' ' ) + break; + + // If there are leading spaces, srcp now + // points behind the beginning of the string, + // otherwise there's nothing to do. + if ( srcp > s ) + { + // Copy the remaining string. + dstp = s; + + while ( *srcp ) + *dstp++ = *srcp++; + + *dstp = 0; + } + +} // trim_leading_whitespace + + + +/*HDR*/ +/** + * @brief Trim both leading and trailing whitespace from a string. + * + * @param[in,out] s The string to be trimmed. + */ +void trim_whitespace( char *s ) +{ + trim_trailing_whitespace( s ); + trim_leading_whitespace( s ); + +} // trim_whitespace + + + +/*HDR*/ +/** + * @brief Copy array of bytes starting at beginning of buffer. + * + * Can be used if the destination address is in the same buffer + * in front of the source address. Even though you would expect + * that @a memcpy would also work for this properly, we have seen + * cases where it didn't, and only @a memmove worked correctly. + * Anyway, we try to avoid the overhead of @a memmove. + * + * @param[out] dst Destination address behind the source address. + * @param[in] src Source address. + * @param[in] n_bytes Number of bytes to copy. + * + * @see ::mbg_memcpy_reversed + */ +void mbg_memcpy( void *dst, const void *src, size_t n_bytes ) +{ + uint8_t *dstp = (uint8_t *) dst; + uint8_t *srcp = (uint8_t *) src; + + while ( n_bytes-- ) + *dstp++ = *srcp++; + +} // mbg_memcpy + + + +/*HDR*/ +/** + * @brief Copy an array of bytes in reversed order, starting at end of buffer. + * + * Can be used if the destination address is in the same buffer + * behind the source address, so the source address would be + * overwritten by a normal @a memcpy. + * + * @param[out] dst Destination address behind the source address. + * @param[in] src Source address. + * @param[in] n_bytes Number of bytes to copy. + * + * @see ::mbg_memcpy + */ +void mbg_memcpy_reversed( void *dst, const void *src, size_t n_bytes ) +{ + if ( n_bytes ) // Just to be sure it isn't 0. + { + uint8_t *dstp = ( (uint8_t *) dst ) + n_bytes; + uint8_t *srcp = ( (uint8_t *) src ) + n_bytes; + + while ( n_bytes-- ) + *(--dstp) = *(--srcp); + } + +} // mbg_memcpy_reversed + + + diff --git a/mbglib/common/str_util.h b/mbglib/common/str_util.h new file mode 100644 index 0000000..e6f130d --- /dev/null +++ b/mbglib/common/str_util.h @@ -0,0 +1,391 @@ + +/************************************************************************** + * + * $Id: str_util.h 1.14 2022/12/21 15:02:26 martin.burnicki REL_M $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Definitions and prototypes for str_util.c + * + * ----------------------------------------------------------------------- + * $Log: str_util.h $ + * Revision 1.14 2022/12/21 15:02:26 martin.burnicki + * Fixed some size_t/int mismatch. + * Revision 1.13 2022/08/26 15:02:13 martin.burnicki + * Updated a doxygen comment. + * Revision 1.12 2021/03/22 11:27:45 martin + * Updated some comments. + * Revision 1.11 2021/03/16 12:21:51 martin + * Updated some comments. + * Revision 1.10 2021/03/12 11:00:28 martin + * Updated some doxygen comments. + * Revision 1.9 2020/10/15 13:38:44 martin + * Fixed build on FreeBSD. + * Revision 1.8 2020/02/27 13:57:12 martin + * Updated function prototypes. + * Revision 1.7 2019/07/31 15:42:39 martin + * Doxygen changes. + * Revision 1.6 2018/08/23 13:10:26 martin + * New inline functions mbg_buffer_specs_valid() and + * mbg_chk_snprint_results() that can also be called + * from code used in kernel mode. + * Updated function prototypes. + * 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 + * Added macro _sn_cpy_str_safe() to simplify calls. + * Revision 1.2 2016/08/05 12:33:17 martin + * Moved string trim functions from cfg_util module here. + * Added variable str_not_avail. + * Fixed some spelling. + * Updated function prototypes. + * Revision 1.1 2015/08/25 15:57:43 martin + * Initial revision. + * + **************************************************************************/ + +#ifndef _STR_UTIL_H +#define _STR_UTIL_H + +/* Other headers to be included */ + +#include <words.h> // implicitly includes mbg_tgt.h for non-firmware projects + +#if defined( MBG_TGT_KERNEL ) + #include <mbgddmsg.h> + + #if defined( MBG_TGT_FREEBSD ) + #include <sys/stddef.h> // NULL + #endif +#else + #include <stdlib.h> + #include <stdarg.h> + #include <limits.h> +#endif + + +#ifdef _STR_UTIL + #define _ext + #define _DO_INIT +#else + #define _ext extern +#endif + + +/* Start of header body */ + +#ifdef __cplusplus +extern "C" { +#endif + + +_ext const char *str_not_avail +#ifdef _DO_INIT + = "N/A" +#endif +; + + + +static __mbg_inline /*HDR*/ +/** + * @brief Check if the buffer plus size parameters passed to a function are valid. + * + * This function can be used to check parameters that have been + * passed to another function to specify an output buffer to be filled. + * + * If no buffer has been specified, or the size of the buffer which + * may remain after a previous operation is 0 or even less than 0, + * no data can be placed in the buffer. + * + * @param[in] s The address of the specified buffer. + * @param[in] max_len The size of the specified buffer. + * + * @return @a true if the buffer address is not @a NULL and the size is > 0, else @a false. + */ +bool mbg_buffer_specs_valid( char *s, ssize_t max_len ) +{ + return ( s != NULL ) + && ( max_len > 0 ) + && ( max_len < INT_MAX ); + +} // mbg_buffer_specs_valid + + + +static __mbg_inline /*HDR*/ +/** + * @brief Check the results of an snprintf()-like function. + * + * Implementations of <em>snprintf</em>-like functions may behave differently + * and badly if the specified output buffer is too small. + * The exact behavior depends on the runtime library shipped with a + * specific build environment for a specific operating system, + * the version of that runtime library, and may even differ depending + * on whether kernel mode or user mode code is compiled. + * + * This function can be called after any <em>snprintf</em>-like function + * to make sure that a valid buffer is always 0-terminated, and the + * number returned to indicate how many bytes have been written to + * the buffer is never less than 0, and never exceeds the real size + * of the buffer. + * + * @param[in] n The return code from an <em>snprintf</em>-like function that has been called before. + * @param[in] s The address of the buffer that had been passed to the <em>snprintf</em>-like function. + * @param[in] max_len The size of the specified buffer that had been passed to the <em>snprintf</em>-like function. + * + * @return The real number of bytes that had been written to the buffer. + * + * @see ::vsnprintf_safe + * @see ::mbg_kdd_vsnprintf + * @see ::mbg_buffer_specs_valid + */ +int mbg_chk_snprint_results( int n, char *s, ssize_t max_len ) +{ + if ( !mbg_buffer_specs_valid( s, max_len ) ) + return 0; // Buffer parameters are not valid. + + + // Force proper worst-case termination of the output string. + s[max_len - 1] = 0; + + // If n is > 0, but less than the specified buffer size we + // assume the value is correct. + if ( n > 0 && n < max_len ) + goto out; + + // Determine the real string length, but don't just call strlen() + // because that function may not be available in kernel mode. + for ( n = 0; s[n]; n++ ); + +out: + // Most snprintf()-like functions take a "size_t" to specify the buffer size, + // but just return an "int", which may be a smaller data type than "size_t", + // so we do a conversion here, if required, and try to do the conversion + // in a safe way. + return _int_from_size_t( n ); + +} // mbg_chk_snprint_results + + + +#define _sn_cpy_str_safe( _dst, _src ) sn_cpy_str_safe( _dst, sizeof( _dst ), _src ) + + +/* ----- function prototypes begin ----- */ + +/* This section was generated automatically */ +/* by MAKEHDR, do not remove the comments. */ + + /** + * @brief A portable, safe implementation of vsnprintf(). + * + * Unfortunately, the behavior of @a vsnprintf and therefore also that + * of @a snprintf differs in detail in different build environments + * and runtime libraries. + * + * If the output exceeds the buffer size and thus is truncated, then:<br> + * + * - On Windows, a negative value is returned and maybe ***no*** + * terminating 0 is written to the output buffer, so the output string + * may not be terminated properly. + * + * - Some versions of glibc return the number of bytes that ***would*** + * have been written to the buffer ***if*** the buffer would have been + * large enough, instead of the true number of characters that have + * been written to the buffer. + * + * So subsequent calls like + * + * @code{.c} + n = snprintf( s, max_len, ... ); + n += snprintf( &s[n], max_len - n, ... ); + * @endcode + * + * may always work properly, or fail with buffer overruns or stack + * corruption depending on the build environment. + * This wrapper function takes care that strings are always terminated + * properly, and that the returned value always matches the number of + * characters really written to the string buffer, excluding the + * terminating 0. + * + * @note The @a size_t type parameter used to specify the buffer size + * can be larger (e.g. @a unsigned_long) than the @a int type returned + * by mostly all functions of the @a printf family. So if a very large + * buffer is specified, and a large number of characters (more than + * @a INT_MAX) are written to that buffer, how can an @a int type + * return the large number of characters written to the buffer? + * We also try to workaround this here. + * + * @param[out] s The string buffer to be filled. + * @param[in] max_len Size of the output buffer for a 0-terminated string. + * @param[in] fmt Format string according to subsequent parameters. + * @param[in] args Variable argument list in @a va_list format. + * + * @return The number of characters written to the output buffer, + * except the terminating 0. + * + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ + __attribute__( ( format( printf, 3, 0 ) ) ) int vsnprintf_safe( char *s, ssize_t max_len, const char *fmt, va_list args ) ; + + /** + * @brief A portable, safe implementation of snprintf(). + * + * For a detailed description see ::vsnprintf_safe. + * + * @param[out] s The string buffer to be filled. + * @param[in] max_len Size of the output buffer for a 0-terminated string. + * @param[in] fmt Format string according to subsequent parameters. + * @param[in] ... Variable argument list according to the @p fmt format string. + * + * @return The number of characters written to the output buffer, + * except the terminating 0. + * + * @see ::vsnprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ + __attribute__( ( format( printf, 3, 4 ) ) ) int snprintf_safe( char *s, ssize_t max_len, const char *fmt, ... ) ; + + /** + * @brief A portable, safe implementation of strncpy(). + * + * In the original implementation of @a strncpy, if the length of the + * string to be copied into the destination buffer exceeds the specified + * buffer length, the string in the output buffer is not 0-terminated. + * + * Our implementation always forces a proper termination by 0, but unlike + * the original implementation of @a strncpy, it does ***not*** fill the whole + * remaining buffer space with '0' characters. + * + * @param[out] dst Pointer to the output buffer. + * @param[in] src Pointer to the input buffer. + * @param[in] max_len Size of the output buffer for 0-terminated string. + * + * @return Pointer to the destination buffer. + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::sn_cpy_str_safe + * @see ::sn_cpy_char_safe + */ + char *strncpy_safe( char *dst, const char *src, size_t max_len ) ; + + /** + * @brief A function to copy a string safely, returning the number of characters copied. + * + * This basically works like ::strncpy_safe but instead of a pointer to + * the destination buffer it returns the number of characters copied + * to the destination buffer. + * + * @param[out] dst Pointer to the output buffer. + * @param[in] max_len Size of the output buffer for 0-terminated string. + * @param[in] src Pointer to the input buffer. + * + * @return The number of characters written to the output buffer, + * except the terminating 0. + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_char_safe + */ + 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. + * + * This basically works like ::sn_cpy_str_safe but expects a character + * to be copied to the destination buffer. Appends a terminating 0 to + * the string buffer and returns the number of characters copied to + * the destination buffer, usually 0 or 1. + * + * @param[out] dst Pointer to the output buffer. + * @param[in] max_len Size of the output buffer for 0-terminated string. + * @param[in] c Character to be copied to the destination buffer. + * + * @return The number of characters written to the output buffer, + * except the terminating 0. + * + * @see ::vsnprintf_safe + * @see ::snprintf_safe + * @see ::strncpy_safe + * @see ::sn_cpy_str_safe + */ + int sn_cpy_char_safe( char *dst, size_t max_len, char c ) ; + + /** + * @brief Trim whitespace at the end of a string. + * + * @param[in,out] s The string to be trimmed. + */ + void trim_trailing_whitespace( char *s ) ; + + /** + * @brief Trim whitespace at the beginning of a string. + * + * @param[in,out] s The string to be trimmed. + */ + void trim_leading_whitespace( char *s ) ; + + /** + * @brief Trim both leading and trailing whitespace from a string. + * + * @param[in,out] s The string to be trimmed. + */ + void trim_whitespace( char *s ) ; + + /** + * @brief Copy array of bytes starting at beginning of buffer. + * + * Can be used if the destination address is in the same buffer + * in front of the source address. Even though you would expect + * that @a memcpy would also work for this properly, we have seen + * cases where it didn't, and only @a memmove worked correctly. + * Anyway, we try to avoid the overhead of @a memmove. + * + * @param[out] dst Destination address behind the source address. + * @param[in] src Source address. + * @param[in] n_bytes Number of bytes to copy. + * + * @see ::mbg_memcpy_reversed + */ + void mbg_memcpy( void *dst, const void *src, size_t n_bytes ) ; + + /** + * @brief Copy an array of bytes in reversed order, starting at end of buffer. + * + * Can be used if the destination address is in the same buffer + * behind the source address, so the source address would be + * overwritten by a normal @a memcpy. + * + * @param[out] dst Destination address behind the source address. + * @param[in] src Source address. + * @param[in] n_bytes Number of bytes to copy. + * + * @see ::mbg_memcpy + */ + void mbg_memcpy_reversed( void *dst, const void *src, size_t n_bytes ) ; + + +/* ----- function prototypes end ----- */ + +#ifdef __cplusplus +} +#endif + + +/* End of header body */ + +#undef _ext +#undef _DO_INIT + +#endif /* _STR_UTIL_H */ diff --git a/mbglib/common/use_pack.h b/mbglib/common/use_pack.h new file mode 100644 index 0000000..4da7bec --- /dev/null +++ b/mbglib/common/use_pack.h @@ -0,0 +1,45 @@ + +/************************************************************************** + * + * $Id: use_pack.h 1.6 2022/10/13 16:02:51 martin.burnicki REL_M $ + * + * Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany + * + * Description: + * Check the current compiler type to decide if pragma pack() is + * required to pack cross-platform data structures. + * + * ----------------------------------------------------------------------- + * $Log: use_pack.h $ + * Revision 1.6 2022/10/13 16:02:51 martin.burnicki + * Removed tabs and trailing spaces. + * Revision 1.5 2012/10/12 12:40:01Z martin + * Removed temporary changes. + * Revision 1.4 2012/10/02 18:06:25 martin + * Temporary changes to test alignment under Linux/Sparc. + * Revision 1.3 2011/01/26 10:01:41 martin + * Provided a way to suppress packing of structures on a project base. + * Revision 1.2 2002/02/25 08:50:33 Andre + * query __ARM added, __SH2 removed + * Revision 1.1 2001/03/30 08:54:33Z MARTIN + * Initial revision + * + **************************************************************************/ + +#ifndef _USE_PACK_H +#define _USE_PACK_H + +#if ( !defined( _C166 ) && \ + !defined( _CC51 ) && \ + !defined( __ARM ) ) + + // _NO_USE_PACK can be defined for specific projects + // to avoid packing of structures. + #if ( !defined( _NO_USE_PACK ) ) + #define _USE_PACK + #endif + +#endif + +#endif /* _USE_PACK_H */ + |