#include "contiki.h"
#include "contiki-net.h"

#include "dev/leds.h"
#include "net/rime/rimeaddr.h"
#include "net/rime/packetbuf.h"
#include "net/rime/broadcast.h"

#include "net/rime/network_l.h"

#include "node-id.h"

#define DEBUG 1
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif

#include "../mobility.h"

static uint32_t last_rcvd_dl, count_dl = 0;

static u8_t data_type = DEFAULT_DATA, dl_rate = 0, lock = 0;

PROCESS(router_packet_process, "Router-Demo With Network_layer");
PROCESS(dl_counter_process, "Router_counter-process");
AUTOSTART_PROCESSES(&router_packet_process, &dl_counter_process);

/*implements a counter, the leds count from 0 to 7
 *param count - the value to be displayed of the leds 
 */
static void leds_set(uint8_t count){
 
         if(count & LEDS_GREEN){
           leds_on(LEDS_GREEN<<1);
         }else{
            leds_off(LEDS_GREEN<<1);
         }

         if(count & LEDS_YELLOW){
           leds_on(LEDS_YELLOW>>1);
         }else{
           leds_off(LEDS_YELLOW>>1);
         }

         if(count & LEDS_RED){
          leds_on(LEDS_RED);
         }else{
          leds_off(LEDS_RED);
         }
}
/*----------------------------------------------------------------------------*/
static void inpacket(rimeaddr_t *from, void* data, uint8_t len){
    packet_t *p =(packet_t *)data;
    //leds_set(p->seqno);
    leds_toggle(LEDS_RED);
    count_dl++;
    /*PRINTF("Router_node Msg recvd seq:%3d from: %d.%d  len:%d\n",
            p->seqno, from->u8[0], from->u8[1], len);*/
}
/*----------------------------------------------------------------------------*/
PROCESS_THREAD(router_packet_process, ev, data)
{
  
  
   PROCESS_EXITHANDLER(network_close());  
   
   PROCESS_BEGIN();
   
    static struct etimer et;
   /*we ant a router to send 30 packets per second 
    NOTE: replace 30 with 1, and disactivate PROCESS_YIELD() in the while loop
    *in the case that a router node does not need to send data packets.
    */
   static u8_t datarate = 1; 
   static rimeaddr_t dest, addr;   
   addr.u8[0] = 35;

   dest.u8[0] = 1;

   /*We open the connection*/
   network_open();
 
   /*we set the call back function to receive incoming traffic*/
   network_recv_func(inpacket);
   
   /*We set at which data rate we will be transmitting*/
   network_set_data_rate(datarate);
   
   static uint8_t val = 0;

   /*etimer_set(&et, 15*CLOCK_SECOND); //wait 15 seconds before transmitting any data
        
   PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));*/

   while(1) {
        PROCESS_YIELD();
                      
        etimer_set(&et, CLOCK_SECOND/datarate);
        
        PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
      
        if(lock){ 
            data_type = DATA_RATE_COUNTER;
        }else{
            data_type = DEFAULT_DATA;
        }       
        packet_t *packet = (packet_t*)network_getbuffer(sizeof (packet_t));
        
        if(lock){ 
           packet->seqno  = dl_rate;
           lock           = 0;
        }else{
            packet->seqno = val++;
        }
        
        packet->type      = 1;
            
        network_broadcast();
   }

   PROCESS_END();
}
/*----------------------------------------------------------------------------*/
/* Every second a selected router node, feeds back the downlink data rate measured 
   at this node. In this way the sink can comput the sum of the uplink and
 * the downlink data rates. 
 */
PROCESS_THREAD(dl_counter_process, ev, data){
    PROCESS_BEGIN();
    
   static rimeaddr_t dest_addr;   

   dest_addr.u8[0] = 1;
   
    while(1){ 
        PROCESS_YIELD();
        if(node_id == 2 || rimeaddr_node_addr.u8[1] == 112){
            static struct etimer et;

            etimer_set(&et, CLOCK_SECOND);
            PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
                      
            /*
             We calculate how many packet we received during 1 second, this is
              the downlink data rate (sink --> router)
             */
            dl_rate = (u8_t)(count_dl-last_rcvd_dl);
            last_rcvd_dl = count_dl;
          
            /*we ask the transmitter process to send a report 
              packet containing the downlink data rate
             */
            if(lock == 0){ 
                lock = 1;
            }
        }else{
            PROCESS_YIELD();
            printf("I'm not the selected counter router\n");
        }
    }
    PROCESS_END();
}
/*----------------------------------------------------------------------------*/