From f96e01483e9341ef7e10d93a3aa9dac10fd9f1be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B5=9C=EB=AF=BC=EC=84=9C?= <chlalstj1@ajou.ac.kr>
Date: Sat, 7 Dec 2024 15:50:56 +0000
Subject: [PATCH] =?UTF-8?q?feat:=20=EB=B0=B0=ED=84=B0=EB=A6=AC=20=EB=9E=9C?=
 =?UTF-8?q?=EB=8D=A4=EA=B0=92=EC=9C=BC=EB=A1=9C=20=EC=8B=9C=EC=9E=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 charger.cpp | 423 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 250 insertions(+), 173 deletions(-)

diff --git a/charger.cpp b/charger.cpp
index 1bf8858..35fc97c 100644
--- a/charger.cpp
+++ b/charger.cpp
@@ -1,253 +1,330 @@
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <linux/i2c-dev.h>
-#include <arpa/inet.h>
-#include <sys/ioctl.h>
-#include "MFRC522.h"
-
-#define I2C_ADDR 0x23
-#define LCD_CHR 1
-#define LCD_CMD 0
-#define LINE1 0x80
-#define LINE2 0xC0
-#define LCD_BACKLIGHT 0x08
-#define ENABLE 0b00000100
-#define BUFFER_SIZE 1024
-
-#define SERVER_IP "127.0.0.1"
-#define SERVER_PORT 12345
-
-int lcd_fd;
-int client_socket;
-int battery_percentage = 50;
-int charging = 0;
-int fire_detected = 0;
-int car_parked = 0;
-
-void lcd_init(int fd);
-void lcd_byte(int fd, int bits, int mode);
-void lcd_toggle_enable(int fd, int bits);
-void lcd_loc(int fd, int line);
-void lcd_clear(int fd);
-void typeln(int fd, const char *s);
-void *listen_to_server(void *arg);
-void *update_battery_status(void *arg);
-void *rfid_tag_listener(void *arg);
+#include <stdio.h> // 표준 입출력 라이브러리
+#include <string.h> // 문자열 처리 라이브러리
+#include <fcntl.h> // 파일 제어 관련 라이브러리
+#include <unistd.h> // 유닉스 표준 시스템 호출 관련 라이브러리
+#include <pthread.h> // POSIX 스레드 관련 라이브러리
+#include <stdlib.h> // 일반 유틸리티 함수 라이브러리
+#include <stdint.h> // 정수 타입 정의 라이브러리
+#include <linux/i2c-dev.h> // I2C 장치 드라이버 관련 헤더
+#include <arpa/inet.h> // 인터넷 주소 변환 함수 관련 헤더
+#include <sys/ioctl.h> // I/O 제어 함수 관련 헤더
+#include "MFRC522.h" // RFID 모듈 관련 헤더 파일 (사용자 정의)
+
+#define I2C_ADDR 0x23 // I2C LCD 디바이스 주소
+#define LCD_CHR 1 // LCD 데이터 모드
+#define LCD_CMD 0 // LCD 명령 모드
+#define LINE1 0x80 // LCD 첫 번째 줄
+#define LINE2 0xC0 // LCD 두 번째 줄
+#define LCD_BACKLIGHT 0x08 // LCD 백라이트 ON
+#define ENABLE 0b00000100 // LCD enable 비트 설정
+#define BUFFER_SIZE 1024 // 서버로부터 수신할 데이터의 버퍼 크기
+
+#define SERVER_IP "127.0.0.1" // 서버 IP 주소 (localhost)
+#define SERVER_PORT 12345 // 서버 포트 번호
+
+// 전역 변수 선언
+int lcd_fd; // LCD I2C 파일 디스크립터
+int client_socket; // 클라이언트 소켓
+int battery_percentage; // 배터리 충전 상태 (0 ~ 99까지 랜덤한 값으로 가정)
+int charging = 0; // 충전 여부 (0: 충전 중 아님, 1: 충전 중)
+int fire_detected = 0; // 화재 감지 여부 (0: 감지 안 됨, 1: 감지됨)
+int car_parked = 0; // 차량 주차 여부 (0: 미주차, 1: 주차)
+
+// 함수 프로토타입 선언
+void lcd_init(int fd); // LCD 초기화 함수
+void lcd_byte(int fd, int bits, int mode); // LCD 데이터 전송 함수
+void lcd_toggle_enable(int fd, int bits); // LCD enable 토글 함수
+void lcd_loc(int fd, int line); // LCD 줄 선택 함수
+void lcd_clear(int fd); // LCD 화면 초기화 함수
+void typeln(int fd, const char *s); // LCD 문자열 출력 함수
+void *listen_to_server(void *arg); // 서버 메시지 수신 스레드 함수
+void *update_battery_status(void *arg); // 배터리 상태 업데이트 스레드 함수
+void *rfid_tag_listener(void *arg); // RFID 태그 감지 스레드 함수
+
+// 서버 연결을 초기화하는 함수
+int connect_to_server() {
+    if (client_socket > 0) { // 이미 소켓이 열려 있다면 닫기
+        close(client_socket);
+    }
 
-int main() {
-    pthread_t server_thread, battery_thread, rfid_thread;
+    client_socket = socket(AF_INET, SOCK_STREAM, 0); // 새 소켓 생성
+    if (client_socket < 0) {
+        perror("Socket creation failed"); // 소켓 생성 실패 처리
+        return -1;
+    }
+
+    struct sockaddr_in server_address;
+    server_address.sin_family = AF_INET; // IPv4 설정
+    server_address.sin_port = htons(SERVER_PORT); // 포트 설정
+    inet_pton(AF_INET, SERVER_IP, &server_address.sin_addr); // IP 주소 변환
+
+    if (connect(client_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) { // 서버 연결 시도
+        perror("Connection to server failed");
+        return -1;
+    }
+
+    printf("Connected to the server successfully.\n");
+    return 0;
+}
 
-    // Initialize LCD
-    const char *i2c_device = "/dev/i2c-1";
-    lcd_fd = open(i2c_device, O_RDWR);
+// LCD 초기화를 수행하는 함수
+void lcd_reset() {
+    const char *i2c_device = "/dev/i2c-1"; // I2C 장치 파일 경로
+    lcd_fd = open(i2c_device, O_RDWR); // I2C 장치 열기
     if (lcd_fd < 0) {
-        perror("Failed to open I2C device");
-        return 1;
+        perror("Failed to open I2C device"); // 실패 시 오류 출력
+        return;
     }
 
-    if (ioctl(lcd_fd, I2C_SLAVE, I2C_ADDR) < 0) {
+    if (ioctl(lcd_fd, I2C_SLAVE, I2C_ADDR) < 0) { // 슬레이브 장치 설정
         perror("Failed to acquire bus access or talk to slave");
         close(lcd_fd);
-        return 1;
+        return;
     }
 
-    lcd_init(lcd_fd);
+    lcd_init(lcd_fd); // LCD 초기화
+}
 
-    client_socket = socket(AF_INET, SOCK_STREAM, 0);
-    if (client_socket < 0) {
-        perror("Socket creation failed");
-        return 1;
-    }
+int main() {
+    pthread_t server_thread, battery_thread, rfid_thread; // 스레드 식별자
+    srand(time(NULL)); // 랜덤 시드 설정
+    battery_percentage = rand() % 100; // 배터리 초기값 설정
 
-    struct sockaddr_in server_address;
-    server_address.sin_family = AF_INET;
-    server_address.sin_port = htons(SERVER_PORT);
-    inet_pton(AF_INET, SERVER_IP, &server_address.sin_addr);
+    lcd_reset(); // LCD 초기화
 
-    if (connect(client_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
-        perror("Connection to server failed");
-        return 1;
-    }
+    while (1) {
+        if (connect_to_server() == 0) { // 서버 연결 성공 시
+            printf("Connected to server. Starting threads...\n");
 
-    // Create threads
-    pthread_create(&server_thread, NULL, listen_to_server, NULL);
-    pthread_create(&battery_thread, NULL, update_battery_status, NULL);
-    pthread_create(&rfid_thread, NULL, rfid_tag_listener, NULL);
+            pthread_create(&server_thread, NULL, listen_to_server, NULL); // 서버 수신 스레드 생성
+            pthread_create(&battery_thread, NULL, update_battery_status, NULL); // 배터리 업데이트 스레드 생성
+            pthread_create(&rfid_thread, NULL, rfid_tag_listener, NULL); // RFID 감지 스레드 생성
 
-    pthread_join(server_thread, NULL);
-    pthread_join(battery_thread, NULL);
-    pthread_join(rfid_thread, NULL);
+            pthread_join(server_thread, NULL); // 서버 스레드 종료 대기
+
+            pthread_cancel(battery_thread); // 배터리 스레드 종료
+            pthread_cancel(rfid_thread); // RFID 스레드 종료
+            pthread_join(battery_thread, NULL); // 배터리 스레드 자원 해제
+            pthread_join(rfid_thread, NULL); // RFID 스레드 자원 해제
+        } else {
+            sleep(5); // 재연결 대기
+        }
+    }
 
-    close(client_socket);
-    close(lcd_fd);
+    close(client_socket); // 클라이언트 소켓 닫기
+    close(lcd_fd); // LCD 파일 디스크립터 닫기
 
     return 0;
 }
 
+// LCD 초기화 함수
 void lcd_init(int fd) {
-    lcd_byte(fd, 0x33, LCD_CMD);
-    lcd_byte(fd, 0x32, LCD_CMD);
-    lcd_byte(fd, 0x06, LCD_CMD);
-    lcd_byte(fd, 0x0C, LCD_CMD);
-    lcd_byte(fd, 0x28, LCD_CMD);
-    lcd_byte(fd, 0x01, LCD_CMD);
-    usleep(5000);
+    lcd_byte(fd, 0x33, LCD_CMD); // 초기화 명령 1
+    lcd_byte(fd, 0x32, LCD_CMD); // 초기화 명령 2
+    lcd_byte(fd, 0x06, LCD_CMD); // 화면 이동 설정
+    lcd_byte(fd, 0x0C, LCD_CMD); // 디스플레이 켜기
+    lcd_byte(fd, 0x28, LCD_CMD); // 2라인 모드 설정
+    lcd_byte(fd, 0x01, LCD_CMD); // 화면 지우기
+    usleep(5000); // 초기화 대기
 }
 
+// LCD 데이터 전송 함수
 void lcd_byte(int fd, int bits, int mode) {
-    int bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT;
-    int bits_low = mode | ((bits << 4) & 0xF0) | LCD_BACKLIGHT;
+    int bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT; // 상위 4비트 설정
+    int bits_low = mode | ((bits << 4) & 0xF0) | LCD_BACKLIGHT; // 하위 4비트 설정
 
-    write(fd, &bits_high, 1);
-    lcd_toggle_enable(fd, bits_high);
+    write(fd, &bits_high, 1); // 상위 4비트 전송
+    lcd_toggle_enable(fd, bits_high); // Enable 신호 토글
 
-    write(fd, &bits_low, 1);
-    lcd_toggle_enable(fd, bits_low);
+    write(fd, &bits_low, 1); // 하위 4비트 전송
+    lcd_toggle_enable(fd, bits_low); // Enable 신호 토글
 }
 
+// LCD Enable 토글 함수
 void lcd_toggle_enable(int fd, int bits) {
-    usleep(500);
-    int bits_enable = bits | ENABLE;
-    int bits_disable = bits & ~ENABLE;
+    usleep(500); // 대기
+    int bits_enable = bits | ENABLE; // Enable 설정
+    int bits_disable = bits & ~ENABLE; // Enable 해제
 
-    write(fd, &bits_enable, 1);
-    write(fd, &bits_disable, 1);
-    usleep(500);
+    write(fd, &bits_enable, 1); // Enable 활성화
+    write(fd, &bits_disable, 1); // Enable 비활성화
+    usleep(500); // 대기
 }
 
+// LCD 특정 줄로 커서 이동
 void lcd_loc(int fd, int line) {
-    lcd_byte(fd, line, LCD_CMD);
+    lcd_byte(fd, line, LCD_CMD); // 줄 위치 설정
 }
 
+// LCD 화면 초기화
 void lcd_clear(int fd) {
-    lcd_byte(fd, 0x01, LCD_CMD);
-    lcd_byte(fd, 0x02, LCD_CMD);
+    lcd_byte(fd, 0x01, LCD_CMD); // 화면 지우기 명령
+    usleep(5000); // 대기
+    lcd_byte(fd, 0x02, LCD_CMD); // 커서 초기화
+    usleep(5000); // 대기
 }
 
+// LCD 문자열 출력 함수
 void typeln(int fd, const char *s) {
     while (*s) {
-        lcd_byte(fd, *(s++), LCD_CHR);
+        lcd_byte(fd, *(s++), LCD_CHR); // 문자 출력
     }
 }
 
+// 문자열 양끝 공백 제거 함수
+char *trim(char *str) {
+    char *end;
+    while (isspace((unsigned char)*str)) str++; // 시작 공백 제거
+    if (*str == 0) return str; // 문자열이 비어 있으면 반환
+
+    end = str + strlen(str) - 1; // 끝 공백 제거
+    while (end > str && isspace((unsigned char)*end)) end--;
+
+    *(end + 1) = '\0'; // 문자열 종료 설정
+    return str;
+}
+
+// 서버 메시지 수신 및 처리 스레드
 void *listen_to_server(void *arg) {
     char buffer[BUFFER_SIZE];
 
     while (1) {
-        int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0);
-        if (bytes_received <= 0) {
-            perror("Server connection lost");
-            break;
+        int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0); // 서버로부터 데이터를 수신
+        if (bytes_received <= 0) { // 수신 실패 또는 연결 종료 시
+            perror("Server connection lost. Attempting to reconnect..."); // 오류 메시지 출력
+            lcd_clear(lcd_fd); // LCD 화면 초기화
+            lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 커서 이동
+            typeln(lcd_fd, "Connection lost."); // 연결 끊김 메시지 출력
+            lcd_loc(lcd_fd, LINE2); // 두 번째 줄로 커서 이동
+            typeln(lcd_fd, "Reconnecting..."); // 재연결 시도 메시지 출력
+            break; // 재연결을 위해 루프 종료
         }
 
-        buffer[bytes_received] = '\0';
-        printf("%s\n", buffer);
-
-        fire_detected = strstr(buffer, "-FIRE") != NULL;
-        if (fire_detected) {
-            charging = 0;
-            lcd_clear(lcd_fd);
-            lcd_loc(lcd_fd, LINE1);
-            typeln(lcd_fd, "FIRE ALERT!");
-            lcd_loc(lcd_fd, LINE2);
-            typeln(lcd_fd, "EVACUATE AREA!");
-        } else if (strcmp(buffer, "0-PARK") == 0) {
-            car_parked = 1;
-        } else if (strcmp(buffer, "0-EXIT") == 0) {
-            car_parked = 1;
-            car_parked = 0;
-            battery_percentage = 50;
-            charging = 0;
-            lcd_clear(lcd_fd);
-        } else if (strcmp(buffer, "CLEAR") == 0) {
-            car_parked = 1;
-            fire_detected = 0;
-            lcd_clear(lcd_fd);
+        buffer[bytes_received] = '\0'; // 수신 데이터 끝에 null 문자 추가
+        printf("Received message: %s\n", buffer); // 수신된 메시지 출력
+
+        if (fire_detected) { // 화재 감지 상태에서
+            if (strcmp(trim(buffer), "CLEAR") == 0) { // CLEAR 메시지 확인
+                lcd_reset(); // LCD 초기화
+                lcd_clear(lcd_fd); // LCD 화면 지우기
+                lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 이동
+                typeln(lcd_fd, "Fire cleared!"); // 화재 해제 메시지 출력
+                lcd_loc(lcd_fd, LINE2); // 두 번째 줄로 이동
+                typeln(lcd_fd, "All systems OK"); // 시스템 정상 메시지 출력
+                sleep(5); // 5초 대기
+                fire_detected = 0; // 화재 경고 해제
+                car_parked = 0; // 차량 주차 상태 초기화
+            } else {
+                printf("Fire alarm still active. Ignored message: %s\n", buffer); // 무시된 메시지 출력
+                continue; // 루프 계속 진행
+            }
+        } else if (strstr(buffer, "-FIRE") != NULL) { // 화재 경고 메시지 수신 시
+            printf("FIRE ALERT RECEIVED\n"); // 경고 로그 출력
+            fire_detected = 1; // 화재 상태 활성화
+            charging = 0; // 충전 중지
+            lcd_reset(); // LCD 초기화
+            lcd_clear(lcd_fd); // LCD 화면 지우기
+            lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 이동
+            typeln(lcd_fd, "FIRE ALERT!"); // 화재 경고 메시지 출력
+            lcd_loc(lcd_fd, LINE2); // 두 번째 줄로 이동
+            typeln(lcd_fd, "EVACUATE AREA!"); // 대피 메시지 출력
+        } else if (strcmp(trim(buffer), "0-PARK") == 0) { // 차량 주차 메시지 수신 시
+            printf("CAR PARKED\n"); // 주차 상태 로그 출력
+            car_parked = 1; // 차량 주차 상태 활성화
+        } else if (strcmp(trim(buffer), "0-EXIT") == 0) { // 차량 출차 메시지 수신 시
+            printf("CAR EXITED\n"); // 출차 상태 로그 출력
+            lcd_reset(); // LCD 초기화
+            usleep(5000);
+            lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 이동
+            typeln(lcd_fd, "Car exited."); // 출차 메시지 출력
+            sleep(2); // 2초 대기
+            car_parked = 0; // 차량 주차 상태 초기화
+            battery_percentage = rand() % 100; // 배터리 상태 초기화
+            charging = 0; // 충전 중지
         }
     }
 
-    return NULL;
+    return NULL; // 스레드 종료
 }
 
+// 배터리 상태 업데이트 스레드
 void *update_battery_status(void *arg) {
     while (1) {
-        if (charging && !fire_detected && car_parked) {
-            if (battery_percentage < 100) {
-                battery_percentage++;
-                lcd_clear(lcd_fd);
-                lcd_loc(lcd_fd, LINE1);
+        if (charging && !fire_detected && car_parked) { // 충전 조건 확인
+            if (battery_percentage < 100) { // 배터리 충전 중
+                battery_percentage++; // 배터리 퍼센트 증가
+                lcd_reset(); // LCD 초기화
+                lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 이동
                 char msg[16];
-                snprintf(msg, sizeof(msg), "Charging: %d%%", battery_percentage);
-                typeln(lcd_fd, msg);
+                snprintf(msg, sizeof(msg), "Charging: %d%%", battery_percentage); // 충전 상태 메시지 생성
+                typeln(lcd_fd, msg); // 충전 상태 메시지 출력
 
                 char server_msg[16];
-                snprintf(server_msg, sizeof(server_msg), "0-%d", battery_percentage);
-                send(client_socket, server_msg, strlen(server_msg), 0);
+                snprintf(server_msg, sizeof(server_msg), "0-%d", battery_percentage); // 서버 전송 메시지 생성
+                send(client_socket, server_msg, strlen(server_msg), 0); // 서버로 전송
             } else {
-                lcd_loc(lcd_fd, LINE1);
-                typeln(lcd_fd, "CHARGE COMPLETE");
-                sleep(1);
+                lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 이동
+                typeln(lcd_fd, "CHARGE COMPLETE"); // 충전 완료 메시지 출력
+                sleep(1); // 1초 대기
             }
-            sleep(1);
+            sleep(1); // 다음 업데이트까지 대기
         } else {
-            usleep(500000);
+            usleep(500000); // 충전 조건 미충족 시 대기
         }
     }
 
-    return NULL;
+    return NULL; // 스레드 종료
 }
 
+// RFID 태그 감지 및 처리 스레드
 void *rfid_tag_listener(void *arg) {
-    MFRC522 rfid(RPI_V2_GPIO_P1_24, RPI_V2_GPIO_P1_15);
-    rfid.PCD_Init();
+    MFRC522 rfid(RPI_V2_GPIO_P1_24, RPI_V2_GPIO_P1_15); // RFID 모듈 초기화
+    rfid.PCD_Init(); // RFID 모듈 초기화 호출
 
-    uint8_t card_id[4];
+    uint8_t card_id[4]; // RFID 카드 ID 저장 공간
 
     while (1) {
-        if (!fire_detected) {
-            if (!car_parked) {  // 주차 대기 상황
-                lcd_clear(lcd_fd);
-                lcd_loc(lcd_fd, LINE1);
-                typeln(lcd_fd, "NO CAR PARKED");
-                sleep(2);
-            } else if (charging) {  // 충전중 (충전 중지 감지)
-                if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
-                    memcpy(card_id, rfid.uid.uidByte, 4);
-
-                    charging = 0;
-                    lcd_clear(lcd_fd);
-                    lcd_loc(lcd_fd, LINE1);
-                    typeln(lcd_fd, "Charging Stopped");
-                    sleep(2);
+        if (!fire_detected) { // 화재 상태가 아닐 경우
+            if (!car_parked) { // 차량이 주차되지 않은 경우
+                lcd_reset(); // LCD 초기화
+                lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 이동
+                typeln(lcd_fd, "NO CAR PARKED"); // 주차 필요 메시지 출력
+                sleep(2); // 2초 대기
+            } else if (charging) { // 차량이 충전 중인 경우
+                if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) { // 새 카드 감지 및 읽기 성공
+                    memcpy(card_id, rfid.uid.uidByte, 4); // 카드 ID 복사
+                    charging = 0; // 충전 중지
+                    lcd_reset(); // LCD 초기화
+                    lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 이동
+                    typeln(lcd_fd, "Charging Stopped"); // 충전 중지 메시지 출력
+                    sleep(2); // 2초 대기
                 }
-            } else if (!charging) {  // 충전 대기중 (충전 시작 감지)
-                lcd_clear(lcd_fd);
-                lcd_loc(lcd_fd, LINE1);
-                typeln(lcd_fd, "Scan your card");
-
-                if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
-                    memcpy(card_id, rfid.uid.uidByte, 4);
-
-                    charging = 1;
-                    lcd_clear(lcd_fd);
-                    lcd_loc(lcd_fd, LINE1);
-                    typeln(lcd_fd, "Card Accepted");
+            } else if (!charging) { // 차량이 충전 대기 중인 경우
+                lcd_reset(); // LCD 초기화
+
+                lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 이동
+                typeln(lcd_fd, "Scan your card"); // 카드 스캔 요청 메시지 출력
+                lcd_loc(lcd_fd, LINE2); // 두 번째 줄로 이동
+                typeln(lcd_fd, "for 1 second"); // 카드 스캔 요청 메시지 출력
+                sleep(1); // 1초 대기
+                if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) { // 새 카드 감지 및 읽기 성공
+                    memcpy(card_id, rfid.uid.uidByte, 4); // 카드 ID 복사
+
+                    charging = 1; // 충전 시작
+                    lcd_reset(); // LCD 초기화
+                    lcd_loc(lcd_fd, LINE1); // 첫 번째 줄로 이동
+                    typeln(lcd_fd, "Card Accepted"); // 카드 인식 메시지 출력
 
                     char uid_message[64];
-                    snprintf(uid_message, sizeof(uid_message), "0-d%02X%02X%02X%02X", card_id[0], card_id[1], card_id[2], card_id[3]);
-                    send(client_socket, uid_message, strlen(uid_message), 0);
-                    sleep(2);
+                    snprintf(uid_message, sizeof(uid_message), "0-d%02X%02X%02X%02X", card_id[0], card_id[1], card_id[2], card_id[3]); // 카드 ID 메시지 생성
+                    send(client_socket, uid_message, strlen(uid_message), 0); // 서버로 전송
+                    sleep(2); // 2초 대기
                 }
             }
 
-            usleep(100000);
+            usleep(100000); // 루프 대기 시간
         }
     }
 
-    return NULL;
+    return NULL; // 스레드 종료
 }
-- 
GitLab