#include #include #include // gettimeofday #include #include #include #include #include #include #include #include #include #include #include #include #include #include "serial.h" #include "uartinf.h" #include #define RECV_PORT 12000 // UDP接收端口 #define SEND_PORT 12001 // 发送端口(UART转NET) /* ===================== 网络帧协议定义 ===================== */ #define NET_FRAME_LEN 32 /* 收/发报文固定长度 */ #define NET_TAIL 0xBB /* 帧尾 */ #define PAYLOAD_LEN 30 /* 帧长度 byte0..29 */ #define BYTE_MODE 30 /* 接收帧 mode 字段偏移(0-4) */ #define BYTE_TAIL 31 /* 接收帧帧尾偏移 */ #define CHECKSUM_END 30 /* 校验和覆盖 byte0..byte30(含) */ #define NET_FRAME_MAX_LEN 256 /* recvfrom 缓冲大小 */ /* ===================== 共享内存 ===================== */ #define SHM_MSG_NAME "/video_switch" #define SHM_MODE_IDX 0 /* switch_mode -> shm[0](即 switch_video[0]) */ static int *shm_msg = NULL; char _rx_data[200]; static int socket_descriptor; static struct sockaddr_in address; bool first = false; int socket_descriptor_recv; struct sockaddr_in address_recv; pthread_attr_t attr; pthread_t pkts_thread; /* 打开共享内存 /param.txt(由 lc6600_uart 进程写入 RSSI) */ static int *param_memory_open(void) { int fd = shm_open("/param.txt", O_RDWR, 0777); if (fd < 0) { fd = shm_open("/param.txt", O_RDWR | O_CREAT, 0777); if (fd < 0) { perror("shm_open /param.txt"); return NULL; } if (ftruncate(fd, 4096) == -1) { perror("ftruncate /param.txt"); return NULL; } } int *retval = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (retval == MAP_FAILED) { perror("mmap /param.txt"); return NULL; } return retval; } static int *switch_memory_open(void) { char buf[128]; int fd; sprintf(buf, SHM_MSG_NAME); fd = shm_open(buf, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if(fd < 0) { perror("shm_open"); exit(1); } if (ftruncate(fd, 4096) == -1) { perror("ftruncate"); exit(1); } int *retval = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); return retval; } /* 读 GPIO71(0/1),失败返回默认值 1 */ static int read_gpio72(void) { char val = 0; int fd = open("/sys/class/gpio/gpio71/value", O_RDONLY); if (fd < 0) return 0; /* 失败默认 0 */ if (read(fd, &val, 1) != 1) { close(fd); return 0; /* 失败默认 0 */ } close(fd); return (val == '0') ? 1 : 0; /* 反相:GPIO=1 → 0,GPIO=0 → 1 */ } int init_net_recv(int port){ int i; struct timeval tv; bzero(&address_recv,sizeof(struct sockaddr_in)); address_recv.sin_family=AF_INET; address_recv.sin_addr.s_addr=htonl(INADDR_ANY); address_recv.sin_port=htons(port); socket_descriptor_recv=socket(AF_INET,SOCK_DGRAM,0);//IPV4 tv.tv_sec = 2; tv.tv_usec = 0; if (setsockopt(socket_descriptor_recv, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { printf("socket option SO_RCVTIMEO not support\n"); return -1; } if (bind(socket_descriptor_recv, (struct sockaddr *)&address_recv, sizeof(struct sockaddr_in)) < 0) { perror("bind"); exit(1); } return 0; } int udp_init(char *ip, int port){ bzero(&address,sizeof(address)); address.sin_family=AF_INET; address.sin_addr.s_addr=inet_addr(ip); address.sin_port=htons(port); socket_descriptor=socket(AF_INET,SOCK_DGRAM,0);//IPV4 return 0; } #if 0 void *net_recv(void *arg) { int i; struct sockaddr_in clientAddr; int len = sizeof(clientAddr); int ret; struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; if (setsockopt(socket_descriptor_recv, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { printf("socket option SO_RCVTIMEO not support\n"); //return -1; } char buffer_cmd[200]; while(1){ i = recvfrom(socket_descriptor_recv, buffer_cmd, 200, 0, (struct sockaddr*)&clientAddr, &len); if(i>0){ uart_write_len(ROUTE_UART,buffer_cmd,i); } else{ printf(" time_out to receive data\n"); } } } #endif #if 1 void *net_recv(void *arg) { int i, k; struct sockaddr_in clientAddr; socklen_t len; struct timeval tv; char buffer_cmd[NET_FRAME_MAX_LEN]; char frame_out[NET_FRAME_MAX_LEN]; int sum; unsigned char checksum; tv.tv_sec = 5; tv.tv_usec = 0; if (setsockopt(socket_descriptor_recv, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) printf("socket option SO_RCVTIMEO not support\n"); while (1) { len = sizeof(clientAddr); /* 每次循环重置,recvfrom 会改写 len */ i = recvfrom(socket_descriptor_recv, buffer_cmd, NET_FRAME_MAX_LEN, 0, (struct sockaddr*)&clientAddr, &len); if (i <= 0) { printf(" time_out to receive data\n"); continue; } if (i != NET_FRAME_LEN) { printf("bad frame len=%d\n", i); continue; } /* 帧尾校验 */ if ((unsigned char)buffer_cmd[BYTE_TAIL] != NET_TAIL) { printf("bad tail=%02x\n", (unsigned char)buffer_cmd[BYTE_TAIL]); continue; } /* 解析 mode -> 写共享内存 */ if (shm_msg) { static int last_mode = -1; int mode = (unsigned char)buffer_cmd[BYTE_MODE]; if (mode <= 4) { if (mode != last_mode) { shm_msg[SHM_MODE_IDX] = mode; //写入共享内存 viode_switch last_mode = mode; printf("write shm: mode=%d\n", mode); } } else { printf("filed mode=%d\n", mode); } } /* 2) 校验和 = byte0..byte30 求和取低8位 */ sum = 0; for (k = 0; k <= CHECKSUM_END; k++) sum += (unsigned char)buffer_cmd[k]; checksum = sum & 0xFF; /* 3) 转发:去掉 byte30/31,byte0..29 原样 + 帧尾 + 校验和(仍 32 字节) */ memcpy(frame_out, buffer_cmd, PAYLOAD_LEN); /* 0..29,共 30 字节 */ frame_out[PAYLOAD_LEN] = NET_TAIL; /* [30] 帧尾 */ frame_out[PAYLOAD_LEN + 1] = checksum; /* [31] 校验和 */ #if 0 /* 打印发出的包 */ printf(" send to uart %d bytes:", NET_FRAME_LEN); for (k = 0; k < NET_FRAME_LEN; k++) printf(" %02x", (unsigned char)frame_out[k]); printf("\n"); #endif uart_write_len(ROUTE_UART, frame_out, NET_FRAME_LEN); //发送给串口 } return NULL; } #endif int pthread_init() { int ret; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); ret = pthread_create(&pkts_thread, &attr, net_recv, NULL); pthread_attr_destroy(&attr); if(ret){ printf("create pthread1 error\n"); return 1; } } int main (int argc, char *argv[]) { int n_read; int i; int count=0; int *buffer_param; char buffer_send[100]; int buffer_len; n_read = uart_init(ROUTE_UART, "/dev/ttyAMA2", 115200, 'N'); if(n_read <=0 ) { printf("open /dev/ttyAMA2 failed\n"); return -1; } // udp_init(argv[1], atoi(argv[2])); // init_net_recv(atoi(argv[3])); udp_init("127.0.0.1", SEND_PORT); // 发送目标:本机回环 12001 init_net_recv(RECV_PORT); // 接收:0.0.0.0:12000(INADDR_ANY) shm_msg = switch_memory_open(); buffer_param = param_memory_open(); pthread_init(); while(1){ n_read = uart_read(ROUTE_UART, _rx_data); if(n_read > 0 ){ if (n_read >= 32) { /* 完整 32 字节帧才处理 */ int k, sum = 0; _rx_data[27] = (char)read_gpio72(); /* byte27 = GPIO9_0 反相值 */ if (buffer_param) { /* 写入:byte28/29 = RSSI 信号强度 */ _rx_data[28] = (char)buffer_param[1]; _rx_data[29] = (char)buffer_param[2]; printf("RSSI1 =%d RSSI2 =%d",buffer_param[1],buffer_param[2]); } /* 和校验:byte0..byte30 求和取低 8 位,写入 byte31 */ for (k = 0; k <= 30; k++) sum += (unsigned char)_rx_data[k]; _rx_data[31] = (char)(sum & 0xFF); } sendto(socket_descriptor, _rx_data, n_read, 0, (struct sockaddr *)&address, sizeof(address)); } } }