summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c39
-rw-r--r--lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c26
-rw-r--r--lib/avtp_pipeline/adp/openavb_adp_message.c8
-rw-r--r--lib/avtp_pipeline/aecp/openavb_aecp.h44
-rw-r--r--lib/avtp_pipeline/aecp/openavb_aecp_message.c64
-rw-r--r--lib/avtp_pipeline/aecp/openavb_aecp_sm_entity_model_entity.c292
-rw-r--r--lib/avtp_pipeline/aem/openavb_descriptor_stream_io_pub.h9
-rw-r--r--lib/avtp_pipeline/avdecc/openavb_avdecc_pipeline_interaction_pub.h19
-rw-r--r--lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h44
-rw-r--r--lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_client.c163
-rw-r--r--lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_server.c52
-rw-r--r--lib/avtp_pipeline/endpoint/openavb_endpoint.c25
-rw-r--r--lib/avtp_pipeline/endpoint/openavb_endpoint.h26
-rw-r--r--lib/avtp_pipeline/endpoint/openavb_endpoint_client.c30
-rw-r--r--lib/avtp_pipeline/endpoint/openavb_endpoint_server.c48
-rw-r--r--lib/avtp_pipeline/include/openavb_pub.h2
-rw-r--r--lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_pipeline_interaction.c88
-rw-r--r--lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_osal.h3
-rw-r--r--lib/avtp_pipeline/tl/openavb_talker.h17
-rw-r--r--lib/avtp_pipeline/tl/openavb_talker_endpoint.c22
-rw-r--r--lib/avtp_pipeline/tl/openavb_talker_no_endpoint.c40
-rwxr-xr-xlib/avtp_pipeline/tl/openavb_tl.c2
-rwxr-xr-xlib/avtp_pipeline/tl/openavb_tl_pub.h19
23 files changed, 844 insertions, 238 deletions
diff --git a/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c b/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c
index 3b950f4b..27e2ae6f 100644
--- a/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c
+++ b/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c
@@ -292,7 +292,7 @@ U8 openavbAcmpSMListener_connectListener(openavb_acmp_ACMPCommandResponse_t *res
U8 openavbAcmpSMListener_disconnectListener(openavb_acmp_ACMPCommandResponse_t *response)
{
AVB_TRACE_ENTRY(AVB_TRACE_ACMP);
- U8 retStatus;
+ U8 retStatus;
openavb_acmp_ListenerStreamInfo_t *pListenerStreamInfo = openavbArrayDataIdx(openavbAcmpSMListenerVars.listenerStreamInfos, response->listener_unique_id);
if (pListenerStreamInfo) {
@@ -505,23 +505,32 @@ void openavbAcmpSMListenerStateMachine()
// Save the state for this connection, so it can potentially be fast connected later.
// TODO: Add fast connect support for STREAMING_WAIT connections by handling START_STREAMING and STOP_STREAMING commands.
- if (gAvdeccCfg.bFastConnectSupported &&
- status == OPENAVB_ACMP_STATUS_SUCCESS &&
- (pRcvdCmdResp->flags & OPENAVB_ACMP_FLAG_STREAMING_WAIT) == 0) {
+ if (status == OPENAVB_ACMP_STATUS_SUCCESS) {
openavb_aem_descriptor_stream_io_t *pDescriptorStreamInput = openavbAemGetDescriptor(openavbAemGetConfigIdx(), OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT, pRcvdCmdResp->listener_unique_id);
if (pDescriptorStreamInput != NULL && pDescriptorStreamInput->stream != NULL) {
- if (openavbAvdeccSaveState(
- pDescriptorStreamInput->stream,
- (pRcvdCmdResp->flags & (OPENAVB_ACMP_FLAG_CLASS_B | OPENAVB_ACMP_FLAG_SUPPORTS_ENCRYPTED | OPENAVB_ACMP_FLAG_ENCRYPTED_PDU)),
- pRcvdCmdResp->talker_unique_id,
- pRcvdCmdResp->talker_entity_id,
- pRcvdCmdResp->controller_entity_id)) {
- // Let the Controller know that the state is saved.
- response.flags |= OPENAVB_ACMP_FLAG_SAVED_STATE;
- }
- if (pDescriptorStreamInput->fast_connect_status >= OPENAVB_FAST_CONNECT_STATUS_IN_PROGRESS) {
- pDescriptorStreamInput->fast_connect_status = OPENAVB_FAST_CONNECT_STATUS_SUCCEEDED;
+ if (gAvdeccCfg.bFastConnectSupported &&
+ (pRcvdCmdResp->flags & OPENAVB_ACMP_FLAG_STREAMING_WAIT) == 0) {
+ if (openavbAvdeccSaveState(
+ pDescriptorStreamInput->stream,
+ (pRcvdCmdResp->flags & (OPENAVB_ACMP_FLAG_CLASS_B | OPENAVB_ACMP_FLAG_SUPPORTS_ENCRYPTED | OPENAVB_ACMP_FLAG_ENCRYPTED_PDU)),
+ pRcvdCmdResp->talker_unique_id,
+ pRcvdCmdResp->talker_entity_id,
+ pRcvdCmdResp->controller_entity_id)) {
+ // Let the Controller know that the state is saved.
+ response.flags |= OPENAVB_ACMP_FLAG_SAVED_STATE;
+ }
+ if (pDescriptorStreamInput->fast_connect_status >= OPENAVB_FAST_CONNECT_STATUS_IN_PROGRESS) {
+ pDescriptorStreamInput->fast_connect_status = OPENAVB_FAST_CONNECT_STATUS_SUCCEEDED;
+ }
}
+
+ // Save the response flags for reference later.
+ pDescriptorStreamInput->acmp_flags = response.flags;
+
+ // Save the stream information for reference later.
+ memcpy(pDescriptorStreamInput->acmp_stream_id, pRcvdCmdResp->stream_id, 8);
+ memcpy(pDescriptorStreamInput->acmp_dest_addr, pRcvdCmdResp->stream_dest_mac, 6);
+ pDescriptorStreamInput->acmp_stream_vlan_id = pRcvdCmdResp->stream_vlan_id;
}
}
diff --git a/lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c b/lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c
index 53d77758..f0818a24 100644
--- a/lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c
+++ b/lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c
@@ -136,6 +136,16 @@ U8 openavbAcmpSMTalker_connectTalker(openavb_acmp_ACMPCommandResponse_t *command
else {
// Already connected, so return the current status.
AVB_LOG_DEBUG("Sending immediate response to CONNECT_TX_COMMAND");
+ U16 configIdx = openavbAemGetConfigIdx();
+ openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput = openavbAemGetDescriptor(configIdx, OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT, command->talker_unique_id);
+ if (pDescriptorStreamOutput) {
+ command->flags = (pDescriptorStreamOutput->acmp_flags &
+ (OPENAVB_ACMP_FLAG_CLASS_B |
+ OPENAVB_ACMP_FLAG_FAST_CONNECT |
+ OPENAVB_ACMP_FLAG_SAVED_STATE |
+ OPENAVB_ACMP_FLAG_SUPPORTS_ENCRYPTED |
+ OPENAVB_ACMP_FLAG_ENCRYPTED_PDU));
+ }
memcpy(command->stream_id, pTalkerStreamInfo->stream_id, sizeof(command->stream_id));
memcpy(command->stream_dest_mac, pTalkerStreamInfo->stream_dest_mac, sizeof(command->stream_dest_mac));
command->stream_vlan_id = pTalkerStreamInfo->stream_vlan_id;
@@ -620,6 +630,13 @@ void openavbAcmpSMTalker_updateStreamInfo(openavb_tl_data_cfg_t *pCfg)
openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput = openavbAemGetDescriptor(configIdx, OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT, talker_unique_id);
if (pDescriptorStreamOutput && pDescriptorStreamOutput->stream == pCfg) {
+ // Verify that the destination address is valid.
+ if (pCfg->dest_addr.mac == NULL ||
+ memcmp(pCfg->dest_addr.buffer.ether_addr_octet, "\x00\x00\x00\x00\x00\x00", 6) == 0) {
+ AVB_LOG_DEBUG("stream_dest_mac not yet valid. Continue to wait.");
+ continue;
+ }
+
// We will handle the GET_TX_CONNECTION_RESPONSE command response here.
AVB_LOGF_DEBUG("Received an update for talker_unique_id %d", talker_unique_id);
openavb_acmp_ACMPCommandResponse_t *response = pTalkerStreamInfo->waiting_on_talker;
@@ -638,6 +655,15 @@ void openavbAcmpSMTalker_updateStreamInfo(openavb_tl_data_cfg_t *pCfg)
response->stream_vlan_id = pTalkerStreamInfo->stream_vlan_id;
response->connection_count = pTalkerStreamInfo->connection_count;
+ // Save the response flags for reference later.
+ pDescriptorStreamOutput->acmp_flags = response->flags;
+
+ // Save the stream information for reference later.
+ // (This is currently only used by Listeners, but it doesn't hurt to have it just in case.)
+ memcpy(pDescriptorStreamOutput->acmp_stream_id, response->stream_id, 8);
+ memcpy(pDescriptorStreamOutput->acmp_dest_addr, response->stream_dest_mac, 6);
+ pDescriptorStreamOutput->acmp_stream_vlan_id = response->stream_vlan_id;
+
// Send the response.
openavbAcmpSMTalker_txResponse(OPENAVB_ACMP_MESSAGE_TYPE_CONNECT_TX_RESPONSE, response, OPENAVB_ACMP_STATUS_SUCCESS);
AVB_LOG_DEBUG("Sent a CONNECT_TX_RESPONSE command");
diff --git a/lib/avtp_pipeline/adp/openavb_adp_message.c b/lib/avtp_pipeline/adp/openavb_adp_message.c
index 70b7a808..3f695101 100644
--- a/lib/avtp_pipeline/adp/openavb_adp_message.c
+++ b/lib/avtp_pipeline/adp/openavb_adp_message.c
@@ -242,7 +242,7 @@ static void openavbAdpMessageRxFrameReceive(U32 timeoutUsec)
U8 *pBuf, *pFrame;
memset(&hdrInfo, 0, sizeof(hdr_info_t));
-
+
pBuf = (U8 *)openavbRawsockGetRxFrame(rxSock, timeoutUsec, &offset, &len);
if (pBuf) {
pFrame = pBuf + offset;
@@ -370,7 +370,7 @@ void* openavbAdpMessageRxThreadFn(void *pv)
AVB_LOG_DEBUG("ADP Thread Started");
while (bRunning) {
- // Try to get and process an ADP discovery message.
+ // Try to get and process an ADP discovery message.
openavbAdpMessageRxFrameReceive(MICROSECONDS_PER_SECOND);
}
AVB_LOG_DEBUG("ADP Thread Done");
@@ -423,12 +423,12 @@ openavbRC openavbAdpMessageSend(U8 messageType)
// 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
+ // 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
+ // 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;
diff --git a/lib/avtp_pipeline/aecp/openavb_aecp.h b/lib/avtp_pipeline/aecp/openavb_aecp.h
index 404ca09e..cdd57b70 100644
--- a/lib/avtp_pipeline/aecp/openavb_aecp.h
+++ b/lib/avtp_pipeline/aecp/openavb_aecp.h
@@ -111,7 +111,7 @@ typedef struct {
U8 descriptor_data[508];
} openavb_aecp_response_data_read_descriptor_t;
-// SET_STREAM_FORMAT comamnd and response IEEE Std 1722.1-2013 clause 7.4.9
+// SET_STREAM_FORMAT command and response IEEE Std 1722.1-2013 clause 7.4.9
typedef struct {
U16 descriptor_type;
U16 descriptor_index;
@@ -131,6 +131,44 @@ typedef struct {
U8 stream_format[8]; // Stream format sub details aren't needed for this command
} openavb_aecp_response_data_get_stream_format_t;
+// SET_STREAM_INFO command and response IEEE Std 1722.1-2013 clause 7.4.15
+typedef struct {
+ U16 descriptor_type;
+ U16 descriptor_index;
+ U32 flags;
+ U8 stream_format[8];
+ U8 stream_id[8];
+ U32 msrp_accumulated_latency;
+ U8 stream_dest_mac[6];
+ U8 msrp_failure_code;
+ U8 reserved_1;
+ U8 msrp_failure_bridge_id[8];
+ U16 stream_vlan_id;
+ U16 reserved_2;
+} openavb_aecp_commandresponse_data_set_stream_info_t;
+
+// GET_STREAM_INFO command IEEE Std 1722.1-2013 clause 7.4.16
+typedef struct {
+ U16 descriptor_type;
+ U16 descriptor_index;
+} openavb_aecp_command_data_get_stream_info_t;
+
+// GET_STREAM_INFO response IEEE Std 1722.1-2013 clause 7.4.16
+typedef struct {
+ U16 descriptor_type;
+ U16 descriptor_index;
+ U32 flags;
+ U8 stream_format[8];
+ U8 stream_id[8];
+ U32 msrp_accumulated_latency;
+ U8 stream_dest_mac[6];
+ U8 msrp_failure_code;
+ U8 reserved_1;
+ U8 msrp_failure_bridge_id[8];
+ U16 stream_vlan_id;
+ U16 reserved_2;
+} openavb_aecp_response_data_get_stream_info_t;
+
// SET_SAMPLING_RATE command and response IEEE Std 1722.1-2013 clause 7.4.21
typedef struct {
U16 descriptor_type;
@@ -321,6 +359,10 @@ typedef struct {
openavb_aecp_commandresponse_data_set_stream_format_t setStreamFormatRsp;
openavb_aecp_command_data_get_stream_format_t getStreamFormatCmd;
openavb_aecp_response_data_get_stream_format_t getStreamFormatRsp;
+ openavb_aecp_commandresponse_data_set_stream_info_t setStreamInfoCmd;
+ openavb_aecp_commandresponse_data_set_stream_info_t setStreamInfoRsp;
+ openavb_aecp_command_data_get_stream_info_t getStreamInfoCmd;
+ openavb_aecp_response_data_get_stream_info_t getStreamInfoRsp;
openavb_aecp_commandresponse_data_set_sampling_rate_t setSamplingRateCmd;
openavb_aecp_commandresponse_data_set_sampling_rate_t setSamplingRateRsp;
openavb_aecp_command_data_get_sampling_rate_t getSamplingRateCmd;
diff --git a/lib/avtp_pipeline/aecp/openavb_aecp_message.c b/lib/avtp_pipeline/aecp/openavb_aecp_message.c
index e9be6788..b2e55bee 100644
--- a/lib/avtp_pipeline/aecp/openavb_aecp_message.c
+++ b/lib/avtp_pipeline/aecp/openavb_aecp_message.c
@@ -247,8 +247,28 @@ static void openavbAecpMessageRxFrameParse(U8* payload, int payload_len, hdr_inf
case OPENAVB_AEM_COMMAND_CODE_GET_SENSOR_FORMAT:
break;
case OPENAVB_AEM_COMMAND_CODE_SET_STREAM_INFO:
+ {
+ openavb_aecp_commandresponse_data_set_stream_info_t *pDst = &openavbAecpCommandResponse->entityModelPdu.command_data.setStreamInfoCmd;
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ OCT_B2DNTOHL(pDst->flags, pSrc);
+ OCT_B2DMEMCP(pDst->stream_format, pSrc);
+ OCT_B2DMEMCP(pDst->stream_id, pSrc);
+ OCT_B2DNTOHL(pDst->msrp_accumulated_latency, pSrc);
+ OCT_B2DMEMCP(pDst->stream_dest_mac, pSrc);
+ OCT_B2DNTOHB(pDst->msrp_failure_code, pSrc);
+ OCT_B2DNTOHB(pDst->reserved_1, pSrc);
+ OCT_B2DMEMCP(pDst->msrp_failure_bridge_id, pSrc);
+ OCT_B2DNTOHS(pDst->stream_vlan_id, pSrc);
+ OCT_B2DNTOHS(pDst->reserved_2, pSrc);
+ }
break;
case OPENAVB_AEM_COMMAND_CODE_GET_STREAM_INFO:
+ {
+ openavb_aecp_command_data_get_stream_info_t *pDst = &openavbAecpCommandResponse->entityModelPdu.command_data.getStreamInfoCmd;
+ OCT_B2DNTOHS(pDst->descriptor_type, pSrc);
+ OCT_B2DNTOHS(pDst->descriptor_index, pSrc);
+ }
break;
case OPENAVB_AEM_COMMAND_CODE_SET_NAME:
break;
@@ -487,9 +507,15 @@ static void openavbAecpMessageRxFrameParse(U8* payload, int payload_len, hdr_inf
break;
}
- // Notify the state machine of the command request
- // The buffer will be deleted once the request is handled.
- openavbAecpSMEntityModelEntitySet_rcvdCommand(openavbAecpCommandResponse);
+ if (pSrc - payload <= payload_len) {
+ // Notify the state machine of the command request
+ // The buffer will be deleted once the request is handled.
+ openavbAecpSMEntityModelEntitySet_rcvdCommand(openavbAecpCommandResponse);
+ }
+ else {
+ AVB_LOGF_ERROR("Expected packet of size %d, but received one of size %d. Discarding.", pSrc - payload, payload_len);
+ free(openavbAecpCommandResponse);
+ }
}
AVB_TRACE_EXIT(AVB_TRACE_AECP);
@@ -504,7 +530,7 @@ static void openavbAecpMessageRxFrameReceive(U32 timeoutUsec)
U8 *pBuf, *pFrame;
memset(&hdrInfo, 0, sizeof(hdr_info_t));
-
+
pBuf = (U8 *)openavbRawsockGetRxFrame(rxSock, timeoutUsec, &offset, &len);
if (pBuf) {
pFrame = pBuf + offset;
@@ -667,8 +693,38 @@ void openavbAecpMessageTxFrame(openavb_aecp_AEMCommandResponse_t *AEMCommandResp
case OPENAVB_AEM_COMMAND_CODE_GET_SENSOR_FORMAT:
break;
case OPENAVB_AEM_COMMAND_CODE_SET_STREAM_INFO:
+ {
+ openavb_aecp_commandresponse_data_set_stream_info_t *pSrc = &AEMCommandResponse->entityModelPdu.command_data.setStreamInfoRsp;
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BHTONL(pDst, pSrc->flags);
+ OCT_D2BMEMCP(pDst, pSrc->stream_format);
+ OCT_D2BMEMCP(pDst, pSrc->stream_id);
+ OCT_D2BHTONL(pDst, pSrc->msrp_accumulated_latency);
+ OCT_D2BMEMCP(pDst, pSrc->stream_dest_mac);
+ OCT_D2BHTONB(pDst, pSrc->msrp_failure_code);
+ OCT_D2BHTONB(pDst, pSrc->reserved_1);
+ OCT_D2BMEMCP(pDst, pSrc->msrp_failure_bridge_id);
+ OCT_D2BHTONS(pDst, pSrc->stream_vlan_id);
+ OCT_D2BHTONS(pDst, pSrc->reserved_2);
+ }
break;
case OPENAVB_AEM_COMMAND_CODE_GET_STREAM_INFO:
+ {
+ openavb_aecp_response_data_get_stream_info_t *pSrc = &AEMCommandResponse->entityModelPdu.command_data.getStreamInfoRsp;
+ OCT_D2BHTONS(pDst, pSrc->descriptor_type);
+ OCT_D2BHTONS(pDst, pSrc->descriptor_index);
+ OCT_D2BHTONL(pDst, pSrc->flags);
+ OCT_D2BMEMCP(pDst, pSrc->stream_format);
+ OCT_D2BMEMCP(pDst, pSrc->stream_id);
+ OCT_D2BHTONL(pDst, pSrc->msrp_accumulated_latency);
+ OCT_D2BMEMCP(pDst, pSrc->stream_dest_mac);
+ OCT_D2BHTONB(pDst, pSrc->msrp_failure_code);
+ OCT_D2BHTONB(pDst, pSrc->reserved_1);
+ OCT_D2BMEMCP(pDst, pSrc->msrp_failure_bridge_id);
+ OCT_D2BHTONS(pDst, pSrc->stream_vlan_id);
+ OCT_D2BHTONS(pDst, pSrc->reserved_2);
+ }
break;
case OPENAVB_AEM_COMMAND_CODE_SET_NAME:
break;
diff --git a/lib/avtp_pipeline/aecp/openavb_aecp_sm_entity_model_entity.c b/lib/avtp_pipeline/aecp/openavb_aecp_sm_entity_model_entity.c
index 3013642e..e570f654 100644
--- a/lib/avtp_pipeline/aecp/openavb_aecp_sm_entity_model_entity.c
+++ b/lib/avtp_pipeline/aecp/openavb_aecp_sm_entity_model_entity.c
@@ -147,6 +147,7 @@ void acquireEntity()
AEM_LOCK();
if (pCommand->entityModelPdu.command_data.acquireEntityCmd.flags & OPENAVB_AEM_ACQUIRE_ENTITY_COMMAND_FLAG_RELEASE) {
// AVDECC_TODO - need to add mutex for the entity model
+ AVB_LOG_DEBUG("Entity Released");
pAem->entityAcquired = FALSE;
}
else {
@@ -158,11 +159,16 @@ void acquireEntity()
memcpy(pCommand->entityModelPdu.command_data.acquireEntityRsp.owner_id, pAem->acquiredControllerId, sizeof(pCommand->commonPdu.controller_entity_id));
}
else {
- pAem->entityAcquired = TRUE;
- memcpy(pAem->acquiredControllerId, pCommand->commonPdu.controller_entity_id, sizeof(pAem->acquiredControllerId));
- memcpy(pCommand->entityModelPdu.command_data.acquireEntityRsp.owner_id, pCommand->commonPdu.controller_entity_id, sizeof(pCommand->commonPdu.controller_entity_id));
+ // Entity was already acquired by this controller, so indicate a successful acquisition.
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
}
}
+ else {
+ pAem->entityAcquired = TRUE;
+ memcpy(pAem->acquiredControllerId, pCommand->commonPdu.controller_entity_id, sizeof(pAem->acquiredControllerId));
+ memcpy(pCommand->entityModelPdu.command_data.acquireEntityRsp.owner_id, pCommand->commonPdu.controller_entity_id, sizeof(pCommand->commonPdu.controller_entity_id));
+ AVB_LOGF_DEBUG("Entity Acquired by " ENTITYID_FORMAT, pCommand->entityModelPdu.command_data.acquireEntityRsp.owner_id);
+ }
}
AEM_UNLOCK();
}
@@ -193,7 +199,7 @@ void lockEntity()
bool processCommandCheckRestriction_CorrectController()
{
AVB_TRACE_ENTRY(AVB_TRACE_AECP);
- bool bResult = FALSE;
+ bool bResult = TRUE;
openavb_aecp_AEMCommandResponse_t *pCommand = openavbAecpSMEntityModelEntityVars.rcvdCommand;
if (!pCommand) {
@@ -209,11 +215,19 @@ bool processCommandCheckRestriction_CorrectController()
if (memcmp(pAem->acquiredControllerId, pCommand->commonPdu.controller_entity_id, sizeof(pAem->acquiredControllerId)) == 0) {
bResult = TRUE;
}
+ else {
+ AVB_LOGF_DEBUG("Access denied to " ENTITYID_FORMAT " as " ENTITYID_FORMAT " already acquired it", pCommand->commonPdu.controller_entity_id, pAem->acquiredControllerId);
+ bResult = FALSE;
+ }
}
else if (pAem->entityLocked) {
- if (memcmp(pAem->lockedControllerId, pCommand->commonPdu.controller_entity_id, sizeof(pAem->acquiredControllerId)) == 0) {
+ if (memcmp(pAem->lockedControllerId, pCommand->commonPdu.controller_entity_id, sizeof(pAem->lockedControllerId)) == 0) {
bResult = TRUE;
}
+ else {
+ AVB_LOGF_DEBUG("Access denied to " ENTITYID_FORMAT " as " ENTITYID_FORMAT " already locked it", pCommand->commonPdu.controller_entity_id, pAem->lockedControllerId);
+ bResult = FALSE;
+ }
}
AEM_UNLOCK();
}
@@ -223,26 +237,20 @@ bool processCommandCheckRestriction_CorrectController()
}
// Returns TRUE the stream_input or stream_output descriptor is currently not running.
+// NOTE: This function is using the last reported state from the client, not the state AVDECC last told the client to be in.
bool processCommandCheckRestriction_StreamNotRunning(U16 descriptor_type, U16 descriptor_index)
{
AVB_TRACE_ENTRY(AVB_TRACE_AECP);
- bool bResult = FALSE;
+ bool bResult = TRUE;
- if (descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT) {
+ if (descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT ||
+ descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT) {
U16 configIdx = openavbAemGetConfigIdx();
- openavb_aem_descriptor_stream_io_t *pDescriptorStreamInput = openavbAemGetDescriptor(configIdx, descriptor_type, descriptor_index);
- if (pDescriptorStreamInput) {
- if (!openavbAVDECCListenerIsStreaming(pDescriptorStreamInput, configIdx)) {
- bResult = TRUE;
- }
- }
- }
- else if (descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT) {
- U16 configIdx = openavbAemGetConfigIdx();
- openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput = openavbAemGetDescriptor(configIdx, descriptor_type, descriptor_index);
- if (pDescriptorStreamOutput) {
- if (!openavbAVDECCTalkerIsStreaming(pDescriptorStreamOutput, configIdx)) {
- bResult = TRUE;
+ openavb_aem_descriptor_stream_io_t *pDescriptorStreamIO = openavbAemGetDescriptor(configIdx, descriptor_type, descriptor_index);
+ if (pDescriptorStreamIO) {
+ openavbAvdeccMsgStateType_t state = openavbAVDECCGetStreamingState(pDescriptorStreamIO, configIdx);
+ if (state >= OPENAVB_AVDECC_MSG_RUNNING) {
+ bResult = FALSE;
}
}
}
@@ -323,8 +331,15 @@ void processCommand()
if (pCmd->descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT) {
openavb_aem_descriptor_stream_io_t *pDescriptorStreamInput = openavbAemGetDescriptor(openavbAemGetConfigIdx(), pCmd->descriptor_type, pCmd->descriptor_index);
if (pDescriptorStreamInput) {
- memcpy(&pDescriptorStreamInput->current_format, pCmd->stream_format, sizeof(pDescriptorStreamInput->current_format));
- pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+ if (memcmp(&pDescriptorStreamInput->current_format, pCmd->stream_format, sizeof(pDescriptorStreamInput->current_format)) == 0) {
+ // No change needed.
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+ }
+ else {
+ // AVDECC_TODO: Verify that the stream format is supported, and notify the Listener of the change.
+ //memcpy(&pDescriptorStreamInput->current_format, pCmd->stream_format, sizeof(pDescriptorStreamInput->current_format));
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NOT_SUPPORTED;
+ }
}
else {
pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NO_SUCH_DESCRIPTOR;
@@ -333,8 +348,15 @@ void processCommand()
else if (pCmd->descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT) {
openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput = openavbAemGetDescriptor(openavbAemGetConfigIdx(), pCmd->descriptor_type, pCmd->descriptor_index);
if (pDescriptorStreamOutput) {
- memcpy(&pDescriptorStreamOutput->current_format, pCmd->stream_format, sizeof(pDescriptorStreamOutput->current_format));
- pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+ if (memcmp(&pDescriptorStreamOutput->current_format, pCmd->stream_format, sizeof(pDescriptorStreamOutput->current_format)) == 0) {
+ // No change needed.
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+ }
+ else {
+ // AVDECC_TODO: Verify that the stream format is supported, and notify the Talker of the change.
+ //memcpy(&pDescriptorStreamOutput->current_format, pCmd->stream_format, sizeof(pDescriptorStreamOutput->current_format));
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NOT_SUPPORTED;
+ }
}
else {
pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NO_SUCH_DESCRIPTOR;
@@ -395,8 +417,202 @@ void processCommand()
case OPENAVB_AEM_COMMAND_CODE_GET_SENSOR_FORMAT:
break;
case OPENAVB_AEM_COMMAND_CODE_SET_STREAM_INFO:
+ {
+ openavb_aecp_commandresponse_data_set_stream_info_t *pCmd = &pCommand->entityModelPdu.command_data.setStreamInfoCmd;
+ openavb_aecp_commandresponse_data_set_stream_info_t *pRsp = &pCommand->entityModelPdu.command_data.setStreamInfoRsp;
+
+ if (processCommandCheckRestriction_CorrectController()) {
+ if (processCommandCheckRestriction_StreamNotRunning(pCmd->descriptor_type, pCmd->descriptor_index)) {
+ if (pCmd->descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT ||
+ pCmd->descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT) {
+ openavb_aem_descriptor_stream_io_t *pDescriptorStreamIO = openavbAemGetDescriptor(openavbAemGetConfigIdx(), pCmd->descriptor_type, pCmd->descriptor_index);
+ if (pDescriptorStreamIO) {
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+
+ if ((pCmd->flags & OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_FORMAT_VALID) != 0) {
+ if (memcmp(&pDescriptorStreamIO->current_format, pCmd->stream_format, sizeof(pDescriptorStreamIO->current_format)) != 0) {
+ // AVDECC_TODO: Verify that the stream format is supported, and notify the Listener of the change.
+ //memcpy(&pDescriptorStreamInput->current_format, pCmd->stream_format, sizeof(pDescriptorStreamInput->current_format));
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NOT_SUPPORTED;
+ }
+ }
+
+ // AVDECC_TODO: Add support for ENCRYPTED_PDU.
+ if ((pCmd->flags & OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_ENCRYPTED_PDU) != 0) {
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NOT_SUPPORTED;
+ }
+
+ // AVDECC_TODO: Add support for accumulated latency.
+ // For now, just clear the flags and values.
+ pRsp->flags &= ~OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_MSRP_ACC_LAT_VALID;
+ pRsp->msrp_accumulated_latency = 0;
+ pRsp->flags &= ~OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_MSRP_FAILURE_VALID;
+ pRsp->msrp_failure_code = 0;
+ memset(pRsp->msrp_failure_bridge_id, 0, sizeof(pRsp->msrp_failure_bridge_id));
+
+ if (pCommand->headers.status != OPENAVB_AEM_COMMAND_STATUS_SUCCESS) {
+ // As there are already issues, don't bother trying anything following this.
+ }
+ else if (pCmd->descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT) {
+ // If the controller is trying to set the streaming information for the Listener, this is a problem.
+ // The Listener gets this information from the Talker when the connection starts, so setting it here makes no sense.
+ // We also ignore the CLASS_A flag (or absence of it), as the Talker will indicate that value as well.
+ if ((pCmd->flags &
+ (OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_ID_VALID |
+ OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_DEST_MAC_VALID |
+ OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_VLAN_ID_VALID)) != 0) {
+ AVB_LOG_ERROR("SET_STREAM_INFO cannot set stream parameters for Listener");
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_BAD_ARGUMENTS;
+ }
+ }
+ else {
+ // Get the streaming values to send to the Talker.
+ // Invalid values used to indicate those that should not be changed.
+ U8 sr_class = ((pCmd->flags & OPENAVB_ACMP_FLAG_CLASS_B) != 0 ? SR_CLASS_B : SR_CLASS_A);
+ U8 stream_id_valid = FALSE;
+ U8 stream_src_mac[6] = {0, 0, 0, 0, 0, 0};
+ U16 stream_uid = 0;
+ U8 stream_dest_valid = FALSE;
+ U8 stream_dest_mac[6] = {0, 0, 0, 0, 0, 0};
+ U8 stream_vlan_id_valid = FALSE;
+ U16 stream_vlan_id = 0;
+ if ((pCmd->flags & OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_ID_VALID) != 0) {
+ stream_id_valid = TRUE;
+ memcpy(stream_src_mac, pCmd->stream_format, 6);
+ stream_uid = ntohs(*(U16*) (pCmd->stream_format + 6));
+ AVB_LOGF_INFO("AVDECC-specified Stream ID " ETH_FORMAT "/%u for Talker", ETH_OCTETS(stream_src_mac), stream_uid);
+ }
+ if ((pCmd->flags & OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_DEST_MAC_VALID) != 0) {
+ stream_dest_valid = TRUE;
+ memcpy(stream_dest_mac, pCmd->stream_dest_mac, 6);
+ AVB_LOGF_INFO("AVDECC-specified Stream Dest Addr " ETH_FORMAT " for Talker", ETH_OCTETS(stream_dest_mac));
+ }
+ if ((pCmd->flags & OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_VLAN_ID_VALID) != 0) {
+ stream_vlan_id_valid = TRUE;
+ stream_vlan_id = pCmd->stream_vlan_id;
+ AVB_LOGF_INFO("AVDECC-specified Stream VLAN ID %u for Talker", stream_vlan_id);
+ }
+
+ // Pass the values to the Talker.
+ if (!openavbAVDECCSetTalkerStreamInfo(
+ pDescriptorStreamIO, sr_class,
+ stream_id_valid, stream_src_mac, stream_uid,
+ stream_dest_valid, stream_dest_mac,
+ stream_vlan_id_valid, stream_vlan_id)) {
+ AVB_LOG_ERROR("SET_STREAM_INFO error setting stream parameters for Talker");
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NOT_SUPPORTED;
+ }
+ }
+ }
+ else {
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NO_SUCH_DESCRIPTOR;
+ }
+ }
+ }
+ else {
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_STREAM_IS_RUNNING;
+ }
+ }
+ else {
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_ENTITY_ACQUIRED;
+ }
+ }
break;
case OPENAVB_AEM_COMMAND_CODE_GET_STREAM_INFO:
+ {
+ openavb_aecp_command_data_get_stream_info_t *pCmd = &pCommand->entityModelPdu.command_data.getStreamInfoCmd;
+ openavb_aecp_response_data_get_stream_info_t *pRsp = &pCommand->entityModelPdu.command_data.getStreamInfoRsp;
+
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NO_SUCH_DESCRIPTOR;
+
+ if (pRsp->descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT ||
+ pRsp->descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT) {
+ U16 configIdx = openavbAemGetConfigIdx();
+ openavb_aem_descriptor_stream_io_t *pDescriptorStreamIO = openavbAemGetDescriptor(configIdx, pCmd->descriptor_type, pCmd->descriptor_index);
+ if (pDescriptorStreamIO && pDescriptorStreamIO->stream) {
+ openavbAvdeccMsgStateType_t clientState = openavbAVDECCGetStreamingState(pDescriptorStreamIO, configIdx);
+
+ // Get the flags for the current status.
+ pRsp->flags = 0;
+ if (pDescriptorStreamIO->fast_connect_status >= OPENAVB_FAST_CONNECT_STATUS_IN_PROGRESS) {
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_FAST_CONNECT;
+ }
+ if (openavbAvdeccGetSaveStateInfo(pDescriptorStreamIO->stream, NULL, NULL, NULL, NULL)) {
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_SAVED_STATE;
+ }
+ if (clientState >= OPENAVB_AVDECC_MSG_RUNNING) {
+ pRsp->flags |= (pDescriptorStreamIO->acmp_flags &
+ (OPENAVB_ACMP_FLAG_CLASS_B |
+ OPENAVB_ACMP_FLAG_FAST_CONNECT |
+ OPENAVB_ACMP_FLAG_SUPPORTS_ENCRYPTED |
+ OPENAVB_ACMP_FLAG_ENCRYPTED_PDU));
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_CONNECTED;
+ if (clientState == OPENAVB_AVDECC_MSG_PAUSED) {
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAMING_WAIT;
+ }
+
+ // For the Listener, use the streaming values we received from the current Talker.
+ if (pRsp->descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT) {
+ // Get the Stream ID.
+ memcpy(pRsp->stream_id, pDescriptorStreamIO->acmp_stream_id, 8);
+ if (memcmp(pRsp->stream_id, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) != 0) {
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_ID_VALID;
+ }
+
+ // Get the Destination MAC Address.
+ memcpy(pRsp->stream_dest_mac, pDescriptorStreamIO->acmp_dest_addr, 6);
+ if (memcmp(pRsp->stream_id, "\x00\x00\x00\x00\x00\x00", 6) != 0) {
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_DEST_MAC_VALID;
+ }
+
+ // Get the Stream VLAN ID if the other stream identifiers are valid.
+ if ((pRsp->flags & (OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_ID_VALID | OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_DEST_MAC_VALID)) ==
+ (OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_ID_VALID | OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_DEST_MAC_VALID)) {
+ pRsp->stream_vlan_id = pDescriptorStreamIO->acmp_stream_vlan_id;
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_VLAN_ID_VALID;
+ }
+ }
+ }
+
+ // For the Talker, use the values we are or will use for a connection.
+ if (pRsp->descriptor_type == OPENAVB_AEM_DESCRIPTOR_STREAM_OUTPUT) {
+ // Get the Stream ID.
+ if (pDescriptorStreamIO->stream->stream_addr.mac != NULL) {
+ memcpy(pRsp->stream_id, pDescriptorStreamIO->stream->stream_addr.buffer.ether_addr_octet, 6);
+ *(U16*)(pRsp->stream_id) = htons(pDescriptorStreamIO->stream->stream_uid);
+ if (memcmp(pRsp->stream_id, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) != 0) {
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_ID_VALID;
+ }
+ }
+
+ // Get the Destination MAC Address.
+ if (pDescriptorStreamIO->stream->dest_addr.mac != NULL) {
+ memcpy(pRsp->stream_dest_mac, pDescriptorStreamIO->stream->dest_addr.buffer.ether_addr_octet, 6);
+ if (memcmp(pRsp->stream_id, "\x00\x00\x00\x00\x00\x00", 6) != 0) {
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_DEST_MAC_VALID;
+ }
+ }
+
+ // Get the Stream VLAN ID.
+ if (pDescriptorStreamIO->stream->vlan_id != 0) {
+ pRsp->stream_vlan_id = pDescriptorStreamIO->stream->vlan_id;
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_VLAN_ID_VALID;
+ }
+ }
+
+ // AVDECC_TODO: Add TALKER_FAILED flag support.
+
+ // Get the stream format.
+ openavbAemStreamFormatToBuf(&pDescriptorStreamIO->current_format, pRsp->stream_format);
+ pRsp->flags |= OPENAVB_AEM_SET_STREAM_INFO_COMMAND_FLAG_STREAM_FORMAT_VALID;
+
+ // AVDECC_TODO: Add support for msrp_accumulated_latency
+ // AVDECC_TODO: Add support for msrp_failure_bridge_id, and msrp_failure_code
+
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+ }
+ }
+ }
break;
case OPENAVB_AEM_COMMAND_CODE_SET_NAME:
break;
@@ -415,8 +631,15 @@ void processCommand()
if (pCmd->descriptor_type == OPENAVB_AEM_DESCRIPTOR_AUDIO_UNIT) {
openavb_aem_descriptor_audio_unit_t *pDescriptorAudioUnit = openavbAemGetDescriptor(openavbAemGetConfigIdx(), pCmd->descriptor_type, pCmd->descriptor_index);
if (pDescriptorAudioUnit) {
- memcpy(&pDescriptorAudioUnit->current_sampling_rate, pCmd->sampling_rate, sizeof(pDescriptorAudioUnit->current_sampling_rate));
- pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+ if (memcmp(&pDescriptorAudioUnit->current_sampling_rate, pCmd->sampling_rate, sizeof(pDescriptorAudioUnit->current_sampling_rate)) == 0) {
+ // No change needed.
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+ }
+ else {
+ // AVDECC_TODO: Verify that the sample rate is supported, and notify the Talker/Listener of the change.
+ //memcpy(&pDescriptorAudioUnit->current_sampling_rate, pCmd->sampling_rate, sizeof(pDescriptorAudioUnit->current_sampling_rate));
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NOT_SUPPORTED;
+ }
}
else {
pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NO_SUCH_DESCRIPTOR;
@@ -466,8 +689,15 @@ void processCommand()
if (pCmd->descriptor_type == OPENAVB_AEM_DESCRIPTOR_CLOCK_DOMAIN) {
openavb_aem_descriptor_clock_domain_t *pDescriptorClockDomain = openavbAemGetDescriptor(openavbAemGetConfigIdx(), pCmd->descriptor_type, pCmd->descriptor_index);
if (pDescriptorClockDomain) {
- pDescriptorClockDomain->clock_source_index = pCmd->clock_source_index;
- pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+ if (pDescriptorClockDomain->clock_source_index == pCmd->clock_source_index) {
+ // No change needed.
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_SUCCESS;
+ }
+ else {
+ // AVDECC_TODO: Verify that the clock source is supported, and notify the Talker/Listener of the change.
+ //pDescriptorClockDomain->clock_source_index = pCmd->clock_source_index;
+ pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NOT_SUPPORTED;
+ }
}
else {
pCommand->headers.status = OPENAVB_AEM_COMMAND_STATUS_NO_SUCH_DESCRIPTOR;
@@ -998,9 +1228,9 @@ void openavbAecpSMEntityModelEntityStateMachine()
state = OPENAVB_AECP_SM_ENTITY_MODEL_ENTITY_STATE_WAITING;
break;
-
+
default:
- AVB_LOG_DEBUG("State: Unknown");
+ AVB_LOG_ERROR("State: Unknown");
bRunning = FALSE; // Unexpected
break;
@@ -1090,7 +1320,7 @@ void openavbAecpSMEntityModelEntitySet_rcvdCommand(openavb_aecp_AEMCommandRespon
openavbAecpSMGlobalVars.myEntityID,
sizeof(openavbAecpSMGlobalVars.myEntityID)) != 0) {
// Not intended for us.
- free(openavbAecpSMEntityModelEntityVars.rcvdCommand);
+ free(rcvdCommand);
return;
}
diff --git a/lib/avtp_pipeline/aem/openavb_descriptor_stream_io_pub.h b/lib/avtp_pipeline/aem/openavb_descriptor_stream_io_pub.h
index 5ab4ccb5..91fc384f 100644
--- a/lib/avtp_pipeline/aem/openavb_descriptor_stream_io_pub.h
+++ b/lib/avtp_pipeline/aem/openavb_descriptor_stream_io_pub.h
@@ -86,6 +86,15 @@ typedef struct {
U8 fast_connect_talker_entity_id[8];
struct timespec fast_connect_start_time;
+ // OPENAVB_ACMP_FLAG values from CONNECT_TX_RESPONSE or CONNECT_RX_RESPONSE.
+ U16 acmp_flags;
+
+ // Streaming values for GET_STREAM_INFO from CONNECT_TX_RESPONSE or CONNECT_RX_RESPONSE.
+ // These values are currently only used for the Listener, as the Talker can get them from it's current configuration.
+ U8 acmp_stream_id[8];
+ U8 acmp_dest_addr[6];
+ U16 acmp_stream_vlan_id;
+
// Also save a pointer to the supplied stream information.
const openavb_tl_data_cfg_t *stream;
diff --git a/lib/avtp_pipeline/avdecc/openavb_avdecc_pipeline_interaction_pub.h b/lib/avtp_pipeline/avdecc/openavb_avdecc_pipeline_interaction_pub.h
index 9ba33ed0..c7edac96 100644
--- a/lib/avtp_pipeline/avdecc/openavb_avdecc_pipeline_interaction_pub.h
+++ b/lib/avtp_pipeline/avdecc/openavb_avdecc_pipeline_interaction_pub.h
@@ -34,6 +34,7 @@ https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
#include "openavb_acmp.h"
#include "openavb_descriptor_stream_io_pub.h"
+#include "openavb_avdecc_msg.h"
// Run a single talker or listener.
@@ -44,12 +45,22 @@ bool openavbAVDECCRunTalker(openavb_aem_descriptor_stream_io_t *pDescriptorStrea
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 TalkerStrreamInfo will be filled.
+// 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);
-// Determine if the talker or listener is streaming.
-bool openavbAVDECCListenerIsStreaming(openavb_aem_descriptor_stream_io_t *pDescriptorStreamInput, U16 configIdx);
-bool openavbAVDECCTalkerIsStreaming(openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput, U16 configIdx);
+// 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);
diff --git a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h
index 01c6bde9..5efd90d2 100644
--- a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h
+++ b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h
@@ -79,21 +79,22 @@ void openavbAvdeccMsgSrvrService(void);
typedef enum {
OPENAVB_AVDECC_MSG_UNKNOWN = 0,
OPENAVB_AVDECC_MSG_STOPPED,
+ OPENAVB_AVDECC_MSG_STOPPED_UNEXPECTEDLY,
OPENAVB_AVDECC_MSG_RUNNING,
OPENAVB_AVDECC_MSG_PAUSED,
- OPENAVB_AVDECC_MSG_STOPPED_UNEXPECTEDLY,
} openavbAvdeccMsgStateType_t;
typedef enum {
// Client-to-Server messages
OPENAVB_AVDECC_MSG_VERSION_REQUEST,
OPENAVB_AVDECC_MSG_CLIENT_INIT_IDENTIFY,
- OPENAVB_AVDECC_MSG_TALKER_STREAM_ID,
+ OPENAVB_AVDECC_MSG_C2S_TALKER_STREAM_ID,
OPENAVB_AVDECC_MSG_CLIENT_CHANGE_NOTIFICATION,
// Server-to-Client messages
OPENAVB_AVDECC_MSG_VERSION_CALLBACK,
OPENAVB_AVDECC_MSG_LISTENER_STREAM_ID,
+ OPENAVB_AVDECC_MSG_S2C_TALKER_STREAM_ID,
OPENAVB_AVDECC_MSG_CLIENT_CHANGE_REQUEST,
} openavbAvdeccMsgType_t;
@@ -109,11 +110,12 @@ typedef struct {
} openavbAvdeccMsgParams_ClientInitIdentify_t;
typedef struct {
+ U8 sr_class; // SR_CLASS_A or SR_CLASS_B
U8 stream_src_mac[6]; // MAC Address for the Talker
U16 stream_uid; // Stream ID value
U8 stream_dest_mac[6]; // Multicast address for the stream
U16 stream_vlan_id; // VLAN ID of the stream
-} openavbAvdeccMsgParams_TalkerStreamID_t;
+} openavbAvdeccMsgParams_C2S_TalkerStreamID_t;
typedef struct {
U8 current_state; // Convert to openavbAvdeccMsgStateType_t
@@ -127,6 +129,7 @@ typedef struct {
} openavbAvdeccMsgParams_VersionCallback_t;
typedef struct {
+ U8 sr_class; // SR_CLASS_A or SR_CLASS_B
U8 stream_src_mac[6]; // MAC Address for the Talker
U16 stream_uid; // Stream ID value
U8 stream_dest_mac[6]; // Multicast address for the stream
@@ -134,6 +137,17 @@ typedef struct {
} openavbAvdeccMsgParams_ListenerStreamID_t;
typedef struct {
+ U8 sr_class; // SR_CLASS_A or SR_CLASS_B
+ U8 stream_id_valid; // The stream_src_mac and stream_uid values were supplied
+ U8 stream_src_mac[6]; // MAC Address for the Talker
+ U16 stream_uid; // Stream ID value
+ U8 stream_dest_valid; // The stream_dest_mac value was supplied
+ U8 stream_dest_mac[6]; // Multicast address for the stream
+ U8 stream_vlan_id_valid; // The stream_vlan_id value was supplied
+ U16 stream_vlan_id; // VLAN ID of the stream
+} openavbAvdeccMsgParams_S2C_TalkerStreamID_t;
+
+typedef struct {
U8 desired_state; // Convert to openavbAvdeccMsgStateType_t
} openavbAvdeccMsgParams_ClientChangeRequest_t;
@@ -171,13 +185,27 @@ void openavbAvdeccMsgClntCheckVerMatchesSrvr(int h, U32 AVBVersion);
bool openavbAvdeccMsgClntInitIdentify(int avdeccMsgHandle, const char * friendly_name, U8 talker);
bool openavbAvdeccMsgSrvrHndlInitIdentifyFromClient(int avdeccMsgHandle, char * friendly_name, U8 talker);
-// Client notify the server of the stream values for the Talker to use.
-bool openavbAvdeccMsgClntTalkerStreamID(int avdeccMsgHandle, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id);
-bool openavbAvdeccMsgSrvrHndlTalkerStreamIDFromClient(int avdeccMsgHandle, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id);
+// Client notify the server of the stream values the Talker will be using.
+bool openavbAvdeccMsgClntTalkerStreamID(int avdeccMsgHandle, U8 sr_class, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id);
+bool openavbAvdeccMsgSrvrHndlTalkerStreamIDFromClient(int avdeccMsgHandle, U8 sr_class, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id);
// Server notify the client of the stream values for the Listener to use.
-bool openavbAvdeccMsgSrvrListenerStreamID(int avdeccMsgHandle, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id);
-bool openavbAvdeccMsgClntHndlListenerStreamIDFromServer(int avdeccMsgHandle, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id);
+bool openavbAvdeccMsgSrvrListenerStreamID(int avdeccMsgHandle, U8 sr_class, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id);
+bool openavbAvdeccMsgClntHndlListenerStreamIDFromServer(int avdeccMsgHandle, U8 sr_class, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id);
+
+// Server notify the client of the stream values for the Talker to use (supplied by the AVDECC controller).
+bool openavbAvdeccMsgSrvrTalkerStreamID(
+ int avdeccMsgHandle,
+ 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);
+bool openavbAvdeccMsgClntHndlTalkerStreamIDFromServer(
+ int avdeccMsgHandle,
+ 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);
// Server state change requests, and client notifications of state changes.
bool openavbAvdeccMsgSrvrChangeRequest(int avdeccMsgHandle, openavbAvdeccMsgStateType_t desiredState);
diff --git a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_client.c b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_client.c
index f2addd41..01c827f3 100644
--- a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_client.c
+++ b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_client.c
@@ -86,9 +86,21 @@ static bool openavbAvdeccMsgClntReceiveFromServer(int avdeccMsgHandle, openavbAv
case OPENAVB_AVDECC_MSG_LISTENER_STREAM_ID:
AVB_LOG_DEBUG("Message received: OPENAVB_AVDECC_MSG_LISTENER_STREAM_ID");
openavbAvdeccMsgClntHndlListenerStreamIDFromServer(avdeccMsgHandle,
- msg->params.listenerStreamID.stream_src_mac, ntohs(msg->params.listenerStreamID.stream_uid),
+ msg->params.listenerStreamID.sr_class, msg->params.listenerStreamID.stream_src_mac, ntohs(msg->params.listenerStreamID.stream_uid),
msg->params.listenerStreamID.stream_dest_mac, ntohs(msg->params.listenerStreamID.stream_vlan_id));
break;
+ case OPENAVB_AVDECC_MSG_S2C_TALKER_STREAM_ID:
+ AVB_LOG_DEBUG("Message received: OPENAVB_AVDECC_MSG_S2C_TALKER_STREAM_ID");
+ openavbAvdeccMsgClntHndlTalkerStreamIDFromServer(avdeccMsgHandle,
+ msg->params.s2cTalkerStreamID.sr_class,
+ msg->params.s2cTalkerStreamID.stream_id_valid,
+ msg->params.s2cTalkerStreamID.stream_src_mac,
+ ntohs(msg->params.s2cTalkerStreamID.stream_uid),
+ msg->params.s2cTalkerStreamID.stream_dest_valid,
+ msg->params.s2cTalkerStreamID.stream_dest_mac,
+ msg->params.s2cTalkerStreamID.stream_vlan_id_valid,
+ ntohs(msg->params.s2cTalkerStreamID.stream_vlan_id));
+ break;
case OPENAVB_AVDECC_MSG_CLIENT_CHANGE_REQUEST:
AVB_LOG_DEBUG("Message received: OPENAVB_AVDECC_MSG_CLIENT_CHANGE_REQUEST");
openavbAvdeccMsgClntHndlChangeRequestFromServer(avdeccMsgHandle, (openavbAvdeccMsgStateType_t) msg->params.clientChangeRequest.desired_state);
@@ -162,7 +174,7 @@ bool openavbAvdeccMsgClntInitIdentify(int avdeccMsgHandle, const char * friendly
return ret;
}
-bool openavbAvdeccMsgClntTalkerStreamID(int avdeccMsgHandle, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id)
+bool openavbAvdeccMsgClntTalkerStreamID(int avdeccMsgHandle, U8 sr_class, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id)
{
AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
openavbAvdeccMessage_t msgBuf;
@@ -174,23 +186,17 @@ bool openavbAvdeccMsgClntTalkerStreamID(int avdeccMsgHandle, const U8 stream_src
return false;
}
- // Verify that the destination address is valid.
- if (memcmp(stream_dest_mac, "\x00\x00\x00\x00\x00\x00", 6) == 0) {
- AVB_LOG_DEBUG("stream_dest_mac not yet valid. Not sending to AVDECC Msg Server.");
- return true;
- }
-
- // Verify that the stream_vlan_id is valid.
- if (stream_vlan_id == VLAN_NULL) {
- AVB_LOG_DEBUG("stream_vlan_id not yet valid. Not sending to AVDECC Msg Server.");
- return true;
- }
+ // Send a default stream_vlan_id value if none specified.
+ if (stream_vlan_id == 0) {
+ stream_vlan_id = 2; // SR Class default VLAN Id values per IEEE 802.1Q-2011 Table 9-2
+ }
// Send the stream information to the server.
memset(&msgBuf, 0, OPENAVB_AVDECC_MSG_LEN);
- msgBuf.type = OPENAVB_AVDECC_MSG_TALKER_STREAM_ID;
- openavbAvdeccMsgParams_TalkerStreamID_t * pParams =
- &(msgBuf.params.talkerStreamID);
+ msgBuf.type = OPENAVB_AVDECC_MSG_C2S_TALKER_STREAM_ID;
+ openavbAvdeccMsgParams_C2S_TalkerStreamID_t * pParams =
+ &(msgBuf.params.c2sTalkerStreamID);
+ pParams->sr_class = sr_class;
memcpy(pParams->stream_src_mac, stream_src_mac, 6);
pParams->stream_uid = htons(stream_uid);
memcpy(pParams->stream_dest_mac, stream_dest_mac, 6);
@@ -201,7 +207,7 @@ bool openavbAvdeccMsgClntTalkerStreamID(int avdeccMsgHandle, const U8 stream_src
return ret;
}
-bool openavbAvdeccMsgClntHndlListenerStreamIDFromServer(int avdeccMsgHandle, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id)
+bool openavbAvdeccMsgClntHndlListenerStreamIDFromServer(int avdeccMsgHandle, U8 sr_class, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id)
{
AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
@@ -220,10 +226,11 @@ bool openavbAvdeccMsgClntHndlListenerStreamIDFromServer(int avdeccMsgHandle, con
// Determine if the supplied information differs from the current settings.
openavb_tl_cfg_t * pCfg = &(pState->pTLState->cfg);
- if (memcmp(pCfg->stream_addr.buffer.ether_addr_octet, stream_src_mac, 6) != 0 ||
- pCfg->stream_uid != stream_uid ||
- memcmp(pCfg->dest_addr.buffer.ether_addr_octet, stream_dest_mac, 6) != 0 ||
- pCfg->vlan_id != stream_vlan_id) {
+ if (pCfg->sr_class != sr_class ||
+ memcmp(pCfg->stream_addr.buffer.ether_addr_octet, stream_src_mac, 6) != 0 ||
+ pCfg->stream_uid != stream_uid ||
+ memcmp(pCfg->dest_addr.buffer.ether_addr_octet, stream_dest_mac, 6) != 0 ||
+ pCfg->vlan_id != stream_vlan_id) {
// If the Listener is running, stop the Listener before updating the information.
if (pState->pTLState->bRunning) {
AVB_LOG_DEBUG("Forcing Listener to Stop to change streaming settings");
@@ -231,6 +238,7 @@ bool openavbAvdeccMsgClntHndlListenerStreamIDFromServer(int avdeccMsgHandle, con
}
// Update the stream information supplied by the server.
+ pCfg->sr_class = sr_class;
memcpy(pCfg->stream_addr.buffer.ether_addr_octet, stream_src_mac, 6);
pCfg->stream_addr.mac = &(pCfg->stream_addr.buffer); // Indicate that the MAC Address is valid.
pCfg->stream_uid = stream_uid;
@@ -239,11 +247,116 @@ bool openavbAvdeccMsgClntHndlListenerStreamIDFromServer(int avdeccMsgHandle, con
pCfg->vlan_id = stream_vlan_id;
}
- AVB_LOGF_DEBUG("AVDECC-supplied stream_id: " ETH_FORMAT "/%u",
+ AVB_LOGF_DEBUG("AVDECC-supplied (Listener) sr_class: %u", pCfg->sr_class);
+ AVB_LOGF_DEBUG("AVDECC-supplied (Listener) stream_id: " ETH_FORMAT "/%u",
ETH_OCTETS(pCfg->stream_addr.buffer.ether_addr_octet), pCfg->stream_uid);
- AVB_LOGF_DEBUG("AVDECC-supplied dest_addr: " ETH_FORMAT,
+ AVB_LOGF_DEBUG("AVDECC-supplied (Listener) dest_addr: " ETH_FORMAT,
ETH_OCTETS(pCfg->dest_addr.buffer.ether_addr_octet));
- AVB_LOGF_DEBUG("AVDECC-supplied vlan_id: %u", pCfg->vlan_id);
+ AVB_LOGF_DEBUG("AVDECC-supplied (Listener) vlan_id: %u", pCfg->vlan_id);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return true;
+}
+
+bool openavbAvdeccMsgClntHndlTalkerStreamIDFromServer(int avdeccMsgHandle,
+ 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)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+
+ avdecc_msg_state_t *pState = AvdeccMsgStateListGet(avdeccMsgHandle);
+ if (!pState) {
+ AVB_LOGF_ERROR("avdeccMsgHandle %d not valid", avdeccMsgHandle);
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return false;
+ }
+
+ if (!pState->pTLState) {
+ AVB_LOGF_ERROR("avdeccMsgHandle %d state not valid", avdeccMsgHandle);
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return false;
+ }
+
+ // Update the stream information supplied by the server.
+ openavb_tl_cfg_t * pCfg = &(pState->pTLState->cfg);
+ pCfg->sr_class = sr_class;
+ AVB_LOGF_DEBUG("AVDECC-supplied (Talker) sr_class: %u", pCfg->sr_class);
+ if (stream_id_valid) {
+ if (memcmp(stream_src_mac, "\x00\x00\x00\x00\x00\x00", 6) == 0 && stream_uid == 0) {
+ // Restore from the backup value.
+ if (pCfg->backup_stream_id_valid) {
+ memcpy(pCfg->stream_addr.buffer.ether_addr_octet, pCfg->backup_stream_addr, 6);
+ pCfg->stream_addr.mac = &(pCfg->stream_addr.buffer); // Indicate that the MAC Address is valid.
+ pCfg->stream_uid = pCfg->backup_stream_uid;
+ pCfg->backup_stream_id_valid = FALSE;
+ AVB_LOGF_DEBUG("AVDECC-supplied (Talker) reverted to default stream_id: " ETH_FORMAT "/%u",
+ ETH_OCTETS(pCfg->stream_addr.buffer.ether_addr_octet), pCfg->stream_uid);
+ }
+ }
+ else {
+ // Backup the current value.
+ if (!pCfg->backup_stream_id_valid) {
+ memcpy(pCfg->backup_stream_addr, pCfg->stream_addr.buffer.ether_addr_octet, 6);
+ pCfg->backup_stream_uid = pCfg->stream_uid;
+ pCfg->backup_stream_id_valid = TRUE;
+ }
+
+ // Save the new value.
+ memcpy(pCfg->stream_addr.buffer.ether_addr_octet, stream_src_mac, 6);
+ pCfg->stream_addr.mac = &(pCfg->stream_addr.buffer); // Indicate that the MAC Address is valid.
+ pCfg->stream_uid = stream_uid;
+ AVB_LOGF_DEBUG("AVDECC-supplied (Talker) stream_id: " ETH_FORMAT "/%u",
+ ETH_OCTETS(pCfg->stream_addr.buffer.ether_addr_octet), pCfg->stream_uid);
+ }
+ }
+ if (stream_dest_valid) {
+ if (memcmp(stream_dest_mac, "\x00\x00\x00\x00\x00\x00", 6) == 0) {
+ // Restore from the backup value.
+ if (pCfg->backup_dest_addr_valid) {
+ memcpy(pCfg->dest_addr.buffer.ether_addr_octet, pCfg->backup_dest_addr, 6);
+ pCfg->dest_addr.mac = &(pCfg->dest_addr.buffer); // Indicate that the MAC Address is valid.
+ pCfg->backup_dest_addr_valid = FALSE;
+ AVB_LOGF_DEBUG("AVDECC-supplied (Talker) reverted to default dest_addr: " ETH_FORMAT,
+ ETH_OCTETS(pCfg->dest_addr.buffer.ether_addr_octet));
+ }
+ }
+ else {
+ // Backup the current value.
+ if (!pCfg->backup_dest_addr_valid) {
+ memcpy(pCfg->backup_dest_addr, pCfg->dest_addr.buffer.ether_addr_octet, 6);
+ pCfg->backup_dest_addr_valid = TRUE;
+ }
+
+ // Save the new value.
+ memcpy(pCfg->dest_addr.buffer.ether_addr_octet, stream_dest_mac, 6);
+ pCfg->dest_addr.mac = &(pCfg->dest_addr.buffer); // Indicate that the MAC Address is valid.
+ AVB_LOGF_DEBUG("AVDECC-supplied (Talker) dest_addr: " ETH_FORMAT,
+ ETH_OCTETS(pCfg->dest_addr.buffer.ether_addr_octet));
+ }
+ }
+ if (stream_vlan_id_valid) {
+ if (stream_vlan_id == 0) {
+ // Restore from the backup value.
+ if (pCfg->backup_vlan_id_valid) {
+ pCfg->vlan_id = pCfg->backup_vlan_id;
+ pCfg->backup_vlan_id_valid = FALSE;
+ AVB_LOGF_DEBUG("AVDECC-supplied (Talker) reverted to default vlan_id: %u", pCfg->vlan_id);
+ }
+ }
+ else {
+ // Backup the current value.
+ if (!pCfg->backup_vlan_id_valid) {
+ pCfg->backup_vlan_id_valid = pCfg->vlan_id;
+ pCfg->backup_vlan_id_valid = TRUE;
+ }
+
+ // Save the new value.
+ pCfg->vlan_id = stream_vlan_id;
+ AVB_LOGF_DEBUG("AVDECC-supplied (Talker) vlan_id: %u", pCfg->vlan_id);
+ }
+ }
+
+ // Notify AVDECC of the Talker values to be used after the update.
+ openavbAvdeccMsgClntTalkerStreamID(avdeccMsgHandle, pCfg->sr_class, pCfg->stream_addr.buffer.ether_addr_octet, pCfg->stream_uid, pCfg->dest_addr.buffer.ether_addr_octet, pCfg->vlan_id);
AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
return true;
@@ -413,7 +526,7 @@ void openavbAvdeccMsgRunTalker(avdecc_msg_state_t *pState)
// Let the AVDECC Msg server know our stream ID.
if (!openavbAvdeccMsgClntTalkerStreamID(pState->avdeccMsgHandle,
- cfg->stream_addr.buffer.ether_addr_octet, cfg->stream_uid,
+ cfg->sr_class, cfg->stream_addr.buffer.ether_addr_octet, cfg->stream_uid,
cfg->dest_addr.buffer.ether_addr_octet, cfg->vlan_id)) {
AVB_LOG_ERROR("openavbAvdeccMsgClntTalkerStreamID() failed");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
diff --git a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_server.c b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_server.c
index 3afcfc3d..39fb1a31 100644
--- a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_server.c
+++ b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_server.c
@@ -96,13 +96,14 @@ static bool openavbAvdeccMsgSrvrReceiveFromClient(int avdeccMsgHandle, openavbAv
msg->params.clientInitIdentify.friendly_name,
msg->params.clientInitIdentify.talker);
break;
- case OPENAVB_AVDECC_MSG_TALKER_STREAM_ID:
- AVB_LOG_DEBUG("Message received: OPENAVB_AVDECC_MSG_TALKER_STREAM_ID");
+ case OPENAVB_AVDECC_MSG_C2S_TALKER_STREAM_ID:
+ AVB_LOG_DEBUG("Message received: OPENAVB_AVDECC_MSG_C2S_TALKER_STREAM_ID");
ret = openavbAvdeccMsgSrvrHndlTalkerStreamIDFromClient(avdeccMsgHandle,
- msg->params.talkerStreamID.stream_src_mac,
- ntohs(msg->params.talkerStreamID.stream_uid),
- msg->params.talkerStreamID.stream_dest_mac,
- ntohs(msg->params.talkerStreamID.stream_vlan_id));
+ msg->params.c2sTalkerStreamID.sr_class,
+ msg->params.c2sTalkerStreamID.stream_src_mac,
+ ntohs(msg->params.c2sTalkerStreamID.stream_uid),
+ msg->params.c2sTalkerStreamID.stream_dest_mac,
+ ntohs(msg->params.c2sTalkerStreamID.stream_vlan_id));
break;
case OPENAVB_AVDECC_MSG_CLIENT_CHANGE_NOTIFICATION:
AVB_LOG_DEBUG("Message received: OPENAVB_AVDECC_MSG_CLIENT_CHANGE_NOTIFICATION");
@@ -208,7 +209,7 @@ bool openavbAvdeccMsgSrvrHndlInitIdentifyFromClient(int avdeccMsgHandle, char *
return true;
}
-bool openavbAvdeccMsgSrvrHndlTalkerStreamIDFromClient(int avdeccMsgHandle, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id)
+bool openavbAvdeccMsgSrvrHndlTalkerStreamIDFromClient(int avdeccMsgHandle, U8 sr_class, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id)
{
AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
@@ -227,12 +228,14 @@ bool openavbAvdeccMsgSrvrHndlTalkerStreamIDFromClient(int avdeccMsgHandle, const
}
// Update the stream information supplied by the client.
+ pCfg->sr_class = sr_class;
memcpy(pCfg->stream_addr.buffer.ether_addr_octet, stream_src_mac, 6);
pCfg->stream_addr.mac = &(pCfg->stream_addr.buffer); // Indicate that the MAC Address is valid.
pCfg->stream_uid = stream_uid;
memcpy(pCfg->dest_addr.buffer.ether_addr_octet, stream_dest_mac, 6);
pCfg->dest_addr.mac = &(pCfg->dest_addr.buffer); // Indicate that the MAC Address is valid.
pCfg->vlan_id = stream_vlan_id;
+ AVB_LOGF_DEBUG("Talker-supplied sr_class: %u", pCfg->sr_class);
AVB_LOGF_DEBUG("Talker-supplied stream_id: " ETH_FORMAT "/%u",
ETH_OCTETS(pCfg->stream_addr.buffer.ether_addr_octet), pCfg->stream_uid);
AVB_LOGF_DEBUG("Talker-supplied dest_addr: " ETH_FORMAT,
@@ -246,7 +249,7 @@ bool openavbAvdeccMsgSrvrHndlTalkerStreamIDFromClient(int avdeccMsgHandle, const
return true;
}
-bool openavbAvdeccMsgSrvrListenerStreamID(int avdeccMsgHandle, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id)
+bool openavbAvdeccMsgSrvrListenerStreamID(int avdeccMsgHandle, U8 sr_class, const U8 stream_src_mac[6], U16 stream_uid, const U8 stream_dest_mac[6], U16 stream_vlan_id)
{
AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
openavbAvdeccMessage_t msgBuf;
@@ -262,6 +265,7 @@ bool openavbAvdeccMsgSrvrListenerStreamID(int avdeccMsgHandle, const U8 stream_s
msgBuf.type = OPENAVB_AVDECC_MSG_LISTENER_STREAM_ID;
openavbAvdeccMsgParams_ListenerStreamID_t * pParams =
&(msgBuf.params.listenerStreamID);
+ pParams->sr_class = sr_class;
memcpy(pParams->stream_src_mac, stream_src_mac, 6);
pParams->stream_uid = htons(stream_uid);
memcpy(pParams->stream_dest_mac, stream_dest_mac, 6);
@@ -272,6 +276,38 @@ bool openavbAvdeccMsgSrvrListenerStreamID(int avdeccMsgHandle, const U8 stream_s
return ret;
}
+bool openavbAvdeccMsgSrvrTalkerStreamID(int avdeccMsgHandle,
+ 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)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
+ openavbAvdeccMessage_t msgBuf;
+
+ avdecc_msg_state_t *pState = AvdeccMsgStateListGet(avdeccMsgHandle);
+ if (!pState) {
+ AVB_LOGF_ERROR("avdeccMsgHandle %d not valid", avdeccMsgHandle);
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return false;
+ }
+
+ // Send the stream information to the client.
+ memset(&msgBuf, 0, OPENAVB_AVDECC_MSG_LEN);
+ msgBuf.type = OPENAVB_AVDECC_MSG_S2C_TALKER_STREAM_ID;
+ openavbAvdeccMsgParams_S2C_TalkerStreamID_t * pParams =
+ &(msgBuf.params.s2cTalkerStreamID);
+ pParams->sr_class = sr_class;
+ pParams->stream_id_valid = stream_id_valid;
+ memcpy(pParams->stream_src_mac, stream_src_mac, 6);
+ pParams->stream_uid = htons(stream_uid);
+ pParams->stream_dest_valid = stream_dest_valid;
+ memcpy(pParams->stream_dest_mac, stream_dest_mac, 6);
+ pParams->stream_vlan_id_valid = stream_vlan_id_valid;
+ pParams->stream_vlan_id = htons(stream_vlan_id);
+ bool ret = openavbAvdeccMsgSrvrSendToClient(avdeccMsgHandle, &msgBuf);
+
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
+ return ret;
+}
+
bool openavbAvdeccMsgSrvrChangeRequest(int avdeccMsgHandle, openavbAvdeccMsgStateType_t desiredState)
{
AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
diff --git a/lib/avtp_pipeline/endpoint/openavb_endpoint.c b/lib/avtp_pipeline/endpoint/openavb_endpoint.c
index 71282040..30d8114a 100644
--- a/lib/avtp_pipeline/endpoint/openavb_endpoint.c
+++ b/lib/avtp_pipeline/endpoint/openavb_endpoint.c
@@ -2,16 +2,16 @@
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
@@ -22,10 +22,10 @@ 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
+
+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.
*************************************************************************************************************/
@@ -137,7 +137,7 @@ clientStream_t* addStream(int h, AVBStreamID_t *streamID)
newClientStream->streamID.uniqueID = streamID->uniqueID;
newClientStream->clientHandle = h;
newClientStream->fwmark = INVALID_FWMARK;
-
+
if(x_streamList == NULL) {
x_streamList = newClientStream;
}else {
@@ -215,7 +215,7 @@ static clientStream_t* findStreamMaap(void* hndMaap)
{
AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);
clientStream_t* ps = NULL;
-
+
clientStream_t **lpp;
for(lpp = &x_streamList; *lpp != NULL; lpp = &(*lpp)->next) {
if ((*lpp)->hndMaap == hndMaap)
@@ -231,7 +231,7 @@ static clientStream_t* findStreamMaap(void* hndMaap)
/*************************************************************
*
* Internal function to cleanup streams
- *
+ *
*/
bool x_talkerDeregister(clientStream_t *ps)
{
@@ -255,7 +255,7 @@ bool x_talkerDeregister(clientStream_t *ps)
openavbMaapRelease(ps->hndMaap);
ps->hndMaap = NULL;
}
-
+
// Finish Shaping
if (ps->hndShaper) {
openavbShaperRelease(ps->hndShaper);
@@ -312,7 +312,7 @@ openavbRC strmAttachCb(void* pv,
|| lsnrDecl == openavbSrp_LDSt_Ready_Failed)
{
// Somebody is listening - get ready to stream
-
+
if (ps->fwmark != INVALID_FWMARK) {
AVB_LOG_DEBUG("attach callback: already setup queues");
rc = OPENAVB_SUCCESS;
@@ -354,6 +354,7 @@ openavbRC strmAttachCb(void* pv,
x_cfg.ifname,
ps->destAddr,
lsnrDecl,
+ ps->srClass,
ps->classRate,
ps->vlanID,
ps->priority,
diff --git a/lib/avtp_pipeline/endpoint/openavb_endpoint.h b/lib/avtp_pipeline/endpoint/openavb_endpoint.h
index 7db89e55..a3f82078 100644
--- a/lib/avtp_pipeline/endpoint/openavb_endpoint.h
+++ b/lib/avtp_pipeline/endpoint/openavb_endpoint.h
@@ -2,16 +2,16 @@
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
@@ -22,10 +22,10 @@ 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
+
+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.
*************************************************************************************************************/
@@ -75,6 +75,7 @@ typedef enum {
//////////////////////////////
typedef struct {
U8 destAddr[ETH_ALEN];
+ U8 noMaapAllocate;
AVBTSpec_t tSpec;
U8 srClass;
U8 srRank;
@@ -97,8 +98,9 @@ typedef struct {
//////////////////////////////
typedef struct {
char ifname[IFNAMSIZ + 10]; // Include space for the socket type prefix (e.g. "simple:eth0")
- U8 destAddr[ETH_ALEN];
+ U8 destAddr[ETH_ALEN];
openavbSrpLsnrDeclSubtype_t lsnrDecl;
+ U8 srClass;
U32 classRate;
U16 vlanID;
U8 priority;
@@ -113,7 +115,7 @@ typedef struct {
U8 srClass;
U32 latency;
openavbSrpFailInfo_t failInfo;
-} openavbEndpointParams_ListenerCallback_t;
+} openavbEndpointParams_ListenerCallback_t;
typedef struct {
U32 AVBVersion;
@@ -136,7 +138,7 @@ typedef struct clientStream_t {
U8 srRank; // AVB rank
U32 latency; // internal latency
U32 txRate; // frames per second
-
+
// Information provided by SRP
U8 priority; // AVB priority to use for stream
U16 vlanID; // VLAN ID to use for stream
@@ -209,6 +211,7 @@ void openavbEptClntCheckVerMatchesSrvr(int h, U32 AVBVersion);
bool openavbEptClntRegisterStream(int h,
AVBStreamID_t *streamID,
U8 destAddr[],
+ U8 noMaapAllocation,
AVBTSpec_t *tSpec,
U8 srClass,
U8 srRank,
@@ -217,6 +220,7 @@ bool openavbEptClntRegisterStream(int h,
bool openavbEptSrvrRegisterStream(int h,
AVBStreamID_t *streamID,
U8 destAddr[],
+ U8 noMaapAllocation,
AVBTSpec_t *tSpec,
U8 srClass,
U8 srRank,
@@ -241,6 +245,7 @@ void openavbEptSrvrNotifyTlkrOfSrpCb(int h,
char *ifname,
U8 destAddr[],
openavbSrpLsnrDeclSubtype_t lsnrDecl,
+ U8 srClass,
U32 classRate,
U16 vlanID,
U8 priority,
@@ -250,6 +255,7 @@ void openavbEptClntNotifyTlkrOfSrpCb(int h,
char *ifname,
U8 destAddr[],
openavbSrpLsnrDeclSubtype_t lsnrDecl,
+ U8 srClass,
U32 classRate,
U16 vlanID,
U8 priority,
diff --git a/lib/avtp_pipeline/endpoint/openavb_endpoint_client.c b/lib/avtp_pipeline/endpoint/openavb_endpoint_client.c
index 7f03b938..27d08cee 100644
--- a/lib/avtp_pipeline/endpoint/openavb_endpoint_client.c
+++ b/lib/avtp_pipeline/endpoint/openavb_endpoint_client.c
@@ -2,16 +2,16 @@
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
@@ -22,10 +22,10 @@ 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
+
+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.
*************************************************************************************************************/
@@ -37,7 +37,7 @@ https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
* This code provides the means for them to do so.
*
* This source file is compiled into the streamer executable.
-*
+*
* It provides proxy functions for the streamer to call. The arguments
* for those calls are packed into messages, which are unpacked in the
* endpoint process and then used to call the real functions.
@@ -81,13 +81,14 @@ static bool openavbEptClntReceiveFromServer(int h, openavbEndpointMessage_t *msg
msg->params.talkerCallback.ifname,
msg->params.talkerCallback.destAddr,
msg->params.talkerCallback.lsnrDecl,
+ msg->params.talkerCallback.srClass,
msg->params.talkerCallback.classRate,
msg->params.talkerCallback.vlanID,
msg->params.talkerCallback.priority,
msg->params.talkerCallback.fwmark);
break;
case OPENAVB_ENDPOINT_LISTENER_CALLBACK:
- openavbEptClntNotifyLstnrOfSrpCb(h,
+ openavbEptClntNotifyLstnrOfSrpCb(h,
&msg->streamID,
msg->params.listenerCallback.ifname,
msg->params.listenerCallback.destAddr,
@@ -112,6 +113,7 @@ static bool openavbEptClntReceiveFromServer(int h, openavbEndpointMessage_t *msg
bool openavbEptClntRegisterStream(int h,
AVBStreamID_t *streamID,
U8 destAddr[],
+ U8 noMaapAllocate,
AVBTSpec_t *tSpec,
U8 srClass,
U8 srRank,
@@ -131,8 +133,10 @@ bool openavbEptClntRegisterStream(int h,
memset(&msgBuf, 0, OPENAVB_ENDPOINT_MSG_LEN);
msgBuf.type = OPENAVB_ENDPOINT_TALKER_REGISTER;
memcpy(&(msgBuf.streamID), streamID, sizeof(AVBStreamID_t));
- if (destAddr)
+ if (destAddr) {
memcpy(msgBuf.params.talkerRegister.destAddr, destAddr, ETH_ALEN);
+ msgBuf.params.talkerRegister.noMaapAllocate = noMaapAllocate;
+ }
msgBuf.params.talkerRegister.tSpec.maxFrameSize = tSpec->maxFrameSize;
msgBuf.params.talkerRegister.tSpec.maxIntervalFrames = tSpec->maxIntervalFrames;
msgBuf.params.talkerRegister.srClass = srClass;
@@ -156,7 +160,7 @@ bool openavbEptClntAttachStream(int h, AVBStreamID_t *streamID,
AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
return FALSE;
}
-
+
memset(&msgBuf, 0, OPENAVB_ENDPOINT_MSG_LEN);
msgBuf.type = OPENAVB_ENDPOINT_LISTENER_ATTACH;
memcpy(&(msgBuf.streamID), streamID, sizeof(AVBStreamID_t));
@@ -186,7 +190,7 @@ bool openavbEptClntStopStream(int h, AVBStreamID_t *streamID)
AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
return ret;
}
-
+
bool openavbEptClntRequestVersionFromServer(int h)
{
AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);
@@ -199,4 +203,4 @@ bool openavbEptClntRequestVersionFromServer(int h)
AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
return ret;
}
-
+
diff --git a/lib/avtp_pipeline/endpoint/openavb_endpoint_server.c b/lib/avtp_pipeline/endpoint/openavb_endpoint_server.c
index 350dcff4..22208333 100644
--- a/lib/avtp_pipeline/endpoint/openavb_endpoint_server.c
+++ b/lib/avtp_pipeline/endpoint/openavb_endpoint_server.c
@@ -2,16 +2,16 @@
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
@@ -22,10 +22,10 @@ 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
+
+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.
*************************************************************************************************************/
@@ -36,7 +36,7 @@ https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
* "endpoint" process to create a reservation for their traffic.
*
* This code implements the endpoint (server) side of the IPC.
- *
+ *
* It provides proxy functions for the endpoint to call. The arguments
* for those calls are packed into messages, which are unpacked in the
* streamer processes and then used to call the real functions.
@@ -78,18 +78,19 @@ static bool openavbEptSrvrReceiveFromClient(int h, openavbEndpointMessage_t *msg
AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
return FALSE;
}
-
+
bool ret = FALSE;
switch (msg->type) {
case OPENAVB_ENDPOINT_TALKER_REGISTER:
AVB_LOGF_DEBUG("TalkerRegister from client uid=%d", msg->streamID.uniqueID);
ret = openavbEptSrvrRegisterStream(h, &msg->streamID,
- msg->params.talkerRegister.destAddr,
- &msg->params.talkerRegister.tSpec,
- msg->params.talkerRegister.srClass,
- msg->params.talkerRegister.srRank,
- msg->params.talkerRegister.latency,
- msg->params.talkerRegister.txRate);
+ msg->params.talkerRegister.destAddr,
+ msg->params.talkerRegister.noMaapAllocate,
+ &msg->params.talkerRegister.tSpec,
+ msg->params.talkerRegister.srClass,
+ msg->params.talkerRegister.srRank,
+ msg->params.talkerRegister.latency,
+ msg->params.talkerRegister.txRate);
break;
case OPENAVB_ENDPOINT_LISTENER_ATTACH:
AVB_LOGF_DEBUG("ListenerAttach from client uid=%d", msg->streamID.uniqueID);
@@ -119,10 +120,11 @@ void openavbEptSrvrNotifyTlkrOfSrpCb(int h,
char *ifname,
U8 destAddr[ETH_ALEN],
openavbSrpLsnrDeclSubtype_t lsnrDecl,
+ U8 srClass,
U32 classRate,
U16 vlanID,
U8 priority,
- U16 fwmark)
+ U16 fwmark)
{
AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);
openavbEndpointMessage_t msgBuf;
@@ -139,6 +141,7 @@ void openavbEptSrvrNotifyTlkrOfSrpCb(int h,
strncpy(msgBuf.params.talkerCallback.ifname, ifname, IFNAMSIZ - 1);
memcpy(msgBuf.params.talkerCallback.destAddr, destAddr, ETH_ALEN);
msgBuf.params.talkerCallback.lsnrDecl = lsnrDecl;
+ msgBuf.params.talkerCallback.srClass = srClass;
msgBuf.params.talkerCallback.classRate = classRate;
msgBuf.params.talkerCallback.vlanID = vlanID;
msgBuf.params.talkerCallback.priority = priority;
@@ -162,7 +165,7 @@ void openavbEptSrvrNotifyLstnrOfSrpCb(int h,
openavbEndpointMessage_t msgBuf;
// Check for valid parameters. DestAddr is optional and checked later.
- if (!streamID || !ifname) {
+ if (!streamID || !ifname) {
AVB_LOG_ERROR("Listener callback; invalid argument passed");
AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
return;
@@ -172,7 +175,7 @@ void openavbEptSrvrNotifyLstnrOfSrpCb(int h,
msgBuf.type = OPENAVB_ENDPOINT_LISTENER_CALLBACK;
memcpy(&(msgBuf.streamID), streamID, sizeof(AVBStreamID_t));
strncpy(msgBuf.params.listenerCallback.ifname, ifname, IFNAMSIZ - 1);
- if (destAddr)
+ if (destAddr)
memcpy(msgBuf.params.listenerCallback.destAddr, destAddr, ETH_ALEN);
msgBuf.params.listenerCallback.tlkrDecl = tlkrDecl;
if (tSpec)
@@ -203,6 +206,7 @@ void openavbEptSrvrSendServerVersionToClient(int h, U32 AVBVersion)
bool openavbEptSrvrRegisterStream(int h,
AVBStreamID_t *streamID,
U8 destAddr[],
+ U8 noMaapAllocation,
AVBTSpec_t *tSpec,
U8 srClass,
U8 srRank,
@@ -214,7 +218,7 @@ bool openavbEptSrvrRegisterStream(int h,
AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);
clientStream_t *ps = findStream(streamID);
-
+
if (ps && ps->clientHandle != h) {
AVB_LOGF_ERROR("Error registering talker; multiple clients for stream %d", streamID->uniqueID);
AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
@@ -236,7 +240,7 @@ bool openavbEptSrvrRegisterStream(int h,
ps->fwmark = INVALID_FWMARK;
// If MAAP is available, or no client-supplied address, allocate an address.
- if (openavbMaapDaemonAvailable() ||
+ if ((!noMaapAllocation && openavbMaapDaemonAvailable()) ||
memcmp(ps->destAddr, destAddr, ETH_ALEN) == 0) {
struct ether_addr addr;
ps->hndMaap = openavbMaapAllocate(1, &addr);
@@ -299,7 +303,7 @@ bool openavbEptSrvrRegisterStream(int h,
}
openavbEndPtLogAllStaticStreams();
-
+
AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
return IS_OPENAVB_SUCCESS(rc);
}
@@ -393,7 +397,7 @@ bool openavbEptSrvrHndlVerRqstFromClient(int h)
return TRUE;
}
-/* Called if a client closes their end of the IPC
+/* Called if a client closes their end of the IPC
*/
void openavbEptSrvrCloseClientConnection(int h)
{
diff --git a/lib/avtp_pipeline/include/openavb_pub.h b/lib/avtp_pipeline/include/openavb_pub.h
index 95fe6378..9e530cef 100644
--- a/lib/avtp_pipeline/include/openavb_pub.h
+++ b/lib/avtp_pipeline/include/openavb_pub.h
@@ -51,7 +51,7 @@ https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
#define AVB_CORE_VER_MAJOR (0)
#define AVB_CORE_VER_MINOR (1)
-#define AVB_CORE_VER_REVISION (2)
+#define AVB_CORE_VER_REVISION (3)
// Standard release designations. Uncomment one AVB_RELEASE_TYPE
#define AVB_CORE_RELEASE_TYPE "Development"
diff --git a/lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_pipeline_interaction.c b/lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_pipeline_interaction.c
index d88c0f85..5e6a5051 100644
--- a/lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_pipeline_interaction.c
+++ b/lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_pipeline_interaction.c
@@ -67,6 +67,7 @@ bool openavbAVDECCRunListener(openavb_aem_descriptor_stream_io_t *pDescriptorStr
// Send the Stream ID to the client.
// The client will stop a running Listener if the settings differ from its current values.
if (!openavbAvdeccMsgSrvrListenerStreamID(pDescriptorStreamInput->stream->client->avdeccMsgHandle,
+ ((pListenerStreamInfo->flags & OPENAVB_ACMP_FLAG_CLASS_B) != 0 ? SR_CLASS_B : SR_CLASS_A),
pListenerStreamInfo->stream_id, /* The first 6 bytes of the steam_id are the source MAC Address */
(((U16) pListenerStreamInfo->stream_id[6]) << 8 | (U16) pListenerStreamInfo->stream_id[7]),
pListenerStreamInfo->stream_dest_mac,
@@ -264,87 +265,96 @@ bool openavbAVDECCGetTalkerStreamInfo(openavb_aem_descriptor_stream_io_t *pDescr
(((U16) pTalkerStreamInfo->stream_id[6]) << 8) | (U16) pTalkerStreamInfo->stream_id[7]);
// Get the VLAN ID.
- if (pDescriptorStreamOutput->stream->vlan_id == VLAN_NULL) {
- AVB_LOG_ERROR("openavbAVDECCGetTalkerStreamInfo Invalid stream vlan_id");
- AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return FALSE;
- }
pTalkerStreamInfo->stream_vlan_id = pDescriptorStreamOutput->stream->vlan_id;
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
return TRUE;
}
-bool openavbAVDECCListenerIsStreaming(openavb_aem_descriptor_stream_io_t *pDescriptorStreamInput, U16 configIdx)
+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)
{
AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
// Sanity tests.
- if (!pDescriptorStreamInput) {
- AVB_LOG_ERROR("openavbAVDECCListenerIsStreaming Invalid descriptor");
+ if (!pDescriptorStreamOutput) {
+ AVB_LOG_ERROR("openavbAVDECCSetTalkerStreamInfo Invalid descriptor");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
return FALSE;
}
- if (!pDescriptorStreamInput->stream) {
- AVB_LOG_ERROR("openavbAVDECCListenerIsStreaming Invalid StreamInput descriptor stream");
+ if (!pDescriptorStreamOutput->stream) {
+ AVB_LOG_ERROR("openavbAVDECCSetTalkerStreamInfo Invalid StreamInput descriptor stream");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
return FALSE;
}
- if (!pDescriptorStreamInput->stream->client) {
- AVB_LOG_ERROR("openavbAVDECCListenerIsStreaming Invalid stream client pointer");
+ if (!pDescriptorStreamOutput->stream->client) {
+ AVB_LOG_ERROR("openavbAVDECCSetTalkerStreamInfo Invalid stream client pointer");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
return FALSE;
}
- // Return the current Listener state.
- // If the state is not known, assume the Listener is not running.
- if (pDescriptorStreamInput->stream->client->lastReportedState == OPENAVB_AVDECC_MSG_RUNNING) {
- AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return TRUE;
- }
- if (pDescriptorStreamInput->stream->client->lastReportedState != OPENAVB_AVDECC_MSG_STOPPED) {
- AVB_LOG_WARNING("Listener state unknown");
+ // Send the information to the client.
+ if (!openavbAvdeccMsgSrvrTalkerStreamID(pDescriptorStreamOutput->stream->client->avdeccMsgHandle,
+ sr_class, stream_id_valid, stream_src_mac, stream_uid, stream_dest_valid, stream_dest_mac, stream_vlan_id_valid, stream_vlan_id)) {
+ AVB_LOG_ERROR("Error sending stream info updates to Talker");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
return FALSE;
}
+
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return FALSE;
+ return TRUE;
}
-bool openavbAVDECCTalkerIsStreaming(openavb_aem_descriptor_stream_io_t *pDescriptorStreamOutput, U16 configIdx)
+openavbAvdeccMsgStateType_t openavbAVDECCGetRequestedState(openavb_aem_descriptor_stream_io_t *pDescriptorStream, U16 configIdx)
{
AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
// Sanity tests.
- if (!pDescriptorStreamOutput) {
- AVB_LOG_ERROR("openavbAVDECCTalkerIsStreaming Invalid descriptor");
+ if (!pDescriptorStream) {
+ AVB_LOG_ERROR("openavbAVDECCGetRequestedState Invalid descriptor");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return FALSE;
+ return OPENAVB_AVDECC_MSG_UNKNOWN;
}
- if (!pDescriptorStreamOutput->stream) {
- AVB_LOG_ERROR("openavbAVDECCTalkerIsStreaming Invalid StreamInput descriptor stream");
+ if (!pDescriptorStream->stream) {
+ AVB_LOG_ERROR("openavbAVDECCGetRequestedState Invalid descriptor stream");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return FALSE;
+ return OPENAVB_AVDECC_MSG_UNKNOWN;
}
- if (!pDescriptorStreamOutput->stream->client) {
- AVB_LOG_ERROR("openavbAVDECCTalkerIsStreaming Invalid stream client pointer");
+ if (!pDescriptorStream->stream->client) {
+ AVB_LOG_DEBUG("openavbAVDECCGetRequestedState Invalid stream client pointer");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return FALSE;
+ return OPENAVB_AVDECC_MSG_UNKNOWN;
}
- // Return the current Talker state.
- // If the state is not known, assume the Talker is not running.
- if (pDescriptorStreamOutput->stream->client->lastReportedState == OPENAVB_AVDECC_MSG_RUNNING) {
+ // Return the current state.
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return pDescriptorStream->stream->client->lastRequestedState;
+}
+
+openavbAvdeccMsgStateType_t openavbAVDECCGetStreamingState(openavb_aem_descriptor_stream_io_t *pDescriptorStream, U16 configIdx)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_AVDECC);
+
+ // Sanity tests.
+ if (!pDescriptorStream) {
+ AVB_LOG_ERROR("openavbAVDECCGetStreamingState Invalid descriptor");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return TRUE;
+ return OPENAVB_AVDECC_MSG_UNKNOWN;
}
- if (pDescriptorStreamOutput->stream->client->lastReportedState != OPENAVB_AVDECC_MSG_STOPPED) {
- AVB_LOG_WARNING("Talker state unknown");
+ if (!pDescriptorStream->stream) {
+ AVB_LOG_ERROR("openavbAVDECCGetStreamingState Invalid descriptor stream");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return FALSE;
+ return OPENAVB_AVDECC_MSG_UNKNOWN;
}
+ if (!pDescriptorStream->stream->client) {
+ AVB_LOG_DEBUG("openavbAVDECCGetStreamingState Invalid stream client pointer");
+ AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
+ return OPENAVB_AVDECC_MSG_UNKNOWN;
+ }
+
+ // Return the current state.
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return FALSE;
+ return pDescriptorStream->stream->client->lastReportedState;
}
void openavbAVDECCPauseStream(openavb_aem_descriptor_stream_io_t *pDescriptor, bool bPause)
diff --git a/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_osal.h b/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_osal.h
index f866c9dd..b68ea38d 100644
--- a/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_osal.h
+++ b/lib/avtp_pipeline/platform/Linux/avdecc_msg/openavb_avdecc_msg_osal.h
@@ -46,12 +46,13 @@ typedef struct {
// Client-to-Server messages
openavbAvdeccMsgParams_VersionRequest_t versionRequest;
openavbAvdeccMsgParams_ClientInitIdentify_t clientInitIdentify;
- openavbAvdeccMsgParams_TalkerStreamID_t talkerStreamID;
+ openavbAvdeccMsgParams_C2S_TalkerStreamID_t c2sTalkerStreamID;
openavbAvdeccMsgParams_ClientChangeNotification_t clientChangeNotification;
// Server-to-Client messages
openavbAvdeccMsgParams_VersionCallback_t versionCallback;
openavbAvdeccMsgParams_ListenerStreamID_t listenerStreamID;
+ openavbAvdeccMsgParams_S2C_TalkerStreamID_t s2cTalkerStreamID;
openavbAvdeccMsgParams_ClientChangeRequest_t clientChangeRequest;
} params;
} openavbAvdeccMessage_t;
diff --git a/lib/avtp_pipeline/tl/openavb_talker.h b/lib/avtp_pipeline/tl/openavb_talker.h
index 49d196ca..86bfc39e 100644
--- a/lib/avtp_pipeline/tl/openavb_talker.h
+++ b/lib/avtp_pipeline/tl/openavb_talker.h
@@ -2,16 +2,16 @@
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
@@ -22,10 +22,10 @@ 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
+
+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.
*************************************************************************************************************/
@@ -41,9 +41,10 @@ https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
typedef struct {
// Data from callback
char ifname[IFNAMSIZ + 10]; // Include space for the socket type prefix (e.g. "simple:eth0")
- AVBStreamID_t streamID;
+ AVBStreamID_t streamID;
U8 destAddr[ETH_ALEN];
AVBTSpec_t tSpec;
+ U8 srClass;
U32 classRate;
U32 fwmark;
U16 vlanID;
diff --git a/lib/avtp_pipeline/tl/openavb_talker_endpoint.c b/lib/avtp_pipeline/tl/openavb_talker_endpoint.c
index 01b1053a..e3343e78 100644
--- a/lib/avtp_pipeline/tl/openavb_talker_endpoint.c
+++ b/lib/avtp_pipeline/tl/openavb_talker_endpoint.c
@@ -2,16 +2,16 @@
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
@@ -22,15 +22,15 @@ 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
+
+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 SUMMARY : Talker implementation for use with endpoint
+* MODULE SUMMARY : Talker implementation for use with endpoint
*/
#include <stdlib.h>
@@ -58,6 +58,7 @@ void openavbEptClntNotifyTlkrOfSrpCb(int endpointHandle,
char *ifname,
U8 destAddr[],
openavbSrpLsnrDeclSubtype_t lsnrDecl,
+ U8 srClass,
U32 classRate,
U16 vlanID,
U8 priority,
@@ -95,6 +96,7 @@ void openavbEptClntNotifyTlkrOfSrpCb(int endpointHandle,
}
memcpy(&pTalkerData->streamID, streamID, sizeof(AVBStreamID_t));
memcpy(&pTalkerData->destAddr, destAddr, ETH_ALEN);
+ pTalkerData->srClass = srClass;
pTalkerData->classRate = classRate;
pTalkerData->vlanID = vlanID;
pTalkerData->vlanPCP = priority;
@@ -113,6 +115,7 @@ void openavbEptClntNotifyTlkrOfSrpCb(int endpointHandle,
}
memcpy(&pTalkerData->streamID, streamID, sizeof(AVBStreamID_t));
memcpy(&pTalkerData->destAddr, destAddr, ETH_ALEN);
+ pTalkerData->srClass = srClass;
pTalkerData->classRate = classRate;
pTalkerData->vlanID = vlanID;
pTalkerData->vlanPCP = priority;
@@ -131,7 +134,7 @@ void openavbEptClntNotifyTlkrOfSrpCb(int endpointHandle,
// Let the AVDECC Msg server know our current stream ID, in case it was updated by MAAP.
if (pTLState->avdeccMsgHandle != AVB_AVDECC_MSG_HANDLE_INVALID) {
if (!openavbAvdeccMsgClntTalkerStreamID(pTLState->avdeccMsgHandle,
- pTalkerData->streamID.addr, pTalkerData->streamID.uniqueID,
+ pTalkerData->srClass, pTalkerData->streamID.addr, pTalkerData->streamID.uniqueID,
pTalkerData->destAddr, pTalkerData->vlanID)) {
AVB_LOG_ERROR("openavbAvdeccMsgClntTalkerStreamID() failed");
}
@@ -183,6 +186,7 @@ bool openavbTLRunTalkerInit(tl_state_t *pTLState)
return (openavbEptClntRegisterStream(pTLState->endpointHandle,
&streamID,
pCfg->dest_addr.mac->ether_addr_octet,
+ pCfg->backup_dest_addr_valid, // If we have a backup dest_addr, then the current one was forced and MAAP should not be used.
&pTalkerData->tSpec,
pCfg->sr_class,
pCfg->sr_rank,
diff --git a/lib/avtp_pipeline/tl/openavb_talker_no_endpoint.c b/lib/avtp_pipeline/tl/openavb_talker_no_endpoint.c
index 0c99c60c..03cb8ade 100644
--- a/lib/avtp_pipeline/tl/openavb_talker_no_endpoint.c
+++ b/lib/avtp_pipeline/tl/openavb_talker_no_endpoint.c
@@ -2,16 +2,16 @@
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
@@ -22,15 +22,15 @@ 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
+
+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 SUMMARY : Talker implementation for use without endpoint
+* MODULE SUMMARY : Talker implementation for use without endpoint
*/
#include <stdlib.h>
@@ -63,7 +63,7 @@ bool openavbTLRunTalkerInit(tl_state_t *pTLState)
//avtp_stream_t *pStream = (avtp_stream_t *)(pTalkerData->avtpHandle);
strncpy(pTalkerData->ifname, pCfg->ifname, IFNAMSIZ);
-
+
// CORE_TODO: It would be good to have some parts of endpoint moved into non-endpoint general code to handle some the stream
// configuration values.
// strncpy(pTalkerData->ifname, pCfg->ifname, IFNAMSIZ);
@@ -72,18 +72,19 @@ bool openavbTLRunTalkerInit(tl_state_t *pTLState)
}else {
AVB_LOG_WARNING("Stream Address Not Set");
}
-
+
pTalkerData->streamID.uniqueID = pCfg->stream_uid;
+ pTalkerData->srClass = pCfg->sr_class;
if (pCfg->sr_class == SR_CLASS_A) {
pTalkerData->classRate = 8000;
- pTalkerData->vlanID = pCfg->vlan_id == VLAN_NULL ?
- SR_CLASS_A_DEFAULT_VID : pCfg->vlan_id;
+ pTalkerData->vlanID = (pCfg->vlan_id == 0 ?
+ SR_CLASS_A_DEFAULT_VID : pCfg->vlan_id);
pTalkerData->vlanPCP = SR_CLASS_A_DEFAULT_PRIORITY;
}
else if (pCfg->sr_class == SR_CLASS_B) {
pTalkerData->classRate = 4000;
- pTalkerData->vlanID = pCfg->vlan_id == VLAN_NULL ?
- SR_CLASS_B_DEFAULT_VID : pCfg->vlan_id;
+ pTalkerData->vlanID = (pCfg->vlan_id == 0 ?
+ SR_CLASS_B_DEFAULT_VID : pCfg->vlan_id);
pTalkerData->vlanPCP = SR_CLASS_B_DEFAULT_PRIORITY;
}
memcpy(&pTalkerData->destAddr, &pCfg->dest_addr.mac->ether_addr_octet, ETH_ALEN);
@@ -101,10 +102,10 @@ bool openavbTLRunTalkerInit(tl_state_t *pTLState)
unsigned int map_intv_frames = pCfg->map_cb.map_get_max_interval_frames_cb(pTLState->pMediaQ, pTLState->cfg.sr_class);
pCfg->max_interval_frames = map_intv_frames > 0 ? map_intv_frames : pCfg->max_interval_frames;
}
- }
+ }
pTalkerData->tSpec.maxIntervalFrames = pCfg->max_interval_frames;
pTalkerData->tSpec.maxFrameSize = pCfg->map_cb.map_max_data_size_cb(pTLState->pMediaQ);
-
+
// TODO_COREAVB : This wakeRate should also be set in the endpoint case and removed from the tasker.c start stream
if (!pCfg->map_cb.map_transmit_interval_cb(pTLState->pMediaQ)) {
pTalkerData->wakeRate = pTalkerData->classRate / pCfg->batch_factor;
@@ -124,15 +125,15 @@ bool openavbTLRunTalkerInit(tl_state_t *pTLState)
if (pTalkerData->fwmark == INVALID_FWMARK)
return FALSE;
-
+
AVB_LOGF_INFO("Dest Addr: "ETH_FORMAT, ETH_OCTETS(pTalkerData->destAddr));
AVB_LOGF_INFO("Starting stream: "STREAMID_FORMAT, STREAMID_ARGS(&pTalkerData->streamID));
talkerStartStream(pTLState);
-
+
// Let the AVDECC Msg server know our current stream ID, in case it is waiting for an update.
if (pTLState->avdeccMsgHandle != AVB_AVDECC_MSG_HANDLE_INVALID) {
if (!openavbAvdeccMsgClntTalkerStreamID(pTLState->avdeccMsgHandle,
- pTalkerData->streamID.addr, pTalkerData->streamID.uniqueID,
+ pTalkerData->srClass, pTalkerData->streamID.addr, pTalkerData->streamID.uniqueID,
pTalkerData->destAddr, pTalkerData->vlanID)) {
AVB_LOG_ERROR("openavbAvdeccMsgClntTalkerStreamID() failed");
}
@@ -153,6 +154,7 @@ AVBStreamID_t *streamID,
char *ifname,
U8 destAddr[],
openavbSrpLsnrDeclSubtype_t lsnrDecl,
+U8 srClass,
U32 classRate,
U16 vlanID,
U8 priority,
diff --git a/lib/avtp_pipeline/tl/openavb_tl.c b/lib/avtp_pipeline/tl/openavb_tl.c
index 34efccd2..e3e75ad5 100755
--- a/lib/avtp_pipeline/tl/openavb_tl.c
+++ b/lib/avtp_pipeline/tl/openavb_tl.c
@@ -391,7 +391,7 @@ EXTERN_DLL_EXPORT void openavbTLInitCfg(openavb_tl_cfg_t *pCfg)
pCfg->rx_signal_mode = 1;
pCfg->pMapInitFn = NULL;
pCfg->pIntfInitFn = NULL;
- pCfg->vlan_id = VLAN_NULL;
+ pCfg->vlan_id = 0;
pCfg->fixed_timestamp = 0;
pCfg->spin_wait = FALSE;
pCfg->thread_rt_priority = 0;
diff --git a/lib/avtp_pipeline/tl/openavb_tl_pub.h b/lib/avtp_pipeline/tl/openavb_tl_pub.h
index 89d4784d..1359da16 100755
--- a/lib/avtp_pipeline/tl/openavb_tl_pub.h
+++ b/lib/avtp_pipeline/tl/openavb_tl_pub.h
@@ -79,9 +79,6 @@ typedef enum {
/// Maximum size of the friendly name
#define FRIENDLY_NAME_SIZE 64
-/// Indicates that VLAN ID is not set in configuration
-#define VLAN_NULL UINT16_MAX
-
/// Initial talker/listener state
typedef enum {
/// Unspecified
@@ -162,6 +159,22 @@ typedef struct {
openavb_map_initialize_fn_t pMapInitFn;
/// Initialization function in interface
openavb_intf_initialize_fn_t pIntfInitFn;
+
+ /// TRUE if backup_stream_addr and backup_stream_uid are valid.
+ bool backup_stream_id_valid;
+ /// Saved original MAC address of the source
+ U8 backup_stream_addr[ETH_ALEN];
+ /// Stream UID (has to be unique)
+ U16 backup_stream_uid;
+ /// TRUE if backup_dest_addr_valid is valid.
+ bool backup_dest_addr_valid;
+ /// Saved original MAC address of destination - multicast (talker only if SRP is enabled)
+ U8 backup_dest_addr[ETH_ALEN];
+ /// TRUE if backup_vlan_id_valid is valid.
+ bool backup_vlan_id_valid;
+ /// Saved original VLAN ID
+ U16 backup_vlan_id;
+
} openavb_tl_cfg_t;
/// Structure holding configuration of mapping and interface modules