aboutsummaryrefslogtreecommitdiffstats
path: root/libccnx-transport-rta/ccnx/transport/transport_rta/commands
diff options
context:
space:
mode:
Diffstat (limited to 'libccnx-transport-rta/ccnx/transport/transport_rta/commands')
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.c365
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.h619
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.c61
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.h145
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.c113
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.h274
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.c59
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.h141
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.c96
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.h219
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.c81
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.h125
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/.gitignore7
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/CMakeLists.txt18
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_Command.c475
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandCloseConnection.c125
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandCreateProtocolStack.c215
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandDestroyProtocolStack.c125
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandOpenConnection.c199
-rw-r--r--libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandTransmitStatistics.c170
20 files changed, 3632 insertions, 0 deletions
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.c
new file mode 100644
index 00000000..4e0e91d0
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.c
@@ -0,0 +1,365 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implements the single wrapper for commands sent over the command channel
+ *
+ */
+
+#include <config.h>
+
+#include <LongBow/runtime.h>
+
+#include <stdio.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Object.h>
+#include <parc/algol/parc_DisplayIndented.h>
+
+#include <ccnx/transport/transport_rta/commands/rta_Command.h>
+
+/*
+ * Internal definition of command types
+ */
+typedef enum {
+ RtaCommandType_Unknown = 0,
+ RtaCommandType_CreateProtocolStack,
+ RtaCommandType_OpenConnection,
+ RtaCommandType_CloseConnection,
+ RtaCommandType_DestroyProtocolStack,
+ RtaCommandType_ShutdownFramework,
+ RtaCommandType_TransmitStatistics,
+ RtaCommandType_Last
+} _RtaCommandType;
+
+struct rta_command {
+ _RtaCommandType type;
+
+ union {
+ RtaCommandCloseConnection *closeConnection;
+ RtaCommandOpenConnection *openConnection;
+ RtaCommandCreateProtocolStack *createStack;
+ RtaCommandDestroyProtocolStack *destroyStack;
+ RtaCommandTransmitStatistics *transmitStats;
+
+ // shutdown framework has no value it will be NULL
+ // Statistics has no value
+ void *noValue;
+ } value;
+};
+
+static struct commandtype_to_string {
+ _RtaCommandType type;
+ const char *string;
+} _RtaCommandTypeToString[] = {
+ { .type = RtaCommandType_Unknown, .string = "Unknown" },
+ { .type = RtaCommandType_CreateProtocolStack, .string = "CreateProtocolStack" },
+ { .type = RtaCommandType_OpenConnection, .string = "OpenConnection" },
+ { .type = RtaCommandType_CloseConnection, .string = "CloseConnection" },
+ { .type = RtaCommandType_DestroyProtocolStack, .string = "DestroyProtocolStack" },
+ { .type = RtaCommandType_ShutdownFramework, .string = "ShutdownFramework" },
+ { .type = RtaCommandType_TransmitStatistics, .string = "TransmitStatistics" },
+ { .type = RtaCommandType_Last, .string = NULL },
+};
+
+// ===============================
+// Internal API
+
+static void
+_rtaCommand_Destroy(RtaCommand **commandPtr)
+{
+ RtaCommand *command = *commandPtr;
+ switch (command->type) {
+ case RtaCommandType_ShutdownFramework:
+ // no inner-release needed
+ break;
+
+ case RtaCommandType_CreateProtocolStack:
+ rtaCommandCreateProtocolStack_Release(&command->value.createStack);
+ break;
+
+ case RtaCommandType_OpenConnection:
+ rtaCommandOpenConnection_Release(&command->value.openConnection);
+ break;
+
+ case RtaCommandType_CloseConnection:
+ rtaCommandCloseConnection_Release(&command->value.closeConnection);
+ break;
+
+ case RtaCommandType_DestroyProtocolStack:
+ rtaCommandDestroyProtocolStack_Release(&command->value.destroyStack);
+ break;
+
+ case RtaCommandType_TransmitStatistics:
+ rtaCommandTransmitStatistics_Release(&command->value.transmitStats);
+ break;
+
+ default:
+ trapIllegalValue(command->type, "Illegal command type %d", command->type);
+ break;
+ }
+}
+
+#ifdef Transport_DISABLE_VALIDATION
+# define _rtaCommand_OptionalAssertValid(_instance_)
+#else
+# define _rtaCommand_OptionalAssertValid(_instance_) _rtaCommand_AssertValid(_instance_)
+#endif
+
+static void
+_rtaCommand_AssertValid(const RtaCommand *command)
+{
+ assertNotNull(command, "RtaCommand must be non-null");
+ assertTrue(RtaCommandType_Unknown < command->type && command->type < RtaCommandType_Last,
+ "Invalid RtaCommand type, must be %d < type %d < %d",
+ RtaCommandType_Unknown,
+ command->type,
+ RtaCommandType_Last);
+
+ switch (command->type) {
+ case RtaCommandType_ShutdownFramework:
+ assertNull(command->value.noValue, "RtaCommand value must be null for ShutdownFramework or Statistics");
+ break;
+
+ case RtaCommandType_CreateProtocolStack:
+ assertNotNull(command->value.createStack, "RtaCommand createStack member must be non-null");
+ break;
+
+ case RtaCommandType_OpenConnection:
+ assertNotNull(command->value.openConnection, "RtaCommand openConnection member must be non-null");
+ break;
+
+ case RtaCommandType_CloseConnection:
+ assertNotNull(command->value.closeConnection, "RtaCommand closeConnection member must be non-null");
+ break;
+
+ case RtaCommandType_DestroyProtocolStack:
+ assertNotNull(command->value.destroyStack, "RtaCommand destroyStack member must be non-null");
+ break;
+
+ case RtaCommandType_TransmitStatistics:
+ assertNotNull(command->value.transmitStats, "RtaCommand transmitStats member must be non-null");
+ break;
+
+ default:
+ trapIllegalValue(command->type, "Illegal command type %d", command->type);
+ break;
+ }
+}
+
+parcObject_ExtendPARCObject(RtaCommand, _rtaCommand_Destroy, NULL, NULL, NULL, NULL, NULL, NULL);
+
+parcObject_ImplementAcquire(rtaCommand, RtaCommand);
+
+parcObject_ImplementRelease(rtaCommand, RtaCommand);
+
+static RtaCommand *
+_rtaCommand_Allocate(_RtaCommandType type)
+{
+ RtaCommand *command = parcObject_CreateInstance(RtaCommand);
+ command->type = type;
+ return command;
+}
+
+static const char *
+_rtaCommand_TypeToString(const RtaCommand *command)
+{
+ for (int i = 0; _RtaCommandTypeToString[i].string != NULL; i++) {
+ if (_RtaCommandTypeToString[i].type == command->type) {
+ return _RtaCommandTypeToString[i].string;
+ }
+ }
+ trapUnexpectedState("Command is not a valid type: %d", command->type);
+}
+
+// ===============================
+// Public API
+
+void
+rtaCommand_Display(const RtaCommand *command, int indentation)
+{
+ _rtaCommand_OptionalAssertValid(command);
+
+ parcDisplayIndented_PrintLine(indentation, "RtaCommand type %s (%d) value pointer %p\n",
+ _rtaCommand_TypeToString(command), command->type, command->value);
+}
+
+/*
+ * Gets a reference to itself and puts it in the ring buffer
+ */
+bool
+rtaCommand_Write(const RtaCommand *command, PARCRingBuffer1x1 *commandRingBuffer)
+{
+ _rtaCommand_OptionalAssertValid(command);
+
+ RtaCommand *reference = rtaCommand_Acquire(command);
+
+ bool addedToRingBuffer = parcRingBuffer1x1_Put(commandRingBuffer, reference);
+
+ if (!addedToRingBuffer) {
+ // it was not stored in the ring, so we need to be responsible and release it
+ rtaCommand_Release(&reference);
+ }
+
+ return addedToRingBuffer;
+}
+
+RtaCommand *
+rtaCommand_Read(PARCRingBuffer1x1 *commandRingBuffer)
+{
+ RtaCommand *referenceFromRing = NULL;
+
+ bool fetchedReference = parcRingBuffer1x1_Get(commandRingBuffer, (void **) &referenceFromRing);
+ if (fetchedReference) {
+ return referenceFromRing;
+ }
+ return NULL;
+}
+
+// ======================
+// CLOSE CONNECTION
+
+bool
+rtaCommand_IsCloseConnection(const RtaCommand *command)
+{
+ _rtaCommand_OptionalAssertValid(command);
+ return (command->type == RtaCommandType_CloseConnection);
+}
+
+RtaCommand *
+rtaCommand_CreateCloseConnection(const RtaCommandCloseConnection *close)
+{
+ RtaCommand *command = _rtaCommand_Allocate(RtaCommandType_CloseConnection);
+ command->value.closeConnection = rtaCommandCloseConnection_Acquire(close);
+ return command;
+}
+
+const RtaCommandCloseConnection *
+rtaCommand_GetCloseConnection(const RtaCommand *command)
+{
+ assertTrue(rtaCommand_IsCloseConnection(command), "Command is not CloseConnection");
+ return command->value.closeConnection;
+}
+
+// ======================
+// OPEN CONNECTION
+
+bool
+rtaCommand_IsOpenConnection(const RtaCommand *command)
+{
+ _rtaCommand_OptionalAssertValid(command);
+ return (command->type == RtaCommandType_OpenConnection);
+}
+
+RtaCommand *
+rtaCommand_CreateOpenConnection(const RtaCommandOpenConnection *open)
+{
+ RtaCommand *command = _rtaCommand_Allocate(RtaCommandType_OpenConnection);
+ command->value.openConnection = rtaCommandOpenConnection_Acquire(open);
+ return command;
+}
+
+const RtaCommandOpenConnection *
+rtaCommand_GetOpenConnection(const RtaCommand *command)
+{
+ assertTrue(rtaCommand_IsOpenConnection(command), "Command is not OpenConnection");
+ return command->value.openConnection;
+}
+
+// ======================
+// CREATE STACK
+
+bool
+rtaCommand_IsCreateProtocolStack(const RtaCommand *command)
+{
+ _rtaCommand_OptionalAssertValid(command);
+ return (command->type == RtaCommandType_CreateProtocolStack);
+}
+
+RtaCommand *
+rtaCommand_CreateCreateProtocolStack(const RtaCommandCreateProtocolStack *createStack)
+{
+ RtaCommand *command = _rtaCommand_Allocate(RtaCommandType_CreateProtocolStack);
+ command->value.createStack = rtaCommandCreateProtocolStack_Acquire(createStack);
+ return command;
+}
+
+const RtaCommandCreateProtocolStack *
+rtaCommand_GetCreateProtocolStack(const RtaCommand *command)
+{
+ assertTrue(rtaCommand_IsCreateProtocolStack(command), "Command is not CreateProtocolStack");
+ return command->value.createStack;
+}
+
+bool
+rtaCommand_IsDestroyProtocolStack(const RtaCommand *command)
+{
+ _rtaCommand_OptionalAssertValid(command);
+ return (command->type == RtaCommandType_DestroyProtocolStack);
+}
+
+RtaCommand *
+rtaCommand_CreateDestroyProtocolStack(const RtaCommandDestroyProtocolStack *destroyStack)
+{
+ RtaCommand *command = _rtaCommand_Allocate(RtaCommandType_DestroyProtocolStack);
+ command->value.destroyStack = rtaCommandDestroyProtocolStack_Acquire(destroyStack);
+ return command;
+}
+
+const RtaCommandDestroyProtocolStack *
+rtaCommand_GetDestroyProtocolStack(const RtaCommand *command)
+{
+ assertTrue(rtaCommand_IsDestroyProtocolStack(command), "Command is not DestroyProtocolStack");
+ return command->value.destroyStack;
+}
+
+bool
+rtaCommand_IsShutdownFramework(const RtaCommand *command)
+{
+ _rtaCommand_OptionalAssertValid(command);
+ return (command->type == RtaCommandType_ShutdownFramework);
+}
+
+RtaCommand *
+rtaCommand_CreateShutdownFramework(void)
+{
+ RtaCommand *command = _rtaCommand_Allocate(RtaCommandType_ShutdownFramework);
+ command->value.noValue = NULL;
+ return command;
+}
+
+// no getter
+
+bool
+rtaCommand_IsTransmitStatistics(const RtaCommand *command)
+{
+ _rtaCommand_OptionalAssertValid(command);
+ return (command->type == RtaCommandType_TransmitStatistics);
+}
+
+RtaCommand *
+rtaCommand_CreateTransmitStatistics(const RtaCommandTransmitStatistics *transmitStats)
+{
+ RtaCommand *command = _rtaCommand_Allocate(RtaCommandType_TransmitStatistics);
+ command->value.transmitStats = rtaCommandTransmitStatistics_Acquire(transmitStats);
+ return command;
+}
+
+const RtaCommandTransmitStatistics *
+rtaCommand_GetTransmitStatistics(const RtaCommand *command)
+{
+ assertTrue(rtaCommand_IsTransmitStatistics(command), "Command is not TransmitStatistics");
+ return command->value.transmitStats;
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.h b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.h
new file mode 100644
index 00000000..02973c54
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.h
@@ -0,0 +1,619 @@
+/*
+ * 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 rta_Command.h
+ * @brief Wraps individual commands and is written to/from a Ring Buffer
+ *
+ * The RtaCommand is the common wrapper for all the specific command types. It also supports functions to
+ * write it to a PARCRingBuffer and read from a one.
+ *
+ * The ShutdownFramework command is a little different than all the other commands. There are no parameters
+ * to this command, so there is no separate type for it. You can create an RtaCommand of this flavor and
+ * check for it (rtaCommand_IsShutdownFramework), but there is no Get function.
+ *
+ */
+#ifndef Libccnx_rta_Commands_h
+#define Libccnx_rta_Commands_h
+
+struct rta_command;
+typedef struct rta_command RtaCommand;
+
+#include <ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.h>
+#include <ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.h>
+#include <ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.h>
+#include <ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.h>
+#include <ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.h>
+
+#include <parc/concurrent/parc_RingBuffer_1x1.h>
+
+
+/**
+ * Writes a command to a Ring Buffer
+ *
+ * Creates a reference to the command and puts the reference on the ring buffer.
+ * The caller still owns their own reference to the command.
+ *
+ * This command does not involve a PARCNotifier. If using a notifier in conjunction
+ * with the ring buffer, the caller is reponsible for posting the notification after
+ * all ther writes are done.
+ *
+ * The function will not block. If the ring buffer is full, it will return false.
+ *
+ * @param [in] command The command to put (by reference) on the ring buffer.
+ * @param [in] commandRingBuffer The ring buffer to use
+ *
+ * @return true A reference was put on the ring buffer
+ * @return false Failed to put reference, likely because the ring buffer was full.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ *
+ * bool success = rtaCommand_Write(command, ring);
+ * if (!success) {
+ * // return error to user that we're backlogged
+ * }
+ *
+ * rtaCommand_Release(&command);
+ * }
+ * @endcode
+ */
+bool rtaCommand_Write(const RtaCommand *command, PARCRingBuffer1x1 *commandRingBuffer);
+
+/**
+ * Reads a command from a ring buffer
+ *
+ * If the buffer is empty, will return NULL.
+ *
+ * @param [in] commandRingBuffer The buffer to read
+ *
+ * @return non-null A valid command object
+ * @return null Could not read a whole command object
+ *
+ * Example:
+ * @code
+ * {
+ * PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(4, NULL);
+ * RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ *
+ * bool success = rtaCommand_Write(command, ring);
+ * assertTrue(success, "Failed to put command in to ring buffer");
+ *
+ * // We should now have two references
+ * assertTrue(parcObject_GetReferenceCount(command) == 2, "Wrong refernce count, got %zu expected %zu", parcObject_GetReferenceCount(command), 2);
+ *
+ * RtaCommand *test = rtaCommand_Read(ring);
+ * assertTrue(test == command, "Wrong pointers, got %p expected %p", (void *) test, (void *) command);
+ *
+ * rtaCommand_Release(&command);
+ * rtaCommand_Release(&test);
+ * parcRingBuffer1x1_Release(&ring);
+ * }
+ * @endcode
+ */
+RtaCommand *rtaCommand_Read(PARCRingBuffer1x1 *commandRingBuffer);
+
+/**
+ * Increase the number of references to a `RtaCommand`.
+ *
+ * Note that new `RtaCommand` is not created,
+ * only that the given `RtaCommand` reference count is incremented.
+ * Discard the reference by invoking `rtaCommand_Release`.
+ *
+ * @param [in] command The RtaCommand to reference.
+ *
+ * @return non-null A reference to `command`.
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ * RtaCommand *second = rtaCommand_Acquire(command);
+ *
+ * // release order does not matter
+ * rtaCommand_Release(&command);
+ * rtaCommand_Release(&second);
+ * }
+ * @endcode
+ */
+RtaCommand *rtaCommand_Acquire(const RtaCommand *command);
+
+/**
+ * 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] commandPtr A pointer to the object to release, will return NULL'd.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ * RtaCommand *second = rtaCommand_Acquire(command);
+ *
+ * // release order does not matter
+ * rtaCommand_Release(&command);
+ * rtaCommand_Release(&second);
+ * }
+ * @endcode
+ */
+void rtaCommand_Release(RtaCommand **commandPtr);
+
+/**
+ * Print a human readable representation of the given `RtaCommand`.
+ *
+ * @param [in] command A pointer to the instance to display.
+ * @param [in] indentation The level of indentation to use to pretty-print the output.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ * rtaCommand_Display(command, 0);
+ * rtaCommand_Release(&command);
+ * }
+ * @endcode
+ *
+ */
+void rtaCommand_Display(const RtaCommand *command, int indentation);
+
+// ======================
+// CLOSE CONNECTION
+
+
+/**
+ * Tests if the RtaCommand is of type CloseConnection
+ *
+ * Tests if the RtaCommand is of type CloseConnection. This will also assert the
+ * RtaCommand invariants, so the RtaCommand object must be a properly constructed object.
+ *
+ * @param [in] command An allocated RtaCommand ojbect
+ *
+ * @return true The object is of type CloseConnection
+ * @return false The object is of some other type
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(77);
+ * RtaCommand *command = rtaCommand_CreateCloseConnection(closeConnection);
+ * assertTrue(rtaCommand_IsCloseConnection(command), "Command is not CloseConnection");
+ * rtaCommand_Release(&command);
+ * rtaCommandCloseConnection_Release(&closeConnection);
+ * }
+ * @endcode
+ */
+bool rtaCommand_IsCloseConnection(const RtaCommand *command);
+
+/**
+ * Allocates and creates an RtaCommand object from a RtaCommandCloseConnection
+ *
+ * Allocates and creates an RtaCommand object from a RtaCommandCloseConnection
+ * by acquiring a reference to it and storing it in the RtaCommand. The caller
+ * may release their reference to `close` at any time.
+ *
+ * @param [in] close The specific command to make acquire a reference from.
+ *
+ * @return non-null A properly allocated and configured RtaCommand.
+ * @return null An error.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(77);
+ * RtaCommand *command = rtaCommand_CreateCloseConnection(closeConnection);
+ *
+ * // release order does not matter
+ * rtaCommand_Release(&command);
+ * rtaCommandCloseConnection_Release(&closeConnection);
+ * }
+ * @endcode
+ */
+RtaCommand *rtaCommand_CreateCloseConnection(const RtaCommandCloseConnection *close);
+
+/**
+ * Returns the internal RtaCommandCloseConnection object
+ *
+ * Returns the internal RtaCommandCloseConnection object, the user should not release it.
+ * The the RtaCommand is not of type CloseConnection, it will assert in its validation.
+ *
+ * @param [in] command The RtaCommand to query for the object.
+ *
+ * @return The RtaCommandCloseConnection object that constructed the RtaCommand.
+ *
+ * Example:
+ * @code
+ * RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(77);
+ * RtaCommand *command = rtaCommand_CreateCloseConnection(closeConnection);
+ *
+ * const RtaCommandCloseConnection *testValue = rtaCommand_GetCloseConnection(command);
+ * assertTrue(testValue == closeConnection, "Wrong pointer returned");
+ *
+ * rtaCommand_Release(&command);
+ * rtaCommandCloseConnection_Release(&closeConnection);
+ * @endcode
+ */
+const RtaCommandCloseConnection *rtaCommand_GetCloseConnection(const RtaCommand *command);
+
+// ======================
+// OPEN CONNECTION
+
+/**
+ * Tests if the RtaCommand is of type OpenConnection
+ *
+ * Tests if the RtaCommand is of type OpenConnection. This will also assert the
+ * RtaCommand invariants, so the RtaCommand object must be a properly constructed object.
+ *
+ * @param [in] command An allocated RtaCommand ojbect
+ *
+ * @return true The object is of type OpenConnection
+ * @return false The object is of some other type
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandOpenConnection *openConnection = rtaCommandOpenConnection_Create(111, 2341, 2450987, NULL);
+ * RtaCommand *command = rtaCommand_CreateOpenConnection(openConnection);
+ * assertTrue(rtaCommand_IsOpenConnection(command), "Command is not OpenConnection");
+ * rtaCommand_Release(&command);
+ * rtaCommandOpenConnection_Release(&openConnection);
+ * }
+ * @endcode
+ */
+bool rtaCommand_IsOpenConnection(const RtaCommand *command);
+
+/**
+ * Allocates and creates an RtaCommand object from a RtaCommandOpenConnection
+ *
+ * Allocates and creates an RtaCommand object from a RtaCommandOpenConnection
+ * by acquiring a reference to it and storing it in the RtaCommand. The caller
+ * may release their reference to `open` at any time.
+ *
+ * @param [in] open The specific command to make acquire a reference from.
+ *
+ * @return non-null A properly allocated and configured RtaCommand.
+ * @return null An error.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandOpenConnection *openConnection = rtaCommandOpenConnection_Create(111, 2341, 2450987, NULL);
+ * RtaCommand *command = rtaCommand_CreateOpenConnection(openConnection);
+ *
+ * // release order does not matter
+ * rtaCommand_Release(&command);
+ * rtaCommandOpenConnection_Release(&openConnection);
+ * }
+ * @endcode
+ */
+RtaCommand *rtaCommand_CreateOpenConnection(const RtaCommandOpenConnection *open);
+
+/**
+ * Returns the internal RtaCommandOpenConnection object
+ *
+ * Returns the internal RtaCommandOpenConnection object, the user should not release it.
+ * The the RtaCommand is not of type CloseConnection, it will assert in its validation.
+ *
+ * @param [in] command The RtaCommand to query for the object.
+ *
+ * @return The RtaCommandOpenConnection object that constructed the RtaCommand.
+ *
+ * Example:
+ * @code
+ * RtaCommandOpenConnection *openConnection = rtaCommandOpenConnection_Create(111, 2341, 2450987, NULL);
+ * RtaCommand *command = rtaCommand_CreateOpenConnection(openConnection);
+ *
+ * const RtaCommandOpenConnection *testValue = rtaCommand_GetOpenConnection(command);
+ * assertTrue(testValue == openConnection, "Wrong pointer returned");
+ *
+ * rtaCommand_Release(&command);
+ * rtaCommandOpenConnection_Release(&openConnection);
+ * @endcode
+ */
+const RtaCommandOpenConnection *rtaCommand_GetOpenConnection(const RtaCommand *command);
+
+// ======================
+// CREATE STACK
+
+/**
+ * Tests if the RtaCommand is of type CreateProtocolStack
+ *
+ * Tests if the RtaCommand is of type CreateProtocolStack. This will also assert the
+ * RtaCommand invariants, so the RtaCommand object must be a properly constructed object.
+ *
+ * @param [in] command An allocated RtaCommand ojbect
+ *
+ * @return true The object is of type CreateProtocolStack
+ * @return false The object is of some other type
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(111, config);
+ * RtaCommand *command = rtaCommand_CreateCreateProtocolStack(createStack);
+ * assertTrue(rtaCommand_IsCreateProtocolStack(command), "Command is not CreateProtocolStack");
+ * rtaCommand_Release(&command);
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+bool rtaCommand_IsCreateProtocolStack(const RtaCommand *command);
+
+/**
+ * Allocates and creates an RtaCommand object from a RtaCommandCreateProtocolStack
+ *
+ * Allocates and creates an RtaCommand object from a RtaCommandCreateProtocolStack
+ * by acquiring a reference to it and storing it in the RtaCommand. The caller
+ * may release their reference to `createStack` at any time.
+ *
+ * @param [in] createStack The specific command to make acquire a reference from.
+ *
+ * @return non-null A properly allocated and configured RtaCommand.
+ * @return null An error.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(111, config);
+ * RtaCommand *command = rtaCommand_CreateCreateProtocolStack(createStack);
+ *
+ * // release order does not matter
+ * rtaCommand_Release(&command);
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+RtaCommand *rtaCommand_CreateCreateProtocolStack(const RtaCommandCreateProtocolStack *createStack);
+
+/**
+ * Returns the internal RtaCommandCreateProtocolStack object
+ *
+ * Returns the internal RtaCommandCreateProtocolStack object, the user should not release it.
+ * The the RtaCommand is not of type CloseConnection, it will assert in its validation.
+ *
+ * @param [in] command The RtaCommand to query for the object.
+ *
+ * @return The RtaCommandCreateProtocolStack object that constructed the RtaCommand.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(111, config);
+ * RtaCommand *command = rtaCommand_CreateCreateProtocolStack(createStack);
+ *
+ * const RtaCommandOpenConnection *testValue = rtaCommand_GetOpenConnection(command);
+ * assertTrue(testValue == createStack, "Wrong pointer returned");
+ *
+ * rtaCommand_Release(&command);
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+const RtaCommandCreateProtocolStack *rtaCommand_GetCreateProtocolStack(const RtaCommand *command);
+
+// ======================
+// DESTROY STACK
+
+/**
+ * Tests if the RtaCommand is of type DestroyProtocolStack
+ *
+ * Tests if the RtaCommand is of type DestroyProtocolStack. This will also assert the
+ * RtaCommand invariants, so the RtaCommand object must be a properly constructed object.
+ *
+ * @param [in] command An allocated RtaCommand ojbect
+ *
+ * @return true The object is of type DestroyProtocolStack
+ * @return false The object is of some other type
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(77);
+ * RtaCommand *command = rtaCommand_CreateDestroyProtocolStack(destroyStack);
+ * assertTrue(rtaCommand_IsDestroyProtocolStack(command), "Command is not DestroyProtocolStack");
+ * rtaCommand_Release(&command);
+ * rtaCommandDestroyProtocolStack_Release(&destroyStack);
+ * }
+ * @endcode
+ */
+bool rtaCommand_IsDestroyProtocolStack(const RtaCommand *command);
+
+/**
+ * Allocates and creates an RtaCommand object from a RtaCommandDestroyProtocolStack
+ *
+ * Allocates and creates an RtaCommand object from a RtaCommandDestroyProtocolStack
+ * by acquiring a reference to it and storing it in the RtaCommand. The caller
+ * may release their reference to `destroyStack` at any time.
+ *
+ * @param [in] destroyStack The specific command to make acquire a reference from.
+ *
+ * @return non-null A properly allocated and configured RtaCommand.
+ * @return null An error.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(77);
+ * RtaCommand *command = rtaCommand_CreateDestroyProtocolStack(destroyStack);
+ *
+ * // release order does not matter
+ * rtaCommand_Release(&command);
+ * rtaCommandDestroyProtocolStack_Release(&destroyStack);
+ * }
+ * @endcode
+ */
+RtaCommand *rtaCommand_CreateDestroyProtocolStack(const RtaCommandDestroyProtocolStack *destroyStack);
+
+/**
+ * Returns the internal RtaCommandDestroyProtocolStack object
+ *
+ * Returns the internal RtaCommandDestroyProtocolStack object, the user should not release it.
+ * The the RtaCommand is not of type CloseConnection, it will assert in its validation.
+ *
+ * @param [in] command The RtaCommand to query for the object.
+ *
+ * @return The RtaCommandDestroyProtocolStack object that constructed the RtaCommand.
+ *
+ * Example:
+ * @code
+ * RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(77);
+ * RtaCommand *command = rtaCommand_CreateDestroyProtocolStack(destroyStack);
+ *
+ * const RtaCommandDestroyProtocolStack *testValue = rtaCommand_GetOpenConnection(command);
+ * assertTrue(testValue == destroyStack, "Wrong pointer returned");
+ *
+ * rtaCommand_Release(&command);
+ * rtaCommandDestroyProtocolStack_Release(&destroyStack);
+ * @endcode
+ */
+const RtaCommandDestroyProtocolStack *rtaCommand_GetDestroyProtocolStack(const RtaCommand *command);
+
+// ======================
+// SHUTDOWN FRAMEWORK
+
+/**
+ * Tests if the RtaCommand is of type ShutdownFramework
+ *
+ * Tests if the RtaCommand is of type ShutdownFramework. This will also assert the
+ * RtaCommand invariants, so the RtaCommand object must be a properly constructed object.
+ *
+ * The ShutdownFramework command has no parameters, so there is no rtaCommand_GetShutdownFramework() function.
+ *
+ * @param [in] command An allocated RtaCommand ojbect
+ *
+ * @return true The object is of type ShutdownFramework
+ * @return false The object is of some other type
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ * assertTrue(rtaCommand_IsShutdownFramework(command), "Command is not shutdown framework");
+ * rtaCommand_Release(&command);
+ * }
+ * @endcode
+ */
+bool rtaCommand_IsShutdownFramework(const RtaCommand *command);
+
+/**
+ * Allocates and creates an RtaCommand object of type ShutdownFramework.
+ *
+ * Allocates and creates an RtaCommand object of type ShutdownFramework.
+ * There are no parameters to ShutdownFramework, so there is no underlying type.
+ *
+ * @return non-null A properly allocated and configured RtaCommand.
+ * @return null An error.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ * rtaCommand_Release(&command);
+ * }
+ * @endcode
+ */
+RtaCommand *rtaCommand_CreateShutdownFramework(void);
+
+// ======================
+// TRANSMIT STATS
+
+/**
+ * Tests if the RtaCommand is of type TransmitStatistics
+ *
+ * Tests if the RtaCommand is of type TransmitStatistics. This will also assert the
+ * RtaCommand invariants, so the RtaCommand object must be a properly constructed object.
+ *
+ * @param [in] command An allocated RtaCommand ojbect
+ *
+ * @return true The object is of type TransmitStatistics
+ * @return false The object is of some other type
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandTransmitStatistics *transmitStats = rtaCommandTransmitStatistics_Create((struct timeval) { 1, 2 }, "filename");
+ * RtaCommand *command = rtaCommand_CreateTransmitStatistics(transmitStats);
+ * assertTrue(rtaCommand_IsTransmitStatistics(command), "Command is not TransmitStatistics");
+ * rtaCommand_Release(&command);
+ * rtaCommandTransmitStatistics_Release(&transmitStats);
+ * }
+ * @endcode
+ */
+bool rtaCommand_IsTransmitStatistics(const RtaCommand *command);
+
+/**
+ * Allocates and creates an RtaCommand object from a RtaCommandTransmitStatistics
+ *
+ * Allocates and creates an RtaCommand object from a RtaCommandTransmitStatistics
+ * by acquiring a reference to it and storing it in the RtaCommand. The caller
+ * may release their reference to `transmitStats` at any time.
+ *
+ * @param [in] transmitStats The specific command to make acquire a reference from.
+ *
+ * @return non-null A properly allocated and configured RtaCommand.
+ * @return null An error.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandTransmitStatistics *transmitStats = rtaCommandTransmitStatistics_Create((struct timeval) { 1, 2 }, "filename");
+ * RtaCommand *command = rtaCommand_CreateTransmitStatistics(transmitStats);
+ *
+ * // release order does not matter
+ * rtaCommand_Release(&command);
+ * rtaCommandTransmitStatistics_Release(&transmitStats);
+ * }
+ * @endcode
+ */
+RtaCommand *rtaCommand_CreateTransmitStatistics(const RtaCommandTransmitStatistics *transmitStats);
+
+/**
+ * Returns the internal RtaCommandTransmitStatistics object
+ *
+ * Returns the internal RtaCommandTransmitStatistics object, the user should not release it.
+ * The the RtaCommand is not of type CloseConnection, it will assert in its validation.
+ *
+ * @param [in] command The RtaCommand to query for the object.
+ *
+ * @return The RtaCommandTransmitStatistics object that constructed the RtaCommand.
+ *
+ * Example:
+ * @code
+ * RtaCommandTransmitStatistics *transmitStats = rtaCommandTransmitStatistics_Create((struct timeval) { 1, 2 }, "filename");
+ * RtaCommand *command = rtaCommand_CreateTransmitStatistics(transmitStats);
+ *
+ * const RtaCommandDestroyProtocolStack *testValue = rtaCommand_GetOpenConnection(command);
+ * assertTrue(testValue == destroyStack, "Wrong pointer returned");
+ *
+ * rtaCommand_Release(&command);
+ * rtaCommandTransmitStatistics_Release(&transmitStats);
+ * @endcode
+ */
+const RtaCommandTransmitStatistics *rtaCommand_GetTransmitStatistics(const RtaCommand *command);
+#endif // Libccnx_rta_Commands_h
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.c
new file mode 100644
index 00000000..d5c092e8
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.c
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * Implements the RtaCommandCloseConnection object. Only has to pass one argument, the apiSocket number,
+ * to identify which connection to close.
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+
+#include <config.h>
+
+#include <LongBow/runtime.h>
+
+#include <stdio.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Object.h>
+
+#include <ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.h>
+
+struct rta_command_closeconnection {
+ int apiNotifierFd;
+};
+
+parcObject_ExtendPARCObject(RtaCommandCloseConnection, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+parcObject_ImplementAcquire(rtaCommandCloseConnection, RtaCommandCloseConnection);
+
+parcObject_ImplementRelease(rtaCommandCloseConnection, RtaCommandCloseConnection);
+
+RtaCommandCloseConnection *
+rtaCommandCloseConnection_Create(int apiNotifierFd)
+{
+ RtaCommandCloseConnection *closeConnection = parcObject_CreateInstance(RtaCommandCloseConnection);
+ closeConnection->apiNotifierFd = apiNotifierFd;
+ return closeConnection;
+}
+
+int
+rtaCommandCloseConnection_GetApiNotifierFd(const RtaCommandCloseConnection *closeConnection)
+{
+ assertNotNull(closeConnection, "Parameter closeConnection must be non-null");
+ return closeConnection->apiNotifierFd;
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.h b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.h
new file mode 100644
index 00000000..4c46d831
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCloseConnection.h
@@ -0,0 +1,145 @@
+/*
+ * 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 rta_CommandCloseConnection.h
+ * @brief Represents a command to close a connection
+ *
+ * Used to construct an RtaCommand object that is passed to rtaTransport_PassCommand() or _rtaTransport_SendCommandToFramework()
+ * to send a command from the API's thread of execution to the Transport's thread of execution.
+ *
+ */
+#ifndef Libccnx_rta_CommandCloseConnection_h
+#define Libccnx_rta_CommandCloseConnection_h
+
+struct rta_command_closeconnection;
+typedef struct rta_command_closeconnection RtaCommandCloseConnection;
+
+/**
+ * Creates a CloseConnection command object
+ *
+ * Creates a CloseConnection command object used to signal the RTA framework to
+ * close a specified connection. The user passes its socket number to the close
+ * command to signify which connection.
+ *
+ * The apiNotifierFd number must correspond to the apiSocket number used in rtaCommandOpenConnection().
+ *
+ * @param [in] apiNotifierFd The descriptor number used by the API
+ *
+ * @return non-null An allocated object
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * void foo(RTATransport *transport)
+ * {
+ * #define API_SIDE 0
+ * #define TRANSPORT_SIDE 1
+ *
+ * int pair[2];
+ * socketpair(AF_LOCAL, SOCK_STREAM, 0, pair);
+ * PARCJSON *config = createConnectionConfig();
+ *
+ * RtaCommandOpenConnection *openCommand = rtaCommandOpenConnection_Create(6, pair[API_SIDE], pair[TRANSPORT_SIDE], config);
+ * RtaCommand *command = rtaCommand_CreateOpenConnection(openCommand);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandOpenConnection_Release(&openCommand);
+ *
+ * // ... do work ...
+ *
+ * RtaCommandCloseConnection *closeCommand = rtaCommandCloseConnection_Create(pair[API_SIDE]);
+ * command = rtaCommand_CreateCloseConnection(openCommand);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandCloseConnection_Release(&closeCommand);
+ * }
+ * @endcode
+ */
+RtaCommandCloseConnection *rtaCommandCloseConnection_Create(int apiNotifierFd);
+
+/**
+ * Increase the number of references to a `RtaCommandCloseConnection`.
+ *
+ * Note that new `RtaCommandCloseConnection` is not created,
+ * only that the given `RtaCommandCloseConnection` reference count is incremented.
+ * Discard the reference by invoking `rtaCommandCloseConnection_Release`.
+ *
+ * @param [in] closeConnection The RtaCommandCloseConnection to reference.
+ *
+ * @return non-null A reference to `closeConnection`.
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(pair[API_SIDE]);
+ * RtaCommandCloseConnection *second = rtaCommandCloseConnection_Acquire(closeConnection);
+ *
+ * // release order does not matter
+ * rtaCommandCloseConnection_Release(&closeConnection);
+ * rtaCommandCloseConnection_Release(&second);
+ * }
+ * @endcode
+ */
+RtaCommandCloseConnection *rtaCommandCloseConnection_Acquire(const RtaCommandCloseConnection *closeConnection);
+
+/**
+ * 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] closePtr A pointer to the object to release, will return NULL'd.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandCloseConnection *closeCommand = rtaCommandCloseConnection_Create(pair[API_SIDE]);
+ * RtaCommand *command = rtaCommand_CreateCloseConnection(openCommand);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandCloseConnection_Release(&closeCommand);
+ * }
+ * @endcode
+ */
+void rtaCommandCloseConnection_Release(RtaCommandCloseConnection **closePtr);
+
+/**
+ * Returns the API notifier descriptor of the close command
+ *
+ * Returns the apiNotifierFd parameter.
+ *
+ * @param [in] closeConnection An allocated RtaCommandCloseConnection
+ *
+ * @return integer The value passed to rtaCommandCloseConnection_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int apiNotifierFd = 7;
+ * RtaCommandCloseConnection *closeCommand = rtaCommandCloseConnection_Create(apiNotifierFd);
+ * int testValue = rtaCommandCloseConnection_GetApiNotifierFd(closeCommand);
+ * assertTrue(testValue == apiNotifierFd, "Wrong value got %d expected %d", testValue, apiNotifierFd);
+ * rtaCommandCloseConnection_Release(&closeCommand);
+ * }
+ * @endcode
+ */
+int rtaCommandCloseConnection_GetApiNotifierFd(const RtaCommandCloseConnection *closeConnection);
+#endif // Libccnx_rta_CommandCloseConnection_h
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.c
new file mode 100644
index 00000000..fb5ecd9a
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.c
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * Implements the RtaCommandCreateProtocolStack object which signals to RTA Framework to open a new connection
+ * with the given configuration.
+ */
+#include <config.h>
+
+#include <LongBow/runtime.h>
+
+#include <stdio.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Object.h>
+
+#include <ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.h>
+
+struct rta_command_createprotocolstack {
+ int stackId;
+ CCNxStackConfig *config;
+};
+
+static void
+_rtaCommandCreateProtocolStack_Destroy(RtaCommandCreateProtocolStack **openConnectionPtr)
+{
+ RtaCommandCreateProtocolStack *openConnection = *openConnectionPtr;
+
+ if (openConnection->config) {
+ ccnxStackConfig_Release(&openConnection->config);
+ }
+}
+
+parcObject_ExtendPARCObject(RtaCommandCreateProtocolStack, _rtaCommandCreateProtocolStack_Destroy,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+
+parcObject_ImplementAcquire(rtaCommandCreateProtocolStack, RtaCommandCreateProtocolStack);
+
+parcObject_ImplementRelease(rtaCommandCreateProtocolStack, RtaCommandCreateProtocolStack);
+
+RtaCommandCreateProtocolStack *
+rtaCommandCreateProtocolStack_Create(int stackId, CCNxStackConfig *config)
+{
+ RtaCommandCreateProtocolStack *createStack = parcObject_CreateInstance(RtaCommandCreateProtocolStack);
+ createStack->stackId = stackId;
+ createStack->config = ccnxStackConfig_Copy(config);
+ return createStack;
+}
+
+const char *
+rtaCommandCreateProtocolStack_AssessValidity(const RtaCommandCreateProtocolStack *instance)
+{
+ char *result = NULL;
+
+ if (instance != NULL) {
+ if (ccnxStackConfig_IsValid(instance->config)) {
+ result = NULL;
+ } else {
+ result = "CCNxStackConfig instance is invalid";
+ }
+ } else {
+ result = "Instance cannot be NULL";
+ }
+
+ return result;
+}
+
+bool
+rtaCommandCreateProtocolStack_IsValid(const RtaCommandCreateProtocolStack *instance)
+{
+ const char *assessment = rtaCommandCreateProtocolStack_AssessValidity(instance);
+ return assessment == NULL;
+}
+
+void
+rtaCommandCreateProtocolStack_AssertValid(const RtaCommandCreateProtocolStack *instance)
+{
+ const char *assessment = rtaCommandCreateProtocolStack_AssessValidity(instance);
+ trapIllegalValueIf(assessment != NULL, "%s", assessment);
+}
+
+int
+rtaCommandCreateProtocolStack_GetStackId(const RtaCommandCreateProtocolStack *createStack)
+{
+ assertNotNull(createStack, "Parameter createStack must be non-null");
+ return createStack->stackId;
+}
+
+CCNxStackConfig *
+rtaCommandCreateProtocolStack_GetStackConfig(const RtaCommandCreateProtocolStack *createStack)
+{
+ return createStack->config;
+}
+
+PARCJSON *
+rtaCommandCreateProtocolStack_GetConfig(const RtaCommandCreateProtocolStack *createStack)
+{
+ assertNotNull(createStack, "Parameter createStack must be non-null");
+ return ccnxStackConfig_GetJson(createStack->config);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.h b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.h
new file mode 100644
index 00000000..a14f651c
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandCreateProtocolStack.h
@@ -0,0 +1,274 @@
+/*
+ * 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 rta_CommandCreateProtocolStack.h
+ * @brief Represents a command to create a protocol stack
+ *
+ * Used to construct an RtaCommand object that is passed to rtaTransport_PassCommand() or _rtaTransport_SendCommandToFramework()
+ * to send a command from the API's thread of execution to the Transport's thread of execution.
+ *
+ */
+#ifndef Libccnx_rta_CommandCreateProtocolStack_h
+#define Libccnx_rta_CommandCreateProtocolStack_h
+
+struct rta_command_createprotocolstack;
+typedef struct rta_command_createprotocolstack RtaCommandCreateProtocolStack;
+
+
+#include <ccnx/transport/common/ccnx_StackConfig.h>
+
+/**
+ * Creates a CreateProtocolStack command object
+ *
+ * Creates a CreateProtocolStack command object used to signal the RTA framework to
+ * create a new Protocol Stack with the specified stackId and configuration. The caller is
+ * responsible for ensuring that the stackId is unique among existing stacks (the framework might
+ * assert an error for duplicates). Note that the check for a unique stack ID is only done
+ * once the RtaCommandCreateProtocolStack is passed to the RtaFramework, not on creation
+ * of this object.
+ *
+ * @param [in] stackId The new (unique) ID for the stack to create
+ * @param [in] config the JSON representation of the stack configuration
+ *
+ * @return non-null An allocated object
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * void
+ * foo(RTATransport *transport)
+ * {
+ * int stackId = nextStackIdNumber();
+ *
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ * RtaCommand *command = rtaCommand_CreateCreateProtocolStack(createStack);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ *
+ * // ... do work ...
+ *
+ * RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(stackId);
+ * command = rtaCommand_CreateDestroyProtocolStack(destroyStack);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandDestroyProtocolStack(&destroyStack);
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+RtaCommandCreateProtocolStack *rtaCommandCreateProtocolStack_Create(int stackId, CCNxStackConfig *config);
+
+/**
+ * Increase the number of references to a `RtaCommandCreateProtocolStack`.
+ *
+ * Note that new `RtaCommandCreateProtocolStack` is not created,
+ * only that the given `RtaCommandCreateProtocolStack` reference count is incremented.
+ * Discard the reference by invoking `rtaCommandCreateProtocolStack_Release`.
+ *
+ * @param [in] createStack The RtaCommandCreateProtocolStack to reference.
+ *
+ * @return non-null A reference to `createStack`.
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ * RtaCommandCreateProtocolStack *second = rtaCommandCreateProtocolStack_Acquire(createStack);
+ *
+ * // release order does not matter
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ * rtaCommandCreateProtocolStack_Release(&second);
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+RtaCommandCreateProtocolStack *rtaCommandCreateProtocolStack_Acquire(const RtaCommandCreateProtocolStack *createStack);
+
+/**
+ * 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] closePtr A pointer to the object to release, will return NULL'd.
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ * RtaCommand *command = rtaCommand_CreateCreateProtocolStack(createStack);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+void rtaCommandCreateProtocolStack_Release(RtaCommandCreateProtocolStack **createStackPtr);
+
+/**
+ * Returns the Stack ID of the create stack command
+ *
+ * Returns the Stack ID parameter.
+ *
+ * @param [in] createStack An allocated RtaCommandCreateProtocolStack
+ *
+ * @return integer The value passed to rtaCommandCreateProtocolStack_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ * int testValue = rtaCommandCreateProtocolStack_GetStackId(createStack);
+ * assertTrue(testValue == stackId, "Wrong value got %d expected %d", testValue, stackId);
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+int rtaCommandCreateProtocolStack_GetStackId(const RtaCommandCreateProtocolStack *createStack);
+
+/**
+ * Get the CCNxStackConfig used by the given `RtaCommandCreateProtocolStack` instance.
+ *
+ * @param [in] createStack A pointer to a valid `RtaCommandCreateProtocolStack` instance.
+ *
+ * @return A pointer to the CCNxStackConfig used by the given `RtaCommandCreateProtocolStack` instance.
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ *
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ *
+ * CCNxStackConfig *config = rtaCommandCreateProtocolStack_GetStackConfig(createStack);
+ *
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ *
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+CCNxStackConfig *rtaCommandCreateProtocolStack_GetStackConfig(const RtaCommandCreateProtocolStack *createStack);
+
+/**
+ * Returns the PARCJSON stack configuration of the create stack command
+ *
+ * Returns the JSON representation of the stack configuration.
+ *
+ * @param [in] createStack An allocated RtaCommandCreateProtocolStack
+ *
+ * @return The value passed to rtaCommandCreateProtocolStack_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ *
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ *
+ * PARCJSON *testValue = rtaCommandCreateProtocolStack_GetConfig(createStack);
+ * assertTrue(ccnxJson_Equals(config, testValue), "Wrong value");
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ *
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+PARCJSON *rtaCommandCreateProtocolStack_GetConfig(const RtaCommandCreateProtocolStack *createStack);
+
+/**
+ * Derive an explanation for why a RtaCommandCreateProtocolStack instance is invalid.
+ *
+ * Returns either a nul-terminated C string containing a human-readable explanation,
+ * or NULL which indicates the instance is valid.
+ *
+ * @param [in] instance A pointer to a `RtaCommandCreateProtocolStack` instance.
+ *
+ * @return NULL The instance is valid.
+ * @return non-NULL A nul-terminated C string containing an explanation.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandCreateProtocolStack *instance = rtaCommandCreateProtocolStack_Create(...);
+ *
+ * if (rtaCommandCreateProtocolStack_IsValid(instance)) {
+ * printf("Instance is valid.\n");
+ * }
+ * }
+ * @endcode
+ */
+const char *rtaCommandCreateProtocolStack_AssessValidity(const RtaCommandCreateProtocolStack *instance);
+
+/**
+ * Determine if an instance of `RtaCommandCreateProtocolStack` 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 `RtaCommandCreateProtocolStack` instance.
+ *
+ * @return true The instance is valid.
+ * @return false The instance is not valid.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandCreateProtocolStack *instance = rtaCommandCreateProtocolStack_Create(...);
+ *
+ * if (rtaCommandCreateProtocolStack_IsValid(instance)) {
+ * printf("Instance is valid.\n");
+ * }
+ * }
+ * @endcode
+ */
+bool rtaCommandCreateProtocolStack_IsValid(const RtaCommandCreateProtocolStack *instance);
+
+/**
+ * Assert that the given `RtaCommandCreateProtocolStack` instance is valid.
+ *
+ * @param [in] instance A pointer to a valid RtaCommandCreateProtocolStack instance.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandCreateProtocolStack *a = rtaCommandCreateProtocolStack_Create();
+ *
+ * rtaCommandCreateProtocolStack_AssertValid(a);
+ *
+ * printf("Instance is valid.\n");
+ *
+ * rtaCommandCreateProtocolStack_Release(&b);
+ * }
+ * @endcode
+ */
+void rtaCommandCreateProtocolStack_AssertValid(const RtaCommandCreateProtocolStack *instance);
+#endif // Libccnx_rta_CommandCreateProtocolStack_h
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.c
new file mode 100644
index 00000000..4ce4321f
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.c
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * Implements the RtaCommandDestroyProtocolStack object which signals to RTA Framework to open a new connection
+ * with the given configuration.
+ */
+#include <config.h>
+
+#include <LongBow/runtime.h>
+
+#include <stdio.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Object.h>
+
+#include <ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.h>
+
+struct rta_command_destroyprotocolstack {
+ int stackId;
+};
+
+parcObject_ExtendPARCObject(RtaCommandDestroyProtocolStack,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+parcObject_ImplementAcquire(rtaCommandDestroyProtocolStack, RtaCommandDestroyProtocolStack);
+
+parcObject_ImplementRelease(rtaCommandDestroyProtocolStack, RtaCommandDestroyProtocolStack);
+
+// ======= Public API
+
+RtaCommandDestroyProtocolStack *
+rtaCommandDestroyProtocolStack_Create(int stackId)
+{
+ RtaCommandDestroyProtocolStack *createStack = parcObject_CreateInstance(RtaCommandDestroyProtocolStack);
+ createStack->stackId = stackId;
+ return createStack;
+}
+
+
+int
+rtaCommandDestroyProtocolStack_GetStackId(const RtaCommandDestroyProtocolStack *destroyStack)
+{
+ assertNotNull(destroyStack, "Parameter destroyStack must be non-null");
+ return destroyStack->stackId;
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.h b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.h
new file mode 100644
index 00000000..feecfac9
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandDestroyProtocolStack.h
@@ -0,0 +1,141 @@
+/*
+ * 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 rta_CommandDestroyProtocolStack.h
+ * @brief Represents a command to destroy a protocol stack
+ *
+ * Used to construct an RtaCommand object that is passed to rtaTransport_PassCommand() or _rtaTransport_SendCommandToFramework()
+ * to send a command from the API's thread of execution to the Transport's thread of execution.
+ *
+ */
+#ifndef Libccnx_rta_CommandDestroyProtocolStack_h
+#define Libccnx_rta_CommandDestroyProtocolStack_h
+
+struct rta_command_destroyprotocolstack;
+typedef struct rta_command_destroyprotocolstack RtaCommandDestroyProtocolStack;
+
+/**
+ * Creates a DestroyProtocolStack command object
+ *
+ * Creates a DestroyProtocolStack command object used to signal the RTA framework to
+ * destroy a protocol stack and all connections in it.
+ *
+ * @param [in] stackId The ID used to create the protocol stack.
+ *
+ * @return non-null An allocated object
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * void foo(RTATransport *transport)
+ * {
+ * int stackId = nextStackIdNumber();
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ *
+ * RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ * RtaCommand *command = rtaCommand_CreateCreateProtocolStack(createStack);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandCreateProtocolStack_Release(&createStack);
+ *
+ * // ... do work ...
+ *
+ * RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(stackId);
+ * command = rtaCommand_CreateDestroyProtocolStack(destroyStack);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandDestroyProtocolStack_Release(&destroyStack);
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+RtaCommandDestroyProtocolStack *rtaCommandDestroyProtocolStack_Create(int stackId);
+
+/**
+ * Increase the number of references to a `RtaCommandDestroyProtocolStack`.
+ *
+ * Note that new `RtaCommandDestroyProtocolStack` is not created,
+ * only that the given `RtaCommandDestroyProtocolStack` reference count is incremented.
+ * Discard the reference by invoking `rtaCommandDestroyProtocolStack_Release`.
+ *
+ * @param [in] destroyStack The RtaCommandDestroyProtocolStack to reference.
+ *
+ * @return non-null A reference to `destroyStack`.
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * {
+ * CCNxStackConfig *config = ccnxStackConfig_Create();
+ * RtaCommandDestroyProtocolStack *destroyStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ * RtaCommandDestroyProtocolStack *second = rtaCommandDestroyProtocolStack_Acquire(destroyStack);
+ *
+ * // release order does not matter
+ * rtaCommandDestroyProtocolStack_Release(&destroyStack);
+ * rtaCommandDestroyProtocolStack_Release(&second);
+ * ccnxStackConfig_Release(&config);
+ * }
+ * @endcode
+ */
+RtaCommandDestroyProtocolStack *rtaCommandDestroyProtocolStack_Acquire(const RtaCommandDestroyProtocolStack *destroyStack);
+
+/**
+ * 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] closePtr A pointer to the object to release, will return NULL'd.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(stackId);
+ * RtaCommand *command = rtaCommand_CreateDestroyProtocolStack(destroyStack);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandDestroyProtocolStack(&destroyStack);
+ * }
+ * @endcode
+ */
+void rtaCommandDestroyProtocolStack_Release(RtaCommandDestroyProtocolStack **destroyStackPtr);
+
+/**
+ * Returns the Stack ID of the destroy stack command
+ *
+ * Returns the Stack ID parameter.
+ *
+ * @param [in] destroyStack An allocated RtaCommandDestroyProtocolStack
+ *
+ * @return integer The value passed to rtaCommandDestroyProtocolStack_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ * RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(stackId);
+ * int testValue = rtaCommandDestroyProtocolStack_GetStackId(destroyStack);
+ * assertTrue(testValue == stackId, "Wrong value got %d expected %d", testValue, stackId);
+ * rtaCommandDestroyProtocolStack(&destroyStack);
+ * }
+ * @endcode
+ */
+int rtaCommandDestroyProtocolStack_GetStackId(const RtaCommandDestroyProtocolStack *destroyStack);
+#endif // Libccnx_rta_CommandDestroyProtocolStack_h
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.c
new file mode 100644
index 00000000..1ec1a945
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.c
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * Implements the RtaCommandOpenConnection object which signals to RTA Framework to open a new connection
+ * with the given configuration.
+ */
+#include <config.h>
+
+#include <LongBow/runtime.h>
+
+#include <stdio.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Object.h>
+
+#include <ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.h>
+
+struct rta_command_openconnection {
+ int stackId;
+ int apiNotifierFd;
+ int transportNotifierFd;
+ PARCJSON *config;
+};
+
+// ======= Private API
+
+static void
+_rtaCommandOpenConnection_Destroy(RtaCommandOpenConnection **openConnectionPtr)
+{
+ RtaCommandOpenConnection *openConnection = *openConnectionPtr;
+ if (openConnection->config != NULL) {
+ parcJSON_Release(&openConnection->config);
+ }
+}
+
+parcObject_ExtendPARCObject(RtaCommandOpenConnection, _rtaCommandOpenConnection_Destroy,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+
+parcObject_ImplementAcquire(rtaCommandOpenConnection, RtaCommandOpenConnection);
+
+parcObject_ImplementRelease(rtaCommandOpenConnection, RtaCommandOpenConnection);
+
+// ======= Public API
+
+RtaCommandOpenConnection *
+rtaCommandOpenConnection_Create(int stackId, int apiNotifierFd, int transportNotifierFd, const PARCJSON *config)
+{
+ RtaCommandOpenConnection *openConnection = parcObject_CreateInstance(RtaCommandOpenConnection);
+ openConnection->stackId = stackId;
+ openConnection->apiNotifierFd = apiNotifierFd;
+ openConnection->transportNotifierFd = transportNotifierFd;
+ openConnection->config = parcJSON_Copy(config);
+ return openConnection;
+}
+
+int
+rtaCommandOpenConnection_GetApiNotifierFd(const RtaCommandOpenConnection *openConnection)
+{
+ assertNotNull(openConnection, "Parameter openConnection must be non-null");
+ return openConnection->apiNotifierFd;
+}
+
+int
+rtaCommandOpenConnection_GetStackId(const RtaCommandOpenConnection *openConnection)
+{
+ assertNotNull(openConnection, "Parameter openConnection must be non-null");
+ return openConnection->stackId;
+}
+
+int
+rtaCommandOpenConnection_GetTransportNotifierFd(const RtaCommandOpenConnection *openConnection)
+{
+ assertNotNull(openConnection, "Parameter openConnection must be non-null");
+ return openConnection->transportNotifierFd;
+}
+
+PARCJSON *
+rtaCommandOpenConnection_GetConfig(const RtaCommandOpenConnection *openConnection)
+{
+ assertNotNull(openConnection, "Parameter openConnection must be non-null");
+ return openConnection->config;
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.h b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.h
new file mode 100644
index 00000000..031ae04b
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandOpenConnection.h
@@ -0,0 +1,219 @@
+/*
+ * 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 rta_CommandOpenConnection.h
+ * @brief Represents a command to open a connection
+ *
+ * Used to construct an RtaCommand object that is passed to rtaTransport_PassCommand() or _rtaTransport_SendCommandToFramework()
+ * to send a command from the API's thread of execution to the Transport's thread of execution.
+ *
+ */
+#ifndef Libccnx_rta_CommandOpenConnection_h
+#define Libccnx_rta_CommandOpenConnection_h
+
+
+struct rta_command_openconnection;
+typedef struct rta_command_openconnection RtaCommandOpenConnection;
+
+/**
+ * Creates a OpenConnection command object
+ *
+ * Creates a OpenConnection command object used to signal the RTA framework to
+ * open a specified connection. The user passes in the two sides of a socket pair
+ * plus the JSON representation of the connection.
+ *
+ * The RTA transport API connector will use the transportNotifierFd side of the socket pair.
+ *
+ * The caller must know the protocol stack handle stackId to specify which stack to
+ * associate the connection with.
+ *
+ * @param [in] stackId The protocol stack handle to use for the connection.
+ * @param [in] apiNotifierFd A descriptor used to notify the API that there's data to read from the transport.
+ * @param [in] transportNotifierFd A descriptor used to notify the Transport there's data to read from the API.
+ * @param [in] config The stack/connection config.
+ *
+ * @return non-null An allocated object
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * void foo(RTATransport *transport)
+ * {
+ * #define API_SIDE 0
+ * #define TRANSPORT_SIDE 1
+ *
+ * int pair[2];
+ * socketpair(AF_LOCAL, SOCK_STREAM, 0, pair);
+ * PARCJSON *config = createConnectionConfig();
+ *
+ * RtaCommandOpenConnection *openCommand = rtaCommandOpenConnection_Create(6, pair[API_SIDE], pair[TRANSPORT_SIDE], config);
+ * RtaCommand *command = rtaCommand_CreateOpenConnection(openCommand);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandOpenConnection_Release(&openCommand);
+ *
+ * // ... do work ...
+ * RtaCommandCloseConnection *closeCommand = rtaCommandCloseConnection_Create(pair[API_SIDE]);
+ * RtaCommand *command = rtaCommand_CreateCloseConnection(openCommand);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandCloseConnection_Release(&closeCommand);
+ * }
+ * @endcode
+ */
+RtaCommandOpenConnection *rtaCommandOpenConnection_Create(int stackId, int apiNotifierFd, int transportNotifierFd, const PARCJSON *config);
+
+/**
+ * Increase the number of references to a `RtaCommandOpenConnection`.
+ *
+ * Note that new `RtaCommandOpenConnection` is not created,
+ * only that the given `RtaCommandOpenConnection` reference count is incremented.
+ * Discard the reference by invoking `rtaCommandOpenConnection_Release`.
+ *
+ * @param [in] openConnection The RtaCommandDestroyProtocolStack to reference.
+ *
+ * @return non-null A reference to `openConnection`.
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandOpenConnection *openConnection = rtaCommandOpenConnection_Create(6, pair[API_SIDE], pair[TRANSPORT_SIDE], config);
+ * RtaCommandOpenConnection *second = rtaCommandOpenConnection_Acquire(openConnection);
+ *
+ * // release order does not matter
+ * rtaCommandOpenConnection_Release(&openConnection);
+ * rtaCommandOpenConnection_Release(&second);
+ * }
+ * @endcode
+ */
+RtaCommandOpenConnection *rtaCommandOpenConnection_Acquire(const RtaCommandOpenConnection *openConnection);
+
+/**
+ * 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] closePtr A pointer to the object to release, will return NULL'd.
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandOpenConnection *openCommand = rtaCommandOpenConnection_Create(6, pair[API_SIDE], pair[TRANSPORT_SIDE], config);
+ * RtaCommand *command = rtaCommand_CreateOpenConnection(openCommand);
+ * _rtaTransport_SendCommandToFramework(transport, command);
+ * rtaCommand_Release(&command);
+ * rtaCommandOpenConnection_Release(&openCommand);
+ * }
+ * @endcode
+ */
+void rtaCommandOpenConnection_Release(RtaCommandOpenConnection **openPtr);
+
+/**
+ * Returns the Stack ID of the open command
+ *
+ * Returns the Stack ID parameter.
+ *
+ * @param [in] openConnection An allocated RtaCommandOpenConnection
+ *
+ * @return integer The value passed to rtaCommandOpenConnection_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ * RtaCommandOpenConnection *openCommand = rtaCommandOpenConnection_Create(apiSocket, pair[API_SIDE], pair[TRANSPORT_SIDE], config);
+ * int testValue = rtaCommandOpenConnection_GetStackId(openCommand);
+ * assertTrue(testValue == stackId, "Wrong value got %d expected %d", testValue, stackId);
+ * rtaCommandOpenConnection_Release(&openCommand);
+ * }
+ * @endcode
+ */
+int rtaCommandOpenConnection_GetStackId(const RtaCommandOpenConnection *openConnection);
+
+/**
+ * Returns the API descriptor of the open command
+ *
+ * Returns the apiNotifierFd parameter. The API descriptor is the side read/written by the API.
+ *
+ * @param [in] openConnection An allocated RtaCommandOpenConnection
+ *
+ * @return integer The value passed to rtaCommandOpenConnection_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ * RtaCommandOpenConnection *openCommand = rtaCommandOpenConnection_Create(apiSocket, pair[API_SIDE], pair[TRANSPORT_SIDE], config);
+ * int testValue = rtaCommandOpenConnection_GetApiNotifierFd(openCommand);
+ * assertTrue(testValue == pair[API_SIDE], "Wrong value got %d expected %d", testValue, pair[API_SIDE]);
+ * rtaCommandOpenConnection_Release(&openCommand);
+ * }
+ * @endcode
+ */
+int rtaCommandOpenConnection_GetApiNotifierFd(const RtaCommandOpenConnection *openConnection);
+
+/**
+ * Returns the Transport descriptor of the open command
+ *
+ * Returns the transportNotifierFd parameter. The transport descriptor is the side read/written by the Transport.
+ *
+ * @param [in] openConnection An allocated RtaCommandOpenConnection
+ *
+ * @return integer The value passed to rtaCommandOpenConnection_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ * RtaCommandOpenConnection *openCommand = rtaCommandOpenConnection_Create(apiSocket, pair[API_SIDE], pair[TRANSPORT_SIDE], config);
+ * int testValue = rtaCommandOpenConnection_GetTransportNotifierFd(openCommand);
+ * assertTrue(testValue == pair[TRANSPORT_SIDE], "Wrong value got %d expected %d", testValue, pair[TRANSPORT_SIDE]);
+ * rtaCommandOpenConnection_Release(&openCommand);
+ * }
+ * @endcode
+ */
+int rtaCommandOpenConnection_GetTransportNotifierFd(const RtaCommandOpenConnection *openConnection);
+
+/**
+ * Returns the PARCJSON stack configuration of the create stack command
+ *
+ * Returns the JSON representation of the stack configuration.
+ *
+ * @param [in] createStack An allocated RtaCommandCreateProtocolStack
+ *
+ * @return The value passed to rtaCommandCreateProtocolStack_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ * PARCJSON *config = createConnectionConfiguration();
+ * RtaCommandOpenConnection *openCommand = rtaCommandOpenConnection_Create(apiSocket, pair[API_SIDE], pair[TRANSPORT_SIDE], config);
+ * PARCJSON *testValue = rtaCommandOpenConnection_GetConfig(openCommand);
+ * assertTrue(ccnxJson_Equals(config, testValue), "Wrong value");
+ * rtaCommandOpenConnection_Release(&openCommand);
+ * parcJSON_Release(&config);
+ * }
+ * @endcode
+ */
+PARCJSON *rtaCommandOpenConnection_GetConfig(const RtaCommandOpenConnection *openConnection);
+#endif // Libccnx_rta_CommandOpenConnection_h
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.c
new file mode 100644
index 00000000..129f68c7
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.c
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/**
+ *
+ * Implements the RtaCommandTransmitStatistics object which signals to RTA Framework to open a new connection
+ * with the given configuration.
+ */
+
+#include <config.h>
+
+#include <LongBow/runtime.h>
+
+#include <stdio.h>
+#include <sys/param.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_Object.h>
+
+#include <ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.h>
+
+struct rta_command_transmitstatistics {
+ struct timeval period;
+ char *filename;
+};
+
+// ======= Private API
+
+static void
+_rtaCommandTransmitStatistics_Destroy(RtaCommandTransmitStatistics **transmitStatsPtr)
+{
+ RtaCommandTransmitStatistics *transmitStats = *transmitStatsPtr;
+ parcMemory_Deallocate((void **) &(transmitStats->filename));
+}
+
+parcObject_ExtendPARCObject(RtaCommandTransmitStatistics, _rtaCommandTransmitStatistics_Destroy,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+
+parcObject_ImplementAcquire(rtaCommandTransmitStatistics, RtaCommandTransmitStatistics);
+
+parcObject_ImplementRelease(rtaCommandTransmitStatistics, RtaCommandTransmitStatistics);
+
+// ======= Public API
+
+RtaCommandTransmitStatistics *
+rtaCommandTransmitStatistics_Create(struct timeval period, const char *filename)
+{
+ assertNotNull(filename, "Filename must be non-null");
+
+ RtaCommandTransmitStatistics *transmitStats = parcObject_CreateInstance(RtaCommandTransmitStatistics);
+ memcpy(&transmitStats->period, &period, sizeof(struct timeval));
+ transmitStats->filename = parcMemory_StringDuplicate(filename, PATH_MAX);
+
+ return transmitStats;
+}
+
+struct timeval
+rtaCommandTransmitStatistics_GetPeriod(const RtaCommandTransmitStatistics *transmitStats)
+{
+ assertNotNull(transmitStats, "Parameter transmitStats must be non-null");
+ return transmitStats->period;
+}
+
+const char *
+rtaCommandTransmitStatistics_GetFilename(const RtaCommandTransmitStatistics *transmitStats)
+{
+ assertNotNull(transmitStats, "Parameter transmitStats must be non-null");
+ return transmitStats->filename;
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.h b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.h
new file mode 100644
index 00000000..cc5c9d02
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_CommandTransmitStatistics.h
@@ -0,0 +1,125 @@
+/*
+ * 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 rta_CommandTransmitStatistics.h
+ * @brief Represents a command to setup a statistics file
+ *
+ * Used to construct an RtaCommand object that is passed to rtaTransport_PassCommand() or _rtaTransport_SendCommandToFramework()
+ * to send a command from the API's thread of execution to the Transport's thread of execution.
+ *
+ */
+#ifndef Libccnx_rta_CommandTransmitStatistics_h
+#define Libccnx_rta_CommandTransmitStatistics_h
+
+struct rta_command_transmitstatistics;
+typedef struct rta_command_transmitstatistics RtaCommandTransmitStatistics;
+
+RtaCommandTransmitStatistics *rtaCommandTransmitStatistics_Create(struct timeval period, const char *filename);
+
+/**
+ * Increase the number of references to a `RtaCommandTransmitStatistics`.
+ *
+ * Note that new `RtaCommandTransmitStatistics` is not created,
+ * only that the given `RtaCommandTransmitStatistics` reference count is incremented.
+ * Discard the reference by invoking `rtaCommandTransmitStatistics_Release`.
+ *
+ * @param [in] transmitStats The RtaCommandTransmitStatistics to reference.
+ *
+ * @return non-null A reference to `transmitStats`.
+ * @return null An error
+ *
+ * Example:
+ * @code
+ * {
+ * RtaCommandOpenConnection *transmitStats = rtaCommandTransmitStatistics_Create((struct timeval) { 1, 2 }, "filename");
+ * RtaCommandOpenConnection *second = rtaCommandTransmitStatistics_Acquire(transmitStats);
+ *
+ * // release order does not matter
+ * rtaCommandTransmitStatistics_Release(&transmitStats);
+ * rtaCommandTransmitStatistics_Release(&second);
+ * }
+ * @endcode
+ */
+RtaCommandTransmitStatistics *rtaCommandTransmitStatistics_Acquire(const RtaCommandTransmitStatistics *transmitStats);
+
+/**
+ * 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] openPtr A pointer to the object to release, will return NULL'd.
+ *
+ * Example:
+ * @code
+ * {
+ * }
+ * @endcode
+ */
+void rtaCommandTransmitStatistics_Release(RtaCommandTransmitStatistics **openPtr);
+
+/**
+ * Returns the time period to use when writing statistics
+ *
+ * The time period is how often the transport will write the statistics to the specified file.
+ *
+ * @param [in] transmitStats An allocated RtaCommandTransmitStatistics
+ *
+ * @return timeval The value passed to rtaCommandTransmitStatistics_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ * struct timeval period = { 1, 2 };
+ * const char *filename = "filename";
+ * RtaCommandOpenConnection *transmitStats = rtaCommandTransmitStatistics_Create(period, filename);
+ * struct timeval testValue = rtaCommandTransmitStatistics_GetPeriod(transmitStats);
+ * assertTrue(timercmp(&testValue, &period, ==), "Wrong period");
+ * rtaCommandTransmitStatistics_Release(&transmitStats);
+ * }
+ * @endcode
+ */
+struct timeval rtaCommandTransmitStatistics_GetPeriod(const RtaCommandTransmitStatistics *transmitStats);
+
+/**
+ * Returns the filename to use when writing statistics
+ *
+ * The filename to append statistics to.
+ *
+ * @param [in] transmitStats An allocated RtaCommandTransmitStatistics
+ *
+ * @return timeval The value passed to rtaCommandTransmitStatistics_Create().
+ *
+ * Example:
+ * @code
+ * {
+ * int stackId = 7;
+ * struct timeval period = { 1, 2 };
+ * const char *filename = "filename";
+ * RtaCommandOpenConnection *transmitStats = rtaCommandTransmitStatistics_Create(period, filename);
+ * struct timeval testValue = rtaCommandTransmitStatistics_GetPeriod(transmitStats);
+ * assertTrue(strcmp(filename, testValue) == 0, "Wrong filename");
+ * rtaCommandTransmitStatistics_Release(&transmitStats);
+ * }
+ * @endcode
+ */
+const char *rtaCommandTransmitStatistics_GetFilename(const RtaCommandTransmitStatistics *transmitStats);
+#endif // Libccnx_rta_CommandTransmitStatistics_h
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/.gitignore b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/.gitignore
new file mode 100644
index 00000000..73fd1137
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/.gitignore
@@ -0,0 +1,7 @@
+test_rta_Command
+test_rta_CommandCloseConnection
+test_rta_CommandCreateProtocolStack
+test_rta_CommandDestroyProtocolStack
+test_rta_CommandOpenConnection
+test_rta_CommandTransmitStatistics
+
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/CMakeLists.txt b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/CMakeLists.txt
new file mode 100644
index 00000000..d3a5f009
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Enable gcov output for the tests
+add_definitions(--coverage)
+set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage")
+
+set(TestsExpectedToPass
+ test_rta_Command
+ test_rta_CommandCreateProtocolStack
+ test_rta_CommandOpenConnection
+ test_rta_CommandCloseConnection
+ test_rta_CommandDestroyProtocolStack
+ test_rta_CommandTransmitStatistics
+)
+
+
+foreach(test ${TestsExpectedToPass})
+ AddTest(${test})
+endforeach()
+
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_Command.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_Command.c
new file mode 100644
index 00000000..c27cb41d
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_Command.c
@@ -0,0 +1,475 @@
+/*
+ * 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 Framework.
+#include "../rta_Command.c"
+
+#include <inttypes.h>
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+LONGBOW_TEST_RUNNER(rta_Command)
+{
+ // 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(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(rta_Command)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(rta_Command)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_Acquire);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_Release);
+
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_CreateShutdownFramework);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_CreateCloseConnection);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_CreateCreateProtocolStack);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_CreateDestroyProtocolStack);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_CreateOpenConnection);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_CreateTransmitStatistics);
+
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_GetCloseConnection);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_GetCreateProtocolStack);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_GetDestroyProtocolStack);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_GetOpenConnection);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_GetTransmitStatistics);
+
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsCloseConnection_True);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsCreateProtocolStack_True);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsDestroyProtocolStack_True);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsOpenConnection_True);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsShutdownFramework_True);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsTransmitStatistics_True);
+
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsCloseConnection_False);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsCreateProtocolStack_False);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsDestroyProtocolStack_False);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsOpenConnection_False);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsShutdownFramework_False);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_IsTransmitStatistics_False);
+
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_Read_Single);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_Write_Single);
+
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_Read_Underflow);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_Write_Overflow);
+
+ // miscellaneous functions
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommand_Display);
+}
+
+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, rtaCommand_Acquire)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ size_t firstRefCount = parcObject_GetReferenceCount(command);
+
+ RtaCommand *second = rtaCommand_Acquire(command);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ assertTrue(secondRefCount == firstRefCount + 1, "Wrong refcount after acquire, got %zu expected %zu", secondRefCount, firstRefCount + 1);
+
+ rtaCommand_Release(&command);
+ rtaCommand_Release(&second);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_Release)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+
+ RtaCommand *second = rtaCommand_Acquire(command);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ rtaCommand_Release(&command);
+ size_t thirdRefCount = parcObject_GetReferenceCount(second);
+
+ assertTrue(thirdRefCount == secondRefCount - 1, "Wrong refcount after release, got %zu expected %zu", thirdRefCount, secondRefCount - 1);
+
+ rtaCommand_Release(&second);
+}
+
+// =======================
+// Create/From operations
+
+LONGBOW_TEST_CASE(Global, rtaCommand_CreateShutdownFramework)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ assertNotNull(command, "Got null command from create");
+ assertTrue(command->type == RtaCommandType_ShutdownFramework, "Command is not shutdown framework");
+ rtaCommand_Release(&command);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_CreateCloseConnection)
+{
+ RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(77);
+ RtaCommand *command = rtaCommand_CreateCloseConnection(closeConnection);
+ assertNotNull(command, "Got null command from create");
+ assertTrue(command->type == RtaCommandType_CloseConnection, "Command is not CloseConnection");
+ rtaCommand_Release(&command);
+ rtaCommandCloseConnection_Release(&closeConnection);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_CreateCreateProtocolStack)
+{
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(111, config);
+
+ RtaCommand *command = rtaCommand_CreateCreateProtocolStack(createStack);
+ assertNotNull(command, "Got null command from create");
+ assertTrue(command->type == RtaCommandType_CreateProtocolStack, "Command is not CreateProtocolStack");
+
+ rtaCommand_Release(&command);
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_CreateDestroyProtocolStack)
+{
+ RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(77);
+ RtaCommand *command = rtaCommand_CreateDestroyProtocolStack(destroyStack);
+ assertNotNull(command, "Got null command from create");
+ assertTrue(command->type == RtaCommandType_DestroyProtocolStack, "Command is not DestroyProtocolStack");
+ rtaCommand_Release(&command);
+ rtaCommandDestroyProtocolStack_Release(&destroyStack);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_CreateOpenConnection)
+{
+ RtaCommandOpenConnection *openConnection = rtaCommandOpenConnection_Create(111, 2341, 2450987, NULL);
+ RtaCommand *command = rtaCommand_CreateOpenConnection(openConnection);
+ assertNotNull(command, "Got null command from create");
+ assertTrue(command->type == RtaCommandType_OpenConnection, "Command is not OpenConnection");
+ rtaCommand_Release(&command);
+ rtaCommandOpenConnection_Release(&openConnection);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_CreateTransmitStatistics)
+{
+ RtaCommandTransmitStatistics *transmitStats = rtaCommandTransmitStatistics_Create((struct timeval) { 1, 2 }, "filename");
+ RtaCommand *command = rtaCommand_CreateTransmitStatistics(transmitStats);
+ assertNotNull(command, "Got null command from create");
+ assertTrue(command->type == RtaCommandType_TransmitStatistics, "Command is not TransmitStatistics");
+ rtaCommand_Release(&command);
+ rtaCommandTransmitStatistics_Release(&transmitStats);
+}
+
+// =======================
+// GET operations
+
+LONGBOW_TEST_CASE(Global, rtaCommand_GetCloseConnection)
+{
+ RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(77);
+ RtaCommand *command = rtaCommand_CreateCloseConnection(closeConnection);
+
+ const RtaCommandCloseConnection *test = rtaCommand_GetCloseConnection(command);
+ assertTrue(test == closeConnection, "Wrong pointers, got %p expected %p", (void *) test, (void *) closeConnection);
+
+ rtaCommand_Release(&command);
+ rtaCommandCloseConnection_Release(&closeConnection);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_GetCreateProtocolStack)
+{
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(111, config);
+ RtaCommand *command = rtaCommand_CreateCreateProtocolStack(createStack);
+
+ const RtaCommandCreateProtocolStack *test = rtaCommand_GetCreateProtocolStack(command);
+ assertTrue(test == createStack, "Wrong pointers, got %p expected %p", (void *) test, (void *) createStack);
+
+ rtaCommand_Release(&command);
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_GetDestroyProtocolStack)
+{
+ RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(77);
+ RtaCommand *command = rtaCommand_CreateDestroyProtocolStack(destroyStack);
+
+ const RtaCommandDestroyProtocolStack *test = rtaCommand_GetDestroyProtocolStack(command);
+ assertTrue(test == destroyStack, "Wrong pointers, got %p expected %p", (void *) test, (void *) destroyStack);
+
+ rtaCommand_Release(&command);
+ rtaCommandDestroyProtocolStack_Release(&destroyStack);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_GetOpenConnection)
+{
+ RtaCommandOpenConnection *openConnection = rtaCommandOpenConnection_Create(111, 2341, 2450987, NULL);
+ RtaCommand *command = rtaCommand_CreateOpenConnection(openConnection);
+
+ const RtaCommandOpenConnection *test = rtaCommand_GetOpenConnection(command);
+ assertTrue(test == openConnection, "Wrong pointers, got %p expected %p", (void *) test, (void *) openConnection);
+
+ rtaCommand_Release(&command);
+ rtaCommandOpenConnection_Release(&openConnection);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_GetTransmitStatistics)
+{
+ RtaCommandTransmitStatistics *transmitStats = rtaCommandTransmitStatistics_Create((struct timeval) { 1, 2 }, "filename");
+ RtaCommand *command = rtaCommand_CreateTransmitStatistics(transmitStats);
+
+ const RtaCommandTransmitStatistics *test = rtaCommand_GetTransmitStatistics(command);
+ assertTrue(test == transmitStats, "Wrong pointers, got %p expected %p", (void *) test, (void *) transmitStats);
+
+ rtaCommand_Release(&command);
+ rtaCommandTransmitStatistics_Release(&transmitStats);
+}
+
+// =======================
+// IsX operations
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsCloseConnection_True)
+{
+ RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(77);
+ RtaCommand *command = rtaCommand_CreateCloseConnection(closeConnection);
+ assertTrue(rtaCommand_IsCloseConnection(command), "Command is not CloseConnection");
+ rtaCommand_Release(&command);
+ rtaCommandCloseConnection_Release(&closeConnection);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsCreateProtocolStack_True)
+{
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(111, config);
+ RtaCommand *command = rtaCommand_CreateCreateProtocolStack(createStack);
+ assertTrue(rtaCommand_IsCreateProtocolStack(command), "Command is not CreateProtocolStack");
+ rtaCommand_Release(&command);
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsDestroyProtocolStack_True)
+{
+ RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(77);
+ RtaCommand *command = rtaCommand_CreateDestroyProtocolStack(destroyStack);
+ assertTrue(rtaCommand_IsDestroyProtocolStack(command), "Command is not DestroyProtocolStack");
+ rtaCommand_Release(&command);
+ rtaCommandDestroyProtocolStack_Release(&destroyStack);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsOpenConnection_True)
+{
+ RtaCommandOpenConnection *openConnection = rtaCommandOpenConnection_Create(111, 2341, 2450987, NULL);
+ RtaCommand *command = rtaCommand_CreateOpenConnection(openConnection);
+ assertTrue(rtaCommand_IsOpenConnection(command), "Command is not OpenConnection");
+ rtaCommand_Release(&command);
+ rtaCommandOpenConnection_Release(&openConnection);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsShutdownFramework_True)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ assertTrue(rtaCommand_IsShutdownFramework(command), "Command is not shutdown framework");
+ rtaCommand_Release(&command);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsTransmitStatistics_True)
+{
+ RtaCommandTransmitStatistics *transmitStats = rtaCommandTransmitStatistics_Create((struct timeval) { 1, 2 }, "filename");
+ RtaCommand *command = rtaCommand_CreateTransmitStatistics(transmitStats);
+ assertTrue(rtaCommand_IsTransmitStatistics(command), "Command is not TransmitStatistics");
+ rtaCommand_Release(&command);
+ rtaCommandTransmitStatistics_Release(&transmitStats);
+}
+
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsCloseConnection_False)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ assertFalse(rtaCommand_IsCloseConnection(command), "Command is not CloseConnection, should be false");
+ rtaCommand_Release(&command);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsCreateProtocolStack_False)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ assertFalse(rtaCommand_IsCreateProtocolStack(command), "Command is not CreateProtocolStack, should be false");
+ rtaCommand_Release(&command);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsDestroyProtocolStack_False)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ assertFalse(rtaCommand_IsDestroyProtocolStack(command), "Command is not DestroyProtocolStack, should be false");
+ rtaCommand_Release(&command);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsOpenConnection_False)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ assertFalse(rtaCommand_IsOpenConnection(command), "Command is not OpenConnection, should be false");
+ rtaCommand_Release(&command);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsShutdownFramework_False)
+{
+ RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(77);
+ RtaCommand *command = rtaCommand_CreateCloseConnection(closeConnection);
+ assertFalse(rtaCommand_IsShutdownFramework(command), "Command is not ShutdownFramework, should be false");
+ rtaCommand_Release(&command);
+ rtaCommandCloseConnection_Release(&closeConnection);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_IsTransmitStatistics_False)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ assertFalse(rtaCommand_IsTransmitStatistics(command), "Command is not TransmitStatistics, should be false");
+ rtaCommand_Release(&command);
+}
+
+// ===========================
+// IO operations
+
+/*
+ * Read a single command from a ring buffer
+ */
+LONGBOW_TEST_CASE(Global, rtaCommand_Read_Single)
+{
+ PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(4, NULL);
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+
+ bool success = parcRingBuffer1x1_Put(ring, command);
+ assertTrue(success, "Failed to put command in to ring buffer");
+
+ RtaCommand *test = rtaCommand_Read(ring);
+ assertTrue(test == command, "Wrong pointers, got %p expected %p", (void *) test, (void *) command);
+
+ rtaCommand_Release(&command);
+ parcRingBuffer1x1_Release(&ring);
+}
+
+/*
+ * Write a single command to a ring buffer and make sure it works
+ */
+LONGBOW_TEST_CASE(Global, rtaCommand_Write_Single)
+{
+ PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(4, NULL);
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+
+ bool success = rtaCommand_Write(command, ring);
+ assertTrue(success, "Failed to put command in to ring buffer");
+
+ // We should now have two references
+ assertTrue(parcObject_GetReferenceCount(command) == 2, "Wrong refernce count, got %" PRIu64 " expected %u", parcObject_GetReferenceCount(command), 2);
+
+ RtaCommand *test = rtaCommand_Read(ring);
+ assertTrue(test == command, "Wrong pointers, got %p expected %p", (void *) test, (void *) command);
+
+ rtaCommand_Release(&command);
+ rtaCommand_Release(&test);
+ parcRingBuffer1x1_Release(&ring);
+}
+
+/*
+ * Read from an empty ring buffer
+ */
+LONGBOW_TEST_CASE(Global, rtaCommand_Read_Underflow)
+{
+ PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(4, NULL);
+
+ RtaCommand *test = rtaCommand_Read(ring);
+ assertNull(test, "Should have gotten NULL read from an empty ring buffer");
+
+ parcRingBuffer1x1_Release(&ring);
+}
+
+/*
+ * Write beyond the capacity of the ring buffer
+ */
+LONGBOW_TEST_CASE(Global, rtaCommand_Write_Overflow)
+{
+ // The ring will store up to (ringSize-1) elements, so we can only
+ // have 3 items in a ring of size 4
+ unsigned ringSize = 4;
+ RtaCommand *commandArray[ringSize];
+
+ PARCRingBuffer1x1 *ring = parcRingBuffer1x1_Create(ringSize, NULL);
+
+ for (int i = 0; i < ringSize; i++) {
+ commandArray[i] = rtaCommand_CreateShutdownFramework();
+ }
+
+ for (int i = 0; i < ringSize - 1; i++) {
+ bool success = rtaCommand_Write(commandArray[i], ring);
+ assertTrue(success, "Failed to put command in to ring buffer");
+ }
+
+ // now put the one that will not fit
+ bool shouldFail = rtaCommand_Write(commandArray[ringSize - 1], ring);
+ assertFalse(shouldFail, "Writing overflow item should have failed");
+
+ // now make sure we read off all the right items
+ for (int i = 0; i < ringSize - 1; i++) {
+ RtaCommand *test = rtaCommand_Read(ring);
+ assertTrue(test == commandArray[i], "Wrong pointers, got %p expected %p", (void *) test, (void *) commandArray[i]);
+ rtaCommand_Release(&test);
+ }
+
+ for (int i = 0; i < ringSize; i++) {
+ rtaCommand_Release(&commandArray[i]);
+ }
+ parcRingBuffer1x1_Release(&ring);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommand_Display)
+{
+ RtaCommand *command = rtaCommand_CreateShutdownFramework();
+ rtaCommand_Display(command, 3);
+ rtaCommand_Release(&command);
+}
+
+// ===================================================================
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(rta_Command);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandCloseConnection.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandCloseConnection.c
new file mode 100644
index 00000000..f6c0a3a3
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandCloseConnection.c
@@ -0,0 +1,125 @@
+/*
+ * 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 Framework.
+#include "../rta_CommandCloseConnection.c"
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+LONGBOW_TEST_RUNNER(rta_CommandCloseConnection)
+{
+ // 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(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(rta_CommandCloseConnection)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(rta_CommandCloseConnection)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCloseConnection_Acquire);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCloseConnection_Create);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCloseConnection_GetApiNotifierFd);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCloseConnection_Release);
+}
+
+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, rtaCommandCloseConnection_Acquire)
+{
+ int apiNotifierFd = 7;
+ RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(apiNotifierFd);
+ size_t firstRefCount = parcObject_GetReferenceCount(closeConnection);
+
+ RtaCommandCloseConnection *second = rtaCommandCloseConnection_Acquire(closeConnection);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ assertTrue(secondRefCount == firstRefCount + 1, "Wrong refcount after acquire, got %zu expected %zu", secondRefCount, firstRefCount + 1);
+
+ rtaCommandCloseConnection_Release(&closeConnection);
+ rtaCommandCloseConnection_Release(&second);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCloseConnection_Create)
+{
+ int apiNotifierFd = 7;
+ RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(apiNotifierFd);
+ assertNotNull(closeConnection, "Got null from create");
+ assertTrue(closeConnection->apiNotifierFd == apiNotifierFd, "Internal apiSocket wrong, got %d expected %d", closeConnection->apiNotifierFd, apiNotifierFd);
+ rtaCommandCloseConnection_Release(&closeConnection);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCloseConnection_GetApiNotifierFd)
+{
+ int apiNotifierFd = 7;
+ RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(apiNotifierFd);
+
+ int testFd = rtaCommandCloseConnection_GetApiNotifierFd(closeConnection);
+ assertTrue(testFd == apiNotifierFd, "Wrong value, got %d expected %d", testFd, apiNotifierFd);
+
+ rtaCommandCloseConnection_Release(&closeConnection);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCloseConnection_Release)
+{
+ int apiNotifierFd = 7;
+ RtaCommandCloseConnection *closeConnection = rtaCommandCloseConnection_Create(apiNotifierFd);
+
+ RtaCommandCloseConnection *second = rtaCommandCloseConnection_Acquire(closeConnection);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ rtaCommandCloseConnection_Release(&closeConnection);
+ size_t thirdRefCount = parcObject_GetReferenceCount(second);
+
+ assertTrue(thirdRefCount == secondRefCount - 1, "Wrong refcount after release, got %zu expected %zu", thirdRefCount, secondRefCount - 1);
+
+ rtaCommandCloseConnection_Release(&second);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(rta_CommandCloseConnection);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandCreateProtocolStack.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandCreateProtocolStack.c
new file mode 100644
index 00000000..948477f8
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandCreateProtocolStack.c
@@ -0,0 +1,215 @@
+/*
+ * 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 Framework.
+#include "../rta_CommandCreateProtocolStack.c"
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/testing/parc_ObjectTesting.h>
+
+LONGBOW_TEST_RUNNER(rta_CommandCreateProtocolStack)
+{
+ // 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(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(rta_CommandCreateProtocolStack)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(rta_CommandCreateProtocolStack)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_Acquire);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_Create);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_IsValid);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_IsValid_NULL);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_IsValid_BadCCNxStackConfig);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_AssertValid);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_GetConfig);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_GetStackId);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_GetStackConfig);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandCreateProtocolStack_Release);
+}
+
+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, rtaCommandCreateProtocolStack_Acquire)
+{
+ int stackId = 7;
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+
+ parcObjectTesting_AssertAcquire(createStack);
+
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCreateProtocolStack_Create)
+{
+ int stackId = 7;
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ assertNotNull(createStack, "Expected rtaCommandCreateProtocolStack_Create to return non-NULL.");
+
+ assertTrue(createStack->stackId == stackId, "Expected stackId %d, actual %d", stackId, createStack->stackId);
+
+ assertTrue(ccnxStackConfig_Equals(config, createStack->config),
+ "ProtocolStackConfig instances are not equal");
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCreateProtocolStack_IsValid)
+{
+ int stackId = 7;
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+
+ assertTrue(rtaCommandCreateProtocolStack_IsValid(createStack),
+ "Expected rtaCommandCreateProtocolStack_Create to return a valid instance.");
+
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCreateProtocolStack_IsValid_NULL)
+{
+ RtaCommandCreateProtocolStack *createStack = NULL;
+
+ assertFalse(rtaCommandCreateProtocolStack_IsValid(createStack),
+ "Expected rtaCommandCreateProtocolStack_Create to return a valid instance.");
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCreateProtocolStack_IsValid_BadCCNxStackConfig)
+{
+ int stackId = 7;
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+ CCNxStackConfig *original = createStack->config;
+ createStack->config = NULL; // Make it bad.
+ assertFalse(rtaCommandCreateProtocolStack_IsValid(createStack),
+ "Expected rtaCommandCreateProtocolStack_Create to return a valid instance.");
+ createStack->config = original;
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCreateProtocolStack_AssertValid)
+{
+ int stackId = 7;
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+
+ rtaCommandCreateProtocolStack_AssertValid(createStack);
+
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCreateProtocolStack_GetStackConfig)
+{
+ int stackId = 7;
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+
+ CCNxStackConfig *actual = rtaCommandCreateProtocolStack_GetStackConfig(createStack);
+
+ assertTrue(ccnxStackConfig_Equals(config, actual),
+ "CCNxStackConfig instances are not equal");
+
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCreateProtocolStack_GetConfig)
+{
+ int stackId = 7;
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+
+ assertTrue(ccnxStackConfig_Equals(config, createStack->config),
+ "ProtocolStackConfig instances are not equal");
+
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCreateProtocolStack_GetStackId)
+{
+ int stackId = 7;
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+
+ int testStackId = rtaCommandCreateProtocolStack_GetStackId(createStack);
+ assertTrue(testStackId == stackId, "Wrong value, got %d expected %d", testStackId, stackId);
+
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ ccnxStackConfig_Release(&config);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandCreateProtocolStack_Release)
+{
+ int stackId = 7;
+ CCNxStackConfig *config = ccnxStackConfig_Create();
+ RtaCommandCreateProtocolStack *createStack = rtaCommandCreateProtocolStack_Create(stackId, config);
+
+ RtaCommandCreateProtocolStack *second = rtaCommandCreateProtocolStack_Acquire(createStack);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ rtaCommandCreateProtocolStack_Release(&createStack);
+ size_t thirdRefCount = parcObject_GetReferenceCount(second);
+
+ assertTrue(thirdRefCount == secondRefCount - 1,
+ "Wrong refcount after release, got %zu expected %zu", thirdRefCount, secondRefCount - 1);
+
+ rtaCommandCreateProtocolStack_Release(&second);
+ ccnxStackConfig_Release(&config);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(rta_CommandCreateProtocolStack);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandDestroyProtocolStack.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandDestroyProtocolStack.c
new file mode 100644
index 00000000..37e1128d
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandDestroyProtocolStack.c
@@ -0,0 +1,125 @@
+/*
+ * 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 Framework.
+#include "../rta_CommandDestroyProtocolStack.c"
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+LONGBOW_TEST_RUNNER(rta_CommandDestroyProtocolStack)
+{
+ // 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(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(rta_CommandDestroyProtocolStack)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(rta_CommandDestroyProtocolStack)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandDestroyProtocolStack_Acquire);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandDestroyProtocolStack_Create);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandDestroyProtocolStack_GetStackId);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandDestroyProtocolStack_Release);
+}
+
+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, rtaCommandDestroyProtocolStack_Acquire)
+{
+ int stackId = 7;
+ RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(stackId);
+ size_t firstRefCount = parcObject_GetReferenceCount(destroyStack);
+
+ RtaCommandDestroyProtocolStack *second = rtaCommandDestroyProtocolStack_Acquire(destroyStack);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ assertTrue(secondRefCount == firstRefCount + 1, "Wrong refcount after acquire, got %zu expected %zu", secondRefCount, firstRefCount + 1);
+
+ rtaCommandDestroyProtocolStack_Release(&destroyStack);
+ rtaCommandDestroyProtocolStack_Release(&second);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandDestroyProtocolStack_Create)
+{
+ int stackId = 7;
+ RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(stackId);
+ assertNotNull(destroyStack, "Got null from create");
+ assertTrue(destroyStack->stackId == stackId, "Internal stackId wrong, got %d expected %d", destroyStack->stackId, stackId);
+ rtaCommandDestroyProtocolStack_Release(&destroyStack);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandDestroyProtocolStack_GetStackId)
+{
+ int stackId = 7;
+ RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(stackId);
+
+ int testStackId = rtaCommandDestroyProtocolStack_GetStackId(destroyStack);
+ assertTrue(testStackId == stackId, "Wrong value, got %d expected %d", testStackId, stackId);
+
+ rtaCommandDestroyProtocolStack_Release(&destroyStack);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandDestroyProtocolStack_Release)
+{
+ int stackId = 7;
+ RtaCommandDestroyProtocolStack *destroyStack = rtaCommandDestroyProtocolStack_Create(stackId);
+
+ RtaCommandDestroyProtocolStack *second = rtaCommandDestroyProtocolStack_Acquire(destroyStack);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ rtaCommandDestroyProtocolStack_Release(&destroyStack);
+ size_t thirdRefCount = parcObject_GetReferenceCount(second);
+
+ assertTrue(thirdRefCount == secondRefCount - 1, "Wrong refcount after release, got %zu expected %zu", thirdRefCount, secondRefCount - 1);
+
+ rtaCommandDestroyProtocolStack_Release(&second);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(rta_CommandDestroyProtocolStack);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandOpenConnection.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandOpenConnection.c
new file mode 100644
index 00000000..30d77931
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandOpenConnection.c
@@ -0,0 +1,199 @@
+/*
+ * 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 Framework.
+#include "../rta_CommandOpenConnection.c"
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+typedef struct test_data {
+ int stackId;
+ int apiNotifierFd;
+ int transportNotifierFd;
+ PARCJSON *config;
+
+ RtaCommandOpenConnection *openConnection;
+} TestData;
+
+static TestData *
+_createTestData(void)
+{
+ TestData *data = parcMemory_AllocateAndClear(sizeof(TestData));
+
+ data->stackId = 7;
+ data->apiNotifierFd = 11;
+ data->transportNotifierFd = 10029;
+ data->config = parcJSON_Create();
+
+ data->openConnection = rtaCommandOpenConnection_Create(data->stackId, data->apiNotifierFd, data->transportNotifierFd, data->config);
+
+ return data;
+}
+
+static void
+_destroyTestData(TestData **dataPtr)
+{
+ TestData *data = *dataPtr;
+
+ rtaCommandOpenConnection_Release(&data->openConnection);
+ parcJSON_Release(&data->config);
+ parcMemory_Deallocate((void **) &data);
+
+ *dataPtr = NULL;
+}
+
+// =============================================================
+
+LONGBOW_TEST_RUNNER(rta_CommandOpenConnection)
+{
+ // 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(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(rta_CommandOpenConnection)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(rta_CommandOpenConnection)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandOpenConnection_Acquire);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandOpenConnection_Create);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandOpenConnection_GetApiNotifierFd);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandOpenConnection_GetConfig);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandOpenConnection_GetStackId);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandOpenConnection_GetTransportNotifierFd);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandOpenConnection_Release);
+}
+
+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, rtaCommandOpenConnection_Acquire)
+{
+ TestData *data = _createTestData();
+
+ size_t firstRefCount = parcObject_GetReferenceCount(data->openConnection);
+
+ RtaCommandOpenConnection *second = rtaCommandOpenConnection_Acquire(data->openConnection);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ assertTrue(secondRefCount == firstRefCount + 1, "Wrong refcount after acquire, got %zu expected %zu", secondRefCount, firstRefCount + 1);
+
+ rtaCommandOpenConnection_Release(&second);
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandOpenConnection_Create)
+{
+ TestData *data = _createTestData();
+ assertNotNull(data->openConnection, "Got null from create");
+ assertTrue(data->openConnection->stackId == data->stackId, "Internal stackId wrong, got %d expected %d",
+ data->openConnection->stackId, data->stackId);
+ assertTrue(data->openConnection->apiNotifierFd == data->apiNotifierFd, "Internal apiNotifierFd wrong, got %d expected %d",
+ data->openConnection->apiNotifierFd, data->apiNotifierFd);
+ assertTrue(data->openConnection->transportNotifierFd == data->transportNotifierFd, "Internal transportNotifierFd wrong, got %d expected %d",
+ data->openConnection->transportNotifierFd, data->transportNotifierFd);
+ assertTrue(parcJSON_Equals(data->openConnection->config, data->config), "JSON configs are not equal");
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandOpenConnection_GetApiNotifierFd)
+{
+ TestData *data = _createTestData();
+
+ int testApiFd = rtaCommandOpenConnection_GetApiNotifierFd(data->openConnection);
+ assertTrue(testApiFd == data->apiNotifierFd, "Wrong value, got %d expected %d", testApiFd, data->apiNotifierFd);
+
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandOpenConnection_GetConfig)
+{
+ TestData *data = _createTestData();
+
+ PARCJSON *testConfig = rtaCommandOpenConnection_GetConfig(data->openConnection);
+ assertTrue(parcJSON_Equals(data->config, testConfig), "Configurations do not match");
+
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandOpenConnection_GetStackId)
+{
+ TestData *data = _createTestData();
+
+ int testStackId = rtaCommandOpenConnection_GetStackId(data->openConnection);
+ assertTrue(testStackId == data->stackId, "Wrong value, got %d expected %d", testStackId, data->stackId);
+
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandOpenConnection_GetTransportNotifierFd)
+{
+ TestData *data = _createTestData();
+
+ int testTransportFd = rtaCommandOpenConnection_GetTransportNotifierFd(data->openConnection);
+ assertTrue(testTransportFd == data->transportNotifierFd, "Wrong value, got %d expected %d", testTransportFd, data->transportNotifierFd);
+
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandOpenConnection_Release)
+{
+ TestData *data = _createTestData();
+
+ RtaCommandOpenConnection *second = rtaCommandOpenConnection_Acquire(data->openConnection);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ rtaCommandOpenConnection_Release(&second);
+ size_t thirdRefCount = parcObject_GetReferenceCount(data->openConnection);
+
+ assertTrue(thirdRefCount == secondRefCount - 1, "Wrong refcount after release, got %zu expected %zu", thirdRefCount, secondRefCount - 1);
+
+ _destroyTestData(&data);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(rta_CommandOpenConnection);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandTransmitStatistics.c b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandTransmitStatistics.c
new file mode 100644
index 00000000..cc312e5a
--- /dev/null
+++ b/libccnx-transport-rta/ccnx/transport/transport_rta/commands/test/test_rta_CommandTransmitStatistics.c
@@ -0,0 +1,170 @@
+/*
+ * 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 Framework.
+#include "../rta_CommandTransmitStatistics.c"
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+#include <sys/time.h>
+
+#define MAX_FILENAME 1024
+
+typedef struct test_data {
+ struct timeval period;
+ char filename[MAX_FILENAME];
+
+ RtaCommandTransmitStatistics *transmitStats;
+} TestData;
+
+static TestData *
+_createTestData(void)
+{
+ TestData *data = parcMemory_AllocateAndClear(sizeof(TestData));
+ assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData));
+
+ data->period = (struct timeval) { .tv_sec = 1234, .tv_usec = 2389484 };
+ snprintf(data->filename, MAX_FILENAME, "Miss Piggy");
+
+ data->transmitStats = rtaCommandTransmitStatistics_Create(data->period, data->filename);
+
+ return data;
+}
+
+static void
+_destroyTestData(TestData **dataPtr)
+{
+ TestData *data = *dataPtr;
+ rtaCommandTransmitStatistics_Release(&data->transmitStats);
+ parcMemory_Deallocate((void **) &data);
+ *dataPtr = NULL;
+}
+
+// =============================================================
+LONGBOW_TEST_RUNNER(rta_CommandTransmitStatistics)
+{
+ // 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(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(rta_CommandTransmitStatistics)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(rta_CommandTransmitStatistics)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandTransmitStatistics_Acquire);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandTransmitStatistics_Create);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandTransmitStatistics_GetFilename);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandTransmitStatistics_GetPeriod);
+ LONGBOW_RUN_TEST_CASE(Global, rtaCommandTransmitStatistics_Release);
+}
+
+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, rtaCommandTransmitStatistics_Acquire)
+{
+ TestData *data = _createTestData();
+
+ size_t firstRefCount = parcObject_GetReferenceCount(data->transmitStats);
+
+ RtaCommandTransmitStatistics *second = rtaCommandTransmitStatistics_Acquire(data->transmitStats);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ assertTrue(secondRefCount == firstRefCount + 1, "Wrong refcount after acquire, got %zu expected %zu", secondRefCount, firstRefCount + 1);
+
+ rtaCommandTransmitStatistics_Release(&second);
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandTransmitStatistics_Create)
+{
+ TestData *data = _createTestData();
+ assertNotNull(data->transmitStats, "Got null from create");
+
+ assertTrue(timercmp(&data->period, &data->transmitStats->period, ==), "Period values not equal");
+ assertTrue(strcmp(data->filename, data->transmitStats->filename) == 0, "Filenames not equal");
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandTransmitStatistics_GetFilename)
+{
+ TestData *data = _createTestData();
+
+ const char *testFilename = rtaCommandTransmitStatistics_GetFilename(data->transmitStats);
+ assertTrue(strcmp(data->filename, testFilename) == 0, "Filenames not equal");
+
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandTransmitStatistics_GetPeriod)
+{
+ TestData *data = _createTestData();
+
+ struct timeval testPeriod = rtaCommandTransmitStatistics_GetPeriod(data->transmitStats);
+ assertTrue(timercmp(&data->period, &testPeriod, ==), "Period values not equal");
+
+ _destroyTestData(&data);
+}
+
+LONGBOW_TEST_CASE(Global, rtaCommandTransmitStatistics_Release)
+{
+ TestData *data = _createTestData();
+
+ RtaCommandTransmitStatistics *second = rtaCommandTransmitStatistics_Acquire(data->transmitStats);
+ size_t secondRefCount = parcObject_GetReferenceCount(second);
+
+ rtaCommandTransmitStatistics_Release(&second);
+ size_t thirdRefCount = parcObject_GetReferenceCount(data->transmitStats);
+
+ assertTrue(thirdRefCount == secondRefCount - 1, "Wrong refcount after release, got %zu expected %zu", thirdRefCount, secondRefCount - 1);
+
+ _destroyTestData(&data);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(rta_CommandTransmitStatistics);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}