Elevator/build_http/main.cpp

349 lines
12 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
// }