/*	       lact_lan.c   2.02.000 20JUN99 12:44  */

#include "sys.h"
#include "lac.h"
#include "lact_lan.h"
/******************************************************************************
 * LACT LAN : LACP TESTER : LAN ATTACH, RECEPTION AND TRANSMISSION MONITORING
 ******************************************************************************
 */
/******************************************************************************
 * LACT LAN : DISPLAY ROUTINES
 ******************************************************************************
 */
/*---------------------------------------------------------------------------*/
static void print_physical_port(Lac_port *port)
{
   printf("%d.%d ", port->system->id, port->port_no);
}

/*---------------------------------------------------------------------------*/
static void print_info(Lac_info *i)
{
   Lac_state *is = &i->state;
   printf("%d.%3d:%d.%d=%d ",  i->system_priority, i->system_id,
                               i->port_priority, i->port_no,
                               i->key);
 
   if (is->lacp_activity)           printf("Active   ");
                               else printf("Passive  ");
   if (is->lacp_timeout)            printf("Nervous  ");
                               else printf("   .     ");
   if (is->aggregation)             printf("Aggregate  ");
                               else printf("   .       ");
   if (is->synchronization)         printf("In sync  ");
                               else printf("   .     ");
   if (is->collecting)              printf("Collecting  ");
                               else printf("   .        ");
   if (is->distributing)            printf("Distributing  ");
                               else printf("              ");
   if (is->defaulted)               printf("Defaulted  ");
                               else printf("           ");
   if (is->expired)                 printf("Expired");
                               else printf("       ");
   printf("\n");
}
/*---------------------------------------------------------------------------*/
static void print_pdu(Lac_pdu *pdu)
{
   printf("Actor   "); print_info(&pdu->actor);
   printf("                   ");
   printf("Partner "); print_info(&pdu->partner);
}
/*---------------------------------------------------------------------------*/
static void test_rx(Node *node, void *pdu)
{/*
  * rx_fn() for physical port's mac node.
  */
   Lac_port *port  = (Lac_port *)node->owner;
   Lac_pdu   *lacpdu = (Lac_pdu   *)pdu;

   printf("%4d.%1d:", sys_time()/10,sys_time()%10);
   printf("RX at ");
   print_physical_port(port);
   print_pdu(lacpdu);
   printf("\n");

   lac_rx(port, lacpdu);
}
/*---------------------------------------------------------------------------*/
static void test_tx(Node *node, void *pdu)
{/*
  * tx_fn() for physical port's mac node.
  */
   Lac_port *port  = (Lac_port *)node->owner;
   Lac_pdu   *lacpdu = (Lac_pdu   *)pdu;

   printf("%4d.%1d:", sys_time()/10,sys_time()%10);
   printf("TX at ");
   print_physical_port(port);
   print_pdu(lacpdu);
   printf("\n");

   sys_lan_tx(node, pdu);
}
/*---------------------------------------------------------------------------*/
void test_mux_rx_status(Node *mux, Boolean yes, Node *mac)
{/*
  * rx_status_fn() for port's mux node.
  */
   Lac_port *aport = (Lac_port *)mux->owner;
   Lac_port *port  = (Lac_port *)mac->owner;

   printf("%4d.%1d:", sys_time()/10,sys_time()%10);
   printf("      %d.%d ", port->system->id, port->port_no);

   if (yes)
   {
      printf("Collector    Enabled for Aggregate Port");
   }
   else
   {
      printf("Collector   Disabled for Aggregate Port");
   }

   printf(" %d.%d  \n\n",aport->system->id, aport->port_no);
}
/*---------------------------------------------------------------------------*/
void test_mux_tx_status(Node *mux, Boolean yes, Node *mac)
{/*
  * tx_status_fn() for port's mux node.
  */

   Lac_port *aport = (Lac_port *)mux->owner;
   Lac_port *port  = (Lac_port *)mac->owner;

   printf("%4d.%1d:", sys_time()/10,sys_time()%10);
   printf("      %d.%d ",port->system->id, port->port_no);

   if (yes)
   {
      printf("Distributor  Enabled for Aggregate Port");
   }
   else
   {
      printf("Distributor Disabled for Aggregate Port");
   }

   printf(" %d.%d  \n\n",aport->system->id, aport->port_no);
}
/******************************************************************************
 * LACT LAN : CREATE AND ATTACH (DETACH) PHYSICAL PORTS TO (FROM) LANS
 ******************************************************************************
 */
/*---------------------------------------------------------------------------*/
extern void lact_lan_attach(Lan *lan, Lac_port *port)
{
   sys_attach_lan_node(lan, &port->mac);
    
   port->mac.rx_fn = &test_rx;
   port->mac.tx_fn = &test_tx;
}
/*---------------------------------------------------------------------------*/
extern void lact_lan_detach(Lac_port *port)
{
   sys_detach_lan_node(&port->mac);
    
   port->mac.rx_fn = &test_rx;
   port->mac.tx_fn = &test_tx;
}
/*---------------------------------------------------------------------------*/
static void lact_user_attach(Lac_port *port)
{
   port->mux.rx_status_fn = &test_mux_rx_status;
   port->mux.tx_status_fn = &test_mux_tx_status;
}
/*---------------------------------------------------------------------------*/
extern void lact_add_port(Lac_system *system,
                          Port_no port_no, Lac_port **port, Lan *lan)
{
   if (lac_create_port(system,  port_no, port))
   {
      lact_lan_attach(lan, *port);
      lact_user_attach(*port);
}  }
/******************************************************************************
 * LACT : TEST TIMING
 ******************************************************************************
 */
extern void lact_run_for(int advance_time_by)
{  int i;
   for (i=0;i< advance_time_by;i++)
   {
      sys_tick();
   }
}

/******************************************************************************
 * LACT: TEST PDU CREATION AND TRANSMISSION
 ******************************************************************************
 */

extern void lact_txpdu(Node *tester,
   Port_no         a_port_priority,     Port_no   a_port_no,
   System_priority a_system_priority,   System_id a_system_id,
   Key             a_key,
   Flag a_lacp_activity,   Flag a_lacp_timeout, Flag a_aggregation,
   Flag a_synchronization, Flag a_collecting,   Flag a_distributing,

   Port_no         p_port_priority,     Port_no   p_port_no,
   System_priority p_system_priority,   System_id p_system_id,
   Key             p_key,
   Flag p_lacp_activity,   Flag p_lacp_timeout, Flag p_aggregation,
   Flag p_synchronization, Flag p_collecting,   Flag p_distributing)
{
   Lac_pdu *m; Lac_info *a; Lac_info *p; Lac_state *as; Lac_state *ps;

   if (sysmalloc(sizeof(Lac_pdu), &m))
   {
   a = &m->actor; p = &m->partner; as = &a->state; ps = &p->state;

   a->port_priority   = a_port_priority;   a->port_no   = a_port_no;
   a->system_priority = a_system_priority; a->system_id = a_system_id;
   a->key = a_key;
   as->lacp_activity = a_lacp_activity; as->lacp_timeout    = a_lacp_timeout;
   as->aggregation = a_aggregation; as->synchronization = a_synchronization; 
   as->collecting  = a_collecting;  as->distributing    = a_distributing;
   as->defaulted = False;       as->expired   = False;
   p->port_priority   = p_port_priority;   p->port_no   = p_port_no;
   p->system_priority = p_system_priority; p->system_id = p_system_id;
   p->key = p_key;
   ps->lacp_activity = p_lacp_activity; ps->lacp_timeout    = p_lacp_timeout;
   ps->aggregation = p_aggregation; ps->synchronization = p_synchronization; 
   ps->collecting  = p_collecting;  ps->distributing    = p_distributing;
   ps->defaulted   = False;         ps->expired         = False;

   sys_tx(tester, m);
   sysfree(m);
}  }

/******************************************************************************
 * LACT LAN : ATTACH (DETACH) LAN TESTER GENERATORS & MONITORS
 ******************************************************************************
 */
/*---------------------------------------------------------------------------*/
static void tester_rx(Node *tester, void *msg){}

/*---------------------------------------------------------------------------*/
static void tester_tx(Node *tester, void *msg){}

/*---------------------------------------------------------------------------*/
static void tester_rx_status(Node *tester, Boolean yes, void *arg){}

/*---------------------------------------------------------------------------*/
static void tester_tx_status(Node *tester, Boolean yes, void *arg){}

/*---------------------------------------------------------------------------*/
void lact_init_tester(Node *tester)
{
   init_node(tester, tester);

   tester->rx_fn        = &tester_rx;

   tester->rx_status_fn = &tester_rx_status;
   tester->tx_status_fn = &tester_tx_status;
}


