Notice
Recent Posts
Recent Comments
Today
Total
05-16 05:42
Archives
관리 메뉴

Jeongchul Kim

Intel Edison board 웹에서 LED 제어하기 본문

사물인터넷

Intel Edison board 웹에서 LED 제어하기

김 정출 2016. 3. 8. 13:58


Intel Edison board 웹에서 LED 제어하기


소스 입력하기


#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <string.h>

#include <fcntl.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

void * on_connect(void *arg);

void sendData(FILE *response, char *file_name);

void sendHead(FILE *response,int status,  char *mime_type);

void sendNoService(FILE *response);

int main(int argc, char **argv){

int serv_sock;

pthread_t thread;

struct sockaddr_in serv_addr, clnt_addr;

socklen_t clnt_addr_size;

int port = 8000;

if(argc >= 2){

port = atoi(argv[1]);

}

serv_sock = socket(PF_INET, SOCK_STREAM, 0);

if(serv_sock == -1){

perror("fail to open socker");

return 1;

}

memset(&serv_addr, 0, sizeof(serv_addr));

serv_addr.sin_family = AF_INET;

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

serv_addr.sin_port = htons(port);

if(bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr))==-1){

perror("fail to bind");

return 1;

}

if(listen(serv_sock, 10) ==-1){

perror("fail to listen");

return 1;

}

printf("server is running on %d\n", port);

while(1){

int clnt_sock;

clnt_addr_size = sizeof(clnt_addr);

clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

if(clnt_sock == -1){

perror("fail to accep");

continue;

}

printf("client ip:%s\n", inet_ntoa(clnt_addr.sin_addr));

pthread_create(&thread, NULL, on_connect, &clnt_sock);

pthread_join(thread, 0);

close(clnt_sock);

}

printf("server has been shutdown\n");

return 0;

}

void * on_connect(void *arg){

int clnt_sock = *((int *)arg);

FILE *request, *response;

char line[BUFSIZ];

char method[10];

char file_name[256]="/home/root/public", url[256];

request = fdopen(clnt_sock, "r");

response = fdopen(dup(clnt_sock), "w");

fgets(line, BUFSIZ, request);

printf("%s", line);

strcpy(method, strtok(line, " "));

if(strcmp(method, "GET") == 0){

strcpy(url, strtok(NULL, " "));

if(strcmp(url, "/") == 0){

strcat(url, "index.html");

}

strcat(file_name, url);

while(1){

memset(line, 0, sizeof(line));

fgets(line, BUFSIZ, request);

if(strcmp(line,"\r\n") == 0){

      break;

}

printf("%s", line);

}

sendData(response, file_name);

}else{

sendNoService(response);

}

fclose(request);

fclose(response);

return (void *)NULL;

}

void sendData(FILE *response, char *file_name){

char buff[BUFSIZ];

int len;

int fd;

fd = open(file_name, O_RDONLY);

if(fd == -1){

perror(file_name);

sendHead(response, 404, "text/html");

}else{

sendHead(response, 200, "text/html");

while( (len = read(fd, buff, BUFSIZ))>0){

fwrite(buff, sizeof(char), len, response);

}

}

fflush(response);

}

void sendHead(FILE *response,int status,  char *mime_type){

char res_line[80] = "HTTP/1.1";

char content_type[1024] = "Conent-Type:";

char body[1024] = "<html><body><h1>";

strcat(content_type, mime_type);

strcat(content_type, "\r\n\r\n");

switch(status){

case 200:

strcat(res_line, " 200 OK\r\n");

break;

case 404:

strcat(res_line, " 404 Not Fount\r\n");

strcat(body, "404 Not Found</h1></body></html>");

break;

default:

strcat(res_line, " 500 Interanl server error\r\n");

strcat(body, "500 Internal server error</h1></body></html>");

break;

}

fputs(res_line, response);

fputs(content_type, response);

if(status != 200){

fputs(body, response);

}

}

void sendNoService(FILE *response){

sendHead(response, 200, "text/html");

char *body = "<html><body><h1>Sorry. Only GET method available</h1></body></html>";

fputs(body, response);

fflush(response);

}



라이브러리 추가하기


링커 라이브러리에서 pthread 라이브러리 추가


컴파일해본다.

컴파일 완료



Target SSH Conections 창에서 Launch Terminal 실행


index.html 생성

<!Doctype html>

<html>

<body>

<h1>Welcome to Edison</h1>

<p>Made by Jeongchul</p>

<form method="GET" action="/cgi/cmd">

<button name = "led" value="on">On</button>

<button name = "led" value="on">Off</button>

</form>

</body>

</html>



mkdir명령어로 public 디렉터리 생성


Eclipse 창의 perspective에서 Remote Systems로 변경

My Home에 생성된 public에 index.html을 복사 붙여넣기한다.


명령어를 통해 확인한다


보드에 업로드 해보자

완료가 되면 웹서버 주소로 접근해보자


192.168.0.246:8000

자신의 ip는 ifconfig로 확인하자


192.168.0.246:8000 로 접근



LED 제어를 위한 index.html 수정하기


<!Doctype html>

<html>

<body>

<h1>Welcome to Edison</h1>

<p>Made by Jeongchul</p>

<form method="GET" action="/cgi/cmd">

<button name = "led" value="on">On</button>

<button name = "led" value="off">Off</button>

</form>

</body>

</html>






수정된 내용을 Remote System Explorer를 통해 갱신한다.



웹 브라우저로 주소에 접근한다.


이제 C 언어 파일을 수정한다.

소스 코드 수정

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <string.h>

#include <fcntl.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include "mraa.h"

#define CGI "/cgi/"

void * on_connect(void *arg);

void sendData(FILE *response, char *file_name);

void sendHead(FILE *response,int status,  char *mime_type);

void sendNoService(FILE *response);

void doCGI(FILE *response, char *url);

int turn_led(int pin, int isOn);

int main(int argc, char **argv){

int serv_sock;

pthread_t thread;

struct sockaddr_in serv_addr, clnt_addr;

socklen_t clnt_addr_size;

int port = 8000;

if(argc >= 2){

port = atoi(argv[1]);

}

serv_sock = socket(PF_INET, SOCK_STREAM, 0);

if(serv_sock == -1){

perror("fail to open socker");

return 1;

}

memset(&serv_addr, 0, sizeof(serv_addr));

serv_addr.sin_family = AF_INET;

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

serv_addr.sin_port = htons(port);

if(bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr))==-1){

perror("fail to bind");

return 1;

}

if(listen(serv_sock, 10) ==-1){

perror("fail to listen");

return 1;

}

printf("server is running on %d\n", port);

while(1){

int clnt_sock;

clnt_addr_size = sizeof(clnt_addr);

clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

if(clnt_sock == -1){

perror("fail to accep");

continue;

}

printf("client ip:%s\n", inet_ntoa(clnt_addr.sin_addr));

pthread_create(&thread, NULL, on_connect, &clnt_sock);

pthread_join(thread, 0);

close(clnt_sock);

}

printf("server has been shutdown\n");

return 0;

}

void * on_connect(void *arg){

int clnt_sock = *((int *)arg);

FILE *request, *response;

char line[BUFSIZ];

char method[10];

char file_name[256]="/home/root/public", url[256];

request = fdopen(clnt_sock, "r");

response = fdopen(dup(clnt_sock), "w");

fgets(line, BUFSIZ, request);

printf("%s", line);

strcpy(method, strtok(line, " "));

if(strcmp(method, "GET") == 0){

strcpy(url, strtok(NULL, " "));

if(strncmp(url,CGI,strlen(CGI)) == 0){ // Is it start /cgi/?

printf("\ncgi : %s\n",url);

doCGI(response, url + strlen(CGI)); // move pointer /cgi/

} else {

if(strcmp(url, "/") == 0){

strcat(url, "index.html");

}

strcat(file_name, url);

while(1){

memset(line, 0, sizeof(line));

fgets(line, BUFSIZ, request);

if(strcmp(line,"\r\n") == 0){

  break;

}

printf("%s", line);

}

sendData(response, file_name);

}

}else{

sendNoService(response);

}

fclose(request);

fclose(response);

return (void *)NULL;

}

void sendData(FILE *response, char *file_name){

char buff[BUFSIZ];

int len;

int fd;

fd = open(file_name, O_RDONLY);

if(fd == -1){

perror(file_name);

sendHead(response, 404, "text/html");

}else{

sendHead(response, 200, "text/html");

while( (len = read(fd, buff, BUFSIZ))>0){

fwrite(buff, sizeof(char), len, response);

}

}

fflush(response);

}

void sendHead(FILE *response,int status,  char *mime_type){

char res_line[80] = "HTTP/1.1";

char content_type[1024] = "Conent-Type:";

char body[1024] = "<html><body><h1>";

strcat(content_type, mime_type);

strcat(content_type, "\r\n\r\n");

switch(status){

case 200:

strcat(res_line, " 200 OK\r\n");

break;

case 404:

strcat(res_line, " 404 Not Fount\r\n");

strcat(body, "404 Not Found</h1></body></html>");

break;

default:

strcat(res_line, " 500 Interanl server error\r\n");

strcat(body, "500 Internal server error</h1></body></html>");

break;

}

fputs(res_line, response);

fputs(content_type, response);

if(status != 200){

fputs(body, response);

}

}

void sendNoService(FILE *response){

sendHead(response, 200, "text/html");

char *body = "<html><body><h1>Sorry. Only GET method available</h1></body></html>";

fputs(body, response);

fflush(response);

}

void doCGI(FILE *response, char *url){

char cmd[256], key[256], value[256];

printf("cgi url : %s",url);

strcpy(cmd, strtok(url,"?"));

strcpy(key, strtok(NULL,"="));

strcpy(value,strtok(NULL,"="));

printf("cmd : %s, key : %s, value : %s\n",cmd,key,value);

int result = 0;

char *body;

if(strcmp(cmd,"cmd") == 0) {

if(strcmp(key,"led") == 0) {

if(strcmp(value,"on") == 0) {

result = turn_led(13,1);

body="<html><body><h1>Led On</h1><p>led on successfully</p>\

</body></html>";

}else if(strcmp(value,"off") == 0){

result = turn_led(13,0);

body="<html><body><h1>Led Off</h1><p>led off successfully</p>\

</body></html>";

}

}

if(result == 0) {

sendHead(response, 200, "text/html");

fputs(body,response);

}else {

sendHead(response, 500, "text/html");

}

}

fflush(response);

}

int turn_led(int pin, int isOn){

mraa_gpio_context led = mraa_gpio_init(pin);

if(led == NULL) {

perror("gpio init error");

return 1;

}

if(mraa_gpio_dir(led,MRAA_GPIO_OUT) != MRAA_SUCCESS) {

perror("fail to set led : out");

return 1;

}

if(isOn) {

mraa_gpio_write(led,1);

}else {

mraa_gpio_write(led,0);

}

return 0;

}


테스트

빌드해보고 테스트해봅시다



버튼 Led Off 누를 시


버튼 Led On 누를 시




'사물인터넷' 카테고리의 다른 글

Intel Edison board XDK IoT  (0) 2016.03.08
Intel Edison board Eclipse Java LED 제어하기  (0) 2016.03.08
Intel Edison Board IoT mraa API 사용  (0) 2016.03.08
Intel Edison Board IoT Eclipse  (0) 2016.03.08
Intel Edison Board GPIO Control  (0) 2016.03.08
Comments