MCPcopy Create free account
hub / github.com/CANopenNode/CANopenNode / if

Function if

301/CO_SDOclient.c:441–571  ·  view source on GitHub ↗

Transfer data locally */

Source from the content-addressed store, hash-verified

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

Callers

nothing calls this directly

Calls 10

OD_getSubFunction · 0.85
OD_findFunction · 0.85
OD_getSDOabCodeFunction · 0.85
CO_fifo_getOccupiedFunction · 0.85
CO_fifo_readFunction · 0.85
CO_fifo_altBeginFunction · 0.85
CO_fifo_altFinishFunction · 0.85
CO_fifo_getSpaceFunction · 0.85
CO_fifo_writeFunction · 0.85
reverseBytesFunction · 0.70

Tested by

no test coverage detected