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

feat(c): 컨트롤 및 C 서버

parent 232d5e7a
No related branches found
No related tags found
No related merge requests found
#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, &param);
pthread_attr_init(&attr2);
pthread_attr_setschedpolicy(&attr2, SCHED_RR);
pthread_attr_setinheritsched(&attr2, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedparam(&attr2, &param2);
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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment