summaryrefslogtreecommitdiff
path: root/lib/avtp_pipeline/aem
diff options
context:
space:
mode:
Diffstat (limited to 'lib/avtp_pipeline/aem')
-rw-r--r--lib/avtp_pipeline/aem/CMakeLists.txt21
-rw-r--r--lib/avtp_pipeline/aem/openavb_aem.c534
-rw-r--r--lib/avtp_pipeline/aem/openavb_aem.h103
-rw-r--r--lib/avtp_pipeline/aem/openavb_aem_pub.h80
-rw-r--r--lib/avtp_pipeline/aem/openavb_aem_types_pub.h1339
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster.c179
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster_pub.h65
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_audio_map.c180
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_audio_map.h47
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_audio_map_pub.h69
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_audio_unit.c297
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_audio_unit.h47
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_audio_unit_pub.h99
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_avb_interface.c244
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_avb_interface.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_avb_interface_pub.h73
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_clock_domain.c209
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_clock_domain.h47
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_clock_domain_pub.h66
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_clock_source.c205
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_clock_source.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_clock_source_pub.h65
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_configuration.c197
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_configuration.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_configuration_pub.h70
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_control.c502
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_control.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_control_pub.h111
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_entity.c411
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_entity.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_entity_pub.h108
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_external_port_io.c209
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_external_port_io.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_external_port_io_pub.h66
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_jack_io.c235
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_jack_io.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_jack_io_pub.h66
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_locale.c208
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_locale.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_locale_pub.h69
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler.c230
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler.h44
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler_pub.h91
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_stream_io.c572
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_stream_io.h47
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_stream_io_pub.h111
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io.c207
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io_pub.h65
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_strings.c193
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_strings.h46
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_strings_pub.h65
53 files changed, 8352 insertions, 0 deletions
diff --git a/lib/avtp_pipeline/aem/CMakeLists.txt b/lib/avtp_pipeline/aem/CMakeLists.txt
new file mode 100644
index 00000000..276e403a
--- /dev/null
+++ b/lib/avtp_pipeline/aem/CMakeLists.txt
@@ -0,0 +1,21 @@
+SET (SRC_FILES ${SRC_FILES}
+ ${AVB_SRC_DIR}/aem/openavb_aem.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_entity.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_configuration.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_audio_unit.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_locale.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_strings.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_stream_io.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_jack_io.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_avb_interface.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_clock_source.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_stream_port_io.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_external_port_io.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_audio_cluster.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_audio_map.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_control.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_clock_domain.c
+ ${AVB_SRC_DIR}/aem/openavb_descriptor_locale_strings_handler.c
+ PARENT_SCOPE
+)
+
diff --git a/lib/avtp_pipeline/aem/openavb_aem.c b/lib/avtp_pipeline/aem/openavb_aem.c
new file mode 100644
index 00000000..e9f0f4de
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_aem.c
@@ -0,0 +1,534 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Entity Model
+ * MODULE SUMMARY : Implements the 1722.1 (AVDECC) Entity Model
+ ******************************************************************
+ */
+
+#include "stdlib.h"
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_avdecc.h"
+#include "openavb_aem.h"
+
+MUTEX_HANDLE(openavbAemMutex);
+#define AEM_LOCK() { MUTEX_CREATE_ERR(); MUTEX_LOCK(openavbAemMutex); MUTEX_LOG_ERR("Mutex lock failure"); }
+#define AEM_UNLOCK() { MUTEX_CREATE_ERR(); MUTEX_UNLOCK(openavbAemMutex); MUTEX_LOG_ERR("Mutex unlock failure"); }
+
+static openavb_avdecc_entity_model_t *pAemEntityModel = NULL;
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemCreate(openavb_aem_descriptor_entity_t *pDescriptorEntity)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ MUTEX_ATTR_HANDLE(mta);
+ MUTEX_ATTR_INIT(mta);
+ MUTEX_ATTR_SET_TYPE(mta, MUTEX_ATTR_TYPE_DEFAULT);
+ MUTEX_ATTR_SET_NAME(mta, "openavbAemMutex");
+ MUTEX_CREATE_ERR();
+ MUTEX_CREATE(openavbAemMutex, mta);
+ MUTEX_LOG_ERR("Could not create/initialize 'openavbAemMutex' mutex");
+
+ if (!pDescriptorEntity) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_ENTITY_MODEL_MISSING), AVB_TRACE_AEM);
+ }
+
+ if (!pAemEntityModel) {
+ pAemEntityModel = calloc(1, sizeof(*pAemEntityModel));
+ }
+
+ if (!pAemEntityModel) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY), AVB_TRACE_AEM);
+ }
+
+ pAemEntityModel->pDescriptorEntity = pDescriptorEntity;
+ pAemEntityModel->aemConfigurations = openavbArrayNewArray(sizeof(openavb_aem_configuration_t));
+ memset(pAemEntityModel->aemNonTopLevelDescriptorsArray, 0, sizeof(pAemEntityModel->aemNonTopLevelDescriptorsArray));
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDestroy()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+ // AVDECC_TODO all deallocations will occur here
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+bool openavbAemCheckModel(bool bLog)
+{
+ if (!pAemEntityModel || !pAemEntityModel->pDescriptorEntity) {
+ if (bLog) {
+ AVB_RC_LOG(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_ENTITY_MODEL_MISSING);
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+openavbRC openavbAemAddDescriptorToConfiguration(U16 descriptorType, U16 configIdx)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+ int i1;
+
+ // Make sure Entity Model is created
+ if (!openavbAemCheckModel(FALSE)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_ENTITY_MODEL_MISSING), AVB_TRACE_AEM);
+ }
+
+ if (configIdx == OPENAVB_AEM_DESCRIPTOR_INVALID) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_INVALID_CONFIG_IDX), AVB_TRACE_AEM);
+ }
+ openavb_aem_configuration_t *pConfiguration = openavbArrayDataIdx(pAemEntityModel->aemConfigurations, configIdx);
+ if (!pConfiguration) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_INVALID_CONFIG_IDX), AVB_TRACE_AEM);
+ }
+
+ openavb_aem_descriptor_configuration_t *pConfig = pConfiguration->pDescriptorConfiguration;
+ if (!pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_INVALID_CONFIG_IDX), AVB_TRACE_AEM);
+ }
+
+ // Check if the new descriptor type is in the configuration array
+ for (i1 = 0; i1 < pConfig->descriptor_counts_count; i1++) {
+ if (pConfig->descriptor_counts[i1].descriptor_type == descriptorType) {
+ // Found this descriptor type so just increase the count.
+ pConfig->descriptor_counts[i1].count++;
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+ }
+ }
+
+ // Update counts
+ pConfig->descriptor_counts[pConfig->descriptor_counts_count].descriptor_type = descriptorType;
+ pConfig->descriptor_counts[pConfig->descriptor_counts_count].count++;
+ pConfig->descriptor_counts_count++;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavb_avdecc_entity_model_t *openavbAemGetModel()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pAemEntityModel;
+}
+
+openavb_array_t openavbAemGetDescriptorArray(U16 configIdx, U16 descriptorType)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_array_t retDescriptors = NULL;
+
+ // Make sure Entity Model is created
+ if (!openavbAemCheckModel(TRUE)) {
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ if (descriptorType == OPENAVB_AEM_DESCRIPTOR_ENTITY) {
+ // There is always only a single Entity Descriptor and therefore there isn't an array. NULL will be returned.
+ }
+ else if (descriptorType == OPENAVB_AEM_DESCRIPTOR_CONFIGURATION) {
+ // The configuration descriptor is a special descriptor and not return by this function. NULL will be returned.
+ }
+ else {
+ if (configIdx != OPENAVB_AEM_DESCRIPTOR_INVALID) {
+ openavb_aem_configuration_t *pConfig = openavbArrayDataIdx(pAemEntityModel->aemConfigurations, configIdx);
+ if (pConfig) {
+ retDescriptors = pConfig->descriptorsArray[descriptorType];
+ }
+ }
+
+ // Search the alternate location for non-top-level descriptors.
+ if (!retDescriptors) {
+ retDescriptors = pAemEntityModel->aemNonTopLevelDescriptorsArray[descriptorType];
+ }
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return retDescriptors;
+}
+
+void *openavbAemFindDescriptor(U16 configIdx, U16 descriptorType, U16 descriptorIdx)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ void *retDescriptor = NULL;
+
+ // Make sure Entity Model is created
+ if (!openavbAemCheckModel(TRUE)) {
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ if (descriptorType == OPENAVB_AEM_DESCRIPTOR_ENTITY) {
+ if (pAemEntityModel->pDescriptorEntity &&
+ pAemEntityModel->pDescriptorEntity->descriptor_index == descriptorIdx) {
+ retDescriptor = pAemEntityModel->pDescriptorEntity;
+ }
+ }
+ else if (descriptorType == OPENAVB_AEM_DESCRIPTOR_CONFIGURATION) {
+ if (configIdx != OPENAVB_AEM_DESCRIPTOR_INVALID) {
+ openavb_aem_configuration_t *pConfig = openavbArrayDataIdx(pAemEntityModel->aemConfigurations, configIdx);
+ if (pConfig &&
+ pConfig->pDescriptorConfiguration &&
+ pConfig->pDescriptorConfiguration->descriptor_index == descriptorIdx) {
+ retDescriptor = pConfig->pDescriptorConfiguration;
+ }
+ }
+ }
+ else {
+ openavb_array_t descriptors = NULL;
+ if (configIdx != OPENAVB_AEM_DESCRIPTOR_INVALID) {
+ openavb_aem_configuration_t *pConfig = openavbArrayDataIdx(pAemEntityModel->aemConfigurations, configIdx);
+ if (pConfig) {
+ descriptors = pConfig->descriptorsArray[descriptorType];
+ if (descriptors) {
+ retDescriptor = openavbArrayDataIdx(descriptors, descriptorIdx);
+ }
+ }
+ }
+
+ // Search the alternate location for non-top-level descriptors.
+ if (!retDescriptor) {
+ descriptors = pAemEntityModel->aemNonTopLevelDescriptorsArray[descriptorType];
+ if (descriptors) {
+ retDescriptor = openavbArrayDataIdx(descriptors, descriptorIdx);
+ }
+ }
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return retDescriptor;
+}
+
+openavbRC openavbAemSerializeDescriptor(U16 configIdx, U16 descriptorType, U16 descriptorIdx, U16 bufSize, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ // Make sure Entity Model is created
+ if (!openavbAemCheckModel(FALSE)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_ENTITY_MODEL_MISSING), AVB_TRACE_AEM);
+ }
+
+ if (!pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ void *pDescriptor = openavbAemFindDescriptor(configIdx, descriptorType, descriptorIdx);
+ if (pDescriptor) {
+ openavb_aem_descriptor_common_t *pDescriptorCommon = pDescriptor;
+ if (IS_OPENAVB_FAILURE(pDescriptorCommon->descriptorPvtPtr->update(pDescriptor))) {
+ AVB_RC_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_STALE_DATA), AVB_TRACE_AEM);
+ }
+ if (IS_OPENAVB_FAILURE(pDescriptorCommon->descriptorPvtPtr->toBuf(pDescriptor, bufSize, pBuf, descriptorSize))) {
+ AVB_RC_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_GENERIC), AVB_TRACE_AEM);
+ }
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+ }
+
+ AVB_RC_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_UNKNOWN_DESCRIPTOR), AVB_TRACE_AEM);
+}
+
+bool openavbAemAddDescriptorConfiguration(openavb_aem_descriptor_configuration_t *pDescriptor, U16 *pResultIdx)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ // Make sure Entity Model is created
+ if (!openavbAemCheckModel(TRUE)) {
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ if (!pDescriptor || !pResultIdx) {
+ AVB_RC_LOG(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ // Allocate the new configuration structure
+ openavb_aem_configuration_t *pAemConfiguration = openavbArrayDataNew(pAemEntityModel->aemConfigurations);
+ if (!pAemConfiguration) {
+ AVB_RC_LOG(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ // Assign the descriptor to the new configuration
+ pAemConfiguration->pDescriptorConfiguration = pDescriptor;
+
+ // Set to return descriptor index and increment the count
+ S32 retIdx = openavbArrayFindData(pAemEntityModel->aemConfigurations, pAemConfiguration);
+ if (retIdx < 0) {
+ return FALSE;
+ }
+ *pResultIdx = retIdx;
+
+ pAemEntityModel->pDescriptorEntity->configurations_count++;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT U16 openavbAemGetConfigIdx()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ // This function does NOT check for errors but at a minimum avoid a crash.
+ if (!pAemEntityModel || !pAemEntityModel->pDescriptorEntity) {
+ AVB_RC_LOG(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_ENTITY_MODEL_MISSING);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return 0;
+ }
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pAemEntityModel->pDescriptorEntity->current_configuration;
+}
+
+
+extern DLL_EXPORT bool openavbAemAddDescriptor(void *pDescriptor, U16 configIdx, U16 *pResultIdx)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ // Make sure Entity Model is created
+ if (!openavbAemCheckModel(TRUE)) {
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ if (!pDescriptor || !pResultIdx) {
+ AVB_RC_LOG(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ openavb_aem_descriptor_common_t *pDescriptorCommon = pDescriptor;
+
+ if (pDescriptorCommon->descriptor_type == OPENAVB_AEM_DESCRIPTOR_ENTITY) {
+ // Entity Descriptors aren't handled in this function.
+ AVB_RC_LOG(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+ if (pDescriptorCommon->descriptor_type == OPENAVB_AEM_DESCRIPTOR_CONFIGURATION) {
+ // Configuration descriptors have special processing
+ bool result = openavbAemAddDescriptorConfiguration(pDescriptor, pResultIdx);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return result;
+ }
+
+ openavb_array_t descriptors = NULL;
+ if (pDescriptorCommon->descriptorPvtPtr->bTopLevel) {
+ openavb_aem_configuration_t *pConfig = openavbArrayDataIdx(pAemEntityModel->aemConfigurations, configIdx);
+ if (!pConfig) {
+ AVB_RC_LOG(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT);
+ AVB_LOGF_ERROR("Invalid configuration index %u", configIdx);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+ descriptors = pConfig->descriptorsArray[pDescriptorCommon->descriptor_type];
+
+ if (!descriptors) {
+ // Create array for this type of descriptor in this configuration
+ AVB_LOGF_DEBUG("Created description array for configuration %u, type 0x%04x", configIdx, pDescriptorCommon->descriptor_type);
+ descriptors = openavbArrayNewArray(pDescriptorCommon->descriptorPvtPtr->size);
+ pConfig->descriptorsArray[pDescriptorCommon->descriptor_type] = descriptors;
+ }
+ } else {
+ descriptors = pAemEntityModel->aemNonTopLevelDescriptorsArray[pDescriptorCommon->descriptor_type];
+
+ if (!descriptors) {
+ // Create array for this type of descriptor in this configuration
+ AVB_LOGF_DEBUG("Created non-top-level description array for type 0x%04x", pDescriptorCommon->descriptor_type);
+ descriptors = openavbArrayNewArray(pDescriptorCommon->descriptorPvtPtr->size);
+ pAemEntityModel->aemNonTopLevelDescriptorsArray[pDescriptorCommon->descriptor_type] = descriptors;
+ }
+ }
+
+ if (descriptors) {
+ if (openavbArrayFindData(descriptors, pDescriptor) >= 0) {
+ AVB_LOGF_ERROR("Attempted to add same descriptor (type 0x%04x) twice", pDescriptorCommon->descriptor_type);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ openavb_array_elem_t elem = openavbArrayAdd(descriptors, pDescriptor);
+ if (elem) {
+ *pResultIdx = openavbArrayGetIdx(elem);
+ pDescriptorCommon->descriptor_index = *pResultIdx;
+ if (pDescriptorCommon->descriptorPvtPtr->bTopLevel) {
+ if (!IS_OPENAVB_SUCCESS(openavbAemAddDescriptorToConfiguration(pDescriptorCommon->descriptor_type, configIdx))) {
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+ }
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+ }
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+}
+
+extern DLL_EXPORT void *openavbAemGetDescriptor(U16 configIdx, U16 descriptorType, U16 descriptorIdx)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+ void *retDescriptor = NULL;
+
+ retDescriptor = openavbAemFindDescriptor(configIdx, descriptorType, descriptorIdx);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return retDescriptor;
+}
+
+extern DLL_EXPORT U16 openavbAemGetDescriptorIndex(U16 configIdx, const void *pDescriptor)
+{
+ const openavb_aem_descriptor_common_t *pDescriptorCommon = pDescriptor;
+ U16 descriptorIdx = 0;
+ void * pTest;
+
+ if (!pDescriptorCommon) { return OPENAVB_AEM_DESCRIPTOR_INVALID; }
+
+ do {
+ pTest = openavbAemFindDescriptor(configIdx, pDescriptorCommon->descriptor_type, descriptorIdx);
+ if (pTest == pDescriptor) { return descriptorIdx; }
+ descriptorIdx++;
+ } while (pTest != NULL);
+
+ return OPENAVB_AEM_DESCRIPTOR_INVALID;
+}
+
+extern DLL_EXPORT bool openavbAemSetString(U8 *pMem, const char *pString)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (pMem && pString) {
+ U32 len = strlen(pString);
+ if (len > OPENAVB_AEM_STRLEN_MAX) {
+ len = OPENAVB_AEM_STRLEN_MAX;
+ } else if (len < OPENAVB_AEM_STRLEN_MAX) {
+ memset(pMem + len, 0, OPENAVB_AEM_STRLEN_MAX - len);
+ }
+ memcpy(pMem, pString, len); // Per 1722.1 it is allowable that the AEM string may not be null terminated.
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+}
+
+extern DLL_EXPORT bool openavbAemIsAcquired()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+ AEM_LOCK();
+ bool bResult = pAemEntityModel->entityAcquired;
+ AEM_UNLOCK();
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return bResult;
+}
+
+extern DLL_EXPORT bool openavbAemIsLocked()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+ AEM_LOCK();
+ bool bResult = pAemEntityModel->entityLocked;
+ AEM_UNLOCK();
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return bResult;
+}
+
+extern DLL_EXPORT bool openavbAemAcquire(bool flag)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+ AEM_LOCK();
+ bool bResult = FALSE;
+ if (flag) {
+ if (!pAemEntityModel->entityAcquired) {
+ *(pAemEntityModel->acquiredControllerId) = (U64)0x0000000000000000L;
+ pAemEntityModel->entityAcquired = TRUE;
+ bResult = TRUE;
+ }
+ }
+ else {
+ if (pAemEntityModel->entityAcquired) {
+ if ((U64)*pAemEntityModel->acquiredControllerId == 0x0000000000000000L) {
+ // Only unacquire if controller ID is zero.
+ pAemEntityModel->entityAcquired = FALSE;
+ bResult = TRUE;
+ }
+ }
+ }
+ AEM_UNLOCK();
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return bResult;
+}
+
+extern DLL_EXPORT bool openavbAemLock(bool flag)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+ AEM_LOCK();
+ bool bResult = FALSE;
+ if (flag) {
+ if (!pAemEntityModel->entityLocked) {
+ *(pAemEntityModel->lockedControllerId) = (U64)0x0000000000000000L;
+ pAemEntityModel->entityLocked = TRUE;
+ bResult = TRUE;
+ }
+ }
+ else {
+ if (pAemEntityModel->entityLocked) {
+ if ((U64)*pAemEntityModel->lockedControllerId == 0x0000000000000000L) {
+ // Only unlock if controller ID is zero.
+ pAemEntityModel->entityLocked = FALSE;
+ bResult = TRUE;
+ }
+ }
+ }
+ AEM_UNLOCK();
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return bResult;
+}
+
diff --git a/lib/avtp_pipeline/aem/openavb_aem.h b/lib/avtp_pipeline/aem/openavb_aem.h
new file mode 100644
index 00000000..acd8ec33
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_aem.h
@@ -0,0 +1,103 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Entity Model
+ * MODULE SUMMARY : Implements the 1722.1 (AVDECC) Entity Model
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_AEM_H
+#define OPENAVB_AEM_H 1
+
+#include "openavb_array.h"
+#include "openavb_avdecc.h"
+#include "openavb_aem_pub.h"
+#include "openavb_types_pub.h"
+#include "openavb_result_codes.h"
+#include "openavb_endpoint.h"
+
+typedef openavbRC (*openavb_aem_descriptor_to_buf_t)(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize);
+typedef openavbRC (*openavb_aem_descriptor_from_buf_t)(void *pVoidDescriptor, U16 bufLength, U8 *pBuf);
+typedef openavbRC (*openavb_aem_descriptor_update_t)(void *pVoidDescriptor);
+
+struct openavb_descriptor_pvt {
+ U32 size;
+ bool bTopLevel; // See IEEE Std 1722.1-2013 clause 7.2.2 for a list of top level descriptors.
+ openavb_aem_descriptor_to_buf_t toBuf;
+ openavb_aem_descriptor_from_buf_t fromBuf;
+ openavb_aem_descriptor_update_t update;
+};
+
+// Every descriptor must begin with these same members. The structure isn't embedded to make hosting applications cleaner.
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+ U16 descriptor_type;
+ U16 descriptor_index;
+} openavb_aem_descriptor_common_t;
+
+typedef struct {
+ openavb_aem_descriptor_configuration_t *pDescriptorConfiguration;
+ openavb_array_t descriptorsArray[OPENAVB_AEM_DESCRIPTOR_COUNT];
+} openavb_aem_configuration_t;
+
+typedef struct {
+ openavb_aem_descriptor_entity_t *pDescriptorEntity;
+ bool entityAcquired;
+ U8 acquiredControllerId[8];
+ bool entityLocked;
+ U8 lockedControllerId[8];
+
+ openavb_array_t aemConfigurations;
+ openavb_array_t aemNonTopLevelDescriptorsArray[OPENAVB_AEM_DESCRIPTOR_COUNT];
+} openavb_avdecc_entity_model_t;
+
+
+// Create the Entity Model
+openavbRC openavbAemCreate(openavb_aem_descriptor_entity_t *pDescriptorEntity);
+
+// Destory the Entity Model
+openavbRC openavbAemDestroy(void);
+
+// Return the Entity Model
+openavb_avdecc_entity_model_t *openavbAemGetModel(void);
+
+// Checks if the Entity Model is valid
+bool openavbAemCheckModel(bool bLog);
+
+// Return the array of descriptors for a specific descroptor type for the specified configuration.
+openavb_array_t openavbAemGetDescriptorArray(U16 configIdx, U16 descriptorType);
+
+// Serialize a descriptor into a buffer. pBuf is filled with the descriptor data. descriptorSize is set to the size of the data placed into the buffer.
+openavbRC openavbAemSerializeDescriptor(U16 configIdx, U16 descriptorType, U16 descriptorIdx, U16 bufSize, U8 *pBuf, U16 *descriptorSize);
+
+#endif // OPENAVB_AEM_H
diff --git a/lib/avtp_pipeline/aem/openavb_aem_pub.h b/lib/avtp_pipeline/aem/openavb_aem_pub.h
new file mode 100644
index 00000000..b5c206c3
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_aem_pub.h
@@ -0,0 +1,80 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Entity Model Public Interface
+ * MODULE SUMMARY : Public Interface for the AVDECC Entity Model Functionality
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_AEM_PUB_H
+#define OPENAVB_AEM_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+
+typedef struct openavb_descriptor_pvt *openavb_descriptor_pvt_ptr_t;
+
+typedef struct openavb_avdecc_configuration_cfg openavb_avdecc_configuration_cfg_t;
+
+// Before calling any Entity Model functions the AVDECC function openavbAvdeccInitialize() must be called with the Entity Descriptor.
+// The Entity Descriptor is the root of all descriptors and must exist to do most things in AVDECC.
+
+// Gets the current configuration descriptor index for the Entity Model. Error checking is not performed on this function.
+U16 openavbAemGetConfigIdx(void);
+
+// Adds descriptors to the Entity Model. The Configuration Descriptor must be added first.
+bool openavbAemAddDescriptor(void *pDescriptor, U16 configIdx, U16 *pResultIdx);
+
+// Get a pointer to a descriptor in the Entity Model.
+void *openavbAemGetDescriptor(U16 configIdx, U16 descriptorType, U16 descriptorIdx);
+
+// Get the index of the descriptor in the Entity Model, or OPENAVB_AEM_DESCRIPTOR_INVALID if not found.
+U16 openavbAemGetDescriptorIndex(U16 configIdx, const void *pDescriptor);
+
+// Add a string to a standard descriptor U8 [64] string field.
+bool openavbAemSetString(U8 *pMem, const char *pString);
+
+// Checks if the Entity Model is acquired.
+bool openavbAemIsAcquired(void);
+
+// Checks if the Entity Model is locked.
+bool openavbAemIsLocked(void);
+
+// Sets the internal Entity Model acquired flag. Care should be used with this function it can impact controller access.
+bool openavbAemAcquire(bool flag);
+
+// Sets the internal Entity Model acquired flag. Care should be used with this function it can impact controller access.
+bool openavbAemLock(bool flag);
+
+
+#endif // OPENAVB_AEM_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_aem_types_pub.h b/lib/avtp_pipeline/aem/openavb_aem_types_pub.h
new file mode 100644
index 00000000..71c29c28
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_aem_types_pub.h
@@ -0,0 +1,1339 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Entity Model Types
+ * MODULE SUMMARY : AVDECC Entity Model Types
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_AEM_TYPES_PUB_H
+#define OPENAVB_AEM_TYPES_PUB_H 1
+
+#include "openavb_types_pub.h"
+
+#define OPENAVB_AEM_STRLEN_MAX (64)
+
+// Descriptors IEEE Std 1722.1-2013 clause 7.2
+#define OPENAVB_AEM_DESCRIPTOR_ENTITY (0x0000)
+#define OPENAVB_AEM_DESCRIPTOR_CONFIGURATION (0x0001)
+#define OPENAVB_AEM_DESCRIPTOR_AUDIO_UNIT (0x0002)
+#define OPENAVB_AEM_DESCRIPTOR_VIDEO_UNIT (0x0003)
+#define OPENAVB_AEM_DESCRIPTOR_SENSOR_UNIT (0x0004)
+#define OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT (0x0005)
+#define OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT (0x0006)
+#define OPENAVB_AEM_DESCRIPTOR_JACK_INPUT (0x0007)
+#define OPENAVB_AEM_DESCRIPTOR_JACK_OUTPUT (0x0008)
+#define OPENAVB_AEM_DESCRIPTOR_AVB_INTERFACE (0x0009)
+#define OPENAVB_AEM_DESCRIPTOR_CLOCK_SOURCE (0x000a)
+#define OPENAVB_AEM_DESCRIPTOR_MEMORY_OBJECT (0x000b)
+#define OPENAVB_AEM_DESCRIPTOR_LOCALE (0x000c)
+#define OPENAVB_AEM_DESCRIPTOR_STRINGS (0x000d)
+#define OPENAVB_AEM_DESCRIPTOR_STREAM_PORT_INPUT (0x000e)
+#define OPENAVB_AEM_DESCRIPTOR_STREAM_PORT_OUTPUT (0x000f)
+#define OPENAVB_AEM_DESCRIPTOR_EXTERNAL_PORT_INPUT (0x0010)
+#define OPENAVB_AEM_DESCRIPTOR_EXTERNAL_PORT_OUTPUT (0x0011)
+#define OPENAVB_AEM_DESCRIPTOR_INTERNAL_PORT_INPUT (0x0012)
+#define OPENAVB_AEM_DESCRIPTOR_INTERNAL_PORT_OUTPUT (0x0013)
+#define OPENAVB_AEM_DESCRIPTOR_AUDIO_CLUSTER (0x0014)
+#define OPENAVB_AEM_DESCRIPTOR_VIDEO_CLUSTER (0x0015)
+#define OPENAVB_AEM_DESCRIPTOR_SENSOR_CLUSTER (0x0016)
+#define OPENAVB_AEM_DESCRIPTOR_AUDIO_MAP (0x0017)
+#define OPENAVB_AEM_DESCRIPTOR_VIDEO_MAP (0x0018)
+#define OPENAVB_AEM_DESCRIPTOR_SENSOR_MAP (0x0019)
+#define OPENAVB_AEM_DESCRIPTOR_CONTROL (0x001a)
+#define OPENAVB_AEM_DESCRIPTOR_SIGNAL_SELECTOR (0x001b)
+#define OPENAVB_AEM_DESCRIPTOR_MIXER (0x001c)
+#define OPENAVB_AEM_DESCRIPTOR_MATRIX (0x001d)
+#define OPENAVB_AEM_DESCRIPTOR_MATRIX_SIGNAL (0x001e)
+#define OPENAVB_AEM_DESCRIPTOR_SIGNAL_SPLITTER (0x001f)
+#define OPENAVB_AEM_DESCRIPTOR_SIGNAL_COMBINER (0x0020)
+#define OPENAVB_AEM_DESCRIPTOR_SIGNAL_DEMULTIPLEXER (0x0021)
+#define OPENAVB_AEM_DESCRIPTOR_SIGNAL_MULTIPLEXER (0x0022)
+#define OPENAVB_AEM_DESCRIPTOR_SIGNAL_TRANSCODER (0x0023)
+#define OPENAVB_AEM_DESCRIPTOR_CLOCK_DOMAIN (0x0024)
+#define OPENAVB_AEM_DESCRIPTOR_CONTROL_BLOCK (0x0025)
+#define OPENAVB_AEM_DESCRIPTOR_INVALID (0xffff)
+
+// This is the total number of decriptor types
+#define OPENAVB_AEM_DESCRIPTOR_COUNT (OPENAVB_AEM_DESCRIPTOR_CONTROL_BLOCK + 1)
+
+
+// Stream flags IEEE Std 1722.1-2013 clause 7.2.6.1
+#define OPENAVB_AEM_STREAM_FLAG_CLOCK_SYNC_SOURCE (0x0001)
+#define OPENAVB_AEM_STREAM_FLAG_CLASS_A (0x0002)
+#define OPENAVB_AEM_STREAM_FLAG_CLASS_B (0x0004)
+#define OPENAVB_AEM_STREAM_FLAG_SUPPORTS_ENCRYPTED (0x0008)
+#define OPENAVB_AEM_STREAM_FLAG_PRIMARY_BACKUP_SUPPORTED (0x0010)
+#define OPENAVB_AEM_STREAM_FLAG_PRIMARY_BACKUP_VALID (0x0020)
+#define OPENAVB_AEM_STREAM_FLAG_SECONDARY_BACKUP_SUPPORTED (0x0040)
+#define OPENAVB_AEM_STREAM_FLAG_SECONDARY_BACKUP_VALID (0x0080)
+#define OPENAVB_AEM_STREAM_FLAG_TERTIARY_BACKUP_SUPPORTED (0x0100)
+#define OPENAVB_AEM_STREAM_FLAG_TERTIARY_BACKUP_VALID (0x0200)
+
+// Jack Flags IEEE Std 1722.1-2013 clause 7.2.7.1
+#define OPENAVB_AEM_JACK_FLAG_CLOCK_SYNC_SOURCE (0x0001)
+#define OPENAVB_AEM_JACK_FLAG_CAPTIVE (0x0002)
+
+// Jack Types IEEE Std 1722.1-2013 clause 7.2.7.2
+#define OPENAVB_AEM_JACK_TYPE_SPEAKER (0x0000)
+#define OPENAVB_AEM_JACK_TYPE_HEADPHONE (0x0001)
+#define OPENAVB_AEM_JACK_TYPE_ANALOG_MICROPHONE (0x0002)
+#define OPENAVB_AEM_JACK_TYPE_SPDIF (0x0003)
+#define OPENAVB_AEM_JACK_TYPE_ADAT (0x0004)
+#define OPENAVB_AEM_JACK_TYPE_TDIF (0x0005)
+#define OPENAVB_AEM_JACK_TYPE_MADI (0x0006)
+#define OPENAVB_AEM_JACK_TYPE_UNBALANCED_ANALOG (0x0007)
+#define OPENAVB_AEM_JACK_TYPE_BALANCED_ANALOG (0x0008)
+#define OPENAVB_AEM_JACK_TYPE_DIGITAL (0x0009)
+#define OPENAVB_AEM_JACK_TYPE_MIDI (0x000a)
+#define OPENAVB_AEM_JACK_TYPE_AES_EBU (0x000b)
+#define OPENAVB_AEM_JACK_TYPE_COMPOSITE_VIDEO (0x000c)
+#define OPENAVB_AEM_JACK_TYPE_S_VHS_VIDEO (0x000d)
+#define OPENAVB_AEM_JACK_TYPE_COMPONENT_VIDEO (0x000e)
+#define OPENAVB_AEM_JACK_TYPE_DVI (0x000f)
+#define OPENAVB_AEM_JACK_TYPE_HDMI (0x0010)
+#define OPENAVB_AEM_JACK_TYPE_UDI (0x0011)
+#define OPENAVB_AEM_JACK_TYPE_DISPLAYPORT (0x0012)
+#define OPENAVB_AEM_JACK_TYPE_ANTENNA (0x0013)
+#define OPENAVB_AEM_JACK_TYPE_ANALOG_TUNER (0x0014)
+#define OPENAVB_AEM_JACK_TYPE_ETHERNET (0x0015)
+#define OPENAVB_AEM_JACK_TYPE_WIFI (0x0016)
+#define OPENAVB_AEM_JACK_TYPE_USB (0x0017)
+#define OPENAVB_AEM_JACK_TYPE_PCI (0x0018)
+#define OPENAVB_AEM_JACK_TYPE_PCI_E (0x0019)
+#define OPENAVB_AEM_JACK_TYPE_SCSI (0x001a)
+#define OPENAVB_AEM_JACK_TYPE_ATA (0x001b)
+#define OPENAVB_AEM_JACK_TYPE_IMAGER (0x001c)
+#define OPENAVB_AEM_JACK_TYPE_IR (0x001d)
+#define OPENAVB_AEM_JACK_TYPE_THUNDERBOLT (0x001e)
+#define OPENAVB_AEM_JACK_TYPE_SATA (0x001f)
+#define OPENAVB_AEM_JACK_TYPE_SMPTE_LTC (0x0020)
+#define OPENAVB_AEM_JACK_TYPE_DIGITAL_MICROPHONE (0x0021)
+#define OPENAVB_AEM_JACK_TYPE_AUDIO_MEDIA_CLOCK (0x0022)
+#define OPENAVB_AEM_JACK_TYPE_VIDEO_MEDIA_CLOCK (0x0023)
+#define OPENAVB_AEM_JACK_TYPE_GNSS_CLOCK (0x0024)
+#define OPENAVB_AEM_JACK_TYPE_PPS (0x0025)
+#define OPENAVB_AEM_JACK_TYPE_EXPANSION (0xffff)
+
+// Interface Types IEEE Std 1722.1-2013 clause 7.2.8.1
+#define OPENAVB_AEM_INTERFACE_TYPE_GPTP_GRANDMASTER_SUPPORTED (0x0001)
+#define OPENAVB_AEM_INTERFACE_TYPE_GPTP_SUPPORTED (0x0002)
+#define OPENAVB_AEM_INTERFACE_TYPE_SRP_SUPPORTED (0x0004)
+
+// Clock Source Flags IEEE Std 1722.1-2013 clause 7.2.9.1
+#define OPENAVB_AEM_CLOCK_SOURCE_FLAG_STREAM_ID (0x0001)
+#define OPENAVB_AEM_CLOCK_SOURCE_FLAG_LOCAL_ID (0x0002)
+
+// Clock Source Types IEEE Std 1722.1-2013 clause 7.2.9.2
+#define OPENAVB_AEM_CLOCK_SOURCE_TYPE_INTERNAL (0x0000)
+#define OPENAVB_AEM_CLOCK_SOURCE_TYPE_EXTERNAL (0x0001)
+#define OPENAVB_AEM_CLOCK_SOURCE_TYPE_INPUT_STREAM (0x0002)
+#define OPENAVB_AEM_CLOCK_SOURCE_TYPE_EXPANSION (0xffff)
+
+// Memory Object Types IEEE Std 1722.1-2013 clause 7.2.10.1
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_FIRMWARE_IMAGE (0x0000)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_VENDOR_SPECIFIC (0x0001)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_CRASH_DUMP (0x0002)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_LOG_OBJECT (0x0003)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_AUTOSTART_SETTINGS (0x0004)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_SNAPSHOT_SETTINGS (0x0005)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_SVG_MANUFACTURER (0x0006)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_SVG_ENTITY (0x0007)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_SVG_GENERIC (0x0008)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_PNG_MANUFACTURER (0x0009)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_PNG_ENTITY (0x000a)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_PNG_GENERIC (0x000b)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_DAE_MANUFACTURER (0x000c)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_DAE_ENTITY (0x000d)
+#define OPENAVB_AEM_MEMORY_OBJECT_TYPE_DAE_GENERIC (0x000e)
+
+// Memory Object Operation Types IEEE Std 1722.1-2013 clause 7.2.10.2
+#define OPENAVB_AEM_MEMORY_OBJECT_OPERATION_TYPE_STORE (0x0000)
+#define OPENAVB_AEM_MEMORY_OBJECT_OPERATION_TYPE_STORE_AND_REBOOT (0x0001)
+#define OPENAVB_AEM_MEMORY_OBJECT_OPERATION_TYPE_READ (0x0002)
+#define OPENAVB_AEM_MEMORY_OBJECT_OPERATION_TYPE_ERASE (0x0003)
+#define OPENAVB_AEM_MEMORY_OBJECT_OPERATION_TYPE_UPLOAD (0x0004)
+
+// Port Flags IEEE Std 1722.1-2013 clause 7.2.13.1
+#define OPENAVB_AEM_PORT_FLAG_CLOCK_SYNC_SOURCE (0x0001)
+#define OPENAVB_AEM_PORT_FLAG_ASYNC_SAMPLE_RATE_CONV (0x0002)
+#define OPENAVB_AEM_PORT_FLAG_SYNC_SAMPLE_RATE_CONV (0x0004)
+
+// Audio Cluster Formats IEEE Std 1722.1-2013 clause 7.2.16.1
+#define OPENAVB_AEM_AUDIO_CLUSTER_FORMAT_IEC_60958 (0x00)
+#define OPENAVB_AEM_AUDIO_CLUSTER_FORMAT_MBLA (0x40)
+#define OPENAVB_AEM_AUDIO_CLUSTER_FORMAT_MIDI (0x80)
+#define OPENAVB_AEM_AUDIO_CLUSTER_FORMAT_SMPTE (0x88)
+
+// Video Cluster Formats IEEE Std 1722.1-2013 clause 7.2.17.1
+#define OPENAVB_AEM_VIDEO_CLUSTER_FORMAT_MPEG_PES_FORMAT (0x00)
+#define OPENAVB_AEM_VIDEO_CLUSTER_FORMAT_AVTP_FORMAT (0x01)
+#define OPENAVB_AEM_VIDEO_CLUSTER_FORMAT_RTP_PAYLOAD_FORMAT (0x02)
+#define OPENAVB_AEM_VIDEO_CLUSTER_FORMAT_VENDOR_SPECIFIC_FORMAT (0xfe)
+#define OPENAVB_AEM_VIDEO_CLUSTER_FORMAT_EXPERIMENTAL_FORMAT (0xff)
+
+// Control Value Type Max Counts IEEE Std 1722.1-2013 clause 7.2.22
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_INT8 (40)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT8 (40)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_INT16 (25)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT16 (25)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_INT32 (14)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT32 (14)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_INT64 (7)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT64 (7)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_FLOAT (14)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_DOUBLE (7)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT8 (400)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT8 (400)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT16 (199)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT16 (199)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT32 (98)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT32 (98)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT64 (48)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT64 (48)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_FLOAT (98)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_DOUBLE (48)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_STRING (199)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_INT8 (396)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT8 (396)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_INT16 (196)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT16 (196)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_INT32 (96)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT32 (96)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_INT64 (46)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT64 (46)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_FLOAT (96)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_DOUBLE (46)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_UTF8 (1)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_BODE_PLOT (29)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SMPTE_TIME (1)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SAMPLE_RATE (1)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_GPTP_TIME (1)
+#define OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_VENDOR (1)
+
+// Control Value Type Max Sources IEEE Std 1722.1-2013 clause 7.2.24
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_INT8 (68)
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_UINT8 (68)
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_INT16 (67)
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_UINT16 (67)
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_INT32 (65)
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_UINT32 (65)
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_INT64 (61)
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_UINT64 (61)
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_FLOAT (65)
+#define OPENAVB_AEM_MIXER_VALUE_MAX_SOURCE_CONTROL_LINEAR_DOUBLE (61)
+
+// Matrix Control Value Type Max Counts IEEE Std 1722.1-2013 clause 7.2.25
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT32 (14)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_LINEAR_INT64 (7)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT64 (7)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_LINEAR_FLOAT (14)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_LINEAR_DOUBLE (7)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT8 (400)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT8 (400)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT16 (199)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT16 (199)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT32 (98)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT32 (98)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT64 (48)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT64 (48)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_FLOAT (98)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_DOUBLE (48)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_UTF8 (1)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_BODE_PLOT (29)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_INT8 (396)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT8 (396)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_INT16 (196)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT16 (196)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_INT32 (96)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT32 (96)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_INT64 (46)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT64 (46)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_FLOAT (96)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_ARRAY_DOUBLE (46)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SELECTOR_STRING (199)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SMPTE_TIME (1)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_SAMPLE_RATE (1)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_GPTP_TIME (1)
+#define OPENAVB_AEM_MATRIX_VALUE_MAX_COUNT_CONTROL_VENDOR (1)
+
+// Transcoder Control Value Type Max Counts IEEE Std 1722.1-2013 clause 7.2.31
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_INT8 (41)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT8 (41)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_INT16 (26)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT16 (26)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_INT32 (14)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT32 (14)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_INT64 (8)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT64 (8)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_FLOAT (14)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_LINEAR_DOUBLE (8)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT8 (412)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT8 (412)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT16 (205)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT16 (205)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT32 (101)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT32 (101)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT64 (49)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT64 (49)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_FLOAT (101)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_DOUBLE (49)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_INT8 (408)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT8 (408)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_INT16 (202)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT16 (202)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_INT32 (99)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT32 (99)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_INT64 (47)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT64 (47)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_FLOAT (99)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_ARRAY_DOUBLE (47)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SELECTOR_STRING (205)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_SAMPLE_RATE (1)
+#define OPENAVB_AEM_TRANSCODER_VALUE_MAX_COUNT_CONTROL_VENDOR (1)
+
+// Sample rates IEEE Std 1722.1-2013 clause 7.3.1
+typedef struct {
+ U8 pull;
+ U32 base;
+} openavb_aem_sampling_rate_t;
+
+// Sample rate pull field IEEE Std 1722.1-2013 clause 7.3.1.1
+#define OPENAVB_AEM_SAMPLE_RATE_PULL_MULTI_BASE_FREQ_BY_1_0 (0)
+#define OPENAVB_AEM_SAMPLE_RATE_PULL_MULTI_BASE_FREQ_BY_1_DIV_1_001 (1)
+#define OPENAVB_AEM_SAMPLE_RATE_PULL_MULTI_BASE_FREQ_BY_1_001 (2)
+#define OPENAVB_AEM_SAMPLE_RATE_PULL_MULTI_BASE_FREQ_BY_24_DIV_25 (3)
+#define OPENAVB_AEM_SAMPLE_RATE_PULL_MULTI_BASE_FREQ_BY_25_DIV_24 (4)
+
+// Stream formats : IIDC IEEE Std 1722.1-2013 clause 7.3.2.1.1.1
+typedef struct {
+ U8 sf;
+} openavb_aem_stream_format_iec_61883_iidc_t;
+
+// Stream formats : IIDC IEEE Std 1722.1-2013 clause 7.3.2.1.1.1
+typedef struct {
+ U8 sf;
+ U8 iidc_format;
+ U8 iidc_mode;
+ U8 iidc_rate;
+} openavb_aem_stream_format_iidc_t;
+
+// Stream formats : IEC 61883 IEEE Std 1722.1-2013 clause 7.3.2.1.1.1
+typedef struct {
+ U8 sf;
+ U8 fmt;
+} openavb_aem_stream_format_iec_61883_t;
+
+// Stream formats : IEC 61883-4 IEEE Std 1722.1-2013 clause 7.3.2.1.1.2
+typedef struct {
+ U8 sf;
+ U8 fmt;
+} openavb_aem_stream_format_iec_61883_4_t;
+
+// Stream formats : IEC 61883-6 IEEE Std 1722.1-2013 clause 7.3.2.1.1.4
+typedef struct {
+ U8 sf;
+ U8 fmt;
+ U8 fdf_evt;
+ U8 fdf_sfc;
+ U8 dbs;
+ U8 b;
+ U8 nb;
+} openavb_aem_stream_format_iec_61883_6_t;
+
+// Stream formats : IEC 61883-6 32 bit IEEE Std 1722.1-2013 clause 7.3.2.1.1.4
+typedef struct {
+ U8 sf;
+ U8 fmt;
+ U8 fdf_evt;
+ U8 fdf_sfc;
+ U8 dbs;
+ U8 b;
+ U8 nb;
+} openavb_aem_stream_format_iec_61883_6_32bit_t;
+
+// Stream formats : IEC 61883-6 float IEEE Std 1722.1-2013 clause 7.3.2.1.1.5
+typedef struct {
+ U8 sf;
+ U8 fmt;
+ U8 fdf_evt;
+ U8 fdf_sfc;
+ U8 dbs;
+ U8 b;
+ U8 nb;
+} openavb_aem_stream_format_iec_61883_6_float_t;
+
+// Stream formats : IEC 61883-6 float IEEE Std 1722.1-2013 clause 7.3.2.1.1.6
+typedef struct {
+ U8 sf;
+ U8 fmt;
+ U8 fdf_evt;
+ U8 fdf_sfc;
+ U8 dbs;
+ U8 b;
+ U8 nb;
+ U8 label_iec_60958_cnt;
+ U8 label_mbla_cnt;
+ U8 label_midi_cnt;
+ U8 label_smptecnt;
+} openavb_aem_stream_format_iec_61883_6_am824_t;
+
+// Stream formats : IEC 61883-8 IEEE Std 1722.1-2013 clause 7.3.2.1.1.7
+typedef struct {
+ U8 sf;
+ U8 fmt;
+ U8 video_mode;
+ U8 compress_mode;
+ U8 color_space;
+} openavb_aem_stream_format_iec_61883_8_t;
+
+// Stream formats : AVTP Audio IEEE Std 1722.1-2013 clause 7.3.2.1.3
+typedef struct {
+ U8 nominal_sample_rate;
+ U8 format;
+ U8 bit_depth;
+ U16 channels_per_frame;
+ U16 samples_per_frame;
+} openavb_aem_stream_format_avtp_audio_t;
+
+// Stream formats : AVTP Video IEEE Std 1722.1-2013 clause 7.3.2.1.4
+typedef struct {
+ U8 format;
+} openavb_aem_stream_format_avtp_video_t;
+
+// Stream formats : AVTP Control IEEE Std 1722.1-2013 clause 7.3.2.1.5
+typedef struct {
+ U8 protocol_type;
+ U8 format_id[6];
+} openavb_aem_stream_format_avtp_control_t;
+
+// Stream formats : Vendor IEEE Std 1722.1-2013 clause 7.3.2.1.6
+typedef struct {
+ U8 format_id[6];
+} openavb_aem_stream_format_vendor_t;
+
+// Stream formats : Experimental IEEE Std 1722.1-2013 clause 7.3.2.1.7
+typedef struct {
+} openavb_aem_stream_format_experimental_t;
+
+// Stream formats : Vendor Specific IEEE Std 1722.1-2013 clause 7.3.2.2.1
+typedef struct {
+ U8 format_id[6];
+} openavb_aem_stream_format_vendor_specific_t;
+
+// Stream formats IEEE Std 1722.1-2013 clause 7.3.2
+typedef struct {
+ U8 v;
+ U8 subtype;
+ union {
+ openavb_aem_stream_format_iec_61883_iidc_t iec_61883_iidc;
+ openavb_aem_stream_format_iidc_t iidc;
+ openavb_aem_stream_format_iec_61883_t iec_61883;
+ openavb_aem_stream_format_iec_61883_4_t iec_61883_4;
+ openavb_aem_stream_format_iec_61883_6_32bit_t iec_61883_6;
+ openavb_aem_stream_format_iec_61883_6_32bit_t iec_61883_6_32bit;
+ openavb_aem_stream_format_iec_61883_6_float_t iec_61883_6_float;
+ openavb_aem_stream_format_iec_61883_6_am824_t iec_61883_6_am824;
+ openavb_aem_stream_format_iec_61883_8_t iec_61883_8;
+ openavb_aem_stream_format_avtp_audio_t avtp_audio;
+ openavb_aem_stream_format_avtp_video_t avtp_video;
+ openavb_aem_stream_format_avtp_control_t avtp_control;
+ openavb_aem_stream_format_vendor_t vendor;
+ openavb_aem_stream_format_experimental_t experimental;
+ openavb_aem_stream_format_vendor_specific_t vendor_specific;
+ } subtypes;
+} openavb_aem_stream_format_t;
+
+
+#define OPENAVB_AEM_STREAM_FORMAT_SF_IIDC (0x00)
+#define OPENAVB_AEM_STREAM_FORMAT_SF_IEC_61883 (0x00)
+
+#define OPENAVB_AEM_STREAM_FORMAT_FMT_61883_4 (0x20)
+#define OPENAVB_AEM_STREAM_FORMAT_FMT_61883_6 (0x10)
+#define OPENAVB_AEM_STREAM_FORMAT_FMT_61883_8 (0x01)
+
+#define OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_AM824 (0x00)
+#define OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_32BITS (0x06)
+#define OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_FLOAT (0x04)
+
+
+// Stream formats IEEE Std 1722.1-2013 clause 7.3.2.1
+#define OPENAVB_AEM_STREAM_FORMAT_61883_IIDC_SUBTYPE (0x00)
+#define OPENAVB_AEM_STREAM_FORMAT_MMA_SUBTYPE (0x01)
+#define OPENAVB_AEM_STREAM_FORMAT_AVTP_AUDIO_SUBTYPE (0x02)
+#define OPENAVB_AEM_STREAM_FORMAT_AVTP_VIDEO_SUBTYPE (0x03)
+#define OPENAVB_AEM_STREAM_FORMAT_AVTP_CONTROL_SUBTYPE (0x04)
+#define OPENAVB_AEM_STREAM_FORMAT_VENDOR_SUBTYPE (0x6f)
+#define OPENAVB_AEM_STREAM_FORMAT_EXPERIMENTAL_SUBTYPE (0x7f)
+
+// AVTP Audio Stream Sample Rates IEEE Std 1722.1-2013 7.3.2.1.3
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_NOT_SPECIFIED (0x0)
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_8_KHZ (0x1)
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_16_KHZ (0x2)
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_32_KHZ (0x3)
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_44_1_KHZ (0x4)
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_48_KHZ (0x5)
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_88_2_KHZ (0x6)
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_96_KHZ (0x7)
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_176_4_KHZ (0x8)
+#define OPENAVB_AEM_AUDIO_STREAM_SAMPLE_RATE_192_KHZ (0x9)
+
+// AVTP Audio Stream Format IEEE Std 1722.1-2013 7.3.2.1.3
+#define OPENAVB_AEM_AUDIO_STREAM_FORMAT_NOT_SPECIFIED (0)
+#define OPENAVB_AEM_AUDIO_STREAM_FORMAT_FLOAT (1)
+#define OPENAVB_AEM_AUDIO_STREAM_FORMAT_32BIT_INTEGER (2)
+#define OPENAVB_AEM_AUDIO_STREAM_FORMAT_24BIT_PACKED_INTEGER (3)
+#define OPENAVB_AEM_AUDIO_STREAM_FORMAT_16BIT_INTEGER (4)
+
+// AVTP Video Stream Format IEEE Std 1722.1-2013 7.3.2.1.4
+#define OPENAVB_AEM_VIDEO_STREAM_FORMAT_RESERVED (0x00)
+#define OPENAVB_AEM_VIDEO_STREAM_FORMAT_AVTP_FORMAT (0x01)
+#define OPENAVB_AEM_VIDEO_STREAM_FORMAT_RTP_PAYLOAD_TYPE (0x02)
+#define OPENAVB_AEM_VIDEO_STREAM_FORMAT_VENDOR_SPECIFIC (0xfe)
+#define OPENAVB_AEM_VIDEO_STREAM_FORMAT_EXPERIMENTAL (0xff)
+
+// AVTP Control Stream Format IEEE Std 1722.1-2013 7.3.2.1.5
+#define OPENAVB_AEM_CONTROL_STREAM_FORMAT_AUTOMOTIVE (0)
+#define OPENAVB_AEM_CONTROL_STREAM_FORMAT_TSCS (3)
+#define OPENAVB_AEM_CONTROL_STREAM_FORMAT_VENDOR_DEFINED (15)
+
+// Control Value Units IEEE Std 1722.1-2013 clause 7.3.3
+#define OPENAVB_AEM_UNIT_UNITLESS (0x00)
+#define OPENAVB_AEM_UNIT_UNITLESS_COUNT (0x01)
+#define OPENAVB_AEM_UNIT_UNITLESS_PERCENT (0x02)
+#define OPENAVB_AEM_UNIT_UNITLESS_FSTOP (0x03)
+#define OPENAVB_AEM_UNIT_TIME_SECONDS (0x08)
+#define OPENAVB_AEM_UNIT_TIME_MINUTES (0x09)
+#define OPENAVB_AEM_UNIT_TIME_HOURS (0x0a)
+#define OPENAVB_AEM_UNIT_TIME_DAYS (0x0b)
+#define OPENAVB_AEM_UNIT_TIME_MONTHS (0x0c)
+#define OPENAVB_AEM_UNIT_TIME_YEARS (0x0d)
+#define OPENAVB_AEM_UNIT_TIME_SAMPLES (0x0e)
+#define OPENAVB_AEM_UNIT_TIME_FRAMES (0x0f)
+#define OPENAVB_AEM_UNIT_FREQUENCY_HERTZ (0x10)
+#define OPENAVB_AEM_UNIT_FREQUENCY_SEMITONES (0x11)
+#define OPENAVB_AEM_UNIT_FREQUENCY_CENTS (0x12)
+#define OPENAVB_AEM_UNIT_FREQUENCY_OCTAVES (0x13)
+#define OPENAVB_AEM_UNIT_FREQUENCY_FPS (0x14)
+#define OPENAVB_AEM_UNIT_DISTANCE_METRES (0x18)
+#define OPENAVB_AEM_UNIT_TEMPERATURE_KELVIN (0x20)
+#define OPENAVB_AEM_UNIT_MASS_GRAMS (0x28)
+#define OPENAVB_AEM_UNIT_VOLTAGE_VOLTS (0x30)
+#define OPENAVB_AEM_UNIT_VOLTAGE_DBV (0x31)
+#define OPENAVB_AEM_UNIT_VOLTAGE_DBU (0x32)
+#define OPENAVB_AEM_UNIT_CURRENT_AMPS (0x38)
+#define OPENAVB_AEM_UNIT_POWER_WATTS (0x40)
+#define OPENAVB_AEM_UNIT_POWER_DBM (0x41)
+#define OPENAVB_AEM_UNIT_POWER_DBW (0x42)
+#define OPENAVB_AEM_UNIT_PRESSURE_PASCALS (0x48)
+#define OPENAVB_AEM_UNIT_MEMORY_BITS (0x50)
+#define OPENAVB_AEM_UNIT_MEMORY_BYTES (0x51)
+#define OPENAVB_AEM_UNIT_MEMORY_KIBIBYTES (0x52)
+#define OPENAVB_AEM_UNIT_MEMORY_MEBIBYTES (0x53)
+#define OPENAVB_AEM_UNIT_MEMORY_GIBIBYTES (0x54)
+#define OPENAVB_AEM_UNIT_MEMORY_TEBIBYTES (0x55)
+#define OPENAVB_AEM_UNIT_BANDWIDTH_BITS_PER_SEC (0x58)
+#define OPENAVB_AEM_UNIT_BANDWIDTH_BYTES_PER_SEC (0x59)
+#define OPENAVB_AEM_UNIT_BANDWIDTH_KIBIBYTES_PER_SEC (0x5a)
+#define OPENAVB_AEM_UNIT_BANDWIDTH_MEBIBYTES_PER_SEC (0x5b)
+#define OPENAVB_AEM_UNIT_BANDWIDTH_GIGIBYTES_PER_SEC (0x5c)
+#define OPENAVB_AEM_UNIT_BANDWIDTH_TEBIBYTES_PER_SEC (0x5d)
+#define OPENAVB_AEM_UNIT_LUMINOSITY_CANDELAS (0x60)
+#define OPENAVB_AEM_UNIT_ENERGY_JOULES (0x68)
+#define OPENAVB_AEM_UNIT_ANGLE_RADIANS (0x70)
+#define OPENAVB_AEM_UNIT_FORCE_NEWTONS (0x78)
+#define OPENAVB_AEM_UNIT_RESISTANCE_OHMS (0x80)
+#define OPENAVB_AEM_UNIT_VELOCITY_METRES_PER_SEC (0x88)
+#define OPENAVB_AEM_UNIT_VELOCITY_RADIANS_PER_SEC (0x89)
+#define OPENAVB_AEM_UNIT_ACCELERATION_METRES_PER_SEC_SQUARED (0x90)
+#define OPENAVB_AEM_UNIT_ACCELERATION_RADIANS_PER_SEC_SQUARED (0x91)
+#define OPENAVB_AEM_UNIT_MAGNETIC_FLUX_TESLAS (0x98)
+#define OPENAVB_AEM_UNIT_AREA_METRES_SQUARED (0xa0)
+#define OPENAVB_AEM_UNIT_VOLUME_METRES_CUBED (0xa8)
+#define OPENAVB_AEM_UNIT_VOLUME_LITRES (0xa9)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DB (0xb0)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DB_PEAK (0xb1)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DB_RMS (0xb2)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DBFS (0xb3)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DBFS_PEAK (0xb4)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DBFS_RMS (0xb5)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DBTP (0xb6)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DB_SPL_A (0xb7)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DB_Z (0xb8)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DB_SPL_C (0xb9)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DB_SPL (0xba)
+#define OPENAVB_AEM_UNIT_LOUDNESS_LU (0xbb)
+#define OPENAVB_AEM_UNIT_LOUDNESS_LUFS (0xbc)
+#define OPENAVB_AEM_UNIT_LOUDNESS_DB_A (0xbd)
+
+// Control Types IEEE Std 1722.1-2013 clause 7.3.4
+#define OPENAVB_AEM_CONTROL_TYPE_ENABLE (0x90e0f00000000000ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_IDENTIFY (0x90e0f00000000001ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MUTE (0x90e0f00000000002ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_INVERT (0x90e0f00000000003ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_GAIN (0x90e0f00000000004ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_ATTENUATE (0x90e0f00000000005ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_DELAY (0x90e0f00000000006ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_SRC_MODE (0x90e0f00000000007ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_SNAPSHOT (0x90e0f00000000008ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_POW_LINE_FREQ (0x90e0f00000000009ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_POWER_STATUS (0x90e0f0000000000aULL)
+#define OPENAVB_AEM_CONTROL_TYPE_FAN_STATUS (0x90e0f0000000000bULL)
+#define OPENAVB_AEM_CONTROL_TYPE_TEMPERATURE (0x90e0f0000000000cULL)
+#define OPENAVB_AEM_CONTROL_TYPE_ALTITUDE (0x90e0f0000000000dULL)
+#define OPENAVB_AEM_CONTROL_TYPE_ABSOLUTE_HUMIDITY (0x90e0f0000000000eULL)
+#define OPENAVB_AEM_CONTROL_TYPE_RELATIVE_HUMIDITY (0x90e0f0000000000fULL)
+#define OPENAVB_AEM_CONTROL_TYPE_ORIENTATION (0x90e0f00000000010ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_VELOCITY (0x90e0f00000000011ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_ACCELERATION (0x90e0f00000000012ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_FILTER_RESPONSE (0x90e0f00000000013ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_PANPOT (0x90e0f00000010000ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_PHANTOM (0x90e0f00000010001ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_AUDIO_SCALE (0x90e0f00000010002ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_AUDIO_METERS (0x90e0f00000010003ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_AUDIO_SPECTRUM (0x90e0f00000010004ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_SCANNING_MODE (0x90e0f00000020000ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_AUTO_EXP_MODE (0x90e0f00000020001ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_AUTO_EXP_PRIO (0x90e0f00000020002ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_EXP_TIME (0x90e0f00000020003ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_FOCUS (0x90e0f00000020004ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_FOCUS_AUTO (0x90e0f00000020005ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_IRIS (0x90e0f00000020006ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_ZOOM (0x90e0f00000020007ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_PRIVACY (0x90e0f00000020008ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_BACKLIGHT (0x90e0f00000020009ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_BRIGHTNESS (0x90e0f0000002000aULL)
+#define OPENAVB_AEM_CONTROL_TYPE_CONTRAST (0x90e0f0000002000bULL)
+#define OPENAVB_AEM_CONTROL_TYPE_HUE (0x90e0f0000002000cULL)
+#define OPENAVB_AEM_CONTROL_TYPE_SATURATION (0x90e0f0000002000dULL)
+#define OPENAVB_AEM_CONTROL_TYPE_SHARPNESS (0x90e0f0000002000eULL)
+#define OPENAVB_AEM_CONTROL_TYPE_GAMMA (0x90e0f0000002000fULL)
+#define OPENAVB_AEM_CONTROL_TYPE_WHITE_BAL_TEMP (0x90e0f00000020010ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_WHITE_BAL_TEMP_AUTO (0x90e0f00000020011ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_WHITE_BAL_COMP (0x90e0f00000020012ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_WHITE_BAL_COMP_AUTO (0x90e0f00000020013ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_DIGITAL_ZOOM (0x90e0f00000020014ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_PLAYLIST (0x90e0f00000030000ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_PLAYLIST_NAME (0x90e0f00000030001ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_DISK (0x90e0f00000030002ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_DISK_NAME (0x90e0f00000030003ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_TRACK (0x90e0f00000030004ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_TRACK_NAME (0x90e0f00000030005ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_SPEED (0x90e0f00000030006ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_SAMPLE_POSITION (0x90e0f00000030007ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_PLAYBACK_TRANSPORT (0x90e0f00000030008ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_RECORD_TRANSPORT (0x90e0f00000030009ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_FREQUENCY (0x90e0f00000040000ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_MODULATION (0x90e0f00000040001ULL)
+#define OPENAVB_AEM_CONTROL_TYPE_POLARIZATION (0x90e0f00000040002ULL)
+
+// Sample Rate Convertor (SRC_MODE) Mode IEEE Std 1722.1-2013 clause 7.3.4.8
+#define OPENAVB_AEM_CONTROL_TYPE_SRC_MODE_OFF (0x00)
+#define OPENAVB_AEM_CONTROL_TYPE_SRC_MODE_SYNCHRONOUS (0x01)
+#define OPENAVB_AEM_CONTROL_TYPE_SRC_MODE_ASYNCHRONOUS (0x02)
+
+// Snapshot Control (SNAPSHOT) IEEE Std 1722.1-2013 clause 7.3.4.9
+#define OPENAVB_AEM_CONTROL_TYPE_SNAPSHOT_CAPTURE (0x0000)
+#define OPENAVB_AEM_CONTROL_TYPE_SNAPSHOT_RECALL (0x0001)
+#define OPENAVB_AEM_CONTROL_TYPE_SNAPSHOT_ERASE (0x0002)
+
+// Power Line Frequency Control (POW_LINE_FREQ) IEEE Std 1722.1-2013 clause 7.3.4.10
+#define OPENAVB_AEM_CONTROL_TYPE_POW_LINE_FREQ_FIFTY_HERTZ (50)
+#define OPENAVB_AEM_CONTROL_TYPE_POW_LINE_FREQ_SIXTY_HERTZ (60)
+
+// Auto Exposure Mode Control (AUTO_EXP_MODE) IEEE Std 1722.1-2013 clause 7.3.4.27
+#define OPENAVB_AEM_CONTROL_TYPE_AUTO_EXP_MODE_MANUAL (0x01)
+#define OPENAVB_AEM_CONTROL_TYPE_AUTO_EXP_MODE_AUTO (0x11)
+#define OPENAVB_AEM_CONTROL_TYPE_AUTO_EXP_MODE_SHUTTER_PRIO (0x21)
+#define OPENAVB_AEM_CONTROL_TYPE_AUTO_EXP_MODE_APER_PRIO (0x31)
+
+// Media Disk Selection Control (MEDIA_DISK) IEEE Std 1722.1-2013 clause 7.3.4.49
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_DISK_CHOOSE (0x0000)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_DISK_PREVIOUS (0x0001)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_DISK_NEXT (0x0002)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_DISK_OPEN (0x0003)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_DISK_CLOSE (0x0004)
+
+// Media Playback Transport Control (MEDIA_PLAYBACK_TRANSPORT) IEEE Std 1722.1-2013 clause 7.3.4.55
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_PLAYBACK_TRANSPORT_STOP (0x0000)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_PLAYBACK_TRANSPORT_PLAY (0x0001)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_PLAYBACK_TRANSPORT_PAUSE (0x0002)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_PLAYBACK_TRANSPORT_UNPAUSE (0x0003)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_PLAYBACK_TRANSPORT_SCAN_FORWARD (0x0004)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_PLAYBACK_TRANSPORT_SCAN_BACKWARD (0x0005)
+
+// Media Record Transport Control (MEDIA_RECORD_TRANSPORT) IEEE Std 1722.1-2013 clause 7.3.4.56
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_RECORD_TRANSPORT_STOP (0x0000)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_RECORD_TRANSPORT_PLAY (0x0001)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_RECORD_TRANSPORT_PAUSE (0x0002)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_RECORD_TRANSPORT_UNPAUSE (0x0003)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_RECORD_TRANSPORT_SCAN_FORWARD (0x0004)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_RECORD_TRANSPORT_SCAN_BACKWARD (0x0005)
+#define OPENAVB_AEM_CONTROL_TYPE_MEDIA_RECORD_TRANSPORT_RECORD (0x0006)
+
+// Modulation Control (MODULATION) IEEE Std 1722.1-2013 clause 7.3.4.58
+#define OPENAVB_AEM_CONTROL_TYPE_MODULATION_AMPLITUDE_MODULATION (0x00)
+#define OPENAVB_AEM_CONTROL_TYPE_MODULATION_FREQUENCY_MODULATION (0x01)
+#define OPENAVB_AEM_CONTROL_TYPE_MODULATION_PHASE_MODULATION (0x02)
+
+// Polarization Control (POLARIZATION) IEEE Std 1722.1-2013 clause 7.3.4.59
+#define OPENAVB_AEM_CONTROL_TYPE_POLARIZATION_VERTICAL (0x00)
+#define OPENAVB_AEM_CONTROL_TYPE_POLARIZATION_HORIZONTAL (0x01)
+#define OPENAVB_AEM_CONTROL_TYPE_POLARIZATION_LEFT_HAND_CIRCULAR (0x02)
+#define OPENAVB_AEM_CONTROL_TYPE_POLARIZATION_RIGHT_HAND_CIRCULAR (0x03)
+
+// Control_value_type IEEE Std 1722.1-2013 clause 7.3.5.1
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT8 (0x0000)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT8 (0x0001)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT16 (0x0002)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT16 (0x0003)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT32 (0x0004)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT32 (0x0005)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT64 (0x0006)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT64 (0x0007)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_FLOAT (0x0008)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_DOUBLE (0x0009)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT8 (0x000a)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT8 (0x000b)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT16 (0x000c)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT16 (0x000d)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT32 (0x000e)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT32 (0x000f)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT64 (0x0010)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT64 (0x0011)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_FLOAT (0x0012)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_DOUBLE (0x0013)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_STRING (0x0014)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT8 (0x0015)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT8 (0x0016)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT16 (0x0017)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT16 (0x0018)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT32 (0x0019)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT32 (0x001a)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT64 (0x001b)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT64 (0x001c)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_FLOAT (0x001d)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_DOUBLE (0x001e)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_UTF8 (0x001f)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_BODE_PLOT (0x0020)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SMPTE_TIME (0x0021)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SAMPLE_RATE (0x0022)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_GPTP_TIME (0x0023)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_VENDOR (0x3ffe)
+#define OPENAVB_AEM_CONTROL_VALUE_TYPE_EXPANSION (0x3fff)
+
+// Localized String default values IEEE Std 1722.1-2013 clause 7.3.6
+#define OPENAVB_AEM_NO_STRING_OFFSET (0x1fff)
+#define OPENAVB_AEM_NO_STRING_INDEX (7)
+
+// Localized String Reference IEEE Std 1722.1-2013 clause 7.3.6
+typedef struct {
+ U16 offset;
+ U8 index;
+} openavb_aem_string_ref_t;
+
+// Control value formats IEEE Std 1722.1-2013 clause 7.3.5.2
+// Values format for Linear Value Types (CONTROL_LINEAR_INT8 to CONTROL_LINEAR_DOUBLE) IEEE Std 1722.1-2013 clause 7.3.5.2.1
+typedef struct {
+ S8 minimum;
+ S8 maximum;
+ S8 step;
+ S8 default_value;
+ S8 current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_int8_t;
+
+typedef struct {
+ U8 minimum;
+ U8 maximum;
+ U8 step;
+ U8 default_value;
+ U8 current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_uint8_t;
+
+typedef struct {
+ S16 minimum;
+ S16 maximum;
+ S16 step;
+ S16 default_value;
+ S16 current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_int16_t;
+
+typedef struct {
+ U16 minimum;
+ U16 maximum;
+ U16 step;
+ U16 default_value;
+ U16 current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_uint16_t;
+
+typedef struct {
+ S32 minimum;
+ S32 maximum;
+ S32 step;
+ S32 default_value;
+ S32 current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_int32_t;
+
+typedef struct {
+ U32 minimum;
+ U32 maximum;
+ U32 step;
+ U32 default_value;
+ U32 current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_uint32_t;
+
+typedef struct {
+ S64 minimum;
+ S64 maximum;
+ S64 step;
+ S64 default_value;
+ S64 current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_int64_t;
+
+typedef struct {
+ U64 minimum;
+ U64 maximum;
+ U64 step;
+ U64 default_value;
+ U64 current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_uint64_t;
+
+typedef struct {
+ float minimum;
+ float maximum;
+ float step;
+ float default_value;
+ float current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_float_t;
+
+typedef struct {
+ double minimum;
+ double maximum;
+ double step;
+ double default_value;
+ double current;
+ U16 unit;
+ openavb_aem_string_ref_t string;
+} openavb_aem_control_value_format_control_linear_double_t;
+
+
+// Values format for Selector Value Types (CONTROL_SELECTOR_INT8 to CONTROL_SELECTOR_STRING) IEEE Std 1722.1-2013 clause 7.3.5.2.2
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_int8_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_uint8_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_int16_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_uint16_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_int32_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_uint32_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_int64_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_uint64_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_float_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_double_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_selector_string_t;
+
+
+// Values format for Array Value Types (CONTROL_ARRAY_INT8 to CONTROL_ARRAY_ARRAY_DOUBLE) IEEE Std 1722.1-2013 clause 7.3.5.2.3
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_int8_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_uint8_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_int16_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_uint16_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_int32_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_uint32_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_int64_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_uint64_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_float_t;
+
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_array_double_t;
+
+
+// Values format for UTF-8 String Value Type (CONTROL_UTF8) IEEE Std 1722.1-2013 clause 7.3.5.2.4
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_utf8_t;
+
+// Values format for Bode Plot Value Type (CONTROL_BODE_PLOT) IEEE Std 1722.1-2013 clause 7.3.5.2.5
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_bode_plot_t;
+
+// Values format for SMPTE Time Type (CONTROL_SMPTE_TIME) IEEE Std 1722.1-2013 clause 7.3.5.2.6
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_smpte_time_t;
+
+// Values format for Sample Rate Type (CONTROL_SAMPLE_RATE) IEEE Std 1722.1-2013 clause 7.3.5.2.7
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_sample_rate_t;
+
+// Values format for gPTP Time Type (CONTROL_GPTP_TIME) IEEE Std 1722.1-2013 clause 7.3.5.2.8
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_gptp_time_t;
+
+// Values format for Vendor Defined Type (CONTROL_VENDOR) IEEE Std 1722.1-2013 clause 7.3.5.2.9
+typedef struct {
+ // AVDECC_TODO
+} openavb_aem_control_value_format_control_vendor_t;
+
+
+// Content Protection for Video Cluster Format Specific fields IEEE Std 1722.1-2013 clause 7.3.7.1.1
+#define OPENAVB_AEM_VIDEO_CLUSTER_PROTECTION_NONE (0x0)
+#define OPENAVB_AEM_VIDEO_CLUSTER_PROTECTION_HDCP (0x1)
+#define OPENAVB_AEM_VIDEO_CLUSTER_PROTECTION_DTCP (0x2)
+#define OPENAVB_AEM_VIDEO_CLUSTER_PROTECTION_AES_ENCRYPTION (0x3)
+
+// Profiles for MPEG Elementary Streams IEEE Std 1722.1-2013 clause 7.3.7.2.1
+#define OPENAVB_AEM_MPEG_PROFILE_H264_CBP (0x00)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_BP (0x01)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_MP (0x02)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_XP (0x03)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_HIP (0x04)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_PHIP (0x05)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_HI10P (0x06)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_HI422P (0x07)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_HI444PP (0x08)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_HI10I (0x09)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_HI422I (0x0a)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_HI444I (0x0b)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_CAVLC44I (0x0c)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_SBP (0x0d)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_SHP (0x0e)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_SHI (0x0f)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_STHP (0x10)
+#define OPENAVB_AEM_MPEG_PROFILE_H264_MVHP (0x11)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG2_SP (0x12)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG2_MP (0x13)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG2_SNR (0x14)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG2_SPATIAL (0x15)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG2_HP (0x16)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG2_422 (0x17)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG2_MVP (0x18)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG1_LAYER2 (0x80)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG1_LAYER3 (0x81)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG2_LAYER2 (0x82)
+#define OPENAVB_AEM_MPEG_PROFILE_MPEG2_LAYER3 (0x83)
+#define OPENAVB_AEM_MPEG_PROFILE_DOLBY_DIGITAL (0x84)
+#define OPENAVB_AEM_MPEG_PROFILE_DOLBY_DIGITAL_PLUS (0x85)
+#define OPENAVB_AEM_MPEG_PROFILE_DOLBY_DIGITAL_TRUEHD (0x86)
+#define OPENAVB_AEM_MPEG_PROFILE_DOLBY_PRO_LOGIC_II (0x87)
+#define OPENAVB_AEM_MPEG_PROFILE_DOLBY_DIGITAL_EX (0x88)
+#define OPENAVB_AEM_MPEG_PROFILE_DOLBY_DIGITAL_SURROUND_EX (0x89)
+#define OPENAVB_AEM_MPEG_PROFILE_DOLBY_DIGITAL_LIVE (0x8a)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_5_1 (0x8b)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_ES_MATRIX (0x8c)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_ES_DISCRETE (0x8d)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_NEO_6 (0x8e)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_NEO_X (0x8f)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_96_24 (0x90)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_HD (0x91)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_HD_MASTER (0x92)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_INTERACTIVE (0x93)
+#define OPENAVB_AEM_MPEG_PROFILE_DTS_NEO_PC (0x94)
+#define OPENAVB_AEM_MPEG_PROFILE_AAC_LC (0x95)
+#define OPENAVB_AEM_MPEG_PROFILE_AAC_MAIN (0x96)
+#define OPENAVB_AEM_MPEG_PROFILE_AAC_LD (0x97)
+#define OPENAVB_AEM_MPEG_PROFILE_AAC_HE (0x98)
+#define OPENAVB_AEM_MPEG_PROFILE_AAC_HE2 (0x99)
+
+// Levels for H.264 Profiles IEEE Std 1722.1-2013 clause 7.3.7.2.2.1
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_1 (0x00)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_1B (0x01)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_1_1 (0x02)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_1_2 (0x03)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_1_3 (0x01)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_2 (0x05)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_2_1 (0x06)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_2_2 (0x07)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_3 (0x08)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_3_1 (0x09)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_3_2 (0x0a)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_4 (0x0b)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_4_1 (0x0c)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_4_2 (0x0d)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_5 (0x0e)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_5_1 (0x0f)
+#define OPENAVB_AEM_PROFILE_LEVEL_H264_5_2 (0x10)
+
+// Levels for MPEG2 Profiles IEEE Std 1722.1-2013 clause 7.3.7.2.2.2
+#define OPENAVB_AEM_PROFILE_LEVEL_MPEG2_LL (0x00)
+#define OPENAVB_AEM_PROFILE_LEVEL_MPEG2_ML (0x01)
+#define OPENAVB_AEM_PROFILE_LEVEL_MPEG2_H_14 (0x02)
+#define OPENAVB_AEM_PROFILE_LEVEL_MPEG2_HL (0x03)
+
+// Audio Profiles MPEG_PES_FORMAT Compressed Audio sample rates IEEE Std 1722.1-2013 clause 7.3.7.2.3
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_SAMPLE_RATE_8K (0x0)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_SAMPLE_RATE_16K (0x1)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_SAMPLE_RATE_22K05 (0x2)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_SAMPLE_RATE_24K (0x3)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_SAMPLE_RATE_32K (0x4)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_SAMPLE_RATE_44K1 (0x5)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_SAMPLE_RATE_48K (0x6)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_SAMPLE_RATE_96K (0x7)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_SAMPLE_RATE_192K (0x8)
+
+// Audio Profiles MPEG_PES_FORMAT Compressed Audio channel options IEEE Std 1722.1-2013 clause 7.3.7.2.3
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_MONO (0x00)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_STEREO (0x01)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_STEREO_JOINED (0x02)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_DUAL_CHANNEL (0x03)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_2_1 (0x04)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_3_0 (0x05)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_3_1 (0x06)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_4_0 (0x07)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_4_1 (0x08)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_5_0 (0x09)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_5_1 (0x0a)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_6_0 (0x0b)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_6_1 (0x0c)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_7_0 (0x0d)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_7_1 (0x0e)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_8_0 (0x0f)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_10_1 (0x10)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_CHANNEL_OPTION_OTHER (0x1f)
+
+// Audio Profiles MPEG_PES_FORMAT Compressed Audio bitrates IEEE Std 1722.1-2013 clause 7.3.7.2.3
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_VARIABLE_BIT_RATE (0x00)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_16_KB_PER_SEC (0x01)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_24_KB_PER_SEC (0x02)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_32_KB_PER_SEC (0x03)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_40_KB_PER_SEC (0x01)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_48_KB_PER_SEC (0x05)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_56_KB_PER_SEC (0x06)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_64_KB_PER_SEC (0x07)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_80_KB_PER_SEC (0x08)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_96_KB_PER_SEC (0x09)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_112_KB_PER_SEC (0x0a)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_128_KB_PER_SEC (0x0b)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_144_KB_PER_SEC (0x0c)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_160_KB_PER_SEC (0x0d)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_192_KB_PER_SEC (0x0e)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_224_KB_PER_SEC (0x0f)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_256_KB_PER_SEC (0x10)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_288_KB_PER_SEC (0x11)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_320_KB_PER_SEC (0x12)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_352_KB_PER_SEC (0x13)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_384_KB_PER_SEC (0x14)
+#define OPENAVB_AEM_MPEG_PES_FORMAT_COMPRESSED_AUDIO_BITRATE_OTHER (0x7f)
+
+// RTP Payload Subtypes IEEE Std 1722.1-2013 clause 7.3.7.4.1
+#define OPENAVB_AEM_RTP_PAYLOAD_SUBTYPE_RTP_MJPEG (0x0000)
+#define OPENAVB_AEM_RTP_PAYLOAD_SUBTYPE_RTP_H264 (0x0001)
+#define OPENAVB_AEM_RTP_PAYLOAD_SUBTYPE_RTP_JPEG200 (0x0002)
+
+// Video Cluster Color Space IEEE Std 1722.1-2013 clause 7.3.10
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_MONO8 (0x0000)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_MONO12_PACKED (0x0001)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_MONO16 (0x0002)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_MONO16_SIGNED (0x0003)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_YUV411_PACKED (0x0004)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_YUV422_PACKED (0x0005)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_YUV444_PACKED (0x0006)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_RGB_PACKED (0x0007)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_RGB16 (0x0008)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_RGB16_SIGNED (0x0009)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERGR8 (0x000a)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERGR12_PACKED (0x000b)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERGR16 (0x000c)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERRG8 (0x000d)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERRG12_PACKED (0x000e)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERRG16 (0x000f)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERGB8 (0x0010)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERGB12_PACKED (0x0011)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERGB16 (0x0012)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERBG8 (0x0013)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERBG12_PACKED (0x0014)
+#define OPENAVB_AEM_VIDEP_CLUSTER_COLOR_SPACE_BAYERBG16 (0x0015)
+
+// Command Codes IEEE Std 1722.1-2013 clause 7.4
+#define OPENAVB_AEM_COMMAND_CODE_ACQUIRE_ENTITY (0x0000)
+#define OPENAVB_AEM_COMMAND_CODE_LOCK_ENTITY (0x0001)
+#define OPENAVB_AEM_COMMAND_CODE_ENTITY_AVAILABLE (0x0002)
+#define OPENAVB_AEM_COMMAND_CODE_CONTROLLER_AVAILABLE (0x0003)
+#define OPENAVB_AEM_COMMAND_CODE_READ_DESCRIPTOR (0x0004)
+#define OPENAVB_AEM_COMMAND_CODE_WRITE_DESCRIPTOR (0x0005)
+#define OPENAVB_AEM_COMMAND_CODE_SET_CONFIGURATION (0x0006)
+#define OPENAVB_AEM_COMMAND_CODE_GET_CONFIGURATION (0x0007)
+#define OPENAVB_AEM_COMMAND_CODE_SET_STREAM_FORMAT (0x0008)
+#define OPENAVB_AEM_COMMAND_CODE_GET_STREAM_FORMAT (0x0009)
+#define OPENAVB_AEM_COMMAND_CODE_SET_VIDEO_FORMAT (0x000a)
+#define OPENAVB_AEM_COMMAND_CODE_GET_VIDEO_FORMAT (0x000b)
+#define OPENAVB_AEM_COMMAND_CODE_SET_SENSOR_FORMAT (0x000c)
+#define OPENAVB_AEM_COMMAND_CODE_GET_SENSOR_FORMAT (0x000d)
+#define OPENAVB_AEM_COMMAND_CODE_SET_STREAM_INFO (0x000e)
+#define OPENAVB_AEM_COMMAND_CODE_GET_STREAM_INFO (0x000f)
+#define OPENAVB_AEM_COMMAND_CODE_SET_NAME (0x0010)
+#define OPENAVB_AEM_COMMAND_CODE_GET_NAME (0x0011)
+#define OPENAVB_AEM_COMMAND_CODE_SET_ASSOCIATION_ID (0x0012)
+#define OPENAVB_AEM_COMMAND_CODE_GET_ASSOCIATION_ID (0x0013)
+#define OPENAVB_AEM_COMMAND_CODE_SET_SAMPLING_RATE (0x0014)
+#define OPENAVB_AEM_COMMAND_CODE_GET_SAMPLING_RATE (0x0015)
+#define OPENAVB_AEM_COMMAND_CODE_SET_CLOCK_SOURCE (0x0016)
+#define OPENAVB_AEM_COMMAND_CODE_GET_CLOCK_SOURCE (0x0017)
+#define OPENAVB_AEM_COMMAND_CODE_SET_CONTROL (0x0018)
+#define OPENAVB_AEM_COMMAND_CODE_GET_CONTROL (0x0019)
+#define OPENAVB_AEM_COMMAND_CODE_INCREMENT_CONTROL (0x001a)
+#define OPENAVB_AEM_COMMAND_CODE_DECREMENT_CONTROL (0x001b)
+#define OPENAVB_AEM_COMMAND_CODE_SET_SIGNAL_SELECTOR (0x001c)
+#define OPENAVB_AEM_COMMAND_CODE_GET_SIGNAL_SELECTOR (0x001d)
+#define OPENAVB_AEM_COMMAND_CODE_SET_MIXER (0x001e)
+#define OPENAVB_AEM_COMMAND_CODE_GET_MIXER (0x001f)
+#define OPENAVB_AEM_COMMAND_CODE_SET_MATRIX (0x0020)
+#define OPENAVB_AEM_COMMAND_CODE_GET_MATRIX (0x0021)
+#define OPENAVB_AEM_COMMAND_CODE_START_STREAMING (0x0022)
+#define OPENAVB_AEM_COMMAND_CODE_STOP_STREAMING (0x0023)
+#define OPENAVB_AEM_COMMAND_CODE_REGISTER_UNSOLICITED_NOTIFICATION (0x0024)
+#define OPENAVB_AEM_COMMAND_CODE_DEREGISTER_UNSOLICITED_NOTIFICATION (0x0025)
+#define OPENAVB_AEM_COMMAND_CODE_IDENTIFY_NOTIFICATION (0x0026)
+#define OPENAVB_AEM_COMMAND_CODE_GET_AVB_INFO (0x0027)
+#define OPENAVB_AEM_COMMAND_CODE_GET_AS_PATH (0x0028)
+#define OPENAVB_AEM_COMMAND_CODE_GET_COUNTERS (0x0029)
+#define OPENAVB_AEM_COMMAND_CODE_REBOOT (0x002a)
+#define OPENAVB_AEM_COMMAND_CODE_GET_AUDIO_MAP (0x002b)
+#define OPENAVB_AEM_COMMAND_CODE_ADD_AUDIO_MAPPINGS (0x002c)
+#define OPENAVB_AEM_COMMAND_CODE_REMOVE_AUDIO_MAPPINGS (0x002d)
+#define OPENAVB_AEM_COMMAND_CODE_GET_VIDEO_MAP (0x002e)
+#define OPENAVB_AEM_COMMAND_CODE_ADD_VIDEO_MAPPINGS (0x002f)
+#define OPENAVB_AEM_COMMAND_CODE_REMOVE_VIDEO_MAPPINGS (0x0030)
+#define OPENAVB_AEM_COMMAND_CODE_GET_SENSOR_MAP (0x0031)
+#define OPENAVB_AEM_COMMAND_CODE_ADD_SENSOR_MAPPINGS (0x0032)
+#define OPENAVB_AEM_COMMAND_CODE_REMOVE_SENSOR_MAPPINGS (0x0033)
+#define OPENAVB_AEM_COMMAND_CODE_START_OPERATION (0x0034)
+#define OPENAVB_AEM_COMMAND_CODE_ABORT_OPERATION (0x0035)
+#define OPENAVB_AEM_COMMAND_CODE_OPERATION_STATUS (0x0036)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_ADD_KEY (0x0037)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_DELETE_KEY (0x0038)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_GET_KEY_LIST (0x0039)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_GET_KEY (0x003a)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_ADD_KEY_TO_CHAIN (0x003b)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_DELETE_KEY_FROM_CHAIN (0x003c)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_GET_KEYCHAIN_LIST (0x003d)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_GET_IDENTITY (0x003e)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_ADD_TOKEN (0x003f)
+#define OPENAVB_AEM_COMMAND_CODE_AUTH_DELETE_TOKEN (0x0040)
+#define OPENAVB_AEM_COMMAND_CODE_AUTHENTICATE (0x0041)
+#define OPENAVB_AEM_COMMAND_CODE_DEAUTHENTICATE (0x0042)
+#define OPENAVB_AEM_COMMAND_CODE_ENABLE_TRANSPORT_SECURITY (0x0043)
+#define OPENAVB_AEM_COMMAND_CODE_DISABLE_TRANSPORT_SECURITY (0x0044)
+#define OPENAVB_AEM_COMMAND_CODE_ENABLE_STREAM_ENCRYPTION (0x0045)
+#define OPENAVB_AEM_COMMAND_CODE_DISABLE_STREAM_ENCRYPTION (0x0046)
+#define OPENAVB_AEM_COMMAND_CODE_SET_MEMORY_OBJECT_LENGTH (0x0047)
+#define OPENAVB_AEM_COMMAND_CODE_GET_MEMORY_OBJECT_LENGTH (0x0048)
+#define OPENAVB_AEM_COMMAND_CODE_SET_STREAM_BACKUP (0x0049)
+#define OPENAVB_AEM_COMMAND_CODE_GET_STREAM_BACKUP (0x004a)
+#define OPENAVB_AEM_COMMAND_CODE_EXPANSION (0x7fff)
+
+// Command Status IEEE Std 1722.1-2013 clause 7.4
+#define OPENAVB_AEM_COMMAND_STATUS_SUCCESS (0)
+#define OPENAVB_AEM_COMMAND_STATUS_NOT_IMPLEMENTED (1)
+#define OPENAVB_AEM_COMMAND_STATUS_NO_SUCH_DESCRIPTOR (2)
+#define OPENAVB_AEM_COMMAND_STATUS_ENTITY_LOCKED (3)
+#define OPENAVB_AEM_COMMAND_STATUS_ENTITY_ACQUIRED (4)
+#define OPENAVB_AEM_COMMAND_STATUS_NOT_AUTHENTICATED (5)
+#define OPENAVB_AEM_COMMAND_STATUS_AUTHENTICATION_DISABLED (6)
+#define OPENAVB_AEM_COMMAND_STATUS_BAD_ARGUMENTS (7)
+#define OPENAVB_AEM_COMMAND_STATUS_NO_RESOURCES (8)
+#define OPENAVB_AEM_COMMAND_STATUS_IN_PROGRESS (9)
+#define OPENAVB_AEM_COMMAND_STATUS_ENTITY_MISBEHAVING (10)
+#define OPENAVB_AEM_COMMAND_STATUS_NOT_SUPPORTED (11)
+#define OPENAVB_AEM_COMMAND_STATUS_STREAM_IS_RUNNING (12)
+
+// ACQUIRE_ENTITY Command Flags IEEE Std 1722.1-2013 clause 7.4.1
+#define OPENAVB_AEM_ACQUIRE_ENTITY_COMMAND_FLAG_PERSISTENT (0x00000001)
+#define OPENAVB_AEM_ACQUIRE_ENTITY_COMMAND_FLAG_RELEASE (0x80000000)
+
+// LOCK ENTITY Command Flags IEEE Std 1722.1-2013 clause 7.4.2
+#define OPENAVB_AEM_LOCK_ENTITY_COMMAND_FLAG_UNLOCK (ox00000001)
+
+// SET_STREAM_INFO Command Flags IEEE Std 1722.1-2013 clause 7.4.15
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_CLASS_B (0x00000001)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_FAST_CONNECT (0x00000002)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_SAVED_STATE (0x00000004)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAMING_WAIT (0x00000008)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_ENCRYPTED_PDU (0x00000010)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_VLAN_ID_VALID (0x02000000)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_CONNECTED (0x04000000)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_MSRP_FAILURE_VALID (0x08000000)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_DEST_MAC_VALID (0x10000000)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_MSRP_ACC_LAT_VALID (0x20000000)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_ID_VALID (0x40000000)
+#define OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_FORMAT_VALID (0x80000000)
+
+// SET_MATRIX Command Direction IEEE Std 1722.1-2013 clause 7.4.33
+#define OPENAVB_AEM_SET_MATRIX_COMMAND_DIRECTION_HORIZONTAL (0)
+#define OPENAVB_AEM_SET_MATRIX_COMMAND_DIRECTION_VERTICAL (1)
+
+// GET_AVB_INFO Command Flags IEEE Std 1722.1-2013 clause 7.4.40
+#define OPENAVB_AEM_GET_AVB_INFO_COMMAND_FLAG_AS_CAPABLE (0x01)
+#define OPENAVB_AEM_GET_AVB_INFO_COMMAND_GPTP_ENABLED (0x02)
+#define OPENAVB_AEM_GET_AVB_INFO_COMMAND_SRP_ENABLED (0x04)
+
+// GET_COUNTERS Command ENTITY Counters IEEE Std 1722.1-2013 clause 7.4.42
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_ENTITY_COUNTER_ENTITY_SPECIFIC_8 (0x01000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_ENTITY_COUNTER_ENTITY_SPECIFIC_7 (0x02000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_ENTITY_COUNTER_ENTITY_SPECIFIC_6 (0x04000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_ENTITY_COUNTER_ENTITY_SPECIFIC_5 (0x08000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_ENTITY_COUNTER_ENTITY_SPECIFIC_4 (0x10000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_ENTITY_COUNTER_ENTITY_SPECIFIC_3 (0x20000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_ENTITY_COUNTER_ENTITY_SPECIFIC_2 (0x40000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_ENTITY_COUNTER_ENTITY_SPECIFIC_1 (0x80000000)
+
+// GET_COUNTERS Command AVB_INTERFACE Counters IEEE Std 1722.1-2013 clause 7.4.42
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_LINK_UP (0x00000001)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_LINK_DOWN (0x00000002)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_FRAMES_TX (0x00000004)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_FRAMES_RX (0x00000008)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_RX_CRC_ERROR (0x00000010)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_GPTP_GM_CHANGED (0x00000020)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_ENTITY_SPECIFIC_8 (0x01000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_ENTITY_SPECIFIC_7 (0x02000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_ENTITY_SPECIFIC_6 (0x04000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_ENTITY_SPECIFIC_5 (0x08000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_ENTITY_SPECIFIC_4 (0x10000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_ENTITY_SPECIFIC_3 (0x20000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_ENTITY_SPECIFIC_2 (0x40000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_AVB_INTERFACE_COUNTER_ENTITY_SPECIFIC_1 (0x80000000)
+
+// GET_COUNTERS Command CLOCK_DOMAIN Counters IEEE Std 1722.1-2013 clause 7.4.42
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_LOCKED (0x00000001)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_UNLOCKED (0x00000002)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_ENTITY_SPECIFIC_1 (0x01000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_ENTITY_SPECIFIC_2 (0x02000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_ENTITY_SPECIFIC_3 (0x04000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_ENTITY_SPECIFIC_4 (0x08000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_ENTITY_SPECIFIC_5 (0x10000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_ENTITY_SPECIFIC_6 (0x20000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_ENTITY_SPECIFIC_7 (0x40000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_CLOCK_DOMAIN_COUNTER_ENTITY_SPECIFIC_8 (0x80000000)
+
+// GET_COUNTERS Command STREAM_INPUT Counters IEEE Std 1722.1-2013 clause 7.4.42
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_MEDIA_LOCKED (0x00000001)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_MEDIA_UNLOCKED (0x00000002)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_STREAM_RESET (0x00000004)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_SEQ_NUM_MISMATCH (0x00000008)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_MEDIA_RESET (0x00000010)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_TIMESTAMP_UNCERTAIN (0x00000020)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_TIMESTAMP_VALID (0x00000040)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_TIMESTAMP_NOT_VALID (0x00000080)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_UNSUPPORTED_FORMAT (0x00000100)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_LATE_TIMESTAMP (0x00000200)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_EARLY_TIMESTAMP (0x00000400)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_FRAMES_RX (0x00000800)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_FRAMES_TX (0x00001000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_ENTITY_SPECIFIC_8 (0x01000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_ENTITY_SPECIFIC_7 (0x02000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_ENTITY_SPECIFIC_6 (0x04000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_ENTITY_SPECIFIC_5 (0x08000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_ENTITY_SPECIFIC_4 (0x10000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_ENTITY_SPECIFIC_3 (0x20000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_ENTITY_SPECIFIC_2 (0x40000000)
+#define OPENAVB_AEM_GET_COUNTERS_COMMAND_STREAM_INPUT_COUNTER_ENTITY_SPECIFIC_1 (0x80000000)
+
+#endif // OPENAVB_AEM_TYPES_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster.c b/lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster.c
new file mode 100644
index 00000000..b3addd1a
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster.c
@@ -0,0 +1,179 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Audio Cluster Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Audio Cluster IEEE Std 1722.1-2013 clause 7.2.16
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_audio_cluster.h"
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorAudioClusterToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_cluster_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AUDIO_CLUSTER_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_audio_cluster_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->object_name);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.index, 0, 2);
+ OCT_D2BHTONS(pDst, pSrc->signal_type);
+ OCT_D2BHTONS(pDst, pSrc->signal_index);
+ OCT_D2BHTONS(pDst, pSrc->signal_output);
+ OCT_D2BHTONL(pDst, pSrc->path_latency);
+ OCT_D2BHTONL(pDst, pSrc->block_latency);
+ OCT_D2BHTONS(pDst, pSrc->channel_count);
+ OCT_D2BHTONB(pDst, pSrc->format);
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorAudioClusterFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_cluster_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AUDIO_CLUSTER_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_audio_cluster_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->object_name, pSrc);
+ BIT_B2DNTOHS(pDst->localized_description.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->localized_description.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DNTOHS(pDst->signal_type, pSrc);
+ OCT_B2DNTOHS(pDst->signal_index, pSrc);
+ OCT_B2DNTOHS(pDst->signal_output, pSrc);
+ OCT_B2DNTOHL(pDst->path_latency, pSrc);
+ OCT_B2DNTOHL(pDst->block_latency, pSrc);
+ OCT_B2DNTOHS(pDst->channel_count, pSrc);
+ OCT_B2DNTOHB(pDst->format, pSrc);
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorAudioClusterUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_cluster_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_audio_cluster_t *openavbAemDescriptorAudioClusterNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_cluster_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_audio_cluster_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = FALSE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorAudioClusterToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorAudioClusterFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorAudioClusterUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_AUDIO_CLUSTER;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster.h b/lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster.h
new file mode 100644
index 00000000..b1a5d9b5
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Audio Cluster Descriptor
+ * MODULE SUMMARY : Interface for the Audio Cluster Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_AUDIO_CLUSTER_H
+#define OPENAVB_DESCRIPTOR_AUDIO_CLUSTER_H 1
+
+#include "openavb_descriptor_audio_cluster_pub.h"
+
+#define OPENAVB_DESCRIPTOR_AUDIO_CLUSTER_BASE_LENGTH (87)
+
+#endif // OPENAVB_DESCRIPTOR_AUDIO_CLUSTER_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster_pub.h
new file mode 100644
index 00000000..4708f030
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_audio_cluster_pub.h
@@ -0,0 +1,65 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Audio Cluster Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Audio Cluster Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_AUDIO_CLUSTER_PUB_H
+#define OPENAVB_DESCRIPTOR_AUDIO_CLUSTER_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+// AUDIO CLUSTER Descriptor IEEE Std 1722.1-2013 clause 7.2.16
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 object_name[OPENAVB_AEM_STRLEN_MAX];
+ openavb_aem_string_ref_t localized_description;
+ U16 signal_type;
+ U16 signal_index;
+ U16 signal_output;
+ U32 path_latency;
+ U32 block_latency;
+ U16 channel_count;
+ U8 format;
+} openavb_aem_descriptor_audio_cluster_t;
+
+openavb_aem_descriptor_audio_cluster_t *openavbAemDescriptorAudioClusterNew(void);
+
+#endif // OPENAVB_DESCRIPTOR_AUDIO_CLUSTER_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_audio_map.c b/lib/avtp_pipeline/aem/openavb_descriptor_audio_map.c
new file mode 100644
index 00000000..514e1909
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_audio_map.c
@@ -0,0 +1,180 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Audio Map Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Audio Map IEEE Std 1722.1-2013 clause 7.2.19
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_audio_map.h"
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorAudioMapToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_map_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AUDIO_MAP_BASE_LENGTH + (pDescriptor->number_of_mappings * OPENAVB_DESCRIPTOR_AUDIO_MAP_AUDIO_MAPPING_FORMAT_LENGTH)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_audio_map_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BHTONS(pDst, pSrc->mappings_offset);
+ OCT_D2BHTONS(pDst, pSrc->number_of_mappings);
+
+ int i1;
+ for (i1 = 0; i1 < pSrc->number_of_mappings; i1++) {
+ OCT_D2BHTONS(pDst, pSrc->mapping_formats[i1].mapping_stream_index);
+ OCT_D2BHTONS(pDst, pSrc->mapping_formats[i1].mapping_stream_channel);
+ OCT_D2BHTONS(pDst, pSrc->mapping_formats[i1].mapping_cluster_offset);
+ OCT_D2BHTONS(pDst, pSrc->mapping_formats[i1].mapping_cluster_channel);
+ }
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorAudioMapFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_map_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AUDIO_MAP_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_audio_map_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DNTOHS(pDst->mappings_offset, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_mappings, pSrc);
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AUDIO_MAP_BASE_LENGTH + (pDescriptor->number_of_mappings * OPENAVB_DESCRIPTOR_AUDIO_MAP_AUDIO_MAPPING_FORMAT_LENGTH)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ int i1;
+ for (i1 = 0; i1 < pDst->number_of_mappings; i1++) {
+ OCT_B2DNTOHS(pDst->mapping_formats[i1].mapping_stream_index, pSrc);
+ OCT_B2DNTOHS(pDst->mapping_formats[i1].mapping_stream_channel, pSrc);
+ OCT_B2DNTOHS(pDst->mapping_formats[i1].mapping_cluster_offset, pSrc);
+ OCT_B2DNTOHS(pDst->mapping_formats[i1].mapping_cluster_channel, pSrc);
+ }
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorAudioMapUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_map_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_audio_map_t *openavbAemDescriptorAudioMapNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_map_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_audio_map_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = FALSE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorAudioMapToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorAudioMapFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorAudioMapUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_AUDIO_MAP;
+ pDescriptor->mappings_offset = OPENAVB_DESCRIPTOR_AUDIO_MAP_BASE_LENGTH;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_audio_map.h b/lib/avtp_pipeline/aem/openavb_descriptor_audio_map.h
new file mode 100644
index 00000000..7eba7ff1
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_audio_map.h
@@ -0,0 +1,47 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Audio Map Descriptor
+ * MODULE SUMMARY : Interface for the Audio Map Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_AUDIO_MAP_H
+#define OPENAVB_DESCRIPTOR_AUDIO_MAP_H 1
+
+#include "openavb_descriptor_audio_map_pub.h"
+
+#define OPENAVB_DESCRIPTOR_AUDIO_MAP_BASE_LENGTH (8)
+#define OPENAVB_DESCRIPTOR_AUDIO_MAP_AUDIO_MAPPING_FORMAT_LENGTH (8)
+
+#endif // OPENAVB_DESCRIPTOR_AUDIO_MAP_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_audio_map_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_audio_map_pub.h
new file mode 100644
index 00000000..902ff71e
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_audio_map_pub.h
@@ -0,0 +1,69 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Audio Map Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Audio Map Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_AUDIO_MAP_PUB_H
+#define OPENAVB_DESCRIPTOR_AUDIO_MAP_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+#define OPENAVB_DESCRIPTOR_AUDIO_MAP_MAX_SAMPLING_RATES (62)
+
+// AUDIO UNIT Descriptor : Audio Mappings Format IEEE Std 1722.1-2013 clause 7.2.19.1
+typedef struct {
+ U16 mapping_stream_index;
+ U16 mapping_stream_channel;
+ U16 mapping_cluster_offset;
+ U16 mapping_cluster_channel;
+} openavb_aem_descriptor_audio_map_audio_mapping_format_t;
+
+// AUDIO MAP Descriptor IEEE Std 1722.1-2013 clause 7.2.19
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U16 mappings_offset;
+ U16 number_of_mappings;
+ openavb_aem_descriptor_audio_map_audio_mapping_format_t mapping_formats[OPENAVB_DESCRIPTOR_AUDIO_MAP_MAX_SAMPLING_RATES];
+} openavb_aem_descriptor_audio_map_t;
+
+openavb_aem_descriptor_audio_map_t *openavbAemDescriptorAudioMapNew();
+
+#endif // OPENAVB_DESCRIPTOR_AUDIO_MAP_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_audio_unit.c b/lib/avtp_pipeline/aem/openavb_descriptor_audio_unit.c
new file mode 100644
index 00000000..0f6fdb4a
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_audio_unit.c
@@ -0,0 +1,297 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Audio Unit Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Audio Unit IEEE Std 1722.1-2013 clause 7.2.3
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_audio_unit.h"
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorAudioUnitToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_unit_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AUDIO_UNIT_BASE_LENGTH + (pDescriptor->sampling_rates_count * OPENAVB_DESCRIPTOR_AUDIO_UNIT_SAMPLING_RATE_LENGTH)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_audio_unit_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->object_name);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.index, 0, 2);
+ OCT_D2BHTONS(pDst, pSrc->clock_domain_index);
+ OCT_D2BHTONS(pDst, pSrc->number_of_stream_input_ports);
+ OCT_D2BHTONS(pDst, pSrc->base_stream_input_port);
+ OCT_D2BHTONS(pDst, pSrc->number_of_stream_output_ports);
+ OCT_D2BHTONS(pDst, pSrc->base_stream_output_port);
+ OCT_D2BHTONS(pDst, pSrc->number_of_external_input_ports);
+ OCT_D2BHTONS(pDst, pSrc->base_external_input_port);
+ OCT_D2BHTONS(pDst, pSrc->number_of_external_output_ports);
+ OCT_D2BHTONS(pDst, pSrc->base_external_output_port);
+ OCT_D2BHTONS(pDst, pSrc->number_of_internal_input_ports);
+ OCT_D2BHTONS(pDst, pSrc->base_internal_input_port);
+ OCT_D2BHTONS(pDst, pSrc->number_of_internal_output_ports);
+ OCT_D2BHTONS(pDst, pSrc->base_internal_output_port);
+ OCT_D2BHTONS(pDst, pSrc->number_of_controls);
+ OCT_D2BHTONS(pDst, pSrc->base_control);
+ OCT_D2BHTONS(pDst, pSrc->number_of_signal_selectors);
+ OCT_D2BHTONS(pDst, pSrc->base_signal_selector);
+ OCT_D2BHTONS(pDst, pSrc->number_of_mixers);
+ OCT_D2BHTONS(pDst, pSrc->base_mixer);
+ OCT_D2BHTONS(pDst, pSrc->number_of_matrices);
+ OCT_D2BHTONS(pDst, pSrc->base_matrix);
+ OCT_D2BHTONS(pDst, pSrc->number_of_splitters);
+ OCT_D2BHTONS(pDst, pSrc->base_splitter);
+ OCT_D2BHTONS(pDst, pSrc->number_of_combiners);
+ OCT_D2BHTONS(pDst, pSrc->base_combiner);
+ OCT_D2BHTONS(pDst, pSrc->number_of_demultiplexers);
+ OCT_D2BHTONS(pDst, pSrc->base_demultiplexer);
+ OCT_D2BHTONS(pDst, pSrc->number_of_multiplexers);
+ OCT_D2BHTONS(pDst, pSrc->base_multiplexer);
+ OCT_D2BHTONS(pDst, pSrc->number_of_transcoders);
+ OCT_D2BHTONS(pDst, pSrc->base_transcoder);
+ OCT_D2BHTONS(pDst, pSrc->number_of_control_blocks);
+ OCT_D2BHTONS(pDst, pSrc->base_control_block);
+ BIT_D2BHTONL(pDst, pSrc->current_sampling_rate.pull, 29, 0);
+ BIT_D2BHTONL(pDst, pSrc->current_sampling_rate.base, 0, 4);
+ OCT_D2BHTONS(pDst, pSrc->sampling_rates_offset);
+ OCT_D2BHTONS(pDst, pSrc->sampling_rates_count);
+
+ int i1;
+ for (i1 = 0; i1 < pSrc->sampling_rates_count; i1++) {
+ BIT_D2BHTONL(pDst, pSrc->sampling_rates[i1].pull, 29, 0);
+ BIT_D2BHTONL(pDst, pSrc->sampling_rates[i1].base, 0, 4);
+ }
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorAudioUnitFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_unit_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AUDIO_UNIT_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_audio_unit_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->object_name, pSrc);
+ BIT_B2DNTOHS(pDst->localized_description.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->localized_description.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DNTOHS(pDst->clock_domain_index, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_stream_input_ports, pSrc);
+ OCT_B2DNTOHS(pDst->base_stream_input_port, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_stream_output_ports, pSrc);
+ OCT_B2DNTOHS(pDst->base_stream_output_port, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_external_input_ports, pSrc);
+ OCT_B2DNTOHS(pDst->base_external_input_port, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_external_output_ports, pSrc);
+ OCT_B2DNTOHS(pDst->base_external_output_port, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_internal_input_ports, pSrc);
+ OCT_B2DNTOHS(pDst->base_internal_input_port, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_internal_output_ports, pSrc);
+ OCT_B2DNTOHS(pDst->base_internal_output_port, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_controls, pSrc);
+ OCT_B2DNTOHS(pDst->base_control, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_signal_selectors, pSrc);
+ OCT_B2DNTOHS(pDst->base_signal_selector, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_mixers, pSrc);
+ OCT_B2DNTOHS(pDst->base_mixer, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_matrices, pSrc);
+ OCT_B2DNTOHS(pDst->base_matrix, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_splitters, pSrc);
+ OCT_B2DNTOHS(pDst->base_splitter, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_combiners, pSrc);
+ OCT_B2DNTOHS(pDst->base_combiner, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_demultiplexers, pSrc);
+ OCT_B2DNTOHS(pDst->base_demultiplexer, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_multiplexers, pSrc);
+ OCT_B2DNTOHS(pDst->base_multiplexer, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_transcoders, pSrc);
+ OCT_B2DNTOHS(pDst->base_transcoder, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_control_blocks, pSrc);
+ OCT_B2DNTOHS(pDst->base_control_block, pSrc);
+ BIT_B2DNTOHL(pDst->current_sampling_rate.pull, pSrc, 0xe0000000, 29, 0);
+ BIT_B2DNTOHL(pDst->current_sampling_rate.base, pSrc, 0x1fffffff, 0, 2);
+ OCT_B2DNTOHS(pDst->sampling_rates_offset, pSrc);
+ OCT_B2DNTOHS(pDst->sampling_rates_count, pSrc);
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AUDIO_UNIT_BASE_LENGTH + (pDescriptor->sampling_rates_count * OPENAVB_DESCRIPTOR_AUDIO_UNIT_SAMPLING_RATE_LENGTH)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ int i1;
+ for (i1 = 0; i1 < pDst->sampling_rates_count; i1++) {
+ BIT_B2DNTOHL(pDst->sampling_rates[i1].pull, pSrc, 0xe0000000, 29, 0);
+ BIT_B2DNTOHL(pDst->sampling_rates[i1].base, pSrc, 0x1fffffff, 0, 2);
+ }
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorAudioUnitUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_unit_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_audio_unit_t *openavbAemDescriptorAudioUnitNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_audio_unit_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_audio_unit_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorAudioUnitToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorAudioUnitFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorAudioUnitUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_AUDIO_UNIT;
+ pDescriptor->sampling_rates_offset = OPENAVB_DESCRIPTOR_AUDIO_UNIT_BASE_LENGTH;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorAudioUnitInitialize(openavb_aem_descriptor_audio_unit_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ (void) nConfigIdx;
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // Specify a name.
+ sprintf((char *)(pDescriptor->object_name), "Audio Unit %u", pDescriptor->descriptor_index);
+
+ // Add the port information.
+ if (pConfig->stream->role == AVB_ROLE_TALKER) {
+ // There will be one stream output port.
+ pDescriptor->number_of_stream_output_ports = 1;
+ pDescriptor->base_stream_output_port = 0;
+ }
+ else if (pConfig->stream->role == AVB_ROLE_LISTENER) {
+ // There will be one stream input port.
+ pDescriptor->number_of_stream_input_ports = 1;
+ pDescriptor->base_stream_input_port = 0;
+ }
+ // AVDECC_TODO - Once implemented, add support for External and Internal ports.
+
+ // AVDECC_TODO - Once implemented, add support for mixers, matrices, splitters, combiners, demultiplexers, multiplexers, transcoders, and control blocks.
+
+ // AVDECC_TODO - Add the sample rate information. Should this be done in openavbAemDescriptorAudioUnitUpdate() instead?
+ // AVDECC_TODO - Merge the configurations instead of overwriting it
+ pDescriptor->current_sampling_rate.pull = 0;
+ pDescriptor->current_sampling_rate.base = pConfig->stream->current_sampling_rate;
+ pDescriptor->sampling_rates_offset = OPENAVB_DESCRIPTOR_AUDIO_UNIT_BASE_LENGTH;
+ pDescriptor->sampling_rates_count = pConfig->stream->sampling_rates_count;
+ int i = 0;
+ while (i < OPENAVB_DESCRIPTOR_AUDIO_UNIT_MAX_SAMPLING_RATES && pConfig->stream->sampling_rates[i] != 0)
+ {
+ pDescriptor->sampling_rates[i].pull = 0;
+ pDescriptor->sampling_rates[i].base = pConfig->stream->sampling_rates[i];
+ i++;
+ }
+
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_audio_unit.h b/lib/avtp_pipeline/aem/openavb_descriptor_audio_unit.h
new file mode 100644
index 00000000..9e999530
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_audio_unit.h
@@ -0,0 +1,47 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Audio Unit Descriptor
+ * MODULE SUMMARY : Interface for the Audio Unit Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_AUDIO_UNIT_H
+#define OPENAVB_DESCRIPTOR_AUDIO_UNIT_H 1
+
+#include "openavb_descriptor_audio_unit_pub.h"
+
+#define OPENAVB_DESCRIPTOR_AUDIO_UNIT_BASE_LENGTH (144)
+#define OPENAVB_DESCRIPTOR_AUDIO_UNIT_SAMPLING_RATE_LENGTH (4)
+
+#endif // OPENAVB_DESCRIPTOR_AUDIO_UNIT_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_audio_unit_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_audio_unit_pub.h
new file mode 100644
index 00000000..6b368728
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_audio_unit_pub.h
@@ -0,0 +1,99 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Audio Unit Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Audio Unit Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_AUDIO_UNIT_PUB_H
+#define OPENAVB_DESCRIPTOR_AUDIO_UNIT_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+#define OPENAVB_DESCRIPTOR_AUDIO_UNIT_MAX_SAMPLING_RATES (91)
+
+// AUDIO UNIT Descriptor IEEE Std 1722.1-2013 clause 7.2.3
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 object_name[OPENAVB_AEM_STRLEN_MAX];
+ openavb_aem_string_ref_t localized_description;
+ U16 clock_domain_index;
+ U16 number_of_stream_input_ports;
+ U16 base_stream_input_port;
+ U16 number_of_stream_output_ports;
+ U16 base_stream_output_port;
+ U16 number_of_external_input_ports;
+ U16 base_external_input_port;
+ U16 number_of_external_output_ports;
+ U16 base_external_output_port;
+ U16 number_of_internal_input_ports;
+ U16 base_internal_input_port;
+ U16 number_of_internal_output_ports;
+ U16 base_internal_output_port;
+ U16 number_of_controls;
+ U16 base_control;
+ U16 number_of_signal_selectors;
+ U16 base_signal_selector;
+ U16 number_of_mixers;
+ U16 base_mixer;
+ U16 number_of_matrices;
+ U16 base_matrix;
+ U16 number_of_splitters;
+ U16 base_splitter;
+ U16 number_of_combiners;
+ U16 base_combiner;
+ U16 number_of_demultiplexers;
+ U16 base_demultiplexer;
+ U16 number_of_multiplexers;
+ U16 base_multiplexer;
+ U16 number_of_transcoders;
+ U16 base_transcoder;
+ U16 number_of_control_blocks;
+ U16 base_control_block;
+ openavb_aem_sampling_rate_t current_sampling_rate;
+ U16 sampling_rates_offset;
+ U16 sampling_rates_count;
+ openavb_aem_sampling_rate_t sampling_rates[OPENAVB_DESCRIPTOR_AUDIO_UNIT_MAX_SAMPLING_RATES];
+} openavb_aem_descriptor_audio_unit_t;
+
+openavb_aem_descriptor_audio_unit_t *openavbAemDescriptorAudioUnitNew(void);
+
+bool openavbAemDescriptorAudioUnitInitialize(openavb_aem_descriptor_audio_unit_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+
+#endif // OPENAVB_DESCRIPTOR_AUDIO_UNIT_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_avb_interface.c b/lib/avtp_pipeline/aem/openavb_descriptor_avb_interface.c
new file mode 100644
index 00000000..366f11e4
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_avb_interface.c
@@ -0,0 +1,244 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC AVB Interface Descriptor
+ * MODULE SUMMARY : Implements the AVDECC AVB Interface IEEE Std 1722.1-2013 clause 7.2.8
+ ******************************************************************
+ */
+
+#include "openavb_platform.h"
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_avb_interface.h"
+
+#ifndef AVB_PTP_AVAILABLE
+#include "openavb_grandmaster_osal_pub.h"
+#endif // !AVB_PTP_AVAILABLE
+
+extern openavb_avdecc_cfg_t gAvdeccCfg;
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorAvbInterfaceToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_avb_interface_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AVB_INTERFACE_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_avb_interface_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->object_name);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.index, 0, 2);
+ OCT_D2BMEMCP(pDst, pSrc->mac_address);
+ OCT_D2BHTONS(pDst, pSrc->interface_flags);
+ OCT_D2BMEMCP(pDst, pSrc->clock_identity);
+ OCT_D2BHTONB(pDst, pSrc->priority1);
+ OCT_D2BHTONB(pDst, pSrc->clock_class);
+ OCT_D2BHTONS(pDst, pSrc->offset_scaled_log_variance);
+ OCT_D2BHTONB(pDst, pSrc->clock_accuracy);
+ OCT_D2BHTONB(pDst, pSrc->priority2);
+ OCT_D2BHTONB(pDst, pSrc->domain_number);
+ OCT_D2BHTONB(pDst, pSrc->log_sync_interval);
+ OCT_D2BHTONB(pDst, pSrc->log_announce_interval);
+ OCT_D2BHTONB(pDst, pSrc->log_pdelay_interval);
+ OCT_D2BHTONS(pDst, pSrc->port_number);
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorAvbInterfaceFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_avb_interface_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_AVB_INTERFACE_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_avb_interface_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->object_name, pSrc);
+ BIT_B2DNTOHS(pDst->localized_description.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->localized_description.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DMEMCP(pDst->mac_address, pSrc);
+ OCT_B2DNTOHS(pDst->interface_flags, pSrc);
+ OCT_B2DMEMCP(pDst->clock_identity, pSrc);
+ OCT_B2DNTOHB(pDst->priority1, pSrc);
+ OCT_B2DNTOHB(pDst->clock_class, pSrc);
+ OCT_B2DNTOHS(pDst->offset_scaled_log_variance, pSrc);
+ OCT_B2DNTOHB(pDst->clock_accuracy, pSrc);
+ OCT_B2DNTOHB(pDst->priority2, pSrc);
+ OCT_B2DNTOHB(pDst->domain_number, pSrc);
+ OCT_B2DNTOHB(pDst->log_sync_interval, pSrc);
+ OCT_B2DNTOHB(pDst->log_announce_interval, pSrc);
+ OCT_B2DNTOHB(pDst->log_pdelay_interval, pSrc);
+ OCT_B2DNTOHS(pDst->port_number, pSrc);
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorAvbInterfaceUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_avb_interface_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // Make the Clock Identity the same as the Entity Id.
+ // Just use the first entity descriptor from the first configuration, as they should all be the same.
+ openavb_aem_descriptor_entity_t *pEntityDescriptor =
+ (openavb_aem_descriptor_entity_t *) openavbAemGetDescriptor(0, OPENAVB_AEM_DESCRIPTOR_ENTITY, 0);
+ if (pEntityDescriptor) {
+ memcpy(pDescriptor->clock_identity, pEntityDescriptor->entity_id, sizeof(pDescriptor->clock_identity));
+ }
+
+#ifndef AVB_PTP_AVAILABLE
+ // Get the current grandmaster information.
+ if (!osalClockGrandmasterGetInterface(
+ pDescriptor->clock_identity,
+ &pDescriptor->priority1,
+ &pDescriptor->clock_class,
+ &pDescriptor->offset_scaled_log_variance,
+ &pDescriptor->clock_accuracy,
+ &pDescriptor->priority2,
+ &pDescriptor->domain_number,
+ &pDescriptor->log_sync_interval,
+ &pDescriptor->log_announce_interval,
+ &pDescriptor->log_pdelay_interval,
+ &pDescriptor->port_number))
+ {
+ AVB_LOG_ERROR("osalClockGrandmasterGetInterface failure");
+ }
+#endif // !AVB_PTP_AVAILABLE
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_avb_interface_t *openavbAemDescriptorAvbInterfaceNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_avb_interface_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_avb_interface_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorAvbInterfaceToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorAvbInterfaceFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorAvbInterfaceUpdate;
+
+ strncpy((char *) pDescriptor->object_name, gAvdeccCfg.ifname, sizeof(pDescriptor->object_name));
+ memcpy(pDescriptor->mac_address, gAvdeccCfg.ifmac, sizeof(pDescriptor->mac_address));
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_AVB_INTERFACE;
+
+ // Default to supporting all the interfaces.
+ pDescriptor->interface_flags =
+ OPENAVB_AEM_INTERFACE_TYPE_GPTP_GRANDMASTER_SUPPORTED |
+ OPENAVB_AEM_INTERFACE_TYPE_GPTP_SUPPORTED |
+ OPENAVB_AEM_INTERFACE_TYPE_SRP_SUPPORTED;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorAvbInterfaceInitialize(openavb_aem_descriptor_avb_interface_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ (void) nConfigIdx;
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_avb_interface.h b/lib/avtp_pipeline/aem/openavb_descriptor_avb_interface.h
new file mode 100644
index 00000000..093656c7
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_avb_interface.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC AVB Interface Descriptor
+ * MODULE SUMMARY : Interface for the AVB Interface Desciptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_AVB_INTERFACE_H
+#define OPENAVB_DESCRIPTOR_AVB_INTERFACE_H 1
+
+#include "openavb_descriptor_avb_interface_pub.h"
+
+#define OPENAVB_DESCRIPTOR_AVB_INTERFACE_BASE_LENGTH (98)
+
+#endif // OPENAVB_DESCRIPTOR_AVB_INTERFACE_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_avb_interface_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_avb_interface_pub.h
new file mode 100644
index 00000000..c2c17fed
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_avb_interface_pub.h
@@ -0,0 +1,73 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC AVB Interface Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the AVB Interface Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_AVB_INTERFACE_PUB_H
+#define OPENAVB_DESCRIPTOR_AVB_INTERFACE_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+// AVB INTERFACE Descriptor IEEE Std 1722.1-2013 clause 7.2.8
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 object_name[OPENAVB_AEM_STRLEN_MAX]; // Set internally
+ openavb_aem_string_ref_t localized_description;
+ U8 mac_address[6]; // Set internally
+ U16 interface_flags;
+ U8 clock_identity[8];
+ U8 priority1;
+ U8 clock_class;
+ S16 offset_scaled_log_variance;
+ U8 clock_accuracy;
+ U8 priority2;
+ U8 domain_number;
+ S8 log_sync_interval;
+ S8 log_announce_interval;
+ S8 log_pdelay_interval;
+ U16 port_number;
+} openavb_aem_descriptor_avb_interface_t;
+
+openavb_aem_descriptor_avb_interface_t *openavbAemDescriptorAvbInterfaceNew(void);
+
+bool openavbAemDescriptorAvbInterfaceInitialize(openavb_aem_descriptor_avb_interface_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+
+#endif // OPENAVB_DESCRIPTOR_AVB_INTERFACE_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_clock_domain.c b/lib/avtp_pipeline/aem/openavb_descriptor_clock_domain.c
new file mode 100644
index 00000000..7f0e4018
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_clock_domain.c
@@ -0,0 +1,209 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Clock Domain Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Clock Domain IEEE Std 1722.1-2013 clause 7.2.32
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_clock_domain.h"
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorClockDomainToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_clock_domain_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_BASE_LENGTH + (pDescriptor->clock_sources_count * OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_CLOCK_SOURCE_LENGTH)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_clock_domain_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->object_name);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.index, 0, 2);
+ OCT_D2BHTONS(pDst, pSrc->clock_source_index);
+ OCT_D2BHTONS(pDst, pSrc->clock_sources_offset);
+ OCT_D2BHTONS(pDst, pSrc->clock_sources_count);
+
+ int i1;
+ for (i1 = 0; i1 < pSrc->clock_sources_count; i1++) {
+ OCT_D2BHTONS(pDst, pSrc->clock_sources[i1]);
+ }
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorClockDomainFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_clock_domain_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_clock_domain_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->object_name, pSrc);
+ BIT_B2DNTOHS(pDst->localized_description.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->localized_description.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DNTOHS(pDst->clock_source_index, pSrc);
+ OCT_B2DNTOHS(pDst->clock_sources_offset, pSrc);
+ OCT_B2DNTOHS(pDst->clock_sources_count, pSrc);
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_BASE_LENGTH + (pDescriptor->clock_sources_count * OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_CLOCK_SOURCE_LENGTH)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ int i1;
+ for (i1 = 0; i1 < pDst->clock_sources_count; i1++) {
+ OCT_B2DNTOHS(pDst->clock_sources[i1], pSrc);
+ }
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorClockDomainUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_clock_domain_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_clock_domain_t *openavbAemDescriptorClockDomainNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_clock_domain_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_clock_domain_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorClockDomainToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorClockDomainFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorClockDomainUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_CLOCK_DOMAIN;
+ pDescriptor->clock_sources_offset = OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_BASE_LENGTH;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorClockDomainInitialize(openavb_aem_descriptor_clock_domain_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ int i;
+ openavb_aem_descriptor_clock_source_t *pClockSourceDescriptor;
+
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // Specify a name.
+ strcpy((char *)(pDescriptor->object_name), "Clock Domain");
+
+ // Add all the current clocks for this configuration to this domain.
+ for (i = 0; i < OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_MAX_CLOCK_SOURCES; ++i) {
+ pClockSourceDescriptor =
+ (openavb_aem_descriptor_clock_source_t *) openavbAemGetDescriptor(nConfigIdx, OPENAVB_AEM_DESCRIPTOR_CLOCK_SOURCE, i);
+ if (pClockSourceDescriptor == NULL) { break; }
+ pDescriptor->clock_sources[i] = pClockSourceDescriptor->descriptor_index;
+ pDescriptor->clock_sources_count = i + 1;
+ }
+
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_clock_domain.h b/lib/avtp_pipeline/aem/openavb_descriptor_clock_domain.h
new file mode 100644
index 00000000..7d30bd42
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_clock_domain.h
@@ -0,0 +1,47 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Clock Domain Descriptor
+ * MODULE SUMMARY : Interface for the Clock Domain Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_H
+#define OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_H 1
+
+#include "openavb_descriptor_clock_domain_pub.h"
+
+#define OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_BASE_LENGTH (76)
+#define OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_CLOCK_SOURCE_LENGTH (2)
+
+#endif // OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_clock_domain_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_clock_domain_pub.h
new file mode 100644
index 00000000..6458a41d
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_clock_domain_pub.h
@@ -0,0 +1,66 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Clock Domain Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Clock Domain Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_PUB_H
+#define OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+#define OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_MAX_CLOCK_SOURCES (249)
+
+// CLOCK DOMAIN Descriptor IEEE Std 1722.1-2013 clause 7.2.32
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 object_name[OPENAVB_AEM_STRLEN_MAX];
+ openavb_aem_string_ref_t localized_description;
+ U16 clock_source_index;
+ U16 clock_sources_offset;
+ U16 clock_sources_count;
+ U16 clock_sources[OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_MAX_CLOCK_SOURCES];
+} openavb_aem_descriptor_clock_domain_t;
+
+openavb_aem_descriptor_clock_domain_t *openavbAemDescriptorClockDomainNew(void);
+
+bool openavbAemDescriptorClockDomainInitialize(openavb_aem_descriptor_clock_domain_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+
+#endif // OPENAVB_DESCRIPTOR_CLOCK_DOMAIN_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_clock_source.c b/lib/avtp_pipeline/aem/openavb_descriptor_clock_source.c
new file mode 100644
index 00000000..3246607a
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_clock_source.c
@@ -0,0 +1,205 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Clock Source Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Clock Source IEEE Std 1722.1-2013 clause 7.2.9
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_clock_source.h"
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorClockSourceToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_clock_source_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CLOCK_SOURCE_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_clock_source_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->object_name);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.index, 0, 2);
+ OCT_D2BHTONS(pDst, pSrc->clock_source_flags);
+ OCT_D2BHTONS(pDst, pSrc->clock_source_type);
+ OCT_D2BMEMCP(pDst, pSrc->clock_source_identifier);
+ OCT_D2BHTONS(pDst, pSrc->clock_source_location_type);
+ OCT_D2BHTONS(pDst, pSrc->clock_source_location_index);
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorClockSourceFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_clock_source_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CLOCK_SOURCE_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_clock_source_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->object_name, pSrc);
+ BIT_B2DNTOHS(pDst->localized_description.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->localized_description.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DNTOHS(pDst->clock_source_flags, pSrc);
+ OCT_B2DNTOHS(pDst->clock_source_type, pSrc);
+ OCT_B2DMEMCP(pDst->clock_source_identifier, pSrc);
+ OCT_B2DNTOHS(pDst->clock_source_location_type, pSrc);
+ OCT_B2DNTOHS(pDst->clock_source_location_index, pSrc);
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorClockSourceUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_clock_source_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_clock_source_t *openavbAemDescriptorClockSourceNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_clock_source_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_clock_source_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorClockSourceToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorClockSourceFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorClockSourceUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_CLOCK_SOURCE;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorClockSourceInitialize(openavb_aem_descriptor_clock_source_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ (void) nConfigIdx;
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO: These values need to be verified.
+ if (pConfig->stream->role == AVB_ROLE_TALKER)
+ {
+ // Make this an internal clock.
+ strcpy((char *) pDescriptor->object_name, "Internal Clock");
+ pDescriptor->clock_source_flags = 0;
+ pDescriptor->clock_source_type = OPENAVB_AEM_CLOCK_SOURCE_TYPE_INTERNAL;
+ pDescriptor->clock_source_location_type = OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT;
+ pDescriptor->clock_source_location_index = 0;
+ }
+ else if (pConfig->stream->role == AVB_ROLE_LISTENER)
+ {
+ // Use the Talker's clock.
+ strcpy((char *) pDescriptor->object_name, "Input Stream");
+ pDescriptor->clock_source_flags = OPENAVB_AEM_CLOCK_SOURCE_FLAG_STREAM_ID;
+ pDescriptor->clock_source_type = OPENAVB_AEM_CLOCK_SOURCE_TYPE_INPUT_STREAM;
+ memcpy(pDescriptor->clock_source_identifier, pConfig->stream->stream_addr.buffer.ether_addr_octet, ETH_ALEN);
+ pDescriptor->clock_source_location_type = OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT;
+ pDescriptor->clock_source_location_index = 0;
+ }
+
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_clock_source.h b/lib/avtp_pipeline/aem/openavb_descriptor_clock_source.h
new file mode 100644
index 00000000..29f9dd13
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_clock_source.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Clock Source Descriptor
+ * MODULE SUMMARY : Interface for the Clock Source Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_CLOCK_SOURCE_H
+#define OPENAVB_DESCRIPTOR_CLOCK_SOURCE_H 1
+
+#include "openavb_descriptor_clock_source_pub.h"
+
+#define OPENAVB_DESCRIPTOR_CLOCK_SOURCE_BASE_LENGTH (86)
+
+#endif // OPENAVB_DESCRIPTOR_CLOCK_SOURCE_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_clock_source_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_clock_source_pub.h
new file mode 100644
index 00000000..10b2b723
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_clock_source_pub.h
@@ -0,0 +1,65 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Clock Source Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Clock Source Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_CLOCK_SOURCE_PUB_H
+#define OPENAVB_DESCRIPTOR_CLOCK_SOURCE_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+// CLOCK SOURCE Descriptor IEEE Std 1722.1-2013 clause 7.2.9
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 object_name[OPENAVB_AEM_STRLEN_MAX];
+ openavb_aem_string_ref_t localized_description;
+ U16 clock_source_flags;
+ U16 clock_source_type;
+ U8 clock_source_identifier[8];
+ U16 clock_source_location_type;
+ U16 clock_source_location_index;
+} openavb_aem_descriptor_clock_source_t;
+
+openavb_aem_descriptor_clock_source_t *openavbAemDescriptorClockSourceNew(void);
+
+bool openavbAemDescriptorClockSourceInitialize(openavb_aem_descriptor_clock_source_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+
+#endif // OPENAVB_DESCRIPTOR_CLOCK_SOURCE_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_configuration.c b/lib/avtp_pipeline/aem/openavb_descriptor_configuration.c
new file mode 100644
index 00000000..aaa442fa
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_configuration.c
@@ -0,0 +1,197 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Configuration Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Configuration Descriptor IEEE Std 1722.1-2013 clause 7.2.1
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_configuration.h"
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorConfigurationToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_configuration_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CONFIGURATION_BASE_LENGTH + (pDescriptor->descriptor_counts_count * sizeof(*pDescriptor->descriptor_counts))) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_configuration_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->object_name);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.index, 0, 2);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_counts_count);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_counts_offset);
+
+ int i1;
+ for (i1 = 0; i1 < pSrc->descriptor_counts_count; i1++) {
+ OCT_D2BHTONS(pDst, pSrc->descriptor_counts[i1].descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_counts[i1].count);
+ }
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorConfigurationFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_configuration_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CONFIGURATION_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_configuration_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->object_name, pSrc);
+ BIT_B2DNTOHS(pDst->localized_description.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->localized_description.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DNTOHS(pDst->descriptor_counts_count, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_counts_offset, pSrc);
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CONFIGURATION_BASE_LENGTH + (pDescriptor->descriptor_counts_count * sizeof(*pDescriptor->descriptor_counts))) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ int i1;
+ for (i1 = 0; i1 < pDst->descriptor_counts_count; i1++) {
+ OCT_B2DNTOHS(pDst->descriptor_counts[i1].descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_counts[i1].count, pSrc);
+ }
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorConfigurationUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_configuration_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_configuration_t *openavbAemDescriptorConfigurationNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_configuration_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_configuration_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorConfigurationToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorConfigurationFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorConfigurationUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_CONFIGURATION;
+ pDescriptor->descriptor_counts_offset = OPENAVB_DESCRIPTOR_CONFIGURATION_BASE_LENGTH;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorConfigurationInitialize(openavb_aem_descriptor_configuration_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ (void) nConfigIdx;
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ openavbAemSetString(pDescriptor->object_name, pConfig->friendly_name);
+
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_configuration.h b/lib/avtp_pipeline/aem/openavb_descriptor_configuration.h
new file mode 100644
index 00000000..1b804c4f
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_configuration.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Configuration Descriptor
+ * MODULE SUMMARY : Interface for the Configuration Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_CONFIGURATION_H
+#define OPENAVB_DESCRIPTOR_CONFIGURATION_H 1
+
+#include "openavb_descriptor_configuration_pub.h"
+
+#define OPENAVB_DESCRIPTOR_CONFIGURATION_BASE_LENGTH (74)
+
+#endif // OPENAVB_DESCRIPTOR_CONFIGURATION_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_configuration_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_configuration_pub.h
new file mode 100644
index 00000000..2b6c71ff
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_configuration_pub.h
@@ -0,0 +1,70 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Entity Model : Configuration Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Configuration Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_CONFIGURATION_PUB_H
+#define OPENAVB_DESCRIPTOR_CONFIGURATION_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+#define OPENAVB_DESCRIPTOR_CONFIGURATION_MAX_DESCRIPTOR_COUNTS (108)
+
+// CONFIGURATION Descriptor IEEE Std 1722.1-2013 clause 7.2.2
+typedef struct {
+ U16 descriptor_type;
+ U16 count;
+} openavb_aem_descriptor_configuration_descriptor_counts_t;
+
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 object_name[OPENAVB_AEM_STRLEN_MAX];
+ openavb_aem_string_ref_t localized_description;
+ U16 descriptor_counts_count; // Set internally
+ U16 descriptor_counts_offset; // Set internally
+ openavb_aem_descriptor_configuration_descriptor_counts_t descriptor_counts[OPENAVB_DESCRIPTOR_CONFIGURATION_MAX_DESCRIPTOR_COUNTS]; // Set internally
+} openavb_aem_descriptor_configuration_t;
+
+openavb_aem_descriptor_configuration_t *openavbAemDescriptorConfigurationNew(void);
+
+bool openavbAemDescriptorConfigurationInitialize(openavb_aem_descriptor_configuration_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+
+#endif // OPENAVB_DESCRIPTOR_CONFIGURATION_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_control.c b/lib/avtp_pipeline/aem/openavb_descriptor_control.c
new file mode 100644
index 00000000..a432fe4c
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_control.c
@@ -0,0 +1,502 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Control Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Control IEEE Std 1722.1-2013 clause 7.2.32
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_control.h"
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorControlToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_control_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CONTROL_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_control_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->object_name);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.index, 0, 2);
+ OCT_D2BHTONL(pDst, pSrc->block_latency);
+ OCT_D2BHTONL(pDst, pSrc->control_latency);
+ OCT_D2BHTONS(pDst, pSrc->control_domain);
+ OCT_D2BHTONS(pDst, pSrc->control_value_type);
+ OCT_D2BMEMCP(pDst, &pSrc->control_type);
+ OCT_D2BHTONL(pDst, pSrc->reset_time);
+ OCT_D2BHTONS(pDst, pSrc->values_offset);
+ OCT_D2BHTONS(pDst, pSrc->number_of_values);
+ OCT_D2BHTONS(pDst, pSrc->signal_type);
+ OCT_D2BHTONS(pDst, pSrc->signal_index);
+ OCT_D2BHTONS(pDst, pSrc->signal_output);
+
+ int i1;
+ for (i1 = 0; i1 < pSrc->number_of_values; i1++) {
+ switch (pSrc->control_value_type) {
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT8:
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT8:
+ OCT_D2BHTONB(pDst, pSrc->value_details.linear_int8[i1].minimum);
+ OCT_D2BHTONB(pDst, pSrc->value_details.linear_int8[i1].maximum);
+ OCT_D2BHTONB(pDst, pSrc->value_details.linear_int8[i1].step);
+ OCT_D2BHTONB(pDst, pSrc->value_details.linear_int8[i1].default_value);
+ OCT_D2BHTONB(pDst, pSrc->value_details.linear_int8[i1].current);
+ OCT_D2BHTONS(pDst, pSrc->value_details.linear_int8[i1].unit);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_int8[i1].string.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_int8[i1].string.index, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT16:
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT16:
+ OCT_D2BHTONS(pDst, pSrc->value_details.linear_int16[i1].minimum);
+ OCT_D2BHTONS(pDst, pSrc->value_details.linear_int16[i1].maximum);
+ OCT_D2BHTONS(pDst, pSrc->value_details.linear_int16[i1].step);
+ OCT_D2BHTONS(pDst, pSrc->value_details.linear_int16[i1].default_value);
+ OCT_D2BHTONS(pDst, pSrc->value_details.linear_int16[i1].current);
+ OCT_D2BHTONS(pDst, pSrc->value_details.linear_int16[i1].unit);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_int16[i1].string.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_int16[i1].string.index, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT32:
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT32:
+ OCT_D2BHTONL(pDst, pSrc->value_details.linear_int32[i1].minimum);
+ OCT_D2BHTONL(pDst, pSrc->value_details.linear_int32[i1].maximum);
+ OCT_D2BHTONL(pDst, pSrc->value_details.linear_int32[i1].step);
+ OCT_D2BHTONL(pDst, pSrc->value_details.linear_int32[i1].default_value);
+ OCT_D2BHTONL(pDst, pSrc->value_details.linear_int32[i1].current);
+ OCT_D2BHTONL(pDst, pSrc->value_details.linear_int32[i1].unit);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_int32[i1].string.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_int32[i1].string.index, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT64:
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT64:
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_int64[i1].minimum);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_int64[i1].maximum);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_int64[i1].step);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_int64[i1].default_value);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_int64[i1].current);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_int64[i1].unit);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_int64[i1].string.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_int64[i1].string.index, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_FLOAT:
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_float[i1].minimum);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_float[i1].maximum);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_float[i1].step);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_float[i1].default_value);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_float[i1].current);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_float[i1].unit);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_float[i1].string.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_float[i1].string.index, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_DOUBLE:
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_double[i1].minimum);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_double[i1].maximum);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_double[i1].step);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_double[i1].default_value);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_double[i1].current);
+ OCT_D2BMEMCP(pDst, &pSrc->value_details.linear_double[i1].unit);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_double[i1].string.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->value_details.linear_double[i1].string.index, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT16:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT16:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT32:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT32:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT64:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT64:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_FLOAT:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_DOUBLE:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_STRING:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT16:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT16:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT32:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT32:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT64:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT64:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_FLOAT:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_DOUBLE:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_UTF8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_BODE_PLOT:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SMPTE_TIME:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SAMPLE_RATE:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_GPTP_TIME:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_VENDOR:
+ // AVDECC_TODO
+ break;
+ }
+ }
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorControlFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_control_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_CONTROL_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_control_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->object_name, pSrc);
+ BIT_B2DNTOHS(pDst->localized_description.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->localized_description.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DNTOHL(pDst->block_latency, pSrc);
+ OCT_B2DNTOHL(pDst->control_latency, pSrc);
+ OCT_B2DNTOHS(pDst->control_domain, pSrc);
+ OCT_B2DNTOHS(pDst->control_value_type, pSrc);
+ OCT_B2DMEMCP(&pDst->control_type, pSrc);
+ OCT_B2DNTOHL(pDst->reset_time, pSrc);
+ OCT_B2DNTOHS(pDst->values_offset, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_values, pSrc);
+ OCT_B2DNTOHS(pDst->signal_type, pSrc);
+ OCT_B2DNTOHS(pDst->signal_index, pSrc);
+ OCT_B2DNTOHS(pDst->signal_output, pSrc);
+
+
+ int i1;
+ for (i1 = 0; i1 < pDst->number_of_values; i1++) {
+ switch (pDst->control_value_type) {
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT8:
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT8:
+ OCT_B2DNTOHB(pDst->value_details.linear_int8[i1].minimum, pSrc);
+ OCT_B2DNTOHB(pDst->value_details.linear_int8[i1].maximum, pSrc);
+ OCT_B2DNTOHB(pDst->value_details.linear_int8[i1].step, pSrc);
+ OCT_B2DNTOHB(pDst->value_details.linear_int8[i1].default_value, pSrc);
+ OCT_B2DNTOHB(pDst->value_details.linear_int8[i1].current, pSrc);
+ OCT_B2DNTOHB(pDst->value_details.linear_int8[i1].unit, pSrc);
+ BIT_B2DNTOHS(pDst->value_details.linear_int8[i1].string.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->value_details.linear_int8[i1].string.index, pSrc, 0x0007, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT16:
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT16:
+ OCT_B2DNTOHS(pDst->value_details.linear_int16[i1].minimum, pSrc);
+ OCT_B2DNTOHS(pDst->value_details.linear_int16[i1].maximum, pSrc);
+ OCT_B2DNTOHS(pDst->value_details.linear_int16[i1].step, pSrc);
+ OCT_B2DNTOHS(pDst->value_details.linear_int16[i1].default_value, pSrc);
+ OCT_B2DNTOHS(pDst->value_details.linear_int16[i1].current, pSrc);
+ OCT_B2DNTOHS(pDst->value_details.linear_int16[i1].unit, pSrc);
+ BIT_B2DNTOHS(pDst->value_details.linear_int16[i1].string.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->value_details.linear_int16[i1].string.index, pSrc, 0x0007, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT32:
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT32:
+ OCT_B2DNTOHL(pDst->value_details.linear_int32[i1].minimum, pSrc);
+ OCT_B2DNTOHL(pDst->value_details.linear_int32[i1].maximum, pSrc);
+ OCT_B2DNTOHL(pDst->value_details.linear_int32[i1].step, pSrc);
+ OCT_B2DNTOHL(pDst->value_details.linear_int32[i1].default_value, pSrc);
+ OCT_B2DNTOHL(pDst->value_details.linear_int32[i1].current, pSrc);
+ OCT_B2DNTOHL(pDst->value_details.linear_int32[i1].unit, pSrc);
+ BIT_B2DNTOHS(pDst->value_details.linear_int32[i1].string.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->value_details.linear_int32[i1].string.index, pSrc, 0x0007, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_INT64:
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_UINT64:
+ OCT_B2DMEMCP(&pDst->value_details.linear_int64[i1].minimum, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_int64[i1].maximum, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_int64[i1].step, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_int64[i1].default_value, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_int64[i1].current, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_int64[i1].unit, pSrc);
+ BIT_B2DNTOHS(pDst->value_details.linear_int64[i1].string.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->value_details.linear_int64[i1].string.index, pSrc, 0x0007, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_FLOAT:
+ OCT_B2DMEMCP(&pDst->value_details.linear_float[i1].minimum, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_float[i1].maximum, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_float[i1].step, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_float[i1].default_value, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_float[i1].current, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_float[i1].unit, pSrc);
+ BIT_B2DNTOHS(pDst->value_details.linear_float[i1].string.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->value_details.linear_float[i1].string.index, pSrc, 0x0007, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_LINEAR_DOUBLE:
+ OCT_B2DMEMCP(&pDst->value_details.linear_double[i1].minimum, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_double[i1].maximum, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_double[i1].step, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_double[i1].default_value, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_double[i1].current, pSrc);
+ OCT_B2DMEMCP(&pDst->value_details.linear_double[i1].unit, pSrc);
+ BIT_B2DNTOHS(pDst->value_details.linear_double[i1].string.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->value_details.linear_double[i1].string.index, pSrc, 0x0007, 0, 2);
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT16:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT16:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT32:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT32:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_INT64:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_UINT64:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_FLOAT:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_DOUBLE:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SELECTOR_STRING:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT16:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT16:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT32:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT32:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_INT64:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_UINT64:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_FLOAT:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_ARRAY_DOUBLE:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_UTF8:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_BODE_PLOT:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SMPTE_TIME:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_SAMPLE_RATE:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_GPTP_TIME:
+ // AVDECC_TODO
+ break;
+ case OPENAVB_AEM_CONTROL_VALUE_TYPE_CONTROL_VENDOR:
+ // AVDECC_TODO
+ break;
+ }
+ }
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorControlUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_control_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_control_t *openavbAemDescriptorControlNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_control_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_control_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorControlToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorControlFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorControlUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_CONTROL;
+ pDescriptor->values_offset = OPENAVB_DESCRIPTOR_CONTROL_BASE_LENGTH;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorDescriptorControlInitialize(openavb_aem_descriptor_control_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ (void) nConfigIdx;
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_control.h b/lib/avtp_pipeline/aem/openavb_descriptor_control.h
new file mode 100644
index 00000000..6635e248
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_control.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Control Descriptor
+ * MODULE SUMMARY : Interface for the Control Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_CONTROL_H
+#define OPENAVB_DESCRIPTOR_CONTROL_H 1
+
+#include "openavb_descriptor_control_pub.h"
+
+#define OPENAVB_DESCRIPTOR_CONTROL_BASE_LENGTH (104)
+
+#endif // OPENAVB_DESCRIPTOR_CONTROL_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_control_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_control_pub.h
new file mode 100644
index 00000000..e0a6a0f4
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_control_pub.h
@@ -0,0 +1,111 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Control Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Control Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_CONTROL_PUB_H
+#define OPENAVB_DESCRIPTOR_CONTROL_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+// CONTROL Descriptor IEEE Std 1722.1-2013 clause 7.2.22
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 object_name[OPENAVB_AEM_STRLEN_MAX];
+ openavb_aem_string_ref_t localized_description;
+ U32 block_latency;
+ U32 control_latency;
+ U16 control_domain;
+ U16 control_value_type;
+ U64 control_type;
+ U32 reset_time;
+ U16 values_offset;
+ U16 number_of_values;
+ U16 signal_type;
+ U16 signal_index;
+ U16 signal_output;
+ union {
+ openavb_aem_control_value_format_control_linear_int8_t linear_int8[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_INT8];
+ openavb_aem_control_value_format_control_linear_uint8_t linear_uint8[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT8];
+ openavb_aem_control_value_format_control_linear_int16_t linear_int16[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_INT16];
+ openavb_aem_control_value_format_control_linear_uint16_t linear_uint16[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT16];
+ openavb_aem_control_value_format_control_linear_int32_t linear_int32[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_INT32];
+ openavb_aem_control_value_format_control_linear_uint32_t linear_uint32[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT32];
+ openavb_aem_control_value_format_control_linear_int64_t linear_int64[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_INT64];
+ openavb_aem_control_value_format_control_linear_uint64_t linear_uint64[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_UINT64];
+ openavb_aem_control_value_format_control_linear_float_t linear_float[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_FLOAT];
+ openavb_aem_control_value_format_control_linear_double_t linear_double[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_LINEAR_DOUBLE];
+ openavb_aem_control_value_format_control_selector_int8_t selector_int8[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT8];
+ openavb_aem_control_value_format_control_selector_uint8_t selector_uint8[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT8];
+ openavb_aem_control_value_format_control_selector_int16_t selector_int16[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT16];
+ openavb_aem_control_value_format_control_selector_uint16_t selector_uint16[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT16];
+ openavb_aem_control_value_format_control_selector_int32_t selector_int32[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT32];
+ openavb_aem_control_value_format_control_selector_uint32_t selector_uint32[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT32];
+ openavb_aem_control_value_format_control_selector_int64_t selector_int64[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_INT64];
+ openavb_aem_control_value_format_control_selector_uint64_t selector_uint64[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_UINT64];
+ openavb_aem_control_value_format_control_selector_float_t selector_float[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_FLOAT];
+ openavb_aem_control_value_format_control_selector_double_t selector_double[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_DOUBLE];
+ openavb_aem_control_value_format_control_selector_string_t selector_string[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SELECTOR_STRING];
+ openavb_aem_control_value_format_control_array_int8_t array_int8[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_INT8];
+ openavb_aem_control_value_format_control_array_uint8_t array_uint8[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT8];
+ openavb_aem_control_value_format_control_array_int16_t array_int16[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_INT16];
+ openavb_aem_control_value_format_control_array_uint16_t array_uint16[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT16];
+ openavb_aem_control_value_format_control_array_int32_t array_int32[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_INT32];
+ openavb_aem_control_value_format_control_array_uint32_t array_uint32[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT32];
+ openavb_aem_control_value_format_control_array_int64_t array_int64[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_INT64];
+ openavb_aem_control_value_format_control_array_uint64_t array_uint64[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_UINT64];
+ openavb_aem_control_value_format_control_array_float_t array_float[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_FLOAT];
+ openavb_aem_control_value_format_control_array_double_t array_double[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_ARRAY_DOUBLE];
+ openavb_aem_control_value_format_control_utf8_t utf8[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_UTF8];
+ openavb_aem_control_value_format_control_bode_plot_t bode_plot[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_BODE_PLOT];
+ openavb_aem_control_value_format_control_smpte_time_t smpte_time[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SMPTE_TIME];
+ openavb_aem_control_value_format_control_sample_rate_t sample_rate[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_SAMPLE_RATE];
+ openavb_aem_control_value_format_control_gptp_time_t gptp_time[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_GPTP_TIME];
+ openavb_aem_control_value_format_control_vendor_t vendor[OPENAVB_AEM_VALUE_MAX_COUNT_CONTROL_VENDOR];
+ } value_details;
+} openavb_aem_descriptor_control_t;
+
+
+openavb_aem_descriptor_control_t *openavbAemDescriptorControlNew(void);
+
+bool openavbAemDescriptorDescriptorControlInitialize(openavb_aem_descriptor_control_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+
+#endif // OPENAVB_DESCRIPTOR_CONTROL_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_entity.c b/lib/avtp_pipeline/aem/openavb_descriptor_entity.c
new file mode 100644
index 00000000..6e0e4666
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_entity.c
@@ -0,0 +1,411 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Entity Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Entity Descriptor IEEE Std 1722.1-2013 clause 7.2.1
+ ******************************************************************
+ */
+
+#include "openavb_platform.h"
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_entity.h"
+
+extern openavb_avdecc_cfg_t gAvdeccCfg;
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorEntityToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_entity_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_ENTITY_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_entity_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->entity_id);
+ OCT_D2BMEMCP(pDst, pSrc->entity_model_id);
+ OCT_D2BHTONL(pDst, pSrc->entity_capabilities);
+ OCT_D2BHTONS(pDst, pSrc->talker_stream_sources);
+ OCT_D2BHTONS(pDst, pSrc->talker_capabilities);
+ OCT_D2BHTONS(pDst, pSrc->listener_stream_sinks);
+ OCT_D2BHTONS(pDst, pSrc->listener_capabilities);
+ OCT_D2BHTONL(pDst, pSrc->controller_capabilities);
+ OCT_D2BHTONL(pDst, pSrc->available_index);
+ OCT_D2BMEMCP(pDst, pSrc->association_id);
+ OCT_D2BMEMCP(pDst, pSrc->entity_name);
+ BIT_D2BHTONS(pDst, pSrc->vendor_name_string.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->vendor_name_string.index, 0, 2);
+ BIT_D2BHTONS(pDst, pSrc->model_name_string.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->model_name_string.index, 0, 2);
+ OCT_D2BMEMCP(pDst, pSrc->firmware_version);
+ OCT_D2BMEMCP(pDst, pSrc->group_name);
+ OCT_D2BMEMCP(pDst, pSrc->serial_number);
+ OCT_D2BHTONS(pDst, pSrc->configurations_count);
+ OCT_D2BHTONS(pDst, pSrc->current_configuration);
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorEntityFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_entity_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_ENTITY_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_entity_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->entity_id, pSrc);
+ OCT_B2DMEMCP(pDst->entity_model_id, pSrc);
+ OCT_B2DNTOHL(pDst->entity_capabilities, pSrc);
+ OCT_B2DNTOHS(pDst->talker_stream_sources, pSrc);
+ OCT_B2DNTOHS(pDst->talker_capabilities, pSrc);
+ OCT_B2DNTOHS(pDst->listener_stream_sinks, pSrc);
+ OCT_B2DNTOHS(pDst->listener_capabilities, pSrc);
+ OCT_B2DNTOHL(pDst->controller_capabilities, pSrc);
+ OCT_B2DNTOHL(pDst->available_index, pSrc);
+ OCT_B2DMEMCP(pDst->association_id, pSrc);
+ OCT_B2DMEMCP(pDst->entity_name, pSrc);
+ BIT_B2DNTOHS(pDst->vendor_name_string.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->vendor_name_string.index, pSrc, 0x0007, 0, 2);
+ BIT_B2DNTOHS(pDst->model_name_string.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->model_name_string.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DMEMCP(pDst->firmware_version, pSrc);
+ OCT_B2DMEMCP(pDst->group_name, pSrc);
+ OCT_B2DMEMCP(pDst->serial_number, pSrc);
+ OCT_B2DNTOHS(pDst->configurations_count, pSrc);
+ OCT_B2DNTOHS(pDst->current_configuration, pSrc);
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorEntityUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_entity_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_entity_t *openavbAemDescriptorEntityNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_entity_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(openavb_aem_descriptor_entity_t));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor->descriptorPvtPtr, 0, sizeof(*pDescriptor->descriptorPvtPtr));
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_entity_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorEntityToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorEntityFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorEntityUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_ENTITY;
+ pDescriptor->descriptor_index = 0;
+
+ // Default to no localized strings.
+ pDescriptor->vendor_name_string.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->vendor_name_string.index = OPENAVB_AEM_NO_STRING_INDEX;
+ pDescriptor->model_name_string.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->model_name_string.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_entity_id(openavb_aem_descriptor_entity_t *pDescriptor, char *aMacAddr, U8 *nMacAddr, U16 id)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ struct ether_addr macAddrBuffer;
+ if (aMacAddr) {
+ // If an ascii mac address is passed in parse and use it.
+ memset(macAddrBuffer.ether_addr_octet, 0, sizeof(macAddrBuffer));
+
+ if (!ether_aton_r(aMacAddr, &macAddrBuffer)) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_PARSING_MAC_ADDRESS));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+ memcpy(pDescriptor->entity_id, macAddrBuffer.ether_addr_octet, 3);
+ memcpy(pDescriptor->entity_id + 3 + 2, macAddrBuffer.ether_addr_octet + 3, 3);
+ }
+ else if (nMacAddr) {
+ // If a network mac address is passed in use it.
+ memcpy(pDescriptor->entity_id, nMacAddr, 3);
+ memcpy(pDescriptor->entity_id + 3 + 2, nMacAddr + 3, 3);
+ }
+ else {
+ // If no mac address is passed in obtain it from the stack.
+ memcpy(pDescriptor->entity_id, gAvdeccCfg.ifmac, 3);
+ memcpy(pDescriptor->entity_id + 3 + 2, gAvdeccCfg.ifmac + 3, 3);
+ }
+
+ U16 tmpU16 = htons(id);
+ memcpy(pDescriptor->entity_id + 3, &tmpU16, sizeof(tmpU16));
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_entity_model_id(openavb_aem_descriptor_entity_t *pDescriptor, U8 pData[8])
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !pData) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ memcpy(pDescriptor->entity_model_id, pData, 8);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_entity_capabilities(openavb_aem_descriptor_entity_t *pDescriptor, U32 capabilities)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ pDescriptor->entity_capabilities = capabilities;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_talker_capabilities(openavb_aem_descriptor_entity_t *pDescriptor, U16 num_sources, U16 capabilities)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ pDescriptor->talker_stream_sources = num_sources;
+ pDescriptor->talker_capabilities = capabilities;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_listener_capabilities(openavb_aem_descriptor_entity_t *pDescriptor, U16 num_sinks, U16 capabilities)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ pDescriptor->listener_stream_sinks = num_sinks;
+ pDescriptor->listener_capabilities = capabilities;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_entity_name(openavb_aem_descriptor_entity_t *pDescriptor, char *aName)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !aName) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ openavbAemSetString(pDescriptor->entity_name, aName);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_vendor_name(openavb_aem_descriptor_entity_t *pDescriptor, U16 nOffset, U8 nIndex)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ pDescriptor->vendor_name_string.offset = nOffset;
+ pDescriptor->vendor_name_string.index = nIndex;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_model_name(openavb_aem_descriptor_entity_t *pDescriptor, U16 nOffset, U8 nIndex)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ pDescriptor->model_name_string.offset = nOffset;
+ pDescriptor->model_name_string.index = nIndex;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_firmware_version(openavb_aem_descriptor_entity_t *pDescriptor, char *aFirmwareVersion)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !aFirmwareVersion) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ openavbAemSetString(pDescriptor->firmware_version, aFirmwareVersion);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_group_name(openavb_aem_descriptor_entity_t *pDescriptor, char *aGroupName)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !aGroupName) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ openavbAemSetString(pDescriptor->group_name, aGroupName);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorEntitySet_serial_number(openavb_aem_descriptor_entity_t *pDescriptor, char *aSerialNumber)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !aSerialNumber) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ openavbAemSetString(pDescriptor->serial_number, aSerialNumber);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_entity.h b/lib/avtp_pipeline/aem/openavb_descriptor_entity.h
new file mode 100644
index 00000000..7e8ade4f
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_entity.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Entity Model : Entity Descriptor
+ * MODULE SUMMARY : Interface for the Entity Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_ENTITY_H
+#define OPENAVB_DESCRIPTOR_ENTITY_H 1
+
+#include "openavb_descriptor_entity_pub.h"
+
+#define OPENAVB_DESCRIPTOR_ENTITY_BASE_LENGTH 312
+
+#endif // OPENAVB_DESCRIPTOR_ENTITY_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_entity_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_entity_pub.h
new file mode 100644
index 00000000..00875ae3
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_entity_pub.h
@@ -0,0 +1,108 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Entity Model : Entity Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Entity Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_ENTITY_PUB_H
+#define OPENAVB_DESCRIPTOR_ENTITY_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+// ENTITY Descriptor IEEE Std 1722.1-2013 clause 7.2.1
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 entity_id[8];
+ U8 entity_model_id[8];
+ U32 entity_capabilities;
+ U16 talker_stream_sources;
+ U16 talker_capabilities;
+ U16 listener_stream_sinks;
+ U16 listener_capabilities;
+ U32 controller_capabilities;
+ U32 available_index;
+ U8 association_id[8];
+ U8 entity_name[OPENAVB_AEM_STRLEN_MAX];
+ openavb_aem_string_ref_t vendor_name_string;
+ openavb_aem_string_ref_t model_name_string;
+ U8 firmware_version[OPENAVB_AEM_STRLEN_MAX];
+ U8 group_name[OPENAVB_AEM_STRLEN_MAX];
+ U8 serial_number[OPENAVB_AEM_STRLEN_MAX];
+ U16 configurations_count; // Set internally
+ U16 current_configuration; // Set internally
+} openavb_aem_descriptor_entity_t;
+
+// Create a new Entity Descriptor
+openavb_aem_descriptor_entity_t *openavbAemDescriptorEntityNew(void);
+
+// Set the Entity ID using the common approach of mac address and an ID. Either pass in aMacAddr (ascii) or nMacAddr (network)
+bool openavbAemDescriptorEntitySet_entity_id(openavb_aem_descriptor_entity_t *pDescriptor, char *aMacAddr, U8 *nMacAddr, U16 id);
+
+// Set the Entity Model ID. Pass in a pointer to an array of 8 bytes of arbitrary data.
+bool openavbAemDescriptorEntitySet_entity_model_id(openavb_aem_descriptor_entity_t *pDescriptor, U8 pData[8]);
+
+// Set the Entity Capabilities. Use the OPENAVB_ADP_ENTITY_CAPABILITIES_... flags from adp/openavb_adp_pub.h.
+bool openavbAemDescriptorEntitySet_entity_capabilities(openavb_aem_descriptor_entity_t *pDescriptor, U32 capabilities);
+
+// Set the Talker Capabilities. Use the OPENAVB_ADP_TALKER_CAPABILITIES_... flags from adp/openavb_adp_pub.h.
+bool openavbAemDescriptorEntitySet_talker_capabilities(openavb_aem_descriptor_entity_t *pDescriptor, U16 num_sources, U16 capabilities);
+
+// Set the Listener Capabilities. Use the OPENAVB_ADP_LISTENER_CAPABILITIES_... flags from adp/openavb_adp_pub.h.
+bool openavbAemDescriptorEntitySet_listener_capabilities(openavb_aem_descriptor_entity_t *pDescriptor, U16 num_sinks, U16 capabilities);
+
+// Set the Entity Name.
+bool openavbAemDescriptorEntitySet_entity_name(openavb_aem_descriptor_entity_t *pDescriptor, char *aName);
+
+// Set the Vendor Name.
+bool openavbAemDescriptorEntitySet_vendor_name(openavb_aem_descriptor_entity_t *pDescriptor, U16 nOffset, U8 nIndex);
+
+// Set the Model Name.
+bool openavbAemDescriptorEntitySet_model_name(openavb_aem_descriptor_entity_t *pDescriptor, U16 nOffset, U8 nIndex);
+
+// Set the Firmware Version.
+bool openavbAemDescriptorEntitySet_firmware_version(openavb_aem_descriptor_entity_t *pDescriptor, char *aFirmwareVersion);
+
+// Set the Group Name.
+bool openavbAemDescriptorEntitySet_group_name(openavb_aem_descriptor_entity_t *pDescriptor, char *aGroupName);
+
+// Set the Serial Number.
+bool openavbAemDescriptorEntitySet_serial_number(openavb_aem_descriptor_entity_t *pDescriptor, char *aSerialNumber);
+
+#endif // OPENAVB_DESCRIPTOR_ENTITY_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_external_port_io.c b/lib/avtp_pipeline/aem/openavb_descriptor_external_port_io.c
new file mode 100644
index 00000000..615e800c
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_external_port_io.c
@@ -0,0 +1,209 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC External Port IO Descriptor
+ * MODULE SUMMARY : Implements the AVDECC External Port IO IEEE Std 1722.1-2013 clause 7.2.14
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_external_port_io.h"
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorExternalPortIOToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_external_port_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_EXTERNAL_PORT_IO_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_external_port_io_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BHTONS(pDst, pSrc->clock_domain_index);
+ OCT_D2BHTONS(pDst, pSrc->port_flags);
+ OCT_D2BHTONS(pDst, pSrc->number_of_controls);
+ OCT_D2BHTONS(pDst, pSrc->base_control);
+ OCT_D2BHTONS(pDst, pSrc->signal_type);
+ OCT_D2BHTONS(pDst, pSrc->signal_index);
+ OCT_D2BHTONS(pDst, pSrc->signal_output);
+ OCT_D2BHTONL(pDst, pSrc->block_latency);
+ OCT_D2BHTONS(pDst, pSrc->jack_index);
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorExternalPortIOFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_external_port_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_EXTERNAL_PORT_IO_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_external_port_io_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DNTOHS(pDst->clock_domain_index, pSrc);
+ OCT_B2DNTOHS(pDst->port_flags, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_controls, pSrc);
+ OCT_B2DNTOHS(pDst->base_control, pSrc);
+ OCT_B2DNTOHS(pDst->signal_type, pSrc);
+ OCT_B2DNTOHS(pDst->signal_index, pSrc);
+ OCT_B2DNTOHS(pDst->signal_output, pSrc);
+ OCT_B2DNTOHL(pDst->block_latency, pSrc);
+ OCT_B2DNTOHS(pDst->jack_index, pSrc);
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorExternalPortIOUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_external_port_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_external_port_io_t *openavbAemDescriptorExternalPortInputNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_external_port_io_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_external_port_io_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = FALSE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorExternalPortIOToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorExternalPortIOFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorExternalPortIOUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_STREAM_PORT_INPUT;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT openavb_aem_descriptor_external_port_io_t *openavbAemDescriptorExternalPortOutputNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_external_port_io_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_external_port_io_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = FALSE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorExternalPortIOToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorExternalPortIOFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorExternalPortIOUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_STREAM_PORT_OUTPUT;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_external_port_io.h b/lib/avtp_pipeline/aem/openavb_descriptor_external_port_io.h
new file mode 100644
index 00000000..3336d581
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_external_port_io.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC External Port IO Descriptor
+ * MODULE SUMMARY : Interface for the External Port IO Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_EXTERNAL_PORT_IO_H
+#define OPENAVB_DESCRIPTOR_EXTERNAL_PORT_IO_H 1
+
+#include "openavb_descriptor_external_port_io_pub.h"
+
+#define OPENAVB_DESCRIPTOR_EXTERNAL_PORT_IO_BASE_LENGTH 24
+
+#endif // OPENAVB_DESCRIPTOR_EXTERNAL_PORT_IO_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_external_port_io_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_external_port_io_pub.h
new file mode 100644
index 00000000..7f7522cb
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_external_port_io_pub.h
@@ -0,0 +1,66 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC External Port IO Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the External Port IO Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_EXTERNAL_PORT_IO_PUB_H
+#define OPENAVB_DESCRIPTOR_EXTERNAL_PORT_IO_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+// EXTERNAL PORT IO Descriptor IEEE Std 1722.1-2013 clause 7.2.14
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type;
+ U16 descriptor_index;
+ U16 clock_domain_index;
+ U16 port_flags;
+ U16 number_of_controls;
+ U16 base_control;
+ U16 signal_type;
+ U16 signal_index;
+ U16 signal_output;
+ U32 block_latency;
+ U16 jack_index;
+} openavb_aem_descriptor_external_port_io_t;
+
+openavb_aem_descriptor_external_port_io_t *openavbAemDescriptorExternalPortInputNew(void);
+openavb_aem_descriptor_external_port_io_t *openavbAemDescriptorExternalPortOutputNew(void);
+
+#endif // OPENAVB_DESCRIPTOR_EXTERNAL_PORT_IO_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_jack_io.c b/lib/avtp_pipeline/aem/openavb_descriptor_jack_io.c
new file mode 100644
index 00000000..5813b03b
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_jack_io.c
@@ -0,0 +1,235 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Jack IO Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Jack IO IEEE Std 1722.1-2013 clause 7.2.7
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_jack_io.h"
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorJackIOToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_jack_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_JACK_IO_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_jack_io_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->object_name);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.index, 0, 2);
+ OCT_D2BHTONS(pDst, pSrc->jack_flags);
+ OCT_D2BHTONS(pDst, pSrc->jack_type);
+ OCT_D2BHTONS(pDst, pSrc->number_of_controls);
+ OCT_D2BHTONS(pDst, pSrc->base_control);
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorJackIOFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_jack_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_JACK_IO_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_jack_io_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->object_name, pSrc);
+ BIT_B2DNTOHS(pDst->localized_description.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->localized_description.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DNTOHS(pDst->jack_flags, pSrc);
+ OCT_B2DNTOHS(pDst->jack_type, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_controls, pSrc);
+ OCT_B2DNTOHS(pDst->base_control, pSrc);
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorJackIOUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_jack_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_jack_io_t *openavbAemDescriptorJackInputNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_jack_io_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_jack_io_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorJackIOToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorJackIOFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorJackIOUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_JACK_INPUT;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT openavb_aem_descriptor_jack_io_t *openavbAemDescriptorJackOutputNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_jack_io_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_jack_io_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorJackIOToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorJackIOFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorJackIOUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_JACK_OUTPUT;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorJackInputInitialize(openavb_aem_descriptor_jack_io_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ (void) nConfigIdx;
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorJackOutputInitialize(openavb_aem_descriptor_jack_io_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ (void) nConfigIdx;
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_jack_io.h b/lib/avtp_pipeline/aem/openavb_descriptor_jack_io.h
new file mode 100644
index 00000000..0a747c2a
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_jack_io.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Jack IO Descriptor
+ * MODULE SUMMARY : Interface for the Jack IO Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_JACK_IO_H
+#define OPENAVB_DESCRIPTOR_JACK_IO_H 1
+
+#include "openavb_descriptor_jack_io_pub.h"
+
+#define OPENAVB_DESCRIPTOR_JACK_IO_BASE_LENGTH 78
+
+#endif // OPENAVB_DESCRIPTOR_JACK_IO_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_jack_io_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_jack_io_pub.h
new file mode 100644
index 00000000..a2bf65b4
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_jack_io_pub.h
@@ -0,0 +1,66 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Jack IO Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Jack IO Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_JACK_IO_PUB_H
+#define OPENAVB_DESCRIPTOR_JACK_IO_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+// JACK IO Descriptor IEEE Std 1722.1-2013 clause 7.2.7
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type;
+ U16 descriptor_index;
+ U8 object_name[OPENAVB_AEM_STRLEN_MAX];
+ openavb_aem_string_ref_t localized_description;
+ U16 jack_flags;
+ U16 jack_type;
+ U16 number_of_controls;
+ U16 base_control;
+} openavb_aem_descriptor_jack_io_t;
+
+openavb_aem_descriptor_jack_io_t *openavbAemDescriptorJackInputNew(void);
+openavb_aem_descriptor_jack_io_t *openavbAemDescriptorJackOutputNew(void);
+
+bool openavbAemDescriptorJackInputInitialize(openavb_aem_descriptor_jack_io_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+bool openavbAemDescriptorJackOutputInitialize(openavb_aem_descriptor_jack_io_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+
+#endif // OPENAVB_DESCRIPTOR_JACK_IO_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_locale.c b/lib/avtp_pipeline/aem/openavb_descriptor_locale.c
new file mode 100644
index 00000000..4f486d0d
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_locale.c
@@ -0,0 +1,208 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Locale Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Locale IEEE Std 1722.1-2013 clause 7.2.11
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_locale.h"
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorLocaleToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_locale_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_LOCALE_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_locale_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->locale_identifier);
+ OCT_D2BHTONS(pDst, pSrc->number_of_strings);
+ OCT_D2BHTONS(pDst, pSrc->base_strings);
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorLocaleFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_locale_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_LOCALE_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_locale_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->locale_identifier, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_strings, pSrc);
+ OCT_B2DNTOHS(pDst->base_strings, pSrc);
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorLocaleUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_locale_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_locale_t *openavbAemDescriptorLocaleNew(void)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_locale_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_locale_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorLocaleToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorLocaleFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorLocaleUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_LOCALE;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorLocaleSet_locale_identifier(openavb_aem_descriptor_locale_t *pDescriptor, const char *aLocaleIdentifier)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !aLocaleIdentifier) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ openavbAemSetString(pDescriptor->locale_identifier, aLocaleIdentifier);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorLocaleSet_number_of_strings(openavb_aem_descriptor_locale_t *pDescriptor, U16 uNumberOfStrings)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ pDescriptor->number_of_strings = uNumberOfStrings;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorLocaleSet_base_strings(openavb_aem_descriptor_locale_t *pDescriptor, U16 uBaseStrings)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ pDescriptor->base_strings = uBaseStrings;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_locale.h b/lib/avtp_pipeline/aem/openavb_descriptor_locale.h
new file mode 100644
index 00000000..f5e0ffe3
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_locale.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Locale Descriptor
+ * MODULE SUMMARY : Interface for the Locale Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_LOCALE_H
+#define OPENAVB_DESCRIPTOR_LOCALE_H 1
+
+#include "openavb_descriptor_locale_pub.h"
+
+#define OPENAVB_DESCRIPTOR_LOCALE_BASE_LENGTH 72
+
+#endif // OPENAVB_DESCRIPTOR_LOCALE_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_locale_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_locale_pub.h
new file mode 100644
index 00000000..aba0e01a
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_locale_pub.h
@@ -0,0 +1,69 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Locale Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Locale Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_LOCALE_PUB_H
+#define OPENAVB_DESCRIPTOR_LOCALE_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+// LOCALE Descriptor IEEE Std 1722.1-2013 clause 7.2.11
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 locale_identifier[OPENAVB_AEM_STRLEN_MAX];
+ U16 number_of_strings;
+ U16 base_strings;
+} openavb_aem_descriptor_locale_t;
+
+openavb_aem_descriptor_locale_t *openavbAemDescriptorLocaleNew(void);
+
+// Specify the locale identifier for the descriptor.
+bool openavbAemDescriptorLocaleSet_locale_identifier(openavb_aem_descriptor_locale_t *pDescriptor, const char *aLocaleIdentifier);
+
+// Specify the number of strings descriptors in this locale.
+// The same number should be specified for all locales.
+bool openavbAemDescriptorLocaleSet_number_of_strings(openavb_aem_descriptor_locale_t *pDescriptor, U16 uNumberOfStrings);
+
+// Specify the descriptor index of the first strings descriptor for this locale.
+bool openavbAemDescriptorLocaleSet_base_strings(openavb_aem_descriptor_locale_t *pDescriptor, U16 uBaseStrings);
+
+#endif // OPENAVB_DESCRIPTOR_LOCALE_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler.c b/lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler.c
new file mode 100644
index 00000000..8591bda2
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler.c
@@ -0,0 +1,230 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Locale Strings Handler Descriptor
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_aem.h"
+#include "openavb_descriptor_locale_strings_handler.h"
+
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+
+extern DLL_EXPORT openavb_aem_descriptor_locale_strings_handler_t *openavbAemDescriptorLocaleStringsHandlerNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT void openavbAemDescriptorLocaleStringsHandlerFree(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (pDescriptor) {
+ while (pDescriptor->pFirstGroup) {
+ openavb_aem_descriptor_locale_strings_handler_group_t *pDel = pDescriptor->pFirstGroup;
+ pDescriptor->pFirstGroup = pDel->pNext;
+ free(pDel->pLocale); // TODO BDT_DEBUG Will this be freed elsewhere?
+ free(pDel->pStrings); // TODO BDT_DEBUG Will this be freed elsewhere?
+ free(pDel);
+ }
+ free(pDescriptor);
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+}
+
+extern DLL_EXPORT openavb_aem_descriptor_locale_strings_handler_group_t * openavbAemDescriptorLocaleStringsHandlerGet_group(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor,
+ const char *aLocaleIdentifier,
+ bool bCanCreate)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !aLocaleIdentifier) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ // Do we have a matching item?
+ openavb_aem_descriptor_locale_strings_handler_group_t *pTest = pDescriptor->pFirstGroup;
+ while (pTest) {
+ if (strncmp(aLocaleIdentifier, (const char *) pTest->pLocale->locale_identifier, OPENAVB_AEM_STRLEN_MAX) == 0) {
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pTest;
+ }
+ pTest = pTest->pNext;
+ }
+
+ // Can we allocate a new language structure?
+ if (bCanCreate) {
+ // Allocate a new group.
+ openavb_aem_descriptor_locale_strings_handler_group_t *pNew = malloc(sizeof(openavb_aem_descriptor_locale_strings_handler_group_t));
+ if (!pNew) {
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ pNew->pLocale = openavbAemDescriptorLocaleNew();
+ pNew->pStrings = openavbAemDescriptorStringsNew();
+ if (!pNew->pLocale || !pNew->pStrings) {
+ free(pNew->pLocale);
+ free(pNew->pStrings);
+ free(pNew);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ openavbAemDescriptorLocaleSet_locale_identifier(pNew->pLocale, aLocaleIdentifier);
+
+ // Add the new group to the start of the linked list.
+ pNew->pNext = pDescriptor->pFirstGroup;
+ pDescriptor->pFirstGroup = pNew;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pNew;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+}
+
+extern DLL_EXPORT const char * openavbAemDescriptorLocaleStringsHandlerGet_local_string(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor,
+ const char *aLocaleIdentifier,
+ U8 uStringIndex)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !aLocaleIdentifier || uStringIndex >= OPENAVB_AEM_NUM_DESCRIPTOR_STRINGS) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ // Get the group structure to get this string from.
+ openavb_aem_descriptor_locale_strings_handler_group_t *pGroup = openavbAemDescriptorLocaleStringsHandlerGet_group(pDescriptor, aLocaleIdentifier, FALSE);
+ if (!pGroup) {
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ const char * ret = openavbAemDescriptorStringsGet_string(pGroup->pStrings, uStringIndex);
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return ret;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorLocaleStringsHandlerSet_local_string(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor,
+ const char *aLocaleIdentifier,
+ const char *aString,
+ U8 uStringIndex)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !aLocaleIdentifier || !aString || uStringIndex >= OPENAVB_AEM_NUM_DESCRIPTOR_STRINGS) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ // Get the group structure to add this string to. Create it if needed.
+ openavb_aem_descriptor_locale_strings_handler_group_t *pGroup = openavbAemDescriptorLocaleStringsHandlerGet_group(pDescriptor, aLocaleIdentifier, TRUE);
+ if (!pGroup) {
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ bool ret = openavbAemDescriptorStringsSet_string(pGroup->pStrings, aString, uStringIndex);
+ if (ret) {
+ openavbAemDescriptorLocaleSet_number_of_strings(pGroup->pLocale, 1);
+ openavbAemDescriptorLocaleSet_base_strings(pGroup->pLocale, 0);
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return ret;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorLocaleStringsHandlerAddToConfiguration(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor, U16 nConfigIdx)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_locale_strings_handler_group_t *pCurrent = pDescriptor->pFirstGroup;
+ while (pCurrent) {
+ U16 nResultIdx;
+
+ // Add the locale to the configuration.
+ if (!openavbAemAddDescriptor(pCurrent->pLocale, nConfigIdx, &nResultIdx)) {
+ AVB_LOG_ERROR("Locale Add Descriptor Failure");
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return false;
+ }
+
+ // Add the strings descriptor, if it hasn't already been added.
+ if (openavbAemGetDescriptorIndex(OPENAVB_AEM_DESCRIPTOR_INVALID, pCurrent->pStrings) == OPENAVB_AEM_DESCRIPTOR_INVALID) {
+ if (!openavbAemAddDescriptor(pCurrent->pStrings, OPENAVB_AEM_DESCRIPTOR_INVALID /* Not configuration-specific */, &nResultIdx)) {
+ AVB_LOG_ERROR("Strings Add Descriptor Failure");
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return false;
+ }
+ }
+
+ pCurrent = pCurrent->pNext;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return true;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler.h b/lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler.h
new file mode 100644
index 00000000..adf36ca2
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler.h
@@ -0,0 +1,44 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Locale Descriptor
+ * MODULE SUMMARY : Interface for the Locale Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_LOCALE_STRINGS_HANDLER_H
+#define OPENAVB_DESCRIPTOR_LOCALE_STRINGS_HANDLER_H 1
+
+#include "openavb_descriptor_locale_strings_handler_pub.h"
+
+#endif // OPENAVB_DESCRIPTOR_LOCALE_STRINGS_HANDLER_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler_pub.h
new file mode 100644
index 00000000..04796d0c
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_locale_strings_handler_pub.h
@@ -0,0 +1,91 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Locale Strings Handler Public Interface
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_LOCALE_STRINGS_HANDLER_PUB_H
+#define OPENAVB_DESCRIPTOR_LOCALE_STRINGS_HANDLER_PUB_H 1
+
+#include "openavb_descriptor_locale_pub.h"
+#include "openavb_descriptor_strings_pub.h"
+
+// Grouping that holds a locale, and the strings for that locale.
+struct openavb_aem_descriptor_locale_strings_handler_group {
+ openavb_aem_descriptor_locale_t *pLocale;
+ openavb_aem_descriptor_strings_t *pStrings;
+ struct openavb_aem_descriptor_locale_strings_handler_group *pNext;
+};
+typedef struct openavb_aem_descriptor_locale_strings_handler_group openavb_aem_descriptor_locale_strings_handler_group_t;
+
+// Grouping that holds a locale, and the strings for that locale.
+typedef struct {
+ openavb_aem_descriptor_locale_strings_handler_group_t *pFirstGroup;
+} openavb_aem_descriptor_locale_strings_handler_t;
+
+
+openavb_aem_descriptor_locale_strings_handler_t *openavbAemDescriptorLocaleStringsHandlerNew(void);
+
+void openavbAemDescriptorLocaleStringsHandlerFree(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor);
+
+// Return the group structure for the specified locale.
+// If bCanCreate is TRUE, a structure one will be allocated if needed.
+openavb_aem_descriptor_locale_strings_handler_group_t * openavbAemDescriptorLocaleStringsHandlerGet_group(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor,
+ const char *aLocaleIdentifier,
+ bool bCanCreate);
+
+// Returns the string at the specified index for the given locale,
+// or NULL if the string has not been specified.
+const char * openavbAemDescriptorLocaleStringsHandlerGet_local_string(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor,
+ const char *aLocaleIdentifier,
+ U8 uStringIndex);
+
+// Set a string at the specified index for the given locale.
+// If there was a previous string value, it will be overwritten.
+// The index must be a value less than OPENAVB_AEM_NUM_DESCRIPTOR_STRINGS.
+bool openavbAemDescriptorLocaleStringsHandlerSet_local_string(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor,
+ const char *aLocaleIdentifier,
+ const char *aString,
+ U8 uStringIndex);
+
+// Add the strings to the supplied configuration.
+bool openavbAemDescriptorLocaleStringsHandlerAddToConfiguration(
+ openavb_aem_descriptor_locale_strings_handler_t *pDescriptor,
+ U16 nConfigIdx);
+
+#endif // OPENAVB_DESCRIPTOR_LOCALE_STRINGS_HANDLER_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_stream_io.c b/lib/avtp_pipeline/aem/openavb_descriptor_stream_io.c
new file mode 100644
index 00000000..d585a47d
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_stream_io.c
@@ -0,0 +1,572 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Stream IO Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Stream IO IEEE Std 1722.1-2013 clause 7.2.6
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_stream_io.h"
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+
+openavbRC openavbAemDescriptorStreamIOToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_STREAM_IO_BASE_LENGTH + (pDescriptor->number_of_formats * OPENAVB_DESCRIPTOR_STREAM_IO_FORMAT_LENGTH)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_stream_io_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BMEMCP(pDst, pSrc->object_name);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.offset, 3, 0);
+ BIT_D2BHTONS(pDst, pSrc->localized_description.index, 0, 2);
+ OCT_D2BHTONS(pDst, pSrc->clock_domain_index);
+ OCT_D2BHTONS(pDst, pSrc->stream_flags);
+ openavbAemStreamFormatToBuf(&pSrc->current_format, pDst);
+ pDst += 8;
+ OCT_D2BHTONS(pDst, pSrc->formats_offset);
+ OCT_D2BHTONS(pDst, pSrc->number_of_formats);
+ OCT_D2BMEMCP(pDst, pSrc->backup_talker_entity_id_0);
+ OCT_D2BHTONS(pDst, pSrc->backup_talker_unique_id_0);
+ OCT_D2BMEMCP(pDst, pSrc->backup_talker_entity_id_1);
+ OCT_D2BHTONS(pDst, pSrc->backup_talker_unique_id_1);
+ OCT_D2BMEMCP(pDst, pSrc->backup_talker_entity_id_2);
+ OCT_D2BHTONS(pDst, pSrc->backup_talker_unique_id_2);
+ OCT_D2BMEMCP(pDst, pSrc->backedup_talker_entity_id);
+ OCT_D2BHTONS(pDst, pSrc->backedup_talker_unique_id);
+ OCT_D2BHTONS(pDst, pSrc->avb_interface_index);
+ OCT_D2BHTONL(pDst, pSrc->buffer_length);
+
+ int i1;
+ for (i1 = 0; i1 < pSrc->number_of_formats; i1++) {
+ openavbAemStreamFormatToBuf(&pSrc->stream_formats[i1], pDst);
+ pDst += 8;
+ }
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+
+void x_openavbAemStreamFormatFromBuf(openavb_aem_stream_format_t *pDst, U8 *pBuf)
+{
+ U8 *pSrc = pBuf;
+
+ // Tightly bound to caller not safety checks needed.
+
+ BIT_B2DNTOHB(pDst->v, pSrc, 0x80, 7, 0);
+ if (pDst->v == 0) {
+ BIT_B2DNTOHB(pDst->subtype, pSrc, 0x7f, 0, 1);
+ switch (pDst->subtype) {
+ case OPENAVB_AEM_STREAM_FORMAT_61883_IIDC_SUBTYPE:
+ {
+ BIT_B2DNTOHB(pDst->subtypes.iec_61883_iidc.sf, pSrc, 0x80, 7, 0);
+ if (pDst->subtypes.iec_61883_iidc.sf == OPENAVB_AEM_STREAM_FORMAT_SF_IIDC) {
+ pSrc += 4;
+ OCT_B2DNTOHB(pDst->subtypes.iidc.iidc_format, pSrc);
+ OCT_B2DNTOHB(pDst->subtypes.iidc.iidc_mode, pSrc);
+ OCT_B2DNTOHB(pDst->subtypes.iidc.iidc_rate, pSrc);
+ }
+ else {
+ BIT_B2DNTOHB(pDst->subtypes.iec_61883.sf, pSrc, 0x80, 7, 0);
+ BIT_B2DNTOHB(pDst->subtypes.iec_61883.fmt, pSrc, 0x7e, 1, 1);
+ if (pDst->subtypes.iec_61883.fmt == OPENAVB_AEM_STREAM_FORMAT_FMT_61883_4) {
+ // Nothingn to do
+ }
+ else if (pDst->subtypes.iec_61883.fmt == OPENAVB_AEM_STREAM_FORMAT_FMT_61883_6) {
+ BIT_B2DNTOHB(pDst->subtypes.iec_61883_6.fdf_evt, pSrc, 0xf8, 3, 0);
+ BIT_B2DNTOHB(pDst->subtypes.iec_61883_6.fdf_sfc, pSrc, 0x07, 0, 1);
+ OCT_B2DNTOHB(pDst->subtypes.iec_61883_6.dbs, pSrc);
+ BIT_B2DNTOHB(pDst->subtypes.iec_61883_6.b, pSrc, 0x80, 7, 0);
+ BIT_B2DNTOHB(pDst->subtypes.iec_61883_6.nb, pSrc, 0x40, 6, 1);
+
+ if (pDst->subtypes.iec_61883_6.fdf_evt == OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_32BITS) {
+ // Nothing to do
+ }
+ else if (pDst->subtypes.iec_61883_6.fdf_evt == OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_FLOAT) {
+ // Nothing to do
+ }
+ else if (pDst->subtypes.iec_61883_6.fdf_evt == OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_AM824) {
+ OCT_B2DNTOHB(pDst->subtypes.iec_61883_6_am824.label_iec_60958_cnt, pSrc);
+ OCT_B2DNTOHB(pDst->subtypes.iec_61883_6_am824.label_mbla_cnt, pSrc);
+ BIT_B2DNTOHB(pDst->subtypes.iec_61883_6_am824.label_midi_cnt, pSrc, 0xf0, 4, 0);
+ BIT_B2DNTOHB(pDst->subtypes.iec_61883_6_am824.label_smptecnt, pSrc, 0x0f, 0, 1);
+ }
+ }
+
+ else if (pDst->subtypes.iec_61883.fmt == OPENAVB_AEM_STREAM_FORMAT_FMT_61883_8) {
+ pSrc += 3;
+ OCT_B2DNTOHB(pDst->subtypes.iec_61883_8.video_mode, pSrc);
+ OCT_B2DNTOHB(pDst->subtypes.iec_61883_8.compress_mode, pSrc);
+ OCT_B2DNTOHB(pDst->subtypes.iec_61883_8.color_space, pSrc);
+ }
+ }
+ }
+
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_MMA_SUBTYPE:
+ // Nothing to do
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_AVTP_AUDIO_SUBTYPE:
+ BIT_B2DNTOHB(pDst->subtypes.avtp_audio.nominal_sample_rate, pSrc, 0x0f, 0, 1);
+ OCT_B2DNTOHB(pDst->subtypes.avtp_audio.format, pSrc);
+ OCT_B2DNTOHB(pDst->subtypes.avtp_audio.bit_depth, pSrc);
+ BIT_B2DNTOHL(pDst->subtypes.avtp_audio.channels_per_frame, pSrc, 0xffc00000, 22, 0);
+ BIT_B2DNTOHL(pDst->subtypes.avtp_audio.samples_per_frame, pSrc, 0x003ff000, 12, 4);
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_AVTP_VIDEO_SUBTYPE:
+ OCT_B2DNTOHB(pDst->subtypes.avtp_video.format, pSrc);
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_AVTP_CONTROL_SUBTYPE:
+ BIT_B2DNTOHB(pDst->subtypes.avtp_control.protocol_type, pSrc, 0xf0, 4, 1);
+ OCT_B2DMEMCP(pDst->subtypes.avtp_control.format_id, pSrc);
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_VENDOR_SUBTYPE:
+ pSrc++;
+ OCT_B2DMEMCP(pDst->subtypes.vendor.format_id, pSrc);
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_EXPERIMENTAL_SUBTYPE:
+ // Nothing to do
+ break;
+ }
+ }
+ else {
+ pSrc++;
+ OCT_B2DMEMCP(pDst->subtypes.vendor_specific.format_id, pSrc);
+ }
+}
+
+
+openavbRC openavbAemDescriptorStreamIOFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_STREAM_IO_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_stream_io_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DMEMCP(pDst->object_name, pSrc);
+ BIT_B2DNTOHS(pDst->localized_description.offset, pSrc, 0xfff8, 3, 0);
+ BIT_B2DNTOHS(pDst->localized_description.index, pSrc, 0x0007, 0, 2);
+ OCT_B2DNTOHS(pDst->clock_domain_index, pSrc);
+ OCT_B2DNTOHS(pDst->stream_flags, pSrc);
+ x_openavbAemStreamFormatFromBuf(&pDst->current_format, pSrc);
+ pSrc += 8;
+ OCT_B2DNTOHS(pDst->formats_offset, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_formats, pSrc);
+ OCT_B2DMEMCP(pDst->backup_talker_entity_id_0, pSrc);
+ OCT_B2DNTOHS(pDst->backup_talker_unique_id_0, pSrc);
+ OCT_B2DMEMCP(pDst->backup_talker_entity_id_1, pSrc);
+ OCT_B2DNTOHS(pDst->backup_talker_unique_id_1, pSrc);
+ OCT_B2DMEMCP(pDst->backup_talker_entity_id_2, pSrc);
+ OCT_B2DNTOHS(pDst->backup_talker_unique_id_2, pSrc);
+ OCT_B2DMEMCP(pDst->backedup_talker_entity_id, pSrc);
+ OCT_B2DNTOHS(pDst->backedup_talker_unique_id, pSrc);
+ OCT_B2DNTOHS(pDst->avb_interface_index, pSrc);
+ OCT_B2DNTOHL(pDst->buffer_length, pSrc);
+
+ if (bufLength < OPENAVB_DESCRIPTOR_STREAM_IO_BASE_LENGTH + (pDescriptor->number_of_formats * OPENAVB_DESCRIPTOR_STREAM_IO_FORMAT_LENGTH)) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ int i1;
+ for (i1 = 0; i1 < pDst->number_of_formats; i1++) {
+ x_openavbAemStreamFormatFromBuf(&pDst->stream_formats[i1], pSrc);
+ pSrc += 8;
+ }
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorStreamIOUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_stream_io_t *openavbAemDescriptorStreamInputNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_io_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_stream_io_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorStreamIOToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorStreamIOFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorStreamIOUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT;
+ pDescriptor->formats_offset = OPENAVB_DESCRIPTOR_STREAM_IO_BASE_LENGTH;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ // Will determine the status of this once the Listener has connected to AVDECC.
+ pDescriptor->fast_connect_status = OPENAVB_FAST_CONNECT_STATUS_UNKNOWN;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT openavb_aem_descriptor_stream_io_t *openavbAemDescriptorStreamOutputNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_io_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_stream_io_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = TRUE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorStreamIOToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorStreamIOFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorStreamIOUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT;
+ pDescriptor->formats_offset = OPENAVB_DESCRIPTOR_STREAM_IO_BASE_LENGTH;
+
+ // Default to no localized strings.
+ pDescriptor->localized_description.offset = OPENAVB_AEM_NO_STRING_OFFSET;
+ pDescriptor->localized_description.index = OPENAVB_AEM_NO_STRING_INDEX;
+
+ // Talkers won't attempt to fast connect.
+ pDescriptor->fast_connect_status = OPENAVB_FAST_CONNECT_STATUS_NOT_AVAILABLE;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+static void fillInStreamFormat(openavb_aem_descriptor_stream_io_t *pDescriptor, const openavb_avdecc_configuration_cfg_t *pConfig)
+{ // AVDECC_TODO - Specify the stream format information for MMA Stream Format.
+ if (strcmp(pConfig->stream->map_fn,"openavbMapAVTPAudioInitialize") == 0)
+ {
+ pDescriptor->stream_formats[0].v = 0;
+ pDescriptor->stream_formats[0].subtype = OPENAVB_AEM_STREAM_FORMAT_AVTP_AUDIO_SUBTYPE;
+ pDescriptor->stream_formats[0].subtypes.avtp_audio.nominal_sample_rate = 0x05;
+ pDescriptor->stream_formats[0].subtypes.avtp_audio.format = 2;
+ pDescriptor->stream_formats[0].subtypes.avtp_audio.bit_depth = 32;
+ pDescriptor->stream_formats[0].subtypes.avtp_audio.channels_per_frame = 2;
+ pDescriptor->stream_formats[0].subtypes.avtp_audio.samples_per_frame = 6;
+ }
+ else if (strcmp(pConfig->stream->map_fn,"openavbMapUncmpAudioInitialize") == 0)
+ {
+ pDescriptor->stream_formats[0].v = 0;
+ pDescriptor->stream_formats[0].subtype = OPENAVB_AEM_STREAM_FORMAT_61883_IIDC_SUBTYPE;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_iidc.sf = 1;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.fmt = OPENAVB_AEM_STREAM_FORMAT_FMT_61883_6;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.fdf_evt = OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_AM824;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.fdf_sfc = 0x02;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.dbs = 0x08;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.b = 0x00;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.nb = 0x01;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.label_iec_60958_cnt = 0;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.label_mbla_cnt = 8;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.label_midi_cnt = 0;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_6_am824.label_smptecnt = 0;
+ }
+ else if (strcmp(pConfig->stream->map_fn,"openavbMapCtrlInitialize") == 0)
+ {
+ pDescriptor->stream_formats[0].v = 0;
+ pDescriptor->stream_formats[0].subtype = OPENAVB_AEM_STREAM_FORMAT_AVTP_CONTROL_SUBTYPE;
+ pDescriptor->stream_formats[0].subtypes.avtp_control.protocol_type = 3;
+ pDescriptor->stream_formats[0].subtypes.avtp_control.format_id[0] = 0x90;
+ pDescriptor->stream_formats[0].subtypes.avtp_control.format_id[1] = 0xe0;
+ pDescriptor->stream_formats[0].subtypes.avtp_control.format_id[2] = 0xf0;
+ pDescriptor->stream_formats[0].subtypes.avtp_control.format_id[3] = 0x00;
+ pDescriptor->stream_formats[0].subtypes.avtp_control.format_id[4] = 0x00;
+ pDescriptor->stream_formats[0].subtypes.avtp_control.format_id[5] = 0x00;
+ }
+ else if (strcmp(pConfig->stream->map_fn,"openavbMapMpeg2tsInitialize") == 0)
+ {
+ pDescriptor->stream_formats[0].v = 0;
+ pDescriptor->stream_formats[0].subtype = OPENAVB_AEM_STREAM_FORMAT_61883_IIDC_SUBTYPE;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_4.sf = 1;
+ pDescriptor->stream_formats[0].subtypes.iec_61883_4.fmt = OPENAVB_AEM_STREAM_FORMAT_FMT_61883_4;
+ }
+ else if (strcmp(pConfig->stream->map_fn,"openavbMapMjpegInitialize") == 0 || strcmp(pConfig->stream->map_fn,"openavbMapH264Initialize") == 0)
+ {
+ pDescriptor->stream_formats[0].v = 0;
+ pDescriptor->stream_formats[0].subtype = OPENAVB_AEM_STREAM_FORMAT_AVTP_VIDEO_SUBTYPE;
+ if (strcmp(pConfig->stream->map_fn,"openavbMapMjpegInitialize") == 0)
+ {
+ pDescriptor->stream_formats[0].subtypes.avtp_video.format = OPENAVB_AEM_RTP_PAYLOAD_SUBTYPE_RTP_MJPEG;
+ }
+ else
+ {
+ pDescriptor->stream_formats[0].subtypes.avtp_video.format = OPENAVB_AEM_RTP_PAYLOAD_SUBTYPE_RTP_H264;
+ }
+ }
+ pDescriptor->number_of_formats = 1;
+
+ // Make the current format the first format in the list.
+ memcpy(&(pDescriptor->current_format), &(pDescriptor->stream_formats[0]), sizeof(openavb_aem_stream_format_t));
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorStreamInputInitialize(openavb_aem_descriptor_stream_io_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ (void) nConfigIdx;
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // Specify a name.
+ sprintf((char *)(pDescriptor->object_name), "Stream Input %u", pDescriptor->descriptor_index);
+
+ // Specify the stream flags.
+ // The stream configuration is ignored for Listeners, as Listeners will accept both Class A and Class B.
+ pDescriptor->stream_flags |= ( OPENAVB_AEM_STREAM_FLAG_CLASS_A | OPENAVB_AEM_STREAM_FLAG_CLASS_B );
+
+ // Specify the stream format information.
+ fillInStreamFormat(pDescriptor, pConfig);
+
+ // Save the stream configuration pointer.
+ pDescriptor->stream = pConfig->stream;
+
+ return TRUE;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorStreamOutputInitialize(openavb_aem_descriptor_stream_io_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig)
+{
+ (void) nConfigIdx;
+ if (!pDescriptor || !pConfig) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // Specify a name.
+ sprintf((char *)(pDescriptor->object_name), "Stream Output %u", pDescriptor->descriptor_index);
+
+ // Specify the stream flags.
+ if (pConfig->stream->sr_class == SR_CLASS_A) { pDescriptor->stream_flags |= OPENAVB_AEM_STREAM_FLAG_CLASS_A; }
+ if (pConfig->stream->sr_class == SR_CLASS_B) { pDescriptor->stream_flags |= OPENAVB_AEM_STREAM_FLAG_CLASS_B; }
+
+ // Specify the stream format information.
+ fillInStreamFormat(pDescriptor, pConfig);
+
+ // Save the stream configuration pointer.
+ pDescriptor->stream = pConfig->stream;
+
+ return TRUE;
+}
+
+
+////////////////////////////////
+// Public functions for internal
+// AVDECC use (not exported)
+////////////////////////////////
+
+void openavbAemStreamFormatToBuf(openavb_aem_stream_format_t *pSrc, U8 *pBuf)
+{
+ U8 *pDst = pBuf;
+
+ // Tightly bound to caller not safety checks needed.
+
+ memset(pBuf, 0, 8);
+
+ if (pSrc->v == 0) {
+ BIT_D2BHTONB(pDst, pSrc->v, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtype, 0, 1);
+ switch (pSrc->subtype) {
+ case OPENAVB_AEM_STREAM_FORMAT_61883_IIDC_SUBTYPE:
+ {
+ if (pSrc->subtypes.iec_61883_iidc.sf == OPENAVB_AEM_STREAM_FORMAT_SF_IIDC) {
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iidc.sf, 7, 1);
+ pDst += 3;
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iidc.iidc_format);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iidc.iidc_mode);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iidc.iidc_rate);
+ }
+ else {
+ if (pSrc->subtypes.iec_61883.fmt == OPENAVB_AEM_STREAM_FORMAT_FMT_61883_4) {
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_4.sf, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_4.fmt, 1, 1);
+ }
+ else if (pSrc->subtypes.iec_61883.fmt == OPENAVB_AEM_STREAM_FORMAT_FMT_61883_6) {
+ if (pSrc->subtypes.iec_61883_6.fdf_evt == OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_32BITS) {
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_32bit.sf, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_32bit.fmt, 1, 1);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_32bit.fdf_evt, 3, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_32bit.fdf_sfc, 0, 1);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_32bit.dbs);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_32bit.b, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_32bit.nb, 6, 1);
+ }
+ else if (pSrc->subtypes.iec_61883_6.fdf_evt == OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_FLOAT) {
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_float.sf, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_float.fmt, 1, 1);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_float.fdf_evt, 3, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_float.fdf_sfc, 0, 1);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_float.dbs);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_float.b, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_float.nb, 6, 1);
+ }
+ else if (pSrc->subtypes.iec_61883_6.fdf_evt == OPENAVB_AEM_STREAM_FORMAT_FDF_EVT_61883_6_AM824) {
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.sf, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.fmt, 1, 1);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.fdf_evt, 3, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.fdf_sfc, 0, 1);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.dbs);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.b, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.nb, 6, 1);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.label_iec_60958_cnt);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.label_mbla_cnt);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.label_midi_cnt, 4, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_6_am824.label_smptecnt, 0, 1);
+ }
+ }
+ else if (pSrc->subtypes.iec_61883.fmt == OPENAVB_AEM_STREAM_FORMAT_FMT_61883_8) {
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_8.sf, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_8.fmt, 1, 1);
+ pDst += 3;
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_8.video_mode);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_8.compress_mode);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.iec_61883_8.color_space);
+ }
+ }
+ }
+
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_MMA_SUBTYPE:
+ // Nothing to do
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_AVTP_AUDIO_SUBTYPE:
+ BIT_D2BHTONB(pDst, pSrc->subtypes.avtp_audio.nominal_sample_rate, 0, 1);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.avtp_audio.format);
+ OCT_D2BHTONB(pDst, pSrc->subtypes.avtp_audio.bit_depth);
+ BIT_D2BHTONL(pDst, pSrc->subtypes.avtp_audio.channels_per_frame, 22, 0);
+ BIT_D2BHTONL(pDst, pSrc->subtypes.avtp_audio.samples_per_frame, 12, 4);
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_AVTP_VIDEO_SUBTYPE:
+ OCT_D2BHTONB(pDst, pSrc->subtypes.avtp_video.format);
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_AVTP_CONTROL_SUBTYPE:
+ BIT_D2BHTONB(pDst, pSrc->subtypes.avtp_control.protocol_type, 4, 1);
+ OCT_D2BMEMCP(pDst, pSrc->subtypes.avtp_control.format_id);
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_VENDOR_SUBTYPE:
+ pDst++;
+ OCT_D2BMEMCP(pDst, pSrc->subtypes.vendor.format_id);
+ break;
+ case OPENAVB_AEM_STREAM_FORMAT_EXPERIMENTAL_SUBTYPE:
+ // Nothing to do
+ break;
+ }
+ }
+ else {
+ BIT_D2BHTONB(pDst, pSrc->v, 7, 1);
+ pDst++;
+ OCT_D2BMEMCP(pDst, pSrc->subtypes.vendor_specific.format_id);
+ }
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_stream_io.h b/lib/avtp_pipeline/aem/openavb_descriptor_stream_io.h
new file mode 100644
index 00000000..b4edc9c4
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_stream_io.h
@@ -0,0 +1,47 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Stream IO Descriptor
+ * MODULE SUMMARY : Interface for the Stream IO Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_STREAM_IO_H
+#define OPENAVB_DESCRIPTOR_STREAM_IO_H 1
+
+#include "openavb_descriptor_stream_io_pub.h"
+
+#define OPENAVB_DESCRIPTOR_STREAM_IO_BASE_LENGTH 132
+#define OPENAVB_DESCRIPTOR_STREAM_IO_FORMAT_LENGTH 8
+
+#endif // OPENAVB_DESCRIPTOR_STREAM_IO_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_stream_io_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_stream_io_pub.h
new file mode 100644
index 00000000..91fc384f
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_stream_io_pub.h
@@ -0,0 +1,111 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Stream IO Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Stream IO Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_STREAM_IO_PUB_H
+#define OPENAVB_DESCRIPTOR_STREAM_IO_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+#include "openavb_tl_pub.h"
+#include "openavb_avdecc_read_ini_pub.h"
+
+#define OPENAVB_DESCRIPTOR_STREAM_IO_MAX_FORMATS (47)
+
+// Possible statuses of the fast connect support for the Listener
+typedef enum {
+ OPENAVB_FAST_CONNECT_STATUS_UNKNOWN = 0, // Still need to determine if something is available
+ OPENAVB_FAST_CONNECT_STATUS_NOT_AVAILABLE, // No fast connects available for the Listener, or is a Talker
+ OPENAVB_FAST_CONNECT_STATUS_IN_PROGRESS, // Attempting fast connect
+ OPENAVB_FAST_CONNECT_STATUS_TIMED_OUT, // Talker did not respond to fast connect attempts
+ OPENAVB_FAST_CONNECT_STATUS_SUCCEEDED, // Fast connect was successful; don't need to try again
+} openavb_fast_connect_status_t;
+
+// STREAM IO Descriptor IEEE Std 1722.1-2013 clause 7.2.6
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type;
+ U16 descriptor_index;
+ U8 object_name[OPENAVB_AEM_STRLEN_MAX];
+ openavb_aem_string_ref_t localized_description;
+ U16 clock_domain_index;
+ U16 stream_flags;
+ openavb_aem_stream_format_t current_format;
+ U16 formats_offset;
+ U16 number_of_formats;
+ U8 backup_talker_entity_id_0[8];
+ U16 backup_talker_unique_id_0;
+ U8 backup_talker_entity_id_1[8];
+ U16 backup_talker_unique_id_1;
+ U8 backup_talker_entity_id_2[8];
+ U16 backup_talker_unique_id_2;
+ U8 backedup_talker_entity_id[8];
+ U16 backedup_talker_unique_id;
+ U16 avb_interface_index;
+ U32 buffer_length;
+ openavb_aem_stream_format_t stream_formats[OPENAVB_DESCRIPTOR_STREAM_IO_MAX_FORMATS];
+
+ // Current status of the fast connect support for the Listener.
+ openavb_fast_connect_status_t fast_connect_status;
+ U8 fast_connect_talker_entity_id[8];
+ struct timespec fast_connect_start_time;
+
+ // OPENAVB_ACMP_FLAG values from CONNECT_TX_RESPONSE or CONNECT_RX_RESPONSE.
+ U16 acmp_flags;
+
+ // Streaming values for GET_STREAM_INFO from CONNECT_TX_RESPONSE or CONNECT_RX_RESPONSE.
+ // These values are currently only used for the Listener, as the Talker can get them from it's current configuration.
+ U8 acmp_stream_id[8];
+ U8 acmp_dest_addr[6];
+ U16 acmp_stream_vlan_id;
+
+ // Also save a pointer to the supplied stream information.
+ const openavb_tl_data_cfg_t *stream;
+
+} openavb_aem_descriptor_stream_io_t;
+
+openavb_aem_descriptor_stream_io_t *openavbAemDescriptorStreamInputNew(void);
+openavb_aem_descriptor_stream_io_t *openavbAemDescriptorStreamOutputNew(void);
+
+bool openavbAemDescriptorStreamInputInitialize(openavb_aem_descriptor_stream_io_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+bool openavbAemDescriptorStreamOutputInitialize(openavb_aem_descriptor_stream_io_t *pDescriptor, U16 nConfigIdx, const openavb_avdecc_configuration_cfg_t *pConfig);
+
+void openavbAemStreamFormatToBuf(openavb_aem_stream_format_t *pSrc, U8 *pBuf);
+
+#endif // OPENAVB_DESCRIPTOR_STREAM_IO_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io.c b/lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io.c
new file mode 100644
index 00000000..007a11cb
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io.c
@@ -0,0 +1,207 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Stream Port IO Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Stream Port IO IEEE Std 1722.1-2013 clause 7.2.13
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_stream_port_io.h"
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorStreamPortIOToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_port_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_STREAM_PORT_IO_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_stream_port_io_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BHTONS(pDst, pSrc->clock_domain_index);
+ OCT_D2BHTONS(pDst, pSrc->port_flags);
+ OCT_D2BHTONS(pDst, pSrc->number_of_controls);
+ OCT_D2BHTONS(pDst, pSrc->base_control);
+ OCT_D2BHTONS(pDst, pSrc->number_of_clusters);
+ OCT_D2BHTONS(pDst, pSrc->base_cluster);
+ OCT_D2BHTONS(pDst, pSrc->number_of_maps);
+ OCT_D2BHTONS(pDst, pSrc->base_map);
+
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorStreamPortIOFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_port_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_STREAM_PORT_IO_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_stream_port_io_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DNTOHS(pDst->clock_domain_index, pSrc);
+ OCT_B2DNTOHS(pDst->port_flags, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_controls, pSrc);
+ OCT_B2DNTOHS(pDst->base_control, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_clusters, pSrc);
+ OCT_B2DNTOHS(pDst->base_cluster, pSrc);
+ OCT_B2DNTOHS(pDst->number_of_maps, pSrc);
+ OCT_B2DNTOHS(pDst->base_map, pSrc);
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorStreamPortIOUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_port_io_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_stream_port_io_t *openavbAemDescriptorStreamPortInputNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_port_io_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_stream_port_io_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = FALSE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorStreamPortIOToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorStreamPortIOFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorStreamPortIOUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_STREAM_PORT_INPUT;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT openavb_aem_descriptor_stream_port_io_t *openavbAemDescriptorStreamPortOutputNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_stream_port_io_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_stream_port_io_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = FALSE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorStreamPortIOToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorStreamPortIOFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorStreamPortIOUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_STREAM_PORT_OUTPUT;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io.h b/lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io.h
new file mode 100644
index 00000000..fe331476
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Stream Port IO Descriptor
+ * MODULE SUMMARY : Interface for the Stream Port IO Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_STREAM_PORT_IO_H
+#define OPENAVB_DESCRIPTOR_STREAM_PORT_IO_H 1
+
+#include "openavb_descriptor_stream_port_io_pub.h"
+
+#define OPENAVB_DESCRIPTOR_STREAM_PORT_IO_BASE_LENGTH 20
+
+#endif // OPENAVB_DESCRIPTOR_STREAM_PORT_IO_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io_pub.h
new file mode 100644
index 00000000..000c058d
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_stream_port_io_pub.h
@@ -0,0 +1,65 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Stream Port IO Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Stream Port IO Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_STREAM_PORT_IO_PUB_H
+#define OPENAVB_DESCRIPTOR_STREAM_PORT_IO_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+// STREAM PORT IO Descriptor IEEE Std 1722.1-2013 clause 7.2.13
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type;
+ U16 descriptor_index;
+ U16 clock_domain_index;
+ U16 port_flags;
+ U16 number_of_controls;
+ U16 base_control;
+ U16 number_of_clusters;
+ U16 base_cluster;
+ U16 number_of_maps;
+ U16 base_map;
+} openavb_aem_descriptor_stream_port_io_t;
+
+openavb_aem_descriptor_stream_port_io_t *openavbAemDescriptorStreamPortInputNew(void);
+openavb_aem_descriptor_stream_port_io_t *openavbAemDescriptorStreamPortOutputNew(void);
+
+#endif // OPENAVB_DESCRIPTOR_STREAM_PORT_IO_PUB_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_strings.c b/lib/avtp_pipeline/aem/openavb_descriptor_strings.c
new file mode 100644
index 00000000..dc599622
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_strings.c
@@ -0,0 +1,193 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Strings Descriptor
+ * MODULE SUMMARY : Implements the AVDECC Strings IEEE Std 1722.1-2013 clause 7.2.12
+ ******************************************************************
+ */
+
+#include <stdlib.h>
+
+#define AVB_LOG_COMPONENT "AEM"
+#include "openavb_log.h"
+
+#include "openavb_rawsock.h"
+#include "openavb_aem.h"
+#include "openavb_descriptor_strings.h"
+
+
+////////////////////////////////
+// Private (internal) functions
+////////////////////////////////
+openavbRC openavbAemDescriptorStringsToBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf, U16 *descriptorSize)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_strings_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf || !descriptorSize) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_STRINGS_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ *descriptorSize = 0;
+
+ openavb_aem_descriptor_strings_t *pSrc = pDescriptor;
+ U8 *pDst = pBuf;
+
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ memcpy(pDst, pSrc->string, sizeof(pSrc->string));
+ pDst += sizeof(pSrc->string);
+ *descriptorSize = pDst - pBuf;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorStringsFromBuf(void *pVoidDescriptor, U16 bufLength, U8 *pBuf)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_strings_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor || !pBuf) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ if (bufLength < OPENAVB_DESCRIPTOR_STRINGS_BASE_LENGTH) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_BUFFER_TOO_SMALL), AVB_TRACE_AEM);
+ }
+
+ U8 *pSrc = pBuf;
+ openavb_aem_descriptor_strings_t *pDst = pDescriptor;
+
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ memcpy(pDst->string, pSrc, sizeof(pDst->string));
+ pSrc += sizeof(pDst->string);
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+openavbRC openavbAemDescriptorStringsUpdate(void *pVoidDescriptor)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_strings_t *pDescriptor = pVoidDescriptor;
+
+ if (!pDescriptor) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT), AVB_TRACE_AEM);
+ }
+
+ // AVDECC_TODO - Any updates needed?
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_AEM);
+}
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT openavb_aem_descriptor_strings_t *openavbAemDescriptorStringsNew()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ openavb_aem_descriptor_strings_t *pDescriptor;
+
+ pDescriptor = malloc(sizeof(*pDescriptor));
+
+ if (!pDescriptor) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+ memset(pDescriptor, 0, sizeof(*pDescriptor));
+
+ pDescriptor->descriptorPvtPtr = malloc(sizeof(*pDescriptor->descriptorPvtPtr));
+ if (!pDescriptor->descriptorPvtPtr) {
+ free(pDescriptor);
+ pDescriptor = NULL;
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_OUT_OF_MEMORY));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ pDescriptor->descriptorPvtPtr->size = sizeof(openavb_aem_descriptor_strings_t);
+ pDescriptor->descriptorPvtPtr->bTopLevel = FALSE;
+ pDescriptor->descriptorPvtPtr->toBuf = openavbAemDescriptorStringsToBuf;
+ pDescriptor->descriptorPvtPtr->fromBuf = openavbAemDescriptorStringsFromBuf;
+ pDescriptor->descriptorPvtPtr->update = openavbAemDescriptorStringsUpdate;
+
+ pDescriptor->descriptor_type = OPENAVB_AEM_DESCRIPTOR_STRINGS;
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return pDescriptor;
+}
+
+extern DLL_EXPORT const char * openavbAemDescriptorStringsGet_string(openavb_aem_descriptor_strings_t *pDescriptor, U8 index)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || index >= OPENAVB_AEM_NUM_DESCRIPTOR_STRINGS) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return NULL;
+ }
+
+ const char *ret = (const char *) (pDescriptor->string[index]);
+ if (*ret == '\0') {
+ /* The string is empty. */
+ ret = NULL;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return ret;
+}
+
+extern DLL_EXPORT bool openavbAemDescriptorStringsSet_string(openavb_aem_descriptor_strings_t *pDescriptor, const char *pString, U8 index)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AEM);
+
+ if (!pDescriptor || !pString || index >= OPENAVB_AEM_NUM_DESCRIPTOR_STRINGS) {
+ AVB_RC_LOG(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVB_RC_INVALID_ARGUMENT));
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return FALSE;
+ }
+
+ openavbAemSetString(pDescriptor->string[index], pString);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AEM);
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_strings.h b/lib/avtp_pipeline/aem/openavb_descriptor_strings.h
new file mode 100644
index 00000000..014cb2ac
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_strings.h
@@ -0,0 +1,46 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Strings Descriptor
+ * MODULE SUMMARY : Interface for the Strings Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_STRINGS_H
+#define OPENAVB_DESCRIPTOR_STRINGS_H 1
+
+#include "openavb_descriptor_strings_pub.h"
+
+#define OPENAVB_DESCRIPTOR_STRINGS_BASE_LENGTH 452
+
+#endif // OPENAVB_DESCRIPTOR_STRINGS_H
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_strings_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_strings_pub.h
new file mode 100644
index 00000000..57218c1b
--- /dev/null
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_strings_pub.h
@@ -0,0 +1,65 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+ ******************************************************************
+ * MODULE : AEM - AVDECC Strings Descriptor Public Interface
+ * MODULE SUMMARY : Public Interface for the Strings Descriptor
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_DESCRIPTOR_STRINGS_PUB_H
+#define OPENAVB_DESCRIPTOR_STRINGS_PUB_H 1
+
+#include "openavb_types_pub.h"
+#include "openavb_aem_types_pub.h"
+#include "openavb_aem_pub.h"
+
+#define OPENAVB_AEM_NUM_DESCRIPTOR_STRINGS (7)
+
+// STRINGS Descriptor IEEE Std 1722.1-2013 clause 7.2.12
+typedef struct {
+ openavb_descriptor_pvt_ptr_t descriptorPvtPtr;
+
+ U16 descriptor_type; // Set internally
+ U16 descriptor_index; // Set internally
+ U8 string[OPENAVB_AEM_NUM_DESCRIPTOR_STRINGS][OPENAVB_AEM_STRLEN_MAX];
+} openavb_aem_descriptor_strings_t;
+
+openavb_aem_descriptor_strings_t *openavbAemDescriptorStringsNew(void);
+
+// Returns the descriptor string at the specified index, or NULL if not specified.
+const char * openavbAemDescriptorStringsGet_string(openavb_aem_descriptor_strings_t *pDescriptor, U8 index);
+
+// Set a descriptor string at the specified index.
+bool openavbAemDescriptorStringsSet_string(openavb_aem_descriptor_strings_t *pDescriptor, const char *pString, U8 index);
+
+#endif // OPENAVB_DESCRIPTOR_STRINGS_PUB_H