//*****************************************************************************
//
//! @file
//! @brief ZigBee Encapsulation Protokol
//
//*****************************************************************************

 /*------------------------------------------------------------
 *
 *      ZEP Packets must be received in the following format:
 *      |UDP Header|  ZEP Header |IEEE 802.15.4 Packet|
 *      | 8 bytes  | 16/32 bytes |    <= 127 bytes    |
 *------------------------------------------------------------
 *
 *      ZEP v1 Header will have the following format:
 *      |Preamble|Version|Channel ID|Device ID|CRC/LQI Mode|LQI Val|Reserved|Length|
 *      |2 bytes |1 byte |  1 byte  | 2 bytes |   1 byte   |1 byte |7 bytes |1 byte|
 *
 *      ZEP v2 Header will have the following format (if type=1/Data):
 *      |Preamble|Version| Type |Channel ID|Device ID|CRC/LQI Mode|LQI Val|NTP Timestamp|Sequence#|Reserved|Length|
 *      |2 bytes |1 byte |1 byte|  1 byte  | 2 bytes |   1 byte   |1 byte |   8 bytes   | 4 bytes |10 bytes|1 byte|
 *
 *      ZEP v2 Header will have the following format (if type=2/Ack):
 *      |Preamble|Version| Type |Sequence#|
 *      |2 bytes |1 byte |1 byte| 4 bytes |
 *------------------------------------------------------------
 */


/* Includes ------------------------------------------------------------------*/

// COMPILER



// STELARISWARE
#include "lwip/inet.h"
#include "lwip/udp.h"


// PROJECT INCLUDES
#include "zep.h"
#include "sniffer.h"
#include "radio/packet.h"
#include "myutils/packetfifo.h"


//------------------------------------------------------------
struct udp_pcb *g_udp_pcb;


struct pbuf *g_pbuf;

struct pbuf *pbuf_zep;

struct pbuf *pbuf_data;

struct zep_head g_zepData;


unsigned long *ptrg_zepCounter;

tSnifferSettings *ptrzSnifferSettings;

/* Exported functions ------------------------------------------------------- */


//*****************************************************************************
//
// This example demonstrates the use of the Ethernet Controller.
//
//*****************************************************************************

void
zep_init(unsigned long *ptrz, tSnifferSettings *ptrs)
{
  
  ptrg_zepCounter=ptrz;
  ptrzSnifferSettings=ptrs;
 
  
  g_udp_pcb = udp_new();

  udp_bind(g_udp_pcb, IP_ADDR_ANY, ZEP_DEFAULT_PORT);  
  
  //
  //Init for ZEP header
  //
  
  g_zepData.preamble=ZEP_PREAMBLE;
  g_zepData.version=2;
  g_zepData.type=1;
  g_zepData.channel_id=0;
  g_zepData.device_id=htons(0x0000);     
  g_zepData.lqi_mode=1; 
  g_zepData.lqi=0;
  g_zepData.ntp_time.secs=htonl(0);
  g_zepData.ntp_time.nsecs=htonl(0);
  g_zepData.seqno=htonl(0);          
  memcpy(&g_zepData.reserved,ZEP_RESERVED,10);
  g_zepData.length=0;
  
  
  
  //
  // Prepare pbuf for ZEP header
  //
  pbuf_zep = pbuf_alloc(PBUF_TRANSPORT,0,PBUF_ROM);  
  pbuf_zep->payload=(void*)&g_zepData;
  pbuf_zep->tot_len = pbuf_zep->len = sizeof(struct zep_head);
  
  //
  // Prepare pbuf for data of IEEE 802.15.4
  //          
  pbuf_data = pbuf_alloc(PBUF_TRANSPORT,0,PBUF_ROM); 
  pbuf_data->payload=NULL;
  pbuf_data->tot_len = pbuf_data->len =0;


  pbuf_chain(pbuf_zep, pbuf_data);


}

//*****************************************************************************
//
// ZEP send
//
//*****************************************************************************
void
zep_send(TtrxPacket *trxPacketPtr)
{
    unsigned long ult;
    
    double timestamp;
    
  
  
    g_zepData.channel_id=ptrzSnifferSettings->channel;
   
    g_zepData.seqno=htonl(*ptrg_zepCounter);
    *ptrg_zepCounter+=1;
    
    timestamp=(trxPacketPtr->tmst_timer*CPU_CYCLE_TIME);
    timestamp+=(trxPacketPtr->tmst_tcount*TIMER_MAXTIME);
    
    ult=((unsigned long)timestamp);
    g_zepData.ntp_time.secs=htonl(ult+NTP_BASE_S);
    
    timestamp-=ult;
    //DebugMsg("timestamp=%f",(float)timestamp);
    ult=(unsigned long)(timestamp*1000000);
    //DebugMsg("Ult=%u",ult);
    
    g_zepData.ntp_time.nsecs=htonl((unsigned long)(ult*NTP_BASE_N+1));

    g_zepData.length=trxPacketPtr->length;
    g_zepData.lqi=trxPacketPtr->lqi;
    g_zepData.channel_id=ptrzSnifferSettings->channel;
    
    pbuf_data->payload=(void*)&trxPacketPtr->data;
    pbuf_data->tot_len = pbuf_data->len =trxPacketPtr->length;
    
    pbuf_zep->tot_len = pbuf_zep->len + pbuf_data->tot_len;   
    
    if((udp_sendto(g_udp_pcb, pbuf_zep,
                      (struct ip_addr*)&ptrzSnifferSettings->reipaddr,
                      ptrzSnifferSettings->report))!=ERR_OK)
    {
      DebugMsg("Error packet : (%d)\n",*ptrg_zepCounter);
      ledgreen_pinset(1);
    
    }   


}

