diff options
author | Brant Thomsen <brant.thomsen@harman.com> | 2017-07-14 11:02:57 -0600 |
---|---|---|
committer | Brant Thomsen <brant.thomsen@harman.com> | 2017-07-14 11:02:57 -0600 |
commit | cb9b92a85b86214d11fa6ac74effbe2ce6dd7428 (patch) | |
tree | fb316deaf7026658cb02e29b6f5fb02037e3469f | |
parent | 5a688712a58ea339097ffcbb5badf24373d36d2e (diff) | |
parent | 32a69cc195b83bf8a4cc65e97f01f1eb8636a982 (diff) | |
download | Open-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
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); |