Files
hisi_SS524V100_SDK/mpp/sample/uart2net_mesh/ctrl_pnl.c
T

338 lines
9.8 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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));
}
}
}