From 0de5f59090d6b5ec7c81ae899bd5a278ea3a9749 Mon Sep 17 00:00:00 2001 From: Robert Quattlebaum Date: Mon, 22 Aug 2016 21:19:23 -0700 Subject: [PATCH] ncp-spinel: Added support for PROP_IPV6_ICMP_PING_OFFLOAD (#446) With this change, you can now enable or disable IPv6 ICMP ping offload. It is disabled by default. --- src/ncp/PROTOCOL.md | 10 +++++++++- src/ncp/ncp_base.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/ncp/ncp_base.hpp | 3 +++ src/ncp/spinel.c | 4 ++++ src/ncp/spinel.h | 12 ++++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/ncp/PROTOCOL.md b/src/ncp/PROTOCOL.md index a4130cd9f..f6c1d8591 100644 --- a/src/ncp/PROTOCOL.md +++ b/src/ncp/PROTOCOL.md @@ -1,7 +1,7 @@ Spinel Host Controller Interface ================================ -Updated: 2016-08-17 +Updated: 2016-08-22 Written by: Robert Quattlebaum @@ -1667,3 +1667,11 @@ Array of structures containing: * `C`: Interface ID * `C`: Flags +#### D.5.6. PROP 101: `PROP_IPv6_ICMP_PING_OFFLOAD` +* Type: Read-Write +* Packed-Encoding: `b` + +Allow the NCP to directly respond to ICMP ping requests. If this is +turned on, ping request ICMP packets will not be passed to the host. + +Default value is `false`. diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 71587d9dc..ef12978d5 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -138,6 +138,7 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] = { SPINEL_PROP_IPV6_LL_ADDR, &NcpBase::GetPropertyHandler_IPV6_LL_ADDR }, { SPINEL_PROP_IPV6_ADDRESS_TABLE, &NcpBase::GetPropertyHandler_IPV6_ADDRESS_TABLE }, { SPINEL_PROP_IPV6_ROUTE_TABLE, &NcpBase::GetPropertyHandler_IPV6_ROUTE_TABLE }, + { SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD, &NcpBase::GetPropertyHandler_IPV6_ICMP_PING_OFFLOAD }, { SPINEL_PROP_STREAM_NET, &NcpBase::GetPropertyHandler_STREAM_NET }, @@ -209,6 +210,7 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] = { SPINEL_PROP_STREAM_NET, &NcpBase::SetPropertyHandler_STREAM_NET }, { SPINEL_PROP_IPV6_ML_PREFIX, &NcpBase::SetPropertyHandler_IPV6_ML_PREFIX }, + { SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD, &NcpBase::SetPropertyHandler_IPV6_ICMP_PING_OFFLOAD }, { SPINEL_PROP_MAC_WHITELIST, &NcpBase::SetPropertyHandler_MAC_WHITELIST }, { SPINEL_PROP_MAC_WHITELIST_ENABLED, &NcpBase::SetPropertyHandler_MAC_WHITELIST_ENABLED }, @@ -1811,6 +1813,17 @@ ThreadError NcpBase::GetPropertyHandler_IPV6_ROUTE_TABLE(uint8_t header, spinel_ return SendLastStatus(header, SPINEL_STATUS_UNIMPLEMENTED); } +ThreadError NcpBase::GetPropertyHandler_IPV6_ICMP_PING_OFFLOAD(uint8_t header, spinel_prop_key_t key) +{ + return SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_BOOL_S, + otIsIcmpEchoEnabled() + ); +} + ThreadError NcpBase::GetPropertyHandler_THREAD_LOCAL_ROUTES(uint8_t header, spinel_prop_key_t key) { // TODO: Implement get external route table @@ -2933,6 +2946,33 @@ ThreadError NcpBase::SetPropertyHandler_IPV6_ML_PREFIX(uint8_t header, spinel_pr return errorCode; } +ThreadError NcpBase::SetPropertyHandler_IPV6_ICMP_PING_OFFLOAD(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) +{ + bool isEnabled(false); + spinel_ssize_t parsedLength; + ThreadError errorCode = kThreadError_None; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_BOOL_S, + &isEnabled + ); + + if (parsedLength > 0) + { + otSetIcmpEchoEnabled(isEnabled); + + errorCode = HandleCommandPropertyGet(header, key); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + ThreadError NcpBase::SetPropertyHandler_THREAD_ASSISTING_PORTS(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) { diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index 630169ed2..5a9b126d4 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -279,6 +279,7 @@ private: ThreadError GetPropertyHandler_IPV6_LL_ADDR(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_IPV6_ADDRESS_TABLE(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_IPV6_ROUTE_TABLE(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_IPV6_ICMP_PING_OFFLOAD(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_LOCAL_ROUTES(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_STREAM_NET(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_MAC_SCAN_MASK(uint8_t header, spinel_prop_key_t key); @@ -337,6 +338,8 @@ private: uint16_t value_len); ThreadError SetPropertyHandler_IPV6_ML_PREFIX(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); + ThreadError SetPropertyHandler_IPV6_ICMP_PING_OFFLOAD(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, + uint16_t value_len); ThreadError SetPropertyHandler_PHY_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_MAC_FILTER_MODE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, diff --git a/src/ncp/spinel.c b/src/ncp/spinel.c index 6678cabb4..0d9dda029 100644 --- a/src/ncp/spinel.c +++ b/src/ncp/spinel.c @@ -1082,6 +1082,10 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key) ret = "PROP_IPV6_ROUTE_TABLE"; break; + case SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD: + ret = "SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD"; + break; + case SPINEL_PROP_THREAD_PARENT: ret = "SPINEL_PROP_THREAD_PARENT"; break; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index 1512be912..073ef4a01 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -441,6 +441,18 @@ typedef enum SPINEL_PROP_IPV6_ML_PREFIX = SPINEL_PROP_IPV6__BEGIN + 2, ///< [6C] SPINEL_PROP_IPV6_ADDRESS_TABLE = SPINEL_PROP_IPV6__BEGIN + 3, ///< array(ipv6addr,prefixlen,valid,preferred,flags) [A(T(6CLLC))] SPINEL_PROP_IPV6_ROUTE_TABLE = SPINEL_PROP_IPV6__BEGIN + 4, ///< array(ipv6prefix,prefixlen,iface,flags) [A(T(6CCC))] + + + /// IPv6 ICMP Ping Offload + /** Format: `b` + * + * Allow the NCP to directly respond to ICMP ping requests. If this is + * turned on, ping request ICMP packets will not be passed to the host. + * + * Default value is `false`. + */ + SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD = SPINEL_PROP_IPV6__BEGIN + 5, + SPINEL_PROP_IPV6__END = 0x70, SPINEL_PROP_STREAM__BEGIN = 0x70,