📄 en_cd.c
字号:
}
pBuffer = pTr->pBufA;
/*
** Point over the sequence count, The application will write to the data,
** then when it does a putbuffer we will increment the sequence count
*/
return( pBuffer + 2 );
}
return NULL;
} /* End of EN_CD_GetTransportBuffer() */
/*---------------------------------------------------------------------------
** EN_CD_ReleaseTransportBuffer()
**
** Releases the semaphore associated with the transport buffer
**---------------------------------------------------------------------------
*/
void EN_CD_ReleaseTransportBuffer( UINT16 iTransport )
{
cd_TransportRecordType *pTr;
if ( ( pTr = cd_LookupTransportRecord( CD_ETHERNET_PORT, iTransport ) ) != NULL )
{
GS_SetSemaphore( pTr->xSBufAccess );
}
}
/*---------------------------------------------------------------------------
** EN_CD_PutTransportBuffer()
**---------------------------------------------------------------------------
*/
void EN_CD_PutTransportBuffer( UINT16 iTransport )
{
cd_TransportRecordType *pTr;
UINT32 iPrevBufState;
if ( ( pTr = cd_LookupTransportRecord( CD_ETHERNET_PORT, iTransport ) ) != NULL )
{
iPrevBufState = pTr->iBufState;
/*
** As currently written, it is the responsibility of the bridged
** device to put in the transport sequence count. This is because
** at the device level we have no knowledge of changed data or not
*/
if( !pTr->fBridged )
{
/* Sneak in the sequence count for the tpu */
*((UINT16 *) pTr->pBufA) = ENCAP_VALUE_SHORT(pTr->iLeSeqCount);
pTr->iLeSeqCount += 1;
}
/*
** Make sure the frequency is lower than that specified by the production
** inhibit time. For cyclic connections let the API determine when new
** data is transmitted.
*/
if ( ((( pTr->bClassTrigger & CM_TCT_TRIGGER_MASK ) == CM_TCT_TRIGGER_CYCLIC ) ||
((IS_GT( pTr->lProInhib, ( gs_sTimers.sSysTime.iMSecTime - pTr->iMsecLastSent ))))) &&
(iPrevBufState == A_CURRENT_B_FREE))
{
GS_SetSemaphore( pTr->xSBufAccess );
return;
}
/*
** We sent a message based on a change of state. Retrigger the
** timer to handle the next API.
*/
/*
** start edits: October,10th 2005, H.F.
**
** write to Log-File, if bad API Timer
*/
if( !(pTr->xAPITimer) )
{
GS_LogEvent( CD_BAD_API_TIMER, 0, 0, FATAL );
}
/*
** end edits: October,10th 2005, H.F.
*/
GS_RetriggerTimer( pTr->xAPITimer );
en_cd_Class1TxPacket( pTr->pBufA, pTr);
/*
** start edits: October,13th 2005, H.F.:
**
** update data after transmission
** (NOTE: An ad_ResyncCommAndAppBufs() call before executing
** en_cd_Class1TxPacket() does not work!)
*/
GS_PutMsgQueueBits( AD_xQid, AD_BIT_MSG_SENT_PRO );
/*
** end edits: October,13th 2005, H.F.
*/
/*
** jjw 02/07/01 Update the buffer state after the class 1 send. Class 1
** send will use this as a flag to determine it is the first data being sent on
** a new connection and copy the data regardless of serial number
*/
pTr->iBufState = A_CURRENT_B_FREE;
} /* end - if */
} /* End of EN_CD_PutTransportBuffer() */
/****************************************************************************
**
** Private Services
**
*****************************************************************************
*/
/*---------------------------------------------------------------------------
** en_cd_FreeIpMcastAddress()
**---------------------------------------------------------------------------
*/
void en_cd_FreeIpMcastAddress( CM_ConnectionRecordType *psConnRecord )
{
UINT16 iClass;
iClass = psConnRecord->bClassTrigger & CM_TCT_CLASS_MASK;
if ( ( iClass == CM_TCT_CLASS_1 ) &&
( psConnRecord->sEce.psMcast ) )
{
if( ( psConnRecord->iProConnParams & CM_CP_TYPE_MASK ) == CM_CP_TYPE_MULTICAST )
{
FREE_MCAST_ADDRESS( psConnRecord->sEce.psMcast );
}
else
{
/*
** Consumer must be mcast, which is allocated with a simple GS_Malloc()
*/
GS_Free( psConnRecord->sEce.psMcast );
}
}
} /* End of en_cd_FreeIpMcastAddress() */
/*---------------------------------------------------------------------------
** en_cd_TxFixedTagPacket()
**---------------------------------------------------------------------------
*/
void en_cd_TxFixedTagPacket(CD_PacketTrrblType * pTrrbl)
{
UINT16 iSize;
PKTBUF *msg;
EnCdMessageType EnCdMessage; /* Message to be sent out via tcpip */
UINT32 Status;
/*
** We only accept packets with an open socket. If the application wants to
** send packets to its own node, let it open a socket to it
*/
if (pTrrbl->bRequest != 0)
{
/*
** This request originated from a client on another machine. Lookup the correct
** information so we can send the buffer out. Collect the header information for
** the packet from the tribble. This gets loaded into the buffer ahead of the packet.
**
** Recover the pointer to the original message and insure non-zero!
*/
msg = pTrrbl->xCdHandle;
if (msg == NULL)
{
GS_LogEvent( EN_NO_RESP_TRRBL,
0,
0,
FATAL );
return;
}
}
else
{
/*
** Message is originating on this board. Allocate message dynamically
*/
msg = PktBufAlloc();
if (msg == NULL)
{
/*
** We haven't enough memory to get this message. Don't
** fatal because we may recover.
*/
GS_LogEvent( EN_RESOURCE,
0,
0,
WARNING );
return;
} /* End if message == NULL */
/*
** Transfer host name in case we need to connect. Send this message on to the management task.
** Depending on whether this host has a session set up or not, we may need to do a lot of pre-processing.
*/
EnCdMessage.pcbDestHost = pTrrbl->pCbDestHost;
msg->sOutputQ = MngOutgoingEncapQueue;
msg->sEncap.sHdr.iEncaph_command = ENCAP_CMD_SEND_RRDATA;
msg->sEncap.sHdr.lEncaph_session = 0;
msg->sEncap.sHdr.lEncaph_status = 0;
msg->sEncap.sHdr.lEncaph_opt = 0;
msg->sEncap.sDt_hdr.lDt_target = 0;
msg->sEncap.sDt_hdr.iDt_timeout = 0;
msg->sEncap.sAdr_tag.sTag.iTag_length = 0;
msg->sEncap.sAdr_tag.sTag.iTag_type = 0;
msg->sEncap.sObj_list.iO_count = 2; /* Address and unconnected message only */
msg->sEncap.sPkt_tag.sTag.iTag_type = CPF_TAG_PKT_UCMM;
msg->sEncap.lValid = PKTBUF_ENCAPV_DT | /* Data transfer field is valid */
PKTBUF_ENCAPV_OBJ | /* Object list field is valid */
PKTBUF_ENCAPV_ADR | /* CPF Address tag is valid */
PKTBUF_ENCAPV_PKT; /* CPF packet tag is valid */
/*
** Decided not to save the Cd Packet tribble handle in the context. This would have
** required us to save the tribble, and then create some way of recovering the tribbles
** should the return message not be sent. Instead we will only save the xUmHandle in the
** context and let the UCMM worry about how to handle unreturned responses
*/
msg->sEncap.sHdr.alEncaph_context[ 1 ] = (UINT32) pTrrbl->xUmHandle;
/*
** Encode our IP address into the 0 context field. This will help
** determine that the incoming message is a reply to us and not an
** illegal request from an originator coming in on the wrong socket.
*/
msg->sEncap.sHdr.alEncaph_context[ 0 ] = list_target_data.sS.s_sock.lSin_addr;
msg->pData = &msg->abData[0]; /* used by en_cd_SetSocketAddresses() */
msg->lLength = 0; /* used by en_cd_SetSocketAddresses() */
} /* End message originating on this board */
/*
** setup the SockAddr Info Data types in the packet addenda if needed
*/
en_cd_SetSocketAddresses( msg, &msg->sEce.sSa );
/*
** msg should still have the original command, and options (both in host order) in it.
** Context is also preserved, though the order was never changed
*/
iSize = CB_GetDataSizeComBuf(pTrrbl->pComBuf);
msg->sEncap.sPkt_tag.sTag.iTag_length = iSize;
msg->lLength = iSize;
/*
** Instead of copying the data to a new buffer, just attach the combuff and send it to the
** transmission task
*/
msg->pData = pTrrbl->pComBuf->pData; /* point the datapointer to the combuffer */
msg->pCb = pTrrbl->pComBuf;
EnCdMessage.Command = SENDCOMMBUF; /* Send the attached message using a combuf */
EnCdMessage.PacketBuf = msg; /* Tcpip message to be sent. It will be deleted by the send task */
/*
** Send to queue the message at the send task, or the management task depending on connection state
*/
Status = OE_MsgQSend(msg->sOutputQ,
(char *) &EnCdMessage.Command,
sizeof EnCdMessage,
WAIT_FOREVER,
MSG_PRI_NORMAL);
/*
** Send failed, we need to delete the packet here lest we loose it
*/
if (Status == OE_ERROR)
{
CB_DeleteComBuf( msg->pCb );
PktBufFree(msg);
}
} /* end of en_cd_TxFixedTagPacket() */
/*---------------------------------------------------------------------------
** en_cd_LoadUnschedTxPacket()
**---------------------------------------------------------------------------
*/
void en_cd_LoadUnschedTxPacket( CD_PacketTrrblType *pTrrbl, UINT8 *pabHeader, cd_TransportRecordType *pTranRec,
UINT16 iHeaderSize, UINT16 iTotalSize, BOOL fConfig )
{
UINT16 iSize;
PKTBUF *msg;
EnCdMessageType EnCdMessage;
UINT32 Status;
/*
** Allocate message dynamically. If wee haven't enough memory to get this message.
** Don'tfatal because we may recover.
*/
msg = PktBufAlloc();
if (msg == NULL)
{
GS_LogEvent( EN_RESOURCE,
0,
0,
WARNING );
return;
}
msg->sEncap.sHdr.iEncaph_command = ENCAP_CMD_SEND_UNITDATA; /* We are not yet connected */
msg->sEncap.sHdr.lEncaph_status = 0;
msg->sEncap.sHdr.lEncaph_opt = 0;
msg->sEncap.sDt_hdr.lDt_target = 0;
msg->sEncap.sDt_hdr.iDt_timeout = 0;
msg->sEncap.sAdr_tag.sTag.iTag_type = CPF_TAG_ADR_CONNECTED;
msg->sEncap.sObj_list.iO_count = 2;
msg->sEncap.sPkt_tag.sTag.iTag_type = CPF_TAG_PKT_CONNECTED; /* unconnected message */
msg->sEncap.lValid = PKTBUF_ENCAPV_DT | /* Data transfer field is valid */
PKTBUF_ENCAPV_OBJ | /* Object list field is valid */
PKTBUF_ENCAPV_ADR | /* CPF Address tag is valid */
PKTBUF_ENCAPV_PKT; /* CPF packet tag is valid */
/*
** We are in a bit of a bind here. In the original control net the sequence number was not part of the
** message. In TCPIP it is. If we simply prepend the sequence number on we will get into
** trouble with re-transmits. A re-transmit reuses the original combuf. IF we modify it here, then
** get it back as a re-transmit we will unknowingly modify it again with the sequence number resulting in
** a corrupt message. The only thing we can do is rebuild the message in the buffer space
** provided in msg->data and include the sequence count.
*/
UC_CopyMem( msg->abData, &pabHeader[ 7 ], 2 ); /* First put the sequence count in */
iSize = CB_GetDataSizeComBuf( pTrrbl->pComBuf );
UC_CopyMem( &msg->abData[ 2 ], pTrrbl->pComBuf->pData, iSize ); /* Now copy the body of the message */
msg->sEncap.sAdr_tag.sTag.iTag_length = sizeof msg->sEncap.sAdr_tag.data.sC.lCid;
msg->sEncap.sPkt_tag.sTag.iTag_length = iSize + 2; /* Don't forget the 2 byte sequence we added */
msg->lLength = iSize + 2;
msg->sEncap.sAdr_tag.data.sC.lCid = UC_lTOlLe(*(UINT32 *) &pabHeader[ 3 ]);
msg->pData = msg->abData; /* point the datapointer to the combuffer */
/*
** Send this message on to the xmit task. The session is already open so we can send it immediately
*/
msg->sOutputQ = pTranRec->sEce.sOutputQ;
EnCdMessage.Command = SENDINCORPMESSAGE; /* Send the attached data in the msg packet */
/*
** Tcpip message to be sent. It will be deleted by the send task
** Send to queue the message at the send task, or the management task depending on connection state
*/
EnCdMessage.PacketBuf = msg;
Status = OE_MsgQSend(msg->sOutputQ,
(char *) &EnCdMessage.Command,
sizeof EnCdMessage,
WAIT_FOREVER,
MSG_PRI_NORMAL);
/*
** Send failed, we need to delete the packet here lest we loose it
*/
if (Status == OE_ERROR)
{
PktBufFree(msg);
}
}
#endif /* #ifdef CD_EN_OBJECTS */
/****************************************************************************
**
** End of EN_CD.C
**
*****************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -