DefenderStatus_t Defender_GetTopic()

in source/defender.c [381:459]


DefenderStatus_t Defender_GetTopic( char * pBuffer,
                                    uint16_t bufferLength,
                                    const char * pThingName,
                                    uint16_t thingNameLength,
                                    DefenderTopic_t api,
                                    uint16_t * pOutLength )
{
    DefenderStatus_t ret = DefenderSuccess;
    uint16_t topicLength = 0U, offset = 0U;

    /* The following variables are to address MISRA Rule 7.4 violation of
     * passing const char * for const void * param of memcpy. */
    const char * pDefenderApiPrefix = DEFENDER_API_PREFIX;
    const char * pDefenderApiBridge = DEFENDER_API_BRIDGE;

    if( ( pBuffer == NULL ) ||
        ( pThingName == NULL ) ||
        ( thingNameLength == 0U ) || ( thingNameLength > DEFENDER_THINGNAME_MAX_LENGTH ) ||
        ( api <= DefenderInvalidTopic ) || ( api >= DefenderMaxTopic ) ||
        ( pOutLength == NULL ) )
    {
        ret = DefenderBadParameter;

        LogError( ( "Invalid input parameter. pBuffer: %p, bufferLength: %u, "
                    "pThingName: %p, thingNameLength: %u, api: %d, pOutLength: %p.",
                    ( void * ) pBuffer,
                    ( unsigned int ) bufferLength,
                    ( void * ) pThingName,
                    ( unsigned int ) thingNameLength,
                    api,
                    ( void * ) pOutLength ) );
    }

    if( ret == DefenderSuccess )
    {
        topicLength = getTopicLength( thingNameLength, api );

        if( bufferLength < topicLength )
        {
            ret = DefenderBufferTooSmall;

            LogError( ( "The buffer is too small to hold the topic string. "
                        "Provided buffer size: %u, Required buffer size: %u.",
                        ( unsigned int ) bufferLength,
                        ( unsigned int ) topicLength ) );
        }
    }

    if( ret == DefenderSuccess )
    {
        /* At this point, it is certain that we have a large enough buffer to
         * write the topic string into. */

        /* Write prefix first. */
        ( void ) memcpy( ( void * ) &( pBuffer[ offset ] ),
                         ( const void * ) pDefenderApiPrefix,
                         ( size_t ) DEFENDER_API_LENGTH_PREFIX );
        offset += DEFENDER_API_LENGTH_PREFIX;

        /* Write thing name next. */
        ( void ) memcpy( ( void * ) &( pBuffer[ offset ] ),
                         ( const void * ) pThingName,
                         ( size_t ) thingNameLength );
        offset += thingNameLength;

        /* Write bridge next. */
        ( void ) memcpy( ( void * ) &( pBuffer[ offset ] ),
                         ( const void * ) pDefenderApiBridge,
                         ( size_t ) DEFENDER_API_LENGTH_BRIDGE );
        offset += DEFENDER_API_LENGTH_BRIDGE;

        /* Write report format and suffix. */
        writeFormatAndSuffix( &( pBuffer[ offset ] ), api );

        *pOutLength = topicLength;
    }

    return ret;
}