tangibleInterface.c 4.99 KB
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "serial.h"
#include "ethernet.h"
#include "w5100.h"
#include "socket.h"

#define MAC_SIZE	6
#define IPV4_SIZE	4
#define PRESCALER 1024
#define NB_TICK 6250
#define DELAY 300


bool isComMem = false; // Commande déjà enregistrée ou non?
bool sleep = false; //Etat de l'interface : true = mode sommeil / false = mode eveillé
uint8 comMem[2]; //Commande en mémoire
char msg[30]={'\0'};
typedef enum type_msg {TCP,UDP}type_msg;
bool isTCP_received = false; // <- Msg TCP reçu ou non? Permet la réouverture de la socket TCP pour permettre la réécoute TCP

void init_led(void)
{
  DDRD = 0xFF;
  if (sleep == true) // si IT dort
    {
      PORTD = 0x08;
    }
  else
    {
      PORTD = 0x00;
    }
}

void init_timer(void)
{
        TCCR1B |= _BV(WGM12);
        TCCR1B |= _BV(CS12);  // Facteur de division 1024
        TCCR1B |= _BV(CS10);
        OCR1A  = NB_TICK;
        TIMSK1 |= _BV(OCIE1A);
}

ISR(TIMER1_COMPA_vect)
{
  if(sleep == false)
    PORTD ^= 0x20;
}


void request(SOCKET sock,uint8 rq[2],uint8 addr[IPV4_SIZE],type_msg type)
{
  if (!isComMem) //Aucune commande en mémoire
    {
      isComMem = true;
      comMem[0] = 0xA0; comMem[1] = 0x00; // Pourcentage = 0% clignotage de base
    }
  
  uint8 x = rq [0] & 0xE0; //Récupération de la commande
  x = x >> 5;
  uint16 y = rq[0] & 0x1F; //Récupération du pourcentage
  y = y << 8;
  y += rq[1];
  float per = y*0.0122;

  
  if (type == UDP)
    {
      SOCKET s = 2; //Socket TCP pour réponse à la broadcast UDP
      switch(x)
	{
	case 0: // GETSTATUS ( Via UDP broadcast, on répond en TCP ! )
	  if(socket(s,Sn_MR_TCP,2020,0) == 0)
	    {
	      printf("SOCKET TCP NON INITILIASEE \n");
	    }
	  if (connect(s,addr,2020))
	    {
	      _delay_ms(DELAY); //l'IT doit attendre un peu avant d'envoyer
	      if (sleep==false)
		{
		  strcpy(msg,"\x20\x01");
		}
	      else
		{
		  strcpy(msg,"\x20\x00");
		}
	      send(s,msg,sizeof(char)*strlen(msg));
	    }
	  break;

	case 2: // SLEEP MODE ON/OFF
	  if ((y == 0x0001) & (sleep == true))
	    {
	      sleep = false;
	      printf("MODE EVEILLE\n");
	      PORTD = PORTD ^ 0x08;
	    }
	  else if ((y == 0x0000) & (sleep == false))
	    {
	      sleep = true;
	      printf("MODE SOMMEIL\n");
	      PORTD = 0x08;
	    }
	  break;

	case 5: // SETCOMMANDE
	  if (sleep == false)
	    {
	      OCR1A = NB_TICK - 53*(int)per;
	      comMem[0] = rq[0]; comMem[1] = rq [1]; //save
	    }
	  break;   
	}
    }
  
  else if (type == TCP)
    {
      switch(x)
	{
	case 0: // GETSTATUS
	  if (sleep==false)
	    {
	      strcpy(msg,"\x20\x01");
	    }
	  else
	    {
	      strcpy(msg,"\x20\x00");				    
	    }
	  send(sock,msg,sizeof(char)*strlen(msg)); // REPONSE JE DORS OU NON
	  break;
      
	case 3: // Serveur qui demande la commande en mémoire : pourcentage
	  printf("Request ComMem\n");
	  strcpy(msg,comMem);
	  send(sock,msg,sizeof(char)*strlen(msg));
	  break;

	case 7:
	  printf("Demande de fin de dialogue\n");
	  isTCP_received=true;
	  disconnect(sock);
	  break;
	  
	}
    }  
}
  

  int main(void)
  {
    /*variables*/
    SOCKET sUDP=0,sTCP=1;
  
    uint8_t mac[MAC_SIZE] = {0xA0,0xBD,0xCD,0xDD,0xED,0xFD}; // <- Adresse MAC de l'IT
    uint8_t ip[IPV4_SIZE] = {192,168,1,205}; // <- Adresse IPV4 de l'IT
    uint8_t gateway[4] = {192,168,1,1}; // <- Adresse passerelle 
    uint8_t mask[4] = {255,255,255,0}; // <- Masque de sous réseau
    uint8 buf[2]; // <- Sert à stocker les deux octets recus via TCP & UDP
    uint16 datasize; // <- Sert à stocker la longueur du datagramme
    uint8_t addr[IPV4_SIZE]; // <- Sert à stocker l'adresse IP de l'émetteur
    uint16_t port; // <- Sert à stocker le port utilisé par l'émetteur
    type_msg type;

    /*init*/
    init_led(); // <- Initialise les LEDS 
    init_timer(); // <- Initialise le compteur pour la fréquence du clignotement LED
    init_printf(); // <- Initialise la communication série
    ethernet_init(mac,ip,gateway,mask); // <- Initialise le shield ethernet
  
  
    if (!socket(sUDP,Sn_MR_UDP,2020,0))
      {
	return -1;
      }
    
    if (!socket(sTCP,Sn_MR_TCP,2020,0))
      {
	return -1;
      }
    
    while(1)
      {
	socket(sTCP,Sn_MR_TCP,2020,0);
	listen(sTCP);
	isTCP_received=false;
	while(!isTCP_received)
	  {
	    sei();
	    if (IINCHIP_READ(Sn_SR(sTCP)) == SOCK_ESTABLISHED) // Quelqu'un s'est connecté en TCP
	      {
		cli();
		while(!isTCP_received) // On boucle en attendant le message du client
		  {
		    if(recv(sTCP,buf,2)>0)
		      {
			type=TCP;
			request(sTCP,buf,NULL,type); // On traite le message du client
		      }
		  }
	      }
	    if((datasize=recvfrom(sUDP,buf,sizeof(buf),addr,&port)) == 8) // Quelqu'un a envoyé 2 octets via UDP
	      {
		cli();
		type=UDP;
		printf("MESSAGE RECU VIA UDP %x %x \n",buf[0],buf[1]);
		request(sUDP,buf,addr,type); // On traite le message du client
	      }
	  }	  
      }
    close(sTCP);
    close(sUDP);
    return 0;
  }