📄 httpd.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 + -