summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--daemons/maap/common/maap_log.h10
-rw-r--r--daemons/shaper/src/shaper_log.h20
-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/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/avtp/openavb_avtp.c24
-rw-r--r--lib/avtp_pipeline/endpoint/openavb_endpoint.c1
-rw-r--r--lib/avtp_pipeline/endpoint/openavb_endpoint.h8
-rw-r--r--lib/avtp_pipeline/endpoint/openavb_endpoint_client.c8
-rw-r--r--lib/avtp_pipeline/endpoint/openavb_endpoint_server.c18
-rw-r--r--lib/avtp_pipeline/include/openavb_log_pub.h24
-rw-r--r--lib/avtp_pipeline/include/openavb_pub.h2
-rwxr-xr-xlib/avtp_pipeline/map_aaf_audio/openavb_map_aaf_audio_pub.h14
-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/platform/Linux/endpoint/openavb_endpoint_osal_srp.c2
-rw-r--r--lib/avtp_pipeline/platform/Linux/rawsock/ring_rawsock.c18
-rw-r--r--lib/avtp_pipeline/tl/openavb_listener.c20
-rw-r--r--lib/avtp_pipeline/tl/openavb_talker.h3
-rw-r--r--lib/avtp_pipeline/tl/openavb_talker_endpoint.c6
-rw-r--r--lib/avtp_pipeline/tl/openavb_talker_no_endpoint.c12
-rwxr-xr-xlib/avtp_pipeline/tl/openavb_tl.c2
-rwxr-xr-xlib/avtp_pipeline/tl/openavb_tl_pub.h19
30 files changed, 839 insertions, 215 deletions
diff --git a/daemons/maap/common/maap_log.h b/daemons/maap/common/maap_log.h
index 7d36c1a1..eb9ca01f 100644
--- a/daemons/maap/common/maap_log.h
+++ b/daemons/maap/common/maap_log.h
@@ -162,11 +162,11 @@ typedef enum {
#define LOG_VARX(x, y) x ## y
#define LOG_VAR(x, y) LOG_VARX(x, y)
-// Log a message once. Technically once every 4.2 billion attempts. Usage: LOG_ONCE MAAP_LOG_INFO(...)
-#define IF_LOG_ONCE() static uint32_t LOG_VAR(logOnce,__LINE__); if (!LOG_VAR(logOnce,__LINE__)++)
+// Log a message once. Technically once every 4.2 billion attempts. Usage: IF_LOG_ONCE() MAAP_LOG_INFO(...)
+#define IF_LOG_ONCE() static uint32_t LOG_VAR(logOnce,__LINE__) = 0; if (!LOG_VAR(logOnce,__LINE__)++)
-// Log a message at an interval. Usage: LOG_INTERVAL(100) MAAP_LOG_INFO(...)
-#define IF_LOG_INTERVAL(x) static uint32_t LOG_VAR(logOnce,__LINE__); if (!(LOG_VAR(logOnce,__LINE__)++ % (x - 1)))
+// Log a message at an interval. Usage: IF_LOG_INTERVAL(100) MAAP_LOG_INFO(...)
+#define IF_LOG_INTERVAL(x) static uint32_t LOG_VAR(logOnce,__LINE__) = 0; if (!(LOG_VAR(logOnce,__LINE__)++ % (x)))
#define ETH_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x"
@@ -221,7 +221,7 @@ void maapLogBuffer(
#define MAAP_LOGRT_STATUS(BEGIN, ITEM, END, FMT, TYPE, VAL) maapLogRT(MAAP_LOG_LEVEL_STATUS, BEGIN, ITEM, END, FMT, TYPE, VAL)
#define MAAP_LOGRT_DEBUG(BEGIN, ITEM, END, FMT, TYPE, VAL) maapLogRT(MAAP_LOG_LEVEL_DEBUG, BEGIN, ITEM, END, FMT, TYPE, VAL)
#define MAAP_LOGRT_VERBOSE(BEGIN, ITEM, END, FMT, TYPE, VAL) maapLogRT(MAAP_LOG_LEVEL_VERBOSE, BEGIN, ITEM, END, FMT, TYPE, VAL)
-#define MAAP_LOG_BUFFER(LEVEL, DATA, DATALEN, LINELINE) maapLogBuffer(LEVEL, DATA, DATALEN, LINELINE, MAAP_LOG_COMPANY, MAAP_LOG_COMPONENT, __FILE__, __LINE__)
+#define MAAP_LOG_BUFFER(LEVEL, DATA, DATALEN, LINELINE) do { if (LEVEL <= MAAP_LOG_LEVEL) maapLogBuffer(0, DATA, DATALEN, LINELINE, MAAP_LOG_COMPANY, MAAP_LOG_COMPONENT, __FILE__, __LINE__); } while(0)
#else
#define MAAP_LOGF_DEV(LEVEL, FMT, ...)
#define MAAP_LOGF_ERROR(FMT, ...)
diff --git a/daemons/shaper/src/shaper_log.h b/daemons/shaper/src/shaper_log.h
index 2b97726d..0db3dc36 100644
--- a/daemons/shaper/src/shaper_log.h
+++ b/daemons/shaper/src/shaper_log.h
@@ -162,11 +162,11 @@ typedef enum {
#define LOG_VARX(x, y) x ## y
#define LOG_VAR(x, y) LOG_VARX(x, y)
-// Log a message once. Technically once every 4.2 billion attempts. Usage: LOG_ONCE SHAPER_LOG_INFO(...)
-#define IF_LOG_ONCE() static uint32_t LOG_VAR(logOnce,__LINE__); if (!LOG_VAR(logOnce,__LINE__)++)
+// Log a message once. Technically once every 4.2 billion attempts. Usage: IF_LOG_ONCE() SHAPER_LOG_INFO(...)
+#define IF_LOG_ONCE() static uint32_t LOG_VAR(logOnce,__LINE__) = 0; if (!LOG_VAR(logOnce,__LINE__)++)
-// Log a message at an interval. Usage: LOG_INTERVAL(100) SHAPER_LOG_INFO(...)
-#define IF_LOG_INTERVAL(x) static uint32_t LOG_VAR(logOnce,__LINE__); if (!(LOG_VAR(logOnce,__LINE__)++ % (x - 1)))
+// Log a message at an interval. Usage: IF_LOG_INTERVAL(100) SHAPER_LOG_INFO(...)
+#define IF_LOG_INTERVAL(x) static uint32_t LOG_VAR(logOnce,__LINE__) = 0; if (!(LOG_VAR(logOnce,__LINE__)++ % (x)))
#define ETH_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x"
@@ -203,10 +203,16 @@ void shaperLogBuffer(
#define shaperLogFn2(level, tag, company, component, path, line, fmt, ...) \
- ({\
+ {\
if (level <= SHAPER_LOG_LEVEL) \
shaperLogFn(0, tag, company, component, path, line, fmt, __VA_ARGS__); \
- })
+ }
+
+#define shaperLogBuffer2(level, pData, dataLen, lineLen, company, component, path, line) \
+ {\
+ if (level <= AVB_LOG_LEVEL) \
+ shaperLogBuffer(0, pData, dataLen, lineLen, company, component, path, line); \
+ }
#ifdef SHAPER_LOG_ON
#define SHAPER_LOGF_DEV(LEVEL, FMT, ...) shaperLogFn2(LEVEL, "DEV", SHAPER_LOG_COMPANY, SHAPER_LOG_COMPONENT, __FILE__, __LINE__, FMT, __VA_ARGS__)
@@ -229,7 +235,7 @@ void shaperLogBuffer(
#define SHAPER_LOGRT_STATUS(BEGIN, ITEM, END, FMT, TYPE, VAL) shaperLogRT(SHAPER_LOG_LEVEL_STATUS, BEGIN, ITEM, END, FMT, TYPE, VAL)
#define SHAPER_LOGRT_DEBUG(BEGIN, ITEM, END, FMT, TYPE, VAL) shaperLogRT(SHAPER_LOG_LEVEL_DEBUG, BEGIN, ITEM, END, FMT, TYPE, VAL)
#define SHAPER_LOGRT_VERBOSE(BEGIN, ITEM, END, FMT, TYPE, VAL) shaperLogRT(SHAPER_LOG_LEVEL_VERBOSE, BEGIN, ITEM, END, FMT, TYPE, VAL)
-#define SHAPER_LOG_BUFFER(LEVEL, DATA, DATALEN, LINELINE) shaperLogBuffer(LEVEL, DATA, DATALEN, LINELINE, SHAPER_LOG_COMPANY, SHAPER_LOG_COMPONENT, __FILE__, __LINE__)
+#define SHAPER_LOG_BUFFER(LEVEL, DATA, DATALEN, LINELINE) shaperLogBuffer2(LEVEL, DATA, DATALEN, LINELINE, SHAPER_LOG_COMPANY, SHAPER_LOG_COMPONENT, __FILE__, __LINE__)
#else
#define SHAPER_LOGF_DEV(LEVEL, FMT, ...)
#define SHAPER_LOGF_ERROR(FMT, ...)
diff --git a/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c b/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c
index c10ba2ef..515a557f 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/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 e5315112..326b64b7 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/avtp/openavb_avtp.c b/lib/avtp_pipeline/avtp/openavb_avtp.c
index ddb59181..82932d23 100644
--- a/lib/avtp_pipeline/avtp/openavb_avtp.c
+++ b/lib/avtp_pipeline/avtp/openavb_avtp.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.
*************************************************************************************************************/
@@ -74,7 +74,7 @@ static openavbRC openAvtpSock(avtp_stream_t *pStream)
if (pStream->rawsock != NULL) {
openavbSetRxSignalMode(pStream->rawsock, pStream->bRxSignalMode);
-
+
if (!pStream->tx) {
// Set the multicast address that we want to receive
openavbRawsockRxMulticast(pStream->rawsock, TRUE, pStream->dest_addr.ether_addr_octet);
@@ -256,7 +256,7 @@ static void inline rxDeliveryStats(avtp_rx_info_t *rxInfo,
static openavbRC fillAvtpHdr(avtp_stream_t *pStream, U8 *pFill)
{
AVB_TRACE_ENTRY(AVB_TRACE_AVTP_DETAIL);
-
+
switch (pStream->pMapCB->map_avtp_version_cb()) {
default:
AVB_RC_LOG_RET(AVB_RC(OPENAVB_AVTP_FAILURE | OPENAVBAVTP_RC_INVALID_AVTP_VERSION));
@@ -342,7 +342,7 @@ openavbRC openavbAvtpTx(void *pv, bool bSend, bool txBlockingInIntf)
// Call mapping module to move data into AVTP frame
txCBResult = pStream->pMapCB->map_tx_cb(pStream->pMediaQ, pAvtpFrame, &avtpFrameLen);
-
+
pStream->bytes += avtpFrameLen;
}
else {
@@ -515,7 +515,7 @@ static void x_avtpRxFrame(avtp_stream_t *pStream, U8 *pFrame, U32 frameLen)
}
pStream->pMapCB->map_rx_cb(pStream->pMediaQ, pFrame, frameLen);
-
+
// NOTE : This is a redundant call. It is handled in avtpTryRx()
// pStream->pIntfCB->intf_rx_cb(pStream->pMediaQ);
@@ -577,7 +577,7 @@ static void avtpTryRx(avtp_stream_t *pStream)
timeout = AVTP_MAX_BLOCK_USEC;
if (timeout < RAWSOCK_MIN_TIMEOUT_USEC)
timeout = RAWSOCK_MIN_TIMEOUT_USEC;
-
+
pBuf = (U8 *)openavbRawsockGetRxFrame(pStream->rawsock, timeout, &offsetToFrame, &frameLen);
if (!pBuf)
pStream->pIntfCB->intf_rx_cb(pStream->pMediaQ);
diff --git a/lib/avtp_pipeline/endpoint/openavb_endpoint.c b/lib/avtp_pipeline/endpoint/openavb_endpoint.c
index 0238487d..30d8114a 100644
--- a/lib/avtp_pipeline/endpoint/openavb_endpoint.c
+++ b/lib/avtp_pipeline/endpoint/openavb_endpoint.c
@@ -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 9e6708ae..a3f82078 100644
--- a/lib/avtp_pipeline/endpoint/openavb_endpoint.h
+++ b/lib/avtp_pipeline/endpoint/openavb_endpoint.h
@@ -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;
@@ -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 14b54497..27d08cee 100644
--- a/lib/avtp_pipeline/endpoint/openavb_endpoint_client.c
+++ b/lib/avtp_pipeline/endpoint/openavb_endpoint_client.c
@@ -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;
diff --git a/lib/avtp_pipeline/endpoint/openavb_endpoint_server.c b/lib/avtp_pipeline/endpoint/openavb_endpoint_server.c
index 7736184c..22208333 100644
--- a/lib/avtp_pipeline/endpoint/openavb_endpoint_server.c
+++ b/lib/avtp_pipeline/endpoint/openavb_endpoint_server.c
@@ -84,12 +84,13 @@ static bool openavbEptSrvrReceiveFromClient(int h, openavbEndpointMessage_t *msg
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,6 +120,7 @@ void openavbEptSrvrNotifyTlkrOfSrpCb(int h,
char *ifname,
U8 destAddr[ETH_ALEN],
openavbSrpLsnrDeclSubtype_t lsnrDecl,
+ U8 srClass,
U32 classRate,
U16 vlanID,
U8 priority,
@@ -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;
@@ -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,
@@ -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);
diff --git a/lib/avtp_pipeline/include/openavb_log_pub.h b/lib/avtp_pipeline/include/openavb_log_pub.h
index 805e2d01..846c169e 100644
--- a/lib/avtp_pipeline/include/openavb_log_pub.h
+++ b/lib/avtp_pipeline/include/openavb_log_pub.h
@@ -160,17 +160,17 @@ typedef enum {
#define LOG_VARX(x, y) x ## y
#define LOG_VAR(x, y) LOG_VARX(x, y)
-// Log a message once. Technically once every 4.2 billion attempts. Usage: LOG_ONCE AVB_LOG_INFO(...)
-#define IF_LOG_ONCE() static U32 LOG_VAR(logOnce,__LINE__); if (!LOG_VAR(logOnce,__LINE__)++)
+// Log a message once. Technically once every 4.2 billion attempts. Usage: IF_LOG_ONCE() AVB_LOG_INFO(...)
+#define IF_LOG_ONCE() static U32 LOG_VAR(logOnce,__LINE__) = 0; if (!LOG_VAR(logOnce,__LINE__)++)
-// Log a message at an interval. Usage: LOG_INTERVAL(100) AVB_LOG_INFO(...)
-#define IF_LOG_INTERVAL(x) static U32 LOG_VAR(logOnce,__LINE__); if (!(LOG_VAR(logOnce,__LINE__)++ % (x - 1)))
+// Log a message at an interval. Usage: IF_LOG_INTERVAL(100) AVB_LOG_INFO(...)
+#define IF_LOG_INTERVAL(x) static U32 LOG_VAR(logOnce,__LINE__) = 0; if (!(LOG_VAR(logOnce,__LINE__)++ % (x)))
#define ETH_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x"
#define ETH_OCTETS(a) (a)[0],(a)[1],(a)[2],(a)[3],(a)[4],(a)[5]
-#define STREAMID_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x/%d"
+#define STREAMID_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x/%u"
#define STREAMID_ARGS(s) (s)->addr[0],(s)->addr[1],(s)->addr[2],(s)->addr[3],(s)->addr[4],(s)->addr[5],(s)->uniqueID
#define ENTITYID_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
@@ -206,15 +206,21 @@ void avbLogBuffer(
#define avbLogFn2(level, tag, company, component, path, line, fmt, ...) \
- ({\
+ {\
if (level <= AVB_LOG_LEVEL) \
avbLogFn(0, tag, company, component, path, line, fmt, __VA_ARGS__); \
- })
+ }
#define avbLogRT2(level, bBegin, bItem, bEnd, pFormat, dataType, pVar) \
{\
if (level <= AVB_LOG_LEVEL) \
- avbLogRT(level, bBegin, bItem, bEnd, pFormat, dataType, pVar); \
+ avbLogRT(0, bBegin, bItem, bEnd, pFormat, dataType, pVar); \
+ }
+
+#define avbLogBuffer2(level, pData, dataLen, lineLen, company, component, path, line) \
+ {\
+ if (level <= AVB_LOG_LEVEL) \
+ avbLogBuffer(0, pData, dataLen, lineLen, company, component, path, line); \
}
#ifdef AVB_LOG_ON
@@ -238,7 +244,7 @@ void avbLogBuffer(
#define AVB_LOGRT_STATUS(BEGIN, ITEM, END, FMT, TYPE, VAL) avbLogRT2(AVB_LOG_LEVEL_STATUS, BEGIN, ITEM, END, FMT, TYPE, VAL)
#define AVB_LOGRT_DEBUG(BEGIN, ITEM, END, FMT, TYPE, VAL) avbLogRT2(AVB_LOG_LEVEL_DEBUG, BEGIN, ITEM, END, FMT, TYPE, VAL)
#define AVB_LOGRT_VERBOSE(BEGIN, ITEM, END, FMT, TYPE, VAL) avbLogRT2(AVB_LOG_LEVEL_VERBOSE, BEGIN, ITEM, END, FMT, TYPE, VAL)
-#define AVB_LOG_BUFFER(LEVEL, DATA, DATALEN, LINELINE) avbLogBuffer(LEVEL, DATA, DATALEN, LINELINE, AVB_LOG_COMPANY, AVB_LOG_COMPONENT, __FILE__, __LINE__)
+#define AVB_LOG_BUFFER(LEVEL, DATA, DATALEN, LINELINE) avbLogBuffer2(LEVEL, DATA, DATALEN, LINELINE, AVB_LOG_COMPANY, AVB_LOG_COMPONENT, __FILE__, __LINE__)
#else
#define AVB_LOGF_DEV(LEVEL, FMT, ...)
#define AVB_LOGF_ERROR(FMT, ...)
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/map_aaf_audio/openavb_map_aaf_audio_pub.h b/lib/avtp_pipeline/map_aaf_audio/openavb_map_aaf_audio_pub.h
index 8575ecd7..213f3bb6 100755
--- a/lib/avtp_pipeline/map_aaf_audio/openavb_map_aaf_audio_pub.h
+++ b/lib/avtp_pipeline/map_aaf_audio/openavb_map_aaf_audio_pub.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.
*************************************************************************************************************/
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/platform/Linux/endpoint/openavb_endpoint_osal_srp.c b/lib/avtp_pipeline/platform/Linux/endpoint/openavb_endpoint_osal_srp.c
index 9a7e42f3..9a7d2b33 100644
--- a/lib/avtp_pipeline/platform/Linux/endpoint/openavb_endpoint_osal_srp.c
+++ b/lib/avtp_pipeline/platform/Linux/endpoint/openavb_endpoint_osal_srp.c
@@ -67,7 +67,7 @@ typedef struct {
openavb_list_t strElemList;
-#define SID_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x/%d"
+#define SID_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x/%u"
#define SID_OCTETS(a) (a)[0],(a)[1],(a)[2],(a)[3],(a)[4],(a)[5],(a)[6]<<8|(a)[7]
// Callback for SRP to notify AVTP Talker that a Listener Declaration has been
diff --git a/lib/avtp_pipeline/platform/Linux/rawsock/ring_rawsock.c b/lib/avtp_pipeline/platform/Linux/rawsock/ring_rawsock.c
index 64d222fe..f66878c1 100644
--- a/lib/avtp_pipeline/platform/Linux/rawsock/ring_rawsock.c
+++ b/lib/avtp_pipeline/platform/Linux/rawsock/ring_rawsock.c
@@ -219,9 +219,9 @@ U8* ringRawsockGetTxFrame(void *pvRawsock, bool blocking, unsigned int *len)
// And pointer to portion of buffer to be filled with frame
volatile U8 *pBuffer = (U8*)pHdr + rawsock->bufHdrSize;
- AVB_LOGF_VERBOSE("block=%d, buffer=%d, out=%d, pHdr=%p, pBuffer=%p",
+ AVB_LOGF_VERBOSE("block=%d, buffer=%d, out=%d, pBuffer=%p, pHdr=%p",
rawsock->blockIndex, rawsock->bufferIndex, rawsock->buffersOut,
- pHdr, pBuffer);
+ pBuffer, pHdr);
// Check if buffer ready for user
// In send mode, we want to see TP_STATUS_AVAILABLE
@@ -485,9 +485,9 @@ U8* ringRawsockGetRxFrame(void *pvRawsock, U32 timeout, unsigned int *offset, un
+ (rawsock->bufferIndex * rawsock->bufferSize));
volatile U8 *pBuffer = (U8*)pHdr + rawsock->bufHdrSize;
- AVB_LOGF_VERBOSE("block=%d, buffer=%d, out=%d, pHdr=%p, pBuffer=%p",
+ AVB_LOGF_VERBOSE("block=%d, buffer=%d, out=%d, pBuffer=%p, pHdr=%p",
rawsock->blockIndex, rawsock->bufferIndex, rawsock->buffersOut,
- pHdr, pBuffer);
+ pBuffer, pHdr);
// Check if buffer ready for user
// In receive mode, we want TP_STATUS_USER flag set
@@ -601,7 +601,12 @@ U8* ringRawsockGetRxFrame(void *pvRawsock, U32 timeout, unsigned int *offset, un
rawsock->buffersOut += 1;
if (pHdr->tp_snaplen < pHdr->tp_len) {
+#if (AVB_LOG_LEVEL >= AVB_LOG_LEVEL_VERBOSE)
+ AVB_LOGF_WARNING("Getting RX frame; partial frame ignored (len %d, snaplen %d)", pHdr->tp_len, pHdr->tp_snaplen);
+ AVB_LOG_BUFFER(AVB_LOG_LEVEL_VERBOSE, (const U8 *) pBuffer + (pHdr->tp_mac - rawsock->bufHdrSize), pHdr->tp_len, 16);
+#else
IF_LOG_INTERVAL(1000) AVB_LOGF_WARNING("Getting RX frame; partial frame ignored (len %d, snaplen %d)", pHdr->tp_len, pHdr->tp_snaplen);
+#endif
ringRawsockRelRxFrame(rawsock, (U8*)pBuffer);
AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL);
return NULL;
@@ -610,6 +615,7 @@ U8* ringRawsockGetRxFrame(void *pvRawsock, U32 timeout, unsigned int *offset, un
// Return pointer to the buffer and length
*offset = pHdr->tp_mac - rawsock->bufHdrSize;
*len = pHdr->tp_snaplen;
+ AVB_LOGF_VERBOSE("Good RX frame (len %d, snaplen %d)", pHdr->tp_len, pHdr->tp_snaplen);
AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL);
return (U8*)pBuffer;
@@ -628,7 +634,7 @@ int ringRawsockRxParseHdr(void *pvRawsock, U8 *pBuffer, hdr_info_t *pInfo)
}
volatile struct tpacket2_hdr *pHdr = (struct tpacket2_hdr*)(pBuffer - rawsock->bufHdrSize);
- AVB_LOGF_VERBOSE("pBuffer=%p, pHdr=%p", pBuffer, pHdr);
+ AVB_LOGF_VERBOSE("ringRawsockRxParseHdr: pBuffer=%p, pHdr=%p", pBuffer, pHdr);
memset(pInfo, 0, sizeof(hdr_info_t));
@@ -665,7 +671,7 @@ bool ringRawsockRelRxFrame(void *pvRawsock, U8 *pBuffer)
}
volatile struct tpacket2_hdr *pHdr = (struct tpacket2_hdr*)(pBuffer - rawsock->bufHdrSize);
- AVB_LOGF_VERBOSE("pBuffer=%p, pHdr=%p", pBuffer, pHdr);
+ AVB_LOGF_VERBOSE("ringRawsockRelRxFrame: pBuffer=%p, pHdr=%p", pBuffer, pHdr);
pHdr->tp_status = TP_STATUS_KERNEL;
rawsock->buffersOut -= 1;
diff --git a/lib/avtp_pipeline/tl/openavb_listener.c b/lib/avtp_pipeline/tl/openavb_listener.c
index 6e91e144..53cb3b2e 100644
--- a/lib/avtp_pipeline/tl/openavb_listener.c
+++ b/lib/avtp_pipeline/tl/openavb_listener.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.
*************************************************************************************************************/
@@ -195,7 +195,7 @@ static inline bool listenerDoStream(tl_state_t *pTLState)
pListenerData->nReportCalls = 0;
pListenerData->nReportFrames = 0;
- pListenerData->nextReportNS += (pCfg->report_seconds * NANOSECONDS_PER_SECOND);
+ pListenerData->nextReportNS += (pCfg->report_seconds * NANOSECONDS_PER_SECOND);
}
} else if (pCfg->report_frames > 0 && pListenerData->nReportFrames != pListenerData->lastReportFrames) {
if (pListenerData->nReportFrames % pCfg->report_frames == 1) {
@@ -218,7 +218,7 @@ static inline bool listenerDoStream(tl_state_t *pTLState)
return bRet;
}
-// Called from openavbTLThreadFn() which is started from openavbTLRun()
+// Called from openavbTLThreadFn() which is started from openavbTLRun()
void openavbTLRunListener(tl_state_t *pTLState)
{
AVB_TRACE_ENTRY(AVB_TRACE_TL);
@@ -258,7 +258,7 @@ void openavbTLRunListener(tl_state_t *pTLState)
// Tell endpoint to listen for our stream.
// If there is a talker, we'll get callback (above.)
pTLState->bConnected = openavbTLRunListenerInit(pTLState->endpointHandle, &streamID);
-
+
if (pTLState->bConnected) {
bool bServiceIPC;
diff --git a/lib/avtp_pipeline/tl/openavb_talker.h b/lib/avtp_pipeline/tl/openavb_talker.h
index b886c363..86bfc39e 100644
--- a/lib/avtp_pipeline/tl/openavb_talker.h
+++ b/lib/avtp_pipeline/tl/openavb_talker.h
@@ -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 b20c5188..e3343e78 100644
--- a/lib/avtp_pipeline/tl/openavb_talker_endpoint.c
+++ b/lib/avtp_pipeline/tl/openavb_talker_endpoint.c
@@ -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 4a4768a8..03cb8ade 100644
--- a/lib/avtp_pipeline/tl/openavb_talker_no_endpoint.c
+++ b/lib/avtp_pipeline/tl/openavb_talker_no_endpoint.c
@@ -74,16 +74,17 @@ bool openavbTLRunTalkerInit(tl_state_t *pTLState)
}
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);
@@ -132,7 +133,7 @@ bool openavbTLRunTalkerInit(tl_state_t *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 41934926..4fc6eff5 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 8369db18..d89729a1 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