]> rtime.felk.cvut.cz Git - arc.git/blob - communication/J1939Tp/J1939Tp.c
53bd18da9f0a08608f26552217099417c3375658
[arc.git] / communication / J1939Tp / J1939Tp.c
1 /** @req J1939TP0003 **/\r
2 #include "J1939Tp.h"\r
3 /** @req J1939TP0172 */\r
4 #include "CanIf.h"\r
5 /** @req J1939TP0013 */\r
6 #include "J1939Tp_Cbk.h"\r
7 #include "J1939Tp_Internal.h"\r
8 #include "PduR.h"\r
9 /** @req J1939TP0015 */\r
10 #include "PduR_J1939Tp.h"\r
11 #include <string.h>\r
12 /** @req J1939TP0193 */\r
13 #if (defined(USE_DET))\r
14 #include "Det.h"\r
15 #endif
16 \r
17 /* Globally fulfilled requirements */\r
18 /** @req J1939TP0123 */\r
19 /** @req J1939TP0165 */\r
20 /** @req J1939TP0097 */\r
21 /** @req J1939TP0019 */\r
22 /** @req J1939TP0184 */\r
23 /** @req J1939TP0007 */\r
24 /** @req J1939TP0152 */\r
25 /** @req J1939TP0018 */\r
26 /** @req J1939TP0036 */\r
27 /** @req J1939TP0155 */\r
28 /** @req J1939TP0152 */\r
29 /** @req J1939TP0125 */\r
30 /** @req J1939TP0174 */\r
31 /** @req J1939TP0041 */\r
32 /** @req J1939TP0189 */\r
33 /** @req J1939TP0192 */\r
34 /** @req J1939TP0156 */\r
35 \r
36 /** @req J1939TP0020 */\r
37 static J1939Tp_Internal_GlobalStateInfoType globalState = {\r
38                 .State = J1939TP_OFF,\r
39 };\r
40 static const J1939Tp_ConfigType* J1939Tp_ConfigPtr;\r
41 static J1939Tp_Internal_ChannelInfoType channelInfos[J1939TP_CHANNEL_COUNT];\r
42 static J1939Tp_Internal_TxChannelInfoType txChannelInfos[J1939TP_TX_CHANNEL_COUNT];\r
43 static J1939Tp_Internal_RxChannelInfoType rxChannelInfos[J1939TP_RX_CHANNEL_COUNT];\r
44 static J1939Tp_Internal_PgInfoType pgInfos[J1939TP_PG_COUNT];\r
45 \r
46 /** @req J1939TP0087 */\r
47 void J1939Tp_Init(const J1939Tp_ConfigType* ConfigPtr) {\r
48         #if (J1939TP_DEV_ERROR_DETECT == STD_ON)\r
49         if (globalState.State == J1939TP_ON) {\r
50                 /** @req J1939TP0026 */\r
51                 J1939Tp_Internal_ReportError(J1939TP_INIT_ID, J1939TP_E_REINIT);\r
52         }\r
53         #endif\r
54         int rxCount = 0;\r
55         int txCount = 0;\r
56         for (int i = 0; i < J1939TP_CHANNEL_COUNT; i++) {\r
57                 if (ConfigPtr->Channels[i].Direction == J1939TP_TX) {\r
58                         channelInfos[i].ChannelConfPtr = &(ConfigPtr->Channels[i]);\r
59                         channelInfos[i].TxState = &(txChannelInfos[txCount]);\r
60                         channelInfos[i].TxState->State = J1939TP_TX_IDLE;\r
61                         channelInfos[i].RxState = 0;\r
62                         txCount++;\r
63                 } else if (ConfigPtr->Channels[i].Direction == J1939TP_RX) {\r
64                         channelInfos[i].ChannelConfPtr = &(ConfigPtr->Channels[i]);\r
65                         channelInfos[i].TxState = 0;\r
66                         channelInfos[i].RxState = &(rxChannelInfos[rxCount]);\r
67                         channelInfos[i].RxState->State = J1939TP_RX_IDLE;\r
68                         rxCount++;\r
69                 } else {\r
70                         return; // unexpected\r
71                 }\r
72         }\r
73         for (int i = 0; i < J1939TP_PG_COUNT; i++) {\r
74                 pgInfos[i].PgConfPtr = &(ConfigPtr->Pgs[i]);\r
75                 uint8 channelIndex = ConfigPtr->Pgs[i].Channel - ConfigPtr->Channels;\r
76                 pgInfos[i].ChannelInfoPtr = &(channelInfos[channelIndex]);\r
77 \r
78         }\r
79         J1939Tp_ConfigPtr = ConfigPtr;\r
80         globalState.State = J1939TP_ON; /** @req J1939TP0022 */\r
81 }\r
82 \r
83 void J1939Tp_RxIndication(PduIdType RxPduId, PduInfoType* PduInfoPtr) {\r
84         /** @req J1939TP0030 */\r
85         if (globalState.State == J1939TP_OFF) {\r
86                 return;\r
87         }\r
88         const J1939Tp_RxPduInfoType* RxPduInfo = 0;\r
89         if (J1939Tp_Internal_GetRxPduInfo(RxPduId, &RxPduInfo) != E_OK) {\r
90                 return;\r
91         }\r
92         /*if (J1939Tp_Internal_ValidatePacketType(RxPduInfo) == E_NOT_OK) {\r
93                 return;\r
94         }*/\r
95         J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr = J1939Tp_Internal_GetChannelState(RxPduInfo);\r
96         switch (RxPduInfo->PacketType ) {\r
97                 case J1939TP_REVERSE_CM:\r
98                         J1939Tp_Internal_RxIndication_ReverseCm(PduInfoPtr,ChannelInfoPtr);\r
99                         break;\r
100                 case J1939TP_DT:\r
101                         J1939Tp_Internal_RxIndication_Dt(PduInfoPtr,ChannelInfoPtr);\r
102                         break;\r
103                 case J1939TP_CM:\r
104                         J1939Tp_Internal_RxIndication_Cm(PduInfoPtr,ChannelInfoPtr);\r
105                         break;\r
106                 case J1939TP_DIRECT:\r
107                         J1939Tp_Internal_RxIndication_Direct(PduInfoPtr,ChannelInfoPtr);\r
108                         break;\r
109                 default:\r
110                         return;\r
111         }\r
112 }\r
113 \r
114 \r
115 void J1939Tp_MainFunction(void) {\r
116         /** @req J1939TP0030 */\r
117         if (globalState.State == J1939TP_OFF) {\r
118                 return;\r
119         }\r
120         for (int i = 0; i < J1939TP_CHANNEL_COUNT; i++) {\r
121                 J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr = &(channelInfos[i]);\r
122                 const J1939Tp_ChannelType* Channel = ChannelInfoPtr->ChannelConfPtr;\r
123                 J1939Tp_Internal_TimerStatusType timer = J1939TP_NOT_EXPIRED;\r
124                 switch (Channel->Direction) {\r
125                         case J1939TP_TX:\r
126                                 switch (ChannelInfoPtr->TxState->State) {\r
127                                         case J1939TP_TX_WAIT_DIRECT_SEND_CANIF_CONFIRM:\r
128                                         case J1939TP_TX_WAITING_FOR_CTS:\r
129                                         case J1939TP_TX_WAITING_FOR_END_OF_MSG_ACK:\r
130                                         case J1939TP_TX_WAIT_DT_CANIF_CONFIRM:\r
131                                         case J1939TP_TX_WAIT_RTS_CANIF_CONFIRM:\r
132                                                 timer = J1939Tp_Internal_IncAndCheckTimer(&(ChannelInfoPtr->TxState->TimerInfo));\r
133                                                 if (timer == J1939TP_EXPIRED) {\r
134                                                         timer = J1939TP_NOT_EXPIRED;\r
135                                                         ChannelInfoPtr->TxState->State = J1939TP_TX_IDLE;\r
136                                                         if (ChannelInfoPtr->TxState->CurrentPgPtr != 0) {\r
137                                                                 J1939Tp_Internal_SendConnectionAbort(Channel->CmNPdu,ChannelInfoPtr->TxState->CurrentPgPtr->Pgn);\r
138                                                                 PduR_J1939TpTxConfirmation(ChannelInfoPtr->TxState->CurrentPgPtr->NSdu,NTFRSLT_E_NOT_OK);\r
139                                                         }\r
140                                                 }\r
141                                                 break;\r
142                                         case J1939TP_TX_WAITING_FOR_T1_TIMEOUT:\r
143                                                 timer = J1939Tp_Internal_IncAndCheckTimer(&(ChannelInfoPtr->TxState->TimerInfo));\r
144                                                 if (timer == J1939TP_EXPIRED) {\r
145                                                         timer = J1939TP_NOT_EXPIRED;\r
146                                                         ChannelInfoPtr->TxState->State = J1939TP_TX_WAIT_DT_BAM_CANIF_CONFIRM;\r
147                                                         J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_TX_CONF_TIMEOUT);\r
148                                                         J1939Tp_Internal_SendDt(ChannelInfoPtr);\r
149 \r
150                                                 }\r
151                                                 break;\r
152                                         default:\r
153                                         break;\r
154                                 }\r
155 \r
156                                 break;;\r
157                         case J1939TP_RX:\r
158                                 switch (ChannelInfoPtr->RxState->State) {\r
159                                         case J1939TP_RX_WAIT_CTS_CANIF_CONFIRM:\r
160                                         case J1939TP_RX_RECEIVING_DT:\r
161                                         case J1939TP_RX_WAIT_ENDOFMSGACK_CANIF_CONFIRM:\r
162                                                 timer = J1939Tp_Internal_IncAndCheckTimer(&(ChannelInfoPtr->RxState->TimerInfo));\r
163                                         default:\r
164                                                 break;\r
165                                 }\r
166                                 if (timer == J1939TP_EXPIRED) {\r
167                                         timer = J1939TP_NOT_EXPIRED;\r
168                                         ChannelInfoPtr->RxState->State = J1939TP_RX_IDLE;\r
169                                         if (Channel->Protocol == J1939TP_PROTOCOL_CMDT) {\r
170                                                 J1939Tp_Internal_SendConnectionAbort(Channel->FcNPdu,ChannelInfoPtr->RxState->CurrentPgPtr->Pgn);\r
171                                                 PduR_J1939TpRxIndication(ChannelInfoPtr->RxState->CurrentPgPtr->NSdu,NTFRSLT_E_NOT_OK);\r
172                                         }\r
173                                 }\r
174                         default:\r
175                                 break;\r
176                 }\r
177         }\r
178 }\r
179 void J1939Tp_TxConfirmation(PduIdType RxPdu) {\r
180         /** @req J1939TP0030 */\r
181         if (globalState.State == J1939TP_OFF) {\r
182                 return;\r
183         }\r
184         const J1939Tp_RxPduInfoType* RxPduInfo = 0;\r
185         if (J1939Tp_Internal_GetRxPduInfo(RxPdu, &RxPduInfo) != E_OK) {\r
186                 return;\r
187         }\r
188 \r
189         const J1939Tp_ChannelType* Channel = J1939Tp_Internal_GetChannel(RxPduInfo);\r
190         J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr = J1939Tp_Internal_GetChannelState(RxPduInfo);\r
191         switch (Channel->Direction) {\r
192                 case J1939TP_TX:\r
193                         J1939Tp_Internal_TxConfirmation_TxChannel(ChannelInfoPtr, RxPduInfo);\r
194                         break;\r
195                 case J1939TP_RX:\r
196                         J1939Tp_Internal_TxConfirmation_RxChannel(ChannelInfoPtr, RxPduInfo);\r
197                         break;\r
198                 default:\r
199                         break;\r
200         }\r
201 \r
202 }\r
203 static inline const J1939Tp_ChannelType* J1939Tp_Internal_GetChannel(const J1939Tp_RxPduInfoType* RxPduInfo) {\r
204         return &(J1939Tp_ConfigPtr->Channels[RxPduInfo->ChannelIndex]);\r
205 }\r
206 static inline J1939Tp_Internal_ChannelInfoType* J1939Tp_Internal_GetChannelState(const J1939Tp_RxPduInfoType* RxPduInfo) {\r
207         return &(channelInfos[RxPduInfo->ChannelIndex]);\r
208 }\r
209 static inline Std_ReturnType J1939Tp_Internal_ValidatePacketType(const J1939Tp_RxPduInfoType* RxPduInfo) {\r
210         const J1939Tp_ChannelType* ChannelPtr = J1939Tp_Internal_GetChannel(RxPduInfo);\r
211         switch (RxPduInfo->PacketType) {\r
212                 case J1939TP_REVERSE_CM:\r
213                         if (ChannelPtr->Direction != J1939TP_TX ) {\r
214                                 return E_NOT_OK;\r
215                         }\r
216                         break;\r
217                 case J1939TP_DT:\r
218                         if (ChannelPtr->Direction != J1939TP_RX) {\r
219                                 return E_NOT_OK;\r
220                         }\r
221                         break;\r
222                 case J1939TP_CM:\r
223                         if (ChannelPtr->Direction != J1939TP_RX) {\r
224                                 return E_NOT_OK;\r
225                         }\r
226                         break;\r
227                 default:\r
228                         return E_NOT_OK;\r
229         }\r
230         return E_OK;\r
231 }\r
232 static inline void J1939Tp_Internal_RxIndication_Direct(PduInfoType* PduInfoPtr, J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr) {\r
233         if (PduInfoPtr->SduLength != DIRECT_TRANSMIT_SIZE) {\r
234                 return;\r
235         }\r
236         const J1939Tp_PgType* Pg = ChannelInfoPtr->RxState->CurrentPgPtr;\r
237         PduInfoType* rxPduInfo;\r
238         BufReq_ReturnType r = PduR_J1939TpProvideRxBuffer(Pg->NSdu, DIRECT_TRANSMIT_SIZE, &rxPduInfo);\r
239         if (r == BUFREQ_OK) {\r
240                 memcpy(rxPduInfo->SduDataPtr,&(PduInfoPtr),DIRECT_TRANSMIT_SIZE);\r
241                 PduR_J1939TpRxIndication(Pg->NSdu,NTFRSLT_OK);\r
242                 ChannelInfoPtr->RxState->State = J1939TP_RX_IDLE;\r
243         }\r
244 }\r
245 static inline uint8 J1939Tp_Internal_GetDtPacketsInNextCts(uint8 receivedDtPackets, uint8 totalDtPacketsToReceive) {\r
246         uint8 packetsLeft = totalDtPacketsToReceive - receivedDtPackets;\r
247         if (packetsLeft < (J1939TP_PACKETS_PER_BLOCK)) {\r
248                 return packetsLeft;\r
249         } else {\r
250                 return J1939TP_PACKETS_PER_BLOCK;\r
251         }\r
252 }\r
253 static inline void J1939Tp_Internal_RxIndication_Dt(PduInfoType* PduInfoPtr, J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr) {\r
254         PduInfoType* rxPduInfo;\r
255         if (ChannelInfoPtr->RxState->CurrentPgPtr == 0) {\r
256                 return;\r
257         }\r
258         if (ChannelInfoPtr->RxState->State != J1939TP_RX_RECEIVING_DT) {\r
259                 return;\r
260         }\r
261         PduIdType PduRSdu = ChannelInfoPtr->RxState->CurrentPgPtr->NSdu;\r
262         uint8 requestSize = DT_DATA_SIZE;\r
263         boolean lastMessage = false;\r
264 \r
265         ChannelInfoPtr->RxState->ReceivedDtCount++;\r
266         uint8 expectedSeqNumber = ChannelInfoPtr->RxState->ReceivedDtCount;\r
267         uint8 seqNumber = PduInfoPtr->SduDataPtr[DT_BYTE_SEQ_NUM];\r
268         if (seqNumber != expectedSeqNumber) {\r
269                 ChannelInfoPtr->RxState->State = J1939TP_RX_IDLE;\r
270                 if (ChannelInfoPtr->ChannelConfPtr->Protocol == J1939TP_PROTOCOL_CMDT) {\r
271                         J1939Tp_PgnType pgn = ChannelInfoPtr->RxState->CurrentPgPtr->Pgn;\r
272                         J1939Tp_Internal_SendConnectionAbort(ChannelInfoPtr->ChannelConfPtr->FcNPdu,pgn);\r
273                 }\r
274                 return;\r
275         }\r
276         BufReq_ReturnType r = PduR_J1939TpProvideRxBuffer(PduRSdu, requestSize, &rxPduInfo);\r
277         if (r == BUFREQ_OK) {\r
278                 memcpy(rxPduInfo->SduDataPtr,&(PduInfoPtr[DT_BYTE_DATA_1]),requestSize);\r
279         }\r
280         if (J1939Tp_Internal_IsLastDtBeforeNextCts(ChannelInfoPtr->RxState)) {\r
281                 J1939Tp_PgnType pgn = ChannelInfoPtr->RxState->CurrentPgPtr->Pgn;\r
282                 uint8 requestPackets = J1939Tp_Internal_GetDtPacketsInNextCts(ChannelInfoPtr->RxState->ReceivedDtCount,ChannelInfoPtr->RxState->DtToReceiveCount);\r
283                 ChannelInfoPtr->RxState->State = J1939TP_RX_WAIT_CTS_CANIF_CONFIRM;\r
284                 J1939Tp_Internal_SendCts(ChannelInfoPtr, pgn, ChannelInfoPtr->RxState->ReceivedDtCount+1,requestPackets);\r
285         }\r
286         else if (J1939Tp_Internal_IsLastDt(ChannelInfoPtr->RxState)) {\r
287                 lastMessage = true;\r
288                 J1939Tp_Internal_DtPayloadSizeType receivedBytes = ChannelInfoPtr->RxState->ReceivedDtCount*DT_DATA_SIZE;\r
289                 requestSize = ChannelInfoPtr->RxState->TotalMessageSize - receivedBytes;\r
290                 J1939Tp_Internal_SendEndOfMsgAck(ChannelInfoPtr);\r
291                 ChannelInfoPtr->RxState->State = J1939TP_RX_IDLE;\r
292                 PduR_J1939TpRxIndication(PduRSdu,NTFRSLT_OK);\r
293         } else {\r
294                 J1939Tp_Internal_RxSessionStartTimer(ChannelInfoPtr->RxState,J1939TP_T1_TIMEOUT_MS);\r
295         }\r
296 }\r
297 \r
298 static inline void J1939Tp_Internal_RxIndication_Cm(PduInfoType* PduInfoPtr, J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr) {\r
299         const J1939Tp_PgType* pg = 0;\r
300         J1939Tp_PgnType pgn = J1939Tp_Internal_GetPgn(&(PduInfoPtr->SduDataPtr[CM_PGN_BYTE_1]));\r
301         uint8 pf = J1939Tp_Internal_GetPf(pgn);\r
302         J1939Tp_ProtocolType protocol = J1939Tp_Internal_GetProtocol(pf);\r
303         if (J1939Tp_Internal_GetPgFromPgn(ChannelInfoPtr->ChannelConfPtr,pgn,&pg) != E_OK) {\r
304                 return;\r
305         }\r
306         /** @req J1939TP0173 **/\r
307         if (protocol == J1939TP_PROTOCOL_BAM && pg->Channel->Protocol != protocol) {\r
308                 return;\r
309         }\r
310         if (protocol == J1939TP_PROTOCOL_CMDT && pg->Channel->Protocol != protocol) {\r
311                 J1939Tp_Internal_SendConnectionAbort(pg->Channel->CmNPdu,pgn);\r
312         }\r
313         uint8 Command = PduInfoPtr->SduDataPtr[CM_BYTE_CONTROL];\r
314 \r
315         /** @req J1939TP0043**/\r
316         J1939Tp_Internal_DtPayloadSizeType messageSize = 0;\r
317         messageSize = J1939Tp_Internal_GetRtsMessageSize(PduInfoPtr);\r
318 \r
319         if (Command == RTS_CONTROL_VALUE || Command == BAM_CONTROL_VALUE) {\r
320                 ChannelInfoPtr->RxState->ReceivedDtCount = 0;\r
321                 ChannelInfoPtr->RxState->DtToReceiveCount = PduInfoPtr->SduDataPtr[BAM_RTS_BYTE_NUM_PACKETS];\r
322                 ChannelInfoPtr->RxState->TotalMessageSize = messageSize;\r
323                 ChannelInfoPtr->RxState->CurrentPgPtr = pg;\r
324                 if (Command == RTS_CONTROL_VALUE) {\r
325                         ChannelInfoPtr->RxState->State = J1939TP_RX_WAIT_CTS_CANIF_CONFIRM;\r
326                         J1939Tp_Internal_RxSessionStartTimer(ChannelInfoPtr->RxState,J1939TP_TX_CONF_TIMEOUT);\r
327                         J1939Tp_Internal_SendCts(ChannelInfoPtr,pgn,CTS_START_SEQ_NUM,J1939TP_PACKETS_PER_BLOCK);\r
328 \r
329                 } else if (Command == BAM_CONTROL_VALUE) {\r
330                         J1939Tp_Internal_RxSessionStartTimer(ChannelInfoPtr->RxState,J1939TP_T2_TIMEOUT_MS);\r
331                         ChannelInfoPtr->RxState->State = J1939TP_RX_RECEIVING_DT;\r
332                 }\r
333         } else if (Command == CONNABORT_BYTE_CONTROL) {\r
334                 ChannelInfoPtr->RxState->State = J1939TP_RX_IDLE;\r
335         }\r
336 \r
337 }\r
338 static inline void J1939Tp_Internal_RxIndication_ReverseCm(PduInfoType* PduInfoPtr, J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr) {\r
339         const J1939Tp_PgType* pg = 0;\r
340         J1939Tp_PgnType pgn = J1939Tp_Internal_GetPgn(&(PduInfoPtr->SduDataPtr[CM_PGN_BYTE_1]));\r
341         if (J1939Tp_Internal_GetPgFromPgn(ChannelInfoPtr->ChannelConfPtr,pgn,&pg) != E_OK) {\r
342                 return;\r
343         }\r
344         uint8 Command = PduInfoPtr->SduDataPtr[CM_BYTE_CONTROL];\r
345         switch (Command) {\r
346                 case CTS_CONTROL_VALUE:\r
347                         if (ChannelInfoPtr->TxState->State == J1939TP_TX_WAITING_FOR_CTS) {\r
348                                 uint8 NumPacketsToSend = PduInfoPtr->SduDataPtr[CTS_BYTE_NUM_PACKETS];\r
349                                 uint8 NextPacket = PduInfoPtr->SduDataPtr[CTS_BYTE_NEXT_PACKET];\r
350                                 if (NumPacketsToSend == 0) {\r
351                                         // Receiver wants to keep the connection open but cant receive packets\r
352                                         /** @req J1939TP0195 */\r
353                                         J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_T4_TIMEOUT_MS);\r
354                                 } else if(J1939Tp_Internal_IsDtPacketAlreadySent(NextPacket,ChannelInfoPtr->TxState->SentDtCount)) {\r
355                                         PduR_J1939TpTxConfirmation(pg->NSdu,NTFRSLT_E_NOT_OK);\r
356                                         /** @req J1939TP0190 */\r
357                                         J1939Tp_Internal_SendConnectionAbort(ChannelInfoPtr->ChannelConfPtr->CmNPdu,pgn);\r
358                                         ChannelInfoPtr->TxState->State = J1939TP_TX_IDLE;\r
359                                 } else {\r
360                                         ChannelInfoPtr->TxState->DtToSendBeforeCtsCount = NumPacketsToSend;\r
361                                         ChannelInfoPtr->TxState->State = J1939TP_TX_WAIT_DT_CANIF_CONFIRM;\r
362                                         J1939Tp_Internal_SendDt(ChannelInfoPtr);\r
363                                         J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_TX_CONF_TIMEOUT);\r
364                                 }\r
365                         }\r
366                         break;\r
367                 case ENDOFMSGACK_CONTROL_VALUE:\r
368                         if (ChannelInfoPtr->TxState->State == J1939TP_TX_WAITING_FOR_END_OF_MSG_ACK) {\r
369                                 PduR_J1939TpTxConfirmation(pg->NSdu,NTFRSLT_OK);\r
370                                 ChannelInfoPtr->TxState->State = J1939TP_TX_IDLE;\r
371                         }\r
372                         break;\r
373                 case CONNABORT_CONTROL_VALUE:\r
374                         PduR_J1939TpTxConfirmation(pg->NSdu,NTFRSLT_E_NOT_OK);\r
375                         ChannelInfoPtr->TxState->State = J1939TP_TX_IDLE;\r
376                         break;\r
377                 default:\r
378                         break;\r
379         }\r
380 }\r
381 \r
382 /** @req J1939TP0180 */\r
383 Std_ReturnType J1939Tp_ChangeParameterRequest(PduIdType SduId, TPParameterType Parameter, uint16 value) {\r
384         return E_NOT_OK; /** @req J1939TP0181 */\r
385 }\r
386 static inline void J1939Tp_Internal_TxConfirmation_RxChannel(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr, const J1939Tp_RxPduInfoType* RxPduInfo) {\r
387         switch (RxPduInfo->PacketType ) {\r
388                 case J1939TP_REVERSE_CM:\r
389                         if (ChannelInfoPtr->RxState->State == J1939TP_RX_WAIT_CTS_CANIF_CONFIRM) {\r
390                                 J1939Tp_Internal_RxSessionStartTimer(ChannelInfoPtr->RxState,J1939TP_T2_TIMEOUT_MS);\r
391                                 ChannelInfoPtr->RxState->State = J1939TP_RX_RECEIVING_DT;\r
392                         }\r
393                         break;\r
394                 default:\r
395                         break;\r
396         }\r
397 }\r
398 static inline boolean J1939Tp_Internal_IsDtPacketAlreadySent(uint8 nextPacket, uint8 totalPacketsSent) {\r
399         return nextPacket < totalPacketsSent;\r
400 }\r
401 static inline Std_ReturnType J1939Tp_Internal_GetRxPduInfo(PduIdType RxPdu,const const J1939Tp_RxPduInfoType** RxPduInfo) {\r
402         if (RxPdu < J1939TP_RX_PDU_COUNT) {\r
403                 *RxPduInfo = &(J1939Tp_ConfigPtr->RxPdus[RxPdu]);\r
404                 return E_OK;\r
405         } else {\r
406                 return E_NOT_OK;\r
407         }\r
408 \r
409 }\r
410 static inline Std_ReturnType J1939Tp_Internal_GetPgFromPgn(const J1939Tp_ChannelType* channel, J1939Tp_Internal_PgnType Pgn, const J1939Tp_PgType** Pg) {\r
411         for (int i = 0; i < channel->PgCount; i++) {\r
412                 if (channel->Pgs[i]->Pgn == Pgn) {\r
413                         *Pg = channel->Pgs[i];\r
414                         return E_OK;\r
415                 }\r
416         }\r
417         return E_NOT_OK;\r
418 }\r
419 \r
420 \r
421 static inline boolean J1939Tp_Internal_IsLastDtBeforeNextCts(J1939Tp_Internal_RxChannelInfoType* rxChannelInfo) {\r
422         boolean finalDt = rxChannelInfo->ReceivedDtCount == rxChannelInfo->DtToReceiveCount;\r
423         boolean sendNewCts = rxChannelInfo->ReceivedDtCount % J1939TP_PACKETS_PER_BLOCK == 0;\r
424         return !finalDt && sendNewCts;\r
425 \r
426 \r
427 }\r
428 static inline boolean J1939Tp_Internal_IsLastDt(J1939Tp_Internal_RxChannelInfoType* rxChannelInfo) {\r
429         return (rxChannelInfo->DtToReceiveCount == rxChannelInfo->ReceivedDtCount);\r
430 }\r
431 static inline void J1939Tp_Internal_TxConfirmation_TxChannel(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr, const J1939Tp_RxPduInfoType* RxPduInfo) {\r
432         J1939Tp_Internal_TxChannelStateType State = ChannelInfoPtr->TxState->State;\r
433         switch (RxPduInfo->PacketType ) {\r
434                 case J1939TP_REVERSE_CM:\r
435                         break;\r
436                 case J1939TP_CM:\r
437                         if (State == J1939TP_TX_WAIT_RTS_CANIF_CONFIRM) {\r
438                                 ChannelInfoPtr->TxState->State = J1939TP_TX_WAITING_FOR_CTS;\r
439                                 J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_T3_TIMEOUT_MS);\r
440                         } else if (State == J1939TP_TX_WAIT_BAM_CANIF_CONFIRM) {\r
441                                 ChannelInfoPtr->TxState->State = J1939TP_TX_WAITING_FOR_T1_TIMEOUT;\r
442                                 J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_T1_TIMEOUT_MS);\r
443                         }\r
444                         break;\r
445                 case J1939TP_DT:\r
446                         if (State == J1939TP_TX_WAIT_DT_CANIF_CONFIRM) {\r
447                                 ChannelInfoPtr->TxState->SentDtCount++;\r
448                                 if (J1939Tp_Internal_LastDtSent(ChannelInfoPtr->TxState)) {\r
449                                         J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_T3_TIMEOUT_MS);\r
450                                         ChannelInfoPtr->TxState->State = J1939TP_TX_WAITING_FOR_END_OF_MSG_ACK;\r
451                                 } else if (J1939Tp_Internal_WaitForCts(ChannelInfoPtr->TxState)) {\r
452                                         J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_T3_TIMEOUT_MS);\r
453                                         ChannelInfoPtr->TxState->State = J1939TP_TX_WAITING_FOR_CTS;\r
454                                 } else {\r
455                                         J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_TX_CONF_TIMEOUT);\r
456                                         J1939Tp_Internal_SendDt(ChannelInfoPtr);\r
457                                 }\r
458                         }\r
459                         else if (State == J1939TP_TX_WAIT_DT_BAM_CANIF_CONFIRM) {\r
460                                 ChannelInfoPtr->TxState->SentDtCount++;\r
461                                 if (J1939Tp_Internal_LastDtSent(ChannelInfoPtr->TxState)) {\r
462                                         ChannelInfoPtr->TxState->State = J1939TP_TX_IDLE;\r
463                                         PduR_J1939TpTxConfirmation(ChannelInfoPtr->TxState->CurrentPgPtr->NSdu,NTFRSLT_OK);\r
464                                 } else {\r
465                                         ChannelInfoPtr->TxState->State = J1939TP_TX_WAITING_FOR_T1_TIMEOUT;\r
466                                         J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_T1_TIMEOUT_MS);\r
467                                 }\r
468                         }\r
469                         break;\r
470                 case J1939TP_DIRECT:\r
471                         if (State == J1939TP_TX_WAIT_DIRECT_SEND_CANIF_CONFIRM) {\r
472                                 ChannelInfoPtr->TxState->State = J1939TP_TX_IDLE;\r
473                                 PduR_J1939TpTxConfirmation(ChannelInfoPtr->TxState->CurrentPgPtr->NSdu, NTFRSLT_OK);\r
474                         }\r
475                         break;\r
476                 default:\r
477                         break;\r
478         }\r
479 }\r
480 static inline Std_ReturnType J1939Tp_Internal_GetPg(PduIdType TxSduId,J1939Tp_Internal_PgInfoType** PgInfo) {\r
481         if (TxSduId < J1939TP_PG_COUNT) {\r
482                 *PgInfo = &(pgInfos[TxSduId]);\r
483                 return E_OK;\r
484         }\r
485         return E_NOT_OK;\r
486 }\r
487 Std_ReturnType J1939Tp_CancelTransmitRequest(PduIdType TxSduId) {\r
488         /** @req J1939TP0179 **/\r
489         J1939Tp_Internal_PgInfoType* PgInfo;\r
490         if (J1939Tp_Internal_GetPg(TxSduId,&PgInfo) == E_NOT_OK) {\r
491                 return E_NOT_OK;\r
492         }\r
493         PduR_J1939TpTxConfirmation(PgInfo->PgConfPtr->NSdu,NTFRSLT_E_CANCELATION_NOT_OK);\r
494         return E_OK;\r
495 }\r
496 Std_ReturnType J1939Tp_CancelReceiveRequest(PduIdType RxSduId) {\r
497         /** @req J1939TP0178 **/\r
498         J1939Tp_Internal_PgInfoType* PgInfo;\r
499         if (J1939Tp_Internal_GetPg(RxSduId,&PgInfo) == E_NOT_OK) {\r
500                 return E_NOT_OK;\r
501         }\r
502         PduR_J1939TpTxConfirmation(PgInfo->PgConfPtr->NSdu,NTFRSLT_E_CANCELATION_NOT_OK);\r
503         return E_OK;\r
504 }\r
505 /** @req J1939TP0096 */\r
506 Std_ReturnType J1939Tp_Transmit(PduIdType TxSduId, const PduInfoType* TxInfoPtr) {\r
507         #if J1939TP_DEV_ERROR_DETECT\r
508         if (globalState.State == J1939TP_OFF) {\r
509                 J1939Tp_Internal_ReportError(J1939TP_TRANSMIT_ID,J1939TP_E_UNINIT);\r
510         }\r
511         #endif\r
512         /** @req J1939TP0030 */\r
513         if (globalState.State == J1939TP_OFF) {\r
514                 return E_NOT_OK;\r
515         }\r
516         J1939Tp_Internal_PgInfoType* PgInfo;\r
517 \r
518         if (J1939Tp_Internal_GetPg(TxSduId,&PgInfo) == E_NOT_OK) {\r
519                 return E_NOT_OK;\r
520         }\r
521         const J1939Tp_PgType* Pg = PgInfo->PgConfPtr;\r
522         J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr = PgInfo->ChannelInfoPtr;\r
523         /** @req J1939TP0101 **/\r
524         if (ChannelInfoPtr->TxState->State != J1939TP_TX_IDLE) {\r
525                 return E_NOT_OK;\r
526         }\r
527         if (TxInfoPtr->SduLength <= 8) { // direct transmit\r
528                 PduInfoType* ToSendTxInfoPtr;\r
529                 PduR_J1939TpProvideTxBuffer(Pg->NSdu, &ToSendTxInfoPtr, TxInfoPtr->SduLength);\r
530                 PduIdType CanIfPdu = Pg->DirectNPdu;\r
531                 ChannelInfoPtr->TxState->State = J1939TP_TX_WAIT_DIRECT_SEND_CANIF_CONFIRM;\r
532                 ChannelInfoPtr->TxState->CurrentPgPtr = Pg;\r
533                 CanIf_Transmit(CanIfPdu,ToSendTxInfoPtr);\r
534         } else {\r
535                 uint8 pf = J1939Tp_Internal_GetPf(Pg->Pgn);\r
536                 J1939Tp_ProtocolType protocol = J1939Tp_Internal_GetProtocol(pf);\r
537                 switch (protocol) { /** @req J1939TP0039*/\r
538                         case J1939TP_PROTOCOL_BAM:\r
539                                 ChannelInfoPtr->TxState->State = J1939TP_TX_WAIT_BAM_CANIF_CONFIRM;\r
540                                 ChannelInfoPtr->TxState->TotalMessageSize = TxInfoPtr->SduLength;\r
541                                 ChannelInfoPtr->TxState->CurrentPgPtr = Pg;\r
542                                 ChannelInfoPtr->TxState->SentDtCount = 0;\r
543                                 J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_TX_CONF_TIMEOUT);\r
544                                 J1939Tp_Internal_SendBam(ChannelInfoPtr,TxInfoPtr);\r
545                                 break;\r
546                         case J1939TP_PROTOCOL_CMDT:\r
547                                 ChannelInfoPtr->TxState->State = J1939TP_TX_WAIT_RTS_CANIF_CONFIRM;\r
548                                 ChannelInfoPtr->TxState->TotalMessageSize = TxInfoPtr->SduLength;\r
549                                 ChannelInfoPtr->TxState->PduRPdu = TxSduId;\r
550                                 ChannelInfoPtr->TxState->CurrentPgPtr = Pg;\r
551                                 ChannelInfoPtr->TxState->SentDtCount = 0;\r
552                                 J1939Tp_Internal_SendRts(ChannelInfoPtr,TxInfoPtr);\r
553                                 J1939Tp_Internal_TxSessionStartTimer(ChannelInfoPtr->TxState,J1939TP_TX_CONF_TIMEOUT);\r
554                                 break;\r
555                 }\r
556         }\r
557         return E_OK;\r
558 }\r
559 static inline void J1939Tp_Internal_SendBam(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr,const PduInfoType* TxInfoPtr) {\r
560         uint8 cmBamData[BAM_RTS_SIZE];\r
561         cmBamData[BAM_RTS_BYTE_CONTROL] = BAM_CONTROL_VALUE;\r
562         cmBamData[BAM_RTS_BYTE_LENGTH_1] = (uint8)(TxInfoPtr->SduLength & 0x00FF);\r
563         cmBamData[BAM_RTS_BYTE_LENGTH_2] = (uint8)(TxInfoPtr->SduLength & 0xFF00);\r
564 \r
565         J1939Tp_PgnType pgn = ChannelInfoPtr->TxState->CurrentPgPtr->Pgn;\r
566         cmBamData[BAM_RTS_BYTE_NUM_PACKETS] = J1939TP_Internal_GetNumDtPacketsToSend(TxInfoPtr->SduLength);\r
567         cmBamData[BAM_RTS_BYTE_SAE_ASSIGN] = 0xFF;\r
568         J1939Tp_Internal_SetPgn(&(cmBamData[BAM_RTS_BYTE_PGN_1]),pgn);\r
569 \r
570         PduInfoType cmBamPdu;\r
571         cmBamPdu.SduLength = BAM_RTS_SIZE;\r
572         cmBamPdu.SduDataPtr = cmBamData;\r
573 \r
574         CanIf_Transmit(ChannelInfoPtr->ChannelConfPtr->CmNPdu,&cmBamPdu);\r
575 }\r
576 static inline uint16 J1939Tp_Internal_GetRtsMessageSize(PduInfoType* pduInfo) {\r
577         return (((uint16)pduInfo->SduDataPtr[BAM_RTS_BYTE_LENGTH_1]) << 8) | pduInfo->SduDataPtr[BAM_RTS_BYTE_LENGTH_2];\r
578 }\r
579 \r
580 static inline boolean J1939Tp_Internal_WaitForCts(J1939Tp_Internal_TxChannelInfoType* TxChannelState) {\r
581         return TxChannelState->SentDtCount == TxChannelState->DtToSendBeforeCtsCount;\r
582 }\r
583 \r
584 static inline uint8 J1939TP_Internal_GetNumDtPacketsToSend(uint16 messageSize) {\r
585         uint8 packetsToSend = 0;\r
586         packetsToSend = messageSize/DT_DATA_SIZE;\r
587         if (messageSize % DT_DATA_SIZE != 0) {\r
588                 packetsToSend = packetsToSend + 1;\r
589         }\r
590         return packetsToSend;\r
591 }\r
592 static inline boolean J1939Tp_Internal_LastDtSent(J1939Tp_Internal_TxChannelInfoType* TxChannelState) {\r
593         return J1939TP_Internal_GetNumDtPacketsToSend(TxChannelState->TotalMessageSize) == TxChannelState->SentDtCount;\r
594 }\r
595 \r
596 static inline Std_ReturnType J1939Tp_Internal_ConfGetPg(PduIdType NSduId, const J1939Tp_PgType* Pg) {\r
597         if (NSduId < J1939TP_PG_COUNT) {\r
598                 Pg = &(J1939Tp_ConfigPtr->Pgs[NSduId]);\r
599                 return E_OK;\r
600         } else {\r
601                 return E_NOT_OK;\r
602         }\r
603 }\r
604 \r
605 static inline J1939Tp_Internal_TimerStatusType J1939Tp_Internal_IncAndCheckTimer(J1939Tp_Internal_TimerType* TimerInfo) {\r
606         TimerInfo->Timer += J1939TP_MAIN_FUNCTION_PERIOD;\r
607         if (TimerInfo->Timer >= TimerInfo->TimerExpire) {\r
608                 return J1939TP_EXPIRED;\r
609         }\r
610         return J1939TP_NOT_EXPIRED;\r
611 }\r
612 static inline uint8 J1939Tp_Internal_GetPf(J1939Tp_PgnType pgn) {\r
613         return  (uint8)(pgn >> 8);\r
614 }\r
615 static J1939Tp_ProtocolType J1939Tp_Internal_GetProtocol(uint8 pf) {\r
616         if (pf < 240) {\r
617                 return J1939TP_PROTOCOL_CMDT;\r
618         } else {\r
619                 return J1939TP_PROTOCOL_BAM;\r
620         }\r
621 }\r
622 \r
623 \r
624 static inline void J1939Tp_Internal_SendDt(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr) {\r
625         uint8 requestLength = DT_DATA_SIZE;\r
626         uint8 bytesLeftToSend = ChannelInfoPtr->TxState->TotalMessageSize - ChannelInfoPtr->TxState->SentDtCount * DT_DATA_SIZE;\r
627         if (bytesLeftToSend < DT_DATA_SIZE){\r
628                 requestLength = bytesLeftToSend;\r
629         }\r
630         // prepare dt message\r
631         uint8 dtBuffer[DT_SIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};\r
632         PduInfoType dtPduInfoBuffer;\r
633         dtPduInfoBuffer.SduLength = DT_SIZE;\r
634         dtPduInfoBuffer.SduDataPtr = dtBuffer;\r
635 \r
636         BufReq_ReturnType allocateBufferRes;\r
637         PduInfoType* dataPduInfoBuffer;\r
638         PduIdType Pdur_NSdu = ChannelInfoPtr->TxState->CurrentPgPtr->NSdu;\r
639         allocateBufferRes = PduR_J1939TpProvideTxBuffer(Pdur_NSdu, &dataPduInfoBuffer, requestLength);\r
640         if (allocateBufferRes == BUFREQ_OK) {\r
641                 dtPduInfoBuffer.SduDataPtr[DT_BYTE_SEQ_NUM] = ChannelInfoPtr->TxState->SentDtCount+1;\r
642                 memcpy(&(dtPduInfoBuffer.SduDataPtr[DT_BYTE_DATA_1]), dataPduInfoBuffer, requestLength);\r
643                 PduIdType CanIf_NSdu = ChannelInfoPtr->ChannelConfPtr->DtNPdu;\r
644                 CanIf_Transmit(CanIf_NSdu, &dtPduInfoBuffer);\r
645 \r
646         } else {\r
647                 /* Todo: check for error */\r
648         }\r
649 \r
650 }\r
651 \r
652 static inline void J1939Tp_Internal_SendRts(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr, const PduInfoType* TxInfoPtr) {\r
653         uint8 cmRtsData[BAM_RTS_SIZE];\r
654         cmRtsData[BAM_RTS_BYTE_CONTROL] = 16;\r
655         cmRtsData[BAM_RTS_BYTE_LENGTH_1] = (uint8)(TxInfoPtr->SduLength >> 8);\r
656         cmRtsData[BAM_RTS_BYTE_LENGTH_2] = (uint8)(TxInfoPtr->SduLength);\r
657 \r
658         J1939Tp_PgnType pgn = ChannelInfoPtr->TxState->CurrentPgPtr->Pgn;\r
659         cmRtsData[BAM_RTS_BYTE_NUM_PACKETS] = J1939TP_Internal_GetNumDtPacketsToSend(TxInfoPtr->SduLength);\r
660         cmRtsData[BAM_RTS_BYTE_SAE_ASSIGN] = 0xFF;\r
661         J1939Tp_Internal_SetPgn(&(cmRtsData[BAM_RTS_BYTE_PGN_1]),pgn);\r
662 \r
663         PduInfoType cmRtsPdu;\r
664         cmRtsPdu.SduLength = BAM_RTS_SIZE;\r
665         cmRtsPdu.SduDataPtr = cmRtsData;\r
666 \r
667         CanIf_Transmit(ChannelInfoPtr->ChannelConfPtr->CmNPdu,&cmRtsPdu);\r
668 }\r
669 \r
670 static inline void J1939Tp_Internal_SendEndOfMsgAck(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr) {\r
671         PduInfoType endofmsgInfo;\r
672         uint8 endofmsgData[ENDOFMSGACK_SIZE];\r
673         endofmsgInfo.SduLength = ENDOFMSGACK_SIZE;\r
674         endofmsgInfo.SduDataPtr = endofmsgData;\r
675         endofmsgData[ENDOFMSGACK_BYTE_CONTROL] = ENDOFMSGACK_CONTROL_VALUE;\r
676         endofmsgData[ENDOFMSGACK_BYTE_TOTAL_MSG_SIZE_1] = ((uint8)(ChannelInfoPtr->RxState->TotalMessageSize)) << 8;\r
677         endofmsgData[ENDOFMSGACK_BYTE_TOTAL_MSG_SIZE_2] = ((uint8)(ChannelInfoPtr->RxState->TotalMessageSize));\r
678         endofmsgData[ENDOFMSGACK_BYTE_NUM_PACKETS] = ChannelInfoPtr->RxState->ReceivedDtCount;\r
679         endofmsgData[ENDOFMSGACK_BYTE_SAE_ASSIGN] = 0xFF;\r
680         J1939Tp_Internal_SetPgn(&(endofmsgData[ENDOFMSGACK_BYTE_PGN_1]),ChannelInfoPtr->RxState->CurrentPgPtr->Pgn);\r
681         PduIdType CmNPdu = ChannelInfoPtr->ChannelConfPtr->FcNPdu;\r
682 \r
683         CanIf_Transmit(CmNPdu,&endofmsgInfo);\r
684 }\r
685 \r
686 /**\r
687  * Send a response to the incoming RTS\r
688  * @param NSduId\r
689  * @param RtsPduInfoPtr needs to be a valid RTS message\r
690  */\r
691 static inline void J1939Tp_Internal_SendCts(J1939Tp_Internal_ChannelInfoType* ChannelInfoPtr, J1939Tp_PgnType Pgn, uint8 NextPacketSeqNum,uint8 NumPackets) {\r
692         PduInfoType ctsInfo;\r
693         uint8 ctsData[CTS_SIZE];\r
694         ctsInfo.SduLength = CTS_SIZE;\r
695         ctsInfo.SduDataPtr = ctsData;\r
696         ctsData[CTS_BYTE_CONTROL] = CTS_CONTROL_VALUE;\r
697         ctsData[CTS_BYTE_NUM_PACKETS] = NumPackets;\r
698         ctsData[CTS_BYTE_NEXT_PACKET] = NextPacketSeqNum;\r
699         ctsData[CTS_BYTE_SAE_ASSIGN_1] = 0xFF;\r
700         ctsData[CTS_BYTE_SAE_ASSIGN_2] = 0xFF;\r
701         J1939Tp_Internal_SetPgn(&(ctsData[BAM_RTS_BYTE_PGN_1]),Pgn);\r
702 \r
703         CanIf_Transmit(ChannelInfoPtr->ChannelConfPtr->FcNPdu,&ctsInfo);\r
704 \r
705 }\r
706 static inline void J1939Tp_Internal_SendConnectionAbort(PduIdType CmNPdu, J1939Tp_PgnType Pgn) {\r
707         PduInfoType connAbortInfo;\r
708         uint8 connAbortData[CONNABORT_SIZE];\r
709         connAbortInfo.SduLength = CONNABORT_SIZE;\r
710         connAbortInfo.SduDataPtr = connAbortData;\r
711         connAbortData[CONNABORT_BYTE_CONTROL] = CTS_CONTROL_VALUE;\r
712         connAbortData[CONNABORT_BYTE_SAE_ASSIGN_1] = 0xFF;\r
713         connAbortData[CONNABORT_BYTE_SAE_ASSIGN_2] = 0xFF;\r
714         connAbortData[CONNABORT_BYTE_SAE_ASSIGN_3] = 0xFF;\r
715         connAbortData[CONNABORT_BYTE_SAE_ASSIGN_4] = 0xFF;\r
716         J1939Tp_Internal_SetPgn(&(connAbortData[CONNABORT_BYTE_PGN_1]),Pgn);\r
717         CanIf_Transmit(CmNPdu,&connAbortInfo);\r
718 }\r
719 static inline void J1939Tp_Internal_TxSessionStartTimer(J1939Tp_Internal_TxChannelInfoType* Tx,uint16 TimerExpire) {\r
720         Tx->TimerInfo.Timer = 0;\r
721         Tx->TimerInfo.TimerExpire = TimerExpire;\r
722 }\r
723 static inline void J1939Tp_Internal_RxSessionStartTimer(J1939Tp_Internal_RxChannelInfoType* Rx,uint16 TimerExpire) {\r
724         Rx->TimerInfo.Timer = 0;\r
725         Rx->TimerInfo.TimerExpire = TimerExpire;\r
726 }\r
727 /**\r
728  * set three bytes to a 18 bit pgn value
729  * @param PgnBytes must be three uint8 bytes
730  * @param pgn
731  */\r
732 static inline void J1939Tp_Internal_SetPgn(uint8* PgnBytes,J1939Tp_PgnType pgn ) {\r
733         PgnBytes[2] = pgn; /* get first byte */\r
734         PgnBytes[1] = pgn >> 8; /* get next byte */\r
735         PgnBytes[0] = (pgn >> 16) & 0x3; /* get next two bits */\r
736 }\r
737 /**\r
738  * return a 18 bit pgn value from three bytes
739  * @param PgnBytes must be three uint8 bytes
740  * @return
741  */\r
742 static inline J1939Tp_PgnType J1939Tp_Internal_GetPgn(uint8* PgnBytes) {\r
743         J1939Tp_PgnType pgn = 0;\r
744         pgn = ((uint32)PgnBytes[0]) << 16;\r
745         pgn = pgn | (((uint32)PgnBytes[1]) << 8);\r
746         pgn = pgn | ((uint32)PgnBytes[2]);\r
747         return pgn;\r
748 }\r
749 \r
750 static inline void J1939Tp_Internal_ReportError(uint8 ApiId, uint8 ErrorId) {\r
751 #if (CANSM_DEV_ERROR_DETECT == STD_ON)\r
752         Det_ReportError(MODULE_ID_J1939TP, 0, ApiId, ApiId);\r
753 #endif\r
754 }\r