diff --git a/doc/spinel-protocol-src/spinel-prop-mac.md b/doc/spinel-protocol-src/spinel-prop-mac.md index 5b6015b76..fd317d3da 100644 --- a/doc/spinel-protocol-src/spinel-prop-mac.md +++ b/doc/spinel-protocol-src/spinel-prop-mac.md @@ -125,7 +125,7 @@ per scanned channel with following format: ### PROP 4864: PROP_MAC_WHITELIST {#prop-mac-whitelist} * Type: Read-Write * Packed-Encoding: `A(T(Ec))` -* **OPTIONAL** +* Required capability: `CAP_MAC_WHITELIST` Structure Parameters: @@ -139,6 +139,7 @@ Structure Parameters: ### PROP 4865: PROP_MAC_WHITELIST_ENABLED {#prop-mac-whitelist-enabled} * Type: Read-Write * Packed-Encoding: `b` +* Required capability: `CAP_MAC_WHITELIST` ### PROP 4867: SPINEL_PROP_MAC_SRC_MATCH_ENABLED {#prop-mac-src-match-enabled} * Type: Write @@ -171,3 +172,17 @@ Structure Parameters: * `E`: EUI64 address for hardware generated ACKs +### PROP 4870: PROP_MAC_BLACKLIST {#prop-mac-blacklist} +* Type: Read-Write +* Packed-Encoding: `A(T(E))` +* Required capability: `CAP_MAC_WHITELIST` + +Structure Parameters: + +* `E`: EUI64 address of node + +### PROP 4871: PROP_MAC_BLACKLIST_ENABLED {#prop-mac-blacklist-enabled} +* Type: Read-Write +* Packed-Encoding: `b` +* Required capability: `CAP_MAC_WHITELIST` + diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 6d5cd2f63..63076bc3a 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -3755,12 +3755,12 @@ otError NcpBase::GetPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop_ke SuccessOrExit(errorCode = OutboundFrameBegin()); SuccessOrExit( - errorCode = OutboundFrameFeedPacked( - SPINEL_DATATYPE_COMMAND_PROP_S, - header, - SPINEL_CMD_PROP_VALUE_IS, - key - )); + errorCode = OutboundFrameFeedPacked( + SPINEL_DATATYPE_COMMAND_PROP_S, + header, + SPINEL_CMD_PROP_VALUE_IS, + key + )); for (uint8_t i = 0; (i != 255) && (errorCode == OT_ERROR_NONE); i++) { @@ -3808,6 +3808,62 @@ otError NcpBase::GetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, spinel ); } +otError NcpBase::GetPropertyHandler_MAC_BLACKLIST(uint8_t header, spinel_prop_key_t key) +{ + otMacBlacklistEntry entry; + otError errorCode = OT_ERROR_NONE; + + mDisableStreamWrite = true; + + SuccessOrExit(errorCode = OutboundFrameBegin()); + SuccessOrExit( + errorCode = OutboundFrameFeedPacked( + SPINEL_DATATYPE_COMMAND_PROP_S, + header, + SPINEL_CMD_PROP_VALUE_IS, + key + )); + + for (uint8_t i = 0; (i != 255) && (errorCode == OT_ERROR_NONE); i++) + { + errorCode = otLinkGetBlacklistEntry(mInstance, i, &entry); + + if (errorCode != OT_ERROR_NONE) + { + break; + } + + if (entry.mValid) + { + SuccessOrExit( + errorCode = OutboundFrameFeedPacked( + SPINEL_DATATYPE_STRUCT_S( + SPINEL_DATATYPE_EUI64_S // Extended address + ), + entry.mExtAddress.m8 + )); + } + } + + SuccessOrExit(errorCode = OutboundFrameSend()); + +exit: + mDisableStreamWrite = false; + return errorCode; +} + +otError NcpBase::GetPropertyHandler_MAC_BLACKLIST_ENABLED(uint8_t header, spinel_prop_key_t key) +{ + return SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_BOOL_S, + otLinkIsBlacklistEnabled(mInstance) + ); +} + + #endif // OPENTHREAD_ENABLE_MAC_WHITELIST #if OPENTHREAD_FTD @@ -5871,6 +5927,88 @@ otError NcpBase::SetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, spinel return errorCode; } +otError NcpBase::SetPropertyHandler_MAC_BLACKLIST(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, + uint16_t value_len) +{ + otError errorCode = OT_ERROR_NONE; + spinel_ssize_t parsedLength = 1; + + // First, clear the blacklist. + otLinkClearBlacklist(mInstance); + + while ((errorCode == OT_ERROR_NONE) + && (parsedLength > 0) + && (value_len > 0) + ) + { + otExtAddress *ext_addr = NULL; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_STRUCT_S( + SPINEL_DATATYPE_EUI64_S + ), + &ext_addr + ); + + if (parsedLength <= 0) + { + errorCode = OT_ERROR_PARSE; + break; + } + + errorCode = otLinkAddBlacklist(mInstance, ext_addr->m8); + + value_ptr += parsedLength; + value_len -= parsedLength; + } + + if (errorCode == OT_ERROR_NONE) + { + errorCode = HandleCommandPropertyGet(header, key); + } + else + { + errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode)); + + // We had an error, but we may have actually changed + // the state of the blacklist---so we need to report + // those incomplete changes via an asynchronous + // change event. + HandleCommandPropertyGet(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, key); + } + + return errorCode; +} + +otError NcpBase::SetPropertyHandler_MAC_BLACKLIST_ENABLED(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len) +{ + bool isEnabled; + spinel_ssize_t parsedLength; + otError errorCode = OT_ERROR_NONE; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_BOOL_S, + &isEnabled + ); + + if (parsedLength > 0) + { + otLinkSetBlacklistEnabled(mInstance, isEnabled); + errorCode = HandleCommandPropertyGet(header, key); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + #endif // OPENTHREAD_ENABLE_MAC_WHITELIST #if OPENTHREAD_ENABLE_RAW_LINK_API @@ -7056,7 +7194,6 @@ otError NcpBase::InsertPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop otExtAddress *ext_addr = NULL; int8_t rssi = RSSI_OVERRIDE_DISABLED; - if (value_len > static_cast(sizeof(otExtAddress))) { parsedLength = spinel_datatype_unpack( @@ -7111,6 +7248,47 @@ otError NcpBase::InsertPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop return errorCode; } +otError NcpBase::InsertPropertyHandler_MAC_BLACKLIST(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len) +{ + otError errorCode = OT_ERROR_NONE; + spinel_ssize_t parsedLength; + otExtAddress *ext_addr = NULL; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_EUI64_S, + &ext_addr + ); + + if (parsedLength > 0) + { + errorCode = otLinkAddBlacklist(mInstance, ext_addr->m8); + + if (errorCode == OT_ERROR_NONE) + { + errorCode = SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_INSERTED, + key, + value_ptr, + value_len + ); + } + else + { + errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode)); + } + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + #endif // OPENTHREAD_ENABLE_MAC_WHITELIST #if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD @@ -7549,6 +7727,40 @@ otError NcpBase::RemovePropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop return errorCode; } +otError NcpBase::RemovePropertyHandler_MAC_BLACKLIST(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len) +{ + otError errorCode = OT_ERROR_NONE; + spinel_ssize_t parsedLength; + otExtAddress *ext_addr_ptr = NULL; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_EUI64_S, + &ext_addr_ptr + ); + + if (parsedLength > 0) + { + otLinkRemoveBlacklist(mInstance, ext_addr_ptr->m8); + + errorCode = SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_REMOVED, + key, + value_ptr, + value_len + ); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + #endif // OPENTHREAD_ENABLE_MAC_WHITELIST #if OPENTHREAD_ENABLE_LEGACY diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index 4fec5b90a..9ccb6b03c 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -409,6 +409,8 @@ private: #if OPENTHREAD_ENABLE_MAC_WHITELIST otError GetPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop_key_t key); otError GetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, spinel_prop_key_t key); + otError GetPropertyHandler_MAC_BLACKLIST(uint8_t header, spinel_prop_key_t key); + otError GetPropertyHandler_MAC_BLACKLIST_ENABLED(uint8_t header, spinel_prop_key_t key); #endif otError GetPropertyHandler_THREAD_MODE(uint8_t header, spinel_prop_key_t key); otError GetPropertyHandler_THREAD_CHILD_TIMEOUT(uint8_t header, spinel_prop_key_t key); @@ -523,6 +525,10 @@ private: uint16_t value_len); otError SetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); + otError SetPropertyHandler_MAC_BLACKLIST(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, + uint16_t value_len); + otError SetPropertyHandler_MAC_BLACKLIST_ENABLED(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len); #endif #if OPENTHREAD_ENABLE_RAW_LINK_API otError SetPropertyHandler_MAC_SRC_MATCH_ENABLED(uint8_t header, spinel_prop_key_t key, @@ -633,6 +639,8 @@ private: #if OPENTHREAD_ENABLE_MAC_WHITELIST otError InsertPropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); + otError InsertPropertyHandler_MAC_BLACKLIST(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, + uint16_t value_len); #endif #if OPENTHREAD_ENABLE_COMMISSIONER otError InsertPropertyHandler_THREAD_JOINERS(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, @@ -658,6 +666,8 @@ private: #if OPENTHREAD_ENABLE_MAC_WHITELIST otError RemovePropertyHandler_MAC_WHITELIST(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); + otError RemovePropertyHandler_MAC_BLACKLIST(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, + uint16_t value_len); #endif #if OPENTHREAD_FTD otError RemovePropertyHandler_THREAD_ACTIVE_ROUTER_IDS(uint8_t header, spinel_prop_key_t key, diff --git a/src/ncp/spinel.c b/src/ncp/spinel.c index 2875e2aad..260a68d54 100644 --- a/src/ncp/spinel.c +++ b/src/ncp/spinel.c @@ -1092,6 +1092,14 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES"; break; + case SPINEL_PROP_MAC_BLACKLIST: + ret = "PROP_MAC_BLACKLIST"; + break; + + case SPINEL_PROP_MAC_BLACKLIST_ENABLED: + ret = "PROP_MAC_BLACKLIST_ENABLED"; + break; + case SPINEL_PROP_NET_SAVED: ret = "PROP_NET_SAVED"; break; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index fe9e5b43a..d1335c1ff 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -668,6 +668,20 @@ typedef enum */ SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES = SPINEL_PROP_MAC_EXT__BEGIN + 5, + + /// MAC Blacklist + /** Format: `A(t(E))` + * + * Structure Parameters: + * + * * `E`: EUI64 address of node + */ + SPINEL_PROP_MAC_BLACKLIST = SPINEL_PROP_MAC_EXT__BEGIN + 6, + + /// MAC Blacklist Enabled Flag + /** Format: `b` + */ + SPINEL_PROP_MAC_BLACKLIST_ENABLED = SPINEL_PROP_MAC_EXT__BEGIN + 7, SPINEL_PROP_MAC_EXT__END = 0x1400, SPINEL_PROP_NET__BEGIN = 0x40,