338 lines
9.8 KiB
C
Executable File
338 lines
9.8 KiB
C
Executable File
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <sys/time.h> // gettimeofday
|
||
#include <sys/stat.h>
|
||
#include <string.h>
|
||
#include <unistd.h>
|
||
#include <sys/types.h>
|
||
#include <fcntl.h>
|
||
#include <sys/mman.h>
|
||
#include <sys/ioctl.h>
|
||
#include <sys/socket.h>
|
||
#include <netinet/in.h>
|
||
#include <arpa/inet.h>
|
||
#include <netdb.h>
|
||
#include <errno.h>
|
||
#include <pthread.h>
|
||
#include "serial.h"
|
||
#include "uartinf.h"
|
||
#include <stdbool.h>
|
||
|
||
#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));
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
}
|