Skip to content
Snippets Groups Projects
Commit 67c8523f authored by 김가을's avatar 김가을
Browse files

Upload New File

parent 9b0b3820
Branches
No related tags found
No related merge requests found
server.c 0 → 100644
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h>
int server_sock; // 서버 소켓 descriptor
pthread_t th[3];
int gas_detection = 0; // gas thread에서 소켓 통신 전달 신호값 저장
int motion_detection = 0; // motion thread에서 소켓 통신 전달 신호값 저장
FILE* fp; // pwm duty_cycle 파일 포인터
// 나의 ip 192.168.111.7
struct connecting_socket{ // connection 요청하는 client와 연결하는 socket 생성시 사용하는 구조체
struct sockaddr_in socket_addr ;
socklen_t socket_addr_size;
int sock;
}cs[3];
void siren(){ // pwm 이용해서 사이렌 형식으로 경고등 점등 함수
time_t start = time(NULL);
while(time(NULL)-start <= 5){ // 약 5초간만 점등
for (int i = 0; i < 1000; i+=2){
fprintf(fp,"%d",i*500);
fflush(fp);
usleep(800);
}
for(int i = 1000; i >0; i-=2){
fprintf(fp, "%d",i*500);
fflush(fp);
usleep(800);
}
}
fprintf(fp,"%d",0);
fflush(fp);
}
void* read_gasvalue(void * socket){ // gas 센서 쓰레드
char gas_check;
struct connecting_socket* sk = (struct connecting_socket*)socket;
ssize_t read_stat;
while(1){
read_stat = read(sk->sock, &gas_check, 1);
if(read_stat == -1) {
perror("Client Output; reading data from socket error");
exit(1);
}
else if(read_stat == 0) break;
else{
printf("gas : %c\n",gas_check);
if(!strncmp(&gas_check,"1",1)){ //가스 발생
gas_detection = 1;
sleep(1);
}else {// 가스 미발생
gas_detection = 0;
sleep(1);
}
}
}
close(sk->sock);
printf("connection with client is closed!\n");
}
void* camera(void * socket){ // camer 쓰레드
char buff[3] = "10";
struct connecting_socket* sk = (struct connecting_socket*)socket;
while(1){
if(gas_detection && motion_detection){ // 가스 1 && 모션 1 -> 흡연 감지 됨 -> 촬영신호 1 전달
if(write(sk->sock,&buff[0],1)== -1) perror(" write error");
system("mpg321 -q smoke.mp3"); // 서버실행파일이랑 같은 위치에 있는 mp3 파일 재생
siren(); // 경고등 점등
}else{
if(write(sk->sock,&buff[1],1)== -1) perror(" write error"); // 흡연 아님 -> 신호 0 전달
}
}
}
void* motion(void * socket){ // 모션 센서 쓰레드
char motion_check;
ssize_t read_stat;
struct connecting_socket* sk = (struct connecting_socket*)socket;
while(1){
read_stat = read(sk->sock, &motion_check, 1);
if(read_stat == -1) {
perror("Client Output; reading data from socket error");
exit(1);
}
else if(read_stat == 0) break;
else{
printf("motion %c\n",motion_check);
if(!strncmp(&motion_check,"1",1)){ //모션 발생
motion_detection = 1;
sleep(1);
}else {// 모션 미발생
motion_detection = 0;
sleep(1);
}
}
}
close(sk->sock);
printf("connection with client is closed!\n");
}
void error_handling(char *message, int sock) {//socket error날 시 handle
close(sock); // socket 닫기
perror(message); // error message 출력
fputc('\n', stderr);
exit(1); // 종료
}
void sig_handler(int signo){ // ctrl + C 로 server 강제 종료할 때 handling
printf("\n");
close(server_sock); // 서버 socket 닫기
fclose(fp); // pwm duty_cycle stream 닫기
int fd = open("/sys/class/pwm/pwmchip0/unexport",O_WRONLY);
write(fd,"0",1); // pwm unexport
// write(fd,"1",1);
close(fd);
exit(0); // 종료
}
/* void set_gpio(){
int fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd == -1) {
perror("Error exporting GPIO");
return -1;
}
write(fd,"22",3);
write(fd,"27",3);
close(fd);
sleep(1);
fd = open("/sys/class/gpio/gpio22/direction", O_WRONLY);
if (fd == -1) {
perror("Error set direction gpio");
return -1;
}
write(fd,"out",3);
close(fd);
fd = open("/sys/class/gpio/gpio27/direction", O_WRONLY);
if (fd == -1) {
perror("Error set direction gpio");
return -1;
}
write(fd,"out",3);
close(fd);
} */
void pwm(){ // pwm setting pwm0만 사용
int fd = open("/sys/class/pwm/pwmchip0/export",O_WRONLY);
write(fd,"0",1);
close(fd);
sleep(1);
fd = open("/sys/class/pwm/pwmchip0/pwm0/period", O_WRONLY);
write(fd,"1000000",6);
close(fd);
fd=open("/sys/class/pwm/pwmchip0/pwm0/duty_cycle", O_WRONLY);
write(fd,"0",1);
close(fd);
fd= open("/sys/class/pwm/pwmchip0/pwm0/enable", O_WRONLY);
write(fd,"1",1);
close(fd);
fp=fopen("/sys/class/pwm/pwmchip0/pwm0/duty_cycle", "w");
/* fd = open("/sys/class/pwm/pwmchip0/export",O_WRONLY);
write(fd,"1",1);
close(fd);
sleep(1);
fd = open("/sys/class/pwm/pwmchip0/pwm1/period", O_WRONLY);
write(fd,"1000000",6);
close(fd);
fd=open("/sys/class/pwm/pwmchip0/pwm1/duty_cycle", O_WRONLY);
write(fd,"0",1);
close(fd);
fd= open("/sys/class/pwm/pwmchip0/pwm1/enable", O_WRONLY);
write(fd,"1",1);
close(fd);
fp=fopen("/sys/class/pwm/pwmchip0/pwm1/duty_cycle", "w");
*/
}
int main( int argc, char*argv[]){
struct sockaddr_in server_addr;
int i = 0; // 연결된 클라이언트 수 세기 위한 변수
signal(SIGINT, (void*)sig_handler);
pwm(); // pwm 셋업
if(argc !=2 ){ // server 프로그램 실행시 port num을 인자로 입력하지 않았을 때
printf("Please deliver Port num as argument Correctly!\n");
exit(1);
}
server_sock = socket(PF_INET, SOCK_STREAM, 0); // ipv4 서버 socket 생성
if(server_sock== -1) error_handling("socket() error", server_sock);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; // ipv4
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 서버 Ip 자동 대입
server_addr.sin_port = htons(atoi(argv[1])); // 인자로 받은 port num 저장
if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) // 서버 socket에 ip 포트넘버 지정
error_handling("bind() error", server_sock);
if (listen(server_sock, 5) == -1) error_handling("listen() error", server_sock); // client connection 요청 듣기
while(1) {
if(i==4) break;
cs[i].socket_addr_size = sizeof(cs[i].socket_addr);
cs[i].sock = accept(server_sock, (struct sockaddr *)&(cs[i].socket_addr), &(cs[i].socket_addr_size)); // client connection 요청 받아들이고, connecting socket 생성
if (cs[i].sock == -1) { // accept 함수 error control
perror("accept() error");
close(cs[i].sock); // socket 닫고
printf("errror");
continue; // 다시 accept할 수 있도록 continue
}
// client와의 connection이 성립되어 join 하게되었음을 출력
printf("Client join fd[%d], ip:[%s], port:[%d]\n",cs[i].sock,inet_ntoa(cs[i].socket_addr.sin_addr), ntohs(cs[i].socket_addr.sin_port));
if(!(strncmp("192.168.111.12",inet_ntoa(cs[i].socket_addr.sin_addr),13))){ // 모션
if(pthread_create(&th[i], NULL, motion, (void *)&cs[i] )){
perror("thread creating error");
close(cs[i].sock);
continue;
}
}else if(!(strncmp("192.168.111.5",inet_ntoa(cs[i].socket_addr.sin_addr),13))){ // 가스
if(pthread_create(&th[i], NULL, read_gasvalue, (void *)&cs[i] )){
perror("thread creating error");
close(cs[i].sock);
continue;
}
}else if(!(strncmp("192.168.111.9",inet_ntoa(cs[i].socket_addr.sin_addr),13))){ // 카메라
if(pthread_create(&th[i], NULL, camera, (void *)&cs[i] )){
perror("thread creating error");
close(cs[i].sock); // 에러 발생시 socket닫고
continue; // socket accept부터 다시 while문 돌기
}
}
pthread_detach(th[i++]); // 생성한 thread룰 main 에서 분리해서 원격 shell 종료시 자동 자원 반환하도록
}
while(1){} // main 종료 안되게 무한 반복문 돌려 놓기
return 0;
}
/*
<pseudo code> 미완 코드 구체화 필요
int sock;
int argc, char*argv[]
struct sockaddr_in server_addr;
if (argc != 3) { // client 프로그램 실행 시 인자에 IP랑 port num을 제대로 주지 않았을 때
printf("Please deliver IP & Port num as arguments Correctly!\n");
exit(1);
}
sock = socket(PF_INET, SOCK_STREAM, 0); // socket 생성 TCP 방식 IPv4
if (sock== -1) error_handling("socket() error", sock); // socket 생성시 error control
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; //IPv4
server_addr.sin_addr.s_addr = inet_addr(argv[1]); // IP 변환해서 저장
server_addr.sin_port = htons(atoi(argv[2])); //port num 변환해서 저장
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) error_handling("connect() error", sock);
}
*/
/*
char buff[3]="10"
if(가스 && 일산화 모두 감지){
if(write(sock, &buff[0], 1) == -1) perror("Client input; sending data to server error");
}else{
if(write(sock, &buff[1], 1) == -1) perror("Client input; sending data to server error");
*/
/*
char buff[3]="10"
if(모션 감지 됨){
if(write(sock, &buff[0], 1) == -1) perror("Client input; sending data to server error");
}else{
if(write(sock, &buff[1], 1) == -1) perror("Client input; sending data to server error");
*/
/*
ssize_t read_stat;
char picture;
while(1){
read_stat = read(sock, &picture, 1);
if(read_stat == -1) {
perror("Client Output; reading data from socket error");
exit(1);
}
else if(read_stat == 0) break;
else{
if(!strncmp(&gas_check,"1",1)){ // 사진 찍음
사진 찍기 함수
sleep(1);
system("cd 사진 있는 경로로 이동");
system("python3 email.py");
}
}
*/
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment