Transfer data locally */
| 439 | #if ((CO_CONFIG_SDO_CLI)&CO_CONFIG_SDO_CLI_LOCAL) != 0 |
| 440 | /* Transfer data locally */ |
| 441 | else if ((SDO_C->state == CO_SDO_ST_DOWNLOAD_LOCAL_TRANSFER) && !send_abort) { |
| 442 | /* search object dictionary in first pass */ |
| 443 | if (SDO_C->OD_IO.write == NULL) { |
| 444 | ODR_t odRet; |
| 445 | |
| 446 | odRet = OD_getSub(OD_find(SDO_C->OD, SDO_C->index), SDO_C->subIndex, &SDO_C->OD_IO, false); |
| 447 | |
| 448 | if (odRet != ODR_OK) { |
| 449 | abortCode = (CO_SDO_abortCode_t)OD_getSDOabCode(odRet); |
| 450 | ret = CO_SDO_RT_endedWithClientAbort; |
| 451 | } else if ((SDO_C->OD_IO.stream.attribute & (OD_attr_t)ODA_SDO_RW) == 0U) { |
| 452 | abortCode = CO_SDO_AB_UNSUPPORTED_ACCESS; |
| 453 | ret = CO_SDO_RT_endedWithClientAbort; |
| 454 | } else if ((SDO_C->OD_IO.stream.attribute & (OD_attr_t)ODA_SDO_W) == 0U) { |
| 455 | abortCode = CO_SDO_AB_READONLY; |
| 456 | ret = CO_SDO_RT_endedWithClientAbort; |
| 457 | } else if (SDO_C->OD_IO.write == NULL) { |
| 458 | abortCode = CO_SDO_AB_DEVICE_INCOMPAT; |
| 459 | ret = CO_SDO_RT_endedWithClientAbort; |
| 460 | } else { /* MISRA C 2004 14.10 */ |
| 461 | } |
| 462 | } |
| 463 | /* write data, in several passes if necessary */ |
| 464 | if (SDO_C->OD_IO.write != NULL) { |
| 465 | size_t count = CO_fifo_getOccupied(&SDO_C->bufFifo); |
| 466 | uint8_t buf[CO_CONFIG_SDO_CLI_BUFFER_SIZE + 2U]; |
| 467 | |
| 468 | (void)CO_fifo_read(&SDO_C->bufFifo, buf, count, NULL); |
| 469 | SDO_C->sizeTran += count; |
| 470 | |
| 471 | /* error: no data */ |
| 472 | if ((count == 0U) || (count > CO_CONFIG_SDO_CLI_BUFFER_SIZE)) { |
| 473 | abortCode = CO_SDO_AB_DEVICE_INCOMPAT; |
| 474 | ret = CO_SDO_RT_endedWithClientAbort; |
| 475 | } |
| 476 | /* verify if sizeTran is too large */ |
| 477 | else if ((SDO_C->sizeInd > 0U) && (SDO_C->sizeTran > SDO_C->sizeInd)) { |
| 478 | SDO_C->sizeTran -= count; |
| 479 | abortCode = CO_SDO_AB_DATA_LONG; |
| 480 | ret = CO_SDO_RT_endedWithClientAbort; |
| 481 | } |
| 482 | /* Verify sizeTran is too small in last segment of data */ |
| 483 | else if (!bufferPartial && (SDO_C->sizeInd > 0U) && (SDO_C->sizeTran < SDO_C->sizeInd)) { |
| 484 | abortCode = CO_SDO_AB_DATA_SHORT; |
| 485 | ret = CO_SDO_RT_endedWithClientAbort; |
| 486 | } |
| 487 | /* is the last segment of data? */ |
| 488 | else if (!bufferPartial) { |
| 489 | #ifdef CO_BIG_ENDIAN |
| 490 | /* swap int16_t .. uint64_t data if necessary */ |
| 491 | if ((SDO_C->OD_IO.stream.attribute & ODA_MB) != 0) { |
| 492 | reverseBytes(buf, count); |
| 493 | } |
| 494 | #endif |
| 495 | OD_size_t sizeInOd = SDO_C->OD_IO.stream.dataLength; |
| 496 | |
| 497 | /* If dataType is string, then size of data downloaded may be shorter than size of |
| 498 | * OD data buffer. If so, add two zero bytes to terminate (unicode) string. Shorten |
nothing calls this directly
no test coverage detected