HRESULT avcUnitNotifyAdd(LM_CONTEXT* notifyList, UNION_NOTIFY *notify, PB *packetBlock, BOOL bUsePacketBlock) { HRESULT hResult = NO_ERROR; uint32 notifyAddr = 0; notify->notifyComm.bUsePacketBlock = bUsePacketBlock; hResult = pbGetPacketSrcNodeAddr (packetBlock, ¬ifyAddr); if (hResult != NO_ERROR) return hResult; // determine if there is a notify from same nodeAddr hResult = avcUnitNotifyRemoveOld(notifyList, notifyAddr); if (hResult != NO_ERROR) return hResult; if (bUsePacketBlock) { // copy packetBlock, and add it to our list of Notifications hResult = pbCreateDuplicatePacket(packetBlock, ¬ify->notifyComm.packetBlock, NULL, PB_CREATE_AVC_CB); if (hResult != NO_ERROR) return hResult; } else { NODEHANDLE handle = 0; lalGetHandleFromNodeAddr(notifyAddr, &handle); notify->notifyComm.handle = handle; } hResult = lmAddElement(notifyList, notify, NULL); if (hResult != NO_ERROR) { avcUnitNotifyRemoveComm(notify); return hResult; } #ifdef _SYSDEBUG if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC & SYSDEBUG_TRACE_ERRORS)) //SYSDEBUG_TRACE_AVC { sysPrintCurTime(); sysDebugPrintf("avcUnitNotify insert new notify\n\r"); } #endif //_SYSDEBUG return hResult; }
HRESULT avcUnitNotifyRemoveOld(LM_CONTEXT* notifyList, uint32 nodeAddr) { HRESULT hResult = NO_ERROR; uint32 pos = 0; uint32 index = 0; UNION_NOTIFY *notify; uint32 notifyAddr = 0; BOOL bFound = FALSE; DO_FOREVER { hResult = lmGetNthElement(notifyList, (void **) ¬ify, pos++, &index); if (hResult != NO_ERROR) return NO_ERROR; hResult = pbGetPacketSrcNodeAddr (notify->notifyComm.packetBlock, ¬ifyAddr); lmReleaseElement(notifyList, index); if (hResult != NO_ERROR) return NO_ERROR; if (nodeAddr == notifyAddr) { lmRemoveElement(notifyList, index); bFound = TRUE; break; } } #ifdef _SYSDEBUG if (bFound) { if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC & SYSDEBUG_TRACE_ERRORS)) //SYSDEBUG_TRACE_AVC { sysPrintCurTime(); sysDebugPrintf("avcUnitNotify removed old notify\n\r"); } } #endif //_SYSDEBUG return hResult; }
HRESULT cmpP2PInConnectionBreak(uint32 iPCRNumber, uint32 oPCRNumber, uint16 oNodeAddr) { HRESULT hResult = NO_ERROR; uint32 iNodeAddr = 0; BOOL bUnconnected = TRUE; // check range of iPCRNumber; if (iPCRNumber > plugsGetNumIsochInPlugs()) { hResult = E_CMP_PCR_INVALID; sysLogError(hResult, __LINE__, moduleName); return hResult; } hResult = lalGetThisNodeAddr(&iNodeAddr); if (hResult != NO_ERROR) return hResult; //LM??? retry? hResult = cmpP2PConnectionBreaking(iPCRNumber, (uint16) iNodeAddr, oPCRNumber, oNodeAddr, &bUnconnected); #ifdef _SYSDEBUG if (hResult != NO_ERROR) { if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP)) { sysPrintCurTime(); sysDebugPrintf("cmp: cmpP2PConnectionBreaking failed - we should retry?\n\r"); } } #endif //_SYSDEBUG // update owned connections if (bUnconnected == TRUE) { cmpP2PInConnectionSetOwnedStatus(iPCRNumber, CONNECTION_STATUS_UNCONNECTED); } return hResult; }
HRESULT cmpP2PInConnectionRestore(uint32 iPCRNumber, uint32 oPCRNumber, uint16 oNodeAddr) { HRESULT hResult = NO_ERROR; uint32 iNodeAddr = 0; // check range of iPCRNumber; if (iPCRNumber > plugsGetNumIsochInPlugs()) { hResult = E_CMP_PCR_INVALID; sysLogError(hResult, __LINE__, moduleName); return hResult; } hResult = lalGetThisNodeAddr(&iNodeAddr); if (hResult != NO_ERROR) return hResult; //LM??? retry hResult = cmpP2PConnectionEstablishing(iPCRNumber, (uint16) iNodeAddr, oPCRNumber, oNodeAddr, TRUE /*bRestore*/); #ifdef _SYSDEBUG if (hResult != NO_ERROR) { if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP)) { sysPrintCurTime(); sysDebugPrintf("cmp: cmpP2PConnectionRestore failed - we should retry\n\r"); } } #endif //_SYSDEBUG if (hResult != NO_ERROR) return hResult; // update owned connections hResult = cmpP2PInConnectionSetOwned(iPCRNumber, oPCRNumber, oNodeAddr, CONNECTION_STATUS_CONNECTED); return hResult; }
HRESULT avcUnitNotifyCheck(LM_CONTEXT* notifyList, NOTIFY_CHECK_CALLBACK notifyCheckCB, NOTIFY_UPDATE_CALLBACK notifyUpdateCB) { HRESULT hResult = NO_ERROR; uint32 pos = 0; uint32 index = 0; pDataStream pStream = NULL; UNION_NOTIFY* notify = NULL; AVC_HEADER avcHeader; BOOL bChanged = FALSE; PB *packetBlock; // determine if there is a notify on the specified subunit DO_FOREVER { hResult = lmGetNthElement(notifyList, (void **) ¬ify, pos, &index); if (hResult != NO_ERROR) return NO_ERROR; bChanged = FALSE; // call callback to make notify specific check on notify state hResult = (* notifyCheckCB) (notify, &bChanged); if (bChanged) { #ifdef _SYSDEBUG if (sysDebugIsEnabled(SYSDEBUG_TRACE_AVC & SYSDEBUG_TRACE_ERRORS)) //SYSDEBUG_TRACE_AVC { sysPrintCurTime(); sysDebugPrintf("avcUnitNotify changed state for notify\n\r"); } #endif //_SYSDEBUG hResult = pbGetApplicationDatastream(notify->notifyComm.packetBlock, &pStream); if (hResult != NO_ERROR) break; hResult = avcDecodeHeader(pStream, &avcHeader); if (hResult != NO_ERROR) break; hResult = dsGotoMarker(pStream, DSMARKER_OPERAND_0); if (hResult != NO_ERROR) break; hResult = dsSwitchMode(pStream, dsMODE_WRITE); if (hResult != NO_ERROR) break; // call callback to write notify specific data into stream (from operand[0]) hResult = (* notifyUpdateCB) (notify, pStream); if (hResult != NO_ERROR) break; packetBlock = notify->notifyComm.packetBlock; hResult = lmReleaseElement(notifyList, index); if (hResult != NO_ERROR) break; hResult = lmRemoveElement(notifyList, index); if (hResult != NO_ERROR) break; hResult = avcReplyResponse (AVC_RESPONSE_CHANGED, packetBlock); if (hResult != NO_ERROR) break; } else { lmReleaseElement(notifyList, index); pos++; } } lmReleaseElement(notifyList, index); return hResult; }
HRESULT cmpP2PInConnectionRestoreOwned(BOOL *bRestoreAllDone) { HRESULT hResult = NO_ERROR; uint32 iPCRNumber = 0; uint32 oPCRNumber = 0; uint16 oNodeAddr = 0; CONNECTION_STATUS status = CONNECTION_STATUS_UNCONNECTED; *bRestoreAllDone = TRUE; for (iPCRNumber = 0; iPCRNumber < plugsGetNumIsochInPlugs(); iPCRNumber++) { hResult = cmpP2PInConnectionGetOwnedStatus(iPCRNumber, &status); if (hResult == NO_ERROR && status == CONNECTION_STATUS_PENDING) { #ifdef _CMP_P2P_USE_NODE_HANDLE // handles are already updated during bus reset if (hResult == NO_ERROR) { hResult = cmpP2PInConnectionGetOwned(iPCRNumber, &oPCRNumber, &oNodeAddr, &status); } #else //_CMP_P2P_USE_NODE_HANDLE // get nodeID from CIP header of a isoch packet on specified channel in iPCR update owned connection with obtained nodeAddr uint32 sourceID = 0; uint16 busID = 0; BOOL bValid = FALSE; bValid = avsRxGetSourceID(iPCRNumber, &sourceID); if (bValid == TRUE) { if (hResult == NO_ERROR) { hResult = lalGetBusID(&busID); } #ifdef _SYSDEBUG if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP)) { uint32 iNodeAddr = 0; hResult = lalGetThisNodeAddr(&iNodeAddr); sysPrintCurTime(); sysDebugPrintf("cmp:avsRxGetSourceID returned sourceNodeAddr: 0x%04x, thisNodeAddr: 0x%04x\n\r", busID | sourceID, iNodeAddr); } #endif //_SYSDEBUG if (hResult == NO_ERROR) { hResult = cmpP2PInConnectionGetOwned(iPCRNumber, &oPCRNumber, &oNodeAddr, &status); } if (hResult == NO_ERROR) { oNodeAddr = (uint16) (busID | sourceID); hResult = cmpP2PInConnectionSetOwned(iPCRNumber, oPCRNumber, oNodeAddr, status); } } else { #ifdef _SYSDEBUG if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP)) { sysPrintCurTime(); sysDebugPrintf("cmp:avsRxGetSourceID returned FALSE\n\r"); } #endif //_SYSDEBUG hResult = E_CMP_PCR_NOT_CONNECTED; } #endif //_CMP_P2P_USE_NODE_HANDLE if (hResult == NO_ERROR) { hResult = cmpP2PInConnectionRestore(iPCRNumber, oPCRNumber, oNodeAddr); } if (hResult != NO_ERROR) { *bRestoreAllDone = FALSE; } } } return hResult; }
// break a connection between the iPCR,iNodeAddr and the oPCR,oNodeAddr specified static HRESULT cmpP2PConnectionBreaking(uint32 iPCRNumber, uint16 iNodeAddr, uint32 oPCRNumber, uint16 oNodeAddr, BOOL *bUnconnected) { HRESULT hResult = NO_ERROR; uint32 iPCR = 0; uint32 oPCR = 0; uint32 iPCRNew = 0; uint32 oPCRNew = 0; uint32 iPCRP2PCount = 0; uint32 oPCRP2PCount = 0; uint32 oPCRConnCount = 0; uint32 channel = 0; uint32 bandwidth = 0; BOOL bBreakingOK = FALSE; hResult = cmpReadiPCR(iPCRNumber, iNodeAddr, &iPCR); if (hResult != NO_ERROR) return hResult; hResult = cmpReadoPCR(oPCRNumber, oNodeAddr, &oPCR); if (hResult != NO_ERROR) return hResult; iPCRNew = iPCR; oPCRNew = oPCR; iPCRP2PCount = cmpGetPCRP2PCount(iPCR); oPCRP2PCount = cmpGetPCRP2PCount(oPCR); if (iPCRP2PCount == 0) // oPCR not connected (can't break p2p connection) { hResult = E_CMP_PCR_NOT_CONNECTED; sysLogError(hResult, __LINE__, moduleName); return hResult; } if (oPCRP2PCount == 0) // oPCR not connected (just update local iPCR - connection was not established correctly) { #ifdef _SYSDEBUG if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP)) { sysPrintCurTime(); sysDebugPrintf("cmp:couldn't break connection completely because oPCRP2PCount: 0\n\r"); } #endif //_SYSDEBUG } if (oPCRP2PCount > 0) { oPCRP2PCount--; cmpSetPCRP2PCount(&oPCRNew, oPCRP2PCount); hResult = cmpLockoPCR(oPCRNumber, oNodeAddr, oPCR, oPCRNew); bBreakingOK = (hResult == NO_ERROR); } if (hResult == NO_ERROR) { iPCRP2PCount--; cmpSetPCRP2PCount(&iPCRNew, iPCRP2PCount); hResult = cmpLockiPCR(iPCRNumber, iNodeAddr, iPCR, iPCRNew); } *bUnconnected = (cmpGetPCRP2PCount(iPCRNew) == 0); if (bBreakingOK == TRUE) { oPCRConnCount = cmpGetPCRConnCount(oPCRNew); if (oPCRConnCount == 0) // deallocate 1394 resources if oPCR unconnected { bandwidth = cmpGetPCRBandwidth(oPCR); channel = cmpGetPCRChannel(oPCR); cmpDeallocateIRMResources(channel, bandwidth); } } return hResult; }
// create or overlay a connection between the iPCR,iNodeAddr and the oPCR,oNodeAddr specified static HRESULT cmpP2PConnectionEstablishing(uint32 iPCRNumber, uint16 iNodeAddr, uint32 oPCRNumber, uint16 oNodeAddr, BOOL bRestore) { HRESULT hResult = NO_ERROR; uint32 iPCR = 0; uint32 oPCR = 0; uint32 iPCRP2PCount = 0; uint32 oPCRConnCount = 0; uint32 channel = IRM_ANY_AVAIL_ISOCH_CHANNEL; uint32 bandwidth = 0; hResult = cmpReadiPCRWithPriority(iPCRNumber, iNodeAddr, &iPCR, TRUE); if (hResult != NO_ERROR) return hResult; hResult = cmpReadoPCRWithPriority(oPCRNumber, oNodeAddr, &oPCR, TRUE); if (hResult != NO_ERROR) return hResult; iPCRP2PCount = cmpGetPCRP2PCount(iPCR); oPCRConnCount = cmpGetPCRConnCount(oPCR); if (iPCRP2PCount != 0) // iPCR already connected (can't establish p2p connection) { hResult = E_CMP_PCR_ALREADY_CONNECTED; sysLogError(hResult, __LINE__, moduleName); return hResult; } if (bRestore) // channel in oPCR already specified (perform restoring of p2p connection) { channel = cmpGetPCRChannel(oPCR); } if (oPCRConnCount == 0) // oPCR not connected (allocate IRM resources) { bandwidth = cmpGetPCRBandwidth(oPCR); hResult = cmpAllocateIRMResources(&channel, bandwidth); if (hResult != NO_ERROR) return hResult; } else if (bRestore == FALSE) // oPCR already connected (perform overlaying of p2p connection) { channel = cmpGetPCRChannel(oPCR); } //LM??? retry hResult = cmpP2PConnectionOverlaying(iPCR, iPCRNumber, iNodeAddr, oPCR, oPCRNumber, oNodeAddr, channel, FALSE); #ifdef _SYSDEBUG if (hResult != NO_ERROR) { if (sysDebugIsEnabled(SYSDEBUG_TRACE_CMP)) { sysPrintCurTime(); sysDebugPrintf("cmp: cmpP2PConnectionOverlaying failed - we should retry\n\r"); } } #endif //_SYSDEBUG if (hResult != NO_ERROR) { if (bandwidth) cmpDeallocateIRMResources(channel, bandwidth); return hResult; } return hResult; }