LONGBOW_TEST_CASE(ContentObject, PayloadType)
{
    // The payload type is translated from the wire format value to the CCNxPayloadType value,
    // so this test cannot use the automated framework as the value in the dictionary will not
    // be the same as the value in the wire format

    TestData *data = longBowTestCase_GetClipBoardData(testCase);

    bool decodeSuccess = ccnxCodecSchemaV1MessageDecoder_Decode(data->decoder, data->dictionary);
    assertTrue(decodeSuccess, "failure on ccnxCodecSchemaV1MessageDecoder_Decode");

    CCNxPayloadType testPayloadType = (CCNxPayloadType) _getPayloadType(data->dictionary);

    // look up the true name buffer from the truth table
    TlvExtent extent = getTruthTableExtent(data->truthTable, V1_MANIFEST_OBJ_PAYLOADTYPE);

    PARCBuffer
        *truthbuffer = parcBuffer_Wrap(data->packet, data->packetLength, extent.offset, extent.offset + extent.length);
    uint64_t truthvalue = -2;
    ccnxCodecTlvUtilities_GetVarInt(truthbuffer, parcBuffer_Remaining(truthbuffer), &truthvalue);

    CCNxPayloadType truthPayloadType = -1;
    bool success =
        _translateWirePayloadTypeToCCNxPayloadType((CCNxCodecSchemaV1Types_PayloadType) truthvalue, &truthPayloadType);
    assertTrue(success, "failure in _translateWirePayloadTypeToCCNxPayloadType for wireFormatValue %"
        PRId64, truthvalue);

    parcBuffer_Release(&truthbuffer);

    assertTrue(truthPayloadType == testPayloadType, "Wrong value, got %d expected %d", testPayloadType,
               truthPayloadType);
}
/**
 * Decodes the CCNx message inside a TLV packet
 *
 * Creates an inner decoder that slices the decode buffer then passes that and our
 * message dictionary to the appropriate inner decoder.
 *
 * @param [in] data The packet decoder state
 *
 * @return true successful decode
 * @return false A decoding error
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
static bool
_decodeMessage(_CCNxCodecSchemaV1Data *data)
{
    bool success = false;

    if (ccnxCodecTlvDecoder_EnsureRemaining(data->decoder, 4)) {
        // what kind of message are we looking at?
        // Note that this is based on the TLV container, not the fixed head PacketType
        uint16_t tlv_type = ccnxCodecTlvDecoder_GetType(data->decoder);
        uint16_t tlv_length = ccnxCodecTlvDecoder_GetLength(data->decoder);

        // ensure its a proper tlv type
        switch (tlv_type) {
            case CCNxCodecSchemaV1Types_MessageType_Interest: // fallthrough
            case CCNxCodecSchemaV1Types_MessageType_ContentObject: // fallthrough
            case CCNxCodecSchemaV1Types_MessageType_Control: // fallthrough
                break;

            default:
                return false;
        }

        // cross check with the fixed header value
        // ccnxCodecSchemaV1FixedHeaderDecoder_Decode ensures that PacketLength is not less than HeaderLength
        size_t messageLength = ccnxCodecSchemaV1FixedHeaderDecoder_GetPacketLength(data->packetDictionary) - ccnxCodecSchemaV1FixedHeaderDecoder_GetHeaderLength(data->packetDictionary);

        if (tlv_length <= messageLength && ccnxCodecTlvDecoder_EnsureRemaining(data->decoder, tlv_length)) {
            // This decode is for the "value" of the message, it does not include the wrapper
            CCNxCodecTlvDecoder *messageDecoder = ccnxCodecTlvDecoder_GetContainer(data->decoder, tlv_length);

            if (tlv_type == CCNxCodecSchemaV1Types_MessageType_Control) {
                // the CPI messages are not a proper "message" in that there's no inner TLV, its just data
                success = _decodeCPI(messageDecoder, data->packetDictionary);
            } else {
                success = ccnxCodecSchemaV1MessageDecoder_Decode(messageDecoder, data->packetDictionary);
            }

            ccnxCodecTlvDecoder_Destroy(&messageDecoder);
        } else {
            // raise an error
            CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_TOO_LONG, __func__, __LINE__, ccnxCodecTlvDecoder_Position(data->decoder));
            ccnxCodecTlvDecoder_SetError(data->decoder, error);
            ccnxCodecError_Release(&error);
        }
    }

    return success;
}