Helper function for reading data from Object dictionary. Function also swaps data if necessary and calcualtes CRC. * * @param SDO SDO server * @param [out] abortCode SDO abort code in case of error * @parma countMinimum if data size in buffer is less than countMinimum, then buffer is refilled from OD variable * @param calculateCrc if true, crc is calculated * * Returns true on success, othe
| 507 | * |
| 508 | * Returns true on success, otherwise write also abortCode and sets state to CO_SDO_ST_ABORT */ |
| 509 | static bool_t |
| 510 | readFromOd(CO_SDOserver_t* SDO, CO_SDO_abortCode_t* abortCode, OD_size_t countMinimum, bool_t calculateCrc) { |
| 511 | #if ((CO_CONFIG_SDO_SRV)&CO_CONFIG_SDO_SRV_BLOCK) == 0 |
| 512 | (void)calculateCrc; /* may be unused */ |
| 513 | #endif |
| 514 | OD_size_t countRemain = SDO->bufOffsetWr - SDO->bufOffsetRd; |
| 515 | |
| 516 | if (!SDO->finished && (countRemain < countMinimum)) { |
| 517 | /* first move remaining data to the start of the buffer */ |
| 518 | (void)memmove(SDO->buf, SDO->buf + SDO->bufOffsetRd, countRemain); |
| 519 | SDO->bufOffsetRd = 0; |
| 520 | SDO->bufOffsetWr = countRemain; |
| 521 | |
| 522 | /* Get size of free data buffer */ |
| 523 | OD_size_t countRdRequest = CO_CONFIG_SDO_SRV_BUFFER_SIZE - countRemain; |
| 524 | |
| 525 | /* load data from OD variable into the buffer */ |
| 526 | OD_size_t countRd = 0; |
| 527 | ODR_t odRet; |
| 528 | |
| 529 | CO_LOCK_OD(SDO->CANdevTx); |
| 530 | odRet = SDO->OD_IO.read(&SDO->OD_IO.stream, &SDO->buf[countRemain], countRdRequest, &countRd); |
| 531 | CO_UNLOCK_OD(SDO->CANdevTx); |
| 532 | |
| 533 | if ((odRet != ODR_OK) && (odRet != ODR_PARTIAL)) { |
| 534 | *abortCode = (CO_SDO_abortCode_t)OD_getSDOabCode(odRet); |
| 535 | SDO->state = CO_SDO_ST_ABORT; |
| 536 | return false; |
| 537 | } |
| 538 | |
| 539 | /* if data is string, send only data up to null termination */ |
| 540 | OD_size_t lastRd = countRd + countRemain; |
| 541 | if ((countRd > 0U) && ((SDO->OD_IO.stream.attribute & (OD_attr_t)ODA_STR) != 0U)) { |
| 542 | SDO->buf[lastRd] = 0; /* (SDO->buf is one byte larger) */ |
| 543 | OD_size_t countStr = (OD_size_t)strlen((char*)&SDO->buf[countRemain]); |
| 544 | if (countStr == 0U) { |
| 545 | countStr = 1; |
| 546 | } /* zero length is not allowed */ |
| 547 | if (countStr < countRd) { |
| 548 | /* string terminator found, read is finished, shorten data */ |
| 549 | countRd = countStr; |
| 550 | odRet = ODR_OK; |
| 551 | SDO->OD_IO.stream.dataLength = SDO->sizeTran + countRd; |
| 552 | } |
| 553 | } |
| 554 | |
| 555 | /* partial or finished read */ |
| 556 | SDO->bufOffsetWr = countRemain + countRd; |
| 557 | if ((SDO->bufOffsetWr == 0U) || (odRet == ODR_PARTIAL)) { |
| 558 | SDO->finished = false; |
| 559 | if (SDO->bufOffsetWr < countMinimum) { |
| 560 | *abortCode = CO_SDO_AB_DEVICE_INCOMPAT; |
| 561 | SDO->state = CO_SDO_ST_ABORT; |
| 562 | return false; |
| 563 | } |
| 564 | } else { |
| 565 | SDO->finished = true; |
| 566 | } |
no test coverage detected