diff --git a/server-node-control/control.c b/server-node-control/control.c index d97ae910ec30ecf0aad4cff79f66be4e25b2910a..0d27b1351a381effd3867a5a0c2fb97334483da4 100644 --- a/server-node-control/control.c +++ b/server-node-control/control.c @@ -5,6 +5,7 @@ #include <unistd.h> #include <arpa/inet.h> #include <pthread.h> +#include <signal.h> #define BUFFER_SIZE 1024 #define PORT 12345 @@ -18,322 +19,454 @@ #define PTHREAD_STACK_MIN 16384 #endif -typedef struct { +typedef struct +{ int socket; + int used; struct sockaddr_in address; + } ClientData; -int pySocket, cSocket, clientCnt = 0; +int pySocket, cSocket, clientCnt = 0, isAlive = 0; pthread_t pyThread, clientThreads[MAX_CLIENTS]; ClientData clients[MAX_CLIENTS]; +struct sockaddr_in pyAddr, cAddr, clientAddr; +pthread_attr_t attr, attr2, at[3]; +struct sched_param param, param2; -static int PWMExport(int pwmnum) { -#define BUFFER_MAX 3 - char buffer[BUFFER_MAX]; - int fd, byte; +void *ClientToServer(void *idx); // 클라이언트 => 서버 메세지 전달 +void *ServerToClient(); // 서버 => 클라이언트 메세지 전달 +void handleForce(int signal); // 강제 종료시 리소스 반환 - // TODO: Enter the export path. - fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY); - if (-1 == fd) { - fprintf(stderr, "Failed to open export for export!\n"); - return (-1); - } +static int PWMExport(int pwmnum) +{ +#define BUFFER_MAX 3 + char buffer[BUFFER_MAX]; + int fd, byte; + + // TODO: Enter the export path. + fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY); + if (-1 == fd) + { + fprintf(stderr, "Failed to open export for export!\n"); + return (-1); + } - byte = snprintf(buffer, BUFFER_MAX, "%d", pwmnum); - write(fd, buffer, byte); - close(fd); + byte = snprintf(buffer, BUFFER_MAX, "%d", pwmnum); + write(fd, buffer, byte); + close(fd); - sleep(1); + sleep(1); - return (0); + return (0); } -static int PWMUnexport(int pwmnum) { +static int PWMUnexport(int pwmnum) +{ #define BUFFER_MAX 3 - char buffer[BUFFER_MAX]; - int fd, byte; - - // TODO: Enter the export path. - fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY); - if (-1 == fd) { - fprintf(stderr, "Failed to open export for unexport!\n"); - return (-1); - } + char buffer[BUFFER_MAX]; + int fd, byte; + + // TODO: Enter the export path. + fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY); + if (-1 == fd) + { + fprintf(stderr, "Failed to open export for unexport!\n"); + return (-1); + } - byte = snprintf(buffer, BUFFER_MAX, "%d", pwmnum); - write(fd, buffer, byte); - close(fd); + byte = snprintf(buffer, BUFFER_MAX, "%d", pwmnum); + write(fd, buffer, byte); + close(fd); - sleep(1); + sleep(1); - return (0); + return (0); } -static int PWMEnable(int pwmnum) { - static const char s_enable_str[] = "1"; - - char path[DIRECTION_MAX]; - int fd; +static int PWMEnable(int pwmnum) +{ + static const char s_enable_str[] = "1"; - // TODO: Enter the enable path. - snprintf(path, DIRECTION_MAX, "/sys/class/pwm/pwmchip0/pwm0/enable"); - fd = open(path, O_WRONLY); - if (-1 == fd) { - fprintf(stderr, "Failed to open in enable!\n"); - return -1; - } + char path[DIRECTION_MAX]; + int fd; - write(fd, s_enable_str, strlen(s_enable_str)); - close(fd); + // TODO: Enter the enable path. + snprintf(path, DIRECTION_MAX, "/sys/class/pwm/pwmchip0/pwm0/enable"); + fd = open(path, O_WRONLY); + if (-1 == fd) + { + fprintf(stderr, "Failed to open in enable!\n"); + return -1; + } - return (0); -} -static int PWMWritePeriod(int pwmnum, int value) { - char s_value_str[VALUE_MAX]; - char path[VALUE_MAX]; - int fd, byte; - - // TODO: Enter the period path. - snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm0/period"); - fd = open(path, O_WRONLY); - if (-1 == fd) { - fprintf(stderr, "Failed to open in period!\n"); - return (-1); - } - byte = snprintf(s_value_str, VALUE_MAX, "%d", value); - - if (-1 == write(fd, s_value_str, byte)) { - fprintf(stderr, "Failed to write value in period!\n"); + write(fd, s_enable_str, strlen(s_enable_str)); close(fd); - return -1; - } - close(fd); - return (0); + return (0); } +static int PWMWritePeriod(int pwmnum, int value) +{ + char s_value_str[VALUE_MAX]; + char path[VALUE_MAX]; + int fd, byte; + + // TODO: Enter the period path. + snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm0/period"); + fd = open(path, O_WRONLY); + if (-1 == fd) + { + fprintf(stderr, "Failed to open in period!\n"); + return (-1); + } + byte = snprintf(s_value_str, VALUE_MAX, "%d", value); -static int PWMWriteDutyCycle(int pwmnum, int value) { - char s_value_str[VALUE_MAX]; - char path[VALUE_MAX]; - int fd, byte; - - // TODO: Enter the duty_cycle path. - snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm0/duty_cycle"); - fd = open(path, O_WRONLY); - if (-1 == fd) { - fprintf(stderr, "Failed to open in duty cycle!\n"); - return (-1); - } - byte = snprintf(s_value_str, VALUE_MAX, "%d", value); - - if (-1 == write(fd, s_value_str, byte)) { - fprintf(stderr, "Failed to write value in duty cycle!\n"); + if (-1 == write(fd, s_value_str, byte)) + { + fprintf(stderr, "Failed to write value in period!\n"); + close(fd); + return -1; + } close(fd); - return -1; - } - close(fd); - return (0); + return (0); } -// 클라이언트 수신 스레드 함수 -void *ClientToServer(void *idx) { - int i = *((int*) idx); - char buffer[BUFFER_SIZE]; - char ip[INET_ADDRSTRLEN]; - int len; - - while ((len = recv(clients[i].socket, buffer, BUFFER_SIZE, 0)) > 0) { - buffer[len] = '\0'; - inet_ntop(AF_INET, &clients[i].address.sin_addr, ip, INET_ADDRSTRLEN); - printf("Received from client %s: %s", ip, buffer); - if (send(pySocket, buffer, strlen(buffer), 0) < 0) { - perror("Send message to server error"); - } +static int PWMWriteDutyCycle(int pwmnum, int value) +{ + char s_value_str[VALUE_MAX]; + char path[VALUE_MAX]; + int fd, byte; + + // TODO: Enter the duty_cycle path. + snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm0/duty_cycle"); + fd = open(path, O_WRONLY); + if (-1 == fd) + { + fprintf(stderr, "Failed to open in duty cycle!\n"); + return (-1); } + byte = snprintf(s_value_str, VALUE_MAX, "%d", value); - if (len == 0) { - printf("Client disconnected: %d\n", clients[i].socket); - } else if (len == -1) { - perror("recv error"); + if (-1 == write(fd, s_value_str, byte)) + { + fprintf(stderr, "Failed to write value in duty cycle!\n"); + close(fd); + return -1; } - clientCnt--; - close(clients[i].socket); -} - -// 서버에서 메시지 수신하는 스레드 -void *ServerToClient() { - char buffer[BUFFER_SIZE]; - int len; - while (1) { - if (len = recv(pySocket, buffer, BUFFER_SIZE - 1, 0) <= 0) { - printf("Server disconnected\n"); - close(pySocket); - exit(0); - } - buffer[len] = '\0'; - printf("Received from server: %s\n", buffer); - - if (buffer[2] == 'Y') { - // 차단기 개방 - printf("차단기 개방\n"); - if (PWMExport(PWM)) printf("export error\n"); - if (PWMWritePeriod(PWM, 20000000)) printf("period error\n"); - if (PWMWriteDutyCycle(PWM, 0)) printf("duty error\n"); - if (PWMEnable(PWM)) printf("enable error\n"); - if (PWMWriteDutyCycle(PWM, 2000000)) printf("duty error2\n"); - usleep(100000); - if (PWMUnexport(PWM)) printf("unexport error\n"); - } - - else if (buffer[2] == 'P') { - // 충전기 노드에 주차 사실 알림 - if (send(clients[0].socket, buffer, strlen(buffer), 0) < 0) { - perror("Send message error"); - } - - if (send(clients[1].socket, buffer, strlen(buffer), 0) < 0) { - perror("Send message error"); - } - } + close(fd); - else if (buffer[2] == 'E') { - if (send(clients[0].socket, buffer, strlen(buffer), 0) < 0) { - perror("Send message error"); - } - if (send(clients[1].socket, buffer, strlen(buffer), 0) < 0) { - perror("Send message error"); - } - if (PWMExport(PWM)) printf("export error\n"); - if (PWMWritePeriod(PWM, 20000000)) printf("period error\n"); - if (PWMWriteDutyCycle(PWM, 0)) printf("duty error\n"); - if (PWMEnable(PWM)) printf("enable error\n"); - if (PWMWriteDutyCycle(PWM, 950000)) printf("duty error2\n"); - usleep(100000); - if (PWMUnexport(PWM)) printf("unexport error\n"); - } + return (0); +} - else if (buffer[2] == 'F') { - // 충전기 노드에 화재 사실 알림 - // 화재 노드에 화재 사실 알림 - if (send(clients[0].socket, buffer, strlen(buffer), 0) < 0) { - perror("Send message error"); - } +int main() +{ + socklen_t clientAddrLen = sizeof(clientAddr); - if (send(clients[2].socket, buffer, strlen(buffer), 0) < 0) { - perror("Send message error"); - } - } + // 강제 종료시 리소스 반환 + signal(SIGINT, handleForce); + signal(SIGTERM, handleForce); + signal(SIGSEGV, handleForce); + signal(SIGKILL, handleForce); - else if (buffer[0] == 'C') { - for (int x = 0; x < 3; x++) { - if (send(clients[x].socket, buffer, strlen(buffer), 0) < 0) { - perror("Send message error"); - } - } - } + // clients 배열 초기화 + for (int i = 0; i < MAX_CLIENTS; i++) + { + memset(clients, 0, sizeof(clients)); } -} -int main() { - struct sockaddr_in pyAddr, cAddr, clientAddr; - pthread_attr_t attr, attr2, at[3]; - struct sched_param param, param2; - socklen_t clientAddrLen = sizeof(clientAddr); - param.sched_priority=sched_get_priority_max(SCHED_RR); - param2.sched_priority=sched_get_priority_max(SCHED_RR) - 1; + // 스케쥴링 우선순위 설정 + param.sched_priority = sched_get_priority_max(SCHED_RR); + param2.sched_priority = sched_get_priority_max(SCHED_RR) - 1; + // 스레드 속성 부여 pthread_attr_init(&at[2]); pthread_attr_setschedpolicy(&at[2], SCHED_RR); pthread_attr_setinheritsched(&at[2], PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedparam(&at[2], ¶m); pthread_attr_setstacksize(&at[2], PTHREAD_STACK_MIN); - for (int i = 0; i < 2; i++) { - pthread_attr_init(&at[i]); - pthread_attr_setschedpolicy(&at[i], SCHED_RR); - pthread_attr_setinheritsched(&at[i], PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedparam(&at[i], ¶m2); - pthread_attr_setstacksize(&at[i], PTHREAD_STACK_MIN); -} + for (int i = 0; i < 2; i++) + { + pthread_attr_init(&at[i]); + pthread_attr_setschedpolicy(&at[i], SCHED_RR); + pthread_attr_setinheritsched(&at[i], PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&at[i], ¶m2); + pthread_attr_setstacksize(&at[i], PTHREAD_STACK_MIN); + } // 서버로 연결할 클라이언트 소켓 생성 - if ((pySocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("Socket creation error"); + if ((pySocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + fprintf(stderr, "Socket creation error\n"); return -1; } // 서버로 메시지 전송할 소켓 설정 pyAddr.sin_family = AF_INET; pyAddr.sin_port = htons(49152); - if (inet_pton(AF_INET, "127.0.0.1", &pyAddr.sin_addr) <= 0) { - perror("Address error"); + if (inet_pton(AF_INET, "127.0.0.1", &pyAddr.sin_addr) <= 0) + { + fprintf(stderr, "Address error\n"); + close(pySocket); return -1; } - if (connect(pySocket, (struct sockaddr *)&pyAddr, sizeof(pyAddr)) < 0) { - perror("Connection error"); + + // 서버 연결 + if (connect(pySocket, (struct sockaddr *)&pyAddr, sizeof(pyAddr)) < 0) + { + fprintf(stderr, "Connection error\n"); + close(pySocket); return -1; } printf("Connected to server\n"); + isAlive = 1; + + // 서버 통신 스레드 생성 + pthread_create(&pyThread, &at[2], ServerToClient, NULL); + if (pthread_detach(pyThread) < 0) + { + fprintf(stderr, "Detach thread error\n"); + close(pySocket); + return -1; + } // 클라이언트를 받을 서버 소켓 설정 - if ((cSocket = socket(AF_INET, SOCK_STREAM, 0)) == 0) { - perror("Socket error"); + if ((cSocket = socket(AF_INET, SOCK_STREAM, 0)) == 0) + { + fprintf(stderr, "Socket error\n"); + close(pySocket); + close(cSocket); return -1; } cAddr.sin_family = AF_INET; cAddr.sin_addr.s_addr = INADDR_ANY; cAddr.sin_port = htons(PORT); - if (bind(cSocket, (struct sockaddr *)&cAddr, sizeof(cAddr)) < 0) { - perror("Bind error"); + if (bind(cSocket, (struct sockaddr *)&cAddr, sizeof(cAddr)) < 0) + { + fprintf(stderr, "Bind error\n"); close(cSocket); + close(pySocket); return -1; } - if (listen(cSocket, 3) < 0) { - perror("Listen error"); + if (listen(cSocket, 3) < 0) + { + fprintf(stderr, "Listen error\n"); close(cSocket); + close(pySocket); return -1; } - // 서버 수신용 스레드 시작 - pthread_create(&pyThread, NULL, ServerToClient, NULL); - - while (clientCnt < MAX_CLIENTS) { + // 클라이언트 처리 로직 + while (clientCnt < MAX_CLIENTS) + { int x; char ip[INET_ADDRSTRLEN]; - if ((x = accept(cSocket, (struct sockaddr *)&clientAddr, &clientAddrLen)) < 0) { - perror("Accept error"); + if ((x = accept(cSocket, (struct sockaddr *)&clientAddr, &clientAddrLen)) < 0) + { + fprintf(stderr, "Accept error\n"); continue; } + int *idx = (int *)malloc(sizeof(int *)); + // *idx = ip[11] - '7'; + // if (ip[11] - '7' > 2 || ip[11] - '7' < 0) *idx = 0; + *idx = clientCnt; + ClientData *tmp = (ClientData *)malloc(sizeof(ClientData)); tmp->socket = x; tmp->address = clientAddr; - clients[clientCnt] = *tmp; + clients[*idx] = *tmp; + clients[*idx].used = 1; inet_ntop(AF_INET, &tmp->address.sin_addr, ip, INET_ADDRSTRLEN); - //int *idx = (int *)malloc(sizeof(int *)); - int *idx = ip[11] - '7'; - if (ip[11] - '7' > 2 || ip[11] - '7' < 0) *idx = 0; - - *idx = clientCnt; - if (pthread_create(&clientThreads[*idx], &at[*idx], ClientToServer, (void *)idx) < 0) { - perror("Create thread error"); + if (pthread_create(&clientThreads[*idx], &at[*idx], ClientToServer, (void *)idx) < 0) + { + fprintf(stderr, "Create thread error\n"); close(x); free(tmp); } - if (pthread_detach(clientThreads[*idx]) < 0) { - perror("Detach thread error"); + if (pthread_detach(clientThreads[*idx]) < 0) + { + fprintf(stderr, "Detach thread error\n"); close(x); free(tmp); } - + clientCnt++; } close(pySocket); close(cSocket); return 0; } + +void *ClientToServer(void *idx) +{ + int i = *((int *)idx); + char buffer[BUFFER_SIZE]; + char ip[INET_ADDRSTRLEN]; + int len; + + while ((len = recv(clients[i].socket, buffer, BUFFER_SIZE, 0)) > 0) + { + buffer[len] = '\0'; + inet_ntop(AF_INET, &clients[i].address.sin_addr, ip, INET_ADDRSTRLEN); + printf("Received from client %s: %s", ip, buffer); + if (isAlive && send(pySocket, buffer, strlen(buffer), 0) < 0) + { + fprintf(stderr, "Send message to server error\n"); + } + } + + if (len == 0) + { + printf("Client disconnected: %d\n", clients[i].socket); + } + else if (len == -1) + { + fprintf(stderr, "recv error\n"); + } + clientCnt--; + close(clients[i].socket); +} + +void *ServerToClient() +{ + char buffer[BUFFER_SIZE]; + int len; + while (1) + { + if ((len = recv(pySocket, buffer, BUFFER_SIZE - 1, 0)) <= 0) + { + printf("Server disconnected\n"); + isAlive = 0; + close(pySocket); + usleep(2500000); + if ((pySocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + fprintf(stderr, "Socket creation error\n"); + continue; + } + + // 서버로 메시지 전송할 소켓 설정 + pyAddr.sin_family = AF_INET; + pyAddr.sin_port = htons(49152); + if (inet_pton(AF_INET, "127.0.0.1", &pyAddr.sin_addr) <= 0) + { + fprintf(stderr, "Address error\n"); + close(pySocket); + continue; + } + if (connect(pySocket, (struct sockaddr *)&pyAddr, sizeof(pyAddr)) < 0) + { + fprintf(stderr, "Connection error\n"); + close(pySocket); + continue; + } + isAlive = 1; + printf("Connected to server\n"); + + memset(buffer, 0, sizeof(buffer)); + } + buffer[len] = '\0'; + printf("Received from server: %s\n", buffer); + + if (buffer[2] == 'Y') + { + // 차단기 개방 + printf("차단기 개방\n"); + if (PWMExport(PWM)) + fprintf(stderr, "export error\n"); + if (PWMWritePeriod(PWM, 20000000)) + fprintf(stderr, "period error\n"); + if (PWMWriteDutyCycle(PWM, 0)) + fprintf(stderr, "duty error\n"); + if (PWMEnable(PWM)) + fprintf(stderr, "enable error\n"); + if (PWMWriteDutyCycle(PWM, 2000000)) + fprintf(stderr, "duty error2\n"); + usleep(100000); + if (PWMUnexport(PWM)) + fprintf(stderr, "unexport error\n"); + } + + else if (buffer[2] == 'P') + { + // 충전기 노드에 주차 사실 알림 + if (clients[0].used != 0 && send(clients[0].socket, buffer, strlen(buffer), 0) < 0) + { + fprintf(stderr, "Send message error\n"); + } + + if (clients[1].used != 0 && send(clients[1].socket, buffer, strlen(buffer), 0) < 0) + { + fprintf(stderr, "Send message error\n"); + } + } + + else if (buffer[2] == 'E') + { + if (clients[0].used != 0 && send(clients[0].socket, buffer, strlen(buffer), 0) < 0) + { + fprintf(stderr, "Send message error\n"); + } + if (clients[1].used != 0 && send(clients[1].socket, buffer, strlen(buffer), 0) < 0) + { + fprintf(stderr, "Send message error\n"); + } + if (PWMExport(PWM)) + fprintf(stderr, "export error\n"); + if (PWMWritePeriod(PWM, 20000000)) + fprintf(stderr, "period error\n"); + if (PWMWriteDutyCycle(PWM, 0)) + fprintf(stderr, "duty error\n"); + if (PWMEnable(PWM)) + fprintf(stderr, "enable error\n"); + if (PWMWriteDutyCycle(PWM, 950000)) + fprintf(stderr, "duty error2\n"); + usleep(100000); + if (PWMUnexport(PWM)) + fprintf(stderr, "unexport error\n"); + } + + else if (buffer[2] == 'F') + { + // 충전기 노드에 화재 사실 알림 + // 화재 노드에 화재 사실 알림 + if (clients[0].used != 0 && send(clients[0].socket, buffer, strlen(buffer), 0) < 0) + { + fprintf(stderr, "Send message error\n"); + } + + if (clients[2].used != 0 && send(clients[2].socket, buffer, strlen(buffer), 0) < 0) + { + fprintf(stderr, "Send message error\n"); + } + } + + else if (buffer[0] == 'C') + { + for (int x = 0; x < 3; x++) + { + if (clients[x].used != 0 && send(clients[x].socket, buffer, strlen(buffer), 0) < 0) + { + fprintf(stderr, "Send message error\n"); + } + } + } + } +} + +void handleForce(int signal) +{ + shutdown(pySocket, SHUT_RDWR); + close(pySocket); + close(cSocket); + + pthread_cancel(pyThread); + printf("%d stop\n", signal); + exit(0); +} diff --git a/server-node-spring/src/main/java/org/example/thiefsil/dto/FireDTO.java b/server-node-spring/src/main/java/org/example/thiefsil/dto/FireDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..c816e0e8ac9941374a96ed9feef4bb01b97b5b72 --- /dev/null +++ b/server-node-spring/src/main/java/org/example/thiefsil/dto/FireDTO.java @@ -0,0 +1,4 @@ +package org.example.thiefsil.dto; + +public class FireDTO { +}