diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 40a0b9082..5c9bc9d4e 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -183,12 +183,16 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] = { SPINEL_PROP_IPV6_ROUTE_TABLE, &NcpBase::GetPropertyHandler_IPV6_ROUTE_TABLE }, { SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD, &NcpBase::GetPropertyHandler_IPV6_ICMP_PING_OFFLOAD }, { SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU, &NcpBase::GetPropertyHandler_THREAD_RLOC16_DEBUG_PASSTHRU }, + { SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG, &NcpBase::GetPropertyHandler_THREAD_DISCOVERY_SCAN_JOINER_FLAG }, + { SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING, + &NcpBase::GetPropertyHandler_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING }, + { SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID, &NcpBase::GetPropertyHandler_THREAD_DISCOVERY_SCAN_PANID }, { SPINEL_PROP_STREAM_NET, &NcpBase::GetPropertyHandler_STREAM_NET }, #if OPENTHREAD_FTD { SPINEL_PROP_THREAD_CHILD_TABLE, &NcpBase::GetPropertyHandler_THREAD_CHILD_TABLE }, - { SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT, &NcpBase::GetPropertyHandler_THREAD_LOCAL_LEADER_WEIGHT }, + { SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT, &NcpBase::GetPropertyHandler_THREAD_LOCAL_LEADER_WEIGHT }, { SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED, &NcpBase::GetPropertyHandler_THREAD_ROUTER_ROLE_ENABLED }, { SPINEL_PROP_NET_PSKC, &NcpBase::GetPropertyHandler_NET_PSKC }, { SPINEL_PROP_THREAD_CHILD_COUNT_MAX, &NcpBase::GetPropertyHandler_THREAD_CHILD_COUNT_MAX }, @@ -312,6 +316,11 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] = { SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING, &NcpBase::SetPropertyHandler_NET_REQUIRE_JOIN_EXISTING }, { SPINEL_PROP_DEBUG_NCP_LOG_LEVEL, &NcpBase::SetPropertyHandler_DEBUG_NCP_LOG_LEVEL }, + { SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG, &NcpBase::SetPropertyHandler_THREAD_DISCOVERY_SCAN_JOINER_FLAG }, + { SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING, + &NcpBase::SetPropertyHandler_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING }, + { SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID, &NcpBase::SetPropertyHandler_THREAD_DISCOVERY_SCAN_PANID }, + #if OPENTHREAD_FTD { SPINEL_PROP_NET_PSKC, &NcpBase::SetPropertyHandler_NET_PSKC }, { SPINEL_PROP_THREAD_CHILD_TIMEOUT, &NcpBase::SetPropertyHandler_THREAD_CHILD_TIMEOUT }, @@ -325,7 +334,10 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] = { SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY, &NcpBase::SetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY }, { SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER, &NcpBase::SetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER }, { SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID, &NcpBase::SetPropertyHandler_THREAD_PREFERRED_ROUTER_ID }, -#endif +#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB + { SPINEL_PROP_THREAD_STEERING_DATA, &NcpBase::SetPropertyHandler_THREAD_THREAD_STEERING_DATA }, +#endif // #if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB +#endif // #if OPENTHREAD_FTD #if OPENTHREAD_ENABLE_JAM_DETECTION { SPINEL_PROP_JAM_DETECT_ENABLE, &NcpBase::SetPropertyHandler_JAM_DETECT_ENABLE }, @@ -548,6 +560,9 @@ NcpBase::NcpBase(otInstance *aInstance): mSupportedChannelMask(kPhySupportedChannelMask), mChannelMask(kPhySupportedChannelMask), mScanPeriod(200), // ms + mDiscoveryScanJoinerFlag(false), + mDiscoveryScanEnableFiltering(false), + mDiscoveryScanPanId(0xffff), mUpdateChangedPropsTask(aInstance->mIp6.mTaskletScheduler, &NcpBase::UpdateChangedProps, this), mChangedFlags(NCP_PLAT_RESET_REASON), mShouldSignalEndOfScan(false), @@ -818,42 +833,45 @@ void NcpBase::HandleActiveScanResult_Jump(otActiveScanResult *aResult, void *aCo static_cast(aContext)->HandleActiveScanResult(aResult); } -void NcpBase::HandleActiveScanResult(otActiveScanResult *result) +void NcpBase::HandleActiveScanResult(otActiveScanResult *aResult) { ThreadError errorCode; - if (result) + if (aResult) { - uint8_t flags = static_cast(result->mVersion << SPINEL_BEACON_THREAD_FLAG_VERSION_SHIFT); + uint8_t flags = static_cast(aResult->mVersion << SPINEL_BEACON_THREAD_FLAG_VERSION_SHIFT); - if (result->mIsJoinable) + if (aResult->mIsJoinable) { flags |= SPINEL_BEACON_THREAD_FLAG_JOINABLE; } - if (result->mIsNative) + if (aResult->mIsNative) { flags |= SPINEL_BEACON_THREAD_FLAG_NATIVE; } - NcpBase::SendPropertyUpdate( + SendPropertyUpdate( SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_INSERTED, SPINEL_PROP_MAC_SCAN_BEACON, SPINEL_DATATYPE_MAC_SCAN_RESULT_S( SPINEL_802_15_4_DATATYPE_MAC_SCAN_RESULT_V1_S, - SPINEL_NET_DATATYPE_MAC_SCAN_RESULT_V1_S + SPINEL_NET_DATATYPE_MAC_SCAN_RESULT_V2_S ), - result->mChannel, - result->mRssi, - result->mExtAddress.m8, // laddr - 0xFFFF, // saddr, Not given - result->mPanId, - result->mLqi, - SPINEL_PROTOCOL_TYPE_THREAD, - flags, - result->mNetworkName.m8, - result->mExtendedPanId.m8, OT_EXT_PAN_ID_SIZE + aResult->mChannel, // Channel + aResult->mRssi, // RSSI + // "mac-layer data" + aResult->mExtAddress.m8, // laddr + 0xFFFF, // saddr, not given + aResult->mPanId, // panid + aResult->mLqi, // lqi + // "net-layer data" + SPINEL_PROTOCOL_TYPE_THREAD, // type + flags, // flags + aResult->mNetworkName.m8, // network name + aResult->mExtendedPanId.m8, OT_EXT_PAN_ID_SIZE, // xpanid + aResult->mSteeringData.m8, aResult->mSteeringData.mLength // steering data ); } else @@ -868,7 +886,7 @@ void NcpBase::HandleActiveScanResult(otActiveScanResult *result) SPINEL_SCAN_STATE_IDLE ); - // If we could not send the end of scan inidciator message now (no + // If we could not send the end of scan indicator message now (no // buffer space), we set `mShouldSignalEndOfScan` to true to send // it out when buffer space becomes available. if (errorCode != kThreadError_None) @@ -1850,6 +1868,10 @@ ThreadError NcpBase::GetPropertyHandler_CAPS(uint8_t header, spinel_prop_key_t k SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_JAM_DETECT)); #endif +#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB + SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_OOB_STEERING_DATA)); +#endif + // TODO: Somehow get the following capability from the radio. SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_802_15_4_2450MHZ_OQPSK)); @@ -2060,6 +2082,16 @@ ThreadError NcpBase::GetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_pr SPINEL_SCAN_STATE_ENERGY ); } + else if (otThreadIsDiscoverInProgress(mInstance)) + { + errorCode = SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_UINT8_S, + SPINEL_SCAN_STATE_DISCOVER + ); + } else { errorCode = SendPropertyUpdate( @@ -2777,6 +2809,38 @@ exit: return errorCode; } +ThreadError NcpBase::GetPropertyHandler_THREAD_DISCOVERY_SCAN_JOINER_FLAG(uint8_t header, spinel_prop_key_t key) +{ + return SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_BOOL_S, + mDiscoveryScanJoinerFlag + ); +} + +ThreadError NcpBase::GetPropertyHandler_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING(uint8_t header, spinel_prop_key_t key) +{ + return SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_BOOL_S, + mDiscoveryScanEnableFiltering + ); +} + +ThreadError NcpBase::GetPropertyHandler_THREAD_DISCOVERY_SCAN_PANID(uint8_t header, spinel_prop_key_t key) +{ + return SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_UINT16_S, + mDiscoveryScanPanId + ); +} ThreadError NcpBase::GetPropertyHandler_IPV6_ML_PREFIX(uint8_t header, spinel_prop_key_t key) { @@ -2905,7 +2969,7 @@ ThreadError NcpBase::GetPropertyHandler_THREAD_RLOC16_DEBUG_PASSTHRU(uint8_t hea SPINEL_CMD_PROP_VALUE_IS, key, SPINEL_DATATYPE_BOOL_S, - !otIp6IsReceiveFilterEnabled(mInstance) + !otIp6IsReceiveFilterEnabled(mInstance) ); } @@ -3857,7 +3921,7 @@ uint8_t IndexOfMSB(uint32_t aValue) ThreadError NcpBase::SetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) { - uint8_t i = 0; + uint8_t state = 0; spinel_ssize_t parsedLength; ThreadError errorCode = kThreadError_None; @@ -3865,12 +3929,12 @@ ThreadError NcpBase::SetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_pr value_ptr, value_len, SPINEL_DATATYPE_UINT8_S, - &i + &state ); if (parsedLength > 0) { - switch (i) + switch (state) { case SPINEL_SCAN_STATE_IDLE: errorCode = kThreadError_None; @@ -3950,6 +4014,25 @@ ThreadError NcpBase::SetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_pr break; + case SPINEL_SCAN_STATE_DISCOVER: + + errorCode = otThreadDiscover( + mInstance, + mChannelMask, + mDiscoveryScanPanId, + mDiscoveryScanJoinerFlag, + mDiscoveryScanEnableFiltering, + &HandleActiveScanResult_Jump, + this + ); + + if (errorCode == kThreadError_None) + { + mShouldSignalEndOfScan = false; + } + + break; + default: errorCode = kThreadError_InvalidArgs; break; @@ -4210,7 +4293,7 @@ ThreadError NcpBase::SetPropertyHandler_NET_IF_UP(uint8_t header, spinel_prop_ke if (parsedLength > 0) { - errorCode = otIp6SetEnabled(mInstance, value); + errorCode = otIp6SetEnabled(mInstance, value); } else { @@ -4843,6 +4926,91 @@ ThreadError NcpBase::SetPropertyHandler_THREAD_RLOC16_DEBUG_PASSTHRU(uint8_t hea return errorCode; } +ThreadError NcpBase::SetPropertyHandler_THREAD_DISCOVERY_SCAN_JOINER_FLAG(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len) +{ + bool joinerFlag = false; + spinel_ssize_t parsedLength; + ThreadError errorCode = kThreadError_None; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_BOOL_S, + &joinerFlag + ); + + if (parsedLength > 0) + { + mDiscoveryScanJoinerFlag = joinerFlag; + + errorCode = HandleCommandPropertyGet(header, key); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + +ThreadError NcpBase::SetPropertyHandler_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING(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) + { + mDiscoveryScanEnableFiltering = isEnabled; + + errorCode = HandleCommandPropertyGet(header, key); + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + +ThreadError NcpBase::SetPropertyHandler_THREAD_DISCOVERY_SCAN_PANID(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len) +{ + uint16_t panid; + spinel_ssize_t parsedLength; + ThreadError errorCode = kThreadError_None; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_UINT16_S, + &panid + ); + + if (parsedLength > 0) + { + mDiscoveryScanPanId = panid; + + 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) { @@ -4992,7 +5160,53 @@ ThreadError NcpBase::SetPropertyHandler_THREAD_ROUTER_ROLE_ENABLED(uint8_t heade return errorCode; } -#endif // OPENTHREAD_FTD + +#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB + +ThreadError NcpBase::SetPropertyHandler_THREAD_THREAD_STEERING_DATA(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len) +{ + otExtAddress *extAddress; + spinel_ssize_t parsedLength; + ThreadError errorCode = kThreadError_None; + + parsedLength = spinel_datatype_unpack( + value_ptr, + value_len, + SPINEL_DATATYPE_EUI64_S, + &extAddress + ); + + if (parsedLength > 0) + { + errorCode = otThreadSetSteeringData(mInstance, extAddress); + + if (errorCode == kThreadError_None) + { + errorCode = SendPropertyUpdate( + header, + SPINEL_CMD_PROP_VALUE_IS, + key, + SPINEL_DATATYPE_EUI64_S, + extAddress->m8 + ); + } + else + { + errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode)); + } + } + else + { + errorCode = SendLastStatus(header, SPINEL_STATUS_PARSE_ERROR); + } + + return errorCode; +} + +#endif // #if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB + +#endif // #if OPENTHREAD_FTD ThreadError NcpBase::SetPropertyHandler_CNTR_RESET(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len) @@ -5163,7 +5377,7 @@ ThreadError NcpBase::SetPropertyHandler_MAC_WHITELIST_ENABLED(uint8_t header, sp if (parsedLength > 0) { - otLinkSetWhitelistEnabled(mInstance, isEnabled); + otLinkSetWhitelistEnabled(mInstance, isEnabled); errorCode = HandleCommandPropertyGet(header, key); } else diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index cf142b8e6..716110c66 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -397,6 +397,9 @@ private: ThreadError GetPropertyHandler_NET_REQUIRE_JOIN_EXISTING(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_DEBUG_TEST_ASSERT(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_DEBUG_NCP_LOG_LEVEL(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_THREAD_DISCOVERY_SCAN_JOINER_FLAG(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING(uint8_t header, spinel_prop_key_t key); + ThreadError GetPropertyHandler_THREAD_DISCOVERY_SCAN_PANID(uint8_t header, spinel_prop_key_t key); #if OPENTHREAD_FTD ThreadError GetPropertyHandler_THREAD_CHILD_TABLE(uint8_t header, spinel_prop_key_t key); @@ -409,13 +412,14 @@ private: ThreadError GetPropertyHandler_THREAD_ROUTER_SELECTION_JITTER(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_CONTEXT_REUSE_DELAY(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT(uint8_t header, spinel_prop_key_t key); -#endif +#endif // #if OPENTHREAD_FTD #if OPENTHREAD_ENABLE_COMMISSIONER ThreadError GetPropertyHandler_THREAD_COMMISSIONER_ENABLED(uint8_t header, spinel_prop_key_t key); #endif ThreadError GetPropertyHandler_BA_PROXY_ENABLED(uint8_t header, spinel_prop_key_t key); + #if OPENTHREAD_ENABLE_JAM_DETECTION ThreadError GetPropertyHandler_JAM_DETECT_ENABLE(uint8_t header, spinel_prop_key_t key); ThreadError GetPropertyHandler_JAM_DETECTED(uint8_t header, spinel_prop_key_t key); @@ -534,8 +538,19 @@ private: const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_THREAD_ROUTER_ROLE_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); +#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB + ThreadError SetPropertyHandler_THREAD_THREAD_STEERING_DATA(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len); #endif +#endif // #if OPENTHREAD_FTD + + ThreadError SetPropertyHandler_THREAD_DISCOVERY_SCAN_JOINER_FLAG(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len); + ThreadError SetPropertyHandler_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len); + ThreadError SetPropertyHandler_THREAD_DISCOVERY_SCAN_PANID(uint8_t header, spinel_prop_key_t key, + const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_THREAD_ASSISTING_PORTS(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr, uint16_t value_len); ThreadError SetPropertyHandler_NET_REQUIRE_JOIN_EXISTING(uint8_t header, spinel_prop_key_t key, @@ -639,6 +654,9 @@ private: uint32_t mSupportedChannelMask; uint32_t mChannelMask; uint16_t mScanPeriod; + bool mDiscoveryScanJoinerFlag; + bool mDiscoveryScanEnableFiltering; + uint16_t mDiscoveryScanPanId; Tasklet mUpdateChangedPropsTask; uint32_t mChangedFlags; bool mShouldSignalEndOfScan; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index b9d4a75a2..b40988095 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -1313,6 +1313,11 @@ typedef char spinel_datatype_t; SPINEL_DATATYPE_UTF8_S /* network name */ \ SPINEL_DATATYPE_DATA_WLEN_S /* xpanid */ +#define SPINEL_NET_DATATYPE_MAC_SCAN_RESULT_V2_S \ + SPINEL_NET_DATATYPE_MAC_SCAN_RESULT_V1_S \ + SPINEL_DATATYPE_DATA_WLEN_S /* steering data */ + + #define SPINEL_MAX_UINT_PACKED 2097151 SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_pack(uint8_t *data_out, spinel_size_t data_len,