/****************************************************************** ***** ***** ***** Name: easyweb.c ***** ***** Ver.: 1.0 ***** ***** Date: 07/05/2001 ***** ***** Auth: Andreas Dannenberg ***** ***** HTWK Leipzig ***** ***** university of applied sciences ***** ***** Germany ***** ***** Func: implements a dynamic HTTP-server by using ***** ***** the easyWEB-API ***** ***** ***** ******************************************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "LPC17xx.h" // Keil: Register definition file for LPC17xx #include "ff.h" #include "./SPI_SD_Card/SPI_MSD_Driver.h" #define extern // Keil: Line added for modular project management #include "easyweb.h" #include "type.h" #include "EMAC.h" // Keil: *.c -> *.h // ethernet packet driver #include "tcpip.h" // Keil: *.c -> *.h // easyWEB TCP/IP stack //#include "webpage.h" // webside for our HTTP server (HTML) FATFS fs; /* Work area (file system object) for logical drive */ FIL fsrc; /* file objects */ FILINFO fi; void getPageDir(char*,char*); void lastname(char*,char*); int getType(char *p); extern void TCPClockHandler(void); unsigned char mounted=0; unsigned char getFileActive=0; char GetFile[100]; volatile DWORD TimeTick = 0; /* SysTick interrupt happens every 10 ms */ void SysTick_Handler (void) { TimeTick++; if (TimeTick >= 20) { TimeTick = 0; LPC_GPIO3->FIOPIN ^= 1 << 25; TCPClockHandler(); } } //void main(void) int main(void) { //InitOsc(); // Keil: No oscillator initialization necessary at this time. //InitPorts(); // Keil: No port initialization necessary at this time. SystemInit(); /* setup core clocks */ SysTick_Config(SystemFrequency/100); /* Generate interrupt every 10 ms */ LPC_GPIO0->FIODIR |= 1 << 21; LPC_GPIO0->FIOPIN |= 1 << 21; LPC_GPIO3->FIODIR |= 1 << 25; /* P2.0 defined as Output (LED) */ TCPLowLevelInit(); MSD_SPI_Configuration(); HTTPStatus = 0; // clear HTTP-server's flag register TCPLocalPort = TCP_PORT_HTTP; // set port we want to listen to
while (1) // repeat forever { if (!(SocketStatus & SOCK_ACTIVE)) TCPPassiveOpen(); // listen for incoming TCP-connection DoNetworkStuff(); // handle network and easyWEB-stack if( _card_insert() == 0 && mounted == 0) {f_mount(0,&fs);mounted = 1; }else if(_card_insert()){ mounted = 0;// events } HTTPServer(); } } // This function implements a very simple dynamic HTTP-server. // It waits until connected, then sends a HTTP-header and the // HTML-code stored in memory. Before sending, it replaces // some special strings with dynamic values. // NOTE: For strings crossing page boundaries, replacing will // not work. In this case, simply add some extra lines // (e.g. CR and LFs) to the HTML-code. void HTTPServer(void) { char lName[4]; unsigned int len,lPut = 0; int iType; int a = sizeof(unsigned); if (SocketStatus & SOCK_CONNECTED) // check if somebody has connected to our TCP { if (SocketStatus & SOCK_DATA_AVAILABLE) // check if remote TCP sent data { getPageDir((char*)TCP_RX_BUF,&GetFile[0]); TCPReleaseRxBuffer(); // and throw it away }else if (SocketStatus & SOCK_TX_BUF_RELEASED){ if (!(HTTPStatus & HTTP_SEND_PAGE) && getFileActive == 1) // init byte-counter and pointer to webside { memcpy(TCP_TX_BUF, GetResponse, sizeof(GetResponse) - 1);lPut = sizeof(GetResponse) - 1; if(mounted)// if called the 1st time {if(strcmp(GetFile,"0:/") == 0) { if(f_stat("0:/index.htm",&fi)==FR_OK) { const char res[]={ "HTTP/1.0 200 OK\r\n" "Content-Type: text/html\r\n\r\n" }; f_open(&fsrc,"0:/index.htm",FA_READ); HTTPBytesToSend = fi.fsize;memcpy(TCP_TX_BUF, res, sizeof(res) - 1);TCPTxDataCount = sizeof(res); } else { char str2[]="HTTP/1.0 404 Not Found\r\n"; HTTPBytesToSend = 0;TCPTxDataCount = sizeof(str2); memcpy(TCP_TX_BUF,str2,sizeof(str2));} }else{ lastname(&GetFile[0],lName); iType=getType(lName); if(f_stat(&GetFile[0],&fi)==FR_OK) {f_open(&fsrc,&GetFile[0],FA_READ); HTTPBytesToSend = fi.fsize; memcpy(TCP_TX_BUF + lPut,strContent,sizeof(strContent)); lPut += sizeof(strContent)-1; memcpy(TCP_TX_BUF + lPut,ContentType[iType],strlen(ContentType[iType])); lPut += strlen(ContentType[iType]); memcpy(TCP_TX_BUF + lPut,"\r\n\r\n",4); lPut += 4; TCPTxDataCount =lPut; } else { char str2[]="HTTP/1.0 404 Not Found\r\n"; HTTPBytesToSend = 0;TCPTxDataCount = sizeof(str2); memcpy(TCP_TX_BUF,str2,sizeof(str2));}}} else { char str2[]="<html><body>Plase Insert SC-Card.</body></html>\r\n"; HTTPBytesToSend = 0;TCPTxDataCount = sizeof(str2); memcpy(TCP_TX_BUF,str2,sizeof(str2)); } TCPTransmitTxBuffer();HTTPStatus |= HTTP_SEND_PAGE; // ok, 1st loop executed } else if(HTTPBytesToSend) { f_read(&fsrc,TCP_TX_BUF,MAX_TCP_TX_DATA_SIZE,&len); HTTPBytesToSend -= len; TCPTxDataCount = len; TCPTransmitTxBuffer(); } if(HTTPBytesToSend < 1) {if(getFileActive == 1) TCPClose(); getFileActive = 0; f_close(&fsrc); HTTPStatus &= ~HTTP_SEND_PAGE; } } } else { getFileActive = 0; f_close(&fsrc); HTTPStatus &= ~HTTP_SEND_PAGE; } } void getPageDir(char* rxBuff,char *file_dir) {if(rxBuff[0]=='G' && rxBuff[1]=='E' && rxBuff[2]=='T') { file_dir[0]='0'; file_dir[1]=':'; file_dir[2]='/'; file_dir+=3; rxBuff+=5; while(*rxBuff != ' ') { *file_dir++ = *rxBuff++; } *file_dir = '\0'; getFileActive = 1; } } void lastname(char* filname,char*lastname) { while(*filname++ != '.'); while(*filname != '\0') { *lastname = *filname++; if(*lastname>='a' && *lastname<='z') *lastname++ -= 0x20;} *lastname = '\0'; } int getType(char *p) { int i=0; while(strcmp((char*)xContent[i++],p)!=0) if(i==10)return 10;return i - 1; } //EOF
เราจะมาดูกันเป็นส่วนๆนะครับ
1.ส่วนของฟังก์ชั่น main() ครับ
//void main(void) int main(void) { //InitOsc(); // Keil: No oscillator initialization necessary at this time. //InitPorts(); // Keil: No port initialization necessary at this time. SystemInit(); /* setup core clocks */ SysTick_Config(SystemFrequency/100); /* Generate interrupt every 10 ms */ LPC_GPIO0->FIODIR |= 1 << 21; LPC_GPIO0->FIOPIN |= 1 << 21; LPC_GPIO3->FIODIR |= 1 << 25; /* P2.0 defined as Output (LED) */ TCPLowLevelInit(); MSD_SPI_Configuration(); HTTPStatus = 0; // clear HTTP-server's flag register TCPLocalPort = TCP_PORT_HTTP; // set port we want to listen to
ฟังก์ชั่นนี้จะจัดการกับคำสั่งที่ได้รับมาจาก Client ครับคือลูกข่ายจะเรียกข้อมูลหรือไฟล์จาก Server โดยมีคำสั่ง GET (file directory) ครับคือขึ้นต้นด้วย GET หรือ POST ครับ แต่โปรแกรมที่ผมเขียนไว้ให้นั่น มันสามารถรับได้แค่คำสั่ง GET ครับ