📄 jtransp.c
字号:
/******************************************************************************
*
* File Name: JTransp.c
*
* Description: Transport protocols for the J1939 protocol stack
*
*
* Comments: Includes BAM and CMDT
*
*
* Version Date Author Comments
* ------- ---------- -------------- ------------------------------
* 0.9 18.12.98 Ft Create
* 1.0 24.04.99 Ft C167CR and Tasking compiler
* 1.1 27.03.2001 Ma Bugfixing remainder problem at
* fragmented PG of the last fragment
* 1.2 31.05.2001 Ma merge Stack with CANopen driver
* 2.0 18.06.2001 Ma Version 2.0 new buffer concept and
* documented for doxygen
* 2.1 01.02.2002 Ma changed PDUS handling in CMDT send CTS
* 2.2 06.06.2003 Ma changed CMDT cnxn handling
* 2.3 15.07.2003 Ma added MAX_TP_DATA_LENGTH limitation check
* 2.4 24.06.2004 Ma changed handling of TP_CM state handling during
* data receiption in CMDT protocol
* 2.5 28.06.2004 Ma changed comments
*
* Copyright (c) 1998 - 2004 Vector Informatik GmbH
*****************************************************************************/
#include "Includes.h"
#include "Types.h"
#include "J1939.h"
#include "J1939CFG.h"
#include "J1939PGN.h"
#include "J1939TRA.h"
#include "J1939EXT.h"
/*!
\brief Fill the TX PG structure with corresponding values
*/
/*!
\param dest - the destination address of the PG
\param pduf - PDU Format field of the PG
\param pdus - PDU Specific field of the PG
*/
void FillTPCMAbort(unsigned char dest, unsigned char pduf, unsigned char pdus)
{
if (gTxPGTable[TX_PGN_TPCM].mPGState == PG_TX_FREE)
{
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mControl = TPCM_ABORT;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mBytesLsb = 0xFF;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mBytesMsb = 0xFF;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPackets = 0xFF;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mReserved = 0xFF;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGNlsb = pdus;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGN = pduf;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGNmsb = 0;
gTxPGTable[TX_PGN_TPCM].mSource = gDeviceAddress; /* source addr. */
gTxPGTable[TX_PGN_TPCM].mPDUS = dest; /* dest. addr. */
gTxPGTable[TX_PGN_TPCM].mPGState = PG_TX_REQ; /* ready to transmit */
}
}
/*!
\brief Handler of the RX transport protocol for CMDT PGs
The function handle the CMDT PGs within a fragmented PG.
*/
void HandleRxTransportCmdPG(void)
{
unsigned char pduf, pdus, i, j;
unsigned short tempBytes = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mBytesLsb + (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mBytesMsb << 8);
if ((((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_RTS)
&& (tempBytes <= MAX_TP_DATA_LENGTH)) /* RTS (open cnxn) */
{
/* Check if a transport channel is free */
for (j=0;j<NR_OF_TP_CH; j++)
{
if (gTPRxCnxn[j].mState == CMDT_STATE_CLOSE)
{
pduf = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN;
pdus = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb;
for (i=0; i<NR_OF_RX_PG; i++)
{
/* are we interested in this PGN */
if ((gRxPGTable[i].mPDUF==pduf) &&
(((gRxPGTable[i].mPDUF>239) && (gRxPGTable[i].mPDUS==pdus)) ||
((gRxPGTable[i].mPDUF<240) && (gRxPGTable[RX_PGN_TPCM].mPDUS == gDeviceAddress))))
{
/* initialize transport structure */
/* gTPRxCnxn[j].mState = CMDT_RX_STATE_OPEN;*/
gTPRxCnxn[j].mSource = gRxPGTable[RX_PGN_TPCM].mSource;
gTPRxCnxn[j].mBytes = tempBytes;
gTPRxCnxn[j].mPackets = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPackets;
gTPRxCnxn[j].mSequence = 1;
gTPRxCnxn[j].mRxPGTable = i;
/* Prepare CTS to signal the producer to send data */
if (gTxPGTable[TX_PGN_TPCM].mPGState == PG_TX_FREE)
{
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mControl = TPCM_CTS;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mBytesMsb = 1; /* start with first packet */
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mBytesLsb = 1; /* packets to send*/
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPackets = 0xFF; /* reserved */
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mReserved = 0xFF;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGNlsb = pdus;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGN = pduf;
((struct VJ1939PGN_DATA_EC00*)gTxPGTable[TX_PGN_TPCM].mData)->mPGNmsb = 0;
gTxPGTable[TX_PGN_TPCM].mSource = gDeviceAddress; /* source addr. */
gTxPGTable[TX_PGN_TPCM].mPDUS = gTPRxCnxn[j].mSource; /* dest. addr. */
gTxPGTable[TX_PGN_TPCM].mPGState = PG_TX_REQ; /* ready to transmit */
gTPRxCnxn[j].mTimer = Tim_GetCurrentTime();
gTPRxCnxn[j].mState = CMDT_RX_STATE_DATA;
}
#if 0
else
{
/* Should not occure, do not establish connection. */
/* Send Abort is not possible, too. The send object */
/* is used by another connection */
}
#endif
break;
}
}
break;
}
}
}
else if (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_CTS) /* CTS */
{
if (gTPTxCnxn.mState == CMDT_TX_STATE_OPEN)
{
gTPTxCnxn.mSequence = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mBytesMsb;
gTPTxCnxn.mPToSend = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mBytesLsb;
if (gTPTxCnxn.mPToSend>0) /* no packets to send */
{
gTPTxCnxn.mState = CMDT_TX_STATE_DATA;
}
else
{
gTPTxCnxn.mTimer = Tim_GetCurrentTime();
}
}
} /* elif CTS */
else if (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_EndOfMsgAck) /* EndOfMsgAck */
{
if (gTPTxCnxn.mState == CMDT_TX_STATE_OPEN)
{
gTPTxCnxn.mState = CMDT_STATE_CLOSE;
gTxPGTable[gTPTxCnxn.mRxPGTable].mPGState = PG_TX_FREE; /* Free buffer */
/* inform application */
}
} /* elif EndOfMsgAck */
else if (((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_ABORT) /* Abort */
{
/* Search connection for this abort message */
if ((gTPTxCnxn.mState == CMDT_STATE_CLOSE) &&
(((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb == gTxPGTable[gTPTxCnxn.mRxPGTable].mPDUS) &&
(((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN == gTxPGTable[gTPTxCnxn.mRxPGTable].mPDUF))
{
gTxPGTable[gTPTxCnxn.mRxPGTable].mPGState = PG_TX_FREE; /* free buffer */
gTPTxCnxn.mState = CMDT_STATE_CLOSE; /* close cnxn */
}
else
{
for (j=0;j<NR_OF_TP_CH; j++)
{
if ((gTPRxCnxn[j].mState == CMDT_STATE_CLOSE) &&
(((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb == gRxPGTable[gTPRxCnxn[j].mRxPGTable].mPDUS) &&
(((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN == gRxPGTable[gTPRxCnxn[j].mRxPGTable].mPDUF))
{
gRxPGTable[gTPRxCnxn[j].mRxPGTable].mPGState = PG_RX_FREE; /* free buffer */
gTPRxCnxn[j].mState = CMDT_STATE_CLOSE; /* close cnxn */
break;
}
}
}
} /* elif Abort */
else if ((((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mControl == TPCM_BAM)
&& (tempBytes <= MAX_TP_DATA_LENGTH)) /* BAM */
{
/* Check if BAM channel is free */
for (j=0;j<NR_OF_TP_CH; j++)
{
if (gTPRxCnxn[j].mState == BAM_STATE_CLOSE
&& (gAddressClaimed || (!gAddressClaimed && ((((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN == 0xFE)
&&(((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb == 0xD8)))))
{
pduf = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGN;
pdus = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPGNlsb;
for (i=0;i<NR_OF_RX_PG;i++)
{
/* are we interested in this PGN */
if ((gRxPGTable[i].mPDUF==pduf) &&
(((gRxPGTable[i].mPDUF>239) && (gRxPGTable[i].mPDUS==pdus)) ||
(gRxPGTable[i].mPDUF<240)))
{
/* initialize transport structure */
gTPRxCnxn[j].mState = BAM_RX_STATE_DATA;
gTPRxCnxn[j].mSource = gRxPGTable[RX_PGN_TPCM].mSource;
gTPRxCnxn[j].mBytes = tempBytes;
gTPRxCnxn[j].mPackets = ((struct VJ1939PGN_DATA_EC00*)gRxPGTable[RX_PGN_TPCM].mData)->mPackets;
gTPRxCnxn[j].mSequence = 1;
gTPRxCnxn[j].mRxPGTable = i;
/* start timer for timeout */
gTPRxCnxn[j].mTimer = Tim_GetCurrentTime(); /* set timer to 250ms timeout */
break;
}
}
break;
}
}
} /* elif BAM */
}
/*!
\brief Handler of the RX transport protocol for Data PGs
The function handle the Data PGs within a fragmented PG.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -