📄 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.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* httpd.c
*
* Author : Adam Dunkels <adam@sics.se>
*
* CHANGELOG: this file has been modified by Sergio Perez Alca駃z <serpeal@upvnet.upv.es>
* Departamento de Inform醫ica de Sistemas y Computadores
* Universidad Polit閏nica de Valencia
* Valencia (Spain)
* Date: March 2003
*
*/
#include "httpd.h"
#include "stm3210c_eval_lcd.h" // w w w . a r m j i s h u . c o m
#include "lwip/tcp.h"
#include "fsdata.c"
#include "main.h"
#include <string.h>
#include <stdio.h>
struct http_state
{
char *file;
u32_t left;
};
/*-----------------------------------------------------------------------------------*/
static void
conn_err(void *arg, err_t err)
{
struct http_state *hs;
hs = arg;
mem_free(hs);
}
/*-----------------------------------------------------------------------------------*/
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;
}
}
/*-----------------------------------------------------------------------------------*/
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;
}
/*-----------------------------------------------------------------------------------*/
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;
STM_EVAL_LEDOff(LED1);
STM_EVAL_LEDOff(LED2);
STM_EVAL_LEDOff(LED3);
STM_EVAL_LEDOff(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 */)
{
STM_EVAL_LEDOn(LED1);
}
if(data[i]==0x32 /* 2 */)
{
STM_EVAL_LEDOn(LED2);
}
if(data[i]==0x33 /* 3 */)
{
STM_EVAL_LEDOn(LED3);
}
if(data[i]==0x34 /* 4 */)
{
STM_EVAL_LEDOn(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;
}
/*-----------------------------------------------------------------------------------*/
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);
tcp_err(pcb, conn_err);
tcp_poll(pcb, http_poll, 10);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
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);
}
/*-----------------------------------------------------------------------------------*/
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 + -