#include <sys/types.h>
#include <ppsi/ppsi.h>
#include <softpll_ng.h>

#include <wrpc.h>

#include "dump-info.h"

struct dump_info  dump_info[] = {
/* map for fields of ppsi structures */
#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_globals

	DUMP_HEADER("pp_globals"),
	DUMP_FIELD(pointer, pp_instances),
	DUMP_FIELD(pointer, rt_opts),
	DUMP_FIELD(pointer, defaultDS),
	DUMP_FIELD(pointer, currentDS),
	DUMP_FIELD(pointer, parentDS),
	DUMP_FIELD(pointer, timePropertiesDS),
	DUMP_FIELD(int, ebest_idx),
	DUMP_FIELD(int, ebest_updated),
	DUMP_FIELD(int, nlinks),
	DUMP_FIELD(int, max_links),
	/* substructure pp_globals_cfg */ 
	DUMP_FIELD(int, cfg.cfg_items),
	DUMP_FIELD(int, cfg.cur_ppi_n),

	DUMP_FIELD(int, rxdrop),
	DUMP_FIELD(int, txdrop),
	DUMP_FIELD(pointer, arch_data),
	DUMP_FIELD(pointer, global_ext_data),


#undef DUMP_STRUCT
#define DUMP_STRUCT defaultDS_t /* Horrible typedef */

	DUMP_HEADER("defaultDS_t"),
	DUMP_FIELD(Boolean, twoStepFlag),
	DUMP_FIELD(ClockIdentity, clockIdentity),
	DUMP_FIELD(UInteger16, numberPorts),
	DUMP_FIELD(ClockQuality, clockQuality),
	DUMP_FIELD(UInteger8, priority1),
	DUMP_FIELD(UInteger8, priority2),
	DUMP_FIELD(UInteger8, domainNumber),
	DUMP_FIELD(yes_no_Boolean, slaveOnly),
	/** Optional (IEEE1588-2019) */
//	FIXME: DUMP_FIELD(Timestamp, currentTime),
	DUMP_FIELD(yes_no_Boolean, instanceEnable),
	DUMP_FIELD(yes_no_Boolean, externalPortConfigurationEnabled),
	DUMP_FIELD(Enumeration8, maxStepsRemoved),
	DUMP_FIELD(Enumeration8, SdoId),
	DUMP_FIELD(Enumeration8, instanceType),


#undef DUMP_STRUCT
#define DUMP_STRUCT currentDS_t /* Horrible typedef */

	DUMP_HEADER("currentDS_t"),
	DUMP_FIELD(UInteger16, stepsRemoved),
	DUMP_FIELD(TimeInterval, offsetFromMaster),
	DUMP_FIELD(TimeInterval, meanDelay), /* oneWayDelay */
	DUMP_FIELD(UInteger16, primarySlavePortNumber),


#undef DUMP_STRUCT
#define DUMP_STRUCT parentDS_t /* Horrible typedef */

	DUMP_HEADER("parentDS_t"),
	DUMP_FIELD(PortIdentity, parentPortIdentity),
	DUMP_FIELD(UInteger16, observedParentOffsetScaledLogVariance),
	DUMP_FIELD(Integer32, observedParentClockPhaseChangeRate),
	DUMP_FIELD(ClockIdentity, grandmasterIdentity),
	DUMP_FIELD(ClockQuality, grandmasterClockQuality),
	DUMP_FIELD(UInteger8, grandmasterPriority1),
	DUMP_FIELD(UInteger8, grandmasterPriority2),
	DUMP_FIELD(yes_no_Boolean, newGrandmaster),


#undef DUMP_STRUCT
#define DUMP_STRUCT timePropertiesDS_t /* Horrible typedef */

	DUMP_HEADER("timePropertiesDS_t"),
	DUMP_FIELD(Integer16, currentUtcOffset),
	DUMP_FIELD(yes_no_Boolean, currentUtcOffsetValid),
	DUMP_FIELD(yes_no_Boolean, leap59),
	DUMP_FIELD(yes_no_Boolean, leap61),
	DUMP_FIELD(yes_no_Boolean, timeTraceable),
	DUMP_FIELD(yes_no_Boolean, frequencyTraceable),
	DUMP_FIELD(yes_no_Boolean, ptpTimescale),
	DUMP_FIELD(Enumeration8, timeSource),


#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_servo

	DUMP_HEADER("pp_servo"),
	DUMP_FIELD(long_long, obs_drift),
	DUMP_FIELD(Integer64, mpd_fltr.m),
	DUMP_FIELD(Integer64, mpd_fltr.y),
	DUMP_FIELD(Integer64, mpd_fltr.s_exp),

	/* Data shared with extension servo */
	DUMP_FIELD(pp_time, delayMM), /* Shared with extension servo */
	DUMP_FIELD(pp_time, delayMS), /* Shared with extension servo */
	DUMP_FIELD(pp_time, meanDelay), /* Shared with extension servo */
	DUMP_FIELD(pp_time, offsetFromMaster), /* Shared with extension servo */
	DUMP_FIELD(pp_servo_flag, flags),

	DUMP_FIELD(int, reset_address),

	/* Data used only by extensions */
	DUMP_FIELD(pp_servo_state, state),
	DUMP_FIELD_SIZE(char, servo_state_name, 32),

	/* Data shared with extension servo */
	DUMP_FIELD(UInteger32, update_count),
	DUMP_FIELD(pp_time, update_time),
	DUMP_FIELD(pp_time, t1),
	DUMP_FIELD(pp_time, t2),
	DUMP_FIELD(pp_time, t3),
	DUMP_FIELD(pp_time, t4),
	DUMP_FIELD(pp_time, t5),
	DUMP_FIELD(pp_time, t6),

	DUMP_FIELD(yes_no, servo_locked),
	DUMP_FIELD(yes_no, got_sync),

#if CONFIG_HAS_EXT_L1SYNC || CONFIG_HAS_EXT_WR
#undef DUMP_STRUCT
#define DUMP_STRUCT wrh_servo_t
	DUMP_HEADER("wrh_servo_t"),
	DUMP_FIELD(Integer32, clock_period_ps),
	DUMP_FIELD(Integer64, delayMM_ps),
	DUMP_FIELD(Integer32, cur_setpoint_ps),
	DUMP_FIELD(Integer64, delayMS_ps),
	DUMP_FIELD(int,       tracking_enabled),
	DUMP_FIELD(Integer64, skew_ps),
	DUMP_FIELD(Integer64, offsetMS_ps),
	DUMP_FIELD(UInteger32, n_err_state),
	DUMP_FIELD(UInteger32, n_err_offset),
	DUMP_FIELD(UInteger32, n_err_delta_rtt),
	DUMP_FIELD(Integer64, prev_delayMS_ps),
	DUMP_FIELD(int, missed_iters),
#endif

#if CONFIG_HAS_EXT_WR == 1
#undef DUMP_STRUCT
#define DUMP_STRUCT wr_servo_ext_t
	DUMP_HEADER("wr_servo_ext_t"),
	DUMP_FIELD(pp_time, delta_txm),
	DUMP_FIELD(pp_time, delta_rxm),
	DUMP_FIELD(pp_time, delta_txs),
	DUMP_FIELD(pp_time, delta_rxs),
	DUMP_FIELD(pp_time, rawT1),
	DUMP_FIELD(pp_time, rawT2),
	DUMP_FIELD(pp_time, rawT3),
	DUMP_FIELD(pp_time, rawT4),
	DUMP_FIELD(pp_time, rawT5),
	DUMP_FIELD(pp_time, rawT6),
	DUMP_FIELD(pp_time, rawDelayMM),
#endif

#undef DUMP_STRUCT
#define DUMP_STRUCT portDS_t

	DUMP_HEADER("portDS_t"),
	DUMP_FIELD(PortIdentity, portIdentity),
	DUMP_FIELD(Integer8, logMinDelayReqInterval),
	DUMP_FIELD(Integer8, logAnnounceInterval),
	DUMP_FIELD(UInteger8, announceReceiptTimeout),
	DUMP_FIELD(Integer8, logSyncInterval),
	DUMP_FIELD(pointer, ext_dsport),
	DUMP_FIELD(Integer8, logMinPdelayReqInterval),
	DUMP_FIELD(TimeInterval, meanLinkDelay),
	DUMP_FIELD(UInteger4, versionNumber),
	DUMP_FIELD(UInteger4, minorVersionNumber),
	DUMP_FIELD(TimeInterval, delayAsymmetry),
	DUMP_FIELD(RelativeDifference, delayAsymCoeff),
	DUMP_FIELD(yes_no_Boolean, portEnable),
	DUMP_FIELD(yes_no_Boolean, masterOnly),

#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_instance

	DUMP_HEADER("pp_instance"),
	DUMP_FIELD(ppi_state, state),
	DUMP_FIELD(ppi_state, next_state),
	DUMP_FIELD(int, next_delay),
	DUMP_FIELD(yes_no, is_new_state),
	DUMP_FIELD(pointer, current_state_item),
	DUMP_FIELD(pointer, arch_data),
	DUMP_FIELD(pointer, ext_data),
	DUMP_FIELD(protocol_extension, protocol_extension),
	DUMP_FIELD(pointer, ext_hooks),
	DUMP_FIELD(unsigned_long, d_flags),
	DUMP_FIELD(ppi_flag, flags),
	DUMP_FIELD(ppi_proto, proto),
	DUMP_FIELD(delay_mechanism, delayMechanism),
	DUMP_FIELD(pointer, glbs),
	DUMP_FIELD(pointer, n_ops),
	DUMP_FIELD(pointer, t_ops),
	DUMP_FIELD(pointer, __tx_buffer),
	DUMP_FIELD(pointer, __rx_buffer),
	DUMP_FIELD(pointer, tx_frame),
	DUMP_FIELD(pointer, rx_frame),
	DUMP_FIELD(pointer, tx_ptp),
	DUMP_FIELD(pointer, rx_ptp),

	/* This is a sub-structure */
	DUMP_FIELD(int, ch[0].fd),
	DUMP_FIELD(pointer, ch[0].custom),
	DUMP_FIELD(pointer, ch[0].arch_data),
	DUMP_FIELD_SIZE(bina, ch[0].addr, 6),
	DUMP_FIELD(yes_no, ch[0].pkt_present),
	DUMP_FIELD(int, ch[1].fd),
	DUMP_FIELD(pointer, ch[1].custom),
	DUMP_FIELD(pointer, ch[1].arch_data),
	DUMP_FIELD_SIZE(bina, ch[1].addr, 6),
	DUMP_FIELD(yes_no, ch[1].pkt_present),

	DUMP_FIELD(ip_address, mcast_addr[0]),
	DUMP_FIELD(ip_address, mcast_addr[1]),
	DUMP_FIELD(int, tx_offset),
	DUMP_FIELD(int, rx_offset),
	DUMP_FIELD_SIZE(bina, peer, 6),
	DUMP_FIELD_SIZE(bina, activePeer, 6),
	DUMP_FIELD(uint16_t, peer_vid),

	DUMP_FIELD(pp_time, t1),
	DUMP_FIELD(pp_time, t2),
	DUMP_FIELD(pp_time, t3),
	DUMP_FIELD(pp_time, t4),
	DUMP_FIELD(pp_time, t5),
	DUMP_FIELD(pp_time, t6),
	DUMP_FIELD(Integer32, t4_cf),
	DUMP_FIELD(Integer32, t6_cf),
	DUMP_FIELD(UInteger64, syncCF),
	DUMP_FIELD(pp_time, last_rcv_time),
	DUMP_FIELD(pp_time, last_snt_time),
	DUMP_FIELD(UInteger16, frgn_rec_num),
	DUMP_FIELD(Integer16,  frgn_rec_best),
	DUMP_FIELD(UInteger32, frgn_master_time_window_ms),
	DUMP_FIELD(dummy /*struct pp_frgn_master */, frgn_master), /* use dummy type just to save the offset */
	DUMP_FIELD(pointer, portDS),
	DUMP_FIELD(pointer, servo),

	/*  dump of substructure asymmetryCorrectionPortDS_t; draft P1588_v_29: page 99*/
	DUMP_FIELD(TimeInterval, asymmetryCorrectionPortDS.constantAsymmetry),
	DUMP_FIELD(RelativeDifference, asymmetryCorrectionPortDS.scaledDelayCoefficient),
	DUMP_FIELD(yes_no_Boolean, asymmetryCorrectionPortDS.enable),

	/* dump of substructure timestampCorrectionPortDS_t; draft P1588_v_29: page 99 */
	DUMP_FIELD(TimeInterval, timestampCorrectionPortDS.egressLatency),
	DUMP_FIELD(TimeInterval, timestampCorrectionPortDS.ingressLatency),
	DUMP_FIELD(TimeInterval, timestampCorrectionPortDS.messageTimestampPointLatency),
	DUMP_FIELD(TimeInterval, timestampCorrectionPortDS.semistaticLatency),

	/* dump of substructure externalPortConfigurationPortDS_t; draft P1588: Clause 17.6.3*/
	DUMP_FIELD(ppi_state_Enumeration8, externalPortConfigurationPortDS.desiredState),
	
// 	timeOutInstCnt_t tmo_cfg[PP_TO_COUNT];
	DUMP_FIELD(UInteger16, recv_sync_sequence_id),

	//DUMP_FIELD(UInteger16 sent_seq[__PP_NR_MESSAGES_TYPES]),

	DUMP_FIELD_SIZE(bina, received_ptp_header, sizeof(MsgHeader)),

	DUMP_FIELD(yes_no_Boolean, link_up),
	DUMP_FIELD_SIZE(char, iface_name, 16), /* for direct actions on hardware */
	DUMP_FIELD_SIZE(char, port_name, 16), /* for diagnostics, mainly */
	DUMP_FIELD(int, port_idx),
	DUMP_FIELD(int, vlans_array_len),
	/* FIXME: array */
// 	int vlans[CONFIG_VLAN_ARRAY_SIZE];
	DUMP_FIELD(int, nvlans),

	/* sub structure */
	DUMP_FIELD_SIZE(char, cfg.port_name, 16),
	DUMP_FIELD_SIZE(char, cfg.iface_name, 16),
	DUMP_FIELD(ppi_profile, cfg.profile),
	DUMP_FIELD(delay_mechanism, cfg.delayMechanism),
	/* FIXME: other fields from cfg */

	DUMP_FIELD(unsigned_long, ptp_tx_count),
	DUMP_FIELD(unsigned_long, ptp_rx_count),
	DUMP_FIELD(yes_no_Boolean, received_dresp), /* Count the number of delay response messages received for a given delay request */
	DUMP_FIELD(yes_no_Boolean, received_dresp_fup), /* Count the number of delay response follow up messages received for a given delay request */
	DUMP_FIELD(yes_no_Boolean, ptp_support), /* True if allow pure PTP support */
	DUMP_FIELD(yes_no_Boolean, bmca_execute), /* True: Ask fsm to run bmca state decision */
	DUMP_FIELD(pp_pdstate, pdstate),  /* Protocol detection state */
	DUMP_FIELD(exstate, extState), /* Extension state */

#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_frgn_master
	DUMP_HEADER("pp_frgn_master"),
	DUMP_FIELD(PortIdentity, sourcePortIdentity),
	DUMP_FIELD(PortIdentity, receivePortIdentity),
	DUMP_FIELD(ClockQuality, grandmasterClockQuality),
	DUMP_FIELD(ClockIdentity, grandmasterIdentity),
	DUMP_FIELD(UInteger8, grandmasterPriority1),
	DUMP_FIELD(UInteger8, grandmasterPriority2),
	DUMP_FIELD_SIZE(UInteger8, flagField,2),
	DUMP_FIELD(Enumeration8, timeSource),
	DUMP_FIELD(UInteger16, sequenceId),
	DUMP_FIELD(UInteger16, stepsRemoved),
	DUMP_FIELD(Integer16, currentUtcOffset),
	DUMP_FIELD(yes_no_Boolean, qualified),
	DUMP_FIELD(unsigned_long, lastAnnounceMsgMs),

#if CONFIG_HAS_EXT_WR == 1
#undef DUMP_STRUCT
#define DUMP_STRUCT struct wr_dsport
	DUMP_HEADER("wr_dsport"),
	DUMP_FIELD(wr_state, state),
	DUMP_FIELD(wr_state, next_state),
	DUMP_FIELD(yes_no_Boolean, wrModeOn),
	DUMP_FIELD(yes_no_Boolean, parentWrModeOn),
	DUMP_FIELD(FixedDelta, deltaTx),
	DUMP_FIELD(FixedDelta, deltaRx),
	DUMP_FIELD(UInteger16, otherNodeCalSendPattern),
	DUMP_FIELD(UInteger8, otherNodeCalRetry),
	DUMP_FIELD(UInteger32, otherNodeCalPeriod),
	DUMP_FIELD(FixedDelta, otherNodeDeltaTx),
	DUMP_FIELD(FixedDelta, otherNodeDeltaRx),
	DUMP_FIELD(wr_config_Enumeration8, wrConfig),
	DUMP_FIELD(wr_config_Enumeration8, parentWrConfig),
	DUMP_FIELD(wr_role_Enumeration8, wrMode),
	/* DUMP_FIELD(Enumeration8, wrPortState), not used*/
#endif


#if CONFIG_ARCH_IS_WRPC
#undef DUMP_STRUCT
#define DUMP_STRUCT struct wrpc_arch_data_t
	DUMP_HEADER("wrpc_arch_data_t"),
	DUMP_FIELD(timing_mode, timingMode),
	DUMP_FIELD(wrpc_mode_cfg, wrpcModeCfg),
#endif

#undef DUMP_STRUCT
#define DUMP_STRUCT struct wr_data

	DUMP_HEADER("wr_data"),
	/* These are structs not pointers, but we need to know the offset in wr_data structure */
	DUMP_FIELD(pointer,servo),
	DUMP_FIELD(pointer,servo_ext),

#undef DUMP_STRUCT
#define DUMP_STRUCT struct softpll_state

	DUMP_HEADER("softpll"),
	DUMP_FIELD(spll_mode, mode),
	DUMP_FIELD(int, seq_state),
	DUMP_FIELD(int, dac_timeout),
	DUMP_FIELD(int, delock_count),
	DUMP_FIELD(uint32_t, irq_count),
	DUMP_FIELD(int, mpll_shift_ps),
	DUMP_FIELD(int, helper.p_adder),
	DUMP_FIELD(int, helper.p_setpoint),
	DUMP_FIELD(int, helper.tag_d0),
	DUMP_FIELD(int, helper.ref_src),
	DUMP_FIELD(int, helper.sample_n),
	/* FIXME: missing helper.pi etc.. */
	DUMP_FIELD(yes_no, ext.enabled),
	DUMP_FIELD(int, ext.align_state),
	DUMP_FIELD(int, ext.align_timer),
	DUMP_FIELD(int, ext.align_target),
	DUMP_FIELD(int, ext.align_step),
	DUMP_FIELD(int, ext.align_shift),
	DUMP_FIELD(int, mpll.state),
	/* FIXME: mpll.pi etc */
	DUMP_FIELD(int, mpll.adder_ref),
	DUMP_FIELD(int, mpll.adder_out),
	DUMP_FIELD(int, mpll.tag_ref),
	DUMP_FIELD(int, mpll.tag_out),
	DUMP_FIELD(int, mpll.tag_ref_d),
	DUMP_FIELD(int, mpll.tag_out_d),
	DUMP_FIELD(int, mpll.phase_shift_target),
	DUMP_FIELD(int, mpll.phase_shift_current),
	DUMP_FIELD(int, mpll.id_ref),
	DUMP_FIELD(int, mpll.id_out),
	DUMP_FIELD(int, mpll.sample_n),
	DUMP_FIELD(int, mpll.dac_index),
	DUMP_FIELD(yes_no, mpll.enabled),

#undef DUMP_STRUCT
#define DUMP_STRUCT struct spll_fifo_log

	DUMP_HEADER("pll_fifo"),
	DUMP_FIELD(uint32_t, trr),
	DUMP_FIELD(uint32_t, tstamp),
	DUMP_FIELD(uint32_t, duration),
	DUMP_FIELD(uint16_t, irq_count),
	DUMP_FIELD(uint16_t, tag_count),
	/* FIXME: aux_state and ptracker_state -- variable-len arrays */

#undef DUMP_STRUCT
#define DUMP_STRUCT struct spll_stats

	DUMP_HEADER("stats"),
	DUMP_FIELD(uint32_t, magic),
	DUMP_FIELD(int, ver),
	DUMP_FIELD(int, sequence),
	DUMP_FIELD(spll_mode, mode),
	DUMP_FIELD(int, irq_cnt),
	DUMP_FIELD(int, seq_state),
	DUMP_FIELD(int, align_state),
	DUMP_FIELD(int, H_lock),
	DUMP_FIELD(int, M_lock),
	DUMP_FIELD(int, H_y),
	DUMP_FIELD(int, M_y),
	DUMP_FIELD(int, del_cnt),
	DUMP_FIELD(int, start_cnt),
	DUMP_FIELD_SIZE(char, commit_id, 32),
	DUMP_FIELD_SIZE(char, build_date, 16),
	DUMP_FIELD_SIZE(char, build_time, 16),
	DUMP_FIELD_SIZE(char, build_by, 32),

	DUMP_HEADER("end"),

};
