diff options
Diffstat (limited to 'libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.c')
-rw-r--r-- | libccnx-transport-rta/ccnx/transport/transport_rta/commands/rta_Command.c | 365 |
1 files changed, 365 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; +} |