summaryrefslogtreecommitdiff
path: root/lib/avtp_pipeline/adp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/avtp_pipeline/adp')
-rw-r--r--lib/avtp_pipeline/adp/CMakeLists.txt9
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp.c181
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp.h93
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_message.c464
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_message.h50
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_pub.h90
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_sm_advertise_entity.c252
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_sm_advertise_entity.h63
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_sm_advertise_interface.c341
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_sm_advertise_interface.h73
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_sm_discovery.c45
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_sm_discovery.h48
12 files changed, 1709 insertions, 0 deletions
diff --git a/lib/avtp_pipeline/adp/CMakeLists.txt b/lib/avtp_pipeline/adp/CMakeLists.txt
new file mode 100644
index 00000000..c8da8d8d
--- /dev/null
+++ b/lib/avtp_pipeline/adp/CMakeLists.txt
@@ -0,0 +1,9 @@
+SET (SRC_FILES ${SRC_FILES}
+ ${AVB_SRC_DIR}/adp/openavb_adp.c
+ ${AVB_SRC_DIR}/adp/openavb_adp_message.c
+ ${AVB_SRC_DIR}/adp/openavb_adp_sm_advertise_entity.c
+ ${AVB_SRC_DIR}/adp/openavb_adp_sm_advertise_interface.c
+ ${AVB_SRC_DIR}/adp/openavb_adp_sm_discovery.c
+ PARENT_SCOPE
+)
+
diff --git a/lib/avtp_pipeline/adp/openavb_adp.c b/lib/avtp_pipeline/adp/openavb_adp.c
new file mode 100644
index 00000000..474c8d3e
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp.c
@@ -0,0 +1,181 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol
+ * MODULE SUMMARY : Implements the 1722.1 (AVDECC) discovery protocol
+ ******************************************************************
+ */
+
+#include "openavb_platform.h"
+
+#include <signal.h>
+
+#define AVB_LOG_COMPONENT "ADP"
+#include "openavb_log.h"
+
+#include "openavb_aem.h"
+#include "openavb_adp.h"
+#include "openavb_adp_sm_advertise_entity.h"
+#include "openavb_adp_sm_advertise_interface.h"
+#include "openavb_adp_message.h"
+
+#ifdef AVB_PTP_AVAILABLE
+#include "openavb_ptp_api.h"
+
+// PTP declarations
+openavbRC openavbPtpInitializeSharedMemory ();
+void openavbPtpReleaseSharedMemory ();
+openavbRC openavbPtpUpdateSharedMemoryEntry ();
+openavbRC openavbPtpFindLatestSharedMemoryEntry(U32 *index);
+extern gmChangeTable_t openavbPtpGMChageTable;
+#endif // AVB_PTP_AVAILABLE
+
+openavb_adp_sm_global_vars_t openavbAdpSMGlobalVars;
+
+MUTEX_HANDLE(openavbAdpMutex);
+#define ADP_LOCK() { MUTEX_CREATE_ERR(); MUTEX_LOCK(openavbAdpMutex); MUTEX_LOG_ERR("Mutex lock failure"); }
+#define ADP_UNLOCK() { MUTEX_CREATE_ERR(); MUTEX_UNLOCK(openavbAdpMutex); MUTEX_LOG_ERR("Mutex unlock failure"); }
+
+extern openavb_avdecc_cfg_t gAvdeccCfg;
+
+static bool s_bPreviousHaveTL = false;
+
+openavbRC openavbAdpStart()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ openavb_avdecc_entity_model_t *pAem = openavbAemGetModel();
+ if (!pAem) {
+ AVB_RC_LOG_TRACE_RET(AVB_RC(OPENAVB_AVDECC_FAILURE | OPENAVBAVDECC_RC_ENTITY_MODEL_MISSING), AVB_TRACE_ADP);
+ }
+
+ {
+ MUTEX_ATTR_HANDLE(mta);
+ MUTEX_ATTR_INIT(mta);
+ MUTEX_ATTR_SET_TYPE(mta, MUTEX_ATTR_TYPE_DEFAULT);
+ MUTEX_ATTR_SET_NAME(mta, "openavbAdpMutex");
+ MUTEX_CREATE_ERR();
+ MUTEX_CREATE(openavbAdpMutex, mta);
+ MUTEX_LOG_ERR("Could not create/initialize 'openavbAdpMutex' mutex");
+ }
+
+ ADP_LOCK();
+ {
+ // Populate global ADP vars
+ openavb_adp_control_header_t *pHeader = &openavbAdpSMGlobalVars.entityInfo.header;
+
+ pHeader->cd = 1;
+ pHeader->subtype = OPENAVB_ADP_AVTP_SUBTYPE;
+ pHeader->sv = 0;
+ pHeader->version = 0;
+ pHeader->message_type = 0; // Set later depending on message type
+ pHeader->valid_time = gAvdeccCfg.valid_time;
+ pHeader->control_data_length = 56;
+ memcpy(pHeader->entity_id, pAem->pDescriptorEntity->entity_id, sizeof(pAem->pDescriptorEntity->entity_id));
+ }
+
+ {
+ // Populate global ADP PDU vars
+ openavb_adp_data_unit_t *pPdu = &openavbAdpSMGlobalVars.entityInfo.pdu;
+
+#ifdef AVB_PTP_AVAILABLE
+ openavbRC retCode = OPENAVB_PTP_FAILURE;
+ retCode = openavbPtpInitializeSharedMemory();
+ if (IS_OPENAVB_FAILURE(retCode)) {
+ AVB_LOG_WARNING("Failed to init PTP shared memory");
+ }
+#endif // AVB_PTP_AVAILABLE
+
+ memcpy(pPdu->entity_model_id, pAem->pDescriptorEntity->entity_model_id, sizeof(pPdu->entity_model_id));
+ pPdu->entity_capabilities = pAem->pDescriptorEntity->entity_capabilities;
+ pPdu->talker_stream_sources = pAem->pDescriptorEntity->talker_stream_sources;
+ pPdu->talker_capabilities = pAem->pDescriptorEntity->talker_capabilities;
+ pPdu->listener_stream_sinks = pAem->pDescriptorEntity->listener_stream_sinks;
+ pPdu->listener_capabilities = pAem->pDescriptorEntity->listener_capabilities;
+ pPdu->controller_capabilities = pAem->pDescriptorEntity->controller_capabilities;
+ pPdu->available_index = pAem->pDescriptorEntity->available_index;
+ // The pPdu->gptp_grandmaster_id and pPdu->gptp_domain_number will be filled in when the ADPDU is transmitted.
+ // pPdu->reserved0;
+ // pPdu->identify_control_index = ???; // AVDECC_TODO
+ // pPdu->interface_index = ???; // AVDECC_TODO
+ memcpy(pPdu->association_id, pAem->pDescriptorEntity->association_id, sizeof(pPdu->association_id));
+ // pPdu->reserved1;
+ }
+ ADP_UNLOCK();
+
+ // Wait until we are notified that we have a Talker or Listener before supporting discover.
+ s_bPreviousHaveTL = false;
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_ADP);
+}
+
+void openavbAdpStop()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+#ifdef AVB_PTP_AVAILABLE
+ openavbPtpReleaseSharedMemory();
+#endif // AVB_PTP_AVAILABLE
+
+ // Stop Advertising and supporting Discovery.
+ openavbAdpHaveTL(false);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+
+openavbRC openavbAdpHaveTL(bool bHaveTL)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ if (bHaveTL && !s_bPreviousHaveTL) {
+ // Start Advertising and supporting Discovery.
+ openavbRC rc = openavbAdpMessageHandlerStart();
+ if (IS_OPENAVB_FAILURE(rc)) {
+ AVB_RC_TRACE_RET(rc, AVB_TRACE_ADP);
+ }
+
+ openavbAdpSMAdvertiseInterfaceStart();
+ openavbAdpSMAdvertiseEntityStart();
+ s_bPreviousHaveTL = true;
+ }
+ else if (!bHaveTL && s_bPreviousHaveTL) {
+ // Stop Advertising and supporting Discovery.
+ openavbAdpSMAdvertiseInterfaceStop();
+ openavbAdpSMAdvertiseEntityStop();
+ openavbAdpMessageHandlerStop();
+ s_bPreviousHaveTL = false;
+ }
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_ADP);
+}
diff --git a/lib/avtp_pipeline/adp/openavb_adp.h b/lib/avtp_pipeline/adp/openavb_adp.h
new file mode 100644
index 00000000..54594527
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp.h
@@ -0,0 +1,93 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol Internal Interface
+ * MODULE SUMMARY : Internal Interface for the 1722.1 (AVDECC) discovery protocol
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_ADP_H
+#define OPENAVB_ADP_H 1
+
+#include "openavb_avdecc.h"
+#include "openavb_adp_pub.h"
+
+#define OPENAVB_ADP_AVTP_SUBTYPE (0x7a)
+
+typedef struct {
+ U8 cd;
+ U8 subtype;
+ U8 sv;
+ U8 version;
+ U8 message_type; // Redefined from control data
+ U8 valid_time; // Redefined from status
+ U16 control_data_length;
+ U8 entity_id[8]; // Redefined from stream_id
+} openavb_adp_control_header_t;
+
+typedef struct {
+ 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 gptp_grandmaster_id[8];
+ U8 gptp_domain_number;
+ U8 reserved0[3];
+ U16 identify_control_index;
+ U16 interface_index;
+ U8 association_id[8];
+ U8 reserved1[4];
+} openavb_adp_data_unit_t;
+
+typedef struct {
+ openavb_adp_control_header_t header;
+ openavb_adp_data_unit_t pdu;
+} openavb_adp_entity_info_t;
+
+// IEEE Std 1722.1-2013 clause 6.2.3.
+typedef struct {
+ U64 currentTime;
+ openavb_adp_entity_info_t entityInfo;
+} openavb_adp_sm_global_vars_t;
+
+
+openavbRC openavbAdpStart(void);
+void openavbAdpStop(void);
+
+openavbRC openavbAdpHaveTL(bool bHaveTL);
+
+#endif // OPENAVB_ADP_H
diff --git a/lib/avtp_pipeline/adp/openavb_adp_message.c b/lib/avtp_pipeline/adp/openavb_adp_message.c
new file mode 100644
index 00000000..3f695101
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp_message.c
@@ -0,0 +1,464 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol Message Handler
+ * MODULE SUMMARY : Implements the 1722.1 (AVDECC) discovery protocol message handlers
+ ******************************************************************
+ */
+
+#include "openavb_platform.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#define AVB_LOG_COMPONENT "ADP"
+#include "openavb_log.h"
+
+#include "openavb_debug.h"
+#include "openavb_rawsock.h"
+#include "openavb_avtp.h"
+#include "openavb_srp.h"
+#include "openavb_adp.h"
+#include "openavb_adp_sm_advertise_interface.h"
+#include "openavb_acmp_sm_listener.h"
+
+#ifdef AVB_PTP_AVAILABLE
+#include "openavb_ptp_api.h"
+
+// PTP declarations
+openavbRC openavbPtpInitializeSharedMemory ();
+void openavbPtpReleaseSharedMemory ();
+openavbRC openavbPtpUpdateSharedMemoryEntry ();
+openavbRC openavbPtpFindLatestSharedMemoryEntry(U32 *index);
+extern gmChangeTable_t openavbPtpGMChageTable;
+#else
+#include "openavb_grandmaster_osal_pub.h"
+#endif // AVB_PTP_AVAILABLE
+
+
+#define INVALID_SOCKET (-1)
+
+// ADP Multicast address
+#define ADP_PROTOCOL_ADDR "91:E0:F0:01:00:00"
+
+// message length
+#define AVTP_HDR_LEN 12
+#define ADP_DATA_LEN 56
+#define ADP_FRAME_LEN (ETH_HDR_LEN_VLAN + AVTP_HDR_LEN + ADP_DATA_LEN)
+
+// number of buffers (arbitrary, and rounded up by rawsock)
+#define ADP_NUM_BUFFERS 2
+
+// do cast from ether_addr to U8*
+#define ADDR_PTR(A) (U8*)(&((A)->ether_addr_octet))
+
+extern openavb_avdecc_cfg_t gAvdeccCfg;
+
+extern MUTEX_HANDLE(openavbAdpMutex);
+#define ADP_LOCK() { MUTEX_CREATE_ERR(); MUTEX_LOCK(openavbAdpMutex); MUTEX_LOG_ERR("Mutex lock failure"); }
+#define ADP_UNLOCK() { MUTEX_CREATE_ERR(); MUTEX_UNLOCK(openavbAdpMutex); MUTEX_LOG_ERR("Mutex unlock failure"); }
+
+static void *rxSock = NULL;
+static void *txSock = NULL;
+static struct ether_addr intfAddr;
+static struct ether_addr adpAddr;
+
+extern openavb_adp_sm_global_vars_t openavbAdpSMGlobalVars;
+
+THREAD_TYPE(openavbAdpMessageRxThread);
+THREAD_DEFINITON(openavbAdpMessageRxThread);
+
+static bool bRunning = FALSE;
+
+void openavbAdpCloseSocket()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ if (rxSock) {
+ openavbRawsockClose(rxSock);
+ rxSock = NULL;
+ }
+ if (txSock) {
+ openavbRawsockClose(txSock);
+ txSock = NULL;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+bool openavbAdpOpenSocket(const char* ifname, U16 vlanID, U8 vlanPCP)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ hdr_info_t hdr;
+
+#ifndef UBUNTU
+ // This is the normal case for most of our supported platforms
+ rxSock = openavbRawsockOpen(ifname, TRUE, FALSE, ETHERTYPE_8021Q, ADP_FRAME_LEN, ADP_NUM_BUFFERS);
+#else
+ rxSock = openavbRawsockOpen(ifname, TRUE, FALSE, ETHERTYPE_AVTP, ADP_FRAME_LEN, ADP_NUM_BUFFERS);
+#endif
+ txSock = openavbRawsockOpen(ifname, FALSE, TRUE, ETHERTYPE_AVTP, ADP_FRAME_LEN, ADP_NUM_BUFFERS);
+
+ if (txSock && rxSock
+ && openavbRawsockGetAddr(txSock, ADDR_PTR(&intfAddr))
+ && ether_aton_r(ADP_PROTOCOL_ADDR, &adpAddr)
+ && openavbRawsockRxMulticast(rxSock, TRUE, ADDR_PTR(&adpAddr)))
+ {
+ if (!openavbRawsockRxAVTPSubtype(rxSock, OPENAVB_ADP_AVTP_SUBTYPE | 0x80)) {
+ AVB_LOG_DEBUG("RX AVTP Subtype not supported");
+ }
+
+ memset(&hdr, 0, sizeof(hdr_info_t));
+ hdr.shost = ADDR_PTR(&intfAddr);
+ hdr.dhost = ADDR_PTR(&adpAddr);
+ hdr.ethertype = ETHERTYPE_AVTP;
+ if (vlanID != 0 || vlanPCP != 0) {
+ hdr.vlan = TRUE;
+ hdr.vlan_pcp = vlanPCP;
+ hdr.vlan_vid = vlanID;
+ AVB_LOGF_DEBUG("VLAN pcp=%d vid=%d", hdr.vlan_pcp, hdr.vlan_vid);
+ }
+ if (!openavbRawsockTxSetHdr(txSock, &hdr)) {
+ AVB_LOG_ERROR("TX socket Header Failure");
+ openavbAdpCloseSocket();
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+ return false;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+ return true;
+ }
+
+ AVB_LOG_ERROR("Invalid socket");
+ openavbAdpCloseSocket();
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+ return false;
+}
+
+static void openavbAdpMessageRxFrameParse(U8* payload, int payload_len, hdr_info_t *hdr)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ openavb_adp_control_header_t adpHeader;
+ openavb_adp_data_unit_t adpPdu;
+
+#if 0
+ AVB_LOGF_DEBUG("openavbAdpMessageRxFrameParse packet data (length %d):", payload_len);
+ AVB_LOG_BUFFER(AVB_LOG_LEVEL_DEBUG, payload, payload_len, 16);
+#endif
+
+ U8 *pSrc = payload;
+ {
+ // AVTP Control Header
+ openavb_adp_control_header_t *pDst = &adpHeader;
+
+ BIT_B2DNTOHB(pDst->cd, pSrc, 0x80, 7, 0);
+ BIT_B2DNTOHB(pDst->subtype, pSrc, 0x7f, 0, 1);
+ BIT_B2DNTOHB(pDst->sv, pSrc, 0x80, 7, 0);
+ BIT_B2DNTOHB(pDst->version, pSrc, 0x70, 4, 0);
+ BIT_B2DNTOHB(pDst->message_type, pSrc, 0x0f, 0, 1);
+ BIT_B2DNTOHB(pDst->valid_time, pSrc, 0xf800, 11, 0);
+ BIT_B2DNTOHS(pDst->control_data_length, pSrc, 0x07ff, 0, 2);
+ OCT_B2DMEMCP(pDst->entity_id, pSrc);
+ }
+
+ if (adpHeader.subtype == OPENAVB_ADP_AVTP_SUBTYPE &&
+ (adpHeader.message_type == OPENAVB_ADP_MESSAGE_TYPE_ENTITY_DISCOVER ||
+ (gAvdeccCfg.bFastConnectSupported && adpHeader.message_type == OPENAVB_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE))) {
+ // ADP PDU
+ openavb_adp_data_unit_t *pDst = &adpPdu;
+
+ 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->gptp_grandmaster_id, pSrc);
+ OCT_B2DNTOHB(pDst->gptp_domain_number, pSrc);
+ OCT_B2DMEMCP(pDst->reserved0, pSrc);
+ OCT_B2DNTOHS(pDst->identify_control_index, pSrc);
+ OCT_B2DNTOHS(pDst->interface_index, pSrc);
+ OCT_B2DMEMCP(pDst->association_id, pSrc);
+ OCT_B2DMEMCP(pDst->reserved1, pSrc);
+
+ if (adpHeader.message_type == OPENAVB_ADP_MESSAGE_TYPE_ENTITY_DISCOVER) {
+ // Update the interface state machine
+ openavbAdpSMAdvertiseInterfaceSet_entityID(adpHeader.entity_id);
+ openavbAdpSMAdvertiseInterfaceSet_rcvdDiscover(TRUE);
+ }
+ else {
+ // See if Fast Connect is waiting for this device to be available.
+ if (adpPdu.talker_stream_sources > 0) {
+ openavbAcmpSMListenerSet_talkerTestFastConnect(adpHeader.entity_id);
+ }
+ }
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+static void openavbAdpMessageRxFrameReceive(U32 timeoutUsec)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ hdr_info_t hdrInfo;
+ unsigned int offset, len;
+ U8 *pBuf, *pFrame;
+
+ memset(&hdrInfo, 0, sizeof(hdr_info_t));
+
+ pBuf = (U8 *)openavbRawsockGetRxFrame(rxSock, timeoutUsec, &offset, &len);
+ if (pBuf) {
+ pFrame = pBuf + offset;
+
+ offset = openavbRawsockRxParseHdr(rxSock, pBuf, &hdrInfo);
+ {
+#ifndef UBUNTU
+ if (hdrInfo.ethertype == ETHERTYPE_8021Q) {
+ // Oh! Need to look past the VLAN tag
+ U16 vlan_bits = ntohs(*(U16 *)(pFrame + offset));
+ hdrInfo.vlan = TRUE;
+ hdrInfo.vlan_vid = vlan_bits & 0x0FFF;
+ hdrInfo.vlan_pcp = (vlan_bits >> 13) & 0x0007;
+ offset += 2;
+ hdrInfo.ethertype = ntohs(*(U16 *)(pFrame + offset));
+ offset += 2;
+ }
+#endif
+
+ // Make sure that this is an AVTP packet
+ // (Should always be AVTP if it's to our AVTP-specific multicast address)
+ if (hdrInfo.ethertype == ETHERTYPE_AVTP) {
+ // parse the PDU only for ADP messages
+ if (*(pFrame + offset) == (0x80 | OPENAVB_ADP_AVTP_SUBTYPE)) {
+ if (memcmp(hdrInfo.shost, ADDR_PTR(&intfAddr), 6) != 0) { // Not from us!
+ openavbAdpMessageRxFrameParse(pFrame + offset, len - offset, &hdrInfo);
+ }
+ }
+ }
+ else {
+ AVB_LOG_WARNING("Received non-AVTP frame!");
+ AVB_LOGF_DEBUG("Unexpected packet data (length %d):", len);
+ AVB_LOG_BUFFER(AVB_LOG_LEVEL_DEBUG, pFrame, len, 16);
+ }
+ }
+
+ // Release the frame
+ openavbRawsockRelRxFrame(rxSock, pBuf);
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+
+void openavbAdpMessageTxFrame(U8 msgType, U8 *destAddr)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ U8 *pBuf;
+ U32 size;
+ unsigned int hdrlen = 0;
+
+ pBuf = openavbRawsockGetTxFrame(txSock, TRUE, &size);
+
+ if (!pBuf) {
+ AVB_LOG_ERROR("No TX buffer");
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+ return;
+ }
+
+ if (size < ADP_FRAME_LEN) {
+ AVB_LOG_ERROR("TX buffer too small");
+ openavbRawsockRelTxFrame(txSock, pBuf);
+ pBuf = NULL;
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+ return;
+ }
+
+ memset(pBuf, 0, ADP_FRAME_LEN);
+ openavbRawsockTxFillHdr(txSock, pBuf, &hdrlen);
+
+ if (destAddr)
+ memcpy(pBuf, destAddr, ETH_ALEN);
+
+ ADP_LOCK();
+ U8 *pDst = pBuf + hdrlen;
+ {
+ // AVTP Control Header
+ openavb_adp_control_header_t *pSrc = &openavbAdpSMGlobalVars.entityInfo.header;
+ BIT_D2BHTONB(pDst, pSrc->cd, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->subtype, 0, 1);
+ BIT_D2BHTONB(pDst, pSrc->sv, 7, 0);
+ BIT_D2BHTONB(pDst, pSrc->version, 4, 0);
+ BIT_D2BHTONB(pDst, msgType, 0, 1);
+ BIT_D2BHTONS(pDst, pSrc->valid_time, 11, 0);
+ BIT_D2BHTONS(pDst, pSrc->control_data_length, 0, 2);
+ OCT_D2BMEMCP(pDst, pSrc->entity_id);
+ }
+
+ {
+ // ADP PDU
+ openavb_adp_data_unit_t *pSrc = &openavbAdpSMGlobalVars.entityInfo.pdu;
+ 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->gptp_grandmaster_id);
+ OCT_D2BHTONB(pDst, pSrc->gptp_domain_number);
+ OCT_D2BMEMCP(pDst, pSrc->reserved0);
+ OCT_D2BHTONS(pDst, pSrc->identify_control_index);
+ OCT_D2BHTONS(pDst, pSrc->interface_index);
+ OCT_D2BMEMCP(pDst, pSrc->association_id);
+ OCT_D2BMEMCP(pDst, pSrc->reserved1);
+ }
+ ADP_UNLOCK();
+
+#if 0
+ AVB_LOGF_DEBUG("openavbAdpMessageTxFrame packet data (length %d):", hdrlen + AVTP_HDR_LEN + ADP_DATA_LEN);
+ AVB_LOG_BUFFER(AVB_LOG_LEVEL_DEBUG, pBuf, hdrlen + AVTP_HDR_LEN + ADP_DATA_LEN, 16);
+#endif
+
+ openavbRawsockTxFrameReady(txSock, pBuf, hdrlen + AVTP_HDR_LEN + ADP_DATA_LEN, 0);
+ openavbRawsockSend(txSock);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void* openavbAdpMessageRxThreadFn(void *pv)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ AVB_LOG_DEBUG("ADP Thread Started");
+ while (bRunning) {
+ // Try to get and process an ADP discovery message.
+ openavbAdpMessageRxFrameReceive(MICROSECONDS_PER_SECOND);
+ }
+ AVB_LOG_DEBUG("ADP Thread Done");
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+ return NULL;
+}
+
+openavbRC openavbAdpMessageHandlerStart()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ bRunning = TRUE;
+
+ if (openavbAdpOpenSocket((const char *)gAvdeccCfg.ifname, gAvdeccCfg.vlanID, gAvdeccCfg.vlanPCP)) {
+
+ // Start the RX thread
+ bool errResult;
+ THREAD_CREATE(openavbAdpMessageRxThread, openavbAdpMessageRxThread, NULL, openavbAdpMessageRxThreadFn, NULL);
+ THREAD_CHECK_ERROR(openavbAdpMessageRxThread, "Thread / task creation failed", errResult);
+ if (errResult) {
+ bRunning = FALSE;
+ openavbAdpCloseSocket();
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_FAILURE, AVB_TRACE_ADP);
+ }
+
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_ADP);
+ }
+
+ bRunning = FALSE;
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_FAILURE, AVB_TRACE_ADP);
+}
+
+void openavbAdpMessageHandlerStop()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ if (bRunning) {
+ bRunning = FALSE;
+ THREAD_JOIN(openavbAdpMessageRxThread, NULL);
+ openavbAdpCloseSocket();
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+openavbRC openavbAdpMessageSend(U8 messageType)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ // Note: this entire process of the GM ID is not as the 1722.1 spec expects.
+ // The openavbAdpSMAdvertiseInterfaceSet_advertisedGrandmasterID() should be called when the
+ // stack detects a GM change that will trigger an advertise. Instead we are detecting
+ // the GM change when we have are sending an advertise message. This means we will not have a timely
+ // new advertise in the event of a GM change. Additionally the handling the advertiseInterface var
+ // of GM ID is not normal since the GM ID is being placed directly into the PDU rather than getting
+ // pulled from the state machine var.
+ // AVDECC_TODO: This logic should change to detect GM change else where in the system and call the
+ // expected openavbAdpSMAdvertiseInterfaceSet_advertisedGrandmasterID() to start the advertise process.
+#ifdef AVB_PTP_AVAILABLE
+ openavb_adp_data_unit_t *pPdu = &openavbAdpSMGlobalVars.entityInfo.pdu;
+ openavbRC retCode = OPENAVB_PTP_FAILURE;
+ U32 ptpSharedMemoryEntryIndex;
+ retCode = openavbPtpFindLatestSharedMemoryEntry(&ptpSharedMemoryEntryIndex);
+ if (IS_OPENAVB_FAILURE(retCode)) {
+ AVB_LOG_INFO("Failed to find PTP shared memory entry.");
+ }
+ else {
+ if (memcmp(pPdu->gptp_grandmaster_id, openavbPtpGMChageTable.entry[ptpSharedMemoryEntryIndex].gmId, sizeof(pPdu->gptp_grandmaster_id))) {
+ memcpy(pPdu->gptp_grandmaster_id, openavbPtpGMChageTable.entry[ptpSharedMemoryEntryIndex].gmId, sizeof(pPdu->gptp_grandmaster_id));
+ openavbAdpSMAdvertiseInterfaceSet_advertisedGrandmasterID(pPdu->gptp_grandmaster_id);
+ }
+ }
+#else
+ openavb_adp_data_unit_t *pPdu = &openavbAdpSMGlobalVars.entityInfo.pdu;
+ uint8_t current_grandmaster_id[8];
+ if (!osalAVBGrandmasterGetCurrent(current_grandmaster_id, &(pPdu->gptp_domain_number)))
+ {
+ AVB_LOG_ERROR("osalAVBGrandmasterGetCurrent failure");
+ }
+ else if (memcmp(pPdu->gptp_grandmaster_id, current_grandmaster_id, sizeof(pPdu->gptp_grandmaster_id)))
+ {
+ memcpy(pPdu->gptp_grandmaster_id, current_grandmaster_id, sizeof(pPdu->gptp_grandmaster_id));
+ openavbAdpSMAdvertiseInterfaceSet_advertisedGrandmasterID(pPdu->gptp_grandmaster_id);
+ }
+#endif
+
+ openavbAdpMessageTxFrame(messageType, NULL);
+ AVB_RC_TRACE_RET(OPENAVB_AVDECC_SUCCESS, AVB_TRACE_ADP);
+}
+
diff --git a/lib/avtp_pipeline/adp/openavb_adp_message.h b/lib/avtp_pipeline/adp/openavb_adp_message.h
new file mode 100644
index 00000000..3769ebc6
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp_message.h
@@ -0,0 +1,50 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol Message Handler Interface
+ * MODULE SUMMARY : Interface for the the 1722.1 (AVDECC) discovery protocol message handlers
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_ADP_MESSAGE_H
+#define OPENAVB_ADP_MESSAGE_H 1
+
+#include "openavb_avdecc.h"
+
+openavbRC openavbAdpMessageHandlerStart(void);
+
+void openavbAdpMessageHandlerStop(void);
+
+openavbRC openavbAdpMessageSend(U8 messageType);
+
+#endif // OPENAVB_ADP_MESSAGE_H
diff --git a/lib/avtp_pipeline/adp/openavb_adp_pub.h b/lib/avtp_pipeline/adp/openavb_adp_pub.h
new file mode 100644
index 00000000..6e332486
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp_pub.h
@@ -0,0 +1,90 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol Public Interface
+ * MODULE SUMMARY : Public interface for the 1722.1 (AVDECC) discovery protocol
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_ADP_PUB_H
+#define OPENAVB_ADP_PUB_H 1
+
+// message_type field IEEE Std 1722.1-2013 clause 6.2.1.5
+#define OPENAVB_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE (0x00)
+#define OPENAVB_ADP_MESSAGE_TYPE_ENTITY_DEPARTING (0x01)
+#define OPENAVB_ADP_MESSAGE_TYPE_ENTITY_DISCOVER (0x02)
+
+// entity_capabilities field IEEE Std 1722.1-2013 clause 6.2.1.10
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_EFU_MODE (0x00000001)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_ADDRESS_ACCESS_SUPPORTED (0x00000002)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_GATEWAY_ENTITY (0x00000004)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_AEM_SUPPORTED (0x00000008)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_LEGACY_AVC (0x00000010)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_ASSOCIATION_ID_SUPPORTED (0x00000020)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_ASSOCIATION_ID_VALID (0x00000040)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_VENDOR_UNIQUE_SUPPORTED (0x00000080)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_CLASS_A_SUPPORTED (0x00000100)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_CLASS_B_SUPPORTED (0x00000200)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_GPTP_SUPPORTED (0x00000400)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_AEM_AUTHENTICATION_SUPPORTED (0x00000800)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_AEM_AUTHENTICATION_REQUIRED (0x00001000)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_AEM_PERSISTENT_ACQUIRE_SUPPORTED (0x00002000)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_AEM_IDENTIFY_CONTROL_INDEX_VALID (0x00004000)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_AEM_INTERFACE_INDEX_VALID (0x00008000)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_GENERAL_CONTROLLER_IGNORE (0x00010000)
+#define OPENAVB_ADP_ENTITY_CAPABILITIES_ENTITY_NOT_READY (0x00020000)
+
+// talker_capabilities field IEEE Std 1722.1-2013 clause 6.2.1.12
+#define OPENAVB_ADP_TALKER_CAPABILITIES_IMPLEMENTED (0x0001)
+#define OPENAVB_ADP_TALKER_CAPABILITIES_OTHER_SOURCE (0x0200)
+#define OPENAVB_ADP_TALKER_CAPABILITIES_CONTROL_SOURCE (0x0400)
+#define OPENAVB_ADP_TALKER_CAPABILITIES_MEDIA_CLOCK_SOURCE (0x0800)
+#define OPENAVB_ADP_TALKER_CAPABILITIES_SMPTE_SOURCE (0x1000)
+#define OPENAVB_ADP_TALKER_CAPABILITIES_MIDI_SOURCE (0x2000)
+#define OPENAVB_ADP_TALKER_CAPABILITIES_AUDIO_SOURCE (0x4000)
+#define OPENAVB_ADP_TALKER_CAPABILITIES_VIDEO_SOURCE (0x8000)
+
+// listener_capabilities field IEEE Std 1722.1-2013 clause 6.2.1.14
+#define OPENAVB_ADP_LISTENER_CAPABILITIES_IMPLEMENTED (0x0001)
+#define OPENAVB_ADP_LISTENER_CAPABILITIES_OTHER_SINK (0x0200)
+#define OPENAVB_ADP_LISTENER_CAPABILITIES_CONTROL_SINK (0x0400)
+#define OPENAVB_ADP_LISTENER_CAPABILITIES_MEDIA_CLOCK_SINK (0x0800)
+#define OPENAVB_ADP_LISTENER_CAPABILITIES_SMPTE_SINK (0x1000)
+#define OPENAVB_ADP_LISTENER_CAPABILITIES_MIDI_SINK (0x2000)
+#define OPENAVB_ADP_LISTENER_CAPABILITIES_AUDIO_SINK (0x4000)
+#define OPENAVB_ADP_LISTENER_CAPABILITIES_VIDEO_SINK (0x8000)
+
+// controller_capabilities field IEEE Std 1722.1-2013 clause 6.2.1.15
+#define OPENAVB_ADP_CONTROLLER_CAPABILITES_IMPLEMENTED (0x00000001)
+
+#endif // OPENAVB_ADP_PUB_H
diff --git a/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_entity.c b/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_entity.c
new file mode 100644
index 00000000..6a1e5d44
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_entity.c
@@ -0,0 +1,252 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol : Advertise Entity State Machine
+ * MODULE SUMMARY : Implements the AVDECC Discovery Protocol : Advertise Entity State Machine
+ * IEEE Std 1722.1-2013 clause 6.2.4.
+ ******************************************************************
+ */
+
+#include "openavb_platform.h"
+
+#include <errno.h>
+
+#define AVB_LOG_COMPONENT "ADP"
+#include "openavb_log.h"
+
+#include "openavb_time.h"
+#include "openavb_adp.h"
+#include "openavb_adp_sm_advertise_interface.h"
+#include "openavb_adp_sm_advertise_entity.h"
+
+typedef enum {
+ OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_INITIALIZE,
+ OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_ADVERTISE,
+ OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_RESET_WAIT,
+ OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_WAITING,
+ OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_TERMINATE,
+} openavb_adp_sm_advertise_entity_state_t;
+
+extern openavb_adp_sm_global_vars_t openavbAdpSMGlobalVars;
+extern openavb_adp_sm_advertise_interface_vars_t openavbAdpSMAdvertiseInterfaceVars;
+openavb_adp_sm_advertise_entity_vars_t openavbAdpSMAdvertiseEntityVars;
+
+extern MUTEX_HANDLE(openavbAdpMutex);
+#define ADP_LOCK() { MUTEX_CREATE_ERR(); MUTEX_LOCK(openavbAdpMutex); MUTEX_LOG_ERR("Mutex lock failure"); }
+#define ADP_UNLOCK() { MUTEX_CREATE_ERR(); MUTEX_UNLOCK(openavbAdpMutex); MUTEX_LOG_ERR("Mutex unlock failure"); }
+
+SEM_T(openavbAdpSMAdvertiseEntitySemaphore);
+THREAD_TYPE(openavbAdpSmAdvertiseEntityThread);
+THREAD_DEFINITON(openavbAdpSmAdvertiseEntityThread);
+
+void openavbAdpSMAdvertiseEntity_sendAvailable()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ openavbAdpSMAdvertiseInterfaceSet_doAdvertise(TRUE);
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseEntityStateMachine()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ bool bRunning = TRUE;
+
+ openavb_adp_sm_advertise_entity_state_t state = OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_INITIALIZE;
+
+ while (bRunning) {
+ switch (state) {
+ case OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_INITIALIZE:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_INITIALIZE");
+
+ ADP_LOCK();
+ openavbAdpSMGlobalVars.entityInfo.pdu.available_index = 0;
+ ADP_UNLOCK();
+
+ // The advertise interface will send the first advertisement on startup.
+ // This entity will be responsible for sending subsequent advertisements.
+ // This allows the advertise entity and advertise interface to startup without any inter-dependencies.
+ state = OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_RESET_WAIT;
+ }
+ break;
+ case OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_ADVERTISE:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_ADVERTISE");
+
+ openavbAdpSMAdvertiseEntity_sendAvailable();
+ ADP_LOCK();
+ openavbAdpSMAdvertiseEntityVars.needsAdvertise = FALSE;
+ ADP_UNLOCK();
+ state = OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_RESET_WAIT;
+ }
+ break;
+ case OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_RESET_WAIT:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_RESET_WAIT");
+
+ ADP_LOCK();
+ CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &openavbAdpSMAdvertiseEntityVars.reannounceTimerTimeout);
+ /* The advertisements should be sent at intervals of 1/4 valid_time, where valid_time is in 2-second units.
+ * See IEEE Std 1722.1-2013 clauses 6.2.1.6 and 6.2.4. */
+ U32 advDelayUsec = openavbAdpSMGlobalVars.entityInfo.header.valid_time / 2 * MICROSECONDS_PER_SECOND;
+ if (advDelayUsec < MICROSECONDS_PER_SECOND) {
+ advDelayUsec = MICROSECONDS_PER_SECOND;
+ }
+ openavbTimeTimespecAddUsec(&openavbAdpSMAdvertiseEntityVars.reannounceTimerTimeout, advDelayUsec);
+ ADP_UNLOCK();
+ state = OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_WAITING;
+ }
+ break;
+ case OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_WAITING:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_WAITING");
+
+ ADP_LOCK();
+ openavbAdpSMAdvertiseInterfaceSet_rcvdDiscover(FALSE);
+ openavbAdpSMGlobalVars.entityInfo.pdu.available_index++;
+ ADP_UNLOCK();
+
+ // Wait for change in state
+ while (state == OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_WAITING && bRunning) {
+ U32 timeoutMSec;
+ struct timespec now;
+ CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &now);
+ timeoutMSec = openavbTimeUntilMSec(&now, &openavbAdpSMAdvertiseEntityVars.reannounceTimerTimeout);
+
+ if (timeoutMSec == 0) {
+ /* No need to wait. */
+ state = OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_ADVERTISE;
+ }
+ else {
+ SEM_ERR_T(err);
+ SEM_TIMEDWAIT(openavbAdpSMAdvertiseEntitySemaphore, timeoutMSec, err);
+ if (!SEM_IS_ERR_NONE(err) && !SEM_IS_ERR_TIMEOUT(err)) { AVB_LOGF_WARNING("Semaphore error %d", err); }
+
+ if (openavbAdpSMAdvertiseEntityVars.doTerminate) {
+ bRunning = FALSE;
+ } else if (SEM_IS_ERR_TIMEOUT(err) ||
+ openavbAdpSMAdvertiseEntityVars.needsAdvertise) {
+ state = OPENAVB_ADP_SM_ADVERTISE_ENTITY_STATE_ADVERTISE;
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ AVB_LOG_ERROR("State: Unexpected!");
+ bRunning = FALSE; // Unexpected
+ break;
+ }
+ }
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void* openavbAdpSMAdvertiseEntityThreadFn(void *pv)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ openavbAdpSMAdvertiseEntityStateMachine();
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+ return NULL;
+}
+
+void openavbAdpSMAdvertiseEntityStart()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ SEM_ERR_T(err);
+ SEM_INIT(openavbAdpSMAdvertiseEntitySemaphore, 1, err);
+ SEM_LOG_ERR(err);
+
+ ADP_LOCK();
+ openavbAdpSMAdvertiseEntityVars.needsAdvertise = FALSE;
+ openavbAdpSMAdvertiseEntityVars.doTerminate = FALSE;
+ ADP_UNLOCK();
+
+ // Start the Advertise Entity State Machine
+ bool errResult;
+ THREAD_CREATE(openavbAdpSmAdvertiseEntityThread, openavbAdpSmAdvertiseEntityThread, NULL, openavbAdpSMAdvertiseEntityThreadFn, NULL);
+ THREAD_CHECK_ERROR(openavbAdpSmAdvertiseEntityThread, "Thread / task creation failed", errResult);
+ if (errResult); // Already reported
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseEntityStop()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ openavbAdpSMAdvertiseEntitySet_doTerminate(TRUE);
+ THREAD_JOIN(openavbAdpSmAdvertiseEntityThread, NULL);
+
+ SEM_ERR_T(err);
+ SEM_DESTROY(openavbAdpSMAdvertiseEntitySemaphore, err);
+ SEM_LOG_ERR(err);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseEntitySet_needsAdvertise(bool value)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ openavbAdpSMAdvertiseEntityVars.needsAdvertise = value;
+
+ SEM_ERR_T(err);
+ SEM_POST(openavbAdpSMAdvertiseEntitySemaphore, err);
+ SEM_LOG_ERR(err);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseEntitySet_doTerminate(bool value)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ openavbAdpSMAdvertiseEntityVars.doTerminate = value;
+
+ SEM_ERR_T(err);
+ SEM_POST(openavbAdpSMAdvertiseEntitySemaphore, err);
+ SEM_LOG_ERR(err);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+
+
+
+
diff --git a/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_entity.h b/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_entity.h
new file mode 100644
index 00000000..97f20e39
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_entity.h
@@ -0,0 +1,63 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol : Advertise Entity State Machine Interface
+ * MODULE SUMMARY : Interface for the AVDECC Discovery Protocol : Advertise Entity State Machine
+ * IEEE Std 1722.1-2013 clause 6.2.4.
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_ADP_SM_ADVERTISE_ENTITY_H
+#define OPENAVB_ADP_SM_ADVERTISE_ENTITY_H 1
+
+#include "openavb_adp.h"
+
+// State machine vars IEEE Std 1722.1-2013 clause 6.2.4.1
+typedef struct {
+ struct timespec reannounceTimerTimeout;
+ bool needsAdvertise;
+ bool doTerminate;
+} openavb_adp_sm_advertise_entity_vars_t;
+
+// State machine functions IEEE Std 1722.1-2013 clause 6.2.4.2
+void openavbAdpSMAdvertiseEntity_sendAvailable(void);
+
+void openavbAdpSMAdvertiseEntityStart(void);
+void openavbAdpSMAdvertiseEntityStop(void);
+
+// Accessors
+void openavbAdpSMAdvertiseEntitySet_needsAdvertise(bool value);
+void openavbAdpSMAdvertiseEntitySet_doTerminate(bool value);
+
+
+#endif // OPENAVB_ADP_SM_ADVERTISE_ENTITY_H
diff --git a/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_interface.c b/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_interface.c
new file mode 100644
index 00000000..1bc1f101
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_interface.c
@@ -0,0 +1,341 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol : Advertise interface State Machine
+ * MODULE SUMMARY : Implements the AVDECC Discovery Protocol : Advertise Interface State Machine
+ * IEEE Std 1722.1-2013 clause 6.2.5.
+ *
+ * Note: 1722.1 allows for multiple Interface state machines,
+ * one per AVB Interface descriptor. This implementation
+ * assumes one AVB Interface descriptor exists in the Entity Model.
+ ******************************************************************
+ */
+
+#include "openavb_platform.h"
+
+#include <signal.h>
+
+#define AVB_LOG_COMPONENT "ADP"
+#include "openavb_log.h"
+
+#include "openavb_adp_sm_advertise_interface.h"
+#include "openavb_adp_sm_advertise_entity.h"
+#include "openavb_adp_message.h"
+
+#define OPENAVB_ADP_SM_ADVERTISE_INTERFACE_WAIT_TIME_USEC 10000
+
+typedef enum {
+ OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_INITIALIZE,
+ OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_WAITING,
+ OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_DEPARTING,
+ OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_ADVERTISE,
+ OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_RECEIVED_DISCOVER,
+ OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_UPDATE_GM,
+ OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_LINK_STATE_CHANGE,
+} openavb_adp_sm_advertise_interface_state_t;
+
+extern openavb_avdecc_cfg_t gAvdeccCfg;
+extern openavb_adp_sm_global_vars_t openavbAdpSMGlobalVars;
+extern openavb_adp_sm_advertise_entity_vars_t openavbAdpSMAdvertiseEntityVars;
+openavb_adp_sm_advertise_interface_vars_t openavbAdpSMAdvertiseInterfaceVars;
+
+extern MUTEX_HANDLE(openavbAdpMutex);
+#define ADP_LOCK() { MUTEX_CREATE_ERR(); MUTEX_LOCK(openavbAdpMutex); MUTEX_LOG_ERR("Mutex lock failure"); }
+#define ADP_UNLOCK() { MUTEX_CREATE_ERR(); MUTEX_UNLOCK(openavbAdpMutex); MUTEX_LOG_ERR("Mutex unlock failure"); }
+
+SEM_T(openavbAdpSMAdvertiseInterfaceSemaphore);
+THREAD_TYPE(openavbAdpSmAdvertiseInterfaceThread);
+THREAD_DEFINITON(openavbAdpSmAdvertiseInterfaceThread);
+
+void openavbAdpSMAdvertiseInterface_txEntityAvailable()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ ADP_LOCK();
+ openavbAdpSMGlobalVars.entityInfo.header.valid_time = gAvdeccCfg.valid_time;
+ ADP_UNLOCK();
+ openavbAdpMessageSend(OPENAVB_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE);
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseInterface_txEntityDeparting()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ ADP_LOCK();
+ openavbAdpSMGlobalVars.entityInfo.header.valid_time = 0;
+ ADP_UNLOCK();
+ openavbAdpMessageSend(OPENAVB_ADP_MESSAGE_TYPE_ENTITY_DEPARTING);
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseInterfaceStateMachine()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ bool bRunning = TRUE;
+
+ openavb_adp_sm_advertise_interface_state_t state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_INITIALIZE;
+
+ while (bRunning) {
+ switch (state) {
+ case OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_INITIALIZE:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_INITIALIZE");
+
+ ADP_LOCK();
+ openavbAdpSMAdvertiseInterfaceVars.lastLinkIsUp = FALSE;
+ openavbAdpSMAdvertiseInterfaceVars.doAdvertise = FALSE; // Per 1722.1 What's next notes
+ memcpy(openavbAdpSMAdvertiseInterfaceVars.advertisedGrandmasterID,
+ openavbAdpSMGlobalVars.entityInfo.pdu.gptp_grandmaster_id,
+ sizeof(openavbAdpSMGlobalVars.entityInfo.pdu.gptp_grandmaster_id));
+ ADP_UNLOCK();
+
+ // This interface will send the first advertisement on startup.
+ // The advertise entity will be responsible for sending subsequent advertisements.
+ // This allows the advertise entity and advertise interface to startup without any inter-dependencies.
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_ADVERTISE;
+ }
+ break;
+ case OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_WAITING:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_WAITING");
+
+ // openavbAdpSMAdvertiseInterfaceVars.rcvdDiscover = FALSE; // Per 1722.1 What's next notes. Note: setting this elsewhere otherwise incorrect behavior.
+ // openavbAdpSMGlobalVars.entityInfo.pdu.available_index++; // Per 1722.1 What's next notes
+
+ // Wait for a change in state
+ while (state == OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_WAITING && bRunning) {
+ SEM_ERR_T(err);
+ SEM_WAIT(openavbAdpSMAdvertiseInterfaceSemaphore, err);
+ if (!SEM_IS_ERR_NONE(err)) { AVB_LOGF_WARNING("Semaphore error %d", err); }
+
+ ADP_LOCK();
+ if (openavbAdpSMAdvertiseInterfaceVars.doTerminate)
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_DEPARTING;
+ else if (openavbAdpSMAdvertiseInterfaceVars.doAdvertise)
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_ADVERTISE;
+ else if (openavbAdpSMAdvertiseInterfaceVars.rcvdDiscover)
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_RECEIVED_DISCOVER;
+ else if (memcmp(openavbAdpSMAdvertiseInterfaceVars.advertisedGrandmasterID,
+ openavbAdpSMGlobalVars.entityInfo.pdu.gptp_grandmaster_id,
+ sizeof(openavbAdpSMGlobalVars.entityInfo.pdu.gptp_grandmaster_id)))
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_UPDATE_GM;
+ else if (openavbAdpSMAdvertiseInterfaceVars.lastLinkIsUp != openavbAdpSMAdvertiseInterfaceVars.linkIsUp)
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_LINK_STATE_CHANGE;
+ ADP_UNLOCK();
+ }
+ }
+ break;
+ case OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_DEPARTING:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_DEPARTING");
+
+ openavbAdpSMAdvertiseInterface_txEntityDeparting();
+ bRunning = FALSE;
+ }
+ break;
+ case OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_ADVERTISE:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_ADVERTISE");
+
+ ADP_LOCK();
+ openavbAdpSMAdvertiseInterfaceVars.doAdvertise = FALSE; // Per 1722.1 What's next notes
+ ADP_UNLOCK();
+ openavbAdpSMAdvertiseInterface_txEntityAvailable();
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_WAITING;
+ }
+ break;
+ case OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_RECEIVED_DISCOVER:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_RECEIVED_DISCOVER");
+
+ ADP_LOCK();
+ openavbAdpSMAdvertiseInterfaceVars.rcvdDiscover = FALSE; // Not per spec but is needed.
+ if (((U64)*openavbAdpSMAdvertiseInterfaceVars.entityID == 0x0000000000000000L) ||
+ ((U64)*openavbAdpSMAdvertiseInterfaceVars.entityID == (U64)*openavbAdpSMGlobalVars.entityInfo.header.entity_id)) {
+ openavbAdpSMAdvertiseEntitySet_needsAdvertise(TRUE);
+ }
+ ADP_UNLOCK();
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_WAITING;
+ }
+ break;
+ case OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_UPDATE_GM:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_UPDATE_GM");
+
+ openavbAdpSMAdvertiseEntitySet_needsAdvertise(TRUE);
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_WAITING;
+ }
+ break;
+ case OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_LINK_STATE_CHANGE:
+ {
+ AVB_TRACE_LINE(AVB_TRACE_ADP);
+ AVB_LOG_DEBUG("State: OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_LINK_STATE_CHANGE");
+
+ openavbAdpSMAdvertiseInterfaceVars.lastLinkIsUp = openavbAdpSMAdvertiseInterfaceVars.linkIsUp;
+ if (openavbAdpSMAdvertiseInterfaceVars.linkIsUp) {
+ openavbAdpSMAdvertiseEntitySet_needsAdvertise(TRUE);
+ }
+ state = OPENAVB_ADP_SM_ADVERTISE_INTERFACE_STATE_WAITING;
+ }
+ break;
+ default:
+ AVB_LOG_ERROR("State: Unexpected!");
+ bRunning = FALSE; // Unexpected
+ break;
+ }
+ }
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void* openavbAdpSMAdvertiseInterfaceThreadFn(void *pv)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ openavbAdpSMAdvertiseInterfaceStateMachine();
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+ return NULL;
+}
+
+
+void openavbAdpSMAdvertiseInterfaceStart()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ SEM_ERR_T(err);
+ SEM_INIT(openavbAdpSMAdvertiseInterfaceSemaphore, 1, err);
+ SEM_LOG_ERR(err);
+
+ ADP_LOCK();
+ memset(&openavbAdpSMAdvertiseInterfaceVars, 0, sizeof(openavbAdpSMAdvertiseInterfaceVars));
+ ADP_UNLOCK();
+
+ // Start the Advertise Entity State Machine
+ bool errResult;
+ THREAD_CREATE(openavbAdpSmAdvertiseInterfaceThread, openavbAdpSmAdvertiseInterfaceThread, NULL, openavbAdpSMAdvertiseInterfaceThreadFn, NULL);
+ THREAD_CHECK_ERROR(openavbAdpSmAdvertiseInterfaceThread, "Thread / task creation failed", errResult);
+ if (errResult); // Already reported
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseInterfaceStop()
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+
+ openavbAdpSMAdvertiseInterfaceSet_doTerminate(TRUE);
+ THREAD_JOIN(openavbAdpSmAdvertiseInterfaceThread, NULL);
+
+ SEM_ERR_T(err);
+ SEM_DESTROY(openavbAdpSMAdvertiseInterfaceSemaphore, err);
+ SEM_LOG_ERR(err);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseInterfaceSet_advertisedGrandmasterID(U8 *pValue)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ if (pValue) {
+ memcpy(openavbAdpSMAdvertiseInterfaceVars.advertisedGrandmasterID, pValue, sizeof(openavbAdpSMAdvertiseInterfaceVars.advertisedGrandmasterID));
+ }
+
+ SEM_ERR_T(err);
+ SEM_POST(openavbAdpSMAdvertiseInterfaceSemaphore, err);
+ SEM_LOG_ERR(err);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseInterfaceSet_rcvdDiscover(bool value)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ openavbAdpSMAdvertiseInterfaceVars.rcvdDiscover = value;
+
+ SEM_ERR_T(err);
+ SEM_POST(openavbAdpSMAdvertiseInterfaceSemaphore, err);
+ SEM_LOG_ERR(err);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseInterfaceSet_entityID(U8 *pValue)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ if (pValue) {
+ memcpy(openavbAdpSMAdvertiseInterfaceVars.entityID, pValue, sizeof(openavbAdpSMAdvertiseInterfaceVars.entityID));
+ }
+ // sem post is done when the rcvdDiscover is set.
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseInterfaceSet_doTerminate(bool value)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ openavbAdpSMAdvertiseInterfaceVars.doTerminate = value;
+
+ SEM_ERR_T(err);
+ SEM_POST(openavbAdpSMAdvertiseInterfaceSemaphore, err);
+ SEM_LOG_ERR(err);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseInterfaceSet_doAdvertise(bool value)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ openavbAdpSMAdvertiseInterfaceVars.doAdvertise = value;
+
+ SEM_ERR_T(err);
+ SEM_POST(openavbAdpSMAdvertiseInterfaceSemaphore, err);
+ SEM_LOG_ERR(err);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+void openavbAdpSMAdvertiseInterfaceSet_linkIsUp(bool value)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ADP);
+ openavbAdpSMAdvertiseInterfaceVars.linkIsUp = value;
+
+ SEM_ERR_T(err);
+ SEM_POST(openavbAdpSMAdvertiseInterfaceSemaphore, err);
+ SEM_LOG_ERR(err);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ADP);
+}
+
+
diff --git a/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_interface.h b/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_interface.h
new file mode 100644
index 00000000..4c32b5f7
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp_sm_advertise_interface.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 : ADP - AVDECC Discovery Protocol : Advertise interface State Machine Interface
+ * MODULE SUMMARY : Interface for the AVDECC Discovery Protocol : Advertise Interface State Machine
+ * IEEE Std 1722.1-2013 clause 6.2.5.
+ ******************************************************************
+ */
+
+#ifndef OPENAVB_ADP_SM_ADVERTISE_INTERFACE_H
+#define OPENAVB_ADP_SM_ADVERTISE_INTERFACE_H 1
+
+#include "openavb_adp.h"
+
+// State machine vars IEEE Std 1722.1-2013 clause 6.2.5.1
+typedef struct {
+ U8 advertisedGrandmasterID[8];
+ bool rcvdDiscover;
+ U8 entityID[8];
+ bool doTerminate;
+ bool doAdvertise;
+ bool linkIsUp;
+ bool lastLinkIsUp;
+} openavb_adp_sm_advertise_interface_vars_t;
+
+// State machine functions IEEE Std 1722.1-2013 clause 6.2.5.2
+void openavbAdpSMAdvertiseInterface_txEntityAvailable(void);
+void openavbAdpSMAdvertiseInterface_txEntityDeparting(void);
+
+void openavbAdpSMAdvertiseInterfaceStart(void);
+void openavbAdpSMAdvertiseInterfaceStop(void);
+
+// Accessors
+void openavbAdpSMAdvertiseInterfaceSet_advertisedGrandmasterID(U8 *pValue);
+void openavbAdpSMAdvertiseInterfaceSet_rcvdDiscover(bool value);
+void openavbAdpSMAdvertiseInterfaceSet_entityID(U8 *pValue);
+void openavbAdpSMAdvertiseInterfaceSet_doTerminate(bool value);
+void openavbAdpSMAdvertiseInterfaceSet_doAdvertise(bool value);
+void openavbAdpSMAdvertiseInterfaceSet_linkIsUp(bool value);
+
+
+
+#endif // OPENAVB_ADP_SM_ADVERTISE_INTERFACE_H
diff --git a/lib/avtp_pipeline/adp/openavb_adp_sm_discovery.c b/lib/avtp_pipeline/adp/openavb_adp_sm_discovery.c
new file mode 100644
index 00000000..b4c1390a
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp_sm_discovery.c
@@ -0,0 +1,45 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol : Discovery State Machine
+ * MODULE SUMMARY : Implements the AVDECC Discovery Protocol : Discovery State Machine
+ * IEEE Std 1722.1-2013 clause 6.2.6.
+ ******************************************************************
+ */
+
+// Not implemented in OPENAVB phase 1 support of 1722.1
+
+#define AVB_LOG_COMPONENT "ADP"
+#include "openavb_log.h"
+
+#include "openavb_adp_sm_discovery.h"
diff --git a/lib/avtp_pipeline/adp/openavb_adp_sm_discovery.h b/lib/avtp_pipeline/adp/openavb_adp_sm_discovery.h
new file mode 100644
index 00000000..7c6cb8be
--- /dev/null
+++ b/lib/avtp_pipeline/adp/openavb_adp_sm_discovery.h
@@ -0,0 +1,48 @@
+/*************************************************************************************************************
+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 : ADP - AVDECC Discovery Protocol : Discovery State Machine Interface
+ * MODULE SUMMARY : Interface for the Implements the AVDECC Discovery Protocol : Discovery State Machine
+ * IEEE Std 1722.1-2013 clause 6.2.6.
+ ******************************************************************
+ */
+
+// Not implemented in OPENAVB phase 1 support of 1722.1
+
+#ifndef OPENAVB_ADP_SM_DISCOVERY_H
+#define OPENAVB_ADP_SM_DISCOVERY_H 1
+
+#include "openavb_adp.h"
+
+
+#endif // OPENAVB_ADP_SM_DISCOVERY_H