2023-05-30 08:53:31 +00:00
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*
|
|
|
|
|
* Change Logs:
|
|
|
|
|
* Date Author Notes
|
|
|
|
|
* 2023-05-30 murmur the first version
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <rtthread.h>
|
|
|
|
|
#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#define LOG_TAG "ttTR"
|
2023-06-06 07:45:13 +00:00
|
|
|
|
#define LOG_LVL LOG_LVL_DBG
|
2023-05-30 08:53:31 +00:00
|
|
|
|
#include <ulog.h>
|
2023-06-20 10:09:07 +00:00
|
|
|
|
|
2023-06-16 03:18:52 +00:00
|
|
|
|
#include <usrcfg.h>
|
2023-08-31 09:14:48 +00:00
|
|
|
|
#include "ttTR.h"
|
2023-05-30 08:53:31 +00:00
|
|
|
|
|
2023-08-26 08:49:19 +00:00
|
|
|
|
#define BUFSZ 2000
|
2023-05-30 08:53:31 +00:00
|
|
|
|
#define RETRYCNT 10
|
2023-06-16 03:18:52 +00:00
|
|
|
|
#define URL TTIP
|
2023-05-30 08:53:31 +00:00
|
|
|
|
#define PORT 8005
|
|
|
|
|
|
2023-06-16 03:18:52 +00:00
|
|
|
|
static int sock=0;
|
2023-08-26 08:49:19 +00:00
|
|
|
|
volatile int flag=0;
|
2023-06-16 03:18:52 +00:00
|
|
|
|
void tcpClose(void)
|
2023-05-30 08:53:31 +00:00
|
|
|
|
{
|
|
|
|
|
/* 关闭这个连接 */
|
|
|
|
|
if (sock) {
|
|
|
|
|
closesocket(sock);
|
2023-07-27 07:46:45 +00:00
|
|
|
|
|
2023-05-30 08:53:31 +00:00
|
|
|
|
}
|
2023-07-27 07:46:45 +00:00
|
|
|
|
flag=0;
|
2023-05-30 08:53:31 +00:00
|
|
|
|
|
|
|
|
|
}
|
2023-07-27 07:46:45 +00:00
|
|
|
|
int isTCPok(void)
|
2023-06-20 10:09:07 +00:00
|
|
|
|
{
|
2023-07-27 07:46:45 +00:00
|
|
|
|
// return sock;
|
2023-07-20 07:29:37 +00:00
|
|
|
|
return flag;
|
2023-06-20 10:09:07 +00:00
|
|
|
|
}
|
2023-05-30 08:53:31 +00:00
|
|
|
|
|
2023-06-16 03:18:52 +00:00
|
|
|
|
int tcpInit(void)
|
2023-05-30 08:53:31 +00:00
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
2023-07-20 07:29:37 +00:00
|
|
|
|
const char *url = URL;
|
|
|
|
|
int port = PORT;
|
|
|
|
|
|
|
|
|
|
/* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
|
|
|
|
|
struct hostent *host;
|
|
|
|
|
host = gethostbyname(url);
|
|
|
|
|
|
|
|
|
|
/* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */
|
|
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
|
|
|
|
{
|
|
|
|
|
/* 创建socket失败 */
|
|
|
|
|
LOG_E("Socket error");
|
|
|
|
|
|
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 初始化预连接的服务端地址 */
|
|
|
|
|
struct sockaddr_in server_addr;
|
|
|
|
|
server_addr.sin_family = AF_INET;
|
|
|
|
|
server_addr.sin_port = htons(port);
|
|
|
|
|
server_addr.sin_addr = *((struct in_addr *) host->h_addr);
|
|
|
|
|
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
|
|
|
|
|
|
|
|
|
|
/* 连接到服务端 */
|
|
|
|
|
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
|
|
|
|
|
{
|
|
|
|
|
/* 连接失败 */
|
2023-08-18 09:10:47 +00:00
|
|
|
|
LOG_E("Connect to TT fail!");
|
2023-07-20 07:29:37 +00:00
|
|
|
|
tcpClose();
|
2023-05-30 08:53:31 +00:00
|
|
|
|
|
2023-07-20 07:29:37 +00:00
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// tcpRecMQ();
|
|
|
|
|
flag=1;
|
2023-05-30 08:53:31 +00:00
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int tcpSend(const rt_uint8_t *send_data, size_t len)
|
|
|
|
|
{
|
2023-06-16 08:20:18 +00:00
|
|
|
|
// LOG_HEX("send",27,send_data,len);
|
2023-05-30 08:53:31 +00:00
|
|
|
|
/* 发送数据到sock连接 */
|
|
|
|
|
int ret = send(sock, send_data, len, 0);
|
|
|
|
|
|
|
|
|
|
if (ret == len)
|
|
|
|
|
{
|
2023-08-08 08:38:50 +00:00
|
|
|
|
// LOG_D("send %d Bytes ok.",len);
|
2023-05-30 08:53:31 +00:00
|
|
|
|
ret = RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LOG_E("Send error, send function return %d", ret);
|
|
|
|
|
ret = RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-16 03:18:52 +00:00
|
|
|
|
/**
|
|
|
|
|
* 接收TCP数据
|
|
|
|
|
* @param recv_data 接收数据缓存,最小200字节
|
|
|
|
|
* @return 接收到的数据长度,-1表示发生了错误。
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int tcpRec(unsigned char *recv_data)
|
|
|
|
|
{
|
|
|
|
|
int ret=RT_ERROR;
|
|
|
|
|
/* 从sock连接中接收最大BUFSZ字节数据 */
|
|
|
|
|
int bytes_received = recv(sock, recv_data, BUFSZ, 0);
|
|
|
|
|
if (bytes_received) {
|
|
|
|
|
return bytes_received;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
LOG_E("received error.");
|
|
|
|
|
return -RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-20 10:09:07 +00:00
|
|
|
|
|
|
|
|
|
struct rt_messagequeue TTrx_mq;
|
|
|
|
|
void init_mq(void)
|
|
|
|
|
{
|
2023-09-16 06:42:37 +00:00
|
|
|
|
static char msg_pool[1024*5];
|
2023-06-20 10:09:07 +00:00
|
|
|
|
/* 初始化消息队列 */
|
|
|
|
|
int result = rt_mq_init(&TTrx_mq, "TTrx_mq",
|
|
|
|
|
msg_pool, /* 存放消息的缓冲区 */
|
|
|
|
|
sizeof(TTRx_MSG), /* 一条消息的最大长度 */
|
|
|
|
|
sizeof(msg_pool), /* 存放消息的缓冲区大小 */
|
|
|
|
|
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
|
|
|
|
|
if (result != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
rt_kprintf("init message queue failed.\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
INIT_COMPONENT_EXPORT(init_mq);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 接收TCP数据,通过消息队列发出通知
|
|
|
|
|
* @param recv_data 接收数据缓存,最小200字节
|
|
|
|
|
* @return 接收到的数据长度,-1表示发生了错误。
|
|
|
|
|
*/
|
|
|
|
|
void tcpRecMQ_thread_entry(void)
|
|
|
|
|
{
|
|
|
|
|
static TTRx_MSG msg;
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
2023-07-27 07:46:45 +00:00
|
|
|
|
if (!isTCPok()) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-06-20 10:09:07 +00:00
|
|
|
|
rt_memset(&msg, 0, sizeof(msg));
|
|
|
|
|
/* 从sock连接中接收最大BUFSZ字节数据 */
|
|
|
|
|
msg.size = recv(sock, msg.data, BUFSZ, 0);
|
|
|
|
|
// if (msg.size < 0)
|
|
|
|
|
// {
|
|
|
|
|
// /* 接收失败,关闭这个连接 */
|
|
|
|
|
// tcpClose();
|
|
|
|
|
// rt_kprintf("\nreceived error,close the socket.\r\n");
|
|
|
|
|
//
|
|
|
|
|
// /* 释放接收缓冲 */
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
2023-07-20 07:29:37 +00:00
|
|
|
|
// LOG_D("%d Bytes received.",msg.size);
|
2023-06-20 10:09:07 +00:00
|
|
|
|
if (msg.size >0 )
|
|
|
|
|
{
|
|
|
|
|
// LOG_D("%d Bytes received.",msg.size);
|
|
|
|
|
// LOG_HEX("tcpTT", 16, msg.data, msg.size);
|
2023-08-21 09:18:07 +00:00
|
|
|
|
// resetTM();
|
2023-06-20 10:09:07 +00:00
|
|
|
|
int result = rt_mq_send(&TTrx_mq, &msg, sizeof(msg));
|
2023-07-20 07:29:37 +00:00
|
|
|
|
if (result == -RT_EFULL)
|
2023-06-20 10:09:07 +00:00
|
|
|
|
{
|
|
|
|
|
/* 消息队列满 */
|
|
|
|
|
LOG_W("message queue full.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-06-21 03:08:53 +00:00
|
|
|
|
msg.size=0;//收到数据长度为0表示tcp断开
|
|
|
|
|
rt_mq_send(&TTrx_mq, &msg, sizeof(msg));
|
2023-07-28 08:29:57 +00:00
|
|
|
|
LOG_W("tcp closed.");
|
2023-07-27 07:46:45 +00:00
|
|
|
|
tcpClose();
|
2023-06-20 10:09:07 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 创建接收线程。发生错误后自动退出。
|
|
|
|
|
*/
|
|
|
|
|
void tcpRecMQ(void)
|
|
|
|
|
{
|
|
|
|
|
/* 创建 serial 线程 */
|
2023-09-05 10:53:01 +00:00
|
|
|
|
rt_thread_t thread = rt_thread_create("tcpRecMQ", tcpRecMQ_thread_entry, RT_NULL, 1024*10, 25, 10);
|
2023-06-20 10:09:07 +00:00
|
|
|
|
/* 创建成功则启动线程 */
|
|
|
|
|
if (thread != RT_NULL)
|
|
|
|
|
{
|
|
|
|
|
rt_thread_startup(thread);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LOG_E("thread 'tcpRecMQ' create failure.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//INIT_COMPONENT_EXPORT(tcpRecMQ);
|
2023-06-16 03:18:52 +00:00
|
|
|
|
/**
|
|
|
|
|
* 发送数据时TT的ack信号
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
static int tcpAck()
|
2023-05-30 08:53:31 +00:00
|
|
|
|
{
|
|
|
|
|
/* 分配用于存放接收数据的缓冲 */
|
|
|
|
|
char *recv_data;
|
|
|
|
|
recv_data = rt_malloc(BUFSZ);
|
|
|
|
|
if (recv_data == RT_NULL)
|
|
|
|
|
{
|
|
|
|
|
LOG_E("No memory.");
|
|
|
|
|
return RT_ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ret=RT_ERROR;
|
|
|
|
|
size_t cnt = RETRYCNT;//尝试次数
|
|
|
|
|
while (cnt--)
|
|
|
|
|
{
|
|
|
|
|
/* 从sock连接中接收最大BUFSZ - 1字节数据 */
|
2023-06-16 03:18:52 +00:00
|
|
|
|
int bytes_received = recv(sock, recv_data, BUFSZ, 0);
|
2023-05-30 08:53:31 +00:00
|
|
|
|
if (bytes_received) {
|
|
|
|
|
LOG_HEX("rec data",16,recv_data,bytes_received);
|
|
|
|
|
//check response
|
|
|
|
|
rt_uint8_t rec_good[] = { 0x88, 0xAA, 0xBB, 0x88 };//前四字节
|
|
|
|
|
if (rt_memcmp(recv_data, rec_good, 4))
|
|
|
|
|
{
|
|
|
|
|
ret = RT_EOK;
|
|
|
|
|
/* 释放接收缓冲 */
|
|
|
|
|
rt_free(recv_data);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
LOG_E("received error.");
|
|
|
|
|
|
|
|
|
|
/* 释放接收缓冲 */
|
|
|
|
|
rt_free(recv_data);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rt_thread_delay(100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 发送一维数组
|
|
|
|
|
* @param msg 待发数据
|
|
|
|
|
* @param len 数组长度
|
|
|
|
|
* @return 成功返回0
|
|
|
|
|
*/
|
|
|
|
|
int sendMsg(const rt_uint8_t *msg, size_t len)
|
|
|
|
|
{
|
|
|
|
|
if (tcpSend(msg, len) != RT_EOK)
|
|
|
|
|
{
|
2023-08-01 08:27:21 +00:00
|
|
|
|
// tcpClose();
|
2023-05-30 08:53:31 +00:00
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
2023-06-19 07:56:45 +00:00
|
|
|
|
//#define CHK_ACK
|
|
|
|
|
#ifdef CHK_ACK
|
|
|
|
|
if (tcpAck() != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
return RT_ERROR;
|
|
|
|
|
// break;
|
|
|
|
|
};
|
2023-05-30 08:53:31 +00:00
|
|
|
|
|
2023-06-19 07:56:45 +00:00
|
|
|
|
#endif
|
2023-08-08 08:38:50 +00:00
|
|
|
|
// return RT_EOK;
|
2023-08-01 08:27:21 +00:00
|
|
|
|
//已发送数据存入log文件
|
2023-08-08 08:38:50 +00:00
|
|
|
|
char str[600];
|
2023-07-26 08:26:53 +00:00
|
|
|
|
bytes2str(msg, len, 16, " ", str);
|
|
|
|
|
trDataTolog(str, strlen(str), 1);
|
2023-08-01 08:27:21 +00:00
|
|
|
|
|
2023-05-30 08:53:31 +00:00
|
|
|
|
return RT_EOK;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 发送二维数组
|
|
|
|
|
* @param msg 待发二维数组
|
|
|
|
|
* @param s 各纬度数组长度
|
|
|
|
|
* @param row 数组长度
|
|
|
|
|
* @return 成功返回0
|
|
|
|
|
*/
|
|
|
|
|
int sendMsgs(const rt_uint8_t (*msg)[200], char *s, size_t row)
|
|
|
|
|
{
|
2023-06-16 03:18:52 +00:00
|
|
|
|
int ret = RT_EOK;
|
2023-05-30 08:53:31 +00:00
|
|
|
|
|
|
|
|
|
if (tcpInit() != RT_EOK)
|
|
|
|
|
{
|
2023-06-16 03:18:52 +00:00
|
|
|
|
ret = RT_ERROR;
|
|
|
|
|
return ret;
|
2023-05-30 08:53:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (size_t var = 0; var < row; var++)
|
|
|
|
|
{
|
|
|
|
|
if (tcpSend(msg[var], s[row]) != RT_EOK)
|
|
|
|
|
{
|
2023-06-16 03:18:52 +00:00
|
|
|
|
ret = RT_ERROR;
|
|
|
|
|
break;
|
2023-05-30 08:53:31 +00:00
|
|
|
|
}
|
2023-06-16 03:18:52 +00:00
|
|
|
|
#ifdef CHK_ACK
|
|
|
|
|
if (tcpAck() != RT_EOK)
|
2023-05-30 08:53:31 +00:00
|
|
|
|
{
|
2023-06-16 03:18:52 +00:00
|
|
|
|
ret = RT_ERROR;
|
|
|
|
|
break;
|
2023-05-30 08:53:31 +00:00
|
|
|
|
};
|
2023-06-16 03:18:52 +00:00
|
|
|
|
|
|
|
|
|
#endif
|
2023-05-30 08:53:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tcpClose();
|
2023-06-16 03:18:52 +00:00
|
|
|
|
return ret;
|
2023-05-30 08:53:31 +00:00
|
|
|
|
}
|