0
Dependencies: EthernetInterface FatFileSystem SDFileSystem mbed-rtos mbed
main.cpp
- Committer:
- jys1
- Date:
- 2015-05-28
- Revision:
- 0:552dbf78352a
File content as of revision 0:552dbf78352a:
#include "mbed.h" #include "SDFileSystem.h" #include "EthernetInterface.h" #include <stdio.h> #include <string.h> #define PORT 80 EthernetInterface eth; TCPSocketServer svr; bool serverIsListened = false; TCPSocketConnection client; bool clientIsConnected = false; DigitalOut led1(LED1); // 서버 응답 상태 DigitalOut led2(LED2); // 소켓 연결 상태 DigitalOut SIGNAL_LED(D13); // 신호 출력용 Ticker led_tick; Serial pc(USBTX, USBRX); SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS /* -------------------------------------------- * 문자열이 해당 패턴으로 끝나는지 판단하는 함수 * * 성공하면 1 반환, 실패하면 0 반환 * -------------------------------------------*/ int str_ends_with(const char *str, const char *suffix) { if (str == NULL || suffix == NULL) return 0; size_t str_len = strlen(str); size_t suffix_len = strlen(suffix); if (suffix_len > str_len) return 0; return (strncmp(str + str_len - suffix_len, suffix, suffix_len) == 0); } /* -------------------------------------------- * LED 점멸 함수 * -------------------------------------------*/ void led_tick_func(void) { if (serverIsListened) { led1 = !led1; } else { led1 = false; } } /* -------------------------------------------- * TCP Socket 서버 설정 함수 * * 성공하면 0 반환, 실패하면 그 외의 값 반환 * -------------------------------------------*/ int init_server(void) { // ethernet interface 설정 eth.init(); // DHCP 사용 eth.connect(); // 연결 // 연결에 성공하면 IP 주소 출력 printf("IP Address is %s\r\n", eth.getIPAddress()); if (strlen(eth.getIPAddress()) == 0) return -1; // tcp socket 설정 (포트번호: 80) if (svr.bind(PORT) < 0) { printf("tcp server bind failed.\r\n"); return -2; } else { printf("tcp server bind successed.\r\n"); serverIsListened = true; } if (svr.listen(1) < 0) { printf("tcp server listen failed.\r\n"); return -3; } else { printf("tcp server is listening...\r\n"); } return 0; } /* -------------------------------------------- * 입력 스트링에서 URL 부분만 잘라서 반환 * -------------------------------------------*/ char* get_url(char* buffer) { size_t len = strlen(buffer); for (int i = 0; i < len; i++) { if ((buffer[i] == ' ') || (buffer[i] == '\t')) { buffer[i] = '\0'; break; } } return buffer; } /* -------------------------------------------- * HTTP 응답 함수 * -------------------------------------------*/ void make_response(char* buffer) { FILE* fp; //setup http response header & data char echoHeader[256] = {}; char filename[1024] = {}; char resbuffer[1024]; char* url = get_url(buffer); // URL이 /ON 이면 SIGNAL_LED ON if ((strcmp(url, "/ON") == 0) || (strcmp(url, "/on") == 0)) { SIGNAL_LED = 1; url = (char*)"/led-on.html"; } // URL이 /OFF 이면 SIGNAL_LED OFF if ((strcmp(url, "/OFF") == 0) || (strcmp(url, "/off") == 0)) { SIGNAL_LED = 0; url = (char*)"/led-off.html"; } // SD Card 상의 파일명으로 매치 sprintf(filename, "/sd/www%s", url); printf("URL = [%s]\r\n", url); printf("FILE NAME = [%s]\r\n", filename); // URL에 파일명이 없으면 index.html로 매칭 if (strcmp(filename, "/sd/www/") == 0) sprintf(filename, "/sd/www/index.html"); printf("FINAL FILE NAME = [%s]\r\n", filename); // html page open fp = fopen(filename, "r"); if (!fp) { // 파일을 찾을 수 없으면 404 에러 메시지 출력 sprintf(echoHeader, "HTTP/1.1 404 Not Found\r\n" "Content-Length: 16\r\n" "Content-Type: text/html\r\n" "Connection: Close\r\n\r\n"); client.send(echoHeader, strlen(echoHeader)); client.send((char*)"FILE NOT FOUND\r\n", 16); clientIsConnected = false; printf("echo back done.\r\n"); return; } // 파일 크기 출력 fseek(fp, 0L, SEEK_END); size_t sz = ftell(fp); printf("file size = %d\r\n", sz); // 응답 헤더 sprintf(echoHeader, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n", sz); client.send(echoHeader, strlen(echoHeader)); // 파일 종류에 따른 응답 헤더 (Content-Type) if (str_ends_with(url, ".html") || str_ends_with(url, ".htm")) { sprintf(echoHeader, "Content-Type: text/html\r\n"); } else if (str_ends_with(url, ".css")) { sprintf(echoHeader, "Content-Type: text/css\r\n"); } else if (str_ends_with(url, ".png")) { sprintf(echoHeader, "Content-Type: image/png\r\n"); } else if (str_ends_with(url, ".jpg")) { sprintf(echoHeader, "Content-Type: image/jpeg\r\n"); } else if (str_ends_with(url, ".gif")) { sprintf(echoHeader, "Content-Type: image/gif\r\n"); } else if (str_ends_with(url, ".3gp")) { sprintf(echoHeader, "Content-Type: video/mpeg\r\n"); } else if (str_ends_with(url, ".pdf")) { sprintf(echoHeader, "Content-Type: application/pdf\r\n"); } else if (str_ends_with(url, ".js")) { sprintf(echoHeader, "Content-Type: application/x-javascript\r\n"); } else if (str_ends_with(url, ".xml")) { sprintf(echoHeader, "Content-Type: application/xml\r\n"); } else { sprintf(echoHeader, "Content-Type: text\r\n"); } client.send(echoHeader, strlen(echoHeader)); sprintf(echoHeader, "Connection: Close\r\n\r\n"); client.send(echoHeader, strlen(echoHeader)); // 파일 내용을 읽어서 클라이언트로 전송 fseek(fp, 0L, SEEK_SET); size_t n = 1; while (n) { n = fread(resbuffer, sizeof(char), 1023, fp); resbuffer[n] = '\0'; client.send(resbuffer, n); } fclose(fp); clientIsConnected = false; printf("echo back done.\r\n"); } int main(void) { pc.baud(115200); led_tick.attach(&led_tick_func, 0.5); if (init_server() < 0) { printf("HTTP Server initization failed...\r\n"); for (;;) ; } //listening for http GET request while (serverIsListened) { //blocking mode(never timeout) if (svr.accept(client) < 0) { printf("failed to accept connection.\r\n"); } else { printf("connection success!\r\nIP: %s\r\n",client.get_address()); clientIsConnected = true; led2 = true; while (clientIsConnected) { char buffer[1024] = {}; switch (client.receive(buffer, 1023)) { case 0: printf("recieved buffer is empty.\r\n"); clientIsConnected = false; break; case -1: printf("failed to read data from client.\r\n"); clientIsConnected = false; break; default: printf("Recieved Data: %d\r\n\r\n%.*s\r\n", strlen(buffer),strlen(buffer),buffer); if (buffer[0] == 'G' && buffer[1] == 'E' && buffer[2] == 'T') { printf("GET request incomming.\r\n"); make_response(buffer+4); } break; } } printf("close connection.\r\ntcp server is listening...\r\n"); client.close(); led2 = false; } } }