Elevator/build_http/main.cpp

349 lines
12 KiB
C++
Raw Normal View History

2024-07-28 18:23:29 +08:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <iomanip>
#include <sys/types.h>
#include <sys/stat.h>
#include <sstream>
#include "mongoose.h"
#include <semaphore.h>
#include <time.h>
#define SERIAL_PORT "/dev/ttyS0"
#define BAUD_RATE B115200
#define FILE_PWD "/etc/DeviceID"
char hexData[1024];
int get_return(int serialPort)
{
usleep(10000);
ssize_t size;
unsigned char ch;
char buffer[1024];
hexData[1024]={0};
size = read(serialPort, buffer, sizeof(buffer));
if (size > 0){
std::vector<unsigned char> byteArray;
int i;
for (i = 0; i < size; i++) {
snprintf(&hexData[i * 2], sizeof(hexData) - i * 2, "%02X", buffer[i]);
byteArray.push_back(static_cast<unsigned char>(buffer[i]));
}
printf("Received result: %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;
return 0;
}else{
return -1;
}
}
// 用于处理GET请求的事件处理函数
static void get_handler_10000(struct mg_connection *nc, int ev, void *ev_data) {
if (ev == MG_EV_HTTP_REQUEST) {
struct http_message *hm = (struct http_message *) ev_data;
// 检查HTTP请求方法是否为POST
if (mg_vcmp(&hm->method, "GET") == 0) {
// 解析POST请求的参数
struct mg_str param_str = hm->query_string;
// printf("param: %.*s\n", (int) hm->query_string.len, hm->query_string.p);
char value_buf[256];
int result = mg_get_http_var(&param_str, "DeviceID", value_buf, sizeof(value_buf));
if (result > 0) {
// 参数找到并存储在 value_buf 中
printf("DeviceID: %.*s\n", result, value_buf);
std::string data = value_buf;
FILE *file = fopen(FILE_PWD, "wb"); // 使用二进制模式打开文件
// 检查文件是否成功打开
if (file) {
// 将数据写入文件
size_t bytes_written = fwrite(value_buf, 1, strlen(value_buf), file);
// 检查写入是否成功
if (bytes_written == data.length()) {
printf("Data written to %s successfully.\n", FILE_PWD);
} else {
printf("Error writing data to %s.\n", FILE_PWD);
}
// 关闭文件
fclose(file);
} else {
printf("Error opening file %s for writing.\n", FILE_PWD);
}
} else {
// 参数未找到
mg_http_send_error(nc, 405, "Parameter Not Allowed");
printf("Parameter not found\n");
}
// // 提取POST请求的数据
// char post_data[1024]; // 假设数据大小不超过 1024 字节
// memcpy(post_data, hm->body.p, hm->body.len);
// post_data[hm->body.len] = '\0'; // 添加字符串结束符
// // 处理POST请求数据这里可以根据需要进行处理
// printf("Received POST data: %s\n", post_data);
// 发送HTTP响应
mg_printf(nc, "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: %d\r\n\r\n"
"POST data received and processed\r\n",
(int) strlen("POST data received and processed"));
nc->flags |= MG_F_SEND_AND_CLOSE; // 关闭连接
} else {
// 如果不是POST请求可以返回错误响应
mg_http_send_error(nc, 405, "Method Not Allowed");
}
}
}
// 用于处理GET请求的事件处理函数 气压计
static void get_handler_11000(struct mg_connection *nc, int ev, void *ev_data) {
if (ev == MG_EV_HTTP_REQUEST) {
sem_t *my_semaphore = sem_open("/my_semaphore", O_CREAT, 0644, 1);
struct timespec abs_timeout;
clock_gettime(CLOCK_REALTIME, &abs_timeout);
abs_timeout.tv_sec += 5; // 增加 5 秒的超时时间
int serialPort = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
if (serialPort == -1) {
printf("Failed to open serial port: %s\n", SERIAL_PORT);
}
struct termios tty;
memset(&tty, 0, sizeof(tty));
if (tcgetattr(serialPort, &tty) != 0) {
printf("Failed to get serial port attributes\n");
close(serialPort);
}
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);
}
char buffer[300];
ssize_t bytesRead;
struct http_message *hm = (struct http_message *) ev_data;
// 检查HTTP请求方法是否为POST
if (mg_vcmp(&hm->method, "GET") == 0) {
// 解析POST请求的参数
struct mg_str param_str = hm->query_string;
// printf("param: %.*s\n", (int) hm->query_string.len, hm->query_string.p);
char value_buf[256];
int result = mg_get_http_var(&param_str, "barometer", value_buf, sizeof(value_buf));
if (result > 0) {
// 参数找到并存储在 value_buf 中
printf("barometer: %.*s\n", result, value_buf);
} else {
// 参数未找到
mg_http_send_error(nc, 405, "Parameter Not Allowed");
printf("Parameter not found\n");
}
// 转换成16进制
std::string hex_string = value_buf;
std::vector<unsigned char> response;
// 使用std::stringstream来解析整个16进制字符串
std::stringstream ss(hex_string);
for (int i = 0; i < hex_string.length(); i += 2){
char byte_str[3]; // 两个字符表示一个字节
ss.read(byte_str, 2);
byte_str[2] = '\0'; // 添加字符串终止符
unsigned int byte;
std::stringstream(byte_str) >> std::hex >> byte;
response.push_back(static_cast<unsigned char>(byte));
}
// 打印转换后的结果
std::cout << "转换后的结果:" << std::endl;
for (const auto &byte : response) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
}
std::cout << std::endl;
if (sem_timedwait(my_semaphore, &abs_timeout) == -1) {
if (errno == ETIMEDOUT) {
// 在这里处理等待超时的情况
printf("等待超时\n");
mg_http_send_error(nc, 406, "写入超时,请稍后再试");
} else {
perror("sem_timedwait");
mg_http_send_error(nc, 407, "未知错误");
}
}else{
write(serialPort, response.data(), response.size());
int read_limit = 0;
int res = -1;
do {
res = get_return(serialPort);
read_limit++;
printf("res: %d i=%d\n",res,read_limit);
} while ((res != 0) && (read_limit < 100));
sem_post(my_semaphore);
// 发送HTTP响应
mg_printf(nc, "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: %d\r\n\r\n"
"%s\r\n",
(int) strlen(hexData),hexData);
nc->flags |= MG_F_SEND_AND_CLOSE; // 关闭连接
}
} else {
// 如果不是POST请求可以返回错误响应
mg_http_send_error(nc, 405, "Method Not Allowed");
}
close(serialPort);
}
}
int main(void) {
struct mg_mgr mgr;
struct mg_connection *nc1,*nc2;
mg_mgr_init(&mgr, NULL);
nc1 = mg_bind(&mgr, "10000", get_handler_10000); // 用于接收设备id
nc2 = mg_bind(&mgr, "11000", get_handler_11000); // 用于接收设备id
// 设置HTTP和WebSocket协议
mg_set_protocol_http_websocket(nc1);
mg_set_protocol_http_websocket(nc2);
printf("Starting web server on port 10000 and 11000\n");
for (;;) {
mg_mgr_poll(&mgr, 1000);
}
mg_mgr_free(&mgr);
return 0;
}
// #include "mongoose.h"
// static void handle_multipart(struct mg_connection *nc, struct http_message *hm) {
// char var_name[256];
// char file_name[256];
// const char *data;
// size_t data_len;
// size_t pos = mg_parse_multipart(
// hm->body.p, hm->body.len, var_name, sizeof(var_name),
// file_name, sizeof(file_name), &data, &data_len
// );
// // 遍历各个部分,处理每个字段的数据
// while (pos > 0) {
// // 在这里处理字段数据
// // printf("File Name: %s\n", file_name);
// printf("Field Name: %s\n", var_name);
// printf("Field Data: %.*s\n", (int) data_len, data);
// FILE *file = fopen(var_name, "wb"); // 使用二进制模式打开文件
// // 检查文件是否成功打开
// if (file) {
// // 将数据写入文件
// size_t bytes_written = fwrite(data, 1, data_len, file);
// // 检查写入是否成功
// if (bytes_written == data_len) {
// printf("Data written to %s successfully.\n", var_name);
// } else {
// printf("Error writing data to %s.\n", var_name);
// }
// // 关闭文件
// fclose(file);
// } else {
// printf("Error opening file %s for writing.\n", var_name);
// }
// // 继续解析下一个部分
// pos = mg_parse_multipart(
// hm->body.p + pos, hm->body.len - pos, var_name, sizeof(var_name),
// file_name, sizeof(file_name), &data, &data_len
// );
// }
// }
// static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
// if (ev == MG_EV_HTTP_REQUEST) {
// struct http_message *hm = (struct http_message *)ev_data;
// // 检查Content-Type是否为multipart/form-data
// // if (mg_vcmp(&hm->header.content_type, "multipart/form-data") == 0) {
// // 调用处理multipart请求的函数
// handle_multipart(nc, hm);
// // } else {
// // mg_http_send_error(nc, 400, "Bad Request");
// // }
// mg_printf(nc, "HTTP/1.1 200 OK\r\n"
// "Content-Type: text/plain\r\n"
// "Content-Length: %d\r\n\r\n"
// "POST data received and processed\r\n",
// (int) strlen("POST data received and processed"));
// nc->flags |= MG_F_SEND_AND_CLOSE; // 关闭连接
// }
// }
// int main(void) {
// struct mg_mgr mgr;
// struct mg_connection *nc;
// mg_mgr_init(&mgr, NULL);
// nc = mg_bind(&mgr, "8080", ev_handler);
// mg_set_protocol_http_websocket(nc);
// printf("Starting web server on port 8080\n");
// for (;;) {
// mg_mgr_poll(&mgr, 1000);
// }
// mg_mgr_free(&mgr);
// return 0;
// }