]> rtime.felk.cvut.cz Git - arc.git/blob - communication/Com/Com_misc.c
COM protection
[arc.git] / communication / Com / Com_misc.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 //lint -esym(960,8.7)   PC-Lint misunderstanding of Misra 8.7 for Com_SystenEndianness and endianess_test\r
18 \r
19 #include <string.h>\r
20 #include <assert.h>\r
21 \r
22 #include "Com_Arc_Types.h"\r
23 #include "Com.h"\r
24 #include "Com_Internal.h"\r
25 #include "Com_misc.h"\r
26 #include "debug.h"\r
27 #include "Cpu.h"\r
28 \r
29 static void Com_ReadDataSegment(uint8 *dest, const uint8 *source, uint8 destByteLength,\r
30                 Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength, boolean signedOutput);\r
31 \r
32 static void Com_WriteDataSegment(uint8 *pdu, uint8 *pduSignalMask, const uint8 *signalDataPtr, uint8 destByteLength,\r
33                 Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength);\r
34 \r
35 void Com_ReadSignalDataFromPdu(\r
36                         const Com_SignalIdType signalId,\r
37                         void *signalData) {\r
38 \r
39         // Get PDU\r
40         const ComSignal_type * Signal = GET_Signal(signalId);\r
41         uint8 pduSize = GET_IPdu(Signal->ComIPduHandleId)->ComIPduSize;\r
42         // Get data\r
43         Com_ReadSignalDataFromPduBuffer(\r
44                         signalId,\r
45                         FALSE,\r
46                         signalData,\r
47                         GET_IPdu(Signal->ComIPduHandleId)->ComIPduDataPtr,\r
48                         pduSize);\r
49 }\r
50 \r
51 void Com_ReadGroupSignalDataFromPdu(\r
52                 const Com_SignalIdType parentSignalId,\r
53                 const Com_SignalIdType groupSignalId,\r
54                 void *signalData) {\r
55 \r
56         // Get PDU\r
57         const ComSignal_type * Signal = GET_Signal(parentSignalId);\r
58         uint8 pduSize = GET_IPdu(Signal->ComIPduHandleId)->ComIPduSize;\r
59         // Get data\r
60         Com_ReadSignalDataFromPduBuffer(\r
61                         groupSignalId,\r
62                         TRUE,\r
63                         signalData,\r
64                         GET_IPdu(Signal->ComIPduHandleId)->ComIPduDataPtr,\r
65                         pduSize);\r
66 }\r
67 \r
68 void Com_ReadSignalDataFromPduBuffer(\r
69                 const uint16 signalId,\r
70                 const boolean isGroupSignal,\r
71                 void *signalData,\r
72                 const void *pduBuffer,\r
73                 uint8 pduSize) {\r
74 \r
75         Com_SignalType signalType;\r
76         ComSignalEndianess_type signalEndianess;\r
77         uint8 signalLength;\r
78         Com_BitPositionType bitPosition;\r
79         uint8 bitSize;\r
80 \r
81         if (!isGroupSignal) {\r
82                 const ComSignal_type * Signal =  GET_Signal(signalId);\r
83                 signalType = Signal->ComSignalType;\r
84                 signalEndianess = Signal->ComSignalEndianess;\r
85                 signalLength = Signal->ComBitSize / 8;\r
86                 bitPosition = Signal->ComBitPosition;\r
87                 bitSize = Signal->ComBitSize;\r
88         } else {\r
89                 const ComGroupSignal_type *GroupSignal = GET_GroupSignal(signalId);\r
90                 signalType = GroupSignal->ComSignalType;\r
91                 signalEndianess = GroupSignal->ComSignalEndianess;\r
92                 signalLength = GroupSignal->ComBitSize / 8;\r
93                 bitPosition = GroupSignal->ComBitPosition;\r
94                 bitSize = GroupSignal->ComBitSize;\r
95         }\r
96 \r
97         uint8 destSize = SignalTypeToSize(signalType, signalLength);\r
98 \r
99         // Pointer to a byte of the source and dest respectively.\r
100         uint8 *signalDataBytes = (uint8 *)signalData;\r
101         uint8 signalDataBytesArray[8];\r
102         const uint8 *pduBufferBytes = (const uint8 *)pduBuffer + (bitPosition/8);\r
103         Com_BitPositionType startBitOffset = 0;\r
104         imask_t state;\r
105         Irq_Save(state);\r
106 \r
107         if (signalEndianess == COM_OPAQUE || signalType == UINT8_N) {\r
108                 // Aligned opaque data -> straight copy\r
109                 memcpy(signalDataBytes, pduBufferBytes, destSize);\r
110 \r
111         } else {\r
112                 // Unaligned data and/or endianness conversion\r
113 \r
114                 if (signalEndianess == COM_LITTLE_ENDIAN) {\r
115                         // Swap source bytes before reading\r
116                         // TODO: Must adapt to larger PDUs!\r
117                         uint8 pduBufferBytes_swap[8];\r
118                         for (uint8 i = 0; i < 8; ++i) {\r
119                                 pduBufferBytes_swap[i] = pduBufferBytes[7 - i];\r
120                         }\r
121                         startBitOffset = intelBitNrToPduOffset(bitPosition%8, bitSize, 64);\r
122                         //lint -save -esym(960,12.5) PC-Lint Exception: OK. PC-Lint Wrong interpretation of MISRA rule 12.5.\r
123                         Com_ReadDataSegment(\r
124                                         signalDataBytesArray, pduBufferBytes_swap, destSize,\r
125                                         startBitOffset, bitSize,\r
126                                         SignalTypeSignedness(signalType));\r
127                         //lint -restore\r
128                 } else {\r
129                         startBitOffset = motorolaBitNrToPduOffset(bitPosition%8);\r
130                         Com_ReadDataSegment(\r
131                                         signalDataBytesArray, pduBufferBytes, destSize,\r
132                                         startBitOffset, bitSize,\r
133                                         SignalTypeSignedness(signalType));\r
134                 }\r
135 \r
136                 if (Com_SystemEndianness == COM_BIG_ENDIAN) {\r
137                         // Straight copy\r
138                         uint8 i;\r
139                         for (i = 0; i < destSize; i++) {\r
140                                 signalDataBytes[i] = signalDataBytesArray[i];\r
141                         }\r
142 \r
143                 } else if (Com_SystemEndianness == COM_LITTLE_ENDIAN) {\r
144                         // Data copy algorithm creates big-endian output data so we swap\r
145                         uint8 i;\r
146                         for (i = 0; i < destSize; i++) {\r
147                                 signalDataBytes[(destSize - 1) - i] = signalDataBytesArray[i];\r
148                         }\r
149                 } else {\r
150                         //lint --e(506) PC-Lint exception Misra 13.7, 14.1, Allow boolean to always be false.\r
151                         assert(0);\r
152                 }\r
153         }\r
154         Irq_Restore(state);\r
155 }\r
156 \r
157 \r
158 void Com_WriteSignalDataToPdu(\r
159                         const Com_SignalIdType signalId,\r
160                         const void *signalData) {\r
161 \r
162         // Get PDU\r
163         const ComSignal_type *Signal     = GET_Signal(signalId);\r
164         const ComIPdu_type   *IPdu       = GET_IPdu(Signal->ComIPduHandleId);\r
165 \r
166         // Get data\r
167         Com_WriteSignalDataToPduBuffer(\r
168                         signalId,\r
169                         FALSE,\r
170                         signalData,\r
171                         (void *)IPdu->ComIPduDataPtr,\r
172                         IPdu->ComIPduSize);\r
173 }\r
174 \r
175 void Com_WriteGroupSignalDataToPdu(\r
176                 const Com_SignalIdType parentSignalId,\r
177                 const Com_SignalIdType groupSignalId,\r
178                 const void *signalData) {\r
179 \r
180         // Get PDU\r
181         const ComSignal_type *Signal     = GET_Signal(parentSignalId);\r
182         const ComIPdu_type   *IPdu       = GET_IPdu(Signal->ComIPduHandleId);\r
183 \r
184         // Get data\r
185         Com_WriteSignalDataToPduBuffer(\r
186                         groupSignalId,\r
187                         TRUE,\r
188                         signalData,\r
189                         (void *)IPdu->ComIPduDataPtr,\r
190                         IPdu->ComIPduSize);\r
191 }\r
192 \r
193 \r
194 void Com_WriteSignalDataToPduBuffer(\r
195                         const uint16 signalId,\r
196                         const boolean isGroupSignal,\r
197                         const void *signalData,\r
198                         void *pduBuffer,\r
199                         const uint8 pduSize) {\r
200         // TODO: Implement writing little-endian signals\r
201 \r
202         Com_SignalType signalType;\r
203         uint8 signalLength;\r
204         Com_BitPositionType bitPosition;\r
205         uint8 bitSize;\r
206         ComSignalEndianess_type endian;\r
207 \r
208         if (!isGroupSignal) {\r
209                 const ComSignal_type * Signal =  GET_Signal(signalId);\r
210                 signalType = Signal->ComSignalType;\r
211                 signalLength = Signal->ComBitSize / 8;\r
212                 bitPosition = Signal->ComBitPosition;\r
213                 bitSize = Signal->ComBitSize;\r
214                 endian = Signal->ComSignalEndianess;\r
215         } else {\r
216                 const ComGroupSignal_type *GroupSignal = GET_GroupSignal(signalId);\r
217                 signalType = GroupSignal->ComSignalType;\r
218                 signalLength = GroupSignal->ComBitSize / 8;\r
219                 bitPosition = GroupSignal->ComBitPosition;\r
220                 bitSize = GroupSignal->ComBitSize;\r
221                 endian = GroupSignal->ComSignalEndianess;\r
222         }\r
223 \r
224         uint8 signalBufferSize = SignalTypeToSize(signalType, signalLength);\r
225         uint8 pduSignalMask[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
226 \r
227         uint8 signalDataBytesArray[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
228         const uint8 *signalDataBytes = (const uint8 *)signalData;\r
229         imask_t irq_state;\r
230 \r
231         Irq_Save(irq_state);\r
232         if (endian == COM_OPAQUE || signalType == UINT8_N) {\r
233                 //assert(bitPosition % 8 == 0);\r
234                 //assert(bitSize % 8 == 0);\r
235                 uint8 *pduBufferBytes = (uint8 *)pduBuffer;\r
236                 uint8 startFromPduByte = bitPosition / 8;\r
237                 memcpy(pduBufferBytes + startFromPduByte, signalDataBytes, signalLength);\r
238         } else {\r
239                 if (Com_SystemEndianness == COM_BIG_ENDIAN) {\r
240                         // Straight copy\r
241                         uint8 i;\r
242                         for (i = 0; i < signalBufferSize; i++) {\r
243                                 signalDataBytesArray[i] = signalDataBytes[i];\r
244                         }\r
245 \r
246                 } else if (Com_SystemEndianness == COM_LITTLE_ENDIAN) {\r
247                         // Data copy algorithm assumes big-endian input data so we swap\r
248                         uint8 i;\r
249                         for (i = 0; i < signalBufferSize; i++) {\r
250                                 signalDataBytesArray[(signalBufferSize - 1) - i] = signalDataBytes[i];\r
251                         }\r
252                 } else {\r
253                         //lint --e(506) PC-Lint exception Misra 13.7, 14.1, Allow boolean to always be false.\r
254                         assert(0);\r
255                 }\r
256 \r
257                 if (endian == COM_BIG_ENDIAN) {\r
258                         Com_BitPositionType startBitOffset = motorolaBitNrToPduOffset(bitPosition%8);\r
259                         uint8 pduBufferBytesStraight[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
260 \r
261                         Com_WriteDataSegment(pduBufferBytesStraight, pduSignalMask,\r
262                                         signalDataBytesArray, signalBufferSize, startBitOffset, bitSize);\r
263 \r
264                         // Straight copy into real pdu buffer (with mutex)\r
265                         uint8 *pduBufferBytes = ((uint8 *)pduBuffer)+(bitPosition/8);\r
266                         uint8 i;\r
267                         for (i = 0; i < 8; i++) {\r
268                                 pduBufferBytes[ i ]  &=        ~( pduSignalMask[ i ] );\r
269                                 pduBufferBytes[ i ]  |=  pduBufferBytesStraight[ i ];\r
270                         }\r
271 \r
272                 } else {\r
273                         uint8 startBitOffset = intelBitNrToPduOffset(bitPosition%8, bitSize, 64);\r
274                         uint8 pduBufferBytesSwapped[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
275 \r
276                         Com_WriteDataSegment(pduBufferBytesSwapped, pduSignalMask,\r
277                                         signalDataBytesArray, signalBufferSize, startBitOffset, bitSize);\r
278 \r
279                         // Swapped copy into real pdu buffer (with mutex)\r
280                         uint8 *pduBufferBytes = ((uint8 *)pduBuffer)+(bitPosition/8);\r
281                         uint8 i;\r
282                         // actually it is only necessary to iterate through the bytes that are written.\r
283                         for (i = 0; i < 8; i++) {\r
284                                 pduBufferBytes[ i ]  &=       ~( pduSignalMask[ (8 - 1) - i ] );\r
285                                 pduBufferBytes[ i ]  |=  pduBufferBytesSwapped[ (8 - 1) - i ];\r
286                         }\r
287                 }\r
288         }\r
289         Irq_Restore(irq_state);\r
290 }\r
291 \r
292 \r
293 /*\r
294  * Read an arbitrary signal segment from buffer.\r
295  * dest:                   pointer to start of destination buffer\r
296  * source:                 pointer to start of source buffer\r
297  * destByteLength:         size of destination buffer in bytes\r
298  * segmentStartBitOffset:  bit offset to signal segment (from first bit in *source data)\r
299  * segmentBitLength:       length in bits of the signal segment to be read\r
300  *\r
301  * Example:\r
302  *    Source data: (ABC... = signal segment)\r
303  *    | -----ABC | DEFGHIJK | LMNOPQ-- |\r
304  *         B0         B1         B2\r
305  *  Parameters:\r
306  *    dest:                  pointer to 32 bit space (needs to be at least 3 bytes to keep the 17 signal bits)\r
307  *    destByteLength:          4\r
308  *    source:                *B0\r
309  *    segmentStartBitOffset:   5\r
310  *    segmentBitLength:       17\r
311  *\r
312  *  Result:\r
313  *    Destination:\r
314  *    | -------- | -------A | BCDEFGHI | JKLMNOPQ |\r
315  *\r
316  */\r
317 static void Com_ReadDataSegment(uint8 *dest, const uint8 *source, uint8 destByteLength,\r
318                 Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength, boolean signedOutput) {\r
319 \r
320         Com_BitPositionType sourceEndBitOffset = segmentStartBitOffset + segmentBitLength - 1;\r
321         Com_BitPositionType sourceStartByte = segmentStartBitOffset / 8;\r
322         uint8 sourceEndByte = (sourceEndBitOffset) / 8;\r
323         uint8 sourceByteLength = sourceEndByte - sourceStartByte;\r
324 \r
325         uint8 segmentStartBitOffsetInsideByte = segmentStartBitOffset % 8;\r
326         uint16 sourceStartByteMask;\r
327 \r
328         uint8 sourceAlignmentShift = 7 - (sourceEndBitOffset % 8);\r
329         uint8 segmentByteLength = 1 + (segmentBitLength - 1) / 8;\r
330         uint8 sourceByteNr = 0;\r
331         uint8 destByteNr = 0;\r
332 \r
333         uint16 shiftReg = 0;\r
334 \r
335         boolean negative;\r
336 \r
337         if ( signedOutput && (*(source + sourceStartByte) & (0x80u >> segmentStartBitOffsetInsideByte)) ) {\r
338                 negative = TRUE;\r
339                 sourceStartByteMask = (0xFF00u >> segmentStartBitOffsetInsideByte);\r
340                 memset(dest, 0xFF, destByteLength);\r
341         } else {\r
342                 negative = FALSE;\r
343                 sourceStartByteMask = (0x00FFu >> segmentStartBitOffsetInsideByte);\r
344                 memset(dest, 0x00u, destByteLength);\r
345         }\r
346 \r
347         // setup to point to end (LSB) of buffers\r
348         source += sourceEndByte;\r
349         dest += destByteLength - 1;\r
350 \r
351         if (negative) {\r
352         // compiles and writes one destination byte on each iteration\r
353                 do {\r
354                         shiftReg = *(source - sourceByteNr) | 0xFF00u;          // read source byte (already matching "byte space")\r
355                         if (sourceByteNr == sourceByteLength) {                         // if we are on the last source byte..\r
356                                 shiftReg |= sourceStartByteMask;                        // ..we need to mask out stuff we don't want\r
357                         }\r
358                         shiftReg >>= sourceAlignmentShift;                                      // shift down to align\r
359                         *(dest - destByteNr) &= shiftReg | 0xFF00u;             // write into destination byte\r
360 \r
361                         sourceByteNr++;                                                                         // move to next source byte\r
362                         if ( (sourceAlignmentShift != 0)                                                // do we have more bits for current dest. byte in this source byte?\r
363                                         && (sourceByteNr <= sourceByteLength) ) {\r
364                                 shiftReg = *(source - sourceByteNr) | 0xFF00u;  // read next source byte\r
365                                 if (sourceByteNr == sourceByteLength) {                 // if we are on the last source byte..\r
366                                         shiftReg |= sourceStartByteMask;                // ..we need to mask out stuff we don't want\r
367                                 }\r
368                                 shiftReg = (uint16)~(shiftReg);                                         // shifting inverted to shift in 1:s\r
369                                 shiftReg <<= 8;                                                         // shift up (to match destination "byte space")\r
370                                 shiftReg = (uint16)~shiftReg;\r
371                                 shiftReg >>= sourceAlignmentShift;                              // shift down to align\r
372                                 *(dest - destByteNr) &= shiftReg | 0xFF00u;     // write into destination byte\r
373                         }\r
374                         destByteNr++;\r
375                 } while (destByteNr < segmentByteLength);\r
376         } else { // positive\r
377                 do {\r
378                         shiftReg = *(source - sourceByteNr) & 0x00FFu;          // read source byte (already matching "byte space")\r
379                         if (sourceByteNr == sourceByteLength) {                         // if we are on the last source byte..\r
380                                 shiftReg &= sourceStartByteMask;                        // ..we need to mask out stuff we don't want\r
381                         }\r
382                         shiftReg >>= sourceAlignmentShift;                                      // shift down to align\r
383                         *(dest - destByteNr) |= shiftReg & 0x00FFu;             // write into destination byte\r
384 \r
385                         sourceByteNr++;                                                                         // move to next source byte\r
386                         if (sourceAlignmentShift != 0                                           // do we have more bits for current dest. byte in this source byte?\r
387                                         && sourceByteNr <= sourceByteLength) {\r
388                                 shiftReg = *(source - sourceByteNr) & 0x00FFu;  // read next source byte\r
389                                 if (sourceByteNr == sourceByteLength) {                 // if we are on the last source byte..\r
390                                         shiftReg &= sourceStartByteMask;                // ..we need to mask out stuff we don't want\r
391                                 }\r
392                                 shiftReg <<= 8;                                                         // shift up (to match destination "byte space")\r
393                                 shiftReg >>= sourceAlignmentShift;                              // shift down to align\r
394                                 *(dest - destByteNr) |= shiftReg & 0x00FFu;     // write into destination byte\r
395                         }\r
396                         destByteNr++;\r
397                 } while (destByteNr < segmentByteLength);\r
398         }\r
399 }\r
400 \r
401 /*\r
402  * Copies the <segmentBitLength> least significant bits from <signal> into <pdu>.\r
403  * The bit segment is placed in <pdu> so that the most significant bit ends up\r
404  * at <segmentStartBitOffset> from the msb of <pdu>.\r
405  * <pduSignalMask> is cleared and written to contain a mask with 1´s where the\r
406  * signal is located in the <pdu>.\r
407  */\r
408 void Com_WriteDataSegment(uint8 *pdu, uint8 *pduSignalMask, const uint8 *signalDataPtr, uint8 destByteLength,\r
409                 Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength) {\r
410         Com_BitPositionType pduEndBitOffset = segmentStartBitOffset + segmentBitLength - 1;\r
411         uint8 pduStartByte = segmentStartBitOffset / 8;\r
412         uint8 pduEndByte = (pduEndBitOffset) / 8;\r
413         uint8 pduByteLength = pduEndByte - pduStartByte;\r
414 \r
415         uint8 segmentStartBitOffsetInsideByte = segmentStartBitOffset % 8;\r
416         uint8 pduStartByteMask = (0xFFu >> segmentStartBitOffsetInsideByte);\r
417 \r
418         uint8 pduAlignmentShift = 7 - (pduEndBitOffset % 8);\r
419         uint8 segmentByteLength = 1 + (segmentBitLength - 1) / 8;\r
420         uint8 pduByteNr = 0;\r
421         uint8 signalByteNr = 0;\r
422 \r
423         uint16 shiftReg = 0;\r
424         uint16 clearReg = 0;\r
425 \r
426         // clear pduSignalMask all the way from 0\r
427         memset(pduSignalMask, 0x00, pduEndByte);\r
428 \r
429         // setup to point to end (LSB) of buffers\r
430         pdu           += pduEndByte;\r
431         pduSignalMask += pduEndByte;\r
432 \r
433         signalDataPtr += destByteLength - 1;\r
434 \r
435         // splits and writes one source byte on each iteration\r
436         do {\r
437                 shiftReg = *(signalDataPtr - signalByteNr) & 0x00FFu;\r
438                 clearReg = 0x00FF;\r
439                 //lint -save -e701 -e734 //PC-Lint Wrong interpretation of MISRA rule 10.5.\r
440                 shiftReg <<= pduAlignmentShift;\r
441                 clearReg <<= pduAlignmentShift;\r
442                 //lint -restore\r
443                 if (pduByteNr == pduByteLength) {\r
444                         shiftReg &= pduStartByteMask;\r
445                         clearReg &= pduStartByteMask;\r
446                 }\r
447                 *(pdu           - pduByteNr) &= (uint16)~(clearReg & 0x00FFu);\r
448                 *(pduSignalMask - pduByteNr) |= (uint16) (clearReg & 0x00FFu);\r
449                 *(pdu           - pduByteNr) |= shiftReg & 0x00FFu;\r
450 \r
451                 pduByteNr++;\r
452                 if ( (pduAlignmentShift != 0)\r
453                                 && (pduByteNr <= pduByteLength) ) {\r
454                         shiftReg = *(signalDataPtr - signalByteNr) & 0x00FFu;\r
455                         clearReg = 0x00FF;\r
456                         //lint -save -e701 -e734 //PC-Lint Wrong interpretation of MISRA rule 10.5.\r
457                         shiftReg <<= pduAlignmentShift;\r
458                         clearReg <<= pduAlignmentShift;\r
459                         shiftReg >>= 8;\r
460                         clearReg >>= 8;\r
461                         //lint -restore\r
462                         if (pduByteNr == pduByteLength) {\r
463                                 shiftReg &= pduStartByteMask;\r
464                                 clearReg &= pduStartByteMask;\r
465                         }\r
466                         *(pdu           - pduByteNr) &= (uint16)~(clearReg & 0x00FFu);\r
467                         *(pduSignalMask - pduByteNr) |= (uint16) (clearReg & 0x00FFu);\r
468                         *(pdu           - pduByteNr) |= shiftReg & 0x00FFu;\r
469                 }\r
470                 signalByteNr++;\r
471         } while (signalByteNr < segmentByteLength);\r
472 }\r
473 \r
474 /*\r
475  * Converts from motorola CAN bit nr to PDU bit offset\r
476  *\r
477  *             motorolaBitNr:  7  6  5  4  3  2  1  0 15 14 13 12 ...\r
478  *  motorolaBitNrToPduOffset:  0  1  2  3  4  5  6  7  8  9 10 11 ...\r
479  */\r
480 Com_BitPositionType motorolaBitNrToPduOffset (Com_BitPositionType motorolaBitNr) {\r
481         uint8 byte = motorolaBitNr / 8;\r
482         Com_BitPositionType offsetToByteStart = (Com_BitPositionType) (byte * 8u);\r
483         Com_BitPositionType offsetInsideByte = motorolaBitNr % 8;\r
484         return (Com_BitPositionType) (offsetToByteStart + (7u - offsetInsideByte));\r
485 }\r
486 \r
487 /*\r
488  * Converts from intel CAN bit nr to PDU bit offset\r
489  *\r
490  *                        pduNumBits: 40\r
491  *  intelBitNr (after PDU byte-swap): 39 38 37 36 35 34 33 32 31 ...  3  2  1  0\r
492  *             intelBitNrToPduOffset:  0  1  2  3  4  5  6  7  8 ... 36 37 38 39\r
493  */\r
494 Com_BitPositionType intelBitNrToPduOffset (Com_BitPositionType intelBitNr, Com_BitPositionType segmentBitLength, Com_BitPositionType pduBitLength) {\r
495         return pduBitLength - (intelBitNr + segmentBitLength);\r
496 }\r
497 \r
498 void Com_RxProcessSignals(const ComIPdu_type *IPdu,Com_Arc_IPdu_type *Arc_IPdu) {\r
499         const ComSignal_type *comSignal;\r
500         for (uint8 i = 0; IPdu->ComIPduSignalRef[i] != NULL; i++) {\r
501                 comSignal = IPdu->ComIPduSignalRef[i];\r
502                 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(comSignal->ComHandleId);\r
503 \r
504                 // If this signal uses an update bit, then it is only considered if this bit is set.\r
505                 if ( (!comSignal->ComSignalArcUseUpdateBit) ||\r
506                         ( (comSignal->ComSignalArcUseUpdateBit) && (TESTBIT(IPdu->ComIPduDataPtr, comSignal->ComUpdateBitPosition)) ) ) {\r
507 \r
508                         if (comSignal->ComTimeoutFactor > 0) { // If reception deadline monitoring is used.\r
509                                 // Reset the deadline monitoring timer.\r
510                                 Arc_Signal->Com_Arc_DeadlineCounter = comSignal->ComTimeoutFactor;\r
511                         }\r
512 \r
513                         // Check the signal processing mode.\r
514                         if (IPdu->ComIPduSignalProcessing == IMMEDIATE) {\r
515                                 // If signal processing mode is IMMEDIATE, notify the signal callback.\r
516                                 if (IPdu->ComIPduSignalRef[i]->ComNotification != NULL) {\r
517                                         IPdu->ComIPduSignalRef[i]->ComNotification();\r
518                                 }\r
519 \r
520                         } else {\r
521                                 // Signal processing mode is DEFERRED, mark the signal as updated.\r
522                                 Arc_Signal->ComSignalUpdated = 1;\r
523                         }\r
524 \r
525                 } else {\r
526                         DEBUG(DEBUG_LOW, "Com_RxIndication: Ignored signal %d of I-PD %d since its update bit was not set\n", comSignal->ComHandleId, ComRxPduId);\r
527                 }\r
528         }\r
529 }\r
530 void UnlockTpBuffer(PduIdType PduId) {\r
531         Com_BufferPduState[PduId].locked = false;\r
532         Com_BufferPduState[PduId].currentPosition = 0;\r
533 }\r
534 \r
535 boolean isPduBufferLocked(PduIdType id) {\r
536         imask_t state;\r
537         Irq_Save(state);\r
538         boolean bufferLocked = Com_BufferPduState[id].locked;\r
539         Irq_Restore(state);\r
540         if (bufferLocked) {\r
541                 return true;\r
542         } else {\r
543                 return false;\r
544         }\r
545 }\r
546 PduIdType getPduId(const ComIPdu_type* IPdu) {\r
547         return (PduIdType)(IPdu - (ComConfig->ComIPdu));\r
548 }\r