Helper function for writing data to Object dictionary. Function swaps data if necessary, * calcualtes (and verifies CRC) writes data to OD and verifies data lengths. * * @param SDO SDO server * @param [out] abortCode SDO abort code in case of error * @param crcOperation 0=none, 1=calculate, 2=calculate and compare * @parma crcClient crc checksum to campare with * * Returns true on success,
| 395 | * |
| 396 | * Returns true on success, otherwise write also abortCode and sets state to CO_SDO_ST_ABORT */ |
| 397 | static bool_t |
| 398 | validateAndWriteToOD(CO_SDOserver_t* SDO, CO_SDO_abortCode_t* abortCode, uint8_t crcOperation, uint16_t crcClient) { |
| 399 | OD_size_t bufOffsetWrOrig = SDO->bufOffsetWr; |
| 400 | |
| 401 | if (SDO->finished) { |
| 402 | /* Verify if size of data downloaded matches size indicated. */ |
| 403 | if ((SDO->sizeInd > 0U) && (SDO->sizeTran != SDO->sizeInd)) { |
| 404 | *abortCode = (SDO->sizeTran > SDO->sizeInd) ? CO_SDO_AB_DATA_LONG : CO_SDO_AB_DATA_SHORT; |
| 405 | SDO->state = CO_SDO_ST_ABORT; |
| 406 | return false; |
| 407 | } |
| 408 | |
| 409 | #ifdef CO_BIG_ENDIAN |
| 410 | /* swap int16_t .. uint64_t data if necessary */ |
| 411 | if ((SDO->OD_IO.stream.attribute & ODA_MB) != 0) { |
| 412 | reverseBytes(SDO->buf, SDO->bufOffsetWr); |
| 413 | } |
| 414 | #endif |
| 415 | |
| 416 | OD_size_t sizeInOd = SDO->OD_IO.stream.dataLength; |
| 417 | |
| 418 | /* If dataType is string, then size of data downloaded may be shorter than size of the |
| 419 | * OD data buffer. If so, add two zero bytes to terminate (unicode) string. Shorten |
| 420 | * also OD data size, (temporary, send information about EOF into OD_IO.write) */ |
| 421 | if (((SDO->OD_IO.stream.attribute & (OD_attr_t)ODA_STR) != 0U) |
| 422 | && ((sizeInOd == 0U) || (SDO->sizeTran < sizeInOd)) |
| 423 | && ((SDO->bufOffsetWr + 2U) <= CO_CONFIG_SDO_SRV_BUFFER_SIZE)) { |
| 424 | SDO->buf[SDO->bufOffsetWr] = 0; |
| 425 | SDO->bufOffsetWr++; |
| 426 | SDO->sizeTran++; |
| 427 | if ((sizeInOd == 0U) || (SDO->sizeTran < sizeInOd)) { |
| 428 | SDO->buf[SDO->bufOffsetWr] = 0; |
| 429 | SDO->bufOffsetWr++; |
| 430 | SDO->sizeTran++; |
| 431 | } |
| 432 | SDO->OD_IO.stream.dataLength = SDO->sizeTran; |
| 433 | } |
| 434 | /* Indicate OD data size, if not indicated. Can be used for EOF check. */ |
| 435 | else if (sizeInOd == 0U) { |
| 436 | SDO->OD_IO.stream.dataLength = SDO->sizeTran; |
| 437 | } |
| 438 | /* Verify if size of data downloaded matches data size in OD. */ |
| 439 | else if (SDO->sizeTran != sizeInOd) { |
| 440 | *abortCode = (SDO->sizeTran > sizeInOd) ? CO_SDO_AB_DATA_LONG : CO_SDO_AB_DATA_SHORT; |
| 441 | SDO->state = CO_SDO_ST_ABORT; |
| 442 | return false; |
| 443 | } else { /* MISRA C 2004 14.10 */ |
| 444 | } |
| 445 | } else { |
| 446 | /* Verify if size of data downloaded is not too large. */ |
| 447 | if ((SDO->sizeInd > 0U) && (SDO->sizeTran > SDO->sizeInd)) { |
| 448 | *abortCode = CO_SDO_AB_DATA_LONG; |
| 449 | SDO->state = CO_SDO_ST_ABORT; |
| 450 | return false; |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | #if ((CO_CONFIG_SDO_SRV)&CO_CONFIG_SDO_SRV_BLOCK) != 0 |
no test coverage detected