From cefd8e8c1f8610f42fa97477f56660266d8617da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Fri, 29 Nov 2024 16:43:37 +0900 Subject: [PATCH] =?UTF-8?q?feat(c):=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=20?= =?UTF-8?q?=EB=B0=8F=20C=20=EC=84=9C=EB=B2=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server-node-control/control.c | 309 ++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 server-node-control/control.c diff --git a/server-node-control/control.c b/server-node-control/control.c new file mode 100644 index 0000000..9691937 --- /dev/null +++ b/server-node-control/control.c @@ -0,0 +1,309 @@ +#include <stdio.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <arpa/inet.h> +#include <pthread.h> + +#define BUFFER_SIZE 1024 +#define PORT 12345 +#define MAX_CLIENTS 5 + +#define PWM 0 +#define VALUE_MAX 256 +#define DIRECTION_MAX 256 + +typedef struct { + int socket; + struct sockaddr_in address; +} ClientData; + +int pySocket, cSocket, clientCnt = 0; +pthread_t pyThread, clientThreads[MAX_CLIENTS]; +ClientData clients[MAX_CLIENTS]; + +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); + + sleep(1); + + return (0); +} + +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); + } + + byte = snprintf(buffer, BUFFER_MAX, "%d", pwmnum); + write(fd, buffer, byte); + close(fd); + + sleep(1); + + return (0); +} + +static int PWMEnable(int pwmnum) { + static const char s_enable_str[] = "1"; + + char path[DIRECTION_MAX]; + int fd; + + // TODO: Enter the enable path. + snprintf(path, DIRECTION_MAX, "/sys/class/pwm/pwmchip0/pwm0/enable", pwmnum); + fd = open(path, O_WRONLY); + if (-1 == fd) { + fprintf(stderr, "Failed to open in enable!\n"); + return -1; + } + + write(fd, s_enable_str, strlen(s_enable_str)); + close(fd); + + 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", pwmnum); + 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"); + close(fd); + return -1; + } + close(fd); + + return (0); +} + +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", pwmnum); + 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"); + close(fd); + return -1; + } + close(fd); + + 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'; + printf("Received from client %d: %s", &clients[i].address.sin_addr, buffer); + inet_ntop(AF_INET, &clients[i].address.sin_addr, ip, INET_ADDRSTRLEN); + if (send(pySocket, buffer, strlen(buffer), 0) < 0) { + perror("Error sending message to server"); + } + } + + if (len == 0) { + printf("Client disconnected: %d\n", clients[i].socket); + } else if (len == -1) { + perror("recv failed"); + } + clientCnt--; + close(clients[i].socket); +} + +// 서버에서 메시지 수신하는 스레드 +void *ServerToClient() { + char buffer[BUFFER_SIZE]; + int len; + while (1) { + len = read(pySocket, buffer, BUFFER_SIZE - 1); + if (len <= 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("Error forwarding message to client"); + } + } + + else if (buffer[2] == 'E') { + // 충전기 노드에 주차 사실 알림 + if (send(clients[0].socket, buffer, strlen(buffer), 0) < 0) { + perror("Error forwarding message to client"); + } + 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("Error forwarding message to client"); + } + + if (send(clients[3].socket, buffer, strlen(buffer), 0) < 0) { + perror("Error forwarding message to client"); + } + } + } +} + +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=3; + param2.sched_priority=2; + + pthread_attr_init(&attr); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&attr, ¶m); + + pthread_attr_init(&attr2); + pthread_attr_setschedpolicy(&attr2, SCHED_RR); + pthread_attr_setinheritsched(&attr2, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedparam(&attr2, ¶m2); + at[0] = at[1] = attr2; + at[2] = attr; + + // 서버로 연결할 클라이언트 소켓 생성 + if ((pySocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("Socket creation error"); + 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("Invalid address / Address not supported"); + return -1; + } + if (connect(pySocket, (struct sockaddr *)&pyAddr, sizeof(pyAddr)) < 0) { + perror("Connection failed"); + return -1; + } + printf("서버에 연결되었습니다.\n"); + + // 클라이언트를 받을 서버 소켓 설정 + if ((cSocket = socket(AF_INET, SOCK_STREAM, 0)) == 0) { + perror("Socket failed"); + 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 failed"); + close(cSocket); + return -1; + } + + if (listen(cSocket, 3) < 0) { + perror("Listen failed"); + close(cSocket); + return -1; + } + + // 서버 수신용 스레드 시작 + pthread_create(&pyThread, NULL, ServerToClient, NULL); + + while (clientCnt < MAX_CLIENTS) { + int x; + char ip[INET_ADDRSTRLEN]; + if ((x = accept(cSocket, (struct sockaddr *)&clientAddr, &clientAddrLen)) < 0) { + perror("Accept failed"); + continue; + } + + ClientData *tmp = (ClientData *)malloc(sizeof(ClientData)); + tmp->socket = x; + tmp->address = clientAddr; + clients[clientCnt] = *tmp; + inet_ntop(AF_INET, &tmp->address.sin_addr, ip, INET_ADDRSTRLEN); + int idx = ip[11] - '7'; + + if (pthread_create(&clientThreads[idx], &at[idx], ClientToServer, (void *)&idx) < 0) { + perror("Failed to create thread"); + close(x); + } + + } + + close(pySocket); + close(cSocket); + return 0; +} -- GitLab