PARCJSON * ccnxManifestHashGroup_ToJson(const CCNxManifestHashGroup *group) { PARCJSON *root = parcJSON_Create(); PARCJSONArray *ptrList = parcJSONArray_Create(); for (size_t i = 0; i < parcLinkedList_Size(group->pointers); i++) { CCNxManifestHashGroupPointer *ptr = (CCNxManifestHashGroupPointer *) parcLinkedList_GetAtIndex(group->pointers, i); PARCJSON *ptrJson = parcJSON_Create(); // Type. parcJSON_AddInteger(ptrJson, "type", ccnxManifestHashGroupPointer_GetType(ptr)); // Digest. char *digestString = parcBuffer_ToHexString(ptr->digest); parcJSON_AddString(ptrJson, "digest", digestString); parcMemory_Deallocate(&digestString); // Add the tuple to the list. PARCJSONValue *val = parcJSONValue_CreateFromJSON(ptrJson); parcJSONArray_AddValue(ptrList, val); // Cleanup parcJSONValue_Release(&val); parcJSON_Release(&ptrJson); } root = parcJSON_AddArray(root, "HashGroup", ptrList); parcJSONArray_Release(&ptrList); if (group->overallDataDigest != NULL) { char *digestString = parcBuffer_ToHexString(group->overallDataDigest); root = parcJSON_AddString(root, "overallDataDigest", digestString); parcMemory_Deallocate((void **) &digestString); } if (group->locator != NULL) { char *locatorString = ccnxName_ToString(group->locator); root = parcJSON_AddString(root, "locator", locatorString); parcMemory_Deallocate((void **) &locatorString); } if (group->entrySize > 0) { root = parcJSON_AddInteger(root, "entrySize", group->entrySize); } if (group->dataSize > 0) { root = parcJSON_AddInteger(root, "dataSize", group->dataSize); } if (group->blockSize > 0) { root = parcJSON_AddInteger(root, "blockSize", group->blockSize); } if (group->treeHeight > 0) { root = parcJSON_AddInteger(root, "treeHeight", group->treeHeight); } return root; }
MetisGenericEther * metisGenericEther_Create(MetisForwarder *metis, const char *deviceName, uint16_t etherType) { assertNotNull(metis, "Parameter metis must be non-null"); // The Darwin generic ether allows a NULL device name, it is used in the unit tests. MetisGenericEther *ether = NULL; if (metisEthernet_IsValidEthertype(etherType)) { ether = parcObject_CreateInstance(MetisGenericEther); ether->ethertype = etherType; ether->logger = metisLogger_Acquire(metisForwarder_GetLogger(metis)); ether->etherSocket = -1; // invalid valid ether->workBuffer = parcEventBuffer_Create(); ether->macAddress = NULL; ether->mtu = metisSystem_InterfaceMtu(metis, deviceName); _darwinEthernet_SetInterfaceAddress(ether, deviceName); bool success = _darwinEthernet_SetupReceive(ether, deviceName); if (success) { if (metisLogger_IsLoggable(ether->logger, MetisLoggerFacility_IO, PARCLogLevel_Info)) { char *str = parcBuffer_ToHexString(ether->macAddress); metisLogger_Log(ether->logger, MetisLoggerFacility_IO, PARCLogLevel_Info, __func__, "GenericEther %p created on device %s (%s) for ethertype 0x%04x fd %d bufferLength %u mtu %u", (void *) ether, deviceName, str, etherType, ether->etherSocket, ether->etherBufferLength, ether->mtu); parcMemory_Deallocate((void **) &str); } } else { if (metisLogger_IsLoggable(ether->logger, MetisLoggerFacility_IO, PARCLogLevel_Error)) { metisLogger_Log(ether->logger, MetisLoggerFacility_IO, PARCLogLevel_Error, __func__, "GenericEther failed to created on device %s for ethertype 0x%04x", deviceName, etherType); } // this will also null ether metisGenericEther_Release(ðer); } assertTrue(ether->etherBufferLength < 65536, "Buffer length way too big, expected less than 65536 got %u", ether->etherBufferLength); } else { if (metisLogger_IsLoggable(metisForwarder_GetLogger(metis), MetisLoggerFacility_IO, PARCLogLevel_Error)) { metisLogger_Log(metisForwarder_GetLogger(metis), MetisLoggerFacility_IO, PARCLogLevel_Error, __func__, "GenericEther failed to created on device %s for ethertype 0x%04x, invalid ethertype", deviceName, etherType); } } return ether; }
LONGBOW_TEST_CASE(Global, ccnxCodecSchemaV1ManifestDecoder_DecodeHashGroupMetadata) { // Re-build the expected metadata from the manifest CCNxName *groupLocator = ccnxName_CreateFromCString("ccnx:/locator"); PARCBuffer *digest = parcBuffer_Allocate(16); for (size_t i = 0; i < parcBuffer_Limit(digest); i++) { parcBuffer_PutUint8(digest, 0); } parcBuffer_Flip(digest); size_t entrySize = 1; size_t dataSize = 2; size_t blockSize = 3; size_t treeHeight = 4; // Compute the expected size of this metadata group. size_t metadataSize = 4 * (4 + 8) + 4 + parcBuffer_Limit(digest) + 4 + strlen("ccnx:/locator"); // See test_ccnxCodecSchemaV1_ManifestEncoder.c for the packet construction details. uint8_t rawMetadata[89] = { 0x00, CCNxCodecSchemaV1Types_CCNxManifestHashGroup_Metadata, 0x00, metadataSize, 0x00, CCNxCodecSchemaV1Types_CCNxManifestHashGroupMetadata_Locator, 0x00, strlen("ccnx:/locator"), 'c', 'c', 'n', 'x', ':', '/', 'l', 'o', 'c', 'a', 't', 'o', 'r', 0x00, CCNxCodecSchemaV1Types_CCNxManifestHashGroupMetadata_DataSize, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, dataSize, 0x00, CCNxCodecSchemaV1Types_CCNxManifestHashGroupMetadata_BlockSize, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, blockSize, 0x00, CCNxCodecSchemaV1Types_CCNxManifestHashGroupMetadata_EntrySize, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, entrySize, 0x00, CCNxCodecSchemaV1Types_CCNxManifestHashGroupMetadata_TreeHeight, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, treeHeight, 0x00, CCNxCodecSchemaV1Types_CCNxManifestHashGroupMetadata_OverallDataSha256, 0x00, parcBuffer_Remaining(digest), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; PARCBuffer *wireFormat = parcBuffer_Flip(parcBuffer_CreateFromArray(rawMetadata, sizeof(rawMetadata))); // Create the encoder and swallow the top level container CCNxCodecTlvDecoder *decoder = ccnxCodecTlvDecoder_Create(wireFormat); ccnxCodecTlvDecoder_GetType(decoder); // swallow type uint16_t length = ccnxCodecTlvDecoder_GetLength(decoder); // Decode the metadata CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create(); bool result = _decodeHashGroupMetadata(decoder, group, length); assertTrue(result, "Expected hash group metadata to be decoded correctly."); const CCNxName *actualLocator = ccnxManifestHashGroup_GetLocator(group); size_t actualEntrySize = ccnxManifestHashGroup_GetEntrySize(group); size_t actualDataSize = ccnxManifestHashGroup_GetDataSize(group); size_t actualBlockSize = ccnxManifestHashGroup_GetBlockSize(group); size_t actualTreeHeight = ccnxManifestHashGroup_GetTreeHeight(group); const PARCBuffer *actualDigest = ccnxManifestHashGroup_GetOverallDataDigest(group); assertTrue(ccnxName_Equals(groupLocator, actualLocator), "Expected decoded locator to equal %s, got %s", ccnxName_ToString(groupLocator), ccnxName_ToString(actualLocator)); assertTrue(entrySize == actualEntrySize, "Expected %zu entry size, got %zu", entrySize, actualEntrySize); assertTrue(dataSize == actualDataSize, "Expected %zu data size, got %zu", dataSize, actualDataSize); assertTrue(blockSize == actualBlockSize, "Expected %zu block size, got %zu", blockSize, actualBlockSize); assertTrue(treeHeight == actualTreeHeight, "Expected %zu tree height, got %zu", treeHeight, actualTreeHeight); assertTrue(parcBuffer_Equals(digest, actualDigest), "Expected %s digest, got %s", parcBuffer_ToHexString(digest), parcBuffer_ToHexString(actualDigest)); parcBuffer_Release(&digest); ccnxName_Release(&groupLocator); ccnxManifestHashGroup_Release(&group); ccnxCodecTlvDecoder_Destroy(&decoder); parcBuffer_Release(&wireFormat); }
LONGBOW_TEST_CASE(Global, ccnxCodecSchemaV1ManifestDecoder_DecodeHashGroup) { uint8_t rawManifest[40] = { 0x00, 0x07, 0x00, 0x24, 0x00, 0x02, 0x00, 0x20, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46 }; PARCBuffer *wireFormat = parcBuffer_Flip(parcBuffer_CreateFromArray(rawManifest, 40)); CCNxCodecTlvDecoder *decoder = ccnxCodecTlvDecoder_Create(wireFormat); CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateManifest(); ccnxCodecTlvDecoder_GetType(decoder); // swallow type uint16_t length = ccnxCodecTlvDecoder_GetLength(decoder); CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create(); bool result = _decodeHashGroup(decoder, dict, group, length); assertTrue(result, "Expected hash group to be decoded correctly."); PARCBuffer *expectedPointer = parcBuffer_AllocateCString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); CCNxManifestHashGroupPointer *pointer = ccnxManifestHashGroup_GetPointerAtIndex(group, 0); const PARCBuffer *actualPointer = ccnxManifestHashGroupPointer_GetDigest(pointer); assertTrue(parcBuffer_Equals(expectedPointer, actualPointer), "Expected decoded pointer to equal %s, got %s", parcBuffer_ToHexString(expectedPointer), parcBuffer_ToHexString(actualPointer)); parcBuffer_Release(&expectedPointer); ccnxManifestHashGroup_Release(&group); ccnxManifest_Release(&dict); ccnxCodecTlvDecoder_Destroy(&decoder); parcBuffer_Release(&wireFormat); }