summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrant Thomsen <brant.thomsen@harman.com>2017-07-14 11:02:57 -0600
committerBrant Thomsen <brant.thomsen@harman.com>2017-07-14 11:02:57 -0600
commitcb9b92a85b86214d11fa6ac74effbe2ce6dd7428 (patch)
treefb316deaf7026658cb02e29b6f5fb02037e3469f
parent5a688712a58ea339097ffcbb5badf24373d36d2e (diff)
parent32a69cc195b83bf8a4cc65e97f01f1eb8636a982 (diff)
downloadOpen-AVB-cb9b92a85b86214d11fa6ac74effbe2ce6dd7428.tar.gz
Merge branch 'avb_endpoint' of ssh://git.ctg-server.hmg.ad.harman.com:2222/clones/Open-AVB into feature-avtp-pipeline-avdecc
-rw-r--r--lib/avtp_pipeline/acmp/openavb_acmp.h2
-rw-r--r--lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c17
-rw-r--r--lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c27
-rw-r--r--lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h3
-rw-r--r--lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_client.c63
-rw-r--r--lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_server.c67
-rw-r--r--lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_pipeline_interaction.c21
-rw-r--r--lib/avtp_pipeline/tl/openavb_listener_endpoint.c6
8 files changed, 152 insertions, 54 deletions
diff --git a/lib/avtp_pipeline/acmp/openavb_acmp.h b/lib/avtp_pipeline/acmp/openavb_acmp.h
index 919b9bc1..0d124fe7 100644
--- a/lib/avtp_pipeline/acmp/openavb_acmp.h
+++ b/lib/avtp_pipeline/acmp/openavb_acmp.h
@@ -136,7 +136,7 @@ typedef struct {
typedef struct {
U8 talker_entity_id[8];
U16 talker_unique_id;
- U8 connected;
+ U8 connected; // Boolean
U8 stream_id[8];
U8 stream_dest_mac[6];
U8 controller_entity_id[8];
diff --git a/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c b/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c
index 42565bdc..53bc2fa4 100644
--- a/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c
+++ b/lib/avtp_pipeline/acmp/openavb_acmp_sm_listener.c
@@ -255,12 +255,12 @@ U8 openavbAcmpSMListener_connectListener(openavb_acmp_ACMPCommandResponse_t *res
openavb_acmp_ListenerStreamInfo_t *pListenerStreamInfo = openavbArrayDataIdx(openavbAcmpSMListenerVars.listenerStreamInfos, response->listener_unique_id);
if (pListenerStreamInfo) {
+ memcpy(pListenerStreamInfo->stream_id, response->stream_id, sizeof(pListenerStreamInfo->stream_id));
+ memcpy(pListenerStreamInfo->controller_entity_id, response->controller_entity_id, sizeof(pListenerStreamInfo->controller_entity_id));
memcpy(pListenerStreamInfo->talker_entity_id, response->talker_entity_id, sizeof(pListenerStreamInfo->talker_entity_id));
pListenerStreamInfo->talker_unique_id = response->talker_unique_id;
- pListenerStreamInfo->connected = TRUE;
- memcpy(pListenerStreamInfo->stream_id, response->stream_id, sizeof(pListenerStreamInfo->stream_id));
memcpy(pListenerStreamInfo->stream_dest_mac, response->stream_dest_mac, sizeof(pListenerStreamInfo->stream_dest_mac));
- memcpy(pListenerStreamInfo->controller_entity_id, response->controller_entity_id, sizeof(pListenerStreamInfo->controller_entity_id));
+ pListenerStreamInfo->connected = TRUE;
pListenerStreamInfo->flags = response->flags;
pListenerStreamInfo->stream_vlan_id = response->stream_vlan_id;
@@ -349,12 +349,13 @@ U8 openavbAcmpSMListener_getState(openavb_acmp_ACMPCommandResponse_t *command)
openavb_acmp_ListenerStreamInfo_t *pListenerStreamInfo = openavbArrayDataIdx(openavbAcmpSMListenerVars.listenerStreamInfos, command->listener_unique_id);
if (pListenerStreamInfo) {
memcpy(command->stream_id, pListenerStreamInfo->stream_id, sizeof(command->stream_id));
+ memcpy(command->talker_entity_id, pListenerStreamInfo->talker_entity_id, sizeof(command->talker_entity_id));
+ command->talker_unique_id = pListenerStreamInfo->talker_unique_id;
+ //command->listener_unique_id = command->listener_unique_id; // Overwriting data in passed in structure
memcpy(command->stream_dest_mac, pListenerStreamInfo->stream_dest_mac, sizeof(command->stream_dest_mac));
- command->stream_vlan_id = pListenerStreamInfo->stream_vlan_id;
command->connection_count = pListenerStreamInfo->connected ? 1 : 0; // AVDECC_TODO - questionable information in spec.
command->flags = pListenerStreamInfo->flags;
- memcpy(command->talker_entity_id, pListenerStreamInfo->talker_entity_id, sizeof(command->talker_entity_id));
- //command->listener_unique_id = command->listener_unique_id; // Overwriting data in passed in structure
+ command->stream_vlan_id = pListenerStreamInfo->stream_vlan_id;
retStatus = OPENAVB_ACMP_STATUS_SUCCESS;
}
@@ -548,7 +549,7 @@ void openavbAcmpSMListenerStateMachine()
openavb_acmp_ACMPCommandResponse_t response;
memcpy(&response, pRcvdCmdResp, sizeof(response));
if (openavbAcmpSMListener_validListenerUnique(pRcvdCmdResp->listener_unique_id)) {
- error = openavbAcmpSMListener_getState(pRcvdCmdResp);
+ error = openavbAcmpSMListener_getState(&response);
}
else {
error = OPENAVB_ACMP_STATUS_LISTENER_UNKNOWN_ID;
@@ -862,6 +863,7 @@ void openavbAcmpSMListenerSet_doTerminate(bool value)
void openavbAcmpSMListenerSet_doFastConnect(const openavb_tl_data_cfg_t *pListener, U16 flags, U16 talker_unique_id, const U8 talker_entity_id[8], const U8 controller_entity_id[8])
{
openavb_acmp_ACMPCommandResponse_t command;
+ static U16 s_sequence_id = 0;
// Get the descriptor and listener_unique_id for the supplied listener.
openavb_aem_descriptor_stream_io_t *pDescriptor;
@@ -906,6 +908,7 @@ void openavbAcmpSMListenerSet_doFastConnect(const openavb_tl_data_cfg_t *pListen
command.talker_unique_id = talker_unique_id;
command.listener_unique_id = listenerUniqueId;
memset(command.stream_dest_mac, 0xFF, 6);
+ command.sequence_id = ++s_sequence_id;
command.flags = flags | OPENAVB_ACMP_FLAG_FAST_CONNECT | OPENAVB_ACMP_FLAG_SAVED_STATE;
AVB_LOGF_INFO("Listener %s attempting fast connect to flags=0x%04x, talker_unique_id=0x%04x, talker_entity_id=" ENTITYID_FORMAT ", controller_entity_id=" ENTITYID_FORMAT,
diff --git a/lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c b/lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c
index 9e298307..53d77758 100644
--- a/lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c
+++ b/lib/avtp_pipeline/acmp/openavb_acmp_sm_talker.c
@@ -127,13 +127,22 @@ U8 openavbAcmpSMTalker_connectTalker(openavb_acmp_ACMPCommandResponse_t *command
if (pTalkerStreamInfo) {
openavb_list_node_t node = openavbAcmpSMTalker_findListenerPairNodeFromCommand(command);
if (node) {
- // Already connected, so return the current status.
- 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;
- command->connection_count = pTalkerStreamInfo->connection_count;
- openavbAcmpSMTalker_txResponse(OPENAVB_ACMP_MESSAGE_TYPE_CONNECT_TX_RESPONSE, command, OPENAVB_ACMP_STATUS_SUCCESS);
- retStatus = OPENAVB_ACMP_STATUS_SUCCESS;
+ if (memcmp(pTalkerStreamInfo->stream_id, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0 ||
+ memcmp(pTalkerStreamInfo->stream_dest_mac, "\x00\x00\x00\x00\x00\x00", 6) == 0) {
+ // In the process of connecting. Ignore this, as we don't yet have a response.
+ AVB_LOG_INFO("Ignoring duplicate CONNECT_TX_COMMAND");
+ retStatus = OPENAVB_ACMP_STATUS_SUCCESS;
+ }
+ else {
+ // Already connected, so return the current status.
+ AVB_LOG_DEBUG("Sending immediate response to CONNECT_TX_COMMAND");
+ 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;
+ command->connection_count = pTalkerStreamInfo->connection_count;
+ openavbAcmpSMTalker_txResponse(OPENAVB_ACMP_MESSAGE_TYPE_CONNECT_TX_RESPONSE, command, OPENAVB_ACMP_STATUS_SUCCESS);
+ retStatus = OPENAVB_ACMP_STATUS_SUCCESS;
+ }
}
else {
if (!pTalkerStreamInfo->connected_listeners) {
@@ -152,13 +161,9 @@ U8 openavbAcmpSMTalker_connectTalker(openavb_acmp_ACMPCommandResponse_t *command
AVB_TRACE_EXIT(AVB_TRACE_ACMP);
return retStatus;
}
- openavbAVDECCGetTalkerStreamInfo(pDescriptorStreamOutput, configIdx, pTalkerStreamInfo);
if (openavbAVDECCRunTalker(pDescriptorStreamOutput, configIdx, pTalkerStreamInfo)) {
- 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;
command->connection_count = pTalkerStreamInfo->connection_count;
// Wait for the Talker to supply us with updated stream information.
diff --git a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h
index 683c555c..01c6bde9 100644
--- a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h
+++ b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg.h
@@ -80,7 +80,8 @@ typedef enum {
OPENAVB_AVDECC_MSG_UNKNOWN = 0,
OPENAVB_AVDECC_MSG_STOPPED,
OPENAVB_AVDECC_MSG_RUNNING,
- OPENAVB_AVDECC_MSG_PAUSED
+ OPENAVB_AVDECC_MSG_PAUSED,
+ OPENAVB_AVDECC_MSG_STOPPED_UNEXPECTEDLY,
} openavbAvdeccMsgStateType_t;
typedef enum {
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 c097370b..f2addd41 100644
--- a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_client.c
+++ b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_client.c
@@ -174,6 +174,18 @@ 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 the stream information to the server.
memset(&msgBuf, 0, OPENAVB_AVDECC_MSG_LEN);
msgBuf.type = OPENAVB_AVDECC_MSG_TALKER_STREAM_ID;
@@ -206,14 +218,27 @@ bool openavbAvdeccMsgClntHndlListenerStreamIDFromServer(int avdeccMsgHandle, con
return false;
}
- // Update the stream information supplied by the server.
+ // Determine if the supplied information differs from the current settings.
openavb_tl_cfg_t * pCfg = &(pState->pTLState->cfg);
- 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;
+ 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 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");
+ openavbAvdeccMsgClntHndlChangeRequestFromServer(avdeccMsgHandle, OPENAVB_AVDECC_MSG_STOPPED);
+ }
+
+ // Update the stream information supplied by the server.
+ 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("AVDECC-supplied 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,
@@ -243,16 +268,16 @@ bool openavbAvdeccMsgClntHndlChangeRequestFromServer(int avdeccMsgHandle, openav
if (pState->pTLState->bRunning) {
if (openavbTLStop((tl_handle_t) pState->pTLState)) {
// NOTE: openavbTLStop() call will cause client change notification if successful.
- AVB_LOGF_INFO("Client %d state changed to stopped", avdeccMsgHandle);
+ AVB_LOGF_INFO("Client %d state changed to Stopped", avdeccMsgHandle);
ret = true;
} else {
// Notify server of issues.
- AVB_LOGF_ERROR("Unable to change client %d state to stopped", avdeccMsgHandle);
+ AVB_LOGF_ERROR("Unable to change client %d state to Stopped", avdeccMsgHandle);
openavbAvdeccMsgClntChangeNotification(avdeccMsgHandle, OPENAVB_AVDECC_MSG_UNKNOWN);
}
} else {
// Notify server we are already in this state.
- AVB_LOGF_INFO("Client %d state is already at stopped", avdeccMsgHandle);
+ AVB_LOGF_INFO("Client %d state is already at Stopped", avdeccMsgHandle);
openavbAvdeccMsgClntChangeNotification(avdeccMsgHandle, OPENAVB_AVDECC_MSG_STOPPED);
ret = true;
}
@@ -264,11 +289,11 @@ bool openavbAvdeccMsgClntHndlChangeRequestFromServer(int avdeccMsgHandle, openav
if (!(pState->pTLState->bRunning)) {
if (openavbTLRun((tl_handle_t) pState->pTLState)) {
// NOTE: openavbTLRun() call will cause client change notification if successful.
- AVB_LOGF_INFO("Client %d state changed to running", avdeccMsgHandle);
+ AVB_LOGF_INFO("Client %d state changed to Running", avdeccMsgHandle);
ret = true;
} else {
// Notify server of issues.
- AVB_LOGF_ERROR("Unable to change client %d state to running", avdeccMsgHandle);
+ AVB_LOGF_ERROR("Unable to change client %d state to Running", avdeccMsgHandle);
openavbAvdeccMsgClntChangeNotification(avdeccMsgHandle, OPENAVB_AVDECC_MSG_UNKNOWN);
}
}
@@ -276,18 +301,18 @@ bool openavbAvdeccMsgClntHndlChangeRequestFromServer(int avdeccMsgHandle, openav
if (pState->pTLState->cfg.role == AVB_ROLE_TALKER) {
openavbTLPauseTalker(pState->pTLState, FALSE);
// NOTE: openavbTLPauseTalker() call will cause Talker change notification.
- AVB_LOGF_INFO("Talker %d state changed from paused to running", avdeccMsgHandle);
+ AVB_LOGF_INFO("Talker %d state changed from Paused to Running", avdeccMsgHandle);
ret = true;
} else {
openavbTLPauseListener(pState->pTLState, FALSE);
// NOTE: openavbTLPauseListener() call will cause Listener change notification.
- AVB_LOGF_INFO("Listener %d state changed from paused to running", avdeccMsgHandle);
+ AVB_LOGF_INFO("Listener %d state changed from Paused to Running", avdeccMsgHandle);
ret = true;
}
}
else {
// Notify server we are already in this state.
- AVB_LOGF_INFO("Client %d state is already at running", avdeccMsgHandle);
+ AVB_LOGF_INFO("Client %d state is already at Running", avdeccMsgHandle);
openavbAvdeccMsgClntChangeNotification(avdeccMsgHandle, OPENAVB_AVDECC_MSG_RUNNING);
ret = true;
}
@@ -298,25 +323,25 @@ bool openavbAvdeccMsgClntHndlChangeRequestFromServer(int avdeccMsgHandle, openav
AVB_LOGF_DEBUG("Paused state requested for client %d", avdeccMsgHandle);
if (!(pState->pTLState->bRunning)) {
// Notify server of issues.
- AVB_LOGF_ERROR("Client %d attempted to pause the stream while not running.", avdeccMsgHandle);
+ AVB_LOGF_ERROR("Client %d attempted to pause the stream while not Running.", avdeccMsgHandle);
openavbAvdeccMsgClntChangeNotification(avdeccMsgHandle, OPENAVB_AVDECC_MSG_UNKNOWN);
}
else if (pState->pTLState->bRunning && !(pState->pTLState->bPaused)) {
if (pState->pTLState->cfg.role == AVB_ROLE_TALKER) {
openavbTLPauseTalker(pState->pTLState, TRUE);
// NOTE: openavbTLPauseTalker() call will cause Talker change notification.
- AVB_LOGF_INFO("Talker %d state changed from running to paused", avdeccMsgHandle);
+ AVB_LOGF_INFO("Talker %d state changed from Running to Paused", avdeccMsgHandle);
ret = true;
} else {
openavbTLPauseListener(pState->pTLState, TRUE);
// NOTE: openavbTLPauseListener() call will cause Listener change notification.
- AVB_LOGF_INFO("Listener %d state changed from running to paused", avdeccMsgHandle);
+ AVB_LOGF_INFO("Listener %d state changed from Running to Paused", avdeccMsgHandle);
ret = true;
}
}
else {
// Notify server we are already in this state.
- AVB_LOGF_INFO("Client %d state is already at paused", avdeccMsgHandle);
+ AVB_LOGF_INFO("Client %d state is already at Paused", avdeccMsgHandle);
openavbAvdeccMsgClntChangeNotification(avdeccMsgHandle, OPENAVB_AVDECC_MSG_PAUSED);
ret = true;
}
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 784da033..4959243e 100644
--- a/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_server.c
+++ b/lib/avtp_pipeline/avdecc_msg/openavb_avdecc_msg_server.c
@@ -237,7 +237,7 @@ bool openavbAvdeccMsgSrvrHndlTalkerStreamIDFromClient(int avdeccMsgHandle, const
ETH_OCTETS(pCfg->stream_addr.buffer.ether_addr_octet), pCfg->stream_uid);
AVB_LOGF_DEBUG("Talker-supplied 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("Talker-supplied vlan_id: %u", pCfg->vlan_id);
// Notify the state machine that we received this information.
openavbAcmpSMTalker_updateStreamInfo(pCfg);
@@ -299,6 +299,24 @@ bool openavbAvdeccMsgSrvrChangeRequest(int avdeccMsgHandle, openavbAvdeccMsgStat
return ret;
}
+static const char * GetStateString(openavbAvdeccMsgStateType_t state)
+{
+ switch (state) {
+ case OPENAVB_AVDECC_MSG_UNKNOWN:
+ return "Unknown";
+ case OPENAVB_AVDECC_MSG_STOPPED:
+ return "Stopped";
+ case OPENAVB_AVDECC_MSG_RUNNING:
+ return "Running";
+ case OPENAVB_AVDECC_MSG_PAUSED:
+ return "Paused";
+ case OPENAVB_AVDECC_MSG_STOPPED_UNEXPECTEDLY:
+ return "Stopped_Unexpectedly";
+ default:
+ return "ERROR";
+ }
+}
+
bool openavbAvdeccMsgSrvrHndlChangeNotificationFromClient(int avdeccMsgHandle, openavbAvdeccMsgStateType_t currentState)
{
AVB_TRACE_ENTRY(AVB_TRACE_AVDECC_MSG);
@@ -312,18 +330,22 @@ bool openavbAvdeccMsgSrvrHndlChangeNotificationFromClient(int avdeccMsgHandle, o
// Save the updated state.
if (currentState != pState->lastReportedState) {
- AVB_LOGF_INFO("client %d state changed from %d to %d", avdeccMsgHandle, pState->lastReportedState, currentState);
+ openavbAvdeccMsgStateType_t previousState = pState->lastReportedState;
pState->lastReportedState = currentState;
+ AVB_LOGF_INFO("Notified of client %d state change from %s to %s (Last requested: %s)",
+ avdeccMsgHandle, GetStateString(previousState), GetStateString(currentState), GetStateString(pState->lastRequestedState));
// If AVDECC did not yet set the client state, set the client state to the desired state.
if (pState->lastRequestedState == OPENAVB_AVDECC_MSG_UNKNOWN) {
if (pState->stream->initial_state == TL_INIT_STATE_RUNNING && pState->lastReportedState != OPENAVB_AVDECC_MSG_RUNNING) {
// Have the client be running if the user explicitly requested it to be running.
openavbAvdeccMsgSrvrChangeRequest(avdeccMsgHandle, OPENAVB_AVDECC_MSG_RUNNING);
- } else if (pState->stream->initial_state != TL_INIT_STATE_RUNNING && pState->lastReportedState == OPENAVB_AVDECC_MSG_RUNNING) {
+ }
+ else if (pState->stream->initial_state != TL_INIT_STATE_RUNNING && pState->lastReportedState == OPENAVB_AVDECC_MSG_RUNNING) {
// Have the client not be running if the user didn't explicitly request it to be running.
openavbAvdeccMsgSrvrChangeRequest(avdeccMsgHandle, OPENAVB_AVDECC_MSG_STOPPED);
- } else if (gAvdeccCfg.bFastConnectSupported &&
+ }
+ else if (gAvdeccCfg.bFastConnectSupported &&
!(pState->bTalker) &&
pState->lastReportedState == OPENAVB_AVDECC_MSG_STOPPED) {
// Listener started as not running, and is not configured to start in the running state.
@@ -339,6 +361,43 @@ bool openavbAvdeccMsgSrvrHndlChangeNotificationFromClient(int avdeccMsgHandle, o
}
}
}
+ else if (currentState == OPENAVB_AVDECC_MSG_STOPPED_UNEXPECTEDLY) {
+ if (previousState != OPENAVB_AVDECC_MSG_STOPPED_UNEXPECTEDLY &&
+ pState->lastRequestedState == OPENAVB_AVDECC_MSG_RUNNING &&
+ gAvdeccCfg.bFastConnectSupported) {
+ // The Talker disappeared. Use fast connect to assist with reconnecting if it reappears.
+ openavb_tl_data_cfg_t *pCfg = pState->stream;
+ if (pCfg) {
+ U16 flags, talker_unique_id;
+ U8 talker_entity_id[8], controller_entity_id[8];
+ bool bAvailable = openavbAvdeccGetSaveStateInfo(pCfg, &flags, &talker_unique_id, &talker_entity_id, &controller_entity_id);
+ if (bAvailable) {
+ // Set the timed-out status for the Listener's descriptor.
+ // The next time the Talker advertises itself, openavbAcmpSMListenerSet_talkerTestFastConnect() should try to reconnect.
+ openavb_aem_descriptor_stream_io_t *pDescriptor;
+ U16 listenerUniqueId;
+ for (listenerUniqueId = 0; listenerUniqueId < 0xFFFF; ++listenerUniqueId) {
+ pDescriptor = openavbAemGetDescriptor(openavbAemGetConfigIdx(), OPENAVB_AEM_DESCRIPTOR_STREAM_INPUT, listenerUniqueId);
+ if (pDescriptor && pDescriptor->stream &&
+ strcmp(pDescriptor->stream->friendly_name, pCfg->friendly_name) == 0) {
+ // We found a match.
+ AVB_LOGF_INFO("Listener %s waiting to fast connect to flags=0x%04x, talker_unique_id=0x%04x, talker_entity_id=" ENTITYID_FORMAT ", controller_entity_id=" ENTITYID_FORMAT,
+ pCfg->friendly_name,
+ flags,
+ talker_unique_id,
+ ENTITYID_ARGS(talker_entity_id),
+ ENTITYID_ARGS(controller_entity_id));
+ pDescriptor->fast_connect_status = OPENAVB_FAST_CONNECT_STATUS_TIMED_OUT;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Now that we have handled this, treat this state as a normal stop.
+ pState->lastReportedState = OPENAVB_AVDECC_MSG_STOPPED;
+ }
}
AVB_TRACE_EXIT(AVB_TRACE_AVDECC_MSG);
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 c3c34718..d88c0f85 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
@@ -64,17 +64,8 @@ bool openavbAVDECCRunListener(openavb_aem_descriptor_stream_io_t *pDescriptorStr
return FALSE;
}
- // Stop the Listener if it is currently running.
- if (pDescriptorStreamInput->stream->client->lastReportedState != OPENAVB_AVDECC_MSG_STOPPED) {
- if (!openavbAvdeccMsgSrvrChangeRequest(pDescriptorStreamInput->stream->client->avdeccMsgHandle, OPENAVB_AVDECC_MSG_STOPPED)) {
- AVB_LOG_ERROR("Error requesting Listener change to Stopped");
- AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
- return FALSE;
- }
- AVB_LOG_INFO("Listener state change to Stopped requested");
- }
-
// 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->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]),
@@ -250,7 +241,7 @@ bool openavbAVDECCGetTalkerStreamInfo(openavb_aem_descriptor_stream_io_t *pDescr
// Get the destination MAC Address.
if (!pDescriptorStreamOutput->stream->dest_addr.mac ||
memcmp(pDescriptorStreamOutput->stream->dest_addr.buffer.ether_addr_octet, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0) {
- AVB_LOG_ERROR("openavbAVDECCGetTalkerStreamInfo Invalid stream dest_addr");
+ AVB_LOG_DEBUG("openavbAVDECCGetTalkerStreamInfo Invalid stream dest_addr");
AVB_TRACE_EXIT(AVB_TRACE_AVDECC);
return FALSE;
}
@@ -272,6 +263,14 @@ bool openavbAVDECCGetTalkerStreamInfo(openavb_aem_descriptor_stream_io_t *pDescr
ETH_OCTETS(pTalkerStreamInfo->stream_id),
(((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;
}
diff --git a/lib/avtp_pipeline/tl/openavb_listener_endpoint.c b/lib/avtp_pipeline/tl/openavb_listener_endpoint.c
index 5da67521..95c2b215 100644
--- a/lib/avtp_pipeline/tl/openavb_listener_endpoint.c
+++ b/lib/avtp_pipeline/tl/openavb_listener_endpoint.c
@@ -42,6 +42,7 @@ https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
#include "openavb_endpoint.h"
#include "openavb_avtp.h"
#include "openavb_listener.h"
+#include "openavb_avdecc_msg.h"
// DEBUG Uncomment to turn on logging for just this module.
//#define AVB_LOG_ON 1
@@ -137,6 +138,11 @@ void openavbEptClntNotifyLstnrOfSrpCb(int endpointHandle,
// We're still interested in the stream
openavbEptClntAttachStream(pTLState->endpointHandle, streamID, openavbSrp_LDSt_Interest);
+
+ // Notify AVDECC that fast connect is desired.
+ if (pTLState->bAvdeccMsgRunning) {
+ openavbAvdeccMsgClntChangeNotification(pTLState->avdeccMsgHandle, OPENAVB_AVDECC_MSG_STOPPED_UNEXPECTEDLY);
+ }
}
AVB_TRACE_EXIT(AVB_TRACE_TL);