⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpd.c

📁 LWIP在STM32裸机上的移植
💻 C
字号:
/*
 * Copyright (c) 2001, Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * httpd.c
 */

#include "httpd.h"
#include "fsdata.c"
#include "stm32f10x.h"
#include <string.h>
#include <stdio.h>

struct http_state
{
  char *file;
  u32_t left;
};

/**
  * @brief  This function is called when an error occurs on the HTTP connection 
  * @param  arg
  * @parm   err
  * @retval None 
  */
static void conn_err(void *arg, err_t err)
{
	struct http_state *hs;

	hs = arg;
	mem_free(hs);
}

/**
 * This function is used when  
 */
static void close_conn(struct tcp_pcb *pcb, struct http_state *hs)
{
	tcp_arg(pcb, NULL);
	tcp_sent(pcb, NULL);
	tcp_recv(pcb, NULL);
	
	mem_free(hs);
	
	tcp_close(pcb);
}

static void send_data(struct tcp_pcb *pcb, struct http_state *hs)
{
	err_t err;
	u16_t len;

	/* We cannot send more data than space avaliable in the send
       buffer. */
  	if(tcp_sndbuf(pcb) < hs->left)
  	{
    	len = tcp_sndbuf(pcb);
  	}
  	else
  	{
    	len = hs->left;
  	}

  	err = tcp_write(pcb, hs->file, len, 0);

  	if(err == ERR_OK)
  	{
    	hs->file += len;
    	hs->left -= len;
  	}
}

/**
 * This function is called when no data is sending and receiving. 
 */
static err_t http_poll(void *arg, struct tcp_pcb *pcb)
{
	if (arg == NULL)
	{
//		printf("Null, close\n");
		tcp_close(pcb);
	}
  	else
  	{
    	send_data(pcb, (struct http_state *)arg);
  	}

	return ERR_OK;
}

static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
	struct http_state *hs;
	
	hs = arg;
	if(hs->left > 0)
	{
		send_data(pcb, hs);
	}
	else
	{
		close_conn(pcb, hs);
	}

	return ERR_OK;
}

/**
  * @brief  Called when a data is received on the HTTP connection
  * @param  arg	the user argument
  * @param  pcb	the tcp_pcb that has received the data
  * @param  p	the packet buffer
  * @param  err	the error value linked with the received data
  * @retval error value
  */
static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
	int i, j;
	char *data;
  	char fname[40];
  	struct fs_file file = {0, 0};
  
	struct http_state *hs;

	hs = arg;

	if(err == ERR_OK && p != NULL)
  	{

    	/* Inform TCP that we have taken the data. */
    	tcp_recved(pcb, p->tot_len);

    	if(hs->file == NULL)
    	{
      		data = p->payload;
        
      		if(strncmp(data, "GET /STM32F107ADC", 17) == 0)
      		{
        		char Digit1=0, Digit2=0, Digit3=0; 
        		int ADCVal = 0;        

        		pbuf_free(p);

        		ADCVal = ADC_GetConversionValue(ADC1);
        		ADCVal = ADCVal/8;
        		Digit1= ADCVal/100;
        		Digit2= (ADCVal-(Digit1*100))/10;
        		Digit3= ADCVal-(Digit1*100)-(Digit2*10);
        
				/* Update the ADC value in STM32F107ADC.html */
        		/* ADC value 1st digit */
        		*((data_STM32F107ADC_html)+ 0xE90) = 0x30 + Digit1; 
        		
				/* ADC value 2nd digit */
        		*((data_STM32F107ADC_html)+ 0xE91) = 0x30 + Digit2; 
        
				/* ADC value 3rd digit*/
        		*((data_STM32F107ADC_html)+ 0xE92) = 0x30 + Digit3; 

        		fs_open("/STM32F107ADC.html", &file);

        		hs->file = file.data;
        		hs->left = file.len;

        		send_data(pcb, hs);

        		/* Tell TCP that we wish be to informed of data that has been
           		   successfully sent by a call to the http_sent() function. */
        		tcp_sent(pcb, http_sent);
      		}
      		else if (strncmp(data, "GET /method=get", 15) == 0)
      		{
        		i = 15;
        		GPIOD->BSRR |= GPIO_Pin_2;	//LED1 灭
        		GPIOD->BSRR |= GPIO_Pin_3;	//LED2 灭
        		GPIOD->BSRR |= GPIO_Pin_4;	//LED3 灭
        		GPIOD->BSRR |= GPIO_Pin_7;	//LED4 灭

       			while(data[i]!=0x20)				 /* */
        		{
          			i++; 
          			if (data[i] == 0x6C)			 /* l */
          			{
            			i++;
            			if (data[i] ==  0x65)		 /* e */
            			{
              				i++;
              				if (data[i] ==  0x64)	 /* d*/
              				{
                				i+=2; 
                				if(data[i]==0x31) 	 /* 1 */
                  					GPIOD->BRR |= GPIO_Pin_2;	//LED1 亮     
                				
								if(data[i]==0x32)	 /* 2 */
                  					GPIOD->BRR |= GPIO_Pin_3;	//LED2 亮   
                				
								if(data[i]==0x33)	 /* 3 */
                  					GPIOD->BRR |= GPIO_Pin_4;	//LED3 亮   
                				
								if(data[i]==0x34)	 /* 4 */
                  					GPIOD->BRR |= GPIO_Pin_7;	//LED4 亮  
              				}   
            			}
          			} 
        		}

        		pbuf_free(p);

        		fs_open("/STM32F107LED.html", &file);

        		hs->file = file.data;
        		hs->left = file.len;

        		send_data(pcb, hs);

        		/* Tell TCP that we wish be to informed of data that has been
           		   successfully sent by a call to the http_sent() function. */
        		tcp_sent(pcb, http_sent);
      		}    
      		else if (strncmp(data, "GET ", 4) == 0)
      		{
        		for (i = 0; i < 40; i++)
        		{
          			if (((char *)data + 4)[i] == ' ' ||
              			((char *)data + 4)[i] == '\r' ||
              			((char *)data + 4)[i] == '\n')
          			{
            			((char *)data + 4)[i] = 0;
          			}
        		}
        
        		i = 0;
        		j = 0;
        
        		do
        		{
          			fname[i] = ((char *)data + 4)[j];
          			j++;
          			i++;
        		}while (fname[i - 1] != 0 && i < 40);
        
        		pbuf_free(p);

        		if (!fs_open(fname, &file))
        		{
          			fs_open("/STM32F107.html", &file);
        		}
        		hs->file = file.data;
        		hs->left = file.len;

        		send_data(pcb, hs);

        		/* Tell TCP that we wish be to informed of data that has been
           		   successfully sent by a call to the http_sent() function. */
        		tcp_sent(pcb, http_sent);
      		}
      		else
      		{
        		close_conn(pcb, hs);		//关闭连接
      		}
    	}
    	else
    	{
      		pbuf_free(p);
    	}
  	}

  	if (err == ERR_OK && p == NULL)
  	{
    	close_conn(pcb, hs);				//关闭连接
  	}
  
  	return ERR_OK;
}

/**
  * @brief  This function when the HTTP connection is established
  * @param  arg  user supplied argument 
  * @param  pcb	 the tcp_pcb which accepted the connection
  * @param  err	 error value
  * @retval ERR_OK
  */
static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
	struct http_state *hs;

	u32_t IPaddress;
	u8_t iptxt[20];
	volatile u8_t iptab[4];
  
	IPaddress = pcb->remote_ip.addr;
	printf("\n\rhttp_accept:%d.%d.%d.%d\n\r", (u8_t)(IPaddress),
                 (u8_t)(IPaddress >> 8),(u8_t)(IPaddress >> 16),(u8_t)(IPaddress >> 24));

	/* read its IP address */
	iptab[0] = (u8_t)(IPaddress >> 24);
	iptab[1] = (u8_t)(IPaddress >> 16);
	iptab[2] = (u8_t)(IPaddress >> 8);
	iptab[3] = (u8_t)(IPaddress);

	sprintf((char*)iptxt, "Http: %d.%d.%d.%d   ", iptab[3], iptab[2], iptab[1], iptab[0]);	
  
//	LCD_DisplayStringLine(Line6, iptxt);
  
	/* Allocate memory for the structure that holds the state of the connection. */
  	hs = mem_malloc(sizeof(struct http_state));

	if (hs == NULL)
	{
		return ERR_MEM;
	}

	/* Initialize the structure. */
	hs->file = NULL;
	hs->left = 0;

	/* Tell TCP that this is the structure we wish to be passed for our callbacks. */
	tcp_arg(pcb, hs);

	/* Tell TCP that we wish to be informed of incoming data by a call
	   to the http_recv() function. */
	tcp_recv(pcb, http_recv);

	//Called when an error occurs on the connection
	tcp_err(pcb, conn_err);

	//使用LwIP轮询功能
	tcp_poll(pcb, http_poll, 10);
	
	return ERR_OK;
}

/**
  * @brief  Initialize the HTTP application  
  * @param  None 
  * @retval None 
  */
void httpd_init(void)
{
	struct tcp_pcb *pcb;

	/* Create a new TCP control block  */
	pcb = tcp_new();
  
	/* Assign to the new pcb a local IP address and a port number */
	/* Using IP_ADDR_ANY allow the pcb to be used by any local interface */
	tcp_bind(pcb, IP_ADDR_ANY, 80);

	/* Set the connection to the LISTEN state */
	pcb = tcp_listen(pcb);

	/* Specify the function to be called when a connection is established */	
	tcp_accept(pcb, http_accept);
}

/**
  * @brief  This function is  
  * @param  name
  * @parm   file
  * @retval  
  */
int fs_open(char *name, struct fs_file *file)
{
	struct fsdata_file_noconst *f;

	for(f = (struct fsdata_file_noconst *)FS_ROOT; f != NULL; 
                    f = (struct fsdata_file_noconst *)f->next)
	{
    	if (!strcmp(name, f->name))
    	{
      		file->data = f->data;
      		file->len = f->len;
      		return 1;
    	}
  	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -