📄 cm_targt.c
字号:
** a successful forward close response, as they differ in Application Reply
** Size/Remaining Path Size
*/
if( !fOpen && ( psConnRecord->sPublic.bGRC == SUCCESS ) )
pLeFwdReply->bPathSize = 0;
else
/*
** end edits: November,15th 2005, H.F.
*/
pLeFwdReply->bPathSize = psConnRecord->bRemainingPathSize;
pLeFwdReply->bReserved = 0;
}
/*
** Build a good or bad reply header based on the status codes.
*/
CI_PrependReplyHeader( pComBuf,
fOpen ? CM_SC_FWD_OPEN : CM_SC_FWD_CLOSE,
psConnRecord->sPublic.bGRC,
psConnRecord->sPublic.iERC );
/*
** Return the packet tribble to the task that started this mess.
** Note that we've done so in the connection record.
*/
GS_ReturnTrrbl( pTrrbl );
*ppTrrbl = NULL;
} /* end of cm_IssueFwdReply() */
/*---------------------------------------------------------------------------
** cm_ObjectTask()
**---------------------------------------------------------------------------
*/
TASKRETURN cm_ObjectTask( TASKPARAM )
{
cm_ConnectionRecordType *psConnRecord;
cm_upsTrrblType upsTrrbl;
/*
** Process requests forever.
*/
while( 1 )
{
/*
** Grab a request from the queue & dispatch to the
** appropriate processing code.
*/
upsTrrbl.Generic = GS_TakeTrrbl( CM_xQid );
switch( upsTrrbl.Generic->eRequest )
{
case TREQ_TIMEOUT_CONNECTION:
/*
** Request to close one connection because of a timeout.
*/
cm_CloseConnection( upsTrrbl.Close, TRUE );
break;
case TREQ_CLOSE_CONNECTION:
/*
** Request to close one connetion.
*/
cm_CloseConnection( upsTrrbl.Close, FALSE );
break;
case TREQ_CLOSE_ALL_CONNECTIONS:
/*
** Request to close all connections and disable the connection
** manager from starting new connections.
** Fall through to the I'm alive case to close
** all existing connections.
*/
cm_s.fAllowConn = FALSE;
case TREQ_RX_IM_ALIVE:
/*
** I'm alive! packet received from another node.
** Scan the active connections list and shut down any existing
** connections with the other node (or all nodes).
*/
cm_ProcessImAlive( upsTrrbl.Packet );
break;
case TREQ_ALLOW_CONNECTIONS:
/*
** Allow connections to be accepted once again. This is the
** matching operation to TREQ_CLOSE_ALL_CONNECTIONS.
*/
cm_s.fAllowConn = TRUE;
GS_ReturnTrrbl( upsTrrbl.Generic );
break;
case TREQ_RX_UNSCHEDULED_PACKET:
/*
** Process a new unscheduled Rx packet,
** most likely a forward open or forward close.
*/
cm_ProcessNewRxPacket( upsTrrbl );
break;
case TREQ_INQUIRE_CONNECTION:
/*
** Inquire if a connection is active.
*/
cm_InquireConnection( upsTrrbl.Inquire );
break;
case TREQ_ENABLE_CONNECTION:
break;
case TREQ_DISABLE_CONNECTION:
break;
/*
** Internal reply from some portion of processing an open.
** - App open response.
** - Transport creation response.
** - App open complete response.
*/
case TREQ_APP_OPEN:
cm_ProcessAppOpen( upsTrrbl.AppOpenClose );
break;
case TREQ_APP_OPEN_COMPLETE:
cm_ProcessAppOpenComplete( upsTrrbl.AppOpenClose );
break;
case TREQ_RESERVE_TRANSPORTS:
psConnRecord = cm_GetPrivateRecord( upsTrrbl.Transport->psConnRecord );
psConnRecord->iSteps |= CM_PS_R_TRAN_RETURNED;
cm_ContinueProcessing( psConnRecord );
GS_DeleteTrrbl( upsTrrbl.Transport );
break;
case TREQ_START_TRANSPORTS:
psConnRecord = cm_GetPrivateRecord( upsTrrbl.Transport->psConnRecord );
psConnRecord->iSteps |= CM_PS_S_TRAN_RETURNED;
cm_ContinueProcessing( psConnRecord );
GS_DeleteTrrbl( upsTrrbl.Transport );
break;
/*
** Internal reply from some portion of procesing a close or timeout.
** - App close response.
** - Transport deletion response.
*/
case TREQ_APP_CLOSE:
cm_ProcessAppClose( upsTrrbl.AppOpenClose );
break;
case TREQ_DELETE_TRANSPORTS:
psConnRecord = cm_GetPrivateRecord( upsTrrbl.Transport->psConnRecord );
psConnRecord->iSteps |= CM_PS_D_TRAN_RETURNED;
cm_ContinueProcessing( psConnRecord );
GS_DeleteTrrbl( upsTrrbl.Transport );
break;
case TREQ_TIMER_EXPIRED:
cm_ProcessTimer( upsTrrbl.Timeout );
break;
/*
** Unsupported tribble.
*/
default:
GS_LogEvent( GS_UNSUPPORTED_TRIBBLE_REQUEST, upsTrrbl.Generic->eRequest, upsTrrbl.Generic, FATAL );
break;
} /* end of switch( pTrrbl->eRequest ) */
} /* end of while( 1 ) */
} /* end of cm_ObjectTask() */
/*---------------------------------------------------------------------------
** cm_PackConnId()
**---------------------------------------------------------------------------
*/
void cm_PackConnId( CM_LeConnIdType *psLeConnId, UINT8 abConnId[] )
{
UINT16 iConnNumber;
/*
** Pack a connection ID from tag order into wire order.
*/
iConnNumber = ( (UINT16)(abConnId[ 2 ]) << 8 ) + abConnId[ 1 ];
psLeConnId->bMacId = abConnId[ 0 ];
psLeConnId->iLeConnNumber = UC_iTOiLe( iConnNumber );
psLeConnId->bAbandoned = 0;
} /* end of cm_PackConnId() */
/*---------------------------------------------------------------------------
** cm_ParseFwdOpen()
**---------------------------------------------------------------------------
*/
void cm_ParseFwdOpen( CB_ComBufType *pComBuf,
cm_ConnectionRecordType *psConnRecord
)
{
INT16 iSegSize;
INT16 iSize;
INT16 iStartingSize;
UINT8 *pbPath;
UINT8 *pbNewPathSizeLocation;
CM_LeFwdOpenType *pLeFwdOpen;
CI_LeKeyType *psLeKey;
BOOL fHaveNetSegment;
BOOL fDone;
pbNewPathSizeLocation = NULL;
/*
** Initialize to not having seen a schedule segment yet
*/
fHaveNetSegment = FALSE;
/*
** Grab the stuff of interest from the forward open itself.
*/
pLeFwdOpen = CB_GetDataPtrComBuf( pComBuf );
psConnRecord->sPublic.bGRC = CI_GRC_SUCCESS;
psConnRecord->sPublic.iERC = CI_GRC_SUCCESS;
psConnRecord->sPublic.bOpenPriorityTickTime = pLeFwdOpen->bOpenPriorityTickTime;
psConnRecord->sPublic.bOpenTimeoutTicks = pLeFwdOpen->bOpenTimeoutTicks;
psConnRecord->sPublic.lLeProConnId = pLeFwdOpen->lLeTOConnId;
psConnRecord->sPublic.lLeConConnId = pLeFwdOpen->lLeOTConnId;
psConnRecord->sPublic.iOrigConnectionSn = UC_iLeTOi( pLeFwdOpen->iLeOrigConnectionSn );
psConnRecord->sPublic.iOrigVendorId = UC_iLeTOi( pLeFwdOpen->iLeOrigVendorId );
psConnRecord->sPublic.lOrigDeviceSn = UC_lLeTOl( pLeFwdOpen->lLeOrigDeviceSn );
psConnRecord->sPublic.bTimeoutMult = pLeFwdOpen->bTimeoutMult;
psConnRecord->sPublic.lProApi = UC_lLeTOl( pLeFwdOpen->lLeTORpi );
psConnRecord->sPublic.lConApi = UC_lLeTOl( pLeFwdOpen->lLeOTRpi );
#ifdef CD_EN_OBJECTS
/* Default the production inhibit to 1/4 the API */
psConnRecord->sPublic.lProInhib = psConnRecord->sPublic.lProApi >> 2;
#endif
psConnRecord->sPublic.iProConnParams = UC_iLeTOi( pLeFwdOpen->iLeTOConnParams );
psConnRecord->sPublic.iConConnParams = UC_iLeTOi( pLeFwdOpen->iLeOTConnParams );
psConnRecord->sPublic.iConAppSize = ( psConnRecord->sPublic.iConConnParams & CM_CP_SIZE_MASK ) - 2;
psConnRecord->sPublic.iProAppSize = ( psConnRecord->sPublic.iProConnParams & CM_CP_SIZE_MASK ) - 2;
psConnRecord->sPublic.bClassTrigger = pLeFwdOpen->bClassTrigger;
/* ! ConformanceTestProblem: if reserved bits are set: error */
if(
((pLeFwdOpen->iLeTOConnParams & 0x6000)==0x6000)
|| ((pLeFwdOpen->iLeOTConnParams & 0x6000)==0x6000)
){
iSize = iStartingSize = (UINT16)pLeFwdOpen->bConnPathSize;
psConnRecord->sPublic.bGRC = CI_GRC_FAILURE;
psConnRecord->sPublic.iERC = CM_ERC_BAD_CONN_TYPE;
goto BailOut;
}
/*
** Strip off the forward open from the combuf.
*/
CB_ShrinkComBuf( pComBuf, sizeof( CM_LeFwdOpenType ) );
/*
** Load in a sensible default for the transmission rate.
*/
psConnRecord->sPublic.bProRate = 1;
/*
** start edits: September,9th 2005, H.F.
**
** Assume, that it is not an Exclusive Owner Connection
*/
psConnRecord->sPublic.bExclusiveOwnerConn = FALSE;
/*
** end edits: September,9th 2005, H.F.
*/
/*
** Start parsing the connection path.
** Verify that the path fits in the remainder of the combuf without
** sloshing over the edges in either direction.
*/
pbPath = CB_GetDataPtrComBuf( pComBuf );
iSize = iStartingSize = (UINT16)pLeFwdOpen->bConnPathSize;
if( ( iSize * 2 ) > CB_GetDataSizeComBuf( pComBuf ) )
{
psConnRecord->sPublic.bGRC = CI_GRC_CONFIG_TOO_SMALL;
goto BailOut;
}
if( ( iSize * 2 ) < CB_GetDataSizeComBuf( pComBuf ) )
{
psConnRecord->sPublic.bGRC = CI_GRC_CONFIG_TOO_BIG;
goto BailOut;
}
/*
** We appear to have a sensible amount of data in the connection path.
** Parse until we run out of stuff in the connection path.
*/
/*
** start edits: October,6th 2005, H.F.
**
** assume, that a data segment does not exist
**
*/
psConnRecord->sPublic.bDataSegSize = 0;
/*
** end edits: October,6th 2005, H.F.
*/
fDone = FALSE;
while( ( iSize > 0 ) && ( fDone == FALSE ) )
{
switch( *pbPath & CI_SEGMENT_TYPE_MASK)
{
case CI_LOGICAL_SEGMENT:
switch( *pbPath )
{
case CI_LOGICAL_SEG_CLASS | CI_LOGICAL_SEG_8_BIT:
/*
** 8 bit class segment.
*/
psConnRecord->sPublic.iClass = *(pbPath + 1);
iSegSize = 1;
break;
case CI_LOGICAL_SEG_CLASS | CI_LOGICAL_SEG_16_BIT:
/*
** 16 bit class segment.
*/
psConnRecord->sPublic.iClass = UC_iLeTOi( *( (UINT16*)(pbPath + 2) ) );
iSegSize = 2;
break;
case CI_LOGICAL_SEG_CON_POINT | CI_LOGICAL_SEG_8_BIT:
/*
** Connection point segment.
** First connection point is for O-T (consumer),
** second is for T-O (producer).
*/
if( psConnRecord->sPublic.iConConnPoint == 0 )
{
psConnRecord->sPublic.iConConnPoint = *(pbPath + 1);
}
else
{
psConnRecord->sPublic.iProConnPoint = *(pbPath + 1);
}
iSegSize = 1;
break;
case CI_LOGICAL_SEG_KEY:
/*
** Electronic key segment.
** Parse out and convert the details.
*/
psLeKey = (void*)(pbPath + 2);
iSegSize = *(pbPath + 1) + 1;
psConnRecord->sPublic.sKey.iVendorId = UC_iLeTOi( psLeKey->iLeVendorId );
psConnRecord->sPublic.sKey.iProductType = UC_iLeTOi( psLeKey->iLeProductType );
psConnRecord->sPublic.sKey.iProductCode = UC_iLeTOi( psLeKey->iLeProductCode );
psConnRecord->sPublic.sKey.fUpdatesAllowed = psLeKey->bMajorRevision & CM_KEY_UPDATES_OK_MASK;
psConnRecord->sPublic.sKey.bMajorRevision = psLeKey->bMajorRevision & CM_KEY_MAJOR_REV_MASK;
psConnRecord->sPublic.sKey.bMinorRevision = psLeKey->bMinorRevision;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -