/*
 *  * Copyright (c) 2007 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.
 **
 ** 
 **/

/*headers */
#include "dag_config_api.h"
#include "dag_platform.h"
#define REPEAT_N_TIMES 100


static int print_auto_neg_speed(char *dag_name, int port_index)
{
    dag_card_ref_t card_ref;
    dag_component_t root_component = NULL;
    dag_component_t port_component = NULL;
    attr_uuid_t attr_line_rate = kNullAttributeUuid;
    attr_uuid_t attr_aug_neg_comp = kNullAttributeUuid;
    int port_count = 0;
    line_rate_t line_speed= kLineRateInvalid;
    bool is_neg_complete = 0;
    int loop_count = 0;
    /* get the card reference , root component and port component */
    card_ref = dag_config_init(dag_name);
    if (NULL == card_ref)
    {
        printf("No card\n");
        return -1;
    }
    root_component = dag_config_get_root_component(card_ref);
    if ( NULL == root_component)
    {
        printf("No root component\n");
        return -1;
    }
    port_count = dag_component_get_subcomponent_count_of_type(root_component, kComponentPort);
    if ( 0 == port_count)
    {
        printf("No Port component found \n");
        return -1;
    }
    if ( port_count < port_index )
   {
        printf("Invalid port Index\n");
        return -1;
    }
    port_component = dag_component_get_subcomponent(root_component, kComponentPort, port_index);
    if ( NULL == port_component)
    {
        printf("Null port component at index %d\n",port_index);
        return -1;
    }
    /* check for auto_neg_complete attribute , if so check for its value and wait till it is set or time out*/
    attr_aug_neg_comp = dag_component_get_attribute_uuid( port_component, kBooleanAttributeAutoNegotiationComplete);
    if ( kNullAttributeUuid == attr_aug_neg_comp)
    {
        /* no auto_neg_complete attribute. This could be an optics transeiver module*/
        printf("NULL auto_neg_complete attribute. Is Optics module?");
    }
    else
    {
        /* check for auto_neg_complete with a time out mechanism*/
       while(loop_count < REPEAT_N_TIMES)
        {
            is_neg_complete = dag_config_get_boolean_attribute(card_ref, attr_aug_neg_comp);
            if (is_neg_complete)
                /* negotiation complete. stop waiting*/
                break;
            /* sleep for a millisecond  REPEAT_N_TIMES times*/
            usleep(30000);
            loop_count++;
        }
    }
    /* get the line rate  attribute*/
    attr_line_rate = dag_component_get_attribute_uuid( port_component, kUint32AttributeLineRate);
    if ( kNullAttributeUuid == attr_line_rate)
    {
        printf("NULL line_rate attribute");
    }
    else
    {
        /* get its value. check the possible values for line_rate_t */
        line_speed = (line_rate_t)dag_config_get_uint32_attribute(card_ref, attr_line_rate);
    }
   
    /* here using the  string converted value of line_rate*/ 
    printf("Port%d AutoNeg is %s completed LineSpeed: %s (Enum value = %u) \n",port_index, (is_neg_complete)?"":"not", dag_config_get_attribute_to_string(card_ref, attr_line_rate),(uint32_t)line_speed);
    return 0;
}


int main(int argc, char *argv[])
{
    char dag_name[64]="dag0";
    int index = 0;
    printf("Example  to get the  line speed .\n Usage is %s <dag> <port_number>\n", argv[0]);
    if ( argc > 1)
    {
        strcpy(dag_name, argv[1]);
    }
    if ( argc > 2)
    {
        index = atoi( argv[2]);
    }
    printf("Using Card %s\n", dag_name);
    
    if ( -1 != print_auto_neg_speed(dag_name, index) )
    {
        printf("Succes..\n");
    }
    else
    {
        printf("Failed ..\n");
    }
    return 0;
 
}
