我需要通过MQTT将自定义硬件设备连接到Azure IoT中心。我正在使用由Microchip PIC24F微控制器通过UART控制的SIMCOM 5300E GPRS模块。
对于最初的原型,我能够连接到标准的MQTT经纪人,如Mosquito和CloudMQTT。我编写了自定义C库来构建“连接”,“订阅”和“发布”命令。这通过TCP / IP连接完美地工作。
我创建了一个Azure IoT集线器并创建了一个设备。使用设备管理器成功生成了SAS令牌。我能够向MQTTbox发送和接收消息。所以我知道集线器,设备和SAS令牌都正常工作。由于我们创建的设备适用于批量市场,因此硬件限制为16位微控制器,因此无法使用Azure IoT SDK。我遵循这里的建议“直接使用MQTT协议”
https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support#using-the-mqtt-protocol-directly
我正在使用AT命令打开与服务器的连接。
AT+CIICR
(成功连接)
AT+CIFSR
(我获得了本地IP)
AT+CIPSSL=1
(启用SIM5300E SSL功能,但我不确定这是如何工作的,也不确定它使用的证书。)
AT+CIPSTART="TCP","xxxxxxxxxx.azure-devices.net","8883"
(其中xxxxxxxxxx是我的中心名称。我得到“连接好”)
AT+CIPSEND
(服务器返回“>”提示符)
此时我发送了“Connect Packet”,然后是CTRL-Z。我收到“发送确定”,但没有响应,服务器关闭连接。如果我发送类似“PING”的内容,我得不到任何响应,但服务器通常不会关闭连接。
我用来生成字符串的代码是:
const char MQTTProtocolName[10] = "MQTT";
const char MQTTLVL = 0x04;
const char MQTTFlags = 0xC2;
const char MQTTUsername[100] = "xxxxxxxxxxxxx.azure-
devices.net/LumenTest002/api-version=2016-11-14";
const char MQTTPassword[200] = "SharedAccessSignature srxxxxxMYSASxxxxx";
const char MQTTQOS = 0x00;
void connect_MQTT(void)
{
//Calculate MQTT Lengths
MQTTProtocolNameLength = strlen(MQTTProtocolName);
MQTTClientIDLength = strlen(MQTTClientID);
MQTTUsernameLength = strlen(MQTTUsername);
MQTTPasswordLength = strlen(MQTTPassword);
datalength = MQTTProtocolNameLength + 2 + 4 + MQTTClientIDLength + 2 +
MQTTUsernameLength + 2 + MQTTPasswordLength + 2;
//Get Prompt
__delay_ms(100);
putsU2("AT+CIPSEND"); //Send the command to 5300E
__delay_ms(3000);
//Send Byte - Declare as connect
putU2(0x10); //0x10 = Fixed value determined by MQTT Standard
//Send Byte - remaining Length
putU2(datalength & 0xFF);
//Send 2 Bytes - Protocol Length
putU2(MQTTProtocolNameLength >> 8);
putU2(MQTTProtocolNameLength & 0xFF);
//Send Bytes - Protocol Name
for (Counter = 0; Counter < MQTTProtocolNameLength; Counter++)
{
putU2(MQTTProtocolName[Counter]);
}
//Send Byte - Level
putU2(MQTTLVL);
//Send Byte - Flags
putU2(MQTTFlags);
//Send 2 Bytes - Keep Alive
putU2(MQTTKeepAlive >> 8);
putU2(MQTTKeepAlive & 0xFF);
//Send 2 Bytes - Client ID Length
putU2(MQTTClientIDLength >> 8);
putU2(MQTTClientIDLength & 0xFF);
//Send Bytes - (MQTTClientID);
for (Counter = 0; Counter < MQTTClientIDLength; Counter++)
{
putU2(MQTTClientID[Counter]);
}
//Send 2 Bytes - MQTTUsernameLength
putU2(MQTTUsernameLength >> 8);
putU2(MQTTUsernameLength & 0xFF);
// Send Bytes -(MQTTUsername);
for (Counter = 0; Counter < MQTTUsernameLength; Counter++)
{
putU2(MQTTUsername[Counter]);
}
//Send 2 Bytes - MQTTPasswordLength
putU2(MQTTPasswordLength >> 8);
putU2(MQTTPasswordLength & 0xFF);
// Send Bytes - MQTTPassword
for (Counter = 0; Counter < MQTTPasswordLength; Counter++)
{
putU2(MQTTPassword[Counter]);
}
//Send Byte - CTRL-Z
putU2(0x1A);
}
使用“AT + CIPACK”我收到响应“+ CIPACK 130,130,0”,表示服务器已收到130个字节,但我没有回应。
所以我有两个问题:
是否通过SSL正确打开了连接?
我认为我不会得到“Connect OK”或“&gt;”如果不是则提示。
我的MQTT“Connect”数据包是否构造正确?
它使用相同的Oasis MQTT标准版V3.1.1,适用于我尝试过的所有其他代理。我假设“MQTTProtocolName”只是“MQTT”,因为我找不到其它的引用。我按照上面链接中的说明制作了“用户名”和“密码”。 SAS令牌当前有效。