Elevator/chuankou2/chuankou.cpp

377 lines
12 KiB
C++

/*
/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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <curl/curl.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <iomanip>
#include <sys/types.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <time.h>
#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<unsigned char>* response) {
size_t totalSize = size * nmemb;
unsigned char* data = static_cast<unsigned char*>(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<unsigned char>& 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<unsigned char>& 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 <<res<< std::endl;
/* 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<int>(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!" <<std::endl;
close(fd);
return 0;
}
void curlToServer_GET(const char* hexData, std::vector<unsigned char>& 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<int>(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<unsigned char> 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<unsigned char>(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<int>(c) << " ";
}
std::cout << std::endl;
//解析部分
if (byteArray.size() >= 16 && byteArray[15] == 0x01) {
// 第15个字节是1
// 在这里编写处理逻辑
std::cout << "功能码为0x01 数据上传" <<std::endl;
if(byteArray.size() >= 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 心跳包" <<std::endl;
// updateElevatorStatus("02");
}
else if (byteArray.size() >= 16 && byteArray[15] == 0x03)
{
// 第15个字节不是1
// 在这里编写处理逻辑
std::cout << "功能码为0x03 版本号上传" <<std::endl;
// updateElevatorStatus("02");
}
else{
std::cout << "数据异常" <<std::endl;
}
// 发送数据到服务器
// sendToServer(hexData);
std::vector<unsigned char> 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;
}