ShadowStatus_t Shadow_MatchTopicString()

in source/shadow.c [764:869]


ShadowStatus_t Shadow_MatchTopicString( const char * pTopic,
                                        uint16_t topicLength,
                                        ShadowMessageType_t * pMessageType,
                                        const char ** pThingName,
                                        uint8_t * pThingNameLength,
                                        const char ** pShadowName,
                                        uint8_t * pShadowNameLength )
{
    uint16_t consumedTopicLength = 0U;
    ShadowStatus_t shadowStatus = SHADOW_SUCCESS;
    uint8_t thingNameLength = 0;
    uint8_t shadowNameLength = 0;

    shadowStatus = validateMatchTopicParameters( pTopic, topicLength, pMessageType );

    /* A shadow topic string takes one of the two forms.
     * Classic shadow:
     *   $aws/things/<thingName>/shadow/<operation>
     *   $aws/things/<thingName>/shadow/<operation>/<suffix>
     * Named shadow:
     *   $aws/things/<thingName>/shadow/name/<shadowName>/<operation>
     *   $aws/things/<thingName>/shadow/name/<shadowName>/<operation>/<suffix>
     *
     * We need to match the following things:
     * 1. Prefix ($aws/things).
     * 2. Thing Name.
     * 3. Classic shadow root (/shadow) OR Named shadow root (/shadow/name) and shadow name
     * 4. Shadow operation and suffix.
     */
    if( shadowStatus == SHADOW_SUCCESS )
    {
        /* First match the prefix. */
        shadowStatus = containsSubString( &( pTopic[ consumedTopicLength ] ),
                                          topicLength - consumedTopicLength,
                                          SHADOW_PREFIX,
                                          SHADOW_PREFIX_LENGTH );

        if( shadowStatus == SHADOW_SUCCESS )
        {
            consumedTopicLength += SHADOW_PREFIX_LENGTH;
        }
        else
        {
            LogDebug( ( "Not a Shadow topic. Failed to parse shadow topic prefix in pTopic %.*s", topicLength, pTopic ) );
        }
    }

    if( shadowStatus == SHADOW_SUCCESS )
    {
        /* Extract thing name. */
        shadowStatus = extractThingName( pTopic,
                                         topicLength,
                                         &consumedTopicLength,
                                         &thingNameLength );
    }

    if( shadowStatus == SHADOW_SUCCESS )
    {
        shadowStatus = extractShadowRootAndName( pTopic,
                                                 topicLength,
                                                 &consumedTopicLength,
                                                 &shadowNameLength );
    }

    if( shadowStatus == SHADOW_SUCCESS )
    {
        /* Extract shadow message type. */
        shadowStatus = extractShadowMessageType( &( pTopic[ consumedTopicLength ] ),
                                                 topicLength - consumedTopicLength,
                                                 pMessageType );

        if( shadowStatus != SHADOW_SUCCESS )
        {
            shadowStatus = SHADOW_MESSAGE_TYPE_PARSE_FAILED;
            LogDebug( ( "Not a Shadow topic. Shadow message type is not in pTopic %.*s, failed to parse shadow message type.", topicLength, pTopic ) );
        }
    }

    if( shadowStatus == SHADOW_SUCCESS )
    {
        /* Update the out parameters if we successfully matched the topic. */
        if( pThingName != NULL )
        {
            /* Thing name comes after shadow prefix. */
            *pThingName = &( pTopic[ SHADOW_PREFIX_LENGTH ] );
        }

        if( pThingNameLength != NULL )
        {
            *pThingNameLength = thingNameLength;
        }

        if( pShadowName != NULL )
        {
            *pShadowName = &( pTopic[ SHADOW_PREFIX_LENGTH + thingNameLength +
                                      SHADOW_NAMED_ROOT_LENGTH ] );
        }

        if( pShadowNameLength != NULL )
        {
            *pShadowNameLength = shadowNameLength;
        }
    }

    return shadowStatus;
}