硬件方面初始化完毕,进入MQTT_Loop函数,开始进行MQTT的一系列操作。
进入以后,MqttSample_Init(smpctx)初始化MQTT,就是配置一系列的设备ID,产品ID等等。
然后通过Mqtt_InitContext(ctx->mqttctx, 1 << 8);初始化一个8字节的上下文变量,设置了首地址,尾地址等等。进而进行回调函数的初始化。
但是,对于回调函数的初始化中,每一个函数名都还跟了一个“回调函数的关联参数”,目前不懂这个是什么意思。例如:
[cce_cpp]
ctx->mqttctx->read_func = MqttSample_RecvPkt;
ctx->mqttctx->writev_func = MqttSample_SendPkt;
ctx->mqttctx->handle_conn_ack = MqttSample_HandleConnAck;
ctx->mqttctx->handle_conn_ack_arg = ctx;//不知道什么意思
ctx->mqttctx->handle_ping_resp = MqttSample_HandlePingResp;
ctx->mqttctx->handle_ping_resp_arg = ctx;
[/cce_cpp]
然后通过MqttBuffer_Init(ctx->mqttbuf);初始化缓冲器变量。
至此,MQTT初始化完毕,开始MQTT的连接。进入MqttSample_CmdConnect函数。
/**
* @brief 发送MQTT Connet报文,登录鉴权
* @param ctx:上下文变量
* @retval ret:0,成功,<0 失败
**/
static int MqttSample_CmdConnect(struct MqttSampleContext *ctx)
首先,打包一个MQTT连接报文,对比分析调用函数和函数原型。
Mqtt_PackConnectPkt(ctx->mqttbuf, 0, ctx->devid, 1, MQTT_DEVICE_PROJ_ID,
MQTT_DEVICE_AUTH_INFO, strlen(MQTT_DEVICE_AUTH_INFO), MQTT_QOS_LEVEL0, 0, ctx->proid,
ctx->apikey, strlen(ctx->apikey));
[cce_cpp] payload = MqttBuffer_AllocExtent(buf, total_len - 10);//可变报头的长度初始值赋值为10,此处再减去10 fix_head->payload[0] = MQTT_PKT_CONNECT << 4; ret = Mqtt_DumpLength(total_len, fix_head->payload + 1); if(ret < 0) { return MQTTERR_PKT_TOO_LARGE; } fix_head->len = ret + 1; // ajust the length of the extent variable_head->payload[0] = 0; variable_head->payload[1] = 4; variable_head->payload[2] = 'M'; variable_head->payload[3] = 'Q'; variable_head->payload[4] = 'T'; variable_head->payload[5] = 'T'; variable_head->payload[6] = 4; // protocol level 4 variable_head->payload[7] = flags; Mqtt_WB16(keep_alive, variable_head->payload + 8); [/cce_cpp] 将ID复制到有效载荷中,再依次写入各种变量。不再一一列举。
[cce_cpp] cursor = payload->payload; Mqtt_PktWriteString(&cursor, id, id_len); [/cce_cpp]
[cce_cpp] MqttBuffer_AppendExtent(buf, fix_head); MqttBuffer_AppendExtent(buf, variable_head); MqttBuffer_AppendExtent(buf, payload); [/cce_cpp]
然后执行Mqtt_SendPkt(ctx->mqttctx, ctx->mqttbuf, 0);