diff options
Diffstat (limited to 'lib/avtp_pipeline/avdecc')
-rw-r--r-- | lib/avtp_pipeline/avdecc/CMakeLists.txt | 12 | ||||
-rw-r--r-- | lib/avtp_pipeline/avdecc/avdecc.ini | 82 | ||||
-rw-r--r-- | lib/avtp_pipeline/avdecc/openavb_avdecc.c | 509 | ||||
-rw-r--r-- | lib/avtp_pipeline/avdecc/openavb_avdecc.h | 210 | ||||
-rw-r--r-- | lib/avtp_pipeline/avdecc/openavb_avdecc_pipeline_interaction_pub.h | 71 | ||||
-rw-r--r-- | lib/avtp_pipeline/avdecc/openavb_avdecc_pub.h | 145 | ||||
-rw-r--r-- | lib/avtp_pipeline/avdecc/openavb_avdecc_read_ini_pub.h | 197 | ||||
-rwxr-xr-x | lib/avtp_pipeline/avdecc/shutdown_openavb_avdecc.sh | 18 |
8 files changed, 1244 insertions, 0 deletions
diff --git a/lib/avtp_pipeline/avdecc/CMakeLists.txt b/lib/avtp_pipeline/avdecc/CMakeLists.txt new file mode 100644 index 00000000..bccfc799 --- /dev/null +++ b/lib/avtp_pipeline/avdecc/CMakeLists.txt @@ -0,0 +1,12 @@ +SET (SRC_FILES ${SRC_FILES}
+ ${AVB_SRC_DIR}/avdecc/openavb_avdecc.c
+ ${AVB_OSAL_DIR}/avdecc/openavb_avdecc_osal.c
+ ${AVB_OSAL_DIR}/avdecc/openavb_avdecc_cfg.c
+ ${AVB_OSAL_DIR}/avdecc/openavb_avdecc_read_ini.c
+ ${AVB_OSAL_DIR}/avdecc/openavb_avdecc_pipeline_interaction.c
+ ${AVB_OSAL_DIR}/avdecc/openavb_avdecc_save_state.c
+ ${AVB_OSAL_DIR}/openavb_osal_avdecc.c
+ ${AVB_OSAL_DIR}/openavb_grandmaster_osal.c
+ ${AVB_SRC_DIR}/avdecc_msg/openavb_avdecc_msg_server.c
+ PARENT_SCOPE
+)
diff --git a/lib/avtp_pipeline/avdecc/avdecc.ini b/lib/avtp_pipeline/avdecc/avdecc.ini new file mode 100644 index 00000000..d4b4bb60 --- /dev/null +++ b/lib/avtp_pipeline/avdecc/avdecc.ini @@ -0,0 +1,82 @@ +[network] + +# Interface name on which to use AVDECC +#ifname=eth2 + + +[vlan] + +# VLAN ID to use for AVDECC traffic. +# If VLAN support is not desired, comment out this value. +#vlanID = 2 + +# VLAN Priority to use for AVDECC traffic. +# If VLAN support is not desired, comment out this value. +#vlanPCP = 3 + + +[fast_connect] + +# If enable (set to 1), the fast_connect option will cause AVDECC-initiated +# connections to be saved to an avdecc_save.ini file. When the AVDECC client +# is restarted after an unexpected shutdown, AVDECC Fast Connect will be +# attempted. +# +# The default value is 0, which disabled the AVDECC Fast Connect and Saved +# State support. +fast_connect = 1 + + +[discovery] + +# The valid_time is the amount of time (in seconds) the device will be +# considered valid by other devices on the network after the last received +# discovery packet. A smaller valid_time value will cause the device to be +# recognized as disappearing more quickly if it is unplugged from the network +# (or stops working), but will result in more background network traffic. +# +# Valid values are 2 to 62 seconds, with only even numbers being allowed. +# The default value is 62 seconds. +valid_time = 20 + + +[descriptor_entity] + +# ID value to be combined with the interface MAC Address to generate the +# entity_id. For example, a device with MAC Address 00:11:22:33:44:55 and +# avdeccId of 0x9876 would be assigned an entity_id of +# 00-01-02-98-76-33-44-55. +# The default ID value is 0xfffe. +#avdeccId = 0xfffe + +# The entity_model_id is a unique vendor-specific 64-bit number used to +# identify an AVDECC data model. +entity_model_id = 0x0000000000000000 + +# The entity_name is a UTF-8 string defining the device's name +entity_name = "ACME Audio Processor" + +# The firmware_version is a UTF-8 string defining the device's firmware +# version +firmware_version = "0.0.0.1" + +# The group_name is a UTF-8 string defining the name of the device's group +group_name = "Acme Processors" + +# The serial_number is a UTF-8 string defining the device's serial number +serial_number = "12345" + + +[localization] + +# A UTF-8 string defining the localization language to use for localized +# strings. The format is "language code - region code". +# Refer to IEEE Std 1722.1-2013 clause 7.2.11 for more details. +locale_identifier = "en" + +# The vendor_name is a localized UTF-8 string defining the vendor's name +vendor_name = "Acme Audio Inc." + +# The model_name is a localized UTF-8 string defining the device's model name +model_name = "Acme 2400X" + diff --git a/lib/avtp_pipeline/avdecc/openavb_avdecc.c b/lib/avtp_pipeline/avdecc/openavb_avdecc.c new file mode 100644 index 00000000..9c82a648 --- /dev/null +++ b/lib/avtp_pipeline/avdecc/openavb_avdecc.c @@ -0,0 +1,509 @@ +/*************************************************************************************************************
+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 : AVDECC - Top level 1722.1 implementation
+ * MODULE SUMMARY : Top level 1722.1 implementation
+ ******************************************************************
+ */
+
+#include "openavb_rawsock.h"
+#include "openavb_avtp.h"
+
+#define AVB_LOG_COMPONENT "AVDECC"
+#include "openavb_log.h"
+
+#include "openavb_aem.h"
+#include "openavb_adp.h"
+#include "openavb_acmp.h"
+#include "openavb_aecp.h"
+
+#include "openavb_endpoint.h"
+
+#define ADDR_PTR(A) (U8*)(&((A)->ether_addr_octet))
+
+openavb_avdecc_cfg_t gAvdeccCfg;
+openavb_tl_data_cfg_t * streamList = NULL;
+openavb_aem_descriptor_configuration_t *pConfiguration = NULL;
+
+static openavb_avdecc_configuration_cfg_t *pFirstConfigurationCfg = NULL;
+static U8 talker_stream_sources = 0;
+static U8 listener_stream_sources = 0;
+static bool first_talker = 1;
+static bool first_listener = 1;
+
+bool openavbAvdeccStartAdp()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
+
+ openavbRC rc = openavbAdpStart();
+ if (IS_OPENAVB_FAILURE(rc)) {
+ openavbAdpStop();
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return TRUE;
+}
+
+void openavbAvdeccStopAdp()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
+ openavbAdpStop();
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+}
+
+bool openavbAvdeccStartCmp()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
+
+ openavbRC rc = openavbAcmpStart();
+ if (IS_OPENAVB_FAILURE(rc)) {
+ openavbAcmpStop();
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return TRUE;
+}
+
+void openavbAvdeccStopCmp()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
+ openavbAcmpStop();
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+}
+
+bool openavbAvdeccStartEcp()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
+
+ openavbRC rc = openavbAecpStart();
+ if (IS_OPENAVB_FAILURE(rc)) {
+ openavbAecpStop();
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return TRUE;
+}
+
+void openavbAvdeccStopEcp()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
+ openavbAecpStop();
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+}
+
+void openavbAvdeccFindMacAddr(void)
+{
+ // Open a rawsock may be the easiest cross platform way to get the MAC address.
+ void *txSock = openavbRawsockOpen(gAvdeccCfg.ifname, FALSE, TRUE, ETHERTYPE_AVTP, 100, 1);
+ if (txSock) {
+ openavbRawsockGetAddr(txSock, gAvdeccCfg.ifmac);
+ openavbRawsockClose(txSock);
+ txSock = NULL;
+ }
+}
+
+bool openavbAvdeccAddConfiguration(openavb_tl_data_cfg_t *stream)
+{
+ bool first_time = 0;
+ // Create a new config to hold the configuration information.
+ openavb_avdecc_configuration_cfg_t *pCfg = malloc(sizeof(openavb_avdecc_configuration_cfg_t));
+ if (!pCfg) {
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ memset(pCfg, 0, sizeof(openavb_avdecc_configuration_cfg_t));
+
+ // Add a pointer to the supplied stream information.
+ pCfg->stream = stream;
+
+ // Add the new config to the end of the list of configurations.
+ if (pFirstConfigurationCfg == NULL) {
+ pFirstConfigurationCfg = pCfg;
+ } else {
+ openavb_avdecc_configuration_cfg_t *pLast = pFirstConfigurationCfg;
+ while (pLast->next != NULL) {
+ pLast = pLast->next;
+ }
+ pLast->next = pCfg;
+ }
+
+ // Create a new configuration.
+ U16 nConfigIdx = 0;
+ if (pConfiguration == NULL)
+ {
+ first_time = 1;
+ pConfiguration = openavbAemDescriptorConfigurationNew();
+ if (!openavbAemAddDescriptor(pConfiguration, OPENAVB_AEM_DESCRIPTOR_INVALID, &nConfigIdx)) {
+ AVB_LOG_ERROR("Error adding AVDECC configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ }
+ // Specify a default user-friendly name to use.
+ // AVDECC_TODO - Allow the user to specify a friendly name, or use the name if the .INI file.
+ if (pCfg->friendly_name[0] == '\0') {
+ snprintf((char *) pCfg->friendly_name, OPENAVB_AEM_STRLEN_MAX, "Configuration %u", nConfigIdx);
+ }
+
+ // Save the stream information in the configuration.
+ if (!openavbAemDescriptorConfigurationInitialize(pConfiguration, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error initializing AVDECC configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ // Add the descriptors needed for both talkers and listeners.
+ U16 nResultIdx;
+ if (first_time)
+ {
+ openavb_aem_descriptor_avb_interface_t *pNewAvbInterface = openavbAemDescriptorAvbInterfaceNew();
+ if (!openavbAemAddDescriptor(pNewAvbInterface, nConfigIdx, &nResultIdx) ||
+ !openavbAemDescriptorAvbInterfaceInitialize(pNewAvbInterface, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error adding AVDECC AVB Interface to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ openavb_aem_descriptor_audio_unit_t *pNewAudioUnit = openavbAemDescriptorAudioUnitNew();
+ if (!openavbAemAddDescriptor(pNewAudioUnit, nConfigIdx, &nResultIdx) ||
+ !openavbAemDescriptorAudioUnitInitialize(pNewAudioUnit, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error adding AVDECC Audio Unit to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ }
+ else
+ {
+ openavb_aem_descriptor_audio_unit_t *pAudioUnitDescriptor =
+ (openavb_aem_descriptor_audio_unit_t *) openavbAemGetDescriptor(nConfigIdx, OPENAVB_AEM_DESCRIPTOR_AUDIO_UNIT, 0);
+ if (pAudioUnitDescriptor != NULL)
+ {
+ if (!openavbAemDescriptorAudioUnitInitialize(pAudioUnitDescriptor, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error updating AVDECC Audio Unit to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ }
+ else
+ {
+ AVB_LOG_ERROR("Error getting AVDECC Audio Unit descriptor");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ }
+
+ // AVDECC_TODO: Add other descriptors as needed. Future options include:
+ // VIDEO_UNIT
+ // SENSOR_UNIT
+ // CONTROL
+
+ if (stream->role == AVB_ROLE_TALKER) {
+ gAvdeccCfg.bTalker = TRUE;
+
+ openavb_aem_descriptor_stream_io_t *pNewStreamOutput = openavbAemDescriptorStreamOutputNew();
+ if (!openavbAemAddDescriptor(pNewStreamOutput, nConfigIdx, &nResultIdx) ||
+ !openavbAemDescriptorStreamOutputInitialize(pNewStreamOutput, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error adding AVDECC Stream Output to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ if (first_talker)
+ {
+ first_talker = 0;
+ openavb_aem_descriptor_clock_source_t *pNewClockSource = openavbAemDescriptorClockSourceNew();
+ if (!openavbAemAddDescriptor(pNewClockSource, nConfigIdx, &nResultIdx) ||
+ !openavbAemDescriptorClockSourceInitialize(pNewClockSource, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error adding AVDECC Clock Source to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ openavb_aem_descriptor_clock_domain_t *pNewClockDomain = openavbAemDescriptorClockDomainNew();
+ if (!openavbAemAddDescriptor(pNewClockDomain, nConfigIdx, &nResultIdx) ||
+ !openavbAemDescriptorClockDomainInitialize(pNewClockDomain, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error adding AVDECC Clock Domain to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ }
+
+ // AVDECC_TODO: Add other descriptors as needed. Future options include:
+ // JACK_INPUT
+ talker_stream_sources++;
+
+ // Add the class specific to the talker.
+ if (stream->sr_class == SR_CLASS_A) { gAvdeccCfg.bClassASupported = TRUE; }
+ if (stream->sr_class == SR_CLASS_B) { gAvdeccCfg.bClassBSupported = TRUE; }
+
+ AVB_LOG_DEBUG("AVDECC talker configuration added");
+ }
+ if (stream->role == AVB_ROLE_LISTENER) {
+ gAvdeccCfg.bListener = TRUE;
+
+ openavb_aem_descriptor_stream_io_t *pNewStreamInput = openavbAemDescriptorStreamInputNew();
+ if (!openavbAemAddDescriptor(pNewStreamInput, nConfigIdx, &nResultIdx) ||
+ !openavbAemDescriptorStreamInputInitialize(pNewStreamInput, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error adding AVDECC Stream Input to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ if (first_listener)
+ {
+ openavb_aem_descriptor_clock_source_t *pNewClockSource = openavbAemDescriptorClockSourceNew();
+ if (!openavbAemAddDescriptor(pNewClockSource, nConfigIdx, &nResultIdx) ||
+ !openavbAemDescriptorClockSourceInitialize(pNewClockSource, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error adding AVDECC Clock Source to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ openavb_aem_descriptor_clock_domain_t *pNewClockDomain = openavbAemDescriptorClockDomainNew();
+ if (!openavbAemAddDescriptor(pNewClockDomain, nConfigIdx, &nResultIdx) ||
+ !openavbAemDescriptorClockDomainInitialize(pNewClockDomain, nConfigIdx, pCfg)) {
+ AVB_LOG_ERROR("Error adding AVDECC Clock Domain to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ }
+
+ // AVDECC_TODO: Add other descriptors as needed. Future options include:
+ // JACK_OUTPUT
+ listener_stream_sources++;
+
+ // Listeners support both Class A and Class B.
+ gAvdeccCfg.bClassASupported = TRUE;
+ gAvdeccCfg.bClassBSupported = TRUE;
+
+ AVB_LOG_DEBUG("AVDECC listener configuration added");
+ }
+
+ if (first_time)
+ {
+ // Add the localized strings to the configuration.
+ if (!openavbAemDescriptorLocaleStringsHandlerAddToConfiguration(gAvdeccCfg.pAemDescriptorLocaleStringsHandler, nConfigIdx)) {
+ AVB_LOG_ERROR("Error adding AVDECC locale strings to configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+////////////////////////////////
+// Public functions
+////////////////////////////////
+extern DLL_EXPORT bool openavbAvdeccInitialize()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
+
+ gAvdeccCfg.pDescriptorEntity = openavbAemDescriptorEntityNew();
+ if (!gAvdeccCfg.pDescriptorEntity) {
+ AVB_LOG_ERROR("Failed to allocate an AVDECC descriptor");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ openavbAvdeccFindMacAddr();
+
+ if (!openavbAemDescriptorEntitySet_entity_id(gAvdeccCfg.pDescriptorEntity, NULL, gAvdeccCfg.ifmac, gAvdeccCfg.avdeccId)) {
+ AVB_LOG_ERROR("Failed to set the AVDECC descriptor");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ // Create the Entity Model
+ openavbRC rc = openavbAemCreate(gAvdeccCfg.pDescriptorEntity);
+ if (IS_OPENAVB_FAILURE(rc)) {
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ // Copy the supplied non-localized strings to the descriptor.
+ openavbAemDescriptorEntitySet_entity_model_id(gAvdeccCfg.pDescriptorEntity, gAvdeccCfg.entity_model_id);
+ openavbAemDescriptorEntitySet_entity_name(gAvdeccCfg.pDescriptorEntity, gAvdeccCfg.entity_name);
+ openavbAemDescriptorEntitySet_firmware_version(gAvdeccCfg.pDescriptorEntity, gAvdeccCfg.firmware_version);
+ openavbAemDescriptorEntitySet_group_name(gAvdeccCfg.pDescriptorEntity, gAvdeccCfg.group_name);
+ openavbAemDescriptorEntitySet_serial_number(gAvdeccCfg.pDescriptorEntity, gAvdeccCfg.serial_number);
+
+ // Initialize the localized strings support.
+ gAvdeccCfg.pAemDescriptorLocaleStringsHandler = openavbAemDescriptorLocaleStringsHandlerNew();
+ if (gAvdeccCfg.pAemDescriptorLocaleStringsHandler) {
+ // Add the strings to the locale strings hander.
+ openavbAemDescriptorLocaleStringsHandlerSet_local_string(
+ gAvdeccCfg.pAemDescriptorLocaleStringsHandler, gAvdeccCfg.locale_identifier, gAvdeccCfg.vendor_name, LOCALE_STRING_VENDOR_NAME_INDEX);
+ openavbAemDescriptorLocaleStringsHandlerSet_local_string(
+ gAvdeccCfg.pAemDescriptorLocaleStringsHandler, gAvdeccCfg.locale_identifier, gAvdeccCfg.model_name, LOCALE_STRING_MODEL_NAME_INDEX);
+
+ // Have the descriptor entity reference the locale strings.
+ openavbAemDescriptorEntitySet_vendor_name(gAvdeccCfg.pDescriptorEntity, 0, LOCALE_STRING_VENDOR_NAME_INDEX);
+ openavbAemDescriptorEntitySet_model_name(gAvdeccCfg.pDescriptorEntity, 0, LOCALE_STRING_MODEL_NAME_INDEX);
+ }
+
+ gAvdeccCfg.bTalker = gAvdeccCfg.bListener = FALSE;
+
+ // Add a configuration for each talker or listener stream.
+ openavb_tl_data_cfg_t *current_stream = streamList;
+ while (current_stream != NULL) {
+ // Create a new configuration with the information from this stream.
+ if (!openavbAvdeccAddConfiguration(current_stream)) {
+ AVB_LOG_ERROR("Error adding AVDECC configuration");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ // Proceed to the next stream.
+ current_stream = current_stream->next;
+ }
+
+ if (!gAvdeccCfg.bTalker && !gAvdeccCfg.bListener) {
+ AVB_LOG_ERROR("No AVDECC Configurations -- Aborting");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ // Add non-top-level descriptors. These are independent of the configurations.
+ // STRINGS are handled by gAvdeccCfg.pAemDescriptorLocaleStringsHandler, so not included here.
+ U16 nResultIdx;
+ if (!openavbAemAddDescriptor(openavbAemDescriptorAudioClusterNew(), OPENAVB_AEM_DESCRIPTOR_INVALID, &nResultIdx)) {
+ AVB_LOG_ERROR("Error adding AVDECC Audio Cluster");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ if (gAvdeccCfg.bTalker) {
+ if (!openavbAemAddDescriptor(openavbAemDescriptorStreamPortOutputNew(), OPENAVB_AEM_DESCRIPTOR_INVALID, &nResultIdx)) {
+ AVB_LOG_ERROR("Error adding AVDECC Output Stream Port");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ }
+ if (gAvdeccCfg.bListener) {
+ if (!openavbAemAddDescriptor(openavbAemDescriptorStreamPortInputNew(), OPENAVB_AEM_DESCRIPTOR_INVALID, &nResultIdx)) {
+ AVB_LOG_ERROR("Error adding AVDECC Input Stream Port");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+ }
+
+ // AVDECC_TODO: Add other descriptors as needed. Future options include:
+ // EXTERNAL_PORT_INPUT
+ // EXTERNAL_PORT_OUTPUT
+ // INTERNAL_PORT_INPUT
+ // INTERNAL_PORT_OUTPUT
+ // VIDEO_CLUSTER
+ // SENSOR_CLUSTER
+ // AUDIO_MAP
+ // VIDEO_MAP
+ // SENSOR_MAP
+
+ // Fill in the descriptor capabilities.
+ // AVDECC_TODO: Set these based on the available capabilities.
+ if (!gAvdeccCfg.bClassASupported && !gAvdeccCfg.bClassBSupported) {
+ // If the user didn't specify a traffic class, assume both are supported.
+ gAvdeccCfg.bClassASupported = gAvdeccCfg.bClassBSupported = TRUE;
+ }
+ openavbAemDescriptorEntitySet_entity_capabilities(gAvdeccCfg.pDescriptorEntity,
+ OPENAVB_ADP_ENTITY_CAPABILITIES_AEM_SUPPORTED |
+ (gAvdeccCfg.bClassASupported ? OPENAVB_ADP_ENTITY_CAPABILITIES_CLASS_A_SUPPORTED : 0) |
+ (gAvdeccCfg.bClassBSupported ? OPENAVB_ADP_ENTITY_CAPABILITIES_CLASS_B_SUPPORTED : 0) |
+ OPENAVB_ADP_ENTITY_CAPABILITIES_GPTP_SUPPORTED);
+
+ if (gAvdeccCfg.bTalker) {
+ // AVDECC_TODO: Set these based on the available capabilities.
+ openavbAemDescriptorEntitySet_talker_capabilities(gAvdeccCfg.pDescriptorEntity, talker_stream_sources,
+ OPENAVB_ADP_TALKER_CAPABILITIES_IMPLEMENTED |
+ OPENAVB_ADP_TALKER_CAPABILITIES_AUDIO_SOURCE |
+ OPENAVB_ADP_TALKER_CAPABILITIES_MEDIA_CLOCK_SOURCE);
+ }
+ if (gAvdeccCfg.bListener) {
+ // AVDECC_TODO: Set these based on the available capabilities.
+ openavbAemDescriptorEntitySet_listener_capabilities(gAvdeccCfg.pDescriptorEntity, listener_stream_sources,
+ OPENAVB_ADP_LISTENER_CAPABILITIES_IMPLEMENTED |
+ OPENAVB_ADP_LISTENER_CAPABILITIES_AUDIO_SINK);
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return TRUE;
+}
+
+// Start the AVDECC protocols.
+extern DLL_EXPORT bool openavbAvdeccStart()
+{
+ if (!openavbAvdeccStartCmp()) {
+ AVB_LOG_ERROR("openavbAvdeccStartCmp() failure!");
+ return FALSE;
+ }
+ if (!openavbAvdeccStartEcp()) {
+ AVB_LOG_ERROR("openavbAvdeccStartEcp() failure!");
+ return FALSE;
+ }
+ if (!openavbAvdeccStartAdp()) {
+ AVB_LOG_ERROR("openavbAvdeccStartAdp() failure!");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// Stop the AVDECC protocols.
+extern DLL_EXPORT void openavbAvdeccStop(void)
+{
+ openavbAvdeccStopCmp();
+ openavbAvdeccStopEcp();
+ openavbAvdeccStopAdp();
+}
+
+extern DLL_EXPORT bool openavbAvdeccCleanup(void)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
+
+ openavbRC rc = openavbAemDestroy();
+
+ while (pFirstConfigurationCfg) {
+ openavb_avdecc_configuration_cfg_t *pDel = pFirstConfigurationCfg;
+ pFirstConfigurationCfg = pFirstConfigurationCfg->next;
+ free(pDel);
+ }
+
+ if (IS_OPENAVB_FAILURE(rc)) {
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return FALSE;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return TRUE;
+}
diff --git a/lib/avtp_pipeline/avdecc/openavb_avdecc.h b/lib/avtp_pipeline/avdecc/openavb_avdecc.h new file mode 100644 index 00000000..6c32b7e4 --- /dev/null +++ b/lib/avtp_pipeline/avdecc/openavb_avdecc.h @@ -0,0 +1,210 @@ +/*************************************************************************************************************
+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 : AVDECC - Top level 1722.1 implementation
+ * MODULE SUMMARY : Top level 1722.1 implementation
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_AVDECC_H
+#define OPENAVB_AVDECC_H 1
+
+#include "openavb_platform.h"
+
+#include "openavb_avdecc_pub.h"
+#include "openavb_avdecc_osal.h"
+#include "openavb_types.h"
+#include "openavb_trace.h"
+
+#ifndef DATA_ALIGNMENT_ADJUSTMENT
+// No Data alignment precaution needed.
+
+// Octet based data 2 buffer macros
+#define OCT_D2BMEMCP(d, s) {size_t data_size = sizeof(s); memcpy(d, s, data_size); d += data_size;} // Uses data_size variable to avoid compiler warnings
+#define OCT_D2BBUFCP(d, s, len) memcpy(d, s, len); d += len;
+#define OCT_D2BHTONB(d, s) *(U8 *)(d) = s; d += sizeof(s);
+#define OCT_D2BHTONS(d, s) *(U16 *)(d) = htons(s); d += sizeof(s);
+#define OCT_D2BHTONL(d, s) *(U32 *)(d) = htonl(s); d += sizeof(s);
+
+// Bit based data 2 buffer macros
+#define BIT_D2BHTONB(d, s, shf, inc) *(U8 *)(d) |= s << shf; d += inc;
+#define BIT_D2BHTONS(d, s, shf, inc) *(U16 *)(d) |= htons((U16)(s << shf)); d += inc;
+#define BIT_D2BHTONL(d, s, shf, inc) *(U32 *)(d) |= htonl((U32)(s << shf)); d += inc;
+
+
+// Octet based buffer 2 data macros
+#define OCT_B2DMEMCP(d, s) {size_t data_size = sizeof(d); memcpy(d, s, data_size); s += data_size;} // Uses data_size variable to avoid compiler warnings
+#define OCT_B2DBUFCP(d, s, len) memcpy(d, s, len); s += len;
+#define OCT_B2DNTOHB(d, s) d = *(U8 *)(s); s += sizeof(d);
+#define OCT_B2DNTOHS(d, s) d = ntohs(*(U16 *)(s)); s += sizeof(d);
+#define OCT_B2DNTOHL(d, s) d = ntohl(*(U32 *)(s)); s += sizeof(d);
+
+// Bit based buffer 2 data macros
+#define BIT_B2DNTOHB(d, s, msk, shf, inc) d = (*(U8 *)(s) & (U8)msk) >> shf; s += inc;
+#define BIT_B2DNTOHS(d, s, msk, shf, inc) d = (ntohs(*(U16 *)(s)) & (U16)msk) >> shf; s += inc;
+#define BIT_B2DNTOHL(d, s, msk, shf, inc) d = (ntohl(*(U32 *)(s)) & (U32)msk) >> shf; s += inc;
+
+#else
+// Data alignment precaution needed.
+
+// Octet based data 2 buffer macros
+#define OCT_D2BMEMCP(d, s) {size_t data_size = sizeof(s); memcpy(d, s, data_size); d += data_size;} // Uses data_size variable to avoid compiler warnings
+
+#define OCT_D2BBUFCP(d, s, len) memcpy(d, s, len); d += len;
+
+//#define OCT_D2BHTONB(d, s) *(U8 *)(d) = s; d += sizeof(s);
+#define OCT_D2BHTONB(d, s) \
+{ \
+memcpy(d, &s, sizeof(U8)); \
+d += sizeof(U8); \
+}
+
+//#define OCT_D2BHTONS(d, s) *(U16 *)(d) = htons(s); d += sizeof(s);
+#define OCT_D2BHTONS(d, s) \
+{ \
+U16 sAlign16 = s; \
+sAlign16 = htons(sAlign16); \
+memcpy(d, &sAlign16, sizeof(U16)); \
+d += sizeof(U16); \
+}
+
+//#define OCT_D2BHTONL(d, s) *(U32 *)(d) = htonl(s); d += sizeof(s);
+#define OCT_D2BHTONL(d, s) \
+{ \
+U32 sAlign32 = s; \
+sAlign32 = htonl(sAlign32); \
+memcpy(d, &sAlign32, sizeof(U32)); \
+d += sizeof(U32); \
+}
+
+// Bit based data 2 buffer macros
+//#define BIT_D2BHTONB(d, s, shf, inc) *(U8 *)(d) |= s << shf; d += inc;
+#define BIT_D2BHTONB(d, s, shf, inc) \
+{ \
+U8 sAlign8 = s << shf; \
+U8 dAlign8; \
+memcpy(&dAlign8, d, sizeof(U8)); \
+dAlign8 |= sAlign8; \
+memcpy(d, &dAlign8, sizeof(U8)); \
+d += inc; \
+}
+
+//#define BIT_D2BHTONS(d, s, shf, inc) *(U16 *)(d) |= htons((U16)(s << shf)); d += inc;
+#define BIT_D2BHTONS(d, s, shf, inc) \
+{ \
+U16 sAlign16 = htons((U16)(s << shf)); \
+U16 dAlign16; \
+memcpy(&dAlign16, d, sizeof(U16)); \
+dAlign16 |= sAlign16; \
+memcpy(d, &dAlign16, sizeof(U16)); \
+d += inc; \
+}
+
+//#define BIT_D2BHTONL(d, s, shf, inc) *(U32 *)(d) |= htonl((U32)(s << shf)); d += inc;
+#define BIT_D2BHTONL(d, s, shf, inc) \
+{ \
+U32 sAlign32 = htonl((U32)(s << shf)); \
+U32 dAlign32; \
+memcpy(&dAlign32, d, sizeof(U32)); \
+dAlign32 |= sAlign32; \
+memcpy(d, &dAlign32, sizeof(U32)); \
+d += inc; \
+}
+
+
+// Octet based buffer 2 data macros
+#define OCT_B2DMEMCP(d, s) {size_t data_size = sizeof(d); memcpy(d, s, data_size); s += data_size;} // Uses data_size variable to avoid compiler warnings
+
+#define OCT_B2DBUFCP(d, s, len) memcpy(d, s, len); s += len;
+
+//#define OCT_B2DNTOHB(d, s) d = *(U8 *)(s); s += sizeof(d);
+#define OCT_B2DNTOHB(d, s) \
+{ \
+memcpy(&d, s, sizeof(U8)); \
+s += sizeof(U8); \
+}
+
+//#define OCT_B2DNTOHS(d, s) d = ntohs(*(U16 *)(s)); s += sizeof(d);
+#define OCT_B2DNTOHS(d, s) \
+{ \
+U16 sAlign16; \
+memcpy(&sAlign16, s, sizeof(U16)); \
+sAlign16 = ntohs(sAlign16); \
+memcpy(&d, &sAlign16, sizeof(U16)); \
+s += sizeof(U16); \
+}
+
+//#define OCT_B2DNTOHL(d, s) d = ntohl(*(U32 *)(s)); s += sizeof(d);
+#define OCT_B2DNTOHL(d, s) \
+{ \
+U32 sAlign32; \
+memcpy(&sAlign32, s, sizeof(U32)); \
+sAlign32 = ntohl(sAlign32); \
+memcpy(&d, &sAlign32, sizeof(U32)); \
+s += sizeof(U32); \
+}
+
+// Bit based buffer 2 data macros
+//#define BIT_B2DNTOHB(d, s, msk, shf, inc) d = (*(U8 *)(s) & (U8)msk) >> shf; s += inc;
+#define BIT_B2DNTOHB(d, s, msk, shf, inc) \
+{ \
+U8 sAlign8; \
+memcpy(&sAlign8, s, sizeof(U8)); \
+sAlign8 = (sAlign8 & (U8)msk) >>shf; \
+memcpy(&d, &sAlign8, sizeof(U8)); \
+s += inc; \
+}
+
+//#define BIT_B2DNTOHS(d, s, msk, shf, inc) d = (ntohs(*(U16 *)(s)) & (U16)msk) >> shf; s += inc;
+#define BIT_B2DNTOHS(d, s, msk, shf, inc) \
+{ \
+U16 sAlign16; \
+memcpy(&sAlign16, s, sizeof(U16)); \
+sAlign16 = (ntohs(sAlign16) & (U16)msk) >> shf; \
+memcpy(&d, &sAlign16, sizeof(U16)); \
+s += inc; \
+}
+
+//#define BIT_B2DNTOHL(d, s, msk, shf, inc) d = (ntohl(*(U32 *)(s)) & (U32)msk) >> shf; s += inc;
+#define BIT_B2DNTOHL(d, s, msk, shf, inc) \
+{ \
+U32 sAlign32; \
+memcpy(&sAlign32, s, sizeof(U32)); \
+sAlign32 = (ntohs(sAlign32) & (U32)msk) >> shf; \
+memcpy(&d, &sAlign32, sizeof(U32)); \
+s += inc; \
+}
+
+#endif
+
+#endif // OPENAVB_AVDECC_H
diff --git a/lib/avtp_pipeline/avdecc/openavb_avdecc_pipeline_interaction_pub.h b/lib/avtp_pipeline/avdecc/openavb_avdecc_pipeline_interaction_pub.h new file mode 100644 index 00000000..c7edac96 --- /dev/null +++ b/lib/avtp_pipeline/avdecc/openavb_avdecc_pipeline_interaction_pub.h @@ -0,0 +1,71 @@ +/*************************************************************************************************************
+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.
+*************************************************************************************************************/
+
+#ifndef OPENAVB_AVDECC_PIPELINE_INTERACTION_PUB_H
+#define OPENAVB_AVDECC_PIPELINE_INTERACTION_PUB_H 1
+
+#include "openavb_acmp.h"
+#include "openavb_descriptor_stream_io_pub.h"
+#include "openavb_avdecc_msg.h"
+
+
+// Run a single talker or listener.
+bool openavbAVDECCRunListener(openavb_aem_descriptor_stream_io_t *pDescriptorStreamInput, U16 configIdx, openavb_acmp_ListenerStreamInfo_t *pListenerStreamInfo);
+bool openavbAVDECCRunTalker(openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput, U16 configIdx, openavb_acmp_TalkerStreamInfo_t *pTalkerStreamInfo);
+
+// Stop a single talker or listener.
+bool openavbAVDECCStopListener(openavb_aem_descriptor_stream_io_t *pDescriptorStreamInput, U16 configIdx, openavb_acmp_ListenerStreamInfo_t *pListenerStreamInfo);
+bool openavbAVDECCStopTalker(openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput, U16 configIdx, openavb_acmp_TalkerStreamInfo_t *pTalkerStreamInfo);
+
+// Get talker stream details. Structure members in TalkerStreamInfo will be filled.
+bool openavbAVDECCGetTalkerStreamInfo(openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput, U16 configIdx, openavb_acmp_TalkerStreamInfo_t *pTalkerStreamInfo);
+
+// Set talker stream details. The settings will be passed to the Talker to use for future connections
+bool openavbAVDECCSetTalkerStreamInfo(
+ openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput,
+ U8 sr_class,
+ U8 stream_id_valid, const U8 stream_src_mac[6], U16 stream_uid,
+ U8 stream_dest_valid, const U8 stream_dest_mac[6],
+ U8 stream_vlan_id_valid, U16 stream_vlan_id);
+
+// Get the streaming state (stopped, running, paused, etc.) AVDECC told the talker or listener to use.
+openavbAvdeccMsgStateType_t openavbAVDECCGetRequestedState(openavb_aem_descriptor_stream_io_t *pDescriptorStreamInput, U16 configIdx);
+
+// Get the streaming state (stopped, running, paused, etc.) last reported by the talker or listener.
+openavbAvdeccMsgStateType_t openavbAVDECCGetStreamingState(openavb_aem_descriptor_stream_io_t *pDescriptorStreamInput, U16 configIdx);
+
+// Pause or resume the stream.
+void openavbAVDECCPauseStream(openavb_aem_descriptor_stream_io_t *pDescriptor, bool bPause);
+
+// Get the current counter value in pValue. Returns TRUE if the counter is supported, FALSE otherwise.
+bool openavbAVDECCGetCounterValue(void *pDescriptor, U16 descriptorType, U32 counterFlag, U32 *pValue);
+
+#endif // OPENAVB_AVDECC_PIPELINE_INTERACTION_PUB_H
diff --git a/lib/avtp_pipeline/avdecc/openavb_avdecc_pub.h b/lib/avtp_pipeline/avdecc/openavb_avdecc_pub.h new file mode 100644 index 00000000..803438ed --- /dev/null +++ b/lib/avtp_pipeline/avdecc/openavb_avdecc_pub.h @@ -0,0 +1,145 @@ +/*************************************************************************************************************
+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 : AVDECC - Top level AVDECC (1722.1) Public Interface
+ * MODULE SUMMARY : Top level AVDECC (1722.1) Public Interface
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_AVDECC_PUB_H
+#define OPENAVB_AVDECC_PUB_H 1
+
+// Entity Model public includes
+#include "openavb_aem_pub.h"
+#include "openavb_descriptor_entity_pub.h"
+#include "openavb_descriptor_configuration_pub.h"
+#include "openavb_descriptor_audio_unit_pub.h"
+#include "openavb_descriptor_stream_io_pub.h"
+#include "openavb_descriptor_jack_io_pub.h"
+#include "openavb_descriptor_avb_interface_pub.h"
+#include "openavb_descriptor_clock_source_pub.h"
+#include "openavb_descriptor_locale_pub.h"
+#include "openavb_descriptor_strings_pub.h"
+#include "openavb_descriptor_control_pub.h"
+#include "openavb_descriptor_stream_port_io_pub.h"
+#include "openavb_descriptor_external_port_io_pub.h"
+#include "openavb_descriptor_audio_cluster_pub.h"
+#include "openavb_descriptor_audio_map_pub.h"
+#include "openavb_descriptor_clock_domain_pub.h"
+#include "openavb_descriptor_locale_strings_handler_pub.h"
+
+// Discovery protocol public includes
+#include "openavb_adp_pub.h"
+
+// Connection management public includes
+#include "openavb_acmp_pub.h"
+
+// Enumeration and control public includes
+#include "openavb_aecp_pub.h"
+
+// openavb_tl_data_cfg_t definition
+#include "openavb_avdecc_read_ini_pub.h"
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+// Indexes for localized strings.
+// (These are defined for internal use, and can be changed as needed.)
+#define LOCALE_STRING_VENDOR_NAME_INDEX 0
+#define LOCALE_STRING_MODEL_NAME_INDEX 1
+
+typedef struct {
+
+ char ifname[IFNAMSIZ + 10]; // Include space for the socket type prefix (e.g. "simple:eth0")
+ U8 ifmac[ETH_ALEN];
+
+ bool bListener;
+ bool bTalker;
+ bool bClassASupported;
+ bool bClassBSupported;
+
+ U16 vlanID;
+ U8 vlanPCP;
+
+ bool bFastConnectSupported; // FAST_CONNECT and SAVED_STATE supported
+
+ U8 valid_time; // Number of 2-second units
+
+ // Information to add to the descriptor.
+ unsigned avdeccId;
+ U8 entity_model_id[8];
+ char entity_name[OPENAVB_AEM_STRLEN_MAX];
+ char firmware_version[OPENAVB_AEM_STRLEN_MAX];
+ char group_name[OPENAVB_AEM_STRLEN_MAX];
+ char serial_number[OPENAVB_AEM_STRLEN_MAX];
+
+ // Localization strings.
+ char locale_identifier[OPENAVB_AEM_STRLEN_MAX];
+ char vendor_name[OPENAVB_AEM_STRLEN_MAX];
+ char model_name[OPENAVB_AEM_STRLEN_MAX];
+
+ openavb_aem_descriptor_entity_t *pDescriptorEntity;
+ openavb_aem_descriptor_locale_strings_handler_t *pAemDescriptorLocaleStringsHandler;
+} openavb_avdecc_cfg_t;
+
+typedef struct openavb_avdecc_configuration_cfg {
+ struct openavb_avdecc_configuration_cfg *next; // next link list pointer
+
+ // Pointer to the endpoint information.
+ openavb_tl_data_cfg_t *stream;
+
+ // Friendly name
+ char friendly_name[OPENAVB_AEM_STRLEN_MAX];
+
+ // AVDECC_TODO: Add additional information as needed.
+
+} openavb_avdecc_configuration_cfg_t;
+
+
+// General initialization for AVDECC. This must be called before any other AVDECC APIs including AEM APIs
+bool openavbAvdeccInitialize(void);
+
+// Start the AVDECC protocols.
+bool openavbAvdeccStart(void);
+
+// Stop the AVDECC protocols.
+void openavbAvdeccStop(void);
+
+// General Cleanup for AVDECC.
+bool openavbAvdeccCleanup(void);
+
+#endif // OPENAVB_AVDECC_PUB_H
diff --git a/lib/avtp_pipeline/avdecc/openavb_avdecc_read_ini_pub.h b/lib/avtp_pipeline/avdecc/openavb_avdecc_read_ini_pub.h new file mode 100644 index 00000000..5c71d5b7 --- /dev/null +++ b/lib/avtp_pipeline/avdecc/openavb_avdecc_read_ini_pub.h @@ -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. +*************************************************************************************************************/ + +/* +* HEADER SUMMARY : AVDECC Read INI Public Interface +*/ + +#ifndef OPENAVB_AVDECC_READ_INI_PUB_H +#define OPENAVB_AVDECC_READ_INI_PUB_H 1 + +#include "openavb_types_pub.h" +#include "openavb_mediaq_pub.h" +#include "openavb_avtp_time_pub.h" +#include "openavb_tl_pub.h" + +#define MAX_SAMPLING_RATES_COUNT 91 + +/** \file + * AVDECC Read INI Public Interface. + */ + +struct _avdecc_msg_state; +typedef struct _avdecc_msg_state avdecc_msg_state_t; + +/// Maximum size of the friendly name +#define FRIENDLY_NAME_SIZE 64 + +/// Structure containing configuration of the host +struct openavb_tl_data_cfg { + struct openavb_tl_data_cfg *next; + + /// Role of the host + avb_role_t role; + /// Initial Talker/Listener state + tl_init_state_t initial_state; + /// MAC address of destination - multicast (talker only if SRP is enabled) + cfg_mac_t dest_addr; + /// MAC address of the source + cfg_mac_t stream_addr; + /// Stream UID (has to be unique) + U16 stream_uid; + /// Maximum number of packets sent during one interval (talker only) + U32 max_interval_frames; + /// Maximum size of the frame + U32 max_frame_size; + /// Setting maximum transit time, on talker value is added to PTP Walltime, + /// on listener value is validated timestamp range + U32 max_transit_usec; + /// Maximum transmit deficit in usec - should be set to expected buffer size + /// on the listener side (talker only) + U32 max_transmit_deficit_usec; + /// Specify manual an internal latency (talker only) + U32 internal_latency; + /// Number of microseconds after which late MediaQItem will be purged as too + /// old (listener only) + U32 max_stale; + /// Number of intervals to handle at once (talker only) + U32 batch_factor; + /// Statistics reporting frequency + U32 report_seconds; + /// Start paused + bool start_paused; + /// Class in which host will operate ::SRClassIdx_t (talker only) + U8 sr_class; + /// Rank of the stream #SR_RANK_REGULAR or #SR_RANK_EMERGENCY (talker only) + U8 sr_rank; + /// Number of raw TX buffers that should be used (talker only) + U32 raw_tx_buffers; + /// Number of raw RX buffers (listener only) + U32 raw_rx_buffers; + /// Is the interface module blocking in the TX CB. + bool tx_blocking_in_intf; + /// VLAN ID + U16 vlan_id; + /// When set incoming packets will trigger a signal to the stream task to wakeup. + bool rx_signal_mode; + /// Enable fixed timestamping in interface + U32 fixed_timestamp; + /// Wait for next observation interval by spinning rather than sleeping + bool spin_wait; + /// Bit mask used for CPU pinning + U32 thread_affinity; + /// Real time priority of thread. + U32 thread_rt_priority; + /// The current sample rate of this Audio Unit + U32 current_sampling_rate; + /// The number of sample rates in the sampling_rates field. + U16 sampling_rates_count; + /// An array of 4-octet sample rates supported by this Audio Unit + U32 sampling_rates[MAX_SAMPLING_RATES_COUNT]; + /// intf_nv_audio_rate + U16 audioRate; + /// intf_nv_audio_bit_depth + U8 audioBitDepth; + /// intf_nv_channels + U8 audioChannels; + /// Friendly name for this configuration + char friendly_name[FRIENDLY_NAME_SIZE]; + /// The name of the initialize function in the mapper + char map_fn[100]; + + // Pointer to the client Talker/Listener. + // Do not free this item; it is for reference only. + const avdecc_msg_state_t * client; +}; + +typedef struct openavb_tl_data_cfg openavb_tl_data_cfg_t; + + +/** Read an ini file. + * + * Parses an input configuration file to populate configuration structures, and + * name value pairs. Only used in Operating Systems that have a file system + * + * \param fileName Pointer to configuration file name + * \param pCfg Pointer to configuration structure + * \return TRUE on success or FALSE on failure + * + * \warning Not available on all platforms + */ +bool openavbReadTlDataIniFile(const char *fileName, openavb_tl_data_cfg_t *pCfg); + + +/** Save the connection to the saved state + * + * If fast connect support is enabled, this function is used to save the state + * of the connection by a Listener when a connection is successfully made to + * a Talker for possible fast connect support later. + * #openavbAvdeccClearSavedState() should be called when the connection is closed. + * + * \param pListener Pointer to configuration for the Listener + * \param flags The flags used for the connection (CLASS_B, SUPPORTS_ENCRYPTED, ENCRYPTED_PDU) + * \param talker_unique_id The unique id for the Talker + * \param talker_entity_id The binary entity id for the Talker + * \param controller_entity_id The binary entity id for the Controller that initiated the connection + * + * \return TRUE on success or FALSE on failure + */ +bool openavbAvdeccSaveState(const openavb_tl_data_cfg_t *pListener, U16 flags, U16 talker_unique_id, const U8 talker_entity_id[8], const U8 controller_entity_id[8]); + +/** Delete a connection with saved state + * + * If fast connect support is enabled, this function is used to clear previously + * saved state information (from a previous call to #openavbAvdeccSaveState). + * This function should be called from the Listener when a Talker/Listener connection is closed + * (and fast connects should no longer be attempted in the future). + * + * \param pListener Pointer to configuration for the Listener + * + * \return TRUE on success or FALSE on failure + */ +bool openavbAvdeccClearSavedState(const openavb_tl_data_cfg_t *pListener); + +/** Determine if the connection has a saved state + * + * If fast connect support is enabled, this function is used to get the last + * saved state (from a call to #openavbAvdeccSaveState) for a Listener, if any. + * + * \param pListener Pointer to configuration for the Listener + * \param p_flags Optional pointer to the flags used for the connection (CLASS_B, SUPPORTS_ENCRYPTED, ENCRYPTED_PDU) + * \param p_talker_unique_id Optional pointer to the unique id for the Talker + * \param p_talker_entity_id Optional pointer to the buffer to fill in the binary entity id for the Talker + * \param p_controller_entity_id Optional pointer to the buffer to fill in the binary entity id for the Controller that initiated the connection + * + * \return TRUE if there is a saved state, or FALSE otherwise + */ +bool openavbAvdeccGetSaveStateInfo(const openavb_tl_data_cfg_t *pListener, U16 *p_flags, U16 *p_talker_unique_id, U8 (*p_talker_entity_id)[8], U8 (*p_controller_entity_id)[8]); + +#endif // OPENAVB_AVDECC_READ_INI_PUB_H diff --git a/lib/avtp_pipeline/avdecc/shutdown_openavb_avdecc.sh b/lib/avtp_pipeline/avdecc/shutdown_openavb_avdecc.sh new file mode 100755 index 00000000..352e5433 --- /dev/null +++ b/lib/avtp_pipeline/avdecc/shutdown_openavb_avdecc.sh @@ -0,0 +1,18 @@ +#! /bin/sh +# +# AVB AVDECC clean-up script +# +# Only needs to be run if the AVDECC process crashes. +# +# Removes resources created/loaded by AVDECC, so that a new +# instance can run. + +IFACES=$(cat /proc/net/dev | grep -- : | cut -d: -f1) + +echo "removing AVDECC resources" + +killall -s SIGINT openavb_avdecc > /dev/null 2>&1 +killall -s SIGINT openavb_harness > /dev/null 2>&1 +killall -s SIGINT openavb_host > /dev/null 2>&1 +rm -f /tmp/avdecc_msg > /dev/null 2>&1 + |