
// COMPILER
#include <stdarg.h>
#include "string.h"
// STELARISWARE
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_nvic.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/timer.h"

#include "utils/softeeprom.h"
// PROJECT INCLUDES
#include "sniffer.h"
#include "radio/packet.h"
#include "radio/at86rf231.h"
#include "radio/at86rf212.h"
#include "radio/spi.h"
#include "net/http_conf.h"
#include "net/ethernetwrapper.h"
#include "myutils/crc.h"
#include "myutils/packetfifo.h"
#include  "net/zep.h"

//*****************************************************************************
//
//! \defgroup sniffer_api Sniffer
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
//! Defines for setting up the system clock.
//
//*****************************************************************************
#define SYSTICKHZ               100
#define SYSTICKMS               (1000 / SYSTICKHZ)
#define SYSTICKUS               (1000000 / SYSTICKHZ)
#define SYSTICKNS               (1000000000 / SYSTICKHZ)


//#define CPU_XTAL 8000000
//	#define DELAY_CYCLES 3
//	#define SYSCTL_DELAY (CPU_XTAL/DELAY_CYCLES)/1000000

#define SYSCTL_DELAY_8MHZ    0.375
#define SYSCTL_DELAY_50MHZ   0.06

#define timerMAX_32BIT_VALUE     ( 0xffffffffUL )

//*****************************************************************************
//
// !Interrupt priority definitions.  The top 3 bits of these values are
// !significant with lower values indicating higher priority interrupts.
//
//*****************************************************************************
//#define TIMER_INT_PRIORITY      0x00
//#define TRX_INT_PRIORITY        0x40
//#define SYSTICK_INT_PRIORITY    0x80
//#define ETHERNET_INT_PRIORITY   0xC0

#define TIMER_INT_PRIORITY      0x20
#define TRX_INT_PRIORITY        0x00
#define SYSTICK_INT_PRIORITY    0x40
#define ETHERNET_INT_PRIORITY   0x80

//*****************************************************************************
//
//! Global variables
//
//*****************************************************************************
    unsigned long g_TimeCounter;	


    tSnifferSettings  sniffer;
    
    unsigned long g_PacketCount;
    unsigned long g_PacketDrop;
//*****************************************************************************
//
//! The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG

#include "myutils/uartstdio.h"

void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif

void DebugInit(void)
{
#ifdef DEBUG
	#define BAUD_RATE 460800

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
	GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
	UARTStdioInitExpClk(0,BAUD_RATE);
#endif	
}

//*****************************************************************************
//
//! Debug messages
//!
//! Description 1
//!
//! \param str is constant format of output
//!
//! \param ... is any other variables
//
//*****************************************************************************

void DebugMsg(const char* str, ...)
{
#ifdef DEBUG
    va_list vaArgP;
    va_start(vaArgP, str);
	UARTvprintf(str,vaArgP);
	va_end(vaArgP);
#endif
}

//*****************************************************************************
//
// The interrupt handler for the SysTick interrupt.
//
//*****************************************************************************
void SysTickIntHandler(void)
{
    //
    // Call the lwIP timer handler.
    //
    lwIPTimer(SYSTICKMS);
}
//*****************************************************************************

// delay in us (should be revised)
void delay(unsigned long ul)
{

    //SysCtlDelay(SYSCTL_DELAY*ul);
    //SysCtlDelay((unsigned long)(ul/SYSCTL_DELAY));
  SysCtlDelay((unsigned long)(ul/SYSCTL_DELAY_8MHZ));
    
        
}

//*****************************************************************************

void trx212_irq_init(void)
{
  SysCtlPeripheralEnable(TRX212_PERIPHERAL);  
  GPIODirModeSet(TRX212_IO_IRQ, GPIO_DIR_MODE_HW); 
  GPIOPadConfigSet(TRX212_IO_IRQ, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); 
  GPIOIntTypeSet(TRX212_IO_IRQ, GPIO_RISING_EDGE); 
  GPIOPinIntEnable(TRX212_IO_IRQ); 
  IntEnable(TRX212_PORT_IRQ);
}
//*****************************************************************************

void trx231_irq_init(void)
{
  SysCtlPeripheralEnable(TRX231_PERIPHERAL);  
  GPIODirModeSet(TRX231_PORT_BASE, TRX231_IRQ, GPIO_DIR_MODE_HW); 
  GPIOPadConfigSet(TRX231_PORT_BASE, TRX231_IRQ, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); 
  GPIOIntTypeSet(TRX231_PORT_BASE, TRX231_IRQ, GPIO_RISING_EDGE); 
  GPIOPinIntEnable(TRX231_PORT_BASE, TRX231_IRQ); 
  IntEnable(TRX231_PORT_IRQ);
}
//*****************************************************************************

void trx231_io_init(void)
{
    SysCtlPeripheralEnable(TRX231_PERIPHERAL); 	
    GPIOPinTypeGPIOOutput(TRX231_PORT_BASE, TRX231_RST | TRX231_SLP | TRX231_SEL);	 							
 	
	trx231_pinset_slptr(0);
 	trx231_pinset_reset(1);
 	trx231_pinset_select(1);
 	
// 	SysCtlPeripheralEnable(LED_PERIPHERAL);
// 	GPIOPinTypeGPIOOutput(LED_PORT_BASE, LED_GREEN);
// 	
// 	ledgreen_pinset(0);
}
//*****************************************************************************

void trx212_io_init(void)
{
    SysCtlPeripheralEnable(TRX212_PERIPHERAL); 	
    //GPIOPinTypeGPIOOutput(TRX231_PORT_BASE, TRX231_RST | TRX231_SLP | TRX231_SEL);	 							
    GPIOPinTypeGPIOOutput(TRX212_IO_SEL);
    GPIOPinTypeGPIOOutput(TRX212_IO_RST);
    GPIOPinTypeGPIOOutput(TRX212_IO_SLP);
 	
    trx212_pinset_slptr(0); 	
    trx212_pinset_reset(1); 	
    trx212_pinset_select(1);
 	
}

//*****************************************************************************

void ledgreen_pinset(tBoolean val)
{
  if(val)
  	GPIOPinWrite(LED_PORT_BASE, LED_GREEN, 0xFF);
  else
    GPIOPinWrite(LED_PORT_BASE, LED_GREEN, 0x00);  	
}

//*****************************************************************************
void LED_init(void)
{
    SysCtlPeripheralEnable(LED_PERIPHERAL); 	
    GPIOPinTypeGPIOOutput(LED_PORT_BASE, LED_GREEN); 	
    ledgreen_pinset(0);  

}
//*****************************************************************************

void trx231_pinset_select(tBoolean val)
{
  if(val)
  	GPIOPinWrite(TRX231_PORT_BASE, TRX231_SEL, 0xFF);
  else
    GPIOPinWrite(TRX231_PORT_BASE, TRX231_SEL, 0x00);  	
}
//*****************************************************************************

void trx231_pinset_reset(tBoolean val)
{
  if(val)
  	GPIOPinWrite(TRX231_PORT_BASE, TRX231_RST, 0xFF);
  else
    GPIOPinWrite(TRX231_PORT_BASE, TRX231_RST, 0x00);  	
}
//*****************************************************************************

void trx231_pinset_slptr(tBoolean val)
{
  if(val)
  	GPIOPinWrite(TRX231_PORT_BASE, TRX231_SLP, 0xFF);
  else
    GPIOPinWrite(TRX231_PORT_BASE, TRX231_SLP, 0x00);  
}
//*****************************************************************************

void trx212_pinset_select(tBoolean val)
{
  if(val)
    GPIOPinWrite(TRX212_IO_SEL, 0xFF);
  else
    GPIOPinWrite(TRX212_IO_SEL, 0x00);  	
}
//*****************************************************************************

void trx212_pinset_reset(tBoolean val)
{
  if(val)
    GPIOPinWrite(TRX212_IO_RST, 0xFF);
  else
    GPIOPinWrite(TRX212_IO_RST, 0x00);  	
}
//*****************************************************************************

void trx212_pinset_slptr(tBoolean val)
{
  if(val) 
    GPIOPinWrite(TRX212_IO_SLP, 0xFF);
  else
    GPIOPinWrite(TRX212_IO_SLP, 0x00);  
}
//*****************************************************************************

void Trx231IntHandler(void) 
{   
    GPIOPinIntClear(TRX231_PORT_BASE, TRX231_IRQ);
    g_PacketCount+=1;
    trx231_irq();
    
}
//*****************************************************************************

void Trx212IntHandler(void) 
{   
    GPIOPinIntClear(TRX212_IO_IRQ);
    g_PacketCount+=1;
    trx212_irq();    
}

//*****************************************************************************
//
// Write
//
//*****************************************************************************
tBoolean Settings_Write(tSnifferSettings *sett)
{
     
    unsigned char *ptr_sett=(unsigned char*)sett;  
    unsigned short id;
    unsigned short crc=0x0000;   
               
    
    DebugMsg("Size of Settings=%d\n",sizeof(tSnifferSettings));  
    
    sett->setIpConfig=false;
      
    //
    // write sniffer settings to emulation EEPROM
    //
    for(id=0;id<(sizeof(tSnifferSettings));id++)  //div 2 WARNING !!!!!!!!!!!!!!!
    {
      if(SoftEEPROMWrite(id, ptr_sett[id])!=0)
      {
         DebugMsg("SoftEEPROM write failed on %d\n",id);
         return false;
         
      }
      crc = update_crc(crc, ptr_sett[id]);
    } 
    
    if(SoftEEPROMWrite(id, crc)!=0)
    {    
      DebugMsg("SoftEEPROM write failed on %d\n",id); 
      return false;
    }
    
    DebugMsg("Settings_Write OK\n");
      
    return true;
}

//*****************************************************************************
//
// Default
//
//*****************************************************************************

tBoolean Settings_Default(tSnifferSettings *sett)
{
	sett->state = STOPPED;

	sett->dhcpOn=false;
        
        sett->filterCrc=false;
        
	sett->ipaddr[0]=10;
	sett->ipaddr[1]=10;
	sett->ipaddr[2]=10;
	sett->ipaddr[3]=2; 

	sett->nmask[0]=255;
	sett->nmask[1]=255;
	sett->nmask[2]=255;
	sett->nmask[3]=0;
	
	sett->gw[0]=10;
	sett->gw[1]=10;
	sett->gw[2]=10;
	sett->gw[3]=1;
	
	sett->channel = 15;
        
        sett->radio = TRX231;
		
	sett->filterPanId[0] = 0;
	sett->filterPanId[1] = 0;
        
        sett->reipaddr[0]=10;
	sett->reipaddr[1]=10;
	sett->reipaddr[2]=10;
	sett->reipaddr[3]=1;
        
        sett->report=17754;
        
        sett->sensitivity=HIGH;
        
        sett->setIpConfig=false;
        
        //
        //Save Default setting to Flash memory
        //
        if(!Settings_Write(sett))
          return false;
        
        return true;

}

//*****************************************************************************
//
// Init
//
//*****************************************************************************
tBoolean Settings_Read(tSnifferSettings *sett)
{
    
    unsigned char *ptr_sett=(unsigned char*)sett;  
    unsigned char id;
    unsigned short data,crc=0x0000; 
    tBoolean found;
    
  
    //
    // read sniffer settings from emulation EEPROM
    // 

    
    for(id=0;id<(sizeof(tSnifferSettings));id++) 
    {
      
      
      if(SoftEEPROMRead(id, &data, &found)!=0)
      {
         DebugMsg("SoftEEPROM read failed on %d\n",id);
         return false;          
      }
      
      //if read is succesfull than check founded data
      if(found==true)
      {
        ptr_sett[id]=data;        
        crc = update_crc(crc, ptr_sett[id]);
      }
      else
      {
        DebugMsg("SoftEEPROM was not found on %d\n",id);
        return false;
      }
      
    } 
    
      if(SoftEEPROMRead(id, &data, &found)!=0)
      {
         DebugMsg("SoftEEPROM read failed on %d\n",id);
         return false;          
      }
      
      //if read is succesfull than check founded data
      if(found==false)
      {
        DebugMsg("SoftEEPROM was not found on %d\n",id);
        return false;
      }
    
    DebugMsg("SoftEEPROM CRC: %04x %04x\n",data, crc);

    if((data!=crc) || (data==0) || (crc==0))
    {
      DebugMsg("SoftEEPROM CRC fail, Setting Default\n");
      if(!Settings_Default(sett))
        return false;
     
    
    }
        
    DebugMsg("Radio=%s (%d)\n",(sett->radio ? "TRX212":"TRX231" ),sett->radio);
    DebugMsg("State=%d, IP=%d.%d.%d.%d\n",sett->state,   
             sett->ipaddr[0], sett->ipaddr[1],sett->ipaddr[2],sett->ipaddr[3]);
    
    DebugMsg("Mask=%d.%d.%d.%d, GW=%d.%d.%d.%d\n",sett->nmask[0],
             sett->nmask[1],sett->nmask[2],sett->nmask[3],
             sett->gw[0],sett->gw[1],sett->gw[2],sett->gw[3]);
    
    DebugMsg("ReIP=%d.%d.%d.%d, RePort=%d, Ch=%d, Sens=%d\n",sett->reipaddr[0],
             sett->reipaddr[1],sett->reipaddr[2],sett->reipaddr[3],
             sett->report, sett->channel,sett->sensitivity);

    DebugMsg("Setting Read OK\n");
    return true;
}

//*****************************************************************************
tBoolean Settings_Init(void)
{  
              
    //
    // initialize SoftEEPROM functionality and setup EEPROM area
    //
    if (SoftEEPROMInit(SOFTEEPROM_START, SOFTEEPROM_END, SOFTEEPROM_SIZE) != 0)
    {    	
      DebugMsg("SoftEEPROM Init failed\n");
      return false;
    
    }
    
    return true;
}
//*****************************************************************************
//
// The interrupt handler for the second timer interrupt.
//
//*****************************************************************************
void
Timer1IntHandler(void)
{
    //
    // Clear the timer interrupt.
    //
    TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);

    //
    // Update the periodic interrupt counter.
    //
    g_TimeCounter+=1;
    //DebugMsg("Timer=%u\n",g_TimeCounter);
    
    
}
//*****************************************************************************
//
// The interrupt init for Timer1.
//
//*****************************************************************************
void
Timer1_init(void)
{ 
    //
    // Enable the peripherals used by this example.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);

    //
    // Configure the two 32-bit periodic timers. Handle every 1ms.
    //
    TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER);  
    TimerLoadSet(TIMER1_BASE, TIMER_A, timerMAX_32BIT_VALUE);
    
    //
    // Setup the interrupts for the timer timeouts.
    //      
    IntEnable(INT_TIMER1A);
    TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);

    //
    // Enable the timers.
    //
    TimerEnable(TIMER1_BASE, TIMER_A);  
}


//*****************************************************************************
//
//  Turn default Trx radio to RX_ON state
//  
//
//*****************************************************************************
void Trx_IntEnable(void)
{
                
  IntEnable(TRX212_PORT_IRQ); 
  IntEnable(TRX231_PORT_IRQ);
              
}

//*****************************************************************************
//
//  Turn default Trx radio to RX_ON state
//  
//
//*****************************************************************************
void Trx_IntDisable(void)
{
              
  IntDisable(TRX212_PORT_IRQ); 
  IntDisable(TRX231_PORT_IRQ);  


}
//*****************************************************************************
//
//  Turn default Trx radio to RX_ON state
//  
//
//*****************************************************************************
tBoolean Trx_RUN(void)
{
  
  switch(sniffer.radio)
  {
  case TRX212:
    {      
      if(trx212_setstate_RX_ON()==false)           
        return false;
     
      break;
    }
    
      
  case TRX231:
    {      
      if(trx231_setstate_RX_ON()==false)           
        return false;
     
      break;
    }
  
  default: 
    return false;
  }  
  
  return true;                                  

}

//*****************************************************************************
//
//!  Turn default Trx radio to TRX_OFF state 
//
//*****************************************************************************
tBoolean Trx_STOP(void)
{
  
  switch(sniffer.radio)
  {
  case TRX212:
    {      
      if(trx212_setstate_TRX_OFF()==false)           
        return false;
     
      break;
    }
    
      
  case TRX231:
    {      
      if(trx231_setstate_TRX_OFF()==false)           
        return false;
     
      break;
    }
  
  default: 
    return false;
  }  
    
  return true;                                  

}
//*****************************************************************************
//
//  Set the Trx radio as default.
//  Default radio is in RX_ON state, other in TRX_OFF
//
//*****************************************************************************
tBoolean Trx_config(void)                  
{
  tBoolean tconf;
  
  //
  //if channel is 0..10 than its for TRX212
  //
  if(sniffer.channel <=10)
  {
    
        //
        //check if TRX231 is on TRX_OFF state
        //
        if(trx231_get_state()!=TRX_OFF)
        {
          if(trx231_setstate_TRX_OFF()==false)
            return false;     
        }
        
        //
        //Turn Trx212 to RX_ON state
        //
        if((trx212_get_state()!=RX_ON) && (sniffer.state==RUNNING)) 
        {
          if(trx212_setstate_RX_ON()==false)           
            return false;     
        } 
        
        tconf=trx212_set_config(sniffer.channel, sniffer.sensitivity, 
                                sniffer.filterPanId, sniffer.state);
        
        DebugMsg("Settings TRX212 return=%s\n",(tconf ? "OK" : "Bad"));
        if(tconf==false)
          return false;
        
        sniffer.radio=TRX212;
        
        DebugMsg("TRX212 is configed\n");
          
        return true;   
    
    
  }
  
  //if channel is 11..26 than its for TRX231
  else if((sniffer.channel >=11) && (sniffer.channel <=26))
  {
        
        //
        //check if TRX212 is on TRX_OFF state
        //
        if(trx212_get_state()!=TRX_OFF)
        {
          if(trx212_setstate_TRX_OFF()==false)
            return false;     
        }
        
        //Turn Trx231 to RX_ON state
        if((trx231_get_state()!=RX_ON) && (sniffer.state==RUNNING)) 
        {
          if(trx231_setstate_RX_ON()==false)           
            return false;     
        }  
        
        tconf=trx231_set_config(sniffer.channel, sniffer.sensitivity, 
                                sniffer.filterPanId, sniffer.state);
        
        DebugMsg("Settings TRX212 return=%s\n",(tconf ? "OK" : "Bad"));
        
        if(tconf==false)
          return false;               
        
        sniffer.radio=TRX231;
        DebugMsg("TRX231 is configed\n");

        
        return true;
    
  }

  return false;

}
//*****************************************************************************
//
// Trx init for AT86RF231 and AT86RF212
//
//*****************************************************************************
tBoolean Trx_init(void)
{
   
    //Init for AT86RF231
  
  if(!trx231_init(&sniffer, &g_TimeCounter))
    return false;   
  
  //Read information about devide
  trx231_print_ident();

  // set transciever to promiscuos mode
  trx231_set_promiscuos_mode();
  
  
  DebugMsg("Init TRX231 seccess\n");
  
  
  //Init for AT86RF212
  
  if(!trx212_init(&sniffer, &g_TimeCounter))
    return false;
  
  //Read information about devide
  trx212_print_ident();

  // set transciever to promiscuos mode
  trx212_set_promiscuos_mode();

  
  DebugMsg("Init TRX212 seccess\n");
  
  //Init was seccesfull

  return true;
}


//*****************************************************************************
//
// Trx init for AT86RF231 and AT86RF212
//
//*****************************************************************************
void Button_init(void)
{
      
    SysCtlPeripheralEnable(BUTTON_PERIPHERAL);
    GPIODirModeSet(BUTTON_IO, GPIO_DIR_MODE_IN);
    GPIOPadConfigSet(BUTTON_IO, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);


}
//*****************************************************************************
//
// Main
//
//*****************************************************************************

int main(void)
{
    unsigned long g_zepCounter;
    unsigned long *pucTemp;
        
    unsigned long *ulIp, *ulMask, *ulGw;

    // Set the clocking to run directly from the crystal. System clock is 8MHz.
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);
    
    
    //
    // Configure SysTick for a periodic interrupt.
    //
    SysTickPeriodSet(SysCtlClockGet() / SYSTICKHZ);
    SysTickEnable();
    SysTickIntEnable();
    
        
    //
    // Configure GPIO pin of Reset button.
    //
    Button_init();
    
    //
    // Configure GPIO pin of LED for sniffer status
    //
    LED_init(); 
   
    //
    // Init Ports, Irq etc.
    //
    DebugInit(); 
    
    
    //
    // Calculate all variant of CRC for packet checksum radio modules
    //
    init_crc_tab();
    
    
    //
    // Initialization emulation EEPROM on FLASH memory
    //
    if(Settings_Init()==false)
    {
      DebugMsg("Setting Init failed\n");
      while(1);
    
    }
    
    //
    // Read previous configuration from FLASH memory
    //
    if(Settings_Read(&sniffer)==false)
    {
      DebugMsg("Setting Read failed\n");
      Settings_Default(&sniffer);
      
    }
    
    //
    // Set default settings if Reset button has been pressed.
    //
    if(GPIOPinRead(BUTTON_IO) == 0)
    {
      DebugMsg("Button was push and Settings is Default\n");
      Settings_Default(&sniffer);
    }


        
    DebugMsg("\nSniffer running\n");
    DebugMsg("System clock = %d Hz\n", SysCtlClockGet());
	
  
    //
    // Configure Ethernet pins and mode
    //
    EthernetPeriphInit(); 

    //
    // Enable processor interrupts.
    //
    IntMasterEnable();

    //
    // Set Ethernet MAC address
    //
    EthernetSetInternalMacAddr((unsigned char *)&sniffer.macaddr);
   
    //
    // Initialize the lwIP library
    //                       
    IpStackInit(&sniffer);

    //
    // Initialize httpd server.
    //                    
    HttpdInit(&sniffer);  
	
    //
    // Configure SPI interface
    //
    spi_init();       
	
    //
    // Prepare FIFO buffer for savings packets
    //
    packetFifoInit();       
	
    //
    // Configure pins Radio modules AT86RF212, AT86RF231
    //
    trx231_io_init(); 
    trx212_io_init();   
    
    //
    // Configure intterup pins of Radio modules
    //
    trx212_irq_init();
    trx231_irq_init();    
        
    //
    // Set the interrupt priorities. 
    //
    IntPriorityGroupingSet(4);
    IntPrioritySet(INT_ETH, ETHERNET_INT_PRIORITY);
    IntPrioritySet(FAULT_SYSTICK, SYSTICK_INT_PRIORITY);
    IntPrioritySet(INT_TIMER1A, TIMER_INT_PRIORITY);
    IntPrioritySet(TRX231_PORT_IRQ, TRX_INT_PRIORITY);
    IntPrioritySet(TRX212_PORT_IRQ, TRX_INT_PRIORITY);

    //
    // Prepare ZEP protocol
    //
    zep_init(&g_zepCounter, &sniffer);
     
    //
    // Initialize Radio modules to promiscuous mode
    //
    if(Trx_init()==false)
    {
      DebugMsg("Inicialization Trx error\n");
      sniffer.state=ERROR;
      
      //infinity loop
      while(1);    
    }
    
    DebugMsg("Inicialization Trx successed\n");
    
    //
    // Configure Radio modules, channel, sensitivity, PAN filter
    //    
    if(Trx_config()==false)
    {
      DebugMsg("Config Trx error\n");
      sniffer.state=ERROR;
      
      //infinity loop
      while(1);
    
    }
    
    DebugMsg("Config Trx successed\n");
    
    //
    // Run default Radio module
    //
    if(Trx_RUN()==false)
    {
      DebugMsg("RUN Trx error\n");
      sniffer.state=ERROR;
      
      //infinity loop
      while(1);
    
    }
    
    //
    // If every configuration before was seccessed, than sniffer is running
    //
    sniffer.state = RUNNING;
    
    
    //
    // Reset all global variables
    //
    Timer1_init();
    g_TimeCounter=0;
    g_PacketCount=0;
    g_PacketDrop=0;
    g_zepCounter=0;
   
    
    
    DebugMsg("Radio=%s (%d)\n",(sniffer.radio ? "TRX212":"TRX231" ),sniffer.radio);
    DebugMsg("State=%d, IP=%d.%d.%d.%d\n",sniffer.state,   
             sniffer.ipaddr[0], sniffer.ipaddr[1],sniffer.ipaddr[2],sniffer.ipaddr[3]);
    
    DebugMsg("Mask=%d.%d.%d.%d, GW=%d.%d.%d.%d\n",sniffer.nmask[0],
             sniffer.nmask[1],sniffer.nmask[2],sniffer.nmask[3],
             sniffer.gw[0],sniffer.gw[1],sniffer.gw[2],sniffer.gw[3]);
    
    DebugMsg("ReIP=%d.%d.%d.%d, RePort=%d, Ch=%d, Sens=%d\n",sniffer.reipaddr[0],sniffer.reipaddr[1],
             sniffer.reipaddr[2],sniffer.reipaddr[3],sniffer.report,sniffer.channel,sniffer.sensitivity);
    
    
    DebugMsg("TRX: %d %d \n",TRX231, TRX212);
    trx212_get_state();
    trx231_get_state();
       
    
    // 
    // Main loop of hole firmware
    while(1)
    {
            
      TtrxPacket *packetPtr;
            
      packetPtr = packetFifoGet();	
            
      if(packetPtr != NULL)
      {       
        zep_send(packetPtr);                                         
        packetFifoGetDone();
      } 
      
      if(sniffer.setIpConfig==true)
      { 
           ulIp = (unsigned long *)&sniffer.ipaddr;
           ulMask = (unsigned long *)&sniffer.nmask;  
           ulGw = (unsigned long *)&sniffer.gw;
           
           //
           // Wait a while
           //
           delay(2000000);
           
           if(sniffer.dhcpOn==false)
             lwIPNetworkConfigChange(htonl(*ulIp), htonl(*ulMask), htonl(*ulGw), IPADDR_USE_STATIC);
           else
           {
                 //
                 // If DHCP has already been started, we need to clear the IPs and
                 // switch to static.  This forces the LWIP to get new IP address
                 // and retry the DHCP connection.
                 //
                 lwIPNetworkConfigChange(0, 0, 0, IPADDR_USE_STATIC);
     
                 //
                 //Restart the DHCP connection.
                 //
                 lwIPNetworkConfigChange(0, 0, 0, IPADDR_USE_DHCP);
             
             
                 DebugMsg("Getting IP address from DHCP...\n");

                 pucTemp = (unsigned long *)&sniffer.ipaddr;
                 
                 //
                 //  Wait until DHCP assign IP address
                 //
                 while((*pucTemp=lwIPLocalIPAddrGet())==0)
                 {
                    delay(1000000);                 
                 }
                
                 pucTemp = (unsigned long *)&sniffer.nmask; 
                 *pucTemp=lwIPLocalNetMaskGet();   
                 pucTemp = (unsigned long *)&sniffer.gw;
                 *pucTemp=lwIPLocalGWAddrGet();
           }
             
           sniffer.setIpConfig=false;
      }
      
    }
          
}//end of Main loop
      
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
    

