如何抑制MQTT?
参考:https://blog.csdn.net/mzwhhwj/article/details/77939165
看上去很简单
先去下载
https://github.com/eclipse/paho.mqtt.embedded-c
paho.mqtt.embedded-c-master.zip 241KB
其实和我自己的TOUCH工程几乎一样
D:\Work\TOUCHBLUE+\Middlewares\Third_Party\mqtt\MQTTPacket
继续
https://blog.csdn.net/qq_27329367/article/details/82970452
工具 其实GIT可以看到的
MQTT 客户端 http://www.jensd.de/apps/mqttfx/1.7.1/
测试服务器: "tcp:// iot.eclipse.org :1883"
看我们的代码 除了上面的 不动的代码
自己写的
D:\MQTT\paho.mqtt.embedded-c-master\MQTTClient-C\src\FreeRTOS\MQTTFreeRTOS.c
和我们是一样的!
也就是我除了上面的文件夹包不动
还需要一个模块MQTTFreeRTOS.c提供支持
还需要mqtt_client.c模块【变化挺大】
支持一个任务模块【其实是从MQTTFreeRTOS.c剥离出来的状态机】统一蓝牙刷卡啥的任务吧我是mqtt_task.c
main_task
||
creat_buletooth_task(); //蓝牙初始化
creat_key_task(); //按键初始化 可以放弃!做中断 触发按键!
creat_swipe_task(); //刷卡初始化
creat_open_log_task(); //开门日志初始化
creat_mqtt_ota_task(); //ota任务
creat_http_task();
create_mqtt_task();
||
osThreadDef(net, mqtt_task, osPriorityHigh, 0, configMINIMAL_STACK_SIZE*10);
||
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;//SDK
mqtt_network_init(&network);//需要自己完成
==插入0==
研究下
参数:
Network network;
typedef struct Network Network;
struct Network
{
xSocket_t my_socket;
int (*mqttread) (Network*, unsigned char*, int, int);
int (*mqttwrite) (Network*, unsigned char*, int, int);
void (*disconnect) (Network*);
};
函数:
void mqtt_network_init(Network* n)
{
n->my_socket = (void *)&mqttSocketId;
n->mqttread = FreeRTOS_read;
n->mqttwrite = FreeRTOS_write;
n->disconnect = FreeRTOS_disconnect;
}
赋值的4个右值:
#1
MqttSocketId mqttSocketId;
typedef struct SocketId
{
int8_t id;
}MqttSocketId;
其实就是通道号
#2
就是一定时间timeout_ms 读到数据放在buffer-len
int FreeRTOS_read(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
int time = timeout_ms/10 ; /* convert milliseconds to ticks */
int recvLen = 0;
do
{
int rc = 0;
rc = FreeRTOS_recv_buffer(n->my_socket, buffer + recvLen, len - recvLen, 10);
if (rc > 0)
recvLen += rc;
else if (rc < 0)
{
recvLen = rc;
break;
}
} while ((recvLen < len) && ( time-- ));
return recvLen;
}
子函数:需要自己完成 吧数据放过来
int FreeRTOS_recv_buffer(void *socketId , uint8_t *buffer , int len ,int timeout_ms)
{
int ret = 0;
MqttSocketId *mqttId = (MqttSocketId *)(socketId);
ret = socket.read_buffer(mqttId->id , buffer , len , timeout_ms);
if( ret == SOCKET_READ_TIMEOUT)
{
return 0;
}
else
{
return ret ;
}
}
#3同上 这里是把数据发出去
int FreeRTOS_write(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
int time = timeout_ms/10000;
int sentLen = 0;
do
{
int rc = 0;
rc = FreeRTOS_send(n->my_socket, buffer + sentLen, len - sentLen, 10000);
if (rc > 0)
{
sentLen += rc;
}
else if (rc < 0)
{
sentLen = rc;
break;
}
} while (sentLen < len && time--);
if( sentLen < 0)
{
log(WARN,"Send error =%d\n" , sentLen);
}
return sentLen;
}
int FreeRTOS_send(void *socketId , uint8_t *buffer , int len ,int timeout_ms)
{
MqttSocketId *mqttId = (MqttSocketId *)(socketId);
int ret = 0;
ret = socket.send(mqttId->id , buffer , len , timeout_ms);
if( ret == SOCKET_OK)
{
return len;
}
return ret;
}
#4就是关闭通道
void FreeRTOS_disconnect(Network* n)
{
MqttSocketId *mqttId = (MqttSocketId *)(n->my_socket);
socket.disconnect(mqttId->id);
}
==插入1==
mqtt_client_init(&client, &network, 30 , 30000,mqttreadbuf, sizeof(mqttreadbuf));
研究一样
其实我们就是做了2个函数 对接 也就是上面2个 一个做了network 一个做了client
参数:
mqttClientType client;
typedef struct _mqttClient
{
uint32_t nextPacketId;
uint32_t commandTimeoutMs;
uint32_t dataRepeatTimeSec;
size_t readbufSize;
uint8_t *readbuf;
uint32_t keepAliveInterval;
char pingOutStanding;
int isconnected;
int cleansession;
struct MessageHandlers
{
uint8_t *topicFilter;
void (*fp) (void * , MessageData*);
} messageHandlers[MAX_MESSAGE_HANDLERS]; /* Message handlers are indexed by subscription topic */
void (*defaultMessageHandler) (MessageData*);
Network* ipstack;
Mutex mutex;
xTaskHandle sendTaskHandle;
} mqttClientType;
extern uint8_t mqttreadbuf[2048];
函数:
void mqtt_client_init(mqttClientType* c, Network* network, uint32_t dataRepeatTime , unsigned int command_timeout_ms, unsigned char* readbuf, size_t readbuf_size)
{
int i = 0;
c->ipstack = network;
c-> dataRepeatTimeSec = dataRepeatTime;
c->commandTimeoutMs = command_timeout_ms;
c->readbuf = readbuf;
c->readbufSize = readbuf_size;
c->isconnected = 0;
c->cleansession = 0;
c->pingOutStanding = 0;
c->nextPacketId = 1;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)//最多订阅5个主题
c->messageHandlers[i].topicFilter = 0;
c->defaultMessageHandler = NULL;
MutexInit(&c->mutex);
c->sendTaskHandle = creat_mqtt_send_task(c);//这里有点意思 是把一个任务 赋值 建立一个TX任务
creat_tsl_mqtt_task(c);//建立一个RX任务
}
void creat_tsl_mqtt_task( mqttClientType* c) {
osThreadDef( mqtt_recv, mqtt_recv_task , osPriorityNormal, 0, configMINIMAL_STACK_SIZE*18);
tslMqttTask = osThreadCreate(osThread(mqtt_recv), (void *)c);
configASSERT(tslMqttTask);
}在mqtt_recv_task处理平台过来的message
也就是此后client有了2个任务
+++
mqttAliveTimerPort = timer.creat(50000 , FALSE , mqtt_keep_alive );
mqttKEEPAliveBLUE = timer.creat(60000 , FALSE , BLUE_keep_alive );//60000 一分钟
建立2个定时任务 后面的是我JS定期上报设备正常异常的BOOL
前面的呢?
void mqtt_keep_alive( void )
{
mqtt_send_keep_alive();
}
void mqtt_send_keep_alive( void )
{
mqttKeepAlive = TRUE;
}
关注他
uint8_t mqttKeepAlive = FALSE;
在 客户模块中
int mqtt_cycle( mqttClientType* c)
if( mqttKeepAlive )
{
mqttKeepAlive = FALSE;
rc = mqtt_keepalive( c );
}
也即是隔一段时间 执行一次 mqtt_keepalive( c );
具体函数int mqtt_keepalive( mqttClientType* c)
可以有时间看看 它是做一个没有body的报文 发送出去
不是发送到我们的平台 是发送到MQTT服务器的 保证不掉线的!
+++
进入到状态机
GMQTT_INIT-初始化清0
GMQTT_CONNECT_TCP
int mqtt_network_connect(Network* n, uint8_t* addr, int port)这里其实是对Network* n的通道号赋值
如果连接失败 就mqtt_network_close == 全部关闭
GMQTT_CONNECT_MQTT
mqtt_login_info(&connectData); 把数据打包在结构体
mqtt_connect_server(&client, &connectData))
int mqtt_connect_server(mqttClientType* c, MQTTPacket_connectData* options)
{
mqttConnackDataType data;
return mqtt_connect_with_results(c, options, &data);
}
比较复杂 是TX在RX的函数
GMQTT_SUBSCRIBE
mqtt_subscribe(&client, ( uint8_t *)topicPath[i] , QOS2, mqtt_message_arrived);//函数 RX怎么办
也即是定下 以后函数都在这里RX 它把数据放到队列 给RX任务处理
GMQTT_DEVINFO
GMQTT_VER
GMQTT_ALIEVE
GMQTT_FILTER
GMQTT_OK
int mqtt_run( mqttClientType* c )
rt = mqtt_cycle(c) ;
也就是最后死循环这个函数mqtt_cycle 如果离线 会自动复位模块的