static int constructConnPayload()

in src/mqtt_codec.c [379:513]


static int constructConnPayload(BUFFER_HANDLE ctrlPacket, const MQTT_CLIENT_OPTIONS* mqttOptions, STRING_HANDLE trace_log)
{
    int result = 0;
    size_t clientLen = 0;
    size_t usernameLen = 0;
    size_t passwordLen = 0;
    size_t willMessageLen = 0;
    size_t willTopicLen = 0;
    size_t spaceLen = 0;
    size_t currLen = 0;
    size_t totalLen = 0;

    if (mqttOptions->clientId != NULL)
    {
        spaceLen += 2;
        clientLen = strlen(mqttOptions->clientId);
    }
    if (mqttOptions->username != NULL)
    {
        spaceLen += 2;
        usernameLen = strlen(mqttOptions->username);
    }
    if (mqttOptions->password != NULL)
    {
        spaceLen += 2;
        passwordLen = strlen(mqttOptions->password);
    }
    if (mqttOptions->willMessage != NULL)
    {
        spaceLen += 2;
        willMessageLen = strlen(mqttOptions->willMessage);
    }
    if (mqttOptions->willTopic != NULL)
    {
        spaceLen += 2;
        willTopicLen = strlen(mqttOptions->willTopic);
    }

    currLen = ctrlPacket == NULL ? 0 : BUFFER_length(ctrlPacket);
    totalLen = clientLen + usernameLen + passwordLen + willMessageLen + willTopicLen + spaceLen;

    if (ctrlPacket == NULL)
    {
        result = MU_FAILURE;
    }
    // Validate the Username & Password
    else if (clientLen > USHRT_MAX)
    {
        result = MU_FAILURE;
    }
    else if (usernameLen == 0 && passwordLen > 0)
    {
        result = MU_FAILURE;
    }
    else if ((willMessageLen > 0 && willTopicLen == 0) || (willTopicLen > 0 && willMessageLen == 0))
    {
        result = MU_FAILURE;
    }
    else if (BUFFER_enlarge(ctrlPacket, totalLen) != 0)
    {
        result = MU_FAILURE;
    }
    else
    {
        uint8_t* packet = BUFFER_u_char(ctrlPacket);
        uint8_t* iterator = packet;

        iterator += currLen;
        byteutil_writeUTF(&iterator, mqttOptions->clientId, (uint16_t)clientLen);

        // TODO: Read on the Will Topic
        if (willMessageLen > USHRT_MAX || willTopicLen > USHRT_MAX || usernameLen > USHRT_MAX || passwordLen > USHRT_MAX)
        {
            result = MU_FAILURE;
        }
        else
        {
            STRING_HANDLE connect_payload_trace = NULL;
            if (trace_log != NULL)
            {
                connect_payload_trace = STRING_new();
            }
            if (willMessageLen > 0 && willTopicLen > 0)
            {
                if (trace_log != NULL)
                {
                    (void)STRING_sprintf(connect_payload_trace, " | WILL_TOPIC: %s", mqttOptions->willTopic);
                }
                packet[CONN_FLAG_BYTE_OFFSET] |= WILL_FLAG_FLAG;
                byteutil_writeUTF(&iterator, mqttOptions->willTopic, (uint16_t)willTopicLen);
                packet[CONN_FLAG_BYTE_OFFSET] |= (mqttOptions->qualityOfServiceValue << 3);
                if (mqttOptions->messageRetain)
                {
                    packet[CONN_FLAG_BYTE_OFFSET] |= WILL_RETAIN_FLAG;
                }
                byteutil_writeUTF(&iterator, mqttOptions->willMessage, (uint16_t)willMessageLen);
            }
            if (usernameLen > 0)
            {
                packet[CONN_FLAG_BYTE_OFFSET] |= USERNAME_FLAG;
                byteutil_writeUTF(&iterator, mqttOptions->username, (uint16_t)usernameLen);
                if (trace_log != NULL)
                {
                    (void)STRING_sprintf(connect_payload_trace, " | USERNAME: %s", mqttOptions->username);
                }
            }
            if (passwordLen > 0)
            {
                packet[CONN_FLAG_BYTE_OFFSET] |= PASSWORD_FLAG;
                byteutil_writeUTF(&iterator, mqttOptions->password, (uint16_t)passwordLen);
                if (trace_log != NULL)
                {
                    (void)STRING_sprintf(connect_payload_trace, " | PWD: XXXX");
                }
            }
            // TODO: Get the rest of the flags
            if (trace_log != NULL)
            {
                (void)STRING_sprintf(connect_payload_trace, " | CLEAN: %s", mqttOptions->useCleanSession ? "1" : "0");
            }
            if (mqttOptions->useCleanSession)
            {
                packet[CONN_FLAG_BYTE_OFFSET] |= CLEAN_SESSION_FLAG;
            }
            if (trace_log != NULL)
            {
                (void)STRING_sprintf(trace_log, " %lu", packet[CONN_FLAG_BYTE_OFFSET]);
                (void)STRING_concat_with_STRING(trace_log, connect_payload_trace);
                STRING_delete(connect_payload_trace);
            }
            result = 0;
        }
    }
    return result;
}