Skip to content
Snippets Groups Projects
Commit c708c546 authored by 천 진강's avatar 천 진강
Browse files

feat(c): Robust 환경 구축

parent d3c1f9c9
No related branches found
No related tags found
No related merge requests found
......@@ -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,23 +19,35 @@
#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;
void *ClientToServer(void *idx); // 클라이언트 => 서버 메세지 전달
void *ServerToClient(); // 서버 => 클라이언트 메세지 전달
void handleForce(int signal); // 강제 종료시 리소스 반환
static int PWMExport(int pwmnum) {
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) {
if (-1 == fd)
{
fprintf(stderr, "Failed to open export for export!\n");
return (-1);
}
......@@ -48,14 +61,16 @@ static int PWMExport(int pwmnum) {
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) {
if (-1 == fd)
{
fprintf(stderr, "Failed to open export for unexport!\n");
return (-1);
}
......@@ -69,7 +84,8 @@ static int PWMUnexport(int pwmnum) {
return (0);
}
static int PWMEnable(int pwmnum) {
static int PWMEnable(int pwmnum)
{
static const char s_enable_str[] = "1";
char path[DIRECTION_MAX];
......@@ -78,7 +94,8 @@ static int PWMEnable(int pwmnum) {
// TODO: Enter the enable path.
snprintf(path, DIRECTION_MAX, "/sys/class/pwm/pwmchip0/pwm0/enable");
fd = open(path, O_WRONLY);
if (-1 == fd) {
if (-1 == fd)
{
fprintf(stderr, "Failed to open in enable!\n");
return -1;
}
......@@ -88,7 +105,8 @@ static int PWMEnable(int pwmnum) {
return (0);
}
static int PWMWritePeriod(int pwmnum, int value) {
static int PWMWritePeriod(int pwmnum, int value)
{
char s_value_str[VALUE_MAX];
char path[VALUE_MAX];
int fd, byte;
......@@ -96,13 +114,15 @@ static int PWMWritePeriod(int pwmnum, int value) {
// TODO: Enter the period path.
snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm0/period");
fd = open(path, O_WRONLY);
if (-1 == fd) {
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)) {
if (-1 == write(fd, s_value_str, byte))
{
fprintf(stderr, "Failed to write value in period!\n");
close(fd);
return -1;
......@@ -112,7 +132,8 @@ static int PWMWritePeriod(int pwmnum, int value) {
return (0);
}
static int PWMWriteDutyCycle(int pwmnum, int value) {
static int PWMWriteDutyCycle(int pwmnum, int value)
{
char s_value_str[VALUE_MAX];
char path[VALUE_MAX];
int fd, byte;
......@@ -120,13 +141,15 @@ static int PWMWriteDutyCycle(int pwmnum, int value) {
// 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) {
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)) {
if (-1 == write(fd, s_value_str, byte))
{
fprintf(stderr, "Failed to write value in duty cycle!\n");
close(fd);
return -1;
......@@ -136,120 +159,35 @@ static int PWMWriteDutyCycle(int pwmnum, int value) {
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");
}
}
if (len == 0) {
printf("Client disconnected: %d\n", clients[i].socket);
} else if (len == -1) {
perror("recv error");
}
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");
}
}
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");
}
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;
// 스레드 속성 부여
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], &param);
pthread_attr_setstacksize(&at[2], PTHREAD_STACK_MIN);
for (int i = 0; i < 2; i++) {
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);
......@@ -258,82 +196,277 @@ int main() {
}
// 서버로 연결할 클라이언트 소켓 생성
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);
}
package org.example.thiefsil.dto;
public class FireDTO {
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment