349 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			349 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | #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(¶m_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(¶m_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;
 | |||
|  | // }
 |