aboutsummaryrefslogtreecommitdiffstats
path: root/libccnx-transport-rta/ccnx/transport/common
diff options
context:
space:
mode:
authorLuca Muscariello <lumuscar+fdio@cisco.com>2017-02-23 20:44:26 +0100
committerLuca Muscariello <lumuscar+fdio@cisco.com>2017-02-23 19:51:14 +0000
commitd18ae43123fcd7604d1c36a1ec8450dbe6071824 (patch)
tree2d49fc3aabd0f2607251c854565648d47b56b2e9 /libccnx-transport-rta/ccnx/transport/common
parent9b30fc10fb1cbebe651e5a107e8ca5b24de54675 (diff)
Initial commit: ccnxlibs.
Change-Id: I1b376527a7dd01a6b9e083a6cb646955902f45c0 Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Diffstat (limited to 'libccnx-transport-rta/ccnx/transport/common')
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/ccnx_ConnectionConfig.c123
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/ccnx_ConnectionConfig.h190
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/ccnx_StackConfig.c160
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/ccnx_StackConfig.h327
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/ccnx_TransportConfig.c120
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/ccnx_TransportConfig.h229
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/test/.gitignore4
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/test/CMakeLists.txt16
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_ConnectionConfig.c183
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_StackConfig.c226
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_TransportConfig.c226
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/test/test_transport.c136
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/test/test_transport_Message.c15
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/test/test_transport_MetaMessage.c283
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/test/test_transport_Stack.c191
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/transport.c123
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/transport.h262
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/transport_Message.c198
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/transport_Message.h175
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/transport_MetaMessage.c193
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/transport_MetaMessage.h515
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/transport_Stack.c137
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/transport_Stack.h354
-rw-r--r--libccnx-transport-rta/ccnx/transport/common/transport_private.h38
24 files changed, 4424 insertions, 0 deletions
diff --git a/libccnx-transport-rta/ccnx/transport/common/ccnx_ConnectionConfig.c b/libccnx-transport-rta/ccnx/transport/common/ccnx_ConnectionConfig.c
new file mode 100644
index 00000000..3792d80b
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/ccnx_ConnectionConfig.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * These are subsystems instantiated within components
+ * They define per-connection behavior, not stack structure.
+ *
+ */
+#include <config.h>
+#include <LongBow/runtime.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_DisplayIndented.h>
+
+#include <ccnx/transport/common/ccnx_TransportConfig.h>
+
+struct ccnx_connection_config {
+ PARCJSON *connjson;
+};
+
+bool
+ccnxConnectionConfig_IsValid(const CCNxConnectionConfig *config)
+{
+ bool result = false;
+ if (config != NULL) {
+ result = true;
+ }
+ return result;
+}
+
+void
+ccnxConnectionConfig_AssertValid(const CCNxConnectionConfig *config)
+{
+ assertTrue(ccnxConnectionConfig_IsValid(config), "CCNxConnectionConfig instance is invalid.");
+}
+
+CCNxConnectionConfig *
+ccnxConnectionConfig_Create(void)
+{
+ CCNxConnectionConfig *config = parcMemory_AllocateAndClear(sizeof(CCNxConnectionConfig));
+ assertNotNull(config, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(CCNxConnectionConfig));
+ config->connjson = parcJSON_Create();
+ return config;
+}
+
+void
+ccnxConnectionConfig_Destroy(CCNxConnectionConfig **connectionConfigPtr)
+{
+ assertNotNull(connectionConfigPtr, "Parameter must be non-null double pointer");
+
+ CCNxConnectionConfig *config = *connectionConfigPtr;
+ ccnxConnectionConfig_OptionalAssertValid(config);
+
+ parcJSON_Release(&config->connjson);
+ parcMemory_Deallocate((void **) &config);
+ *connectionConfigPtr = NULL;
+}
+
+PARCJSON *
+ccnxConnectionConfig_GetJson(const CCNxConnectionConfig *config)
+{
+ ccnxConnectionConfig_OptionalAssertValid(config);
+
+ return config->connjson;
+}
+
+CCNxConnectionConfig *
+ccnxConnectionConfig_Add(CCNxConnectionConfig *config, const char *key, PARCJSONValue *componentJson)
+{
+ ccnxConnectionConfig_OptionalAssertValid(config);
+
+ parcJSON_AddValue(config->connjson, key, componentJson);
+ return config;
+}
+
+CCNxConnectionConfig *
+ccnxConnectionConfig_Copy(const CCNxConnectionConfig *original)
+{
+ ccnxConnectionConfig_OptionalAssertValid(original);
+
+ CCNxConnectionConfig *copy = parcMemory_AllocateAndClear(sizeof(CCNxConnectionConfig));
+ assertNotNull(copy, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(CCNxConnectionConfig));
+ copy->connjson = parcJSON_Copy(original->connjson);
+ return copy;
+}
+
+bool
+ccnxConnectionConfig_Equals(const CCNxConnectionConfig *x, const CCNxConnectionConfig *y)
+{
+ bool result = false;
+
+ if (x == y) {
+ result = true;
+ } else if (x == NULL || y == NULL) {
+ result = false;
+ } else {
+ result = parcJSON_Equals(x->connjson, y->connjson);
+ }
+
+ return result;
+}
+
+void
+ccnxConnectionConfig_Display(const CCNxConnectionConfig *instance, int indentation)
+{
+ parcDisplayIndented_PrintLine(indentation, "ConnectionConfig@%p {", instance);
+ PARCJSON *json = ccnxConnectionConfig_GetJson(instance);
+
+ parcJSON_Display(json, indentation + 1);
+ parcDisplayIndented_PrintLine(indentation, "}");
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/ccnx_ConnectionConfig.h b/libccnx-transport-rta/ccnx/transport/common/ccnx_ConnectionConfig.h
new file mode 100644
index 00000000..37fbcf8c
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/ccnx_ConnectionConfig.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ccnx_ConnectionConfig.
+ * @brief Tranport Stack Connection configuration information.
+ *
+ * These are subsystems instantiated within components
+ * They define per-connection behavior, not stack structure.
+ *
+ */
+#ifndef TransportRTA_connectionConfig_h
+#define TransportRTA_connectionConfig_h
+
+
+struct ccnx_connection_config;
+typedef struct ccnx_connection_config CCNxConnectionConfig;
+
+/**
+ * Create a `CCNxConnectionConfig` instance.
+ *
+ * The instance must be populated with configuration information before it can be used.
+ *
+ *
+ * @return NULL An error occurred.
+ * @return non-NULL A valid `CCNxConnectionConfig` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+ *
+ * ccnxConnectionConfig_Destroy(&config);
+ * @endcode
+ */
+CCNxConnectionConfig *ccnxConnectionConfig_Create(void);
+
+/**
+ * Destroy previously created `CCNxConnectionConfig` instance.
+ *
+ * @param [in] configPtr A pointer to a pointer to a valid `CCNxConnectionConfig` instance that will be set to zero upon return.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+ *
+ * ccnxConnectionConfig_Destroy(&config);
+ * @endcode
+ */
+void ccnxConnectionConfig_Destroy(CCNxConnectionConfig **configPtr);
+
+#ifdef CCNxTransport_DISABLE_VALIDATION
+# define ccnxConnectionConfig_OptionalAssertValid(_instance_)
+#else
+# define ccnxConnectionConfig_OptionalAssertValid(_instance_) ccnxConnectionConfig_AssertValid(_instance_)
+#endif
+
+/**
+ * Determine if an instance of `CCNxTransportConfig` is valid.
+ *
+ * Valid means the internal state of the type is consistent with its required current or future behaviour.
+ * This may include the validation of internal instances of types.
+ *
+ * @param [in] config A pointer to a `CCNxTransportConfig` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+ * ccnxConnectionConfig_IsValid(config);
+ * ccnxConnectionConfig_Destroy(&config);
+ * }
+ * @endcode
+ */
+bool ccnxConnectionConfig_IsValid(const CCNxConnectionConfig *config);
+
+/**
+ * Assert that an instance of `CCNxTransportConfig` is valid.
+ *
+ * Valid means the internal state of the type is consistent with its required current or future behaviour.
+ * This may include the validation of internal instances of types.
+ *
+ * @param [in] config A pointer to a `CCNxTransportConfig` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+ * ccnxConnectionConfig_AssertValid(config);
+ * ccnxConnectionConfig_Destroy(&config);
+ * }
+ * @endcode
+ */
+void ccnxConnectionConfig_AssertValid(const CCNxConnectionConfig *config);
+
+/**
+ * Determine if two `CCNxConnectionConfig` instances are equal.
+ *
+ * The following equivalence relations on non-null `CCNxConnectionConfig` instances are maintained: *
+ * * It is reflexive: for any non-null reference value x, `ccnxConnectionConfig_Equals(x, x)` must return true.
+ *
+ * * It is symmetric: for any non-null reference values x and y, `ccnxConnectionConfig_Equals(x, y)` must return true if and only if
+ * `ccnxConnectionConfig_Equals(y x)` returns true.
+ *
+ * * It is transitive: for any non-null reference values x, y, and z, if
+ * `ccnxConnectionConfig_Equals(x, y)` returns true and
+ * `ccnxConnectionConfig_Equals(y, z)` returns true,
+ * then `ccnxConnectionConfig_Equals(x, z)` must return true.
+ *
+ * * It is consistent: for any non-null reference values x and y, multiple invocations of `ccnxConnectionConfig_Equals(x, y)`
+ * consistently return true or consistently return false.
+ *
+ * * For any non-null reference value x, `ccnxConnectionConfig_Equals(x, NULL)` must return false.
+ *
+ * @param [in] x A pointer to a valid CCNxConnectionConfig instance.
+ * @param [in] y A pointer to a valid CCNxConnectionConfig instance.
+ *
+ * @return true The instances x and y are equal.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxConnectionConfig *a = ccnxConnectionConfig_Create();
+ * CCNxConnectionConfig *b = ccnxConnectionConfig_Create();
+ *
+ * if (ccnxConnectionConfig_Equals(a, b)) {
+ * printf("Instances are equal.\n");
+ * }
+ *
+ * ccnxConnectionConfig_Release(&a);
+ * ccnxConnectionConfig_Release(&b);
+ * }
+ * @endcode
+ * @see ccnxConnectionConfig_HashCode
+ */
+bool ccnxConnectionConfig_Equals(const CCNxConnectionConfig *x, const CCNxConnectionConfig *y);
+
+
+/**
+ * Get the underlying JSON representation of a `CCNxConnectionConfig` instance.
+ *
+ * @param [in] config A pointer to a valid `CCNxConnectionConfig` instance.
+ *
+ * @return non-NULL A pointer to a valid PARCJSON instance.
+ *
+ * Example:
+ * @code
+ * {
+ * <#example#>
+ * }
+ * @endcode
+ */
+PARCJSON *ccnxConnectionConfig_GetJson(const CCNxConnectionConfig *cssonfig);
+
+/**
+ * Add a component's configuration to the connection's configuration. Each component snippit will
+ * result in an addition like this:
+ *
+ * { "key" : { param1 : value1, param2 : value2, ... } }
+ */
+CCNxConnectionConfig *ccnxConnectionConfig_Add(CCNxConnectionConfig *connectionConfig, const char *key, PARCJSONValue *componentJson);
+
+/**
+ * Make a copy of the given CCNxConnectionConfig. The original and copy
+ * must both be destroyed.
+ */
+CCNxConnectionConfig *ccnxConnectionConfig_Copy(const CCNxConnectionConfig *original);
+
+/**
+ * Print a human readable representation of the given instance.
+ *
+ * @param [in] indentation The level of indentation to use to pretty-print the output.
+ * @param [in] instance A pointer to the instance to display.
+ */
+void ccnxConnectionConfig_Display(const CCNxConnectionConfig *instance, int indentation);
+
+#endif
diff --git a/libccnx-transport-rta/ccnx/transport/common/ccnx_StackConfig.c b/libccnx-transport-rta/ccnx/transport/common/ccnx_StackConfig.c
new file mode 100644
index 00000000..b5b55a09
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/ccnx_StackConfig.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include <LongBow/runtime.h>
+
+#include <parc/algol/parc_Object.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_DisplayIndented.h>
+
+#include <ccnx/transport/common/ccnx_StackConfig.h>
+
+struct CCNxStackConfig_ {
+ PARCJSON *stackjson;
+};
+
+static void
+_ccnxStackConfig_Finalize(CCNxStackConfig **instancePtr)
+{
+ assertNotNull(instancePtr, "Parameter must be a non-null pointer to a CCNxStackConfig pointer.");
+
+ CCNxStackConfig *instance = *instancePtr;
+ ccnxStackConfig_OptionalAssertValid(instance);
+
+ parcJSON_Release(&instance->stackjson);
+}
+
+parcObject_ImplementAcquire(ccnxStackConfig, CCNxStackConfig);
+
+parcObject_ImplementRelease(ccnxStackConfig, CCNxStackConfig);
+
+parcObject_ExtendPARCObject(CCNxStackConfig, _ccnxStackConfig_Finalize, ccnxStackConfig_Copy, ccnxStackConfig_ToString, ccnxStackConfig_Equals, NULL, ccnxStackConfig_HashCode, ccnxStackConfig_ToJSON);
+
+void
+ccnxStackConfig_AssertValid(const CCNxStackConfig *instance)
+{
+ assertTrue(ccnxStackConfig_IsValid(instance),
+ "CCNxStackConfig is not valid.");
+}
+
+CCNxStackConfig *
+ccnxStackConfig_Create(void)
+{
+ CCNxStackConfig *result = parcObject_CreateInstance(CCNxStackConfig);
+ if (result != NULL) {
+ result->stackjson = parcJSON_Create();
+ }
+
+ return result;
+}
+
+CCNxStackConfig *
+ccnxStackConfig_Copy(const CCNxStackConfig *original)
+{
+ ccnxStackConfig_OptionalAssertValid(original);
+
+ CCNxStackConfig *result = parcObject_CreateInstance(CCNxStackConfig);
+
+ result->stackjson = parcJSON_Copy(original->stackjson);
+
+ return result;
+}
+
+void
+ccnxStackConfig_Display(const CCNxStackConfig *instance, int indentation)
+{
+ parcDisplayIndented_PrintLine(indentation, "CCNxStackConfig@%p {", instance);
+ PARCJSON *json = ccnxStackConfig_GetJson(instance);
+
+ parcJSON_Display(json, indentation + 1);
+ parcDisplayIndented_PrintLine(indentation, "}");
+}
+
+bool
+ccnxStackConfig_Equals(const CCNxStackConfig *x, const CCNxStackConfig *y)
+{
+ bool result = false;
+
+ if (x == y) {
+ result = true;
+ } else if (x == NULL || y == NULL) {
+ result = false;
+ } else {
+ result = parcJSON_Equals(x->stackjson, y->stackjson);
+ }
+
+ return result;
+}
+
+bool
+ccnxStackConfig_IsValid(const CCNxStackConfig *instance)
+{
+ bool result = false;
+ if (instance != NULL) {
+ result = true;
+ }
+ return result;
+}
+
+PARCJSON *
+ccnxStackConfig_ToJSON(const CCNxStackConfig *instance)
+{
+ ccnxStackConfig_OptionalAssertValid(instance);
+
+ return instance->stackjson;
+}
+
+char *
+ccnxStackConfig_ToString(const CCNxStackConfig *instance)
+{
+ PARCJSON *json = ccnxStackConfig_ToJSON(instance);
+
+ char *result = parcJSON_ToString(json);
+
+ return result;
+}
+
+PARCJSONValue *
+ccnxStackConfig_Get(const CCNxStackConfig *config, const char *componentKey)
+{
+ ccnxStackConfig_OptionalAssertValid(config);
+ PARCJSONValue *value = parcJSON_GetValueByName(config->stackjson, componentKey);
+ return value;
+}
+
+PARCHashCode
+ccnxStackConfig_HashCode(const CCNxStackConfig *config)
+{
+ ccnxStackConfig_OptionalAssertValid(config);
+ return parcJSON_HashCode(config->stackjson);
+}
+
+CCNxStackConfig *
+ccnxStackConfig_Add(CCNxStackConfig *config, const char *componentKey, PARCJSONValue *jsonObject)
+{
+ ccnxStackConfig_OptionalAssertValid(config);
+
+ parcJSON_AddValue(config->stackjson, componentKey, jsonObject);
+ return config;
+}
+
+PARCJSON *
+ccnxStackConfig_GetJson(const CCNxStackConfig *config)
+{
+ ccnxStackConfig_OptionalAssertValid(config);
+
+ return (config->stackjson);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/ccnx_StackConfig.h b/libccnx-transport-rta/ccnx/transport/common/ccnx_StackConfig.h
new file mode 100644
index 00000000..9c3fbbf1
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/ccnx_StackConfig.h
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ccnx_StackConfig.h
+ * @brief <#Brief Description#>
+ *
+ * <#Detailed Description#>
+ *
+ */
+#ifndef TransportLibrary_ccnx_StackConfig
+#define TransportLibrary_ccnx_StackConfig
+#include <stdbool.h>
+
+#include <parc/algol/parc_JSON.h>
+#include <parc/algol/parc_HashCode.h>
+
+
+struct CCNxStackConfig_;
+typedef struct CCNxStackConfig_ CCNxStackConfig;
+
+/**
+ * Increase the number of references to a `CCNxStackConfig` instance.
+ *
+ * Note that new `CCNxStackConfig` is not created,
+ * only that the given `CCNxStackConfig` reference count is incremented.
+ * Discard the reference by invoking `ccnxStackConfig_Release`.
+ *
+ * @param [in] instance A pointer to a valid CCNxStackConfig instance.
+ *
+ * @return The same value as @p instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ *
+ * CCNxStackConfig *b = ccnxStackConfig_Acquire();
+ *
+ * ccnxStackConfig_Release(&a);
+ * ccnxStackConfig_Release(&b);
+ * }
+ * @endcode
+ */
+CCNxStackConfig *ccnxStackConfig_Acquire(const CCNxStackConfig *instance);
+
+#ifdef TransportLibrary_DISABLE_VALIDATION
+# define ccnxStackConfig_OptionalAssertValid(_instance_)
+#else
+# define ccnxStackConfig_OptionalAssertValid(_instance_) ccnxStackConfig_AssertValid(_instance_)
+#endif
+
+/**
+ * Assert that the given `CCNxStackConfig` instance is valid.
+ *
+ * @param [in] instance A pointer to a valid CCNxStackConfig instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ *
+ * ccnxStackConfig_AssertValid(a);
+ *
+ * printf("Instance is valid.\n");
+ *
+ * ccnxStackConfig_Release(&b);
+ * }
+ * @endcode
+ */
+void ccnxStackConfig_AssertValid(const CCNxStackConfig *instance);
+
+/**
+ * Create an instance of CCNxStackConfig
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @return non-NULL A pointer to a valid CCNxStackConfig instance.
+ * @return NULL An error occurred.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ *
+ * ccnxStackConfig_Release(&b);
+ * }
+ * @endcode
+ */
+CCNxStackConfig *ccnxStackConfig_Create(void);
+
+/**
+ * Create an independent copy the given `PARCBuffer`
+ *
+ * A new buffer is created as a complete copy of the original.
+ *
+ * @param [in] original A pointer to a valid CCNxStackConfig instance.
+ *
+ * @return NULL Memory could not be allocated.
+ * @return non-NULL A pointer to a new `CCNxStackConfig` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ *
+ * CCNxStackConfig *copy = ccnxStackConfig_Copy(&b);
+ *
+ * ccnxStackConfig_Release(&b);
+ * ccnxStackConfig_Release(&copy);
+ * }
+ * @endcode
+ */
+CCNxStackConfig *ccnxStackConfig_Copy(const CCNxStackConfig *original);
+
+/**
+ * Print a human readable representation of the given `CCNxStackConfig`.
+ *
+ * @param [in] instance A pointer to a valid CCNxStackConfig instance.
+ * @param [in] indentation The indentation level to use for printing.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ *
+ * ccnxStackConfig_Display(a, 0);
+ *
+ * ccnxStackConfig_Release(&b);
+ * }
+ * @endcode
+ */
+void ccnxStackConfig_Display(const CCNxStackConfig *instance, int indentation);
+
+/**
+ * Determine if two `CCNxStackConfig` instances are equal.
+ *
+ * The following equivalence relations on non-null `CCNxStackConfig` instances are maintained: *
+ * * It is reflexive: for any non-null reference value x, `ccnxStackConfig_Equals(x, x)` must return true.
+ *
+ * * It is symmetric: for any non-null reference values x and y, `ccnxStackConfig_Equals(x, y)` must return true if and only if
+ * `ccnxStackConfig_Equals(y x)` returns true.
+ *
+ * * It is transitive: for any non-null reference values x, y, and z, if
+ * `ccnxStackConfig_Equals(x, y)` returns true and
+ * `ccnxStackConfig_Equals(y, z)` returns true,
+ * then `ccnxStackConfig_Equals(x, z)` must return true.
+ *
+ * * It is consistent: for any non-null reference values x and y, multiple invocations of `ccnxStackConfig_Equals(x, y)`
+ * consistently return true or consistently return false.
+ *
+ * * For any non-null reference value x, `ccnxStackConfig_Equals(x, NULL)` must return false.
+ *
+ * @param [in] x A pointer to a valid CCNxStackConfig instance.
+ * @param [in] y A pointer to a valid CCNxStackConfig instance.
+ *
+ * @return true The instances x and y are equal.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ * CCNxStackConfig *b = ccnxStackConfig_Create();
+ *
+ * if (ccnxStackConfig_Equals(a, b)) {
+ * printf("Instances are equal.\n");
+ * }
+ *
+ * ccnxStackConfig_Release(&a);
+ * ccnxStackConfig_Release(&b);
+ * }
+ * @endcode
+ * @see ccnxStackConfig_HashCode
+ */
+bool ccnxStackConfig_Equals(const CCNxStackConfig *x, const CCNxStackConfig *y);
+
+/**
+ * Determine if an instance of `CCNxStackConfig` is valid.
+ *
+ * Valid means the internal state of the type is consistent with its required current or future behaviour.
+ * This may include the validation of internal instances of types.
+ *
+ * @param [in] instance A pointer to a valid CCNxStackConfig instance.
+ *
+ * @return true The instance is valid.
+ * @return false The instance is not valid.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ *
+ * if (ccnxStackConfig_IsValid(a)) {
+ * printf("Instance is valid.\n");
+ * }
+ *
+ * ccnxStackConfig_Release(&b);
+ * }
+ * @endcode
+ *
+ */
+bool ccnxStackConfig_IsValid(const CCNxStackConfig *instance);
+
+/**
+ * Release a previously acquired reference to the given `CCNxStackConfig` instance,
+ * decrementing the reference count for the instance.
+ *
+ * The pointer to the instance is set to NULL as a side-effect of this function.
+ *
+ * If the invocation causes the last reference to the instance to be released,
+ * the instance is deallocated and the instance's implementation will perform
+ * additional cleanup and release other privately held references.
+ *
+ * @param [in,out] instancePtr A pointer to a pointer to the instance to release.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ *
+ * ccnxStackConfig_Release(&a);
+ * }
+ * @endcode
+ */
+void ccnxStackConfig_Release(CCNxStackConfig **instancePtr);
+
+/**
+ * Create a `PARCJSON` instance (representation) of the given object.
+ *
+ * @param [in] instance A pointer to a valid CCNxStackConfig instance.
+ *
+ * @return NULL Memory could not be allocated to contain the `PARCJSON` instance.
+ * @return non-NULL An allocated C string that must be deallocated via parcMemory_Deallocate().
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ *
+ * PARCJSON *json = ccnxStackConfig_ToJSON(a);
+ *
+ * printf("JSON representation: %s\n", parcJSON_ToString(json));
+ * parcJSON_Release(&json);
+ *
+ * ccnxStackConfig_Release(&a);
+ * }
+ * @endcode
+ */
+PARCJSON *ccnxStackConfig_ToJSON(const CCNxStackConfig *instance);
+
+/**
+ * Produce a null-terminated string representation of the specified `CCNxStackConfig`.
+ *
+ * The result must be freed by the caller via {@link parcMemory_Deallocate}.
+ *
+ * @param [in] instance A pointer to a valid CCNxStackConfig instance.
+ *
+ * @return NULL Cannot allocate memory.
+ * @return non-NULL A pointer to an allocated, null-terminated C string that must be deallocated via {@link parcMemory_Deallocate}.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *a = ccnxStackConfig_Create();
+ *
+ * char *string = ccnxStackConfig_ToString(a);
+ *
+ * ccnxStackConfig_Release(&a);
+ *
+ * parcMemory_Deallocate(&string);
+ * }
+ * @endcode
+ *
+ * @see ccnxStackConfig_Display
+ */
+char *ccnxStackConfig_ToString(const CCNxStackConfig *instance);
+
+PARCJSONValue *ccnxStackConfig_Get(const CCNxStackConfig *config, const char *componentKey);
+
+/**
+ * Returns a hash code value for the given instance.
+ *
+ * The general contract of the `HashCode` function is:
+ *
+ * Whenever it is invoked on the same instance more than once during an execution of an application,
+ * the `HashCode` function must consistently return the same value,
+ * provided no information in the instance is modified.
+ *
+ * This value need not remain consistent from one execution of an application to another execution of the same application.
+ * If two instances are equal according to the `Equals` function,
+ * then calling the `HashCode` function on each of the two instances must produce the same result.
+ *
+ * It is not required that if two instances are unequal according to the `Equals` function,
+ * then calling the `HashCode` function
+ * on each of the two objects must produce distinct integer results.
+ *
+ * @param [in] instance A pointer to the `CCNxStackConfig` instance.
+ *
+ * @return The hashcode for the given instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *buffer = ccnxStackConfig_Allocate(10);
+ * PARCHashCode hash = ccnxStackConfig_HashCode(buffer);
+ * ccnxStackConfig_Release(&buffer);
+ * }
+ * @endcode
+ */
+PARCHashCode ccnxStackConfig_HashCode(const CCNxStackConfig *instance);
+
+CCNxStackConfig *ccnxStackConfig_Add(CCNxStackConfig *config, const char *componentKey, PARCJSONValue *jsonObject);
+
+PARCJSON *ccnxStackConfig_GetJson(const CCNxStackConfig *config);
+#endif
diff --git a/libccnx-transport-rta/ccnx/transport/common/ccnx_TransportConfig.c b/libccnx-transport-rta/ccnx/transport/common/ccnx_TransportConfig.c
new file mode 100644
index 00000000..f1d55e6c
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/ccnx_TransportConfig.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <parc/algol/parc_Memory.h>
+#include <LongBow/runtime.h>
+
+#include <ccnx/transport/common/ccnx_TransportConfig.h>
+
+struct transport_config {
+ CCNxStackConfig *stackConfig;
+ CCNxConnectionConfig *connConfig;
+};
+
+bool
+ccnxTransportConfig_IsValid(const CCNxTransportConfig *transportConfig)
+{
+ bool result = false;
+
+ if (transportConfig != NULL) {
+ if (ccnxStackConfig_IsValid(transportConfig->stackConfig)) {
+ if (ccnxConnectionConfig_IsValid(transportConfig->connConfig)) {
+ result = true;
+ }
+ }
+ }
+ return result;
+}
+
+void
+ccnxTransportConfig_AssertValid(const CCNxTransportConfig *config)
+{
+ assertTrue(ccnxTransportConfig_IsValid(config), "CCNxTransportConfig instance is invalid.");
+}
+
+CCNxTransportConfig *
+ccnxTransportConfig_Create(CCNxStackConfig *stackConfig, CCNxConnectionConfig *connConfig)
+{
+ ccnxStackConfig_OptionalAssertValid(stackConfig);
+ ccnxConnectionConfig_OptionalAssertValid(connConfig);
+
+ CCNxTransportConfig *result = parcMemory_AllocateAndClear(sizeof(CCNxTransportConfig));
+ assertNotNull(result, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(CCNxTransportConfig));
+ result->stackConfig = ccnxStackConfig_Acquire(stackConfig);
+ result->connConfig = connConfig;
+ return result;
+}
+
+void
+ccnxTransportConfig_Destroy(CCNxTransportConfig **transportConfigPtr)
+{
+ assertNotNull(transportConfigPtr, "Parameter must be non-null double pointer");
+ ccnxTransportConfig_OptionalAssertValid(*transportConfigPtr);
+
+ CCNxTransportConfig *transConfig = *transportConfigPtr;
+ ccnxStackConfig_Release(&transConfig->stackConfig);
+ ccnxConnectionConfig_Destroy(&transConfig->connConfig);
+ parcMemory_Deallocate((void **) &transConfig);
+ *transportConfigPtr = NULL;
+}
+
+CCNxStackConfig *
+ccnxTransportConfig_GetStackConfig(const CCNxTransportConfig *transportConfig)
+{
+ ccnxTransportConfig_OptionalAssertValid(transportConfig);
+
+ return transportConfig->stackConfig;
+}
+
+CCNxConnectionConfig *
+ccnxTransportConfig_GetConnectionConfig(const CCNxTransportConfig *transportConfig)
+{
+ ccnxTransportConfig_OptionalAssertValid(transportConfig);
+
+ return transportConfig->connConfig;
+}
+
+bool
+ccnxTransportConfig_Equals(const CCNxTransportConfig *x, const CCNxTransportConfig *y)
+{
+ bool result = false;
+
+ if (x == y) {
+ result = true;
+ } else if (x == NULL || y == NULL) {
+ result = false;
+ } else {
+ if (ccnxStackConfig_Equals(x->stackConfig, y->stackConfig)) {
+ result = ccnxConnectionConfig_Equals(x->connConfig, y->connConfig);
+ }
+ }
+
+ return result;
+}
+
+CCNxTransportConfig *
+ccnxTransportConfig_Copy(const CCNxTransportConfig *original)
+{
+ ccnxTransportConfig_OptionalAssertValid(original);
+
+ CCNxTransportConfig *copy = parcMemory_AllocateAndClear(sizeof(CCNxTransportConfig));
+ assertNotNull(copy, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(CCNxTransportConfig));
+
+ copy->stackConfig = ccnxStackConfig_Copy(original->stackConfig);
+ copy->connConfig = ccnxConnectionConfig_Copy(original->connConfig);
+ return copy;
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/ccnx_TransportConfig.h b/libccnx-transport-rta/ccnx/transport/common/ccnx_TransportConfig.h
new file mode 100644
index 00000000..e85cc5f9
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/ccnx_TransportConfig.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ccnx_TransportConfig.h
+ * @brief The Transport Configuration information.
+ *
+ * The API composes the stack and connection parameters using these functions.
+ * The examples below are for the RTA Transport.
+ *
+ * <code>
+ * CCNxStackConfig *stackConfig = ccnxStackConfig_Create();
+ * ccnxStackConfig_AppendComponents(stackConfig, { RtaComponentNames[API_CONNECTOR], RtaComponentNames[FC_VEGAS],
+ * RtaComponentNames[CODEC_CCNB], RtaComponentNames[FWD_CCND] } );
+ *
+ * ccnxStackConfig_AppendApiConnector(stackConfig);
+ * ccnxStackConfig_AppendVegasFlowController(stackConfig);
+ * ccnxStackConfig_AppendCcndCodec(stackConfig);
+ * ccnxStackConfig_AppendCcndForwarder(stackConfig);
+ *
+ * CCNxConnectionConfig *connConfig = ccnxConnectionConfig_Create();
+ * ccnxConnectionConfig_publicKeySignerPkcs12Store(connConfig, "/Users/mmosko/keystore.p12", "123abc");
+ * ccnxConnectionConfig_InMemoryVerifier(connConfig);
+ *
+ *
+ * RtaCommand *cmdCreateStack = rtaCommand_CreateStack( (CommandCreateStack) { .stack_id = 7, .params = ccnxStackConfig_GetJson(stackConfig) } );
+ * rtaCommand_write(cmdCreateStack, command_fd);
+ * ccnxStackConfig_Release(&stackConfig);
+ *
+ * RtaCommand *cmdOpen = rtaCommand_Open( (CommandOpen) { .stack_id = 7, .api_fd = 12, .transport_fd = 13, .params = connecitonConfig_GetJson(connConfig) } );
+ * rtaCommand_write(cmdCreateStack, command_fd);
+ * ccnxConnectionConfig_Destroy(&connConfig);
+ * </code>
+ *
+ */
+#ifndef Libccnx_transport_Configuration_h
+#define Libccnx_transport_Configuration_h
+
+#include <stdarg.h>
+
+#include <ccnx/transport/common/ccnx_StackConfig.h>
+#include <ccnx/transport/common/ccnx_ConnectionConfig.h>
+
+struct transport_config;
+typedef struct transport_config CCNxTransportConfig;
+
+/**
+ * Create a `CCNxTransportConfig` instance.
+ *
+ * The instance must be populated with configuration information before it can be used.
+ *
+ * @param [in] stackConfig A pointer to a valid `CCNxStackConfig` instance.
+ * @param [in] connectionConfig A pointer to a valid `CCNxConnectionConfig` instance.
+ * @return NULL An error occurred.
+ * @return non-NULL A valid `CCNxTransportConfig` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxTransportConfig *config = ccnxTransportConfig_Create(stackConfig, connectionConfig);
+ *
+ * ccnxTransportConfig_Destroy(&config);
+ * @endcode
+ */
+CCNxTransportConfig *ccnxTransportConfig_Create(CCNxStackConfig *stackConfig, CCNxConnectionConfig *connectionConfig);
+
+#ifdef CCNxTransport_DISABLE_VALIDATION
+# define ccnxTransportConfig_OptionalAssertValid(_instance_)
+#else
+# define ccnxTransportConfig_OptionalAssertValid(_instance_) ccnxTransportConfig_AssertValid(_instance_)
+#endif
+/**
+ * Assert that an instance of `CCNxTransportConfig` is valid.
+ *
+ * Valid means the internal state of the type is consistent with its required current or future behaviour.
+ * This may include the validation of internal instances of types.
+ *
+ * @param [in] config A pointer to a `CCNxTransportConfig` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxTransportConfig *config = ccnxTransportConfig_Create(stackConfig, connectionConfig);
+ * ccnxTransportConfig_AssertValid(config);
+ * ccnxTransportConfig_Destroy(&config);
+ * }
+ * @endcode
+ * @see ccnxTransportConfig_IsValid
+ */
+void ccnxTransportConfig_AssertValid(const CCNxTransportConfig *config);
+
+/**
+ * Destroy previously created `CCNxTransportConfig` instance.
+ *
+ * @param [in] configPtr A pointer to a pointer to a valid `CCNxTransportConfig` instance that will be set to zero upon return.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxTransportConfig *config = ccnxTransportConfig_Create(stackConfig, connectionConfig);
+ *
+ * ccnxTransportConfig_Destroy(&config);
+ * }
+ * @endcode
+ */
+void ccnxTransportConfig_Destroy(CCNxTransportConfig **configPtr);
+
+/**
+ * Get the `CCNxStackConfig` instance in the given `CCNxTransportConfig`
+ *
+ * @param [in] config A pointer to a valid `CCNxTransportConfig` instance.
+ *
+ * @return A pointer to the `CCNxStackConfig` instance in the given `CCNxTransportConfig`
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxTransportConfig *config = ccnxTransportConfig_Create(stackConfig, connectionConfig);
+ *
+ * CCNxStackConfig *stack = ccnxTransportConfig_GetStackConfig(config);
+ *
+ * ccnxTransportConfig_Destroy(&config);
+ * }
+ * @endcode
+ */
+CCNxStackConfig *ccnxTransportConfig_GetStackConfig(const CCNxTransportConfig *config);
+
+/**
+ * Get the `CCNxConnectionConfig` instance in the given `CCNxTransportConfig`
+ *
+ * @param [in] config A pointer to a valid `CCNxTransportConfig` instance.
+ *
+ * @return A pointer to the `CCNxConnectionConfig` instance in the given `CCNxTransportConfig`
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxTransportConfig *config = ccnxTransportConfig_Create(stackConfig, connectionConfig);
+ *
+ * CCNxConnectionConfig *connection = ccnxTransportConfig_GetConnectionConfig(config);
+ *
+ * ccnxTransportConfig_Destroy(&config);
+ * }
+ * @endcode
+ */
+CCNxConnectionConfig *ccnxTransportConfig_GetConnectionConfig(const CCNxTransportConfig *config);
+
+/**
+ * Determine if an instance of `CCNxTransportConfig` is valid.
+ *
+ * Valid means the internal state of the type is consistent with its required current or future behaviour.
+ * This may include the validation of internal instances of types.
+ *
+ * @param [in] config A pointer to a `CCNxTransportConfig` instance.
+ *
+ * @return true The instance is valid.
+ * @return false The instance is not valid.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxTransportConfig *config = ccnxTransportConfig_Create(stackConfig, connectionConfig);
+ * ccnxTransportConfig_IsValid(config);
+ * ccnxTransportConfig_Destroy(&config);
+ * }
+ * @endcode
+ * @see ccnxTransportConfig_AssertValid
+ */
+bool ccnxTransportConfig_IsValid(const CCNxTransportConfig *config);
+/**
+ * Determine if two `CCNxTransportConfig` instances are equal.
+ *
+ * The following equivalence relations on non-null `CCNxTransportConfig` instances are maintained: *
+ * * It is reflexive: for any non-null reference value x, `ccnxTransportConfig_Equals(x, x)` must return true.
+ *
+ * * It is symmetric: for any non-null reference values x and y, `ccnxTransportConfig_Equals(x, y)` must return true if and only if
+ * `ccnxTransportConfig_Equals(y x)` returns true.
+ *
+ * * It is transitive: for any non-null reference values x, y, and z, if
+ * `ccnxTransportConfig_Equals(x, y)` returns true and
+ * `ccnxTransportConfig_Equals(y, z)` returns true,
+ * then `ccnxTransportConfig_Equals(x, z)` must return true.
+ *
+ * * It is consistent: for any non-null reference values x and y, multiple invocations of `ccnxTransportConfig_Equals(x, y)`
+ * consistently return true or consistently return false.
+ *
+ * * For any non-null reference value x, `ccnxTransportConfig_Equals(x, NULL)` must return false.
+ *
+ * @param [in] x A pointer to a valid CCNxTransportConfig instance.
+ * @param [in] y A pointer to a valid CCNxTransportConfig instance.
+ *
+ * @return true The instances x and y are equal.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxTransportConfig *a = ccnxTransportConfig_Create();
+ * CCNxTransportConfig *b = ccnxTransportConfig_Create();
+ *
+ * if (ccnxTransportConfig_Equals(a, b)) {
+ * printf("Instances are equal.\n");
+ * }
+ *
+ * ccnxTransportConfig_Release(&a);
+ * ccnxTransportConfig_Release(&b);
+ * }
+ * @endcode
+ * @see ccnxTransportConfig_HashCode
+ */
+bool ccnxTransportConfig_Equals(const CCNxTransportConfig *x, const CCNxTransportConfig *y);
+
+/**
+ * Make a copy of the given TransportConfig. The original and copy
+ * must both be destroyed.
+ */
+CCNxTransportConfig *ccnxTransportConfig_Copy(const CCNxTransportConfig *original);
+#endif // Libccnx_transport_Configuration_h
diff --git a/libccnx-transport-rta/ccnx/transport/common/test/.gitignore b/libccnx-transport-rta/ccnx/transport/common/test/.gitignore
new file mode 100644
index 00000000..6fd12a5f
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/test/.gitignore
@@ -0,0 +1,4 @@
+test_transport_MetaMessage
+test_ccnx_ConnectionConfig
+test_ccnx_StackConfig
+test_ccnx_TransportConfig
diff --git a/libccnx-transport-rta/ccnx/transport/common/test/CMakeLists.txt b/libccnx-transport-rta/ccnx/transport/common/test/CMakeLists.txt
new file mode 100644
index 00000000..c964fc69
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/test/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Enable gcov output for the tests
+add_definitions(--coverage)
+set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage")
+
+set(TestsExpectedToPass
+ test_transport_MetaMessage
+ test_ccnx_ConnectionConfig
+ test_ccnx_StackConfig
+ test_ccnx_TransportConfig
+)
+
+
+foreach(test ${TestsExpectedToPass})
+ AddTest(${test})
+endforeach()
+
diff --git a/libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_ConnectionConfig.c b/libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_ConnectionConfig.c
new file mode 100644
index 00000000..2bc4d121
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_ConnectionConfig.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Runner.
+#include "../ccnx_ConnectionConfig.c"
+
+#include <LongBow/unit-test.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/testing/parc_MemoryTesting.h>
+#include <parc/testing/parc_ObjectTesting.h>
+
+LONGBOW_TEST_RUNNER(ccnx_ConnectionConfig)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified here, but every test must be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Static);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_ConnectionConfig)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_ConnectionConfig)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxConnectionConfig_Add);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxConnectionConfig_AssertValid);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxConnectionConfig_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxConnectionConfig_Copy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxConnectionConfig_CreateDestroy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxConnectionConfig_Display);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxConnectionConfig_GetJson);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxConnectionConfig_IsValid);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+
+ if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) {
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxConnectionConfig_Add)
+{
+ CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+
+ PARCJSONValue *val = parcJSONValue_CreateFromNULL();
+ ccnxConnectionConfig_Add(config, "key", val);
+ parcJSONValue_Release(&val);
+
+ ccnxConnectionConfig_Destroy(&config);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxConnectionConfig_AssertValid)
+{
+ CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+ ccnxConnectionConfig_AssertValid(config);
+ ccnxConnectionConfig_Destroy(&config);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxConnectionConfig_Equals)
+{
+ CCNxConnectionConfig *x = ccnxConnectionConfig_Create();
+ CCNxConnectionConfig *y = ccnxConnectionConfig_Create();
+ CCNxConnectionConfig *z = ccnxConnectionConfig_Create();
+ CCNxConnectionConfig *u1 = ccnxConnectionConfig_Create();
+ PARCJSONValue *val = parcJSONValue_CreateFromNULL();
+ ccnxConnectionConfig_Add(u1, "key", val);
+ parcJSONValue_Release(&val);
+
+ parcObjectTesting_AssertEqualsFunction(ccnxConnectionConfig_Equals, x, y, z, u1);
+
+ ccnxConnectionConfig_Destroy(&x);
+ ccnxConnectionConfig_Destroy(&y);
+ ccnxConnectionConfig_Destroy(&z);
+ ccnxConnectionConfig_Destroy(&u1);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxConnectionConfig_Copy)
+{
+ CCNxConnectionConfig *x = ccnxConnectionConfig_Create();
+ PARCJSONValue *val = parcJSONValue_CreateFromNULL();
+ ccnxConnectionConfig_Add(x, "key", val);
+ parcJSONValue_Release(&val);
+
+ CCNxConnectionConfig *y = ccnxConnectionConfig_Copy(x);
+ assertTrue(ccnxConnectionConfig_Equals(x, y), "Expected the copy to be equal to the original");
+ ccnxConnectionConfig_Destroy(&x);
+ ccnxConnectionConfig_Destroy(&y);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxConnectionConfig_CreateDestroy)
+{
+ CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+ assertNotNull(config, "Expected non-NULL result from ccnxConnectionConfig_Create.");
+ ccnxConnectionConfig_Destroy(&config);
+ assertNull(config, "Expected NULL result from ccnxConnectionConfig_Destroy");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxConnectionConfig_Display)
+{
+ CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+ ccnxConnectionConfig_Display(config, 0);
+
+ ccnxConnectionConfig_Destroy(&config);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxConnectionConfig_GetJson)
+{
+ CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+
+ PARCJSON *json = ccnxConnectionConfig_GetJson(config);
+
+ assertNotNull(json, "Expected ccnxConnectionConfig_GetJson result to be non-null.");
+ ccnxConnectionConfig_Destroy(&config);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxConnectionConfig_IsValid)
+{
+ CCNxConnectionConfig *config = ccnxConnectionConfig_Create();
+ assertTrue(ccnxConnectionConfig_IsValid(config), "Expected ccnxConnectionConfig_Create result to be valid.");
+
+ ccnxConnectionConfig_Destroy(&config);
+ assertFalse(ccnxConnectionConfig_IsValid(config), "Expected ccnxConnectionConfig_Destroy result to be invalid.");
+}
+
+LONGBOW_TEST_FIXTURE(Static)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_ConnectionConfig);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_StackConfig.c b/libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_StackConfig.c
new file mode 100644
index 00000000..4f1ee7dc
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_StackConfig.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Runner.
+#include "../ccnx_StackConfig.c"
+#include <LongBow/unit-test.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/testing/parc_MemoryTesting.h>
+#include <parc/testing/parc_ObjectTesting.h>
+
+LONGBOW_TEST_RUNNER(ccnx_StackConfig)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified here, but every test must be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Static);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_StackConfig)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_StackConfig)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_AddGet);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_AssertValid);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_Copy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_CreateAcquireRelease);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_Display);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_HashCode);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_GetJson);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_IsValid);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_ToJSON);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxStackConfig_ToString);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) {
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_AddGet)
+{
+ CCNxStackConfig *instance = ccnxStackConfig_Create();
+
+ PARCJSONValue *expected = parcJSONValue_CreateFromNULL();
+ ccnxStackConfig_Add(instance, "key", expected);
+
+ PARCJSONValue *actual = ccnxStackConfig_Get(instance, "key");
+
+ assertTrue(parcJSONValue_Equals(expected, actual), "ccnxStackConfig_Get did not return what was 'added'");
+
+ parcJSONValue_Release(&expected);
+
+ ccnxStackConfig_Release(&instance);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_AssertValid)
+{
+ CCNxStackConfig *instance = ccnxStackConfig_Create();
+ ccnxStackConfig_AssertValid(instance);
+
+ ccnxStackConfig_Release(&instance);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_Copy)
+{
+ CCNxStackConfig *instance = ccnxStackConfig_Create();
+ CCNxStackConfig *copy = ccnxStackConfig_Copy(instance);
+ assertTrue(ccnxStackConfig_Equals(instance, copy), "Expected the copy to be equal to the original");
+
+ ccnxStackConfig_Release(&instance);
+ ccnxStackConfig_Release(&copy);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_CreateAcquireRelease)
+{
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ assertNotNull(config, "Expected non-NULL result from ccnxConnectionConfig_Create.");
+
+ CCNxStackConfig *reference = ccnxStackConfig_Acquire(config);
+
+ ccnxStackConfig_Release(&config);
+ assertNull(config, "Expected NULL result from ccnxConnectionConfig_Destroy");
+ ccnxStackConfig_Release(&reference);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_Display)
+{
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ ccnxStackConfig_Display(config, 1);
+
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_Equals)
+{
+ CCNxStackConfig *x = ccnxStackConfig_Create();
+ CCNxStackConfig *y = ccnxStackConfig_Create();
+ CCNxStackConfig *z = ccnxStackConfig_Create();
+
+ CCNxStackConfig *u1 = ccnxStackConfig_Create();
+ PARCJSONValue *val = parcJSONValue_CreateFromNULL();
+ ccnxStackConfig_Add(u1, "key", val);
+ parcJSONValue_Release(&val);
+
+ parcObjectTesting_AssertEquals(x, y, z, NULL);
+
+ ccnxStackConfig_Release(&x);
+ ccnxStackConfig_Release(&y);
+ ccnxStackConfig_Release(&z);
+ ccnxStackConfig_Release(&u1);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_HashCode)
+{
+ CCNxStackConfig *instance = ccnxStackConfig_Create();
+ uint64_t hashCode = ccnxStackConfig_HashCode(instance);
+ printf("%" PRIu64 "\n", hashCode);
+ ccnxStackConfig_Release(&instance);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_GetJson)
+{
+ CCNxStackConfig *instance = ccnxStackConfig_Create();
+ PARCJSON *json = ccnxStackConfig_GetJson(instance);
+
+ assertNotNull(json, "Expected non-null JSON");
+ ccnxStackConfig_Release(&instance);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_IsValid)
+{
+ CCNxStackConfig *instance = ccnxStackConfig_Create();
+ assertTrue(ccnxStackConfig_IsValid(instance), "Expected ccnxStackConfig_Create to result in a valid instance.");
+
+ ccnxStackConfig_Release(&instance);
+ assertFalse(ccnxStackConfig_IsValid(instance), "Expected ccnxStackConfig_Create to result in an invalid instance.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_ToJSON)
+{
+ CCNxStackConfig *instance = ccnxStackConfig_Create();
+ PARCJSON *json = ccnxStackConfig_ToJSON(instance);
+ assertNotNull(json, "Expected non-null JSON");
+
+ ccnxStackConfig_Release(&instance);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_ToString)
+{
+ CCNxStackConfig *instance = ccnxStackConfig_Create();
+ char *string = ccnxStackConfig_ToString(instance);
+ assertNotNull(string, "Expected non-null ccnxStackConfig_ToString");
+
+ parcMemory_Deallocate((void **) &string);
+ ccnxStackConfig_Release(&instance);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxStackConfig_Get)
+{
+ CCNxStackConfig *instance = ccnxStackConfig_Create();
+
+ ccnxStackConfig_Release(&instance);
+}
+
+LONGBOW_TEST_FIXTURE(Static)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_StackConfig);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_TransportConfig.c b/libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_TransportConfig.c
new file mode 100644
index 00000000..8b954419
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/test/test_ccnx_TransportConfig.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Runner.
+#include "../ccnx_TransportConfig.c"
+
+#include <LongBow/unit-test.h>
+
+#include <parc/testing/parc_MemoryTesting.h>
+#include <parc/testing/parc_ObjectTesting.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+
+LONGBOW_TEST_RUNNER(ccnx_TransportConfig)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified here, but every test must be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Static);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_TransportConfig)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_TransportConfig)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTransportConfig_AssertValid);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTransportConfig_Copy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTransportConfig_CreateDestroy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTransportConfig_GetConnectionConfig);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTransportConfig_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTransportConfig_GetStackConfig);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTransportConfig_IsValid_True);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTransportConfig_IsValid_False);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+
+ if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) {
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTransportConfig_AssertValid)
+{
+ CCNxStackConfig *stack = ccnxStackConfig_Create();
+ CCNxConnectionConfig *connection = ccnxConnectionConfig_Create();
+
+ CCNxTransportConfig *x = ccnxTransportConfig_Create(stack, connection);
+
+ ccnxTransportConfig_AssertValid(x);
+
+ ccnxStackConfig_Release(&stack);
+
+ ccnxTransportConfig_Destroy(&x);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTransportConfig_Copy)
+{
+ CCNxStackConfig *stack = ccnxStackConfig_Create();
+ CCNxConnectionConfig *connection = ccnxConnectionConfig_Create();
+
+ CCNxTransportConfig *x = ccnxTransportConfig_Create(stack, connection);
+ assertNotNull(x, "Expected non-null result from ccnxTransportConfig_Create");
+ ccnxStackConfig_Release(&stack);
+
+ CCNxTransportConfig *y = ccnxTransportConfig_Copy(x);
+
+ assertTrue(ccnxTransportConfig_Equals(x, y), "Expected ccnxTransportConfig_Copy result to be equal to the original");
+
+ ccnxTransportConfig_Destroy(&x);
+ ccnxTransportConfig_Destroy(&y);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTransportConfig_Equals)
+{
+ CCNxStackConfig *stack = ccnxStackConfig_Create();
+ CCNxConnectionConfig *connection = ccnxConnectionConfig_Create();
+
+ CCNxTransportConfig *x = ccnxTransportConfig_Create(stack, ccnxConnectionConfig_Copy(connection));
+ CCNxTransportConfig *y = ccnxTransportConfig_Create(stack, ccnxConnectionConfig_Copy(connection));
+ CCNxTransportConfig *z = ccnxTransportConfig_Create(stack, ccnxConnectionConfig_Copy(connection));
+
+ CCNxStackConfig *otherStack = ccnxStackConfig_Create();
+ PARCJSONValue *val = parcJSONValue_CreateFromNULL();
+ ccnxStackConfig_Add(otherStack, "key", val);
+ CCNxTransportConfig *u1 = ccnxTransportConfig_Create(otherStack, ccnxConnectionConfig_Copy(connection));
+
+ CCNxConnectionConfig *otherConnection = ccnxConnectionConfig_Create();
+ ccnxConnectionConfig_Add(otherConnection, "key", val);
+
+ CCNxTransportConfig *u2 = ccnxTransportConfig_Create(stack, otherConnection);
+
+ parcObjectTesting_AssertEqualsFunction(ccnxTransportConfig_Equals, x, y, z, u1, u2);
+
+ assertTrue(ccnxTransportConfig_Equals(x, y), "Expected ccnxTransportConfig_Copy result to be equal to the original");
+
+ parcJSONValue_Release(&val);
+ ccnxStackConfig_Release(&stack);
+ ccnxStackConfig_Release(&otherStack);
+ ccnxConnectionConfig_Destroy(&connection);
+
+ ccnxTransportConfig_Destroy(&x);
+ ccnxTransportConfig_Destroy(&y);
+ ccnxTransportConfig_Destroy(&z);
+ ccnxTransportConfig_Destroy(&u1);
+ ccnxTransportConfig_Destroy(&u2);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTransportConfig_CreateDestroy)
+{
+ CCNxStackConfig *stack = ccnxStackConfig_Create();
+ CCNxConnectionConfig *connection = ccnxConnectionConfig_Create();
+
+ CCNxTransportConfig *x = ccnxTransportConfig_Create(stack, connection);
+ assertNotNull(x, "Expected non-null result from ccnxTransportConfig_Create");
+ ccnxStackConfig_Release(&stack);
+
+ ccnxTransportConfig_Destroy(&x);
+ assertNull(x, "Expected null result from ccnxStackConfig_Release");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTransportConfig_GetConnectionConfig)
+{
+ CCNxStackConfig *stack = ccnxStackConfig_Create();
+ CCNxConnectionConfig *connection = ccnxConnectionConfig_Create();
+
+ CCNxTransportConfig *config = ccnxTransportConfig_Create(stack, connection);
+ ccnxStackConfig_Release(&stack);
+
+ CCNxConnectionConfig *actual = ccnxTransportConfig_GetConnectionConfig(config);
+
+ assertTrue(connection == actual, "Expected ccnxTransportConfig_GetConnectionConfig to return the original.");
+
+ ccnxTransportConfig_Destroy(&config);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTransportConfig_GetStackConfig)
+{
+ CCNxStackConfig *stack = ccnxStackConfig_Create();
+ CCNxConnectionConfig *connection = ccnxConnectionConfig_Create();
+
+ CCNxTransportConfig *config = ccnxTransportConfig_Create(stack, connection);
+
+ CCNxStackConfig *actual = ccnxTransportConfig_GetStackConfig(config);
+
+ assertTrue(stack == actual, "Expected ccnxTransportConfig_GetStackConfig to return the original.");
+
+ ccnxStackConfig_Release(&stack);
+ ccnxTransportConfig_Destroy(&config);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTransportConfig_IsValid_True)
+{
+ CCNxStackConfig *stack = ccnxStackConfig_Create();
+ CCNxConnectionConfig *connection = ccnxConnectionConfig_Create();
+
+ CCNxTransportConfig *x = ccnxTransportConfig_Create(stack, connection);
+ assertTrue(ccnxTransportConfig_IsValid(x), "Expected ccnxTransportConfig_Create to return a valid instance.");
+ ccnxStackConfig_Release(&stack);
+
+ ccnxTransportConfig_Destroy(&x);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTransportConfig_IsValid_False)
+{
+ assertFalse(ccnxTransportConfig_IsValid(NULL), "Expected NULL to be an invalid instance.");
+}
+
+LONGBOW_TEST_FIXTURE(Static)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_TransportConfig);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/test/test_transport.c b/libccnx-transport-rta/ccnx/transport/common/test/test_transport.c
new file mode 100644
index 00000000..2642acd6
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/test/test_transport.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Runner.
+#include "../transport.c"
+
+#include <LongBow/unit-test.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/testing/parc_TestingMemory.h>
+
+LONGBOW_TEST_RUNNER(transport)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified here, but every test must be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Static);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(transport)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(transport)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, Transport_Create_RTA);
+ LONGBOW_RUN_TEST_CASE(Global, Transport_Close);
+ LONGBOW_RUN_TEST_CASE(Global, Transport_Destroy);
+ LONGBOW_RUN_TEST_CASE(Global, Transport_Open);
+ LONGBOW_RUN_TEST_CASE(Global, Transport_PassCommand);
+ LONGBOW_RUN_TEST_CASE(Global, Transport_Recv);
+ LONGBOW_RUN_TEST_CASE(Global, Transport_Send);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ LongBowStatus result = LONGBOW_STATUS_SUCCEEDED;
+ if (parcTestingMemory_ExpectedOutstanding(0, "%s", longBowTestCase_GetFullName(testCase)) == false) {
+ result = LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return result;
+}
+
+LONGBOW_TEST_CASE(Global, Transport_Close)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Global, Transport_Create_RTA)
+{
+ TransportContext *transport = Transport_Create(TRANSPORT_RTA);
+
+ Transport_Destroy(&transport);
+}
+
+LONGBOW_TEST_CASE(Global, Transport_Destroy)
+{
+ TransportContext *transport = Transport_Create(TRANSPORT_RTA);
+
+ Transport_Destroy(&transport);
+}
+
+LONGBOW_TEST_CASE(Global, Transport_Open)
+{
+ TransportContext *transport = Transport_Create(TRANSPORT_RTA);
+
+
+ Transport_Destroy(&transport);
+}
+
+LONGBOW_TEST_CASE(Global, Transport_PassCommand)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Global, Transport_Recv)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Global, Transport_Send)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_FIXTURE(Static)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(transport);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/test/test_transport_Message.c b/libccnx-transport-rta/ccnx/transport/common/test/test_transport_Message.c
new file mode 100644
index 00000000..ec9e3a04
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/test/test_transport_Message.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
diff --git a/libccnx-transport-rta/ccnx/transport/common/test/test_transport_MetaMessage.c b/libccnx-transport-rta/ccnx/transport/common/test/test_transport_MetaMessage.c
new file mode 100644
index 00000000..3896d945
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/test/test_transport_MetaMessage.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../transport_MetaMessage.c"
+#include <stdio.h>
+
+#include <LongBow/unit-test.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+
+#include <ccnx/common/validation/ccnxValidation_CRC32C.h>
+
+LONGBOW_TEST_RUNNER(ccnx_MetaMessage)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Local);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_MetaMessage)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_MetaMessage)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_Acquire_Release);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_CreateFromContentObject);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_CreateFromControl);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_CreateFromInterest);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_Display);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_GetContentObject);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_GetControl);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_GetInterest);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_IsContentObject);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_IsControl);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_IsInterest);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxMetaMessage_EncodeDecode);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_Acquire_Release)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ CCNxMetaMessage *portalMessage = ccnxMetaMessage_CreateFromInterest(interest);
+
+ CCNxMetaMessage *ref1 = ccnxMetaMessage_Acquire(portalMessage);
+ CCNxMetaMessage *ref2 = ccnxMetaMessage_Acquire(portalMessage);
+ CCNxMetaMessage *ref3 = ccnxMetaMessage_Acquire(portalMessage);
+
+ ccnxMetaMessage_Release(&ref1);
+ assertNull(ref1, "Expected pointer to pointer to be null after Release()");
+
+ ccnxMetaMessage_Release(&ref2);
+ assertNull(ref2, "Expected pointer to pointer to be null after Release()");
+
+ ccnxMetaMessage_Release(&ref3);
+ assertNull(ref3, "Expected pointer to pointer to be null after Release()");
+
+ ccnxMetaMessage_Release(&portalMessage);
+ ccnxInterest_Release(&interest);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_CreateFromContentObject)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar");
+ PARCBuffer *payload = parcBuffer_WrapCString("This is some data. It's not good data, but it is data.");
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+
+ CCNxMetaMessage *portalMessage = ccnxMetaMessage_CreateFromContentObject(contentObject);
+ assertNotNull(portalMessage, "Expected a non-null portal message");
+ ccnxMetaMessage_Release(&portalMessage);
+
+ ccnxContentObject_Release(&contentObject);
+ parcBuffer_Release(&payload);
+ ccnxName_Release(&name);
+}
+
+#ifndef BUGZID_712
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_CreateFromControl)
+{
+ testUnimplemented("");
+}
+#endif // !BUGZID_712
+
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_CreateFromInterest)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+
+ CCNxMetaMessage *portalMessage = ccnxMetaMessage_CreateFromInterest(interest);
+ assertNotNull(portalMessage, "Expected a non-null portal message");
+ ccnxMetaMessage_Release(&portalMessage);
+
+ ccnxInterest_Release(&interest);
+ ccnxName_Release(&name);
+}
+
+#ifndef BUGZID_712
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_Display)
+{
+ testUnimplemented("");
+}
+#endif // !BUGZID_712
+
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_GetContentObject)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar");
+ PARCBuffer *payload = parcBuffer_WrapCString("This is some data. It's not good data, but it is data.");
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+
+ CCNxMetaMessage *portalMessage = ccnxMetaMessage_CreateFromContentObject(contentObject);
+
+ CCNxContentObject *reference = ccnxMetaMessage_GetContentObject(portalMessage);
+
+#ifndef BUGZID_712
+ // TODO: We need a ccnxContentObject_Equals()!
+ // assertTrue(ccnxContentObject_Equals(contentObject, reference), "Expected reference to equal original contentObject");
+#endif // !BUGZID_712
+ ccnxContentObject_AssertValid(reference);
+
+ ccnxMetaMessage_Release(&portalMessage);
+
+ ccnxContentObject_Release(&contentObject);
+ parcBuffer_Release(&payload);
+ ccnxName_Release(&name);
+}
+
+#ifndef BUGZID_712
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_GetControl)
+{
+ testUnimplemented("");
+}
+#endif // !BUGZID_712
+
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_GetInterest)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ CCNxMetaMessage *portalMessage = ccnxMetaMessage_CreateFromInterest(interest);
+ CCNxInterest *reference = ccnxMetaMessage_GetInterest(portalMessage);
+
+ assertTrue(ccnxInterest_Equals(interest, reference), "Expected reference to equal original interest");
+ ccnxInterest_AssertValid(reference);
+
+ ccnxInterest_Release(&reference);
+ ccnxMetaMessage_Release(&portalMessage);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_IsContentObject)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar");
+ PARCBuffer *payload = parcBuffer_WrapCString("This is some data. It's not good data, but it is data.");
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+
+ CCNxMetaMessage *portalMessage = ccnxMetaMessage_CreateFromContentObject(contentObject);
+
+ assertTrue(ccnxMetaMessage_IsContentObject(portalMessage), "Expected portal message to be an ContentObject");
+ assertFalse(ccnxMetaMessage_IsInterest(portalMessage), "Did not expect portal message to be an Interest");
+ assertFalse(ccnxMetaMessage_IsControl(portalMessage), "Did not expect portal message to be a Control message");
+
+ ccnxMetaMessage_Release(&portalMessage);
+ ccnxContentObject_Release(&contentObject);
+ parcBuffer_Release(&payload);
+ ccnxName_Release(&name);
+}
+
+#ifndef BUGZID_712
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_IsControl)
+{
+ testUnimplemented("");
+}
+#endif // !BUGZID_712
+
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_IsInterest)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ CCNxMetaMessage *portalMessage = ccnxMetaMessage_CreateFromInterest(interest);
+
+ assertTrue(ccnxMetaMessage_IsInterest(portalMessage), "Expected portal message to be an Interest");
+ assertFalse(ccnxMetaMessage_IsContentObject(portalMessage), "Did not expect portal message to be a ContentObject");
+ assertFalse(ccnxMetaMessage_IsControl(portalMessage), "Did not expect portal message to be a Control message");
+
+ ccnxMetaMessage_Release(&portalMessage);
+ ccnxInterest_Release(&interest);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_EncodeDecode)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ ccnxName_Release(&name);
+
+ PARCSigner *signer = ccnxValidationCRC32C_CreateSigner(); // Would really be SHA256 or something.
+
+ // Encode it to wire format.
+ PARCBuffer *wireFormatBuffer = ccnxMetaMessage_CreateWireFormatBuffer(interest, signer);
+
+ // Now decode it from wireformat.
+ CCNxMetaMessage *decodedMessage = ccnxMetaMessage_CreateFromWireFormatBuffer(wireFormatBuffer);
+
+ // At this point, the unpacked dictionary should be equivalent to the original interest.
+ assertTrue(ccnxInterest_Equals(interest, decodedMessage), "Expected an equivalent interest to be unpacked");
+
+ parcBuffer_Release(&wireFormatBuffer);
+ ccnxInterest_Release(&interest);
+ ccnxMetaMessage_Release(&decodedMessage);
+ parcSigner_Release(&signer);
+}
+
+#ifndef BUGZID_712
+LONGBOW_TEST_CASE(Global, ccnxMetaMessage_Release)
+{
+ testUnimplemented("");
+}
+#endif // !BUGZID_712
+
+LONGBOW_TEST_FIXTURE(Local)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Local)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Local)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_MetaMessage);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/test/test_transport_Stack.c b/libccnx-transport-rta/ccnx/transport/common/test/test_transport_Stack.c
new file mode 100644
index 00000000..4a10d962
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/test/test_transport_Stack.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../transport_Stack.c"
+
+#include <LongBow/testing.h>
+#include <LongBow/debugging.h>
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/algol/parc_DisplayIndented.h>
+
+#include <parc/testing/parc_MemoryTesting.h>
+#include <parc/testing/parc_ObjectTesting.h>
+
+LONGBOW_TEST_RUNNER(transport_Stack)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(CreateAcquireRelease);
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(transport_Stack)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(transport_Stack)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(CreateAcquireRelease)
+{
+ LONGBOW_RUN_TEST_CASE(CreateAcquireRelease, CreateRelease);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(CreateAcquireRelease)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(CreateAcquireRelease)
+{
+ if (!parcMemoryTesting_ExpectedOutstanding(0, "%s leaked memory.", longBowTestCase_GetFullName(testCase))) {
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(CreateAcquireRelease, CreateRelease)
+{
+ TransportStack *instance = transportStack_Create();
+ assertNotNull(instance, "Expected non-null result from transportStack_Create();");
+
+ parcObjectTesting_AssertAcquireReleaseContract(instance);
+
+ transportStack_Release(&instance);
+ assertNull(instance, "Expected null result from transportStack_Release();");
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, transportStack_Compare);
+ LONGBOW_RUN_TEST_CASE(Global, transportStack_Copy);
+ LONGBOW_RUN_TEST_CASE(Global, transportStack_Display);
+ LONGBOW_RUN_TEST_CASE(Global, transportStack_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, transportStack_HashCode);
+ LONGBOW_RUN_TEST_CASE(Global, transportStack_IsValid);
+ LONGBOW_RUN_TEST_CASE(Global, transportStack_ToJSON);
+ LONGBOW_RUN_TEST_CASE(Global, transportStack_ToString);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ if (!parcMemoryTesting_ExpectedOutstanding(0, "%s mismanaged memory.", longBowTestCase_GetFullName(testCase))) {
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, transportStack_Compare)
+{
+ testUnimplemented("");
+}
+
+LONGBOW_TEST_CASE(Global, transportStack_Copy)
+{
+ TransportStack *instance = transportStack_Create();
+ TransportStack *copy = transportStack_Copy(instance);
+ assertTrue(transportStack_Equals(instance, copy), "Expected the copy to be equal to the original");
+
+ transportStack_Release(&instance);
+ transportStack_Release(&copy);
+}
+
+LONGBOW_TEST_CASE(Global, transportStack_Display)
+{
+ TransportStack *instance = transportStack_Create();
+ transportStack_Display(instance, 0);
+ transportStack_Release(&instance);
+}
+
+LONGBOW_TEST_CASE(Global, transportStack_Equals)
+{
+ TransportStack *x = transportStack_Create();
+ TransportStack *y = transportStack_Create();
+ TransportStack *z = transportStack_Create();
+
+ parcObjectTesting_AssertEquals(x, y, z, NULL);
+
+ transportStack_Release(&x);
+ transportStack_Release(&y);
+ transportStack_Release(&z);
+}
+
+LONGBOW_TEST_CASE(Global, transportStack_HashCode)
+{
+ TransportStack *x = transportStack_Create();
+ TransportStack *y = transportStack_Create();
+
+ parcObjectTesting_AssertHashCode(x, y);
+
+ transportStack_Release(&x);
+ transportStack_Release(&y);
+}
+
+LONGBOW_TEST_CASE(Global, transportStack_IsValid)
+{
+ TransportStack *instance = transportStack_Create();
+ assertTrue(transportStack_IsValid(instance), "Expected transportStack_Create to result in a valid instance.");
+
+ transportStack_Release(&instance);
+ assertFalse(transportStack_IsValid(instance), "Expected transportStack_Release to result in an invalid instance.");
+}
+
+LONGBOW_TEST_CASE(Global, transportStack_ToJSON)
+{
+ TransportStack *instance = transportStack_Create();
+
+ PARCJSON *json = transportStack_ToJSON(instance);
+
+ parcJSON_Release(&json);
+
+ transportStack_Release(&instance);
+}
+
+LONGBOW_TEST_CASE(Global, transportStack_ToString)
+{
+ TransportStack *instance = transportStack_Create();
+
+ char *string = transportStack_ToString(instance);
+
+ assertNotNull(string, "Expected non-NULL result from transportStack_ToString");
+
+ parcMemory_Deallocate((void **) &string);
+ transportStack_Release(&instance);
+}
+
+int
+main(int argc, char *argv[argc])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(transport_Stack);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
+
+
diff --git a/libccnx-transport-rta/ccnx/transport/common/transport.c b/libccnx-transport-rta/ccnx/transport/common/transport.c
new file mode 100644
index 00000000..0f9e564d
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/transport.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <LongBow/runtime.h>
+
+#include <parc/algol/parc_Memory.h>
+
+#include "transport.h"
+#include "transport_private.h"
+#include "rta_Transport.h"
+
+struct transport_context {
+ TransportTypes transport_type;
+ struct transport_operations ops;
+ void *transport_data;
+ unsigned references;
+};
+
+// the one global transport, for now
+static TransportContext *the_context = NULL;
+
+TransportContext *
+Transport_Create(TransportTypes type)
+{
+ if (the_context == NULL) {
+ switch (type) {
+ case TRANSPORT_RTA:
+ the_context = parcMemory_Allocate(sizeof(TransportContext));
+ assertNotNull(the_context, "TransportContext could not be allocated, parcMemory_Allocate(%zu) returned NULL", sizeof(TransportContext));
+
+ the_context->references = 0;
+ the_context->ops = rta_ops;
+ the_context->transport_data = the_context->ops.Create();
+ the_context->transport_type = type;
+ break;
+
+ default:
+ fprintf(stderr, "%s unknown transport type %d\n", __func__, type);
+ abort();
+ break;
+ }
+ }
+
+ if (the_context->transport_type == type) {
+ the_context->references++;
+ return the_context;
+ }
+
+ fprintf(stderr, "%s transport type %d not of request type %d\n",
+ __func__, the_context->transport_type, type);
+ abort();
+}
+
+int
+Transport_Open(CCNxTransportConfig *transportConfig)
+{
+ assertNotNull(the_context, "The TransportContext is NULL.");
+ assertNotNull(transportConfig, "The parameter transportConfig must be a non-null CCNxTransportConfig pointer");
+ return the_context->ops.Open(the_context->transport_data, transportConfig);
+}
+
+int
+Transport_Send(int desc, CCNxMetaMessage *msg_in)
+{
+ assertNotNull(the_context, "the_context is null");
+ return the_context->ops.Send(the_context->transport_data, desc, msg_in, CCNxStackTimeout_Never);
+}
+
+TransportIOStatus
+Transport_Recv(int desc, CCNxMetaMessage **msg_out)
+{
+ return the_context->ops.Recv(the_context->transport_data, desc, msg_out, CCNxStackTimeout_Never);
+}
+
+int
+Transport_Close(int desc)
+{
+ return the_context->ops.Close(the_context->transport_data, desc);
+}
+
+int
+Transport_PassCommand(void *stackCommand)
+{
+ return the_context->ops.PassCommand(the_context->transport_data, stackCommand);
+}
+
+void
+Transport_Destroy(TransportContext **ctxPtr)
+{
+ assertNotNull(ctxPtr, "Transport_Destroy called with null context");
+ assertNotNull(*ctxPtr, "Transport_Destroy callled with reference to null");
+
+ TransportContext *ctx = *ctxPtr;
+
+ assertTrue(the_context == ctx, "Passed ctx is not the same");
+ assertTrue(ctx->references > 0, "Invalid reference count");
+
+ ctx->references--;
+ if (ctx->references == 0) {
+ ctx->ops.Destroy(&ctx->transport_data);
+ memset(ctx, 0, sizeof(TransportContext));
+ parcMemory_Deallocate((void **) &ctx);
+ ctx = NULL;
+ the_context = NULL;
+ }
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/transport.h b/libccnx-transport-rta/ccnx/transport/common/transport.h
new file mode 100644
index 00000000..1068d37d
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/transport.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file transport.h
+ * @brief Defines the Transport API from the App API.
+ *
+ * Application interfaces use this API to communicate
+ * with the transport.
+ *
+ * An API will call transport_Create(type), to create
+ * a transport of the given type. Only type TRANSPORT_RTA
+ * is supported at this time. Only one transport may exist,
+ * so multiple calls to transport_Create() will return
+ * a reference counted pointer to the same transport.
+ * When an API is done, it should call transport_Destroy().
+ *
+ * An API opens connections with the forwarder via
+ * transport_Open(PARCJSON *). The JSON dictionary defines
+ * the properties of the protocol stack associated with the
+ * connection. When done, the API should call transport_Close()
+ * on the connection. Multiple calls with the same JSON
+ * definition will return new connecitons using the same
+ * protocol stack.
+ *
+ * See the documentation in transport_rta/core/rta_Component.h
+ * about how to write a new component for use in a protocol stack.
+ *
+ *
+ * transport_Open() requires a JSON configuration string that
+ * defines the SYSTEM and USER parameters. SYSTEM parameters
+ * define the ProtocolStack. USER parameters are variations
+ * within a ProtocolStack, such as which signing keys to use.
+ *
+ * \code{.c}
+ * {
+ * "SYSTEM" : {
+ * "COMPONENTS" : [ array of identifiers ],
+ * <component name> : { component parameters },
+ * <component name> : { component parameters }
+ * }
+ *
+ * "USER" : {
+ * <component name> : {component parameters},
+ * <component name> : {component parameters},
+ * <component name> : {component parameters}
+ * }
+ * }
+ * \endcode
+ *
+ * The COMPONENTS parameter lists the comonents in the protocol stack.
+ * The names should be taken from components.h (e.g. API_CONNECTOR).
+ *
+ * An example would be:
+ * \code{.c}
+ * {
+ * "SYSTEM" : {
+ * "COMPONENTS" : [
+ * "API_CONNECTOR",
+ * "FC_VEGAS,
+ * "VERIFY_ENUMERATED",
+ * "CODEC_TLV",
+ * "FWD_FLAN"
+ * ],
+ * "FWD_FLAN" : { "port" : 1234 },
+ * "FC_VEGAS" : { "max_cwind": 65536 }
+ * }
+ *
+ * "USER" : {
+ * "CODEC_TLV" : {
+ * "SET_SIGNING_KEYSTORE" : {
+ * "KEYSTORE_NAME" : "/Users/alice/.ccnxkeystore",
+ * "KEYSTORE_PASSWD": "1234abcd"
+ * }
+ * }
+ *
+ * "VERIFY_ENUMERATED" : {
+ * "ADD_TRUSTED_CERTS" : [
+ * <PEM encoded X.509 cert>,
+ * <PEM encoded X.509 cert>,
+ * <PEM encoded X.509 cert> ]
+ * "ADD_TRUSTED_ISSUERS" : [
+ * <PEM encoded X.509 cert> ]
+ * "ADD_TRUSTED_KEYS" : [
+ * <PEM encoded RSA public key>,
+ * <PEM encoded DSA public key>]
+ * }
+ * }
+ * }
+ * \endcode
+ *
+ */
+#ifndef CCNX_TRANSPORT_H
+#define CCNX_TRANSPORT_H
+
+#include <ccnx/transport/common/transport_MetaMessage.h>
+
+#include <ccnx/common/internal/ccnx_TlvDictionary.h>
+
+#include <ccnx/transport/common/transport_Message.h>
+#include <ccnx/transport/common/ccnx_TransportConfig.h>
+
+struct transport_context;
+typedef struct transport_context TransportContext;
+
+typedef enum {
+ TRANSPORT_RTA
+} TransportTypes;
+
+typedef enum TransportIOStatus {
+ TransportIOStatus_Success = 0,
+ TransportIOStatus_Error = 1,
+ TransportIOStatus_Timeout = 2
+} TransportIOStatus;
+
+typedef uint64_t CCNxStackTimeout;
+
+/**
+ * @def CCNxStackTimeout_Never
+ * The receive function is a blocking read that never times out.
+ */
+#define CCNxStackTimeout_Never NULL
+
+/*
+ * @def CCNxStackTimeout_Immediate
+ * The receive function is a non-blocking read that immediately either returns a message or nothing.
+ * Equivalent to StackTimeout_MicroSeconds(0)
+ */
+#define CCNxStackTimeout_Immediate (& (uint64_t) { 0 })
+
+/*
+ * @def CCNxStackTimeout_MicroSeconds
+ * The receive function is a blocking read that either waits no longer than the specified number of microseconds or a message,
+ * whichever comes first.
+ */
+#define CCNxStackTimeout_MicroSeconds(_usec_) (& (uint64_t) { _usec_ })
+
+
+/**
+ * Initialize transport. Creates a thread of execution,
+ * you only need one of these.
+ *
+ * You can only have one of these. Multiple calls return a
+ * reference to the existing one (if same type) or an error.
+ *
+ * NULL means error.
+ */
+TransportContext *Transport_Create(TransportTypes type);
+
+/**
+ * Open a descriptor. You may use a select(2) or poll(2) on it, but
+ * you must only use Transport_{Send, Recv, Close} to modify it.
+ *
+ * All transport operations are non-blocking.
+ *
+ * Transport will take ownership of the transportConfig and destroy it and
+ * everyting contained in it.
+ *
+ * Generate the configuration based on your stacks configuration
+ * methods. For RTA, they are in transport_rta/config/.
+ *
+ * @param [in] transportConfig the transport configuration object
+ *
+ * @return the newly opened descriptor
+ *
+ * @see Transport_Close
+ */
+int Transport_Open(CCNxTransportConfig *transportConfig);
+
+/**
+ * Send a `CCNxMetaMessage` to the transport. The CCNxMetaMessage instance is acquired by
+ * the stack and can be released by the caller immediately after sending if desired.
+ *
+ * The CCNxMetaMessage may be a PARCJSON object to modify USER stack parameters.
+ *
+ * @param [in] desc the file descriptor (e.g. one end of a socket) in to which to write he CCNxMetaMessage.
+ * @param [in] msg_in A CCNxMetaMessage instance to send.
+ *
+ * @return 0 if the message was succesfully sent.
+ * @return -1 and sets errno, otherwise. errno will be set to EWOULDBLOCK if it would block.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *msg = ccnxMetaMessage_CreateFromContentObject(contentObject);
+ *
+ * int status = Transport_Send(desc, msg);
+ *
+ * ccnxMetaMessage_Release(&msg);
+ * }
+ * @endcode
+ *
+ * @see ccnxMetaMessage_Release
+ */
+int Transport_Send(int desc, CCNxMetaMessage *msg_in);
+
+/**
+ * Receive a `CCNxMetaMessage` from the transport. The caller is responsible
+ * for calling {@link ccnxMetaMessage_Release} on the message, if successful.
+ *
+ * @param [in] desc the file descriptor (e.g. one end of a socket) from which to read the CCNxMetaMessage.
+ * @param [in] msg_in A CCNxMetaMessage instance to send.
+ *
+ * @return 0 if the message was succesfully sent.
+ * @return -1 and sets errno, otherwise. errno will be set to EWOULDBLOCK if the call would block
+ * or if SO_RCVTIMEO is exceeded on the underlying socket.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *msg;
+ * int status = Transport_Recv(desc, &msg);
+ *
+ * if (status == 0) {
+ * // do things
+ *
+ * ccnxMetaMessage_Release(&msg);
+ * }
+ * }
+ * @endcode
+ *
+ * @see ccnxMetaMessage_Release
+ */
+TransportIOStatus Transport_Recv(int desc, CCNxMetaMessage **msg_out);
+
+/**
+ * Closes a descriptor. Close is immediate, any pending data is lost.
+ *
+ * @param [in] desc the descriptor to close
+ *
+ * @return 0 on success (the descriptor exists and was open)
+ *
+ * @see Transport_Open
+ */
+int Transport_Close(int desc);
+
+/**
+ * Pass a transport-specific command to the underlying framework.
+ * It must be in a "TransportTypes" format that your chosen
+ * transport understands.
+ */
+int Transport_PassCommand(void *stackCommand);
+
+/**
+ * Destroy a TransportContext instance. Shuts done all descriptors and any pending data is lost.
+ *
+ * @param [in] ctxP A pointer to a pointer to the TransportContext instance to release.
+ */
+void Transport_Destroy(TransportContext **ctxP);
+#endif // CCNX_TRANSPORT_H
diff --git a/libccnx-transport-rta/ccnx/transport/common/transport_Message.c b/libccnx-transport-rta/ccnx/transport/common/transport_Message.c
new file mode 100644
index 00000000..1a79ace2
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/transport_Message.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <strings.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include <LongBow/runtime.h>
+#include <parc/algol/parc_Memory.h>
+
+#include <ccnx/transport/common/transport.h>
+#include <ccnx/transport/common/transport_private.h>
+#include <ccnx/transport/common/transport_Message.h>
+
+#define DEBUG_OUTPUT 0
+
+struct transport_message {
+ CCNxTlvDictionary *dictionary;
+ TransportMessage_Free *freefunc;
+ void *info;
+
+ struct timeval creationTime;
+};
+
+static size_t _transport_messages_created = 0;
+static size_t _transport_messages_destroyed = 0;
+
+static void
+_transportMessage_GetTimeOfDay(struct timeval *outputTime)
+{
+#ifdef DEBUG
+ // if in debug mode, time messages
+ gettimeofday(outputTime, NULL);
+#else
+ *outputTime = (struct timeval) { 0, 0 };
+#endif
+}
+
+TransportMessage *
+transportMessage_CreateFromDictionary(CCNxTlvDictionary *dictionary)
+{
+ assertNotNull(dictionary, "Cannot create TransportMessage from NULL Dictionary");
+ if (dictionary == NULL) {
+ return NULL;
+ }
+
+ TransportMessage *tm = parcMemory_AllocateAndClear(sizeof(TransportMessage));
+
+ if (tm != NULL) {
+ tm->dictionary = ccnxTlvDictionary_Acquire(dictionary);
+
+ _transportMessage_GetTimeOfDay(&tm->creationTime);
+
+ _transport_messages_created++;
+
+ if (DEBUG_OUTPUT) {
+ printf("%-35s allocs %zu destroys %zu pointer %p dict %p\n",
+ __func__,
+ _transport_messages_created,
+ _transport_messages_destroyed,
+ (void *) tm,
+ (void *) dictionary);
+ }
+ }
+
+ return tm;
+}
+
+CCNxTlvDictionary *
+transportMessage_GetDictionary(TransportMessage *tm)
+{
+ assertNotNull(tm, "TransportMessage_GetWireMessage called on NULL transport message");
+ return tm->dictionary;
+}
+
+bool
+transportMessage_isValid(const TransportMessage *message)
+{
+ bool result = false;
+ if (message != NULL) {
+ result = true;
+ }
+
+ return result;
+}
+
+void
+transportMessage_AssertValid(const TransportMessage *message)
+{
+ assertTrue(transportMessage_isValid(message), "TransportMessage @ %p is invalid.", (void *) message);
+}
+
+/*
+ * Frees the TransportMessage wrapper, but user is responsible
+ * for destroying the inner pieces.
+ */
+static void
+_transportMessage_Destroy(TransportMessage **msgPtr)
+{
+ assertNotNull(msgPtr, "TransportMessage_Destroy called on NULL transport message pointer");
+ if (msgPtr != NULL) {
+ TransportMessage *msg = *msgPtr;
+ transportMessage_OptionalAssertValid(msg);
+
+ _transport_messages_destroyed++;
+
+ if (DEBUG_OUTPUT) {
+ printf("%-35s allocs %zu destroys %zu pointer %p\n",
+ __func__,
+ _transport_messages_created,
+ _transport_messages_destroyed,
+ (void *) msg);
+ }
+
+ if (msg->freefunc != NULL) {
+ msg->freefunc(&msg->info);
+ }
+
+ parcMemory_Deallocate((void **) &msg);
+ *msgPtr = NULL;
+ }
+}
+
+void
+transportMessage_Destroy(TransportMessage **tmPtr)
+{
+ TransportMessage *tm = *tmPtr;
+ assertNotNull(tmPtr, "called with NULL transport message double pointer");
+
+ assertNotNull(tm, "called with NULL transport message dereference");
+
+ if (tm->dictionary != NULL) {
+ ccnxTlvDictionary_Release(&tm->dictionary);
+ tm->dictionary = NULL;
+ }
+
+ _transportMessage_Destroy(tmPtr);
+}
+
+/*
+ * Add some stack payload to a transport message. Will not be freed.
+ */
+void
+transportMessage_SetInfo(TransportMessage *tm, void *info, TransportMessage_Free *freefunc)
+{
+ assertNotNull(tm, "%s called with NULL transport message", __func__);
+ tm->info = info;
+ tm->freefunc = freefunc;
+}
+
+void *
+transportMessage_GetInfo(const TransportMessage *tm)
+{
+ assertNotNull(tm, "%s called with NULL transport message", __func__);
+ return tm->info;
+}
+
+
+struct timeval
+transportMessage_GetDelay(const TransportMessage *tm)
+{
+ struct timeval now;
+ _transportMessage_GetTimeOfDay(&now);
+ timersub(&now, &tm->creationTime, &now);
+ return now;
+}
+
+bool
+transportMessage_IsControl(const TransportMessage *tm)
+{
+ return ccnxTlvDictionary_IsControl(tm->dictionary);
+}
+
+bool
+transportMessage_IsInterest(const TransportMessage *tm)
+{
+ return ccnxTlvDictionary_IsInterest(tm->dictionary);
+}
+
+bool
+transportMessage_IsContentObject(const TransportMessage *tm)
+{
+ return ccnxTlvDictionary_IsContentObject(tm->dictionary);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/transport_Message.h b/libccnx-transport-rta/ccnx/transport/common/transport_Message.h
new file mode 100644
index 00000000..5f79fc3b
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/transport_Message.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file transport_Message.h
+ * @brief <#Brief Description#>
+ *
+ * NOTE: TransportMessage is being phased out for the CCNxTlvDictionary
+ *
+ */
+#ifndef Libccnx_transport_Message_h
+#define Libccnx_transport_Message_h
+
+#include <ccnx/common/codec/ccnxCodec_NetworkBuffer.h>
+
+#include <ccnx/common/internal/ccnx_TlvDictionary.h>
+
+struct transport_message;
+/**
+ *
+ * @see TransportMessage_CreateFromCcnxMessage
+ * @see TransportMessage_CreateFromMessage
+ */
+typedef struct transport_message TransportMessage;
+
+/**
+ * Stores a reference to the given dictionary
+ *
+ * The caller is responsible for releasing 'dictionary' as the transport message stores its own reference.
+ *
+ * @param [in] dictionary A pointer to a valid `CCNxTlvDictionary`
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+TransportMessage *transportMessage_CreateFromDictionary(CCNxTlvDictionary *dictionary);
+
+bool transportMessage_isValid(const TransportMessage *message);
+
+#ifdef TransportLibrary_DISABLE_VALIDATION
+# define transportMessage_OptionalAssertValid(_instance_)
+#else
+# define transportMessage_OptionalAssertValid(_instance_) transportMessage_AssertValid(_instance_)
+#endif
+/**
+ * Assert that the given `TransportMessage` instance is valid.
+ *
+ * @param [in] message A pointer to a valid TransportMessage instance.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportMessage *a = transportMessage_CreateFromDictionary(dictionary);
+ *
+ * transportMessage_AssertValid(a);
+ *
+ * printf("Instance is valid.\n");
+ *
+ * transportMessage_Release(&b);
+ * }
+ * @endcode
+ */
+void transportMessage_AssertValid(const TransportMessage *message);
+
+/**
+ * <#One Line Description#>
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+CCNxTlvDictionary *transportMessage_GetDictionary(TransportMessage *tm);
+
+/**
+ * Destroy the transport message and everything inside it
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ *
+ * @see <#references#>
+ */
+void transportMessage_Destroy(TransportMessage **tmPtr);
+
+typedef void (TransportMessage_Free)(void **);
+
+/**
+ * <#One Line Description#>
+ *
+ * Add some stack payload to a transport message.
+ * Will not be freed.
+ * This is typically used to put a pointer to the RtaConnection in the message.
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ *
+ * @see <#references#>
+ */
+void transportMessage_SetInfo(TransportMessage *tm, void *info, TransportMessage_Free *freefunc);
+
+/**
+ * <#One Line Description#>
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ *
+ * @see <#references#>
+ */
+void *transportMessage_GetInfo(const TransportMessage *tm);
+
+bool transportMessage_IsControl(const TransportMessage *tm);
+bool transportMessage_IsInterest(const TransportMessage *tm);
+bool transportMessage_IsContentObject(const TransportMessage *tm);
+
+/**
+ * If in DEBUG mode, returns how long the message has been in the system
+ *
+ * If not in DEBUG mode, will always be {.tv_sec = 0, .tv_usec = 0}. The time is based
+ * on gettimeofday().
+ *
+ * @param [<#in out in,out#>] <#name#> <#description#>
+ *
+ * @return <#value#> <#explanation#>
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+struct timeval transportMessage_GetDelay(const TransportMessage *tm);
+#endif // Libccnx_transport_Message_h
diff --git a/libccnx-transport-rta/ccnx/transport/common/transport_MetaMessage.c b/libccnx-transport-rta/ccnx/transport/common/transport_MetaMessage.c
new file mode 100644
index 00000000..a455e7ac
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/transport_MetaMessage.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include <LongBow/runtime.h>
+
+#include <ccnx/transport/common/transport_MetaMessage.h>
+#include <ccnx/common/codec/ccnxCodec_TlvPacket.h>
+#include <ccnx/common/ccnx_WireFormatMessage.h>
+#include <ccnx/common/ccnx_Manifest.h>
+
+CCNxMetaMessage *
+ccnxMetaMessage_CreateFromInterest(const CCNxInterest *interest)
+{
+ return ccnxMetaMessage_Acquire((CCNxMetaMessage *) interest);
+}
+
+CCNxMetaMessage *
+ccnxMetaMessage_CreateFromContentObject(const CCNxContentObject *contentObject)
+{
+ return ccnxMetaMessage_Acquire((CCNxMetaMessage *) contentObject);
+}
+
+CCNxMetaMessage *
+ccnxMetaMessage_CreateFromControl(const CCNxControl *control)
+{
+ return ccnxMetaMessage_Acquire((CCNxMetaMessage *) control);
+}
+
+CCNxMetaMessage *
+ccnxMetaMessage_CreateFromManifest(const CCNxManifest *manifest)
+{
+ return ccnxMetaMessage_Acquire((CCNxMetaMessage *) manifest);
+}
+
+
+CCNxContentObject *
+ccnxMetaMessage_GetContentObject(const CCNxMetaMessage *message)
+{
+ return (CCNxContentObject *) message;
+}
+
+CCNxInterest *
+ccnxMetaMessage_GetInterest(const CCNxMetaMessage *message)
+{
+ return (CCNxInterest *) message;
+}
+
+CCNxInterestReturn *
+ccnxMetaMessage_GetInterestReturn(const CCNxMetaMessage *message)
+{
+ return (CCNxInterestReturn *) message;
+}
+
+CCNxControl *
+ccnxMetaMessage_GetControl(const CCNxMetaMessage *message)
+{
+ return (CCNxControl *) message;
+}
+
+CCNxManifest *
+ccnxMetaMessage_GetManifest(const CCNxMetaMessage *message)
+{
+ return (CCNxManifest *) message;
+}
+
+CCNxMetaMessage *
+ccnxMetaMessage_Acquire(const CCNxMetaMessage *message)
+{
+ return ccnxTlvDictionary_Acquire(message);
+}
+
+void
+ccnxMetaMessage_Release(CCNxMetaMessage **messagePtr)
+{
+ ccnxTlvDictionary_Release(messagePtr);
+}
+
+void
+ccnxMetaMessage_Display(const CCNxMetaMessage *message, int indentation)
+{
+ ccnxTlvDictionary_Display(message, indentation);
+}
+
+bool
+ccnxMetaMessage_IsContentObject(const CCNxMetaMessage *message)
+{
+ return ccnxTlvDictionary_IsContentObject(message);
+}
+
+bool
+ccnxMetaMessage_IsInterest(const CCNxMetaMessage *message)
+{
+ return ccnxTlvDictionary_IsInterest(message);
+}
+
+bool
+ccnxMetaMessage_IsInterestReturn(const CCNxMetaMessage *message)
+{
+ return ccnxTlvDictionary_IsInterestReturn(message);
+}
+
+bool
+ccnxMetaMessage_IsControl(const CCNxMetaMessage *message)
+{
+ return ccnxTlvDictionary_IsControl(message);
+}
+
+bool
+ccnxMetaMessage_IsManifest(const CCNxMetaMessage *message)
+{
+ return ccnxTlvDictionary_IsManifest(message);
+}
+
+/**
+ * Given an iovec encoded version of a TlvDictionary, which is what we get when we call ccnxCodecTlvPacket_DictionaryEncode(),
+ * linearize it into a PARCBuffer so we can treat it as a PARCBuffer.
+ */
+static PARCBuffer *
+_iovecToParcBuffer(const CCNxCodecNetworkBufferIoVec *iovec)
+{
+ PARCBuffer *result = NULL;
+
+ size_t iovcnt = ccnxCodecNetworkBufferIoVec_GetCount((CCNxCodecNetworkBufferIoVec *) iovec);
+ const struct iovec *array = ccnxCodecNetworkBufferIoVec_GetArray((CCNxCodecNetworkBufferIoVec *) iovec);
+
+ size_t totalbytes = 0;
+ for (int i = 0; i < iovcnt; i++) {
+ totalbytes += array[i].iov_len;
+ }
+
+ result = parcBuffer_Allocate(totalbytes);
+ for (int i = 0; i < iovcnt; i++) {
+ parcBuffer_PutArray(result, array[i].iov_len, array[i].iov_base);
+ }
+
+ parcBuffer_Flip(result);
+
+
+ return result;
+}
+
+CCNxMetaMessage *
+ccnxMetaMessage_CreateFromWireFormatBuffer(PARCBuffer *rawMessage)
+{
+ CCNxMetaMessage *result = NULL;
+
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_Create(rawMessage);
+
+ if (message != NULL) {
+ // Get the dictionary from the ccnxWireFormatMessage.
+ CCNxTlvDictionary *dictionary = ccnxWireFormatMessage_GetDictionary(message);
+
+ // We have a partially unpacked dictionary now, but we need to more fully unpack it for our processing.
+ bool success = ccnxCodecTlvPacket_BufferDecode(rawMessage, dictionary);
+
+ if (success) {
+ result = (CCNxMetaMessage *) dictionary;
+ } else {
+ ccnxWireFormatMessage_Release(&message);
+ result = NULL;
+ }
+ }
+
+ return result;
+}
+
+PARCBuffer *
+ccnxMetaMessage_CreateWireFormatBuffer(CCNxMetaMessage *message, PARCSigner *signer)
+{
+ CCNxCodecNetworkBufferIoVec *iovec = ccnxCodecTlvPacket_DictionaryEncode(message, signer);
+
+ // iovec has the wireformat version of 'interest' now.
+
+ PARCBuffer *result = _iovecToParcBuffer(iovec);
+
+ ccnxCodecNetworkBufferIoVec_Release(&iovec);
+
+ return result;
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/transport_MetaMessage.h b/libccnx-transport-rta/ccnx/transport/common/transport_MetaMessage.h
new file mode 100644
index 00000000..f7dda45c
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/transport_MetaMessage.h
@@ -0,0 +1,515 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ccnx_MetaMessage.h
+ * @brief A CCNx message suitable for sending through the CCNx Portal API.
+ *
+ * A CCNxMetaMessage encapsulates a CCN Interest, ContentObject, or Control message, and can
+ * be read from and written to the CCNx Portal API.
+ *
+ */
+#ifndef libccnx_ccnx_MetaMessage_h
+#define libccnx_ccnx_MetaMessage_h
+
+#include <ccnx/common/ccnx_Interest.h>
+#include <ccnx/common/ccnx_InterestReturn.h>
+#include <ccnx/common/ccnx_ContentObject.h>
+#include <ccnx/common/ccnx_Manifest.h>
+#include <ccnx/common/ccnx_WireFormatMessage.h>
+
+#include <ccnx/common/internal/ccnx_TlvDictionary.h>
+
+#include <ccnx/api/control/cpi_ControlMessage.h>
+
+/**
+ * @typedef CCNxMetaMessage
+ * @brief A CCNxMetaMessage encapsulates a CCN Interest, ContentObject, or Control message.
+ */
+typedef CCNxTlvDictionary CCNxMetaMessage;
+
+
+/**
+ * Create a `CCNxMetaMessage` instance containing the given {@link CCNxInterest}.
+ *
+ * A new reference to the `CCNxInterest` is created.
+ *
+ * @param [in] interest A pointer to a valid `CCNxInterest` instance.
+ *
+ * @return NULL The `CCNxInterest` is not valid, or memory could not be allocated.
+ * @return non-NULL A pointer to a `CCNxMetaMessage` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(interest);
+ * }
+ * @endcode
+ */
+CCNxMetaMessage *ccnxMetaMessage_CreateFromInterest(const CCNxInterest *interest);
+
+/**
+ * Create a `CCNxMetaMessage` instance containing the given {@link CCNxContentObject}.
+ *
+ * A new reference to the `CCNxContentObject` is created.
+ *
+ * @param [in] contentObject A pointer to a valid `CCNxContentObject` instance.
+ *
+ * @return NULL The `CCNxContentObject` is not valid, or memory could not be allocated.
+ * @return non-NULL A pointer to a `CCNxMetaMessage` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxMetaMessage_CreateFromContentObject(contentObject);
+ * }
+ * @endcode
+ */
+CCNxMetaMessage *ccnxMetaMessage_CreateFromContentObject(const CCNxContentObject *contentObject);
+
+/**
+ * Create a `CCNxMetaMessage` instance containing the given {@link CCNxControl}.
+ *
+ * A new reference to the `CCNxControl` is created.
+ *
+ * @param [in] control A pointer to a valid `CCNxControl` instance.
+ *
+ * @return NULL The `CCNxControl` is not valid, or memory could not be allocated.
+ * @return non-NULL A pointer to a `CCNxMetaMessage` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxMetaMessage_CreateFromControl(control);
+ * }
+ * @endcode
+ */
+CCNxMetaMessage *ccnxMetaMessage_CreateFromControl(const CCNxControl *control);
+
+/**
+ * Create a `CCNxMetaMessage` instance containing the given {@link CCNxManifest}.
+ *
+ * A new reference to the `CCNxManifest` is created.
+ *
+ * @param [in] control A pointer to a valid `CCNxManifest` instance.
+ *
+ * @return NULL The `CCNxManifest` is not valid, or memory could not be allocated.
+ * @return non-NULL A pointer to a `CCNxMetaMessage` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxMetaMessage_CreateFromManifest(manifest);
+ * }
+ * @endcode
+ */
+CCNxMetaMessage *ccnxMetaMessage_CreateFromManifest(const CCNxManifest *manifest);
+
+/**
+ * Print a human readable representation of the given `CCNxMetaMessage` instance.
+ *
+ * @param [in] message A pointer to the `CCNxMetaMessage` to display.
+ * @param [in] indentation The level of indentation to use to pretty-print the output.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(...);
+ *
+ * ccnxMetaMessage_Display(message, 0);
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ *
+ */
+void ccnxMetaMessage_Display(const CCNxMetaMessage *message, int indentation);
+
+/**
+ * Increase the number of references to a `CCNxMetaMessage`.
+ *
+ * Note that new `CCNxMetaMessage` is not created,
+ * only that the given `CCNxMetaMessage` reference count is incremented.
+ * Discard the reference by invoking {@link ccnxMetaMessage_Release}().
+ *
+ * @param [in] instance A pointer to a `CCNxMetaMessage` instance.
+ * @return The input @p instance.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ * CCNxMetaMessage *messageReference = ccnxMetaMessage_Acquire(message);
+ *
+ * ccnxMetaMessage_Release(&message);
+ * ccnxMetaMessage_Release(&messageReference);
+ * }
+ * @endcode
+ * @see `ccnxMetaMessage_Release`
+ */
+CCNxMetaMessage *ccnxMetaMessage_Acquire(const CCNxMetaMessage *instance);
+
+/**
+ * Determine whether a specified `CCNxMetaMessage` instance encapsulates an {@link CCNxInterest}.
+ *
+ * Returns `true` if the underlying message is a `CCNxInterest`.
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return `true` If the underlying message is a `CCNxInterest`.
+ * @return `false` If the underlying message is not a `CCNxInterest`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsInterest(message)) {
+ * CCNxInterest *interest = ccnxMetaMessage_GetInterest(message);
+ * ...
+ * ccnxInterest_Release(&interest);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ * @see CCNxInterest
+ */
+bool ccnxMetaMessage_IsInterest(const CCNxMetaMessage *message);
+
+/**
+ * Determine whether a specified `CCNxMetaMessage` instance encapsulates an {@link CCNxInterestReturn}.
+ *
+ * Returns `true` if the underlying message is a `CCNxInterestReturn`.
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return `true` If the underlying message is a `CCNxInterestReturn`.
+ * @return `false` If the underlying message is not a `CCNxInterestReturn`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsInterestReturn(message)) {
+ * CCNxInterestReturn *interestReturn = ccnxMetaMessage_GetInterestReturn(message);
+ *
+ * ...
+ * ccnxInterestReturn_Release(&interestReturn);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ * @see CCNxInterestReturn
+ */
+bool ccnxMetaMessage_IsInterestReturn(const CCNxMetaMessage *message);
+
+/**
+ * Determine whether a specified `CCNxMetaMessage` instance encapsulates a {@link CCNxContentObject}.
+ *
+ * Returns true if the underlying message is a `CCNxContentObject`.
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return `true` If the underlying message is a `CCNxContentObject`.
+ * @return `false` If the underlying message is not a `CCNxContentObject`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsContentObject(message)) {
+ * CCNxContentObject *contentObject = ccnxMetaMessage_GetContentObject(message);
+ * ...
+ * ccnxContentObject_Release(&contentObject);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ * @see `CCNxContentObject`
+ */
+bool ccnxMetaMessage_IsContentObject(const CCNxMetaMessage *message);
+
+/**
+ * Determine whether a specified `CCNxMetaMessage` instance encapsulates a {@link CCNxControl}.
+ *
+ * Returns true if the underlying message is a `CCNxControl`.
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return `true` If the underlying message is a `CCNxControl`.
+ * @return `false` If the underlying message is not a `CCNxControl`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsControl(message)) {
+ * CCNxControl *control = ccnxMetaMessage_GetControl(message);
+ * ...
+ * ccnxControl_Release(&control);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ * @see `CCNxControl`
+ */
+bool ccnxMetaMessage_IsControl(const CCNxMetaMessage *message);
+
+/**
+ * Determine whether a specified `CCNxMetaMessage` instance encapsulates a {@link CCNxManifest}.
+ *
+ * Returns true if the underlying message is a `CCNxManifest`.
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return `true` If the underlying message is a `CCNxManifest`.
+ * @return `false` If the underlying message is not a `CCNxManifest`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsManifest(message)) {
+ * CCNxManifest *control = ccnxMetaMessage_GetManifest(message);
+ * ...
+ * ccnxManifest_Release(&manifest);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ * @see `CCNxManifest`
+ */
+bool ccnxMetaMessage_IsManifest(const CCNxMetaMessage *message);
+
+/**
+ * Release a previously acquired reference to the specified instance,
+ * decrementing the reference count for the instance.
+ *
+ * The pointer to the instance is set to NULL as a side-effect of this function.
+ *
+ * If the invocation causes the last reference to the instance to be released,
+ * the instance is deallocated and the instance's implementation will perform
+ * additional cleanup and release other privately held references.
+ *
+ * @param [in,out] messagePtr A pointer to a pointer to the instance to release.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ * CCNxMetaMessage *messageReference = ccnxMetaMessage_Acquire(message);
+ *
+ * ccnxMetaMessage_Release(&message);
+ * ccnxMetaMessage_Release(&messageReference);
+ * }
+ * @endcode
+ * @see {@link ccnxMetaMessage_Acquire}
+ */
+void ccnxMetaMessage_Release(CCNxMetaMessage **messagePtr);
+
+/**
+ * Return a new {@link CCNxContentObject} instance created from the `CCNxMetaMessage`.
+ *
+ * The newly created `CCNxContentObject` instance must eventually be released by calling {@link ccnxContentObject_Release}().
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return A new `CCNxContentObject` instance, which must eventually be released by calling `ccnxContentObject_Release()`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsContentObject(message)) {
+ * CCNxContentObject *contentObject = ccnxMetaMessage_GetContentObject(message);
+ * ...
+ * ccnxContentObject_Release(&contentObject);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ *
+ * @see `ccnxContentObject_Release`
+ * @see {@link ccnxMetaMessage_IsContentObject}
+ */
+CCNxContentObject *ccnxMetaMessage_GetContentObject(const CCNxMetaMessage *message);
+
+/**
+ * Return a new {@link CCNxInterest} instance created from the `CCNxMetaMessage`.
+ *
+ * The newly created `CCNxInterest}\` instance must eventually be released by calling {@link ccnxInterest_Release}().
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return A new `CCNxInterest` instance, which must eventually be released by calling `ccnxInterest_Release()`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsInterest(message)) {
+ * CCNxInterest *interest = ccnxMetaMessage_GetInterest(message);
+ * ...
+ * ccnxInterest_Release(&interest);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ *
+ * @see `ccnxInterest_Release`
+ * @see {@link ccnxMetaMessage_IsInterest}
+ */
+CCNxInterest *ccnxMetaMessage_GetInterest(const CCNxMetaMessage *message);
+
+/**
+ * Return a new {@link CCNxInterestReturn} instance created from the `CCNxMetaMessage`.
+ *
+ * The newly created `CCNxInterestReturn}\` instance must eventually be released by calling {@link ccnxInterest_Release}().
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return A new `CCNxInterest` instance, which must eventually be released by calling `ccnxInterestReturn_Release()`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsInterestReturn(message)) {
+ * CCNxInterestReturn *interestReturn = ccnxMetaMessage_GetInterestReturn(message);
+ *
+ * ...
+ * ccnxInterestReturn_Release(&interestReturn);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ *
+ * @see `ccnxInterest_Release`
+ * @see {@link ccnxMetaMessage_IsInterest}
+ */
+CCNxInterest *ccnxMetaMessage_GetInterestReturn(const CCNxMetaMessage *message);
+
+/**
+ * Return a new {@link CCNxControl} instance created from the `CCNxMetaMessage`.
+ *
+ * The newly created `CCNxControl` instance must eventually be released by calling {@link ccnxControl_Release}().
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return A new `CCNxControl` instance, which must eventually be released by calling `ccnxControl_Release()`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsControl(message)) {
+ * CCNxControl *control = ccnxMetaMessage_GetControl(message);
+ * ...
+ * ccnxControl_Release(&control);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ *
+ * @see `ccnxControl_Release`
+ * @see {@link ccnxMetaMessage_IsControl}
+ */
+CCNxControl *ccnxMetaMessage_GetControl(const CCNxMetaMessage *message);
+
+/**
+ * Return a new {@link CCNxManifest} instance created from the `CCNxMetaMessage`.
+ *
+ * The newly created `CCNxManifest` instance must eventually be released by calling {@link ccnxManifest_Release}().
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ *
+ * @return A new `CCNxManifest` instance, which must eventually be released by calling `ccnxManifest_Release()`.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxMetaMessage *message = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
+ *
+ * if (ccnxMetaMessage_IsManifest(message)) {
+ * CCNxManifest *manifest = ccnxMetaMessage_GetManifest(message);
+ * ...
+ * ccnxManifest_Release(&manifest);
+ * }
+ *
+ * ccnxMetaMessage_Release(&message);
+ * }
+ * @endcode
+ *
+ * @see {@link ccnxManifest_Release}
+ * @see {@link ccnxMetaMessage_IsManifest}
+ */
+CCNxManifest *ccnxMetaMessage_GetManifest(const CCNxMetaMessage *message);
+
+/**
+ * Return a new {@link CCNxMetaMessage} instance created from a wire format message
+ *
+ * The newly created `CCNxMetaMessage` instance must eventually be released by calling {@link CCNxMetaMessage_Release}().
+ *
+ * @param [in] message A pointer to a `PARCBuffer` instance containing a wire format message.
+ *
+ * @return A new `CCNxMetaMessage` instance, which must eventually be released by calling `ccnxMetaMessage_Release()`.
+ *
+ * Example:
+ * @code
+ * {
+ * }
+ * @endcode
+ *
+ */
+CCNxMetaMessage *ccnxMetaMessage_CreateFromWireFormatBuffer(PARCBuffer *rawMessage);
+
+/**
+ * Return a new {@link PARCBuffer} instance containing an encodeded wire format message created
+ * from the source `CCNxMetaMessage`.
+ *
+ * The newly created `PARCBuffer` instance must eventually be released by calling {@link parcBuffer_Release}().
+ *
+ * @param [in] message A pointer to a `CCNxMetaMessage` instance.
+ * @param [in] signer A pointer to a `PARCSigner` instance.
+ *
+ * @return A new `PARCBuffer` instance, which must eventually be released by calling `parcBuffer_Release()`.
+ *
+ * Example:
+ * @code
+ * {
+ * }
+ * @endcode
+ *
+ */
+PARCBuffer *ccnxMetaMessage_CreateWireFormatBuffer(CCNxMetaMessage *message, PARCSigner *signer);
+
+#endif // libccnx_ccnx_MetaMessage_h
diff --git a/libccnx-transport-rta/ccnx/transport/common/transport_Stack.c b/libccnx-transport-rta/ccnx/transport/common/transport_Stack.c
new file mode 100644
index 00000000..1d529710
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/transport_Stack.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include <parc/algol/parc_Object.h>
+#include <parc/algol/parc_DisplayIndented.h>
+#include <parc/algol/parc_Memory.h>
+
+#include <transport_Stack.h>
+
+struct TransportStack {
+ int topFD;
+ int bottomFD;
+};
+
+static void
+_transportStack_Finalize(TransportStack **instancePtr)
+{
+ assertNotNull(instancePtr, "Parameter must be a non-null pointer to a TransportStack pointer.");
+ TransportStack *instance = *instancePtr;
+
+ transportStack_OptionalAssertValid(instance);
+
+ /* cleanup the instance fields here */
+}
+
+parcObject_ImplementAcquire(transportStack, TransportStack);
+
+parcObject_ImplementRelease(transportStack, TransportStack);
+
+parcObject_ExtendPARCObject(TransportStack, _transportStack_Finalize, transportStack_Copy, transportStack_ToString, transportStack_Equals, transportStack_Compare, transportStack_HashCode, transportStack_ToJSON);
+
+
+void
+transportStack_AssertValid(const TransportStack *instance)
+{
+ assertTrue(transportStack_IsValid(instance),
+ "TransportStack is not valid.");
+}
+
+
+TransportStack *
+transportStack_Create(void)
+{
+ TransportStack *result = parcObject_CreateInstance(TransportStack);
+
+ return result;
+}
+
+int
+transportStack_Compare(const TransportStack *instance, const TransportStack *other)
+{
+ int result = 0;
+
+ return result;
+}
+
+TransportStack *
+transportStack_Copy(const TransportStack *original)
+{
+ TransportStack *result = NULL;
+
+ return result;
+}
+
+void
+transportStack_Display(const TransportStack *instance, int indentation)
+{
+ parcDisplayIndented_PrintLine(indentation, "TransportStack@%p {", instance);
+ /* Call Display() functions for the fields here. */
+ parcDisplayIndented_PrintLine(indentation, "}");
+}
+
+bool
+transportStack_Equals(const TransportStack *x, const TransportStack *y)
+{
+ bool result = false;
+
+ if (x == y) {
+ result = true;
+ } else if (x == NULL || y == NULL) {
+ result = false;
+ } else {
+ /* perform instance specific equality tests here. */
+ }
+
+ return result;
+}
+
+PARCHashCode
+transportStack_HashCode(const TransportStack *instance)
+{
+ PARCHashCode result = 0;
+
+ return result;
+}
+
+bool
+transportStack_IsValid(const TransportStack *instance)
+{
+ bool result = false;
+
+ if (instance != NULL) {
+ result = true;
+ }
+
+ return result;
+}
+
+PARCJSON *
+transportStack_ToJSON(const TransportStack *instance)
+{
+ PARCJSON *result = parcJSON_Create();
+
+ return result;
+}
+
+char *
+transportStack_ToString(const TransportStack *instance)
+{
+ char *result = parcMemory_Format("TransportStack@%p\n", instance);
+
+ return result;
+}
diff --git a/libccnx-transport-rta/ccnx/transport/common/transport_Stack.h b/libccnx-transport-rta/ccnx/transport/common/transport_Stack.h
new file mode 100644
index 00000000..6b38c2a5
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/transport_Stack.h
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file transport_Stack.h
+ * @brief <#Brief Description#>
+ *
+ * <#Detailed Description#>
+ *
+ */
+#ifndef libccnx_ccnx_transport_Stack
+#define libccnx_ccnx_transport_Stack
+#include <stdbool.h>
+
+#include <parc/algol/parc_JSON.h>
+#include <parc/algol/parc_HashCode.h>
+
+struct TransportStack;
+typedef struct TransportStack TransportStack;
+
+/**
+ * Increase the number of references to a `TransportStack` instance.
+ *
+ * Note that new `TransportStack` is not created,
+ * only that the given `TransportStack` reference count is incremented.
+ * Discard the reference by invoking `transportStack_Release`.
+ *
+ * @param [in] instance A pointer to a valid TransportStack instance.
+ *
+ * @return The same value as @p instance.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * TransportStack *b = transportStack_Acquire();
+ *
+ * transportStack_Release(&a);
+ * transportStack_Release(&b);
+ * }
+ * @endcode
+ */
+TransportStack *transportStack_Acquire(const TransportStack *instance);
+
+#ifdef LIBRTA_DISABLE_VALIDATION
+# define transportStack_OptionalAssertValid(_instance_)
+#else
+# define transportStack_OptionalAssertValid(_instance_) transportStack_AssertValid(_instance_)
+#endif
+
+/**
+ * Assert that the given `TransportStack` instance is valid.
+ *
+ * @param [in] instance A pointer to a valid TransportStack instance.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * transportStack_AssertValid(a);
+ *
+ * printf("Instance is valid.\n");
+ *
+ * transportStack_Release(&b);
+ * }
+ * @endcode
+ */
+void transportStack_AssertValid(const TransportStack *instance);
+
+/**
+ * Create an instance of TransportStack
+ *
+ * <#Paragraphs Of Explanation#>
+ *
+ * @return non-NULL A pointer to a valid TransportStack instance.
+ * @return NULL An error occurred.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * transportStack_Release(&a);
+ * }
+ * @endcode
+ */
+TransportStack *transportStack_Create(void);
+
+/**
+ * Compares @p instance with @p other for order.
+ *
+ * Returns a negative integer, zero, or a positive integer as @p instance
+ * is less than, equal to, or greater than @p other.
+ *
+ * @param [in] instance A pointer to a valid TransportStack instance.
+ * @param [in] other A pointer to a valid TransportStack instance.
+ *
+ * @return <0 Instance is less than @p other.
+ * @return 0 Instance a and instance b compare the same.
+ * @return >0 Instance a is greater than instance b.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ * TransportStack *b = transportStack_Create();
+ *
+ * if (transportStack_Compare(a, b) == 0) {
+ * printf("Instances are equal.\n");
+ * }
+ *
+ * transportStack_Release(&a);
+ * transportStack_Release(&b);
+ * }
+ * @endcode
+ *
+ * @see transportStack_Equals
+ */
+int transportStack_Compare(const TransportStack *instance, const TransportStack *other);
+
+/**
+ * Create an independent copy the given `PARCBuffer`
+ *
+ * A new buffer is created as a complete copy of the original.
+ *
+ * @param [in] original A pointer to a valid TransportStack instance.
+ *
+ * @return NULL Memory could not be allocated.
+ * @return non-NULL A pointer to a new `TransportStack` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * TransportStack *copy = transportStack_Copy(&b);
+ *
+ * transportStack_Release(&b);
+ * transportStack_Release(&copy);
+ * }
+ * @endcode
+ */
+TransportStack *transportStack_Copy(const TransportStack *original);
+
+/**
+ * Print a human readable representation of the given `TransportStack`.
+ *
+ * @param [in] instance A pointer to a valid TransportStack instance.
+ * @param [in] indentation The indentation level to use for printing.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * transportStack_Display(a, 0);
+ *
+ * transportStack_Release(&a);
+ * }
+ * @endcode
+ */
+void transportStack_Display(const TransportStack *instance, int indentation);
+
+/**
+ * Determine if two `TransportStack` instances are equal.
+ *
+ * The following equivalence relations on non-null `TransportStack` instances are maintained: *
+ * * It is reflexive: for any non-null reference value x, `transportStack_Equals(x, x)` must return true.
+ *
+ * * It is symmetric: for any non-null reference values x and y, `transportStack_Equals(x, y)` must return true if and only if
+ * `transportStack_Equals(y x)` returns true.
+ *
+ * * It is transitive: for any non-null reference values x, y, and z, if
+ * `transportStack_Equals(x, y)` returns true and
+ * `transportStack_Equals(y, z)` returns true,
+ * then `transportStack_Equals(x, z)` must return true.
+ *
+ * * It is consistent: for any non-null reference values x and y, multiple invocations of `transportStack_Equals(x, y)`
+ * consistently return true or consistently return false.
+ *
+ * * For any non-null reference value x, `transportStack_Equals(x, NULL)` must return false.
+ *
+ * @param [in] x A pointer to a valid TransportStack instance.
+ * @param [in] y A pointer to a valid TransportStack instance.
+ *
+ * @return true The instances x and y are equal.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ * TransportStack *b = transportStack_Create();
+ *
+ * if (transportStack_Equals(a, b)) {
+ * printf("Instances are equal.\n");
+ * }
+ *
+ * transportStack_Release(&a);
+ * transportStack_Release(&b);
+ * }
+ * @endcode
+ * @see transportStack_HashCode
+ */
+bool transportStack_Equals(const TransportStack *x, const TransportStack *y);
+
+/**
+ * Returns a hash code value for the given instance.
+ *
+ * The general contract of `HashCode` is:
+ *
+ * Whenever it is invoked on the same instance more than once during an execution of an application,
+ * the `HashCode` function must consistently return the same value,
+ * provided no information used in a corresponding comparisons on the instance is modified.
+ *
+ * This value need not remain consistent from one execution of an application to another execution of the same application.
+ * If two instances are equal according to the {@link transportStack_Equals} method,
+ * then calling the {@link transportStack_HashCode} method on each of the two instances must produce the same integer result.
+ *
+ * It is not required that if two instances are unequal according to the
+ * {@link transportStack_Equals} function,
+ * then calling the `transportStack_HashCode`
+ * method on each of the two objects must produce distinct integer results.
+ *
+ * @param [in] instance A pointer to a valid TransportStack instance.
+ *
+ * @return The hashcode for the given instance.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * PARCHashCode hashValue = transportStack_HashCode(buffer);
+ * transportStack_Release(&a);
+ * }
+ * @endcode
+ */
+PARCHashCode transportStack_HashCode(const TransportStack *instance);
+
+/**
+ * Determine if an instance of `TransportStack` is valid.
+ *
+ * Valid means the internal state of the type is consistent with its required current or future behaviour.
+ * This may include the validation of internal instances of types.
+ *
+ * @param [in] instance A pointer to a valid TransportStack instance.
+ *
+ * @return true The instance is valid.
+ * @return false The instance is not valid.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * if (transportStack_IsValid(a)) {
+ * printf("Instance is valid.\n");
+ * }
+ *
+ * transportStack_Release(&a);
+ * }
+ * @endcode
+ *
+ */
+bool transportStack_IsValid(const TransportStack *instance);
+
+/**
+ * Release a previously acquired reference to the given `TransportStack` instance,
+ * decrementing the reference count for the instance.
+ *
+ * The pointer to the instance is set to NULL as a side-effect of this function.
+ *
+ * If the invocation causes the last reference to the instance to be released,
+ * the instance is deallocated and the instance's implementation will perform
+ * additional cleanup and release other privately held references.
+ *
+ * @param [in,out] instancePtr A pointer to a pointer to the instance to release.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * transportStack_Release(&a);
+ * }
+ * @endcode
+ */
+void transportStack_Release(TransportStack **instancePtr);
+
+/**
+ * Create a `PARCJSON` instance (representation) of the given object.
+ *
+ * @param [in] instance A pointer to a valid TransportStack instance.
+ *
+ * @return NULL Memory could not be allocated to contain the `PARCJSON` instance.
+ * @return non-NULL An allocated C string that must be deallocated via parcMemory_Deallocate().
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * PARCJSON *json = transportStack_ToJSON(a);
+ *
+ * printf("JSON representation: %s\n", parcJSON_ToString(json));
+ * parcJSON_Release(&json);
+ *
+ * transportStack_Release(&a);
+ * }
+ * @endcode
+ */
+PARCJSON *transportStack_ToJSON(const TransportStack *instance);
+
+/**
+ * Produce a null-terminated string representation of the specified `TransportStack`.
+ *
+ * The result must be freed by the caller via {@link parcMemory_Deallocate}.
+ *
+ * @param [in] instance A pointer to a valid TransportStack instance.
+ *
+ * @return NULL Cannot allocate memory.
+ * @return non-NULL A pointer to an allocated, null-terminated C string that must be deallocated via {@link parcMemory_Deallocate}.
+ *
+ * Example:
+ * @code
+ * {
+ * TransportStack *a = transportStack_Create();
+ *
+ * char *string = transportStack_ToString(a);
+ *
+ * transportStack_Release(&a);
+ *
+ * parcMemory_Deallocate(&string);
+ * }
+ * @endcode
+ *
+ * @see transportStack_Display
+ */
+char *transportStack_ToString(const TransportStack *instance);
+#endif
diff --git a/libccnx-transport-rta/ccnx/transport/common/transport_private.h b/libccnx-transport-rta/ccnx/transport/common/transport_private.h
new file mode 100644
index 00000000..a06b74be
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/common/transport_private.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file transport_private.h
+ * @brief <#Brief Description#>
+ *
+ * <#Detailed Description#>
+ *
+ */
+#ifndef Libccnx_transport_private_h
+#define Libccnx_transport_private_h
+
+#include <ccnx/transport/common/transport_MetaMessage.h>
+#include <ccnx/transport/common/ccnx_TransportConfig.h>
+
+struct transport_operations {
+ void* (*Create)(void);
+ int (*Open)(void *ctx, CCNxTransportConfig *transportConfig);
+ int (*Send)(void *ctx, int desc, CCNxMetaMessage *msg, const struct timeval *timeout);
+ TransportIOStatus (*Recv)(void *ctx, int desc, CCNxMetaMessage **msg, const struct timeval *timeout);
+ int (*Close)(void *ctx, int desc);
+ int (*Destroy)(void **ctx);
+ int (*PassCommand)(void *ctx, void *command);
+};
+#endif // Libccnx_transport_private_h