/* /opt/atk-dlrv1126-toolchain/usr/bin/arm-linux-gnueabihf-gcc -o testprogram chuankou.c -I/home/atk/curl/libcurl/include -L/home/atk/curl/libcurl/lib -lcurl /opt/atk-dlrv1126-toolchain/usr/bin/arm-linux-gnueabihf-g++ -o testprogram chuankou.cpp -I/home/atk/curl/libcurl/include -L/home/atk/curl/libcurl/lib -lcurl */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SERIAL_PORT "/dev/ttyS0" #define BAUD_RATE B115200 #define pipeName "/tmp/Elevator_pipe" std::string BASE_URL_string; #define URL_FILE "/demo/bin/URL/SerialUploaderURL" #define API_ENDPOINT "/system/redis/test" static bool quit = false; // 函数用于读取文件并将其内容保存在全局字符串变量中 void readFileAndStoreInGlobal(const std::string& filename, std::string& destination) { std::ifstream file(filename); if (file.is_open()) { std::getline(file, destination); // 读取一行并存储在全局字符串中 file.close(); } else { std::cerr << "无法打开文件: " << filename << std::endl; } } size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::vector* response) { size_t totalSize = size * nmemb; unsigned char* data = static_cast(contents); response->insert(response->end(), data, data + totalSize); return totalSize; } void sendToServer(const char* hexData) { char command[1024]; snprintf(command, sizeof(command), "curl -s -X POST -H 'Content-Type: text/plain' -d '%s' http://192.168.0.190:5000/receive_hex -o res.txt", hexData); system(command); } void uploadByteArray(const std::vector& byteArray) { // 初始化CURL对象 CURL* curl = curl_easy_init(); if (!curl) { // 处理初始化失败的情况 return; } // 创建表单数据 struct curl_httppost* form = nullptr; struct curl_httppost* last = nullptr; // 添加字节数组作为表单字段 curl_formadd(&form, &last, CURLFORM_COPYNAME, "name", // 字段名 CURLFORM_PTRCONTENTS, byteArray.data(), // 字节数组的数据指针 CURLFORM_CONTENTSLENGTH, byteArray.size(), // 字节数组的长度 CURLFORM_END); // 设置请求URL curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/upload"); // 设置POST请求和表单数据 curl_easy_setopt(curl, CURLOPT_POST, 1L); curl_easy_setopt(curl, CURLOPT_HTTPPOST, form); // 执行请求 CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { // 处理请求执行失败的情况 fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } // 清理资源 curl_easy_cleanup(curl); curl_formfree(form); } void curlToServer(const char* hexData, std::vector& response) { CURL *curl; CURLcode res; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); if(curl) { char postData[512];//建立缓冲区 sprintf(postData, "%s", hexData); //把hexData写入缓冲区 // curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.190:5000/receive_hex"); curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.68.173:9080/system/redis/test"); /* Now specify the POST data */ struct curl_slist *plist = NULL; plist = curl_slist_append(plist, "Content-Type:application/json;charset=UTF-8"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, plist); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData); // std::cout << szJsonData << std::endl; // 设置响应回调函数和缓冲区 // 创建一个用于存储返回数据的 unsigned char 数组 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); std::cout <(c) << " "; } std::cout << std::endl; } // /* always cleanup */ curl_easy_cleanup(curl); } } //判断管道是否存在 bool isPipeExists(const char* pipe_Name) { return (access(pipe_Name, F_OK) == 0); } //通过命名管道的方式 int updateElevatorStatus(const char* status){ // const char* pipeName = "/tmp/Elevator_pipe"; // 定义命名管道的路径 // 创建命名管道 // if(!isPipeExists(pipeName)){ // mkfifo(pipeName, 0777); // } // 打开管道进行写入 int fd = open(pipeName, O_WRONLY); if (fd == -1) { std::cerr << "Failed to open the pipe for writing." << std::endl; return 1; } std::string message = status; write(fd, message.c_str(), strlen(message.c_str()) + 1); std::cout << "Hello, Process B!" <& response) { CURL *curl; CURLcode res; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); if(curl) { char postData[512];//建立缓冲区 sprintf(postData, "%s", hexData); //把hexData写入缓冲区 // curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.190:5000/receive_hex"); // curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.68.173:9080/system/redis/test"); // std::string uploader_url = BASE_URL_string + API_ENDPOINT; std::string uploader_url = BASE_URL_string; std::cout<< uploader_url << std::endl; // curl_easy_setopt(curl, CURLOPT_URL, "http://36.108.213.190:10004/system/redis/test"); curl_easy_setopt(curl, CURLOPT_URL, uploader_url.c_str()); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); struct curl_httppost* form = NULL; struct curl_httppost* lastptr = NULL; curl_formadd(&form, &lastptr, CURLFORM_COPYNAME, "name", CURLFORM_COPYCONTENTS, postData, CURLFORM_END); struct curl_slist* headers = NULL; headers = curl_slist_append(headers, "Content-Type: multipart/form-data"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPPOST, form); // 设置响应回调函数和缓冲区 // 创建一个用于存储返回数据的 unsigned char 数组 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); fprintf(stderr, "res: %s\n", curl_easy_strerror(res)); /* Check for errors */ if(res != CURLE_OK){ fprintf(stderr, "curl_easy_perform() passmessage failed: %s\n",curl_easy_strerror(res)); } else { for (unsigned char c : response) { std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast(c) << " "; } std::cout << std::endl; } // /* always cleanup */ curl_easy_cleanup(curl); } } void signal_handler(int signo) { if (signo == SIGINT || signo == SIGTERM) { quit = true; } } int main() { signal(SIGINT, signal_handler); // SIGINT 对应Ctrl+C signal(SIGTERM, signal_handler); // SIGTERM 对应kill或pkill readFileAndStoreInGlobal(URL_FILE, BASE_URL_string); struct timespec abs_timeout; // 打开或创建命名信号量 sem_t *my_semaphore = sem_open("/my_semaphore", O_CREAT, 0644, 1); // sem_t *my_semaphore = sem_open("/my_semaphore", 0); if (my_semaphore == SEM_FAILED) { perror("sem_open"); } int serialPort = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY); if (serialPort == -1) { printf("Failed to open serial port: %s\n", SERIAL_PORT); return 1; } struct termios tty; memset(&tty, 0, sizeof(tty)); if (tcgetattr(serialPort, &tty) != 0) { printf("Failed to get serial port attributes\n"); close(serialPort); return 1; } cfsetospeed(&tty, BAUD_RATE); cfsetispeed(&tty, BAUD_RATE); tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; tty.c_cflag &= ~(PARENB | PARODD); tty.c_cflag &= ~CSTOPB; tty.c_cflag |= CREAD | CLOCAL; tty.c_iflag = IGNPAR; tty.c_oflag = 0; tty.c_lflag = 0; if (tcsetattr(serialPort, TCSANOW, &tty) != 0) { printf("Failed to set serial port attributes\n"); close(serialPort); return 1; } char buffer[255]; ssize_t bytesRead; // 创建命名管道 if(!isPipeExists(pipeName)){ mkfifo(pipeName, 0777); } int i = 50001; while (!quit) { // if(sleep(0.1) != 0){ // printf("被中断\n"); // } clock_gettime(CLOCK_REALTIME, &abs_timeout); abs_timeout.tv_sec += 5; // 增加 5 秒的超时时间 if (sem_timedwait(my_semaphore, &abs_timeout) == -1) { if (errno == ETIMEDOUT) { // 在这里处理等待超时的情况 printf("等待超时\n"); // perror("sem_timedwait"); } else { perror("sem_timedwait"); } continue; } // sem_wait(my_semaphore); bytesRead = read(serialPort, buffer, sizeof(buffer)); i++; if(i%50000==0){ // printf(".\n"); i = 50001; } if (bytesRead > 0) { // 将二进制数据转换为十六进制字符串 char hexData[1024]; std::vector byteArray; int i; for (i = 0; i < bytesRead; i++) { snprintf(&hexData[i * 2], sizeof(hexData) - i * 2, "%02X", buffer[i]); byteArray.push_back(static_cast(buffer[i])); } printf("Received data: %s\n", hexData); for (unsigned char c : byteArray) { std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast(c) << " "; } std::cout << std::endl; //解析部分 if (byteArray.size() >= 16 && byteArray[15] == 0x01) { // 第15个字节是1 // 在这里编写处理逻辑 std::cout << "功能码为0x01 数据上传" <= 24 && byteArray[23] == 0x00){ // updateElevatorStatus("01"); } // else if (byteArray.size() >=24 && byteArray[23] == 0x80){ // } } else if (byteArray.size() >= 16 && byteArray[15] == 0x02) { // 第15个字节不是1 // 在这里编写处理逻辑 std::cout << "功能码为0x02 心跳包" <= 16 && byteArray[15] == 0x03) { // 第15个字节不是1 // 在这里编写处理逻辑 std::cout << "功能码为0x03 版本号上传" < response; // curlToServer(hexData,response); curlToServer_GET(hexData,response); // write(serialPort, response.data(), response.size()); } sem_post(my_semaphore); // printf("出锁"); } close(serialPort); sem_close(my_semaphore); printf("close serialPort and semaphore\n"); return 0; }