/*
 * Copyright (c) 2005-2006 Endace Technology Ltd, Hamilton, New Zealand.
 * All rights reserved.
 *
 * This source code is proprietary to Endace Technology Limited and no part
 * of it may be redistributed, published or disclosed except as outlined in
 * the written contract supplied with this product.
 *
 */

/* For printing card counters*/

#include "../../include/dag_config.h"
#include "../../include/dag_attribute_codes.h"
#include "../../include/dag_component_codes.h"
#include "../../include/dag_component.h"
#include "../../include/dagutil.h"
#include "./counter_printing.h"
#include "./attribute_print.h"
#include "./configuration_printing.h"

#include <stdio.h>
#include <assert.h>

typedef struct
{
	dag_block_type_t id;
	const char* string;
} id_block_string_map_t;


static id_block_string_map_t id_block[] =
{
	{kIDBlockDebug, "Debug"},
	{kIDBlockEthFramerRx, "Framer_Rx"},
	{kIDBlockEthFramerTx, "Framer_Tx"},
	{kIDBlockEthFramerRxTx, "Framer_Tx_Rx"},
	{kIDBlockSonetFramerRx, "Sonet_Framer_Rx"},
	{kIDBlockSonetFramerTx, "Sonet_Framer_Tx"},
	{kIDBlockSonetFramerRxTx, "Sonet_Framer_Tx_Rx"},
	{kIDBlockStreamRx, "Stream_Rx"},
	{kIDBlockStreamTx, "Stream_Tx"},
	{kIDBlockStreamRxTx, "Stream_Tx_Rx"},
	{kIDBlockStreamDropRx, "Stream_Drop_Rx"},
	{kIDBlockStreamDropTx, "Stream_Drop_Tx"},
	{kIDBlockStreamDropRxTx, "Stream_Drop_Tx_Rx"},
	{kIDBlockDropRx, "Drop_Rx"},
	{kIDBlockDropTx, "Drop_Tx"},
	{kIDBlockDropRxTx, "Drop_Tx_Rx"},
	{kIDBlockPortDropRx, "Port_Drop_Rx"},
	{kIDBlockPortDropTx, "Port_Drop_Tx"},
	{kIDBlockPortDropRxTx, "Port_Drop_Tx_Rx"},
	{kIDBlockFilterRx, "Filter_Rx"},
	{kIDBlockFilterTx, "Filter_Tx"},
	{kIDBlockFilterRxTx, "Filter_Tx_Rx"},
	{kIDBlockPatternRx, "Pattern_Rx"},
	{kIDBlockPatternTx, "Pattern_Tx"},
	{kIDBlockPatternRxTx, "Pattern_Tx_Rx"},
        {kIDBlockFrontEndFrequencyReferenceRx, "Front_End_Frequency_Reference_Rx"},
        {kIDBlockFrontEndFrequencyReferenceTx, "Front_End_Frequency_Reference_Tx"},
        {kIDBlockFrontEndFrequencyReferenceRxTx, "Front_End_Frequency_Reference_Rx_Tx"}
};

typedef struct
{
	dag_counter_type_t id;
	const char* string;
} id_counter_string_map_t;


static id_counter_string_map_t id_counter[] =
{
	{kIDCounterInvalid, "Invalid"},
	{kIDCounterRXFrame, "Rx_Frames"},
	{kIDCounterRXByte, "Rx_Bytes"},
	{kIDCounterRXShort, "Rx_Short"},
	{kIDCounterRXLong, "Rx_Long"},
	{kIDCounterRXError, "Rx_Errors"},
	{kIDCounterRXFCS, "Rx_FCS"},
	{kIDCounterRXAbort, "Rx_Abort"},
	{kIDCounterTXFrame, "Tx_Frames"},
	{kIDCounterTXByte, "Tx_Bytes"},
	{kIDCounterDIP4Error, "DIP4_Parity_Errors"},
	{kIDCounterDIP4PlError, "Payload_DIP4_Errors"},
	{kIDCounterBurstError, "Burst_Errors"},
	{kIDCounterPlError, "Payload_Errors"},
	{kIDCounterDebug, "Debug"},
	{kIDCounterFilter, "Filter"},
	{kIDCounterB1Error, "B1_Errors"},
	{kIDCounterB2Error, "B2_Errors"},
	{kIDCounterB3Error, "B3_Errors"},
	{kIDCounterRXErr, "Rx_Errors"},
	{kIDCounterSpaceError, "Space_Errors"},
	{kIDCounterContWdError, "Count_Wd_Errors"},
	{kIDCounterPlContError, "Payload_Count_Errors"},
	{kIDCounterTRDip4Error, "Training_DIP4_Errors"},
	{kIDCounterResvWd, "Resv_Ctrl_Words"},
	{kIDCounterAddrError, "Addr_Errors"},
	{kIDCounterOOFPeriod, "OOF_Period"},
	{kIDCounterNbOOF, "Nb_OOF"},
	{kIDCounterTXOOFPeriod, "Tx_OOF_Period"},
	{kIDCounterTXNbOOF, "Tx_Nb_OOF"},
	{kIDCounterTXError, "Tx_Errors"},
	{kIDCounterStatFrError, "Status_Frame_Errors"},
	{kIDCounterDip2Error, "DIP2_Parity_Errors"},
	{kIDCounterPatternError, "Data_Pattern_Errors"},
	{kIDCounterRXStreamPacket, "Rx_Stream_Packets"},
	{kIDCounterRXStreamByte, "Rx_Stream_Bytes"},
	{kIDCounterTXStreamPacket, "Tx_Stream_Packets"},
	{kIDCounterTXStreamByte, "Tx_Stream_Bytes"},
	{kIDCounterPortDrop, "Port_Drop"},
	{kIDCounterStreamDrop, "Stream_Drop"},
	{kIDCounterSubStreamDrop, "Sub_Stream_Drop"},
	{kIDCounterFilterDrop, "Filter_Drop"},
	{kIDCounterIdleCell, "Idle_Cells"},
	{kIDCounterTxClock, "Transmit_Clock"},
        {kIDCounterRxClock, "Recieve_Clock"},
        {kIDCounterDuckOverflow, "Duck_Overflow"},
        {kIDCounterPhyClockNominal, "Nominal_Pulses"},
	{kIDCounterRxProtocolErrors, "Rx_Protocol_Errors"},
        {kIDCounterTxStreamTypeDrop, "Tx_ERF_Type_Drop"},
        {kIDCounterTxStreamInterfaceDrop, "Tx_ERF_Interface_Drop"},
        {kIDCounterTxStreamRXErrorDrop, "Tx_ERF_RXError_Drop"},
        {kIDCounterTxStreamMinLenDrop, "Tx_ERF_MinLen_Drop"},
        {kIDCounterTxStreamMaxLenDrop, "Tx_ERF_MaxLen_Drop"},
        {kIDCounterTxInterfaceDrop, "Tx_IF_Drop"},
        {kIDCounterTxLateRelease, "Tx_IF_Late_Release"}
};

/* counter statistics to print for dagx should use the Attribute iD and finds the attributes and 
the names uses the old style statistics 
This is used by the -C option only not by the -u (universal counters)
the second parameter is the verbosity level at which we want to print the counters

*/


typedef struct counter_attributes_s {
    dag_attribute_code_t attribute_code;
    int attribute_verbosity;
} counter_attributes_t;

static counter_attributes_t counter_attributes_array[] =
{
	{ kUint64AttributeFIFOOverrunCount, 1},
 	{ kUint32AttributeErrorBlockCounter, 1},
 	{ kUint32AttributeBERCounter,1},
             /* RXF */
 	{ kUint32AttributeRxFrames,0},
 	{ kUint64AttributeRxBytes,0},
 	{ kUint32AttributeTxFrames,0},
 	{ kUint64AttributeTxBytes,0},
 	{ kUint32AttributeCRCErrors,0},
            	/* FCS_ERR */
 	{ kUint64AttributeFCSErrors, 0},
             	/* GOOD_PACKET */
 	{ kUint64AttributeGoodPackets, 1},
 		/* packets which were shorter than a framer setup or firmware module requirement */
 	{ kUint32AttributeShortPacketErrors,1},
 		/* packets which were longer than a framer setup or firmware module requirement */
 	{ kUint32AttributeLongPacketErrors,1},
	//note this one is subcomponent minimac stats in 4.5 
 	{ kUint32AttributeRemoteErrors,1},
	//note this one is subcomponent minimac stats in 4.5  
	 { kUint32AttributeBadSymbols,1},
	//note this one is subcomponent minimac stats in 4.5  
	 { kUint32AttributeConfigSequences,1}
};


static const char* id_counter_to_string(dag_counter_type_t id);
static const char* id_block_to_string(dag_block_type_t id);

/* change the enum id counter to a string */
static const char*
id_counter_to_string(dag_counter_type_t id)
{
    int count = sizeof(id_counter)/sizeof(id_counter_string_map_t);
    int i;

    for (i = 0; i < count; i++)
    {
        if (id_counter[i].id == id)
        {
            return id_counter[i].string;
        }
    }
    return "Unknown";
}

/* change the enum id counter to a string */
static const char*
id_block_to_string(dag_block_type_t id)
{
    int count = sizeof(id_block)/sizeof(id_block_string_map_t);
    int i;

    for (i = 0; i < count; i++)
    {
        if (id_block[i].id == id)
        {
            return id_block[i].string;
        }
    }
    return NULL;
}

/* Attributes to look through and to print it for counters */



void
print_counters(dag_card_ref_t card, int port)
{
    switch (dag_config_get_card_type(card))
    {
        case kDag452e:
        case kDag454e:
        case kDag452gf:
        case kDag452cf:
        case kDag452z:
        case kDag452z8:
            dag45ge_print_counters(card, port);
            break;
	/* we route the 5.2x through the 8.2x counter printing because the cards are basically the same */	
	//case kDag52x:
      	//case kDag82x:
	//case kDag82z:
	//case kDag810:
	//case kDag52sxa: 
	//FIXME: We put this card for the moment here may be it is incorrect but just to have something at the moment 
	//case kDag840:
	//  dagx_print_counters(card, port);
	//    break;
	case kDag37d:
            dag37d_print_counters(card, port);
	    break;
        default:
 	if((dag_config_get_number_block(card) <=  0))
	{
		/*Print Normal Counters*/
 	    dagx_print_counters(card, port);
	}// else print ucsi_counters must have invoked already
            break;
    }
}

void
dagx_print_ucsi_counters(dag_counter_value_t *counters,uint32_t count, int port)
{
	int i = 0;
    if ( NULL == counters)
    {
        dagutil_verbose_level(3, "No counters here. %s\n",__FUNCTION__);
        return;
    }
    for (i=0; i < count ; i++)
    {
        if(( counters[i].subfct == kIDSubfctPort) && (port == counters[i].interface_number))
        {
            printf("%15"PRIu64"",counters[i].value);
        }
    }
}

void
print_univ_counters(dag_card_ref_t card)
{
	int i, j;
	dag_component_t root;
	dag_component_t counter_comp;
	dag_component_t comp;
	int count_block = 0;
	uint32_t count_counter = 0;
	uint32_t temp = -1;
	uint32_t sub_func = 0;
	uint8_t print_stream = 0;
	uint8_t print_filter = 0;
	uint8_t print_general = 0;
	uint32_t sub_func_type = 0;
	uint32_t csi_value = 0;
	attr_uuid_t any_attr;
	uint32_t counter_id = 0;
	attr_uuid_t attr_counter_type = kNullAttributeUuid;
	
	root = dag_config_get_root_component(card);
	count_block = dag_component_get_subcomponent_count_of_type(root, kComponentInterface);

	dag_config_latch_clear_all(card);

	if (count_block > 0)
	{
		printf("\n**** Number of blocks: %d\n", count_block);	

		for (j = 0; j < count_block; j ++)
		{
			comp = dag_component_get_subcomponent(root, kComponentInterface, j);
			any_attr = dag_component_get_attribute_uuid(comp, kUint32AttributeCSIType);	
			count_counter = dag_component_get_subcomponent_count_of_type(comp, kComponentCounter);
			csi_value = dag_config_get_uint32_attribute(card,any_attr);
			printf("Nb of counter(s) in Block ID \"%s\": %d\n", id_block_to_string(csi_value), count_counter);

			if (count_counter > 0)	
			{
				/* print value of counters */
				for (i = 0; i < count_counter; i++)
				{		
					counter_comp = dag_component_get_subcomponent(comp, kComponentCounter, i);
					any_attr = dag_component_get_attribute_uuid(counter_comp, kUint32AttributeSubFunctionType);
					sub_func_type = dag_config_get_uint32_attribute(card, any_attr);
					any_attr = dag_component_get_attribute_uuid(counter_comp, kUint32AttributeSubFunction);
					sub_func = dag_config_get_uint32_attribute(card, any_attr);

					if (sub_func_type == 0)
					{	
						if (sub_func != temp)
							printf("Port: %2c\n", 'A'+sub_func);
						temp = sub_func;
					}
					else if (sub_func_type == 1)
					{
						if(print_stream == 0)
							printf("Stream: %2d\n", sub_func);
						print_stream = 1;
					}
					else if (sub_func_type == 2)
					{
						if(print_filter == 0)
							printf("Filter: %2d\n", sub_func);
						print_filter = 1;
					}
					else if (sub_func_type == 3)
					{
						if(print_general == 0)
							printf("General: \n");	
						print_general = 1;
					}
					attr_counter_type = dag_component_get_attribute_uuid(counter_comp, kUint32AttributeCounterID);
					any_attr = dag_component_get_attribute_uuid(counter_comp, kUint64AttributeValue);
					counter_id = dag_config_get_uint32_attribute(card,attr_counter_type);
				        printf("%22s: %"PRIu64"\n",id_counter_to_string(counter_id), 
												dag_config_get_uint64_attribute(card, any_attr));
				}
			}
			else 
				printf("No counters in block\n");
		}
	}
	else
		printf("No blocks\n");
	
}


void
dagx_print_counters(dag_card_ref_t card_ref, int port)
{
#if 1
	attr_uuid_t any_attribute;
	dag_component_t root;
	int attr_count = 0;
	int i = 0;

    	root = dag_config_get_root_component(card_ref);
    	for( i = 0; i < ( sizeof (counter_attributes_array) / sizeof(counter_attributes_array[0])) ; i++) 
	{
            attr_count = dag_config_get_attribute_count(card_ref,counter_attributes_array[i].attribute_code);
	    // This is only for one port and we assume that it is only port related counters
 	    if( (attr_count > 0) && (counter_attributes_array[i].attribute_verbosity <= dagutil_get_verbosity()) )
	    {
		any_attribute = dag_config_get_indexed_attribute_uuid(card_ref, counter_attributes_array[i].attribute_code, port);
		attribute_print_value(card_ref, any_attribute, kStateActive,port);
            }
       }
#else     
	dag_component_t comp;
	dag_component_t root;

	root = dag_config_get_root_component(card);
	
	comp = dag_component_get_subcomponent(root, kComponentXGMII, port);
	if( comp != kComponentInvalid) {
		comp = dag_component_get_subcomponent(comp, kComponentXGMIIStatistics, port);
		if( comp != kComponentInvalid) {
			xgmii_print_statistics_counters(card, comp);
		}
	}
	if(dag_config_get_card_type(card) == kDag810)
    	{	
    		/* Read Port information */
	    	comp = dag_component_get_subcomponent(root, kComponentPCS, port);
    	}
    	else
    	{
		/* Read Port information */
    		comp = dag_component_get_subcomponent(root, kComponentPort, port);
    	}

	dagx_print_port_counters(card, comp);
#endif 	
}

//This two functions is not used any more 
#if 0 
void
dagx_print_port_counters(dag_card_ref_t card, dag_component_t port)
{
	attr_uuid_t attr;
	if ((dag_config_get_component_code(port) != kComponentPort) && (dag_config_get_component_code(port) != kComponentPCS))
		return;
	
	attr = dag_component_get_attribute_uuid(port, kUint32AttributeErrorBlockCounter);
	print_attribute_value(card, attr);

	attr = dag_component_get_attribute_uuid(port, kUint32AttributeBERCounter);
	print_attribute_value(card, attr);
}

void
xgmii_print_statistics_counters(dag_card_ref_t card, dag_component_t xgmii_stats)
{
	attr_uuid_t attr;
	if (dag_config_get_component_code(xgmii_stats) != kComponentXGMIIStatistics)
		return;

	printf("XGMII counters:\n");
	attr = dag_component_get_attribute_uuid(xgmii_stats, kUint32AttributeRxFrames);
	print_attribute_value(card, attr);

	attr = dag_component_get_attribute_uuid(xgmii_stats, kUint64AttributeRxBytes);
	print_attribute_value(card, attr);

	attr = dag_component_get_attribute_uuid(xgmii_stats, kUint32AttributeTxFrames);
	print_attribute_value(card, attr);

	attr = dag_component_get_attribute_uuid(xgmii_stats, kUint64AttributeTxBytes);
	print_attribute_value(card, attr);

	attr = dag_component_get_attribute_uuid(xgmii_stats, kUint32AttributeCRCErrors);
	print_attribute_value(card, attr);

	attr = dag_component_get_attribute_uuid(xgmii_stats, kUint32AttributeShortPacketErrors);
	print_attribute_value(card, attr);

	attr = dag_component_get_attribute_uuid(xgmii_stats, kUint32AttributeLongPacketErrors);
	print_attribute_value(card, attr);

}
#endif


void
print_counters_header(dag_card_ref_t card)
{
    switch (dag_config_get_card_type(card))
    {
	case kDag37d:
	    dag37d_print_counters_header();
	    break;
        case kDag452e:
        case kDag454e:
        case kDag452gf:
        case kDag452cf:
        case kDag452z:
        case kDag452z8:
            dag45ge_print_counters_header();
            break;
	//case kDag52x:
	//case kDag82x:
	//case kDag82z:
	//case kDag810:
	//case kDag840: //FIXME: this is just temp here 
	//case kDag52sxa:
	//case kDag50s:
	//case kDag50dup:
	//case kDag50z:
	    break;

        default:
	    if(dag_config_get_number_block(card))
	    {
		/*If UCSI counters present print the header*/
		dagx_print_ucsi_counters_header(card);
	    }else
	    {
		/*else print normal counters header*/
	    dagx_print_counters_header(card);
	    }
            break;
    }
}
void
dagx_print_ucsi_counters_header(dag_card_ref_t card)
{
	dag_counter_value_t *counters=NULL;
	uint32_t nb_count = 0;
	uint32_t nb_block = 0;
	int nb_count_s = 0;
	int i, j;
	uint32_t *block_id = NULL;
	
	nb_block = dag_config_get_number_block(card);
	nb_count = dag_config_get_number_all_counters(card);
	
	#if 0
	/*dont need latch and clear now for printing headers.*/
	dag_config_latch_clear_all(card);
	#endif 

	if (nb_block > 0)
	{
		block_id = (uint32_t *)malloc(nb_block*sizeof(int32_t));
		for(j = 0; j < nb_block; j++)
		{
			nb_block = dag_config_get_all_block_id(card, block_id, nb_block);
			nb_count_s = dag_config_get_number_counters(card, (dag_block_type_t)block_id[j]);
				
			if (nb_count > 0)
			{
				counters = (dag_counter_value_t*)malloc(nb_count*sizeof(dag_counter_value_t));
				nb_count_s = dag_config_read_single_block(card, (dag_block_type_t)block_id[j], counters, nb_count_s, 0);
				/*Check if Subfunction Type is Port:*/
				if(counters[0].subfct == 0x00)	
				{	
					/* print value of counters */
					for (i=0; i < nb_count_s; i++)
					{
						if(counters[i].interface_number == 0)
						{	
							printf("%15.15s",id_counter_to_string(counters[i].typeID));	
						}
					}
				}
				free(counters);
			}
			else
				printf("No counters in block %s.\n", id_block_to_string(block_id[j]));
		}
		free(block_id);
	}
	else
		printf("No blocks \n");
}

void
dag37d_print_counters_header()
{
    printf("TxFrames  TxBytes  RxFrames  RxBytes  ");
}

void
dag37d_print_counters(dag_card_ref_t card_ref, int port)
{
    dag_component_t root_component;
    dag_component_t port_component;
    attr_uuid_t any_attribute;

    root_component = dag_config_get_root_component(card_ref);
    port_component = dag_component_get_subcomponent(root_component, kComponentPort, port);
    assert(port_component);

    /* Then read the counters */
    any_attribute = dag_component_get_attribute_uuid(port_component, kUint32AttributeTxFrames);
    assert(any_attribute != kNullAttributeUuid);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(port_component, kUint64AttributeTxBytes);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7" PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(port_component, kUint32AttributeRxFrames);
    assert(any_attribute != kNullAttributeUuid);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(port_component, kUint64AttributeRxBytes);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7" PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attribute));

}



void
dagx_print_counters_header(dag_card_ref_t card_ref)
{
#if 1
	attr_uuid_t any_attribute;
	dag_component_t root;
	int attr_count = 0;
	int i = 0;

    root = dag_config_get_root_component(card_ref);
    for( i = 0; i < ( sizeof (counter_attributes_array) / sizeof(counter_attributes_array[0])) ; i++) {
            attr_count = dag_config_get_attribute_count(card_ref,counter_attributes_array[i].attribute_code);
	    // This is only for the headers and we need only one instance 
 	    if( (attr_count > 0) && (counter_attributes_array[i].attribute_verbosity <= dagutil_get_verbosity()) )
	    {
		any_attribute = dag_config_get_indexed_attribute_uuid(card_ref, counter_attributes_array[i].attribute_code, 0);
		//code = dag_config_get_attribute_code(any_attribute);
		attribute_print_header(card_ref, any_attribute);
            }
    }
#else     
    printf("RxFrames  RxBytes  TxFrames  TxBytes  CRCErrs  ShortErrs  LongErrs  ErrBlock  HighBER  ");
#endif 
}




void
dag45ge_print_counters_header()
{
    printf("TxFrames  TxBytes  RxFrames  RxBytes  CRCErrs  RemoteErrs  BadSmbls  ConfigSeqs  ");
}

void
dag45ge_print_counters(dag_card_ref_t card_ref, int port)
{
    dag_component_t minimacstat_component;
    dag_component_t port_component;
    dag_component_t root_component;
    attr_uuid_t any_attribute;
    
    root_component = dag_config_get_root_component(card_ref);
    /* Read Port information */
    port_component = dag_component_get_subcomponent(root_component, kComponentPort, port);
    assert(port_component);
    minimacstat_component = dag_component_get_subcomponent(port_component, kComponentMiniMacStatistics, 0);
    if(minimacstat_component == NULL)
    {
        /* no component exists */
        return; 
    }
    
    /* we latch the counters before we call this function. Since the latches we can use are global
     * we can't have per attribute latches and if this function is called in sequence with another
     * function that does counter printing, if we latched here and then latched in the other
     * function the data would have already been cleared by the initial latch.
     */

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeTxFrames);
    assert(any_attribute != kNullAttributeUuid);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint64AttributeTxBytes);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7" PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeRxFrames);
    assert(any_attribute != kNullAttributeUuid);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint64AttributeRxBytes);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7" PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeCRCErrors);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeRemoteErrors);
    assert(any_attribute != kNullAttributeUuid);
    printf("%10u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeBadSymbols);
    assert(any_attribute != kNullAttributeUuid);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeConfigSequences);
    assert(any_attribute != kNullAttributeUuid);
    printf("%10u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));

}



