Question

patrickm77 on Sat, 14 Apr 2018 17:39:18


I need to connect a custom hardware device to Azure IoT hub via MQTT. I am using a SIMCOM 5300E GPRS module controlled by a Microchip PIC24F micro controller via the UART.

For the initial prototype I was able to connect to standard MQTT brokers like Mosquito and CloudMQTT. I wrote the custom C libraries to construct the "Connect", "Subscribe" and "Publish" commands. This worked perfectly via a TCP/IP connection.

I made an Azure IoT hub and created a device. The SAS token was successfully generated using device manager. I am able to send and receive messages to MQTTbox. So I know the hub, device and SAS token are all working correctly. Because the device we are creating is intended for a volume market I am limited in hardware to a 16 bit micro controller and therefore unable use the Azure IoT SDKs. I am following the advice here "Using the MQTT Protocol Directly"

https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support#using-the-mqtt-protocol-directly

I'm using AT commands to open a connection to the server.

AT+CIICR  (connects successfully)

AT+CIFSR (I get a local IP)

AT+CIPSSL=1 (Enables the SIM5300E SSL function, though I'm not sure how this works or what certificate it uses.)

AT+CIPSTART="TCP","xxxxxxxxxx.azure-devices.net","8883" (Where xxxxxxxxxx is my hub name. I get "Connect OK)

AT+CIPSEND (The server returns the ">" prompt)

At this point I sent the "Connect Packet" followed by the CTRL-Z. I get "Send OK" but there is no response and the server closes the connection. If I send something like "PING" I get no response but the server does not usually close the connection.

The code I use to generate the string is :


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 sr=xxxxxxxxx.azure-devices.net&sig=b%2BpxxxxxxxxxxxxxxxxxxxxxxWWgnIg5pu%2B01LdINc%3D&se=1555142502&skn=iothubowner";
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); 
    }

Using the "AT+CIPACK" I receive the response "+CIPACK 130,130,0" which indicates that 130 bytes have been received by the server but I have no response.

So I have two questions :

(1) Is the connection correctly opened over SSL? I assume I would not get the "Connect OK" or the ">" prompt if it were not.

(2) Is my MQTT "Connect" packet constructed correctly? It uses the same Oasis MQTT Standard V3.1.1 and works on all other brokers I have tried. i assume the "MQTTProtocolName" is simply "MQTT" as I could find no other reference to it. I  made the "Username" and "Password" as instructed in the link above. The SAS token is currently valid.



Sponsored



Replies

Rita Han on Mon, 16 Apr 2018 09:48:50


Hello patrickm77,

Have you added certificate that Azure uses to secure the connection like described in TLS/SSL configuration section?

Best regards,

Rita


MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


patrickm77 on Fri, 20 Apr 2018 09:19:45


Hi,

I have confirmed the 5300E has SSL over TCP. The problem was in the construction of the hex packets which is extremely specific but I have it working now. Thank you.