读代码-对接MQTT移植

如何抑制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 如果离线 会自动复位模块的

 

你可能感兴趣的:(读代码-对接MQTT移植)