mirror of
https://github.com/espressif/openthread.git
synced 2026-07-26 22:09:05 +00:00
Steering data. (#743)
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\core\coap\coap_header.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\coap_server.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\crc16.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\logging.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\message.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\tasklet.cpp" />
|
||||
@@ -79,6 +80,7 @@
|
||||
<ClInclude Include="..\..\src\core\coap\coap_header.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\coap_server.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\code_utils.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\crc16.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\debug.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\encoding.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\logging.hpp" />
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\core\coap\coap_header.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\coap_server.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\crc16.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\logging.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\message.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\tasklet.cpp" />
|
||||
@@ -79,6 +80,7 @@
|
||||
<ClInclude Include="..\..\src\core\coap\coap_header.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\coap_server.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\code_utils.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\crc16.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\debug.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\encoding.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\logging.hpp" />
|
||||
|
||||
+13
-12
@@ -317,6 +317,18 @@ typedef struct otIp6Address otIp6Address;
|
||||
|
||||
#define OT_CHANNEL_ALL 0xffffffff ///< All channels
|
||||
|
||||
#define OT_STEERING_DATA_MAX_LENGTH 16 ///< Max steering data length (bytes)
|
||||
|
||||
/**
|
||||
* This structure represents the steering data.
|
||||
*
|
||||
*/
|
||||
typedef struct otSteeringData
|
||||
{
|
||||
uint8_t mLength;
|
||||
uint8_t m8[OT_STEERING_DATA_MAX_LENGTH];
|
||||
} otSteeringData;
|
||||
|
||||
/**
|
||||
* This struct represents a received IEEE 802.15.4 Beacon.
|
||||
*
|
||||
@@ -326,6 +338,7 @@ typedef struct otActiveScanResult
|
||||
otExtAddress mExtAddress; ///< IEEE 802.15.4 Extended Address
|
||||
otNetworkName mNetworkName; ///< Thread Network Name
|
||||
otExtendedPanId mExtendedPanId; ///< Thread Extended PAN ID
|
||||
otSteeringData mSteeringData; ///< Steering Data
|
||||
uint16_t mPanId; ///< IEEE 802.15.4 PAN ID
|
||||
uint16_t mJoinerUdpPort; ///< Joiner UDP Port
|
||||
uint8_t mChannel; ///< IEEE 802.15.4 Channel
|
||||
@@ -404,18 +417,6 @@ typedef struct otOperationalDataset
|
||||
bool mIsChannelMaskPage0Set : 1; ///< TRUE if Channel Mask Page 0 is set, FALSE otherwise.
|
||||
} otOperationalDataset;
|
||||
|
||||
#define OT_STEERING_DATA_MAX_LENGTH 16 ///< Max steering data length (bytes)
|
||||
|
||||
/**
|
||||
* This structure represents the steering data.
|
||||
*
|
||||
*/
|
||||
typedef struct otSteeringData
|
||||
{
|
||||
uint8_t mLength;
|
||||
uint8_t m8[OT_STEERING_DATA_MAX_LENGTH];
|
||||
} otSteeringData;
|
||||
|
||||
/**
|
||||
* This structure represents a Commissioning Dataset.
|
||||
*
|
||||
|
||||
@@ -39,6 +39,7 @@ libopenthread_a_SOURCES = \
|
||||
openthread.cpp \
|
||||
coap/coap_header.cpp \
|
||||
coap/coap_server.cpp \
|
||||
common/crc16.cpp \
|
||||
common/logging.cpp \
|
||||
common/message.cpp \
|
||||
common/tasklet.cpp \
|
||||
@@ -115,6 +116,7 @@ noinst_HEADERS = \
|
||||
coap/coap_header.hpp \
|
||||
coap/coap_server.hpp \
|
||||
common/code_utils.hpp \
|
||||
common/crc16.hpp \
|
||||
common/debug.hpp \
|
||||
common/encoding.hpp \
|
||||
common/logging.hpp \
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements CRC16 computations.
|
||||
*/
|
||||
|
||||
#include <common/crc16.hpp>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
Crc16::Crc16(Polynomial aPolynomial)
|
||||
{
|
||||
mPolynomial = static_cast<uint16_t>(aPolynomial);
|
||||
Init();
|
||||
}
|
||||
|
||||
void Crc16::Init(void)
|
||||
{
|
||||
mCrc = 0xffff;
|
||||
}
|
||||
|
||||
void Crc16::Update(uint8_t aByte)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
mCrc = mCrc ^ static_cast<uint16_t>(aByte << 8);
|
||||
i = 8;
|
||||
|
||||
do
|
||||
{
|
||||
if (mCrc & 0x8000)
|
||||
{
|
||||
mCrc = static_cast<uint16_t>(mCrc << 1) ^ mPolynomial;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCrc = static_cast<uint16_t>(mCrc << 1);
|
||||
}
|
||||
}
|
||||
while (--i);
|
||||
}
|
||||
|
||||
uint16_t Crc16::Get(void) const
|
||||
{
|
||||
return mCrc;
|
||||
}
|
||||
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for CRC16 computations.
|
||||
*/
|
||||
|
||||
#ifndef CRC16_HPP_
|
||||
#define CRC16_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
/**
|
||||
* This class implements CRC16 computations.
|
||||
*
|
||||
*/
|
||||
class Crc16
|
||||
{
|
||||
public:
|
||||
enum Polynomial
|
||||
{
|
||||
kCcitt = 0x1021, ///< CRC16_CCITT
|
||||
kAnsi = 0x8005, ///< CRC16-ANSI
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aPolynomial The polynomial value.
|
||||
*
|
||||
*/
|
||||
Crc16(Polynomial aPolynomial);
|
||||
|
||||
/**
|
||||
* This method initializes the CRC16 computation.
|
||||
*
|
||||
*/
|
||||
void Init(void);
|
||||
|
||||
/*c*
|
||||
* This method feeds a byte value into the CRC16 computation.
|
||||
*
|
||||
* @param[in] aByte The byte value.
|
||||
*
|
||||
*/
|
||||
void Update(uint8_t aByte);
|
||||
|
||||
/**
|
||||
* This method gets the current CRC16 value.
|
||||
*
|
||||
* @returns The current CRC16 value.
|
||||
*
|
||||
*/
|
||||
uint16_t Get(void) const;
|
||||
|
||||
private:
|
||||
uint16_t mPolynomial;
|
||||
uint16_t mCrc;
|
||||
};
|
||||
|
||||
} // namespace Thread
|
||||
|
||||
#endif // CRC16_HPP_
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <common/crc16.hpp>
|
||||
#include <common/logging.hpp>
|
||||
#include <meshcop/commissioner.hpp>
|
||||
#include <meshcop/joiner_router.hpp>
|
||||
@@ -81,7 +82,10 @@ ThreadError Commissioner::Start(void)
|
||||
VerifyOrExit(mState == kStateDisabled, error = kThreadError_InvalidState);
|
||||
|
||||
SuccessOrExit(error = mSocket.Open(HandleUdpReceive, this));
|
||||
|
||||
mState = kStatePetition;
|
||||
mTransmitAttempts = 0;
|
||||
|
||||
SendPetition();
|
||||
|
||||
exit:
|
||||
@@ -90,10 +94,84 @@ exit:
|
||||
|
||||
ThreadError Commissioner::Stop(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(mState != kStateDisabled, error = kThreadError_InvalidState);
|
||||
|
||||
mState = kStateDisabled;
|
||||
mTransmitAttempts = 0;
|
||||
|
||||
SendKeepAlive();
|
||||
mTimer.Start(1000);
|
||||
return kThreadError_None;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Commissioner::SendCommissionerSet(void)
|
||||
{
|
||||
ThreadError error;
|
||||
otCommissioningDataset dataset;
|
||||
SteeringDataTlv steeringData;
|
||||
|
||||
VerifyOrExit(mState == kStateActive, error = kThreadError_InvalidState);
|
||||
|
||||
memset(&dataset, 0, sizeof(dataset));
|
||||
|
||||
// session id
|
||||
dataset.mSessionId = mSessionId;
|
||||
dataset.mIsSessionIdSet = true;
|
||||
|
||||
// compute bloom filter
|
||||
steeringData.Init();
|
||||
steeringData.Clear();
|
||||
|
||||
for (size_t i = 0; i < sizeof(mJoiners) / sizeof(mJoiners[0]); i++)
|
||||
{
|
||||
Crc16 ccitt(Crc16::kCcitt);
|
||||
Crc16 ansi(Crc16::kAnsi);
|
||||
|
||||
if (!mJoiners[i].mValid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mJoiners[i].mAny)
|
||||
{
|
||||
steeringData.SetLength(1);
|
||||
steeringData.Set();
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < sizeof(mJoiners[i].mExtAddress.m8); j++)
|
||||
{
|
||||
uint8_t byte = mJoiners[i].mExtAddress.m8[j];
|
||||
ccitt.Update(byte);
|
||||
ansi.Update(byte);
|
||||
}
|
||||
|
||||
steeringData.SetBit(ccitt.Get() % steeringData.GetNumBits());
|
||||
steeringData.SetBit(ansi.Get() % steeringData.GetNumBits());
|
||||
}
|
||||
|
||||
// set bloom filter
|
||||
memcpy(dataset.mSteeringData.m8, steeringData.GetValue(), steeringData.GetLength());
|
||||
dataset.mSteeringData.mLength = steeringData.GetLength();
|
||||
dataset.mIsSteeringDataSet = true;
|
||||
|
||||
SuccessOrExit(error = SendMgmtCommissionerSetRequest(dataset, NULL, 0));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Commissioner::ClearJoiners(void)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(mJoiners) / sizeof(mJoiners[0]); i++)
|
||||
{
|
||||
mJoiners[i].mValid = false;
|
||||
}
|
||||
|
||||
SendCommissionerSet();
|
||||
}
|
||||
|
||||
ThreadError Commissioner::AddJoiner(const Mac::ExtAddress *aExtAddress, const char *aPSKd)
|
||||
@@ -122,6 +200,9 @@ ThreadError Commissioner::AddJoiner(const Mac::ExtAddress *aExtAddress, const ch
|
||||
|
||||
strncpy(mJoiners[i].mPsk, aPSKd, sizeof(mJoiners[i].mPsk));
|
||||
mJoiners[i].mValid = true;
|
||||
|
||||
SendCommissionerSet();
|
||||
|
||||
ExitNow(error = kThreadError_None);
|
||||
}
|
||||
|
||||
@@ -153,6 +234,9 @@ ThreadError Commissioner::RemoveJoiner(const Mac::ExtAddress *aExtAddress)
|
||||
}
|
||||
|
||||
mJoiners[i].mValid = false;
|
||||
|
||||
SendCommissionerSet();
|
||||
|
||||
ExitNow(error = kThreadError_None);
|
||||
}
|
||||
|
||||
@@ -189,7 +273,6 @@ void Commissioner::HandleTimer(void)
|
||||
|
||||
case kStateActive:
|
||||
SendKeepAlive();
|
||||
mTimer.Start(5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -333,10 +416,19 @@ ThreadError Commissioner::SendPetition(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Coap::Header header;
|
||||
Message *message;
|
||||
Message *message = NULL;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
CommissionerIdTlv commissionerId;
|
||||
|
||||
if (mTransmitAttempts >= kPetitionRetryCount)
|
||||
{
|
||||
mState = kStateDisabled;
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
mTimer.Start(Timer::SecToMsec(kPetitionRetryDelay));
|
||||
mTransmitAttempts++;
|
||||
|
||||
for (size_t i = 0; i < sizeof(mCoapToken); i++)
|
||||
{
|
||||
mCoapToken[i] = otPlatRandomGet() & 0xff;
|
||||
@@ -379,11 +471,20 @@ ThreadError Commissioner::SendKeepAlive(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Coap::Header header;
|
||||
Message *message;
|
||||
Message *message = NULL;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
StateTlv state;
|
||||
CommissionerSessionIdTlv sessionId;
|
||||
|
||||
if (mTransmitAttempts >= kPetitionRetryCount)
|
||||
{
|
||||
mState = kStateDisabled;
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
mTimer.Start(Timer::SecToMsec(kPetitionRetryDelay));
|
||||
mTransmitAttempts++;
|
||||
|
||||
for (size_t i = 0; i < sizeof(mCoapToken); i++)
|
||||
{
|
||||
mCoapToken[i] = otPlatRandomGet() & 0xff;
|
||||
@@ -582,16 +683,19 @@ void Commissioner::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &a
|
||||
case kStatePetition:
|
||||
SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kCommissionerSessionId, sizeof(sessionId), sessionId));
|
||||
VerifyOrExit(sessionId.IsValid(), ;);
|
||||
|
||||
mSessionId = sessionId.GetCommissionerSessionId();
|
||||
mState = kStateActive;
|
||||
mTimer.Start(5000);
|
||||
|
||||
otLogInfoMeshCoP("received petition response\r\n");
|
||||
|
||||
mState = kStateActive;
|
||||
mTransmitAttempts = 0;
|
||||
mTimer.Start(Timer::SecToMsec(kKeepAliveTimeout) / 2);
|
||||
break;
|
||||
|
||||
case kStateActive:
|
||||
otLogInfoMeshCoP("received keep alive response\r\n");
|
||||
mTransmitAttempts = 0;
|
||||
mTimer.Start(Timer::SecToMsec(kKeepAliveTimeout) / 2);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,12 @@ public:
|
||||
*/
|
||||
ThreadError Stop(void);
|
||||
|
||||
/**
|
||||
* This method clears all Joiner entries.
|
||||
*
|
||||
*/
|
||||
void ClearJoiners(void);
|
||||
|
||||
/**
|
||||
* This method adds a Joiner entry.
|
||||
*
|
||||
@@ -152,6 +158,14 @@ public:
|
||||
PanIdQueryClient mPanIdQuery;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kPetitionAttemptDelay = 5, ///< COMM_PET_ATTEMPT_DELAY (seconds)
|
||||
kPetitionRetryCount = 2, ///< COMM_PET_RETRY_COUNT
|
||||
kPetitionRetryDelay = 1, ///< COMM_PET_RETRY_DELAY (seconds)
|
||||
kKeepAliveTimeout = 50, ///< TIMEOUT_COMM_PET (seconds)
|
||||
};
|
||||
|
||||
static void HandleTimer(void *aContext);
|
||||
void HandleTimer(void);
|
||||
|
||||
@@ -179,7 +193,7 @@ private:
|
||||
void SendJoinFinalizeResponse(const Coap::Header &aRequestHeader, StateTlv::State aState);
|
||||
|
||||
void SendDatasetChangedResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
ThreadError SendCommissionerSet(void);
|
||||
ThreadError SendPetition(void);
|
||||
ThreadError SendKeepAlive(void);
|
||||
|
||||
@@ -208,6 +222,7 @@ private:
|
||||
Message *mTransmitMessage;
|
||||
Timer mTimer;
|
||||
Tasklet mTransmitTask;
|
||||
uint8_t mTransmitAttempts;
|
||||
bool mSendKek;
|
||||
|
||||
Ip6::UdpSocket mSocket;
|
||||
@@ -218,7 +233,6 @@ private:
|
||||
Coap::Resource mDatasetChanged;
|
||||
Coap::Server &mCoapServer;
|
||||
ThreadNetif &mNetif;
|
||||
|
||||
bool mIsSendMgmtCommRequest;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/crc16.hpp>
|
||||
#include <common/encoding.hpp>
|
||||
#include <common/logging.hpp>
|
||||
#include <meshcop/joiner.hpp>
|
||||
@@ -102,10 +103,30 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult)
|
||||
{
|
||||
if (aResult != NULL)
|
||||
{
|
||||
mJoinerUdpPort = aResult->mJoinerUdpPort;
|
||||
mJoinerRouterPanId = aResult->mPanId;
|
||||
mJoinerRouterChannel = aResult->mChannel;
|
||||
memcpy(&mJoinerRouter, &aResult->mExtAddress, sizeof(mJoinerRouter));
|
||||
SteeringDataTlv steeringData;
|
||||
Mac::ExtAddress extAddress;
|
||||
Crc16 ccitt(Crc16::kCcitt);
|
||||
Crc16 ansi(Crc16::kAnsi);
|
||||
|
||||
mNetif.GetMac().GetHashMacAddress(&extAddress);
|
||||
|
||||
for (size_t i = 0; i < sizeof(extAddress); i++)
|
||||
{
|
||||
ccitt.Update(extAddress.m8[i]);
|
||||
ansi.Update(extAddress.m8[i]);
|
||||
}
|
||||
|
||||
steeringData.SetLength(aResult->mSteeringData.mLength);
|
||||
memcpy(steeringData.GetValue(), aResult->mSteeringData.m8, steeringData.GetLength());
|
||||
|
||||
if (steeringData.GetBit(ccitt.Get() % steeringData.GetNumBits()) &&
|
||||
steeringData.GetBit(ansi.Get() % steeringData.GetNumBits()))
|
||||
{
|
||||
mJoinerUdpPort = aResult->mJoinerUdpPort;
|
||||
mJoinerRouterPanId = aResult->mPanId;
|
||||
mJoinerRouterChannel = aResult->mChannel;
|
||||
memcpy(&mJoinerRouter, &aResult->mExtAddress, sizeof(mJoinerRouter));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -568,13 +568,27 @@ public:
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); }
|
||||
bool IsValid(void) const { return GetLength() <= sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* This method sets all bits in the Bloom Filter to zero.
|
||||
*
|
||||
*/
|
||||
void Clear(void) { memset(mSteeringData, 0, sizeof(mSteeringData)); }
|
||||
void Clear(void) { memset(mSteeringData, 0, GetLength()); }
|
||||
|
||||
/**
|
||||
* Ths method sets all bits in the Bloom Filter to one.
|
||||
*
|
||||
*/
|
||||
void Set(void) { memset(mSteeringData, 0xff, GetLength()); }
|
||||
|
||||
/**
|
||||
* This method returns the number of bits in the Bloom Filter.
|
||||
*
|
||||
* @returns The number of bits in the Bloom Filter.
|
||||
*
|
||||
*/
|
||||
uint8_t GetNumBits(void) const { return GetLength() * 8; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not bit @p aBit is set.
|
||||
@@ -585,7 +599,7 @@ public:
|
||||
* @retval FALSE If bit @p aBit is not set.
|
||||
*
|
||||
*/
|
||||
bool GetBit(uint8_t aBit) const { return (mSteeringData[aBit / 8] & (1 << (aBit % 8))) != 0; }
|
||||
bool GetBit(uint8_t aBit) const { return (mSteeringData[GetLength() - 1 - (aBit / 8)] & (1 << (aBit % 8))) != 0; }
|
||||
|
||||
/**
|
||||
* This method clears bit @p aBit.
|
||||
@@ -593,7 +607,7 @@ public:
|
||||
* @param[in] aBit The bit offset.
|
||||
*
|
||||
*/
|
||||
void ClearBit(uint8_t aBit) { mSteeringData[aBit / 8] &= ~(1 << (aBit % 8)); }
|
||||
void ClearBit(uint8_t aBit) { mSteeringData[GetLength() - 1 - (aBit / 8)] &= ~(1 << (aBit % 8)); }
|
||||
|
||||
/**
|
||||
* This method sets bit @p aBit.
|
||||
@@ -601,7 +615,7 @@ public:
|
||||
* @param[in] aBit The bit offset.
|
||||
*
|
||||
*/
|
||||
void SetBit(uint8_t aBit) { mSteeringData[aBit / 8] |= 1 << (aBit % 8); }
|
||||
void SetBit(uint8_t aBit) { mSteeringData[GetLength() - 1 - (aBit / 8)] |= 1 << (aBit % 8); }
|
||||
|
||||
private:
|
||||
uint8_t mSteeringData[OT_STEERING_DATA_MAX_LENGTH];
|
||||
|
||||
@@ -2406,6 +2406,8 @@ ThreadError Mle::SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_
|
||||
MeshCoP::ExtendedPanIdTlv extPanId;
|
||||
MeshCoP::NetworkNameTlv networkName;
|
||||
MeshCoP::JoinerUdpPortTlv joinerUdpPort;
|
||||
uint8_t *cur;
|
||||
uint8_t length;
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
@@ -2434,6 +2436,25 @@ ThreadError Mle::SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_
|
||||
networkName.SetNetworkName(mMac.GetNetworkName());
|
||||
SuccessOrExit(error = message->Append(&networkName, sizeof(tlv) + networkName.GetLength()));
|
||||
|
||||
// Steering Data TLV
|
||||
if ((cur = mNetif.GetNetworkDataLeader().GetCommissioningData(length)) != NULL)
|
||||
{
|
||||
uint8_t *end = cur + length;
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
MeshCoP::Tlv *meshcop = reinterpret_cast<MeshCoP::Tlv *>(cur);
|
||||
|
||||
if (meshcop->GetType() == MeshCoP::Tlv::kSteeringData)
|
||||
{
|
||||
SuccessOrExit(message->Append(meshcop, sizeof(*meshcop) + meshcop->GetLength()));
|
||||
break;
|
||||
}
|
||||
|
||||
cur += sizeof(*meshcop) + meshcop->GetLength();
|
||||
}
|
||||
}
|
||||
|
||||
// Joiner UDP Port TLV
|
||||
joinerUdpPort.Init();
|
||||
joinerUdpPort.SetUdpPort(mJoinerRouter.GetJoinerUdpPort());
|
||||
@@ -2465,6 +2486,7 @@ ThreadError Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::Mes
|
||||
MeshCoP::DiscoveryResponseTlv discoveryResponse;
|
||||
MeshCoP::ExtendedPanIdTlv extPanId;
|
||||
MeshCoP::NetworkNameTlv networkName;
|
||||
MeshCoP::SteeringDataTlv steeringData;
|
||||
MeshCoP::JoinerUdpPortTlv JoinerUdpPort;
|
||||
otActiveScanResult result;
|
||||
uint16_t offset;
|
||||
@@ -2528,6 +2550,13 @@ ThreadError Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::Mes
|
||||
memcpy(&result.mNetworkName, networkName.GetNetworkName(), networkName.GetLength());
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kSteeringData:
|
||||
aMessage.Read(offset, sizeof(steeringData), &steeringData);
|
||||
VerifyOrExit(steeringData.IsValid(), error = kThreadError_Parse);
|
||||
result.mSteeringData.mLength = steeringData.GetLength();
|
||||
memcpy(result.mSteeringData.m8, steeringData.GetValue(), result.mSteeringData.mLength);
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kJoinerUdpPort:
|
||||
aMessage.Read(offset, sizeof(JoinerUdpPort), &JoinerUdpPort);
|
||||
VerifyOrExit(JoinerUdpPort.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
@@ -60,7 +60,8 @@ class Cert_8_1_01_Commissioning(unittest.TestCase):
|
||||
time.sleep(5)
|
||||
self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'leader')
|
||||
self.nodes[COMMISSIONER].commissioner_start()
|
||||
self.nodes[COMMISSIONER].commissioner_add_joiner('*', 'openthread')
|
||||
time.sleep(3)
|
||||
self.nodes[COMMISSIONER].commissioner_add_joiner(self.nodes[JOINER].get_hashmacaddr(), 'openthread')
|
||||
|
||||
self.nodes[JOINER].interface_up()
|
||||
self.nodes[JOINER].joiner_start('openthread')
|
||||
|
||||
@@ -60,6 +60,7 @@ class Cert_8_1_02_Commissioning(unittest.TestCase):
|
||||
time.sleep(5)
|
||||
self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'leader')
|
||||
self.nodes[COMMISSIONER].commissioner_start()
|
||||
time.sleep(3)
|
||||
self.nodes[COMMISSIONER].commissioner_add_joiner(self.nodes[JOINER].get_hashmacaddr(), 'openthread')
|
||||
|
||||
self.nodes[JOINER].interface_up()
|
||||
|
||||
Reference in New Issue
Block a user