1
0
Fork 0

Verify for restricted CAN-IDs in SYNC, TIME, EMCY, PDO and SDO COB-ID configuration.

This commit is contained in:
Janez 2021-08-09 14:12:19 +02:00
parent 5338f110e1
commit fe3777b781
7 changed files with 66 additions and 30 deletions

View file

@ -94,7 +94,7 @@ static ODR_t OD_write_1014(OD_stream_t *stream, const void *buf,
uint16_t curCanId = em->producerCanId == CO_CAN_ID_EMERGENCY ?
CO_CAN_ID_EMERGENCY + em->nodeId : em->producerCanId;
bool_t newEnabled = (COB_IDEmergency32 & 0x80000000) == 0 && newCanId != 0;
if ((COB_IDEmergency32 & 0x7FFFF800) != 0
if ((COB_IDEmergency32 & 0x7FFFF800)!=0 || CO_IS_RESTRICTED_CAN_ID(newCanId)
|| (em->producerEnabled && newEnabled && newCanId != curCanId)
) {
return ODR_INVALID_VALUE;

View file

@ -540,7 +540,7 @@ static ODR_t OD_write_14xx(OD_stream_t *stream, const void *buf,
* enabling the PDO */
if ((COB_ID & 0x3FFFF800) != 0
|| (valid && PDO->valid && CAN_ID != PDO->configuredCanId)
|| (valid && CAN_ID == 0)
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
|| (valid && PDO->mappedObjectsCount == 0)
) {
return ODR_INVALID_VALUE;
@ -965,7 +965,7 @@ static ODR_t OD_write_18xx(OD_stream_t *stream, const void *buf,
* enabling the PDO */
if ((COB_ID & 0x3FFFF800) != 0
|| (valid && PDO->valid && CAN_ID != PDO->configuredCanId)
|| (valid && CAN_ID == 0)
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
|| (valid && PDO->mappedObjectsCount == 0)
) {
return ODR_INVALID_VALUE;

View file

@ -182,20 +182,21 @@ static ODR_t OD_write_1280(OD_stream_t *stream, const void *buf,
}
CO_SDOclient_t *SDO_C = (CO_SDOclient_t *)stream->object;
uint32_t COB_ID;
uint8_t nodeId;
switch (stream->subIndex) {
case 0: /* Highest sub-index supported */
return ODR_READONLY;
case 1: /* COB-ID client -> server */
COB_ID = CO_getUint32(buf);
case 1: { /* COB-ID client -> server */
uint32_t COB_ID = CO_getUint32(buf);
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FF);
uint16_t CAN_ID_cur = (uint16_t)(SDO_C->COB_IDClientToServer&0x7FF);
bool_t valid = (COB_ID & 0x80000000) == 0;
/* SDO client must not be valid when changing COB_ID */
if ((COB_ID & 0x3FFFF800) != 0
|| ((uint16_t)COB_ID != (uint16_t)SDO_C->COB_IDClientToServer
&& SDO_C->valid && (COB_ID & 0x80000000) == 0)
|| (valid && SDO->valid && CAN_ID != CAN_ID_cur)
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
) {
return ODR_INVALID_VALUE;
}
@ -204,14 +205,18 @@ static ODR_t OD_write_1280(OD_stream_t *stream, const void *buf,
SDO_C->COB_IDServerToClient,
SDO_C->nodeIDOfTheSDOServer);
break;
}
case 2: /* COB-ID server -> client */
COB_ID = CO_getUint32(buf);
case 2: { /* COB-ID server -> client */
uint32_t COB_ID = CO_getUint32(buf);
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FF);
uint16_t CAN_ID_cur = (uint16_t)(SDO_C->COB_IDServerToClient&0x7FF);
bool_t valid = (COB_ID & 0x80000000) == 0;
/* SDO client must not be valid when changing COB_ID */
if ((COB_ID & 0x3FFFF800) != 0
|| ((uint16_t)COB_ID != (uint16_t)SDO_C->COB_IDServerToClient
&& SDO_C->valid && (COB_ID & 0x80000000) == 0)
|| (valid && SDO->valid && CAN_ID != CAN_ID_cur)
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
) {
return ODR_INVALID_VALUE;
}
@ -220,14 +225,16 @@ static ODR_t OD_write_1280(OD_stream_t *stream, const void *buf,
COB_ID,
SDO_C->nodeIDOfTheSDOServer);
break;
}
case 3: /* Node-ID of the SDO server */
nodeId = CO_getUint8(buf);
case 3: { /* Node-ID of the SDO server */
uint8_t nodeId = CO_getUint8(buf);
if (nodeId > 127) {
return ODR_INVALID_VALUE;
}
SDO_C->nodeIDOfTheSDOServer = nodeId;
break;
}
default:
return ODR_SUB_NOT_EXIST;

View file

@ -241,20 +241,21 @@ static ODR_t OD_write_1201_additional(OD_stream_t *stream, const void *buf,
}
CO_SDOserver_t *SDO = (CO_SDOserver_t *)stream->object;
uint32_t COB_ID;
uint8_t nodeId;
switch (stream->subIndex) {
case 0: /* Highest sub-index supported */
return ODR_READONLY;
case 1: /* COB-ID client -> server */
COB_ID = CO_getUint32(buf);
case 1: { /* COB-ID client -> server */
uint32_t COB_ID = CO_getUint32(buf);
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FF);
uint16_t CAN_ID_cur = (uint16_t)(SDO->COB_IDClientToServer & 0x7FF);
bool_t valid = (COB_ID & 0x80000000) == 0;
/* SDO client must not be valid when changing COB_ID */
if ((COB_ID & 0x3FFFF800) != 0
|| ((uint16_t)COB_ID != (uint16_t)SDO->COB_IDClientToServer
&& SDO->valid && (COB_ID & 0x80000000))
|| (valid && SDO->valid && CAN_ID != CAN_ID_cur)
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
) {
return ODR_INVALID_VALUE;
}
@ -265,14 +266,18 @@ static ODR_t OD_write_1201_additional(OD_stream_t *stream, const void *buf,
COB_ID,
SDO->COB_IDServerToClient);
break;
}
case 2: /* COB-ID server -> client */
COB_ID = CO_getUint32(buf);
case 2: { /* COB-ID server -> client */
uint32_t COB_ID = CO_getUint32(buf);
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FF);
uint16_t CAN_ID_cur = (uint16_t)(SDO->COB_IDServerToClient & 0x7FF);
bool_t valid = (COB_ID & 0x80000000) == 0;
/* SDO client must not be valid when changing COB_ID */
if ((COB_ID & 0x3FFFF800) != 0
|| ((uint16_t)COB_ID != (uint16_t)SDO->COB_IDServerToClient
&& SDO->valid && (COB_ID & 0x80000000))
|| (valid && SDO->valid && CAN_ID != CAN_ID_cur)
|| (valid && CO_IS_RESTRICTED_CAN_ID(CAN_ID))
) {
return ODR_INVALID_VALUE;
}
@ -283,16 +288,18 @@ static ODR_t OD_write_1201_additional(OD_stream_t *stream, const void *buf,
SDO->COB_IDClientToServer,
COB_ID);
break;
}
case 3: /* Node-ID of the SDO server */
case 3: { /* Node-ID of the SDO server */
if (count != 1) {
return ODR_TYPE_MISMATCH;
}
nodeId = CO_getUint8(buf);
uint8_t nodeId = CO_getUint8(buf);
if (nodeId < 1 || nodeId > 127) {
return ODR_INVALID_VALUE;
}
break;
}
default:
return ODR_SUB_NOT_EXIST;

View file

@ -96,13 +96,13 @@ static ODR_t OD_write_1005(OD_stream_t *stream, const void *buf,
/* verify written value */
#if (CO_CONFIG_SYNC) & CO_CONFIG_SYNC_PRODUCER
bool_t isProducer = (cobIdSync & 0x40000000) != 0;
if ((cobIdSync & 0xBFFF8000) != 0
if ((cobIdSync & 0xBFFFF800) != 0 || CO_IS_RESTRICTED_CAN_ID(CAN_ID)
|| (SYNC->isProducer && isProducer && CAN_ID != SYNC->CAN_ID)
) {
return ODR_INVALID_VALUE;
}
#else
if ((cobIdSync & 0xFFFF8000) != 0) {
if ((cobIdSync & 0xFFFFF800) != 0 || CO_IS_RESTRICTED_CAN_ID(CAN_ID)) {
return ODR_INVALID_VALUE;
}
#endif

View file

@ -72,8 +72,14 @@ static ODR_t OD_write_1012(OD_stream_t *stream, const void *buf,
CO_TIME_t *TIME = stream->object;
/* update object */
/* verify written value */
uint32_t cobIdTimeStamp = CO_getUint32(buf);
uint16_t CAN_ID = cobIdTimeStamp & 0x7FF;
if ((cobIdTimeStamp & 0x3FFFF800) != 0 || CO_IS_RESTRICTED_CAN_ID(CAN_ID)) {
return ODR_INVALID_VALUE;
}
/* update object */
TIME->isConsumer = (cobIdTimeStamp & 0x80000000L) != 0;
TIME->isProducer = (cobIdTimeStamp & 0x40000000L) != 0;

View file

@ -500,6 +500,22 @@ typedef enum {
} CO_Default_CAN_ID_t;
/**
* Restricted CAN-IDs
*
* Macro for verifying 'Restricted CAN-IDs', as specified by standard CiA301.
* They shall not be used for SYNC, TIME, EMCY, PDO and SDO.
*/
#ifndef CO_IS_RESTRICTED_CAN_ID
#define CO_IS_RESTRICTED_CAN_ID(CAN_ID) ((CAN_ID) <= 0x7F \
|| ((CAN_ID) >= 0x101 && (CAN_ID) <= 0x180) \
|| ((CAN_ID) >= 0x581 && (CAN_ID) <= 0x5FF) \
|| ((CAN_ID) >= 0x601 && (CAN_ID) <= 0x67F) \
|| ((CAN_ID) >= 0x6E0 && (CAN_ID) <= 0x6FF) \
|| (CAN_ID) >= 0x701)
#endif
/**
* CAN error status bitmasks.
*