static MQTTStatus_t createCommand()

in source/core_mqtt_agent.c [417:504]


static MQTTStatus_t createCommand( MQTTAgentCommandType_t commandType,
                                   const MQTTAgentContext_t * pMqttAgentContext,
                                   void * pMqttInfoParam,
                                   MQTTAgentCommandCallback_t commandCompleteCallback,
                                   MQTTAgentCommandContext_t * pCommandCompleteCallbackContext,
                                   MQTTAgentCommand_t * pCommand )
{
    bool isValid, isSpace = true;
    MQTTStatus_t statusReturn;
    const MQTTPublishInfo_t * pPublishInfo;
    size_t uxHeaderBytes;
    const size_t uxControlAndLengthBytes = ( size_t ) 4; /* Control, remaining length and length bytes. */

    assert( pMqttAgentContext != NULL );
    assert( pCommand != NULL );

    ( void ) memset( pCommand, 0x00, sizeof( MQTTAgentCommand_t ) );

    /* Determine if required parameters are present in context. */
    switch( commandType )
    {
        case SUBSCRIBE:
        case UNSUBSCRIBE:
            assert( pMqttInfoParam != NULL );

            /* This message type results in the broker returning an ACK.  The
             * agent maintains an array of outstanding ACK messages.  See if
             * the array contains space for another outstanding ack. */
            isSpace = isSpaceInPendingAckList( pMqttAgentContext );

            isValid = isSpace;

            break;

        case PUBLISH:
            pPublishInfo = ( const MQTTPublishInfo_t * ) pMqttInfoParam;

            /* Calculate the space consumed by everything other than the
             * payload. */
            uxHeaderBytes = uxControlAndLengthBytes;
            uxHeaderBytes += pPublishInfo->topicNameLength;

            /* This message type results in the broker returning an ACK. The
             * agent maintains an array of outstanding ACK messages.  See if
             * the array contains space for another outstanding ack.  QoS0
             * publish does not result in an ack so it doesn't matter if
             * there is no space in the ACK array. */
            if( pPublishInfo->qos != MQTTQoS0 )
            {
                isSpace = isSpaceInPendingAckList( pMqttAgentContext );
            }

            /* Will the message fit in the defined buffer? */
            isValid = ( uxHeaderBytes < pMqttAgentContext->mqttContext.networkBuffer.size ) &&
                      ( isSpace == true );

            break;

        case PROCESSLOOP:
        case PING:
        case CONNECT:
        case DISCONNECT:
        default:
            /* Other operations don't need to store ACKs. */
            isValid = true;
            break;
    }

    if( isValid )
    {
        pCommand->commandType = commandType;
        pCommand->pArgs = pMqttInfoParam;
        pCommand->pCmdContext = pCommandCompleteCallbackContext;
        pCommand->pCommandCompleteCallback = commandCompleteCallback;
    }

    statusReturn = ( isValid ) ? MQTTSuccess : MQTTBadParameter;

    if( ( statusReturn == MQTTBadParameter ) && ( isSpace == false ) )
    {
        /* The error was caused not by a bad parameter, but because there was
         * no room in the pending Ack list for the Ack response to an outgoing
         * PUBLISH or SUBSCRIBE message. */
        statusReturn = MQTTNoMemory;
    }

    return statusReturn;
}