#include <UserButton.h>
#define MSG_LEN 1
#define MAX_NODES 5

module BroadcastC
{
  uses
      {
	interface Timer<TMilli> as myTimer;
	interface Leds;
	interface AMSend as ButtonMsg;
	interface Receive as Collect;
	interface Boot as SendControl;
	interface Boot as ReceiveControl;
	interface LogRead;
	interface LogWrite;
	interface SplitControl as RadioControl;
	interface SplitControl as SerialControl;
	interface Boot as Button;
      interface Get<button_state_t>;
      interface Notify<button_state_t>;
      }
}

implementation 
{
  message_t report;
  uint8_t message[MSG_LEN];
  uint8_t recmsg[MSG_LEN];
  uint16_t counter=0;
  packet_msg_t send;
  packet_msg_t receive;
  ButtonMsg_t button;
  uint8_t list[MAX_NODES];
  uint8_t list2[MAX_NODES];
  uint16_t t=5000; 
  uint16_t count=0;

    typedef nx_struct logentry_t {
    nx_uint8_t id;
    nx_uint16_t content[100];
  } logentry_t;
  
  bool m_busy = TRUE;
  logentry_t m_entry;

  void logsend();
  
  //Initializes the packet for transmission
  void init_data()
      {

	//init message
	memset(message, 0, MSG_LEN);
	call myTimer.startPeriodic(t);
      }

  //Initializes the packet for reception
  void init_recdata()
      {

	//init message
	memset(recmsg, 0, MSG_LEN);
      }

  /* The problem lies here. Eventhough I am calling the ButtonMsg.send 10 times it is being called only once. Also, sometimes the log contains either only '0s' or some garbage values. Occasionally it gives me the correct values. Also I don’t know why, the motes get stuck after some time. They do nothing. */

     void logsend()
	{
	uint16_t i,j;
	call Leds.led0On();
	call Leds.led1On();
	call Leds.led2On(); 
        if(call LogRead.read(&m_entry, sizeof(logentry_t))==SUCCESS){
        button.node_id=1;
	for(i = 0; i < 10; i++){
	      for(j=0;j<10;j++)
		{
		button.content[j]=m_entry.content[(10*i)+j];
		}
		memcpy(call ButtonMsg.getPayload(&report, sizeof(button)),   &button, sizeof button);
/* ButtonMsg.send is being called 10 times but it is executing only once. */
		call ButtonMsg.send(AM_BROADCAST_ADDR, &report, sizeof(button));
		call Leds.led0Off();
		call Leds.led1Off();
		call Leds.led2Off();
  	      }
	} call LogWrite.erase();
   }
  
  //Transmits the number periodically 
  void transmit()
      {
	call Leds.led2Off();
        call Leds.led0Off();
        call Leds.led1On();
    	memcpy(call PacketMsg.getPayload(&report, sizeof(send)), &send, sizeof send);
	call PacketMsg.send(AM_BROADCAST_ADDR, &report, sizeof(send));	
   }

  event void RadioControl.startDone(error_t error){ 
      }

  event void RadioControl.stopDone(error_t error){
      }

  event void SerialControl.startDone(error_t error){ 
      }

  event void SerialControl.stopDone(error_t error){
      }

  event void SendControl.booted()
	{
	init_data();
	call RadioControl.start();
	send.content=1;
	send.c_len=MSG_LEN;
	}

  event void myTimer.fired()
      {
	transmit();
	}
  
  event void PacketMsg.sendDone(message_t * sent, error_t err)
      {
	if(err!=SUCCESS){ call PacketMsg.send(AM_BROADCAST_ADDR, &report, sizeof(send));}
      }

   event void ButtonMsg.sendDone(message_t * sent, error_t err)
      {
	if(err!=SUCCESS){call ButtonMsg.send(AM_BROADCAST_ADDR, &report, sizeof(button));}
      }   
  
  event void Button.booted() {
    call Notify.enable();
    call SerialControl.start();
      }
  
  event void Notify.notify( button_state_t state ) {
    if ( state == BUTTON_PRESSED ) {
      call Leds.led0On();
      logsend();
      } else if ( state == BUTTON_RELEASED ) {
      call Leds.led0Off();
      }
     }

  event void LogRead.readDone(void* buf, storage_len_t len, error_t err) {
    if (err!=SUCCESS ) {
      call LogRead.read(&m_entry, sizeof(logentry_t));
      }
    
  }

  event void ReceiveControl.booted()
	{
	init_recdata();
	call RadioControl.start();
	}

  event void LogWrite.eraseDone(error_t err) {
    if (err == SUCCESS) {
      m_busy = FALSE;
    }
    else {
      // Handle error.
    }
    call Leds.led0Off();
  }

  event message_t* Collect.receive(message_t* msg, void* payload, uint8_t len)
      {
	uint8_t i;
	packet_msg_t *pPacket=payload;
	
	call Leds.led1Off();
	call Leds.led2On();
	call Leds.led0Off();
	
      receive.content=pPacket->content;
	receive.c_len=pPacket->c_len;
	recmsg[0]=receive.content;
	
	if (!m_busy) {
        //m_entry.len = MSG_LEN;
	if(counter<100)
	  {
	  for(i=1;i<100;i++)
		{
		m_entry.content[counter]=recmsg[0];
		counter++;
		}
	  }
	else
	  {
	   m_entry.content[0]=recmsg[0];
	   counter=0;
	  }	
	if (call LogWrite.append(&m_entry, sizeof(logentry_t)) != 	SUCCESS) {
		m_busy = FALSE;
      	}
     }
	
	return msg;
      }
    
	event void LogWrite.appendDone(void* buf, storage_len_t len, 
                                 bool recordsLost, error_t err) {
      m_busy = FALSE;
      }
      
	event void LogRead.seekDone(error_t err) {
      }

      event void LogWrite.syncDone(error_t err) {
  }

}