int main(void)
{
   // uint8_t* udpData;
    uint8_t* tcpData;
    uint8_t p=0;
    uint16_t i=0;
    Seq_number=0xfb0983f7;
    Ack_number=0x00000;
    myport=0xb921;
    id=0x1229;
    uint8_t* http;

    // init controller
    initHw();

    putsUart0("\r\nWeather forecast\r\n");
    // init ethernet interface
    etherInit(ETHER_UNICAST | ETHER_BROADCAST | ETHER_HALFDUPLEX);
    etherSetIpAddress(192,168,137,199);

    // flash phy leds
    etherWritePhy(PHLCON, 0x0880);
    RED_LED = 1;

    waitMicrosecond(500000);
    etherWritePhy(PHLCON, 0x0990);
    RED_LED = 0;
    waitMicrosecond(500000);

    sendSynWeather(data);

    // message loop
    while (1)
    {
        if (etherKbhit())
        {
            if (etherIsOverflow())
            {
                RED_LED = 1;
                waitMicrosecond(100000);
                RED_LED = 0;
            }
            // get packet
            etherGetPacket(data, 1500);
            // handle arp request

            if (etherIsArp(data))
            {
                etherSendArpResp(data);
                RED_LED = 1;
               // GREEN_LED = 1;
                waitMicrosecond(50000);
                RED_LED = 0;
                GREEN_LED = 0;
            }

            // handle ip datagram

            if (etherIsIp(data))
            {
            	if (etherIsIpUnicast(data))
            	{
            		// handle icmp ping request

            		if (etherIsPingReq(data))
					{
					  etherSendPingResp(data);
					  GREEN_LED = 1;
					  waitMicrosecond(50000);
					  GREEN_LED = 0;

					}

					if(etherIsTcp(data))
					{
						tcpData = etherGetTcpData(data);
						if(etherisHandshake1(data))
						{
							etherRespondtoHandshake1(data);
							RED_LED = 1;
							//GREEN_LED=1;
							BLUE_LED=1;
							waitMicrosecond(100000);
							RED_LED = 0;
							//GREEN_LED=0;
							BLUE_LED=0;
							break;
						}

					}


                }
            }
        }
    }

    sendGETRequest(data);

    while(1)
    {
    	if (etherKbhit())
    	{
    		etherGetPacket(data, 1500);
			if(etherIsTcp(data))
			{

				RED_LED = 1;
				//GREEN_LED=1;
				BLUE_LED=1;
				waitMicrosecond(100000);
				RED_LED = 0;
				//GREEN_LED=0;
				BLUE_LED=0;

				if(p<=7)
					{
					if(tcp_DataCount>0)
						etherRespondToData(data);
					}


				//if(p>=2)
				{
					//p=0;
					tcpData = etherGetTcpData(data);
					http=tcpData+9;
					if((*http==0x32))//|(*http==0x35))
					{
						tcpData=tcpData+299;
						for(i=0;i<(tcp_DataCount-299);i++)
						{
						putcUart0(*tcpData);
						tcpData++;
						}
						if(*http==0x32)
								break;
					}
					//break;
					//sendFinRequest(data);

				}
				p++;
			}
    	}

    }
    while(1);

    return 0;
}
/**
*INICIO DO PROGRAMA PRINCIPAL
*/
int main (int argc, char **argv) {
   /* Os sockets. Um que será o socket que vai escutar pelas conexões
    * e o outro que vai ser o socket específico de cada conexão */
	int listenfd, connfd;
   /* Informações sobre o socket (endereço e porta) ficam nesta struct */
	struct sockaddr_in servaddr;
   /* Retorno da função fork para saber quem é o processo filho e quem
    * é o processo pai */
   pid_t childpid;
   /* Armazena linhas recebidas do cliente */
	char	recvline[MAXLINE + 1];
   /* Armazena o tamanho da string lida do cliente */
   ssize_t  n;

	if (argc != 2) {
      fprintf(stderr,"Uso: %s <Porta>\n",argv[0]);
      fprintf(stderr,"Vai rodar um servidor HTTP <Porta> TCP\n");
		exit(1);
	}

   /* Criação de um socket. Eh como se fosse um descritor de arquivo. Eh
    * possivel fazer operacoes como read, write e close. Neste
    * caso o socket criado eh um socket IPv4 (por causa do AF_INET),
    * que vai usar TCP (por causa do SOCK_STREAM), já que o HTTP
    * funciona sobre TCP, e será usado para uma aplicação convencional sobre
    * a Internet (por causa do número 0) */
	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror("socket :(\n");
		exit(2);
	}

   /* Agora é necessário informar os endereços associados a este
    * socket. É necessário informar o endereço / interface e a porta,
    * pois mais adiante o socket ficará esperando conexões nesta porta
    * e neste(s) endereços. Para isso é necessário preencher a struct
    * servaddr. É necessário colocar lá o tipo de socket (No nosso
    * caso AF_INET porque é IPv4), em qual endereço / interface serão
    * esperadas conexões (Neste caso em qualquer uma -- INADDR_ANY) e
    * qual a porta. Neste caso será a porta que foi passada como
    * argumento no shell (atoi(argv[1]))
    */
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port        = htons(atoi(argv[1]));
	if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
		perror("bind :(\n");
		exit(3);
	}

   /* Como este código é o código de um servidor, o socket será um
    * socket passivo. Para isto é necessário chamar a função listen
    * que define que este é um socket de servidor que ficará esperando
    * por conexões nos endereços definidos na função bind. */
	if (listen(listenfd, LISTENQ) == -1) {
		perror("listen :(\n");
		exit(4);
	}
   system("clear");
   printf("[Servidor no ar. Aguardando conexoes na porta %s]\n",argv[1]);
   printf("[Para finalizar, pressione CTRL+c ou rode um kill ou killall]\n");

   /* O servidor no final das contas é um loop infinito de espera por
    * conexões e processamento de cada uma individualmente */
	for (;;) {
      /* O socket inicial que foi criado é o socket que vai aguardar
       * pela conexão na porta especificada. Mas pode ser que existam
       * diversos clientes conectando no servidor. Por isso deve-se
       * utilizar a função accept. Esta função vai retirar uma conexão
       * da fila de conexões que foram aceitas no socket listenfd e
       * vai criar um socket específico para esta conexão. O descritor
       * deste novo socket é o retorno da função accept. */
		if ((connfd = accept(listenfd, (struct sockaddr *) NULL, NULL)) == -1 ) {
			perror("accept :(\n");
			exit(5);
		}

      /* Agora o servidor precisa tratar este cliente de forma
       * separada. Para isto é criado um processo filho usando a
       * função fork. O processo vai ser uma cópia deste. Depois da
       * função fork, os dois processos (pai e filho) estarão no mesmo
       * ponto do código, mas cada um terá um PID diferente. Assim é
       * possível diferenciar o que cada processo terá que fazer. O
       * filho tem que processar a requisição do cliente. O pai tem
       * que voltar no loop para continuar aceitando novas conexões */
      /* Se o retorno da função fork for zero, é porque está no
       * processo filho. */
      if ( (childpid = fork()) == 0) {
         /**** PROCESSO FILHO ****/
         printf("[Uma conexao aberta]\n");
         /* Já que está no processo filho, não precisa mais do socket
          * listenfd. Só o processo pai precisa deste socket. */
         close(listenfd);

         /* Agora pode ler do socket e escrever no socket. Isto tem
          * que ser feito em sincronia com o cliente. Não faz sentido
          * ler sem ter o que ler. Ou seja, neste caso está sendo
          * considerado que o cliente vai enviar algo para o servidor.
          * O servidor vai processar o que tiver sido enviado e vai
          * enviar uma resposta para o cliente (Que precisará estar
          * esperando por esta resposta)
          */

         /* ========================================================= */
         /* ========================================================= */
         /*                         EP1 INÍCIO                        */
         /* ========================================================= */
         /* ========================================================= */
         /* TODO: É esta parte do código que terá que ser modificada
          * para que este servidor consiga interpretar comandos HTTP */

         /* Definindo o cliente */
         Host cliente;
         cliente.destino = servaddr;
         cliente.socket = connfd;

         /* Ler a requisição do cliente*/
         Request client_request = readRequest(cliente);

         /* Mostrar na tela as requisições dos clientes */
         printf("*********************************************************************");
         printf("\n [Metodo requisitado]:   %s \n", client_request.metodo);
         printf("\n [Recurso solicitado]:   %s \n", client_request.recurso);
         printf("\n [Protocolo]:            %s \n", client_request.protocolo);

         /* checar a Request do client */
         CR_returns returns =  checkRequest(cliente, client_request);

         /* enviar resposta da requisição para o cliente */
         if (strcmp(client_request.metodo,"GET")==0) {
            sendGETRequest(cliente, returns);
         }
         else if (strcmp(client_request.metodo,"POST")==0) {
            sendPOSTRequest(cliente, returns,client_request);

         }

         /* ========================================================= */
         /* ========================================================= */
         /*                         EP1 FIM                           */
         /* ========================================================= */
         /* ========================================================= */

         /* Após ter feito toda a troca de informação com o cliente,
          * pode finalizar o processo filho */
         printf("[Uma conexao fechada]\n");
         exit(0);
      }
      /**** PROCESSO PAI ****/
      /* Se for o pai, a única coisa a ser feita é fechar o socket
       * connfd (ele é o socket do cliente específico que será tratado
       * pelo processo filho) */
		close(connfd);
	}
	exit(0);
}