377 lines
12 KiB
C++
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;
|
|
}
|