diff --git a/src/ncp/ncp_base.hpp b/src/ncp/ncp_base.hpp index 0a248b90a..105cbf724 100644 --- a/src/ncp/ncp_base.hpp +++ b/src/ncp/ncp_base.hpp @@ -322,6 +322,8 @@ protected: const otIp6Address ** aDestIpAddress = NULL, bool aAllowEmptyValues = false); + otError EncodeNeighborInfo(const otNeighborInfo &aNeighborInfo); + #if OPENTHREAD_FTD otError EncodeChildInfo(const otChildInfo &aChildInfo); #endif diff --git a/src/ncp/ncp_base_ftd.cpp b/src/ncp/ncp_base_ftd.cpp index 2a8a7ad5f..28cc73d28 100644 --- a/src/ncp/ncp_base_ftd.cpp +++ b/src/ncp/ncp_base_ftd.cpp @@ -122,30 +122,44 @@ void NcpBase::HandleNeighborTableChanged(otNeighborTableEvent aEvent, const otNe void NcpBase::HandleNeighborTableChanged(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo &aEntry) { - otError error = OT_ERROR_NONE; - uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0; - unsigned int command = 0; - - VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(SPINEL_PROP_THREAD_CHILD_TABLE)); - - VerifyOrExit(!aEntry.mInfo.mChild.mIsStateRestoring); + otError error = OT_ERROR_NONE; + unsigned int command = SPINEL_CMD_PROP_VALUE_REMOVED; + spinel_prop_key_t property; switch (aEvent) { case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED: command = SPINEL_CMD_PROP_VALUE_INSERTED; + // Fall through + case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED: + property = SPINEL_PROP_THREAD_CHILD_TABLE; + VerifyOrExit(!aEntry.mInfo.mChild.mIsStateRestoring); break; - case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED: - command = SPINEL_CMD_PROP_VALUE_REMOVED; + case OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED: + command = SPINEL_CMD_PROP_VALUE_INSERTED; + // Fall through + case OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED: + property = SPINEL_PROP_THREAD_NEIGHBOR_TABLE; break; default: ExitNow(); } - SuccessOrExit(error = mEncoder.BeginFrame(header, command, SPINEL_PROP_THREAD_CHILD_TABLE)); - SuccessOrExit(error = EncodeChildInfo(aEntry.mInfo.mChild)); + VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(property)); + + SuccessOrExit(error = mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, command, property)); + + if (property == SPINEL_PROP_THREAD_CHILD_TABLE) + { + SuccessOrExit(error = EncodeChildInfo(aEntry.mInfo.mChild)); + } + else + { + SuccessOrExit(error = EncodeNeighborInfo(aEntry.mInfo.mRouter)); + } + SuccessOrExit(error = mEncoder.EndFrame()); exit: @@ -158,7 +172,10 @@ exit: if (error != OT_ERROR_NONE) { - mShouldEmitChildTableUpdate = true; + if (property == SPINEL_PROP_THREAD_CHILD_TABLE) + { + mShouldEmitChildTableUpdate = true; + } mChangedPropsSet.AddLastStatus(SPINEL_STATUS_NOMEM); mUpdateChangedPropsTask.Post(); diff --git a/src/ncp/ncp_base_mtd.cpp b/src/ncp/ncp_base_mtd.cpp index 6ba02bd33..3256984be 100644 --- a/src/ncp/ncp_base_mtd.cpp +++ b/src/ncp/ncp_base_mtd.cpp @@ -163,6 +163,33 @@ uint8_t NcpBase::LinkFlagsToFlagByte(bool aRxOnWhenIdle, bool aSecureDataRequest return flags; } +otError NcpBase::EncodeNeighborInfo(const otNeighborInfo &aNeighborInfo) +{ + otError error; + uint8_t modeFlags; + + modeFlags = LinkFlagsToFlagByte(aNeighborInfo.mRxOnWhenIdle, aNeighborInfo.mSecureDataRequest, + aNeighborInfo.mFullThreadDevice, aNeighborInfo.mFullNetworkData); + + SuccessOrExit(error = mEncoder.OpenStruct()); + + SuccessOrExit(error = mEncoder.WriteEui64(aNeighborInfo.mExtAddress)); + SuccessOrExit(error = mEncoder.WriteUint16(aNeighborInfo.mRloc16)); + SuccessOrExit(error = mEncoder.WriteUint32(aNeighborInfo.mAge)); + SuccessOrExit(error = mEncoder.WriteUint8(aNeighborInfo.mLinkQualityIn)); + SuccessOrExit(error = mEncoder.WriteInt8(aNeighborInfo.mAverageRssi)); + SuccessOrExit(error = mEncoder.WriteUint8(modeFlags)); + SuccessOrExit(error = mEncoder.WriteBool(aNeighborInfo.mIsChild)); + SuccessOrExit(error = mEncoder.WriteUint32(aNeighborInfo.mLinkFrameCounter)); + SuccessOrExit(error = mEncoder.WriteUint32(aNeighborInfo.mMleFrameCounter)); + SuccessOrExit(error = mEncoder.WriteInt8(aNeighborInfo.mLastRssi)); + + SuccessOrExit(error = mEncoder.CloseStruct()); + +exit: + return error; +} + template <> otError NcpBase::HandlePropertyGet(void) { return mEncoder.WriteUint32(otLinkGetPollPeriod(mInstance)); @@ -577,27 +604,10 @@ template <> otError NcpBase::HandlePropertyGet