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