mirror of
https://github.com/espressif/openthread.git
synced 2026-07-13 15:44:10 +00:00
Merge pull request #507 from jwhui/pr/remove-globals
Remove global variables from core.
This commit is contained in:
+9
-1
@@ -428,6 +428,11 @@ AM_CONDITIONAL([OPENTHREAD_ENABLE_NCP], [test "${enable_ncp}" != "no"])
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_NCP_SPI], [test "${enable_ncp}" = "spi"])
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_NCP_UART], [test "${enable_ncp}" = "uart"])
|
||||
|
||||
MBEDTLS_CPPFLAGS="-I\${abs_top_srcdir}/third_party/mbedtls"
|
||||
MBEDTLS_CPPFLAGS="${MBEDTLS_CPPFLAGS} -I\${abs_top_srcdir}/third_party/mbedtls/repo/include"
|
||||
MBEDTLS_CPPFLAGS="${MBEDTLS_CPPFLAGS} -I\${abs_top_srcdir}/third_party/mbedtls/repo/include/mbedtls"
|
||||
MBEDTLS_CPPFLAGS="${MBEDTLS_CPPFLAGS} -DMBEDTLS_CONFIG_FILE=\\\"mbedtls-config.h\\\""
|
||||
|
||||
#
|
||||
# Diagnostics Library
|
||||
#
|
||||
@@ -602,6 +607,10 @@ if test "${ac_no_link}" != "yes"; then
|
||||
AC_CHECK_FUNCS([memcpy])
|
||||
fi
|
||||
|
||||
# Add any mbedtls CPPFLAGS
|
||||
|
||||
CPPFLAGS="${CPPFLAGS} ${MBEDTLS_CPPFLAGS}"
|
||||
|
||||
# Add any code coverage CPPFLAGS and LDFLAGS
|
||||
|
||||
CPPFLAGS="${CPPFLAGS} ${NL_COVERAGE_CPPFLAGS}"
|
||||
@@ -620,7 +629,6 @@ AC_CONFIG_FILES([
|
||||
Makefile
|
||||
include/Makefile
|
||||
include/cli/Makefile
|
||||
include/crypto/Makefile
|
||||
include/ncp/Makefile
|
||||
include/platform/Makefile
|
||||
src/Makefile
|
||||
|
||||
@@ -32,7 +32,6 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
cli \
|
||||
crypto \
|
||||
ncp \
|
||||
platform \
|
||||
$(NULL)
|
||||
@@ -41,7 +40,6 @@ DIST_SUBDIRS = \
|
||||
|
||||
SUBDIRS = \
|
||||
cli \
|
||||
crypto \
|
||||
ncp \
|
||||
platform \
|
||||
$(NULL)
|
||||
@@ -50,7 +48,6 @@ SUBDIRS = \
|
||||
|
||||
PRETTY_SUBDIRS = \
|
||||
cli \
|
||||
crypto \
|
||||
ncp \
|
||||
platform \
|
||||
$(NULL)
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016, Nest Labs, Inc.
|
||||
# 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.
|
||||
#
|
||||
|
||||
include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
|
||||
|
||||
ot_crypto_headers = \
|
||||
aes_ecb.h \
|
||||
hmac_sha256.h \
|
||||
$(NULL)
|
||||
|
||||
ot_cryptodir = $(includedir)/crypto
|
||||
dist_ot_crypto_HEADERS = $(ot_crypto_headers)
|
||||
|
||||
install-headers: install-includeHEADERS
|
||||
|
||||
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
|
||||
@@ -750,7 +750,8 @@ typedef struct otUdpSocket
|
||||
otSockAddr mPeerName; ///< The peer IPv6 socket address.
|
||||
otUdpReceive mHandler; ///< A function pointer to the application callback.
|
||||
void *mContext; ///< A pointer to application-specific context.
|
||||
struct otUdpSocket *mNext; ///< A pointer to the next UDP socket.
|
||||
void *mTransport; ///< A pointer to the transport object (internal use only).
|
||||
struct otUdpSocket *mNext; ///< A pointer to the next UDP socket (internal use only).
|
||||
} otUdpSocket;
|
||||
|
||||
/**
|
||||
|
||||
+9
-5
@@ -42,6 +42,7 @@
|
||||
#include "cli_dataset.hpp"
|
||||
#include <common/encoding.hpp>
|
||||
#include <common/new.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <platform/random.h>
|
||||
#include <platform/uart.h>
|
||||
|
||||
@@ -49,6 +50,9 @@ using Thread::Encoding::BigEndian::HostSwap16;
|
||||
using Thread::Encoding::BigEndian::HostSwap32;
|
||||
|
||||
namespace Thread {
|
||||
|
||||
extern Ip6::Ip6 *sIp6;
|
||||
|
||||
namespace Cli {
|
||||
|
||||
const struct Command Interpreter::sCommands[] =
|
||||
@@ -116,8 +120,8 @@ static otNetifAddress sAutoAddresses[8];
|
||||
|
||||
void Interpreter::Init(void)
|
||||
{
|
||||
Ip6::Icmp::SetEchoReplyHandler(&HandleEchoResponse, NULL);
|
||||
sPingTimer = new(&sPingTimerBuf) Timer(&HandlePingTimer, NULL);
|
||||
sIp6->mIcmp.SetEchoReplyHandler(&HandleEchoResponse, NULL);
|
||||
sPingTimer = new(&sPingTimerBuf) Timer(sIp6->mTimerScheduler, &HandlePingTimer, NULL);
|
||||
sLength = 8;
|
||||
sCount = 1;
|
||||
sInterval = 1000;
|
||||
@@ -1045,18 +1049,18 @@ void Interpreter::HandlePingTimer(void *aContext)
|
||||
uint32_t timestamp = HostSwap32(Timer::GetNow());
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Icmp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = sIp6->mIcmp.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(×tamp, sizeof(timestamp)));
|
||||
SuccessOrExit(error = message->SetLength(sLength));
|
||||
|
||||
SuccessOrExit(error = Ip6::Icmp::SendEchoRequest(*message, sMessageInfo));
|
||||
SuccessOrExit(error = sIp6->mIcmp.SendEchoRequest(*message, sMessageInfo));
|
||||
sCount--;
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
if (sCount)
|
||||
|
||||
@@ -30,7 +30,7 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
|
||||
|
||||
lib_LIBRARIES = libopenthread.a
|
||||
|
||||
libopenthread_a_CPPFLAGS = \
|
||||
libopenthread_a_CPPFLAGS = \
|
||||
-I$(top_srcdir)/include \
|
||||
$(OPENTHREAD_TARGET_DEFINES) \
|
||||
$(NULL)
|
||||
@@ -44,6 +44,9 @@ libopenthread_a_SOURCES = \
|
||||
common/tasklet.cpp \
|
||||
common/timer.cpp \
|
||||
crypto/aes_ccm.cpp \
|
||||
crypto/aes_ecb.cpp \
|
||||
crypto/hmac_sha256.cpp \
|
||||
crypto/mbedtls.cpp \
|
||||
mac/mac.cpp \
|
||||
mac/mac_frame.cpp \
|
||||
mac/mac_whitelist.cpp \
|
||||
@@ -88,6 +91,9 @@ noinst_HEADERS = \
|
||||
common/tasklet.hpp \
|
||||
common/timer.hpp \
|
||||
crypto/aes_ccm.hpp \
|
||||
crypto/aes_ecb.hpp \
|
||||
crypto/hmac_sha256.hpp \
|
||||
crypto/mbedtls.hpp \
|
||||
mac/mac.hpp \
|
||||
mac/mac_frame.hpp \
|
||||
mac/mac_whitelist.hpp \
|
||||
@@ -95,6 +101,7 @@ noinst_HEADERS = \
|
||||
net/icmp6.hpp \
|
||||
net/ip6.hpp \
|
||||
net/ip6_address.hpp \
|
||||
net/ip6_headers.hpp \
|
||||
net/ip6_filter.hpp \
|
||||
net/ip6_mpl.hpp \
|
||||
net/ip6_routes.hpp \
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
namespace Thread {
|
||||
namespace Coap {
|
||||
|
||||
Server::Server(uint16_t aPort)
|
||||
Server::Server(Ip6::Udp &aUdp, uint16_t aPort):
|
||||
mSocket(aUdp)
|
||||
{
|
||||
mPort = aPort;
|
||||
mResources = NULL;
|
||||
@@ -131,6 +132,11 @@ exit:
|
||||
{}
|
||||
}
|
||||
|
||||
Message *Server::NewMessage(uint16_t aReserved)
|
||||
{
|
||||
return mSocket.NewMessage(aReserved);
|
||||
}
|
||||
|
||||
ThreadError Server::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return mSocket.SendTo(aMessage, aMessageInfo);
|
||||
|
||||
@@ -104,8 +104,11 @@ public:
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aUdp A reference to the UDP object.
|
||||
* @param[in] aPort The port to listen on.
|
||||
*
|
||||
*/
|
||||
explicit Server(uint16_t aPort);
|
||||
Server(Ip6::Udp &aUdp, uint16_t aPort);
|
||||
|
||||
/**
|
||||
* This method starts the CoAP server.
|
||||
@@ -134,6 +137,16 @@ public:
|
||||
*/
|
||||
ThreadError AddResource(Resource &aResource);
|
||||
|
||||
/**
|
||||
* This method returns a new UDP message with sufficient header space reserved.
|
||||
*
|
||||
* @param[in] aReserved The number of header bytes to reserve after the UDP header.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if no buffers are available.
|
||||
*
|
||||
*/
|
||||
Message *NewMessage(uint16_t aReserved);
|
||||
|
||||
/**
|
||||
* This method sends a CoAP response from the server.
|
||||
*
|
||||
|
||||
+64
-65
@@ -38,88 +38,82 @@
|
||||
|
||||
namespace Thread {
|
||||
|
||||
static Buffer *NewBuffer(void);
|
||||
static ThreadError FreeBuffers(Buffer *aBuffer);
|
||||
static ThreadError ReclaimBuffers(int aNumBuffers);
|
||||
MessagePool::MessagePool(void)
|
||||
{
|
||||
mFreeBuffers = mBuffers;
|
||||
|
||||
static int sNumFreeBuffers;
|
||||
static Buffer sBuffers[kNumBuffers];
|
||||
static Buffer *sFreeBuffers;
|
||||
static MessageList sAll;
|
||||
for (int i = 0; i < kNumBuffers - 1; i++)
|
||||
{
|
||||
mBuffers[i].SetNextBuffer(&mBuffers[i + 1]);
|
||||
}
|
||||
|
||||
Buffer *NewBuffer(void)
|
||||
mBuffers[kNumBuffers - 1].SetNextBuffer(NULL);
|
||||
mNumFreeBuffers = kNumBuffers;
|
||||
}
|
||||
|
||||
Message *MessagePool::New(uint8_t aType, uint16_t aReserved)
|
||||
{
|
||||
Message *message = NULL;
|
||||
|
||||
VerifyOrExit((message = static_cast<Message *>(NewBuffer())) != NULL, ;);
|
||||
|
||||
memset(message, 0, sizeof(*message));
|
||||
message->SetMessagePool(this);
|
||||
message->SetType(aType);
|
||||
message->SetReserved(aReserved);
|
||||
message->SetLinkSecurityEnabled(true);
|
||||
|
||||
if (message->SetLength(0) != kThreadError_None)
|
||||
{
|
||||
Free(message);
|
||||
message = NULL;
|
||||
}
|
||||
|
||||
exit:
|
||||
return message;
|
||||
}
|
||||
|
||||
ThreadError MessagePool::Free(Message *aMessage)
|
||||
{
|
||||
assert(aMessage->GetMessageList(MessageInfo::kListAll).mList == NULL &&
|
||||
aMessage->GetMessageList(MessageInfo::kListInterface).mList == NULL);
|
||||
return FreeBuffers(static_cast<Buffer *>(aMessage));
|
||||
}
|
||||
|
||||
Buffer *MessagePool::NewBuffer(void)
|
||||
{
|
||||
Buffer *buffer = NULL;
|
||||
|
||||
VerifyOrExit(sFreeBuffers != NULL, ;);
|
||||
VerifyOrExit(mFreeBuffers != NULL, ;);
|
||||
|
||||
buffer = sFreeBuffers;
|
||||
sFreeBuffers = sFreeBuffers->GetNextBuffer();
|
||||
buffer = mFreeBuffers;
|
||||
mFreeBuffers = mFreeBuffers->GetNextBuffer();
|
||||
buffer->SetNextBuffer(NULL);
|
||||
sNumFreeBuffers--;
|
||||
mNumFreeBuffers--;
|
||||
|
||||
exit:
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ThreadError FreeBuffers(Buffer *aBuffer)
|
||||
ThreadError MessagePool::FreeBuffers(Buffer *aBuffer)
|
||||
{
|
||||
Buffer *tmpBuffer;
|
||||
|
||||
while (aBuffer != NULL)
|
||||
{
|
||||
tmpBuffer = aBuffer->GetNextBuffer();
|
||||
aBuffer->SetNextBuffer(sFreeBuffers);
|
||||
sFreeBuffers = aBuffer;
|
||||
sNumFreeBuffers++;
|
||||
aBuffer->SetNextBuffer(mFreeBuffers);
|
||||
mFreeBuffers = aBuffer;
|
||||
mNumFreeBuffers++;
|
||||
aBuffer = tmpBuffer;
|
||||
}
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError ReclaimBuffers(int aNumBuffers)
|
||||
ThreadError MessagePool::ReclaimBuffers(int aNumBuffers)
|
||||
{
|
||||
return (aNumBuffers <= sNumFreeBuffers) ? kThreadError_None : kThreadError_NoBufs;
|
||||
}
|
||||
|
||||
ThreadError Message::Init(void)
|
||||
{
|
||||
sFreeBuffers = sBuffers;
|
||||
|
||||
for (int i = 0; i < kNumBuffers - 1; i++)
|
||||
{
|
||||
sBuffers[i].SetNextBuffer(&sBuffers[i + 1]);
|
||||
}
|
||||
|
||||
sBuffers[kNumBuffers - 1].SetNextBuffer(NULL);
|
||||
sNumFreeBuffers = kNumBuffers;
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
Message *Message::New(uint8_t aType, uint16_t aReserved)
|
||||
{
|
||||
Message *message = NULL;
|
||||
|
||||
VerifyOrExit((message = reinterpret_cast<Message *>(NewBuffer())) != NULL, ;);
|
||||
|
||||
memset(message, 0, sizeof(*message));
|
||||
message->SetType(aType);
|
||||
message->SetReserved(aReserved);
|
||||
message->SetLinkSecurityEnabled(true);
|
||||
|
||||
VerifyOrExit(message->SetLength(0) == kThreadError_None, Message::Free(*message));
|
||||
|
||||
exit:
|
||||
return message;
|
||||
}
|
||||
|
||||
ThreadError Message::Free(Message &aMessage)
|
||||
{
|
||||
assert(aMessage.GetMessageList(MessageInfo::kListAll).mList == NULL &&
|
||||
aMessage.GetMessageList(MessageInfo::kListInterface).mList == NULL);
|
||||
return FreeBuffers(reinterpret_cast<Buffer *>(&aMessage));
|
||||
return (aNumBuffers <= mNumFreeBuffers) ? kThreadError_None : kThreadError_NoBufs;
|
||||
}
|
||||
|
||||
ThreadError Message::ResizeMessage(uint16_t aLength)
|
||||
@@ -135,7 +129,7 @@ ThreadError Message::ResizeMessage(uint16_t aLength)
|
||||
{
|
||||
if (curBuffer->GetNextBuffer() == NULL)
|
||||
{
|
||||
curBuffer->SetNextBuffer(NewBuffer());
|
||||
curBuffer->SetNextBuffer(GetMessagePool()->NewBuffer());
|
||||
VerifyOrExit(curBuffer->GetNextBuffer() != NULL, error = kThreadError_NoBufs);
|
||||
}
|
||||
|
||||
@@ -148,12 +142,17 @@ ThreadError Message::ResizeMessage(uint16_t aLength)
|
||||
curBuffer = curBuffer->GetNextBuffer();
|
||||
lastBuffer->SetNextBuffer(NULL);
|
||||
|
||||
FreeBuffers(curBuffer);
|
||||
GetMessagePool()->FreeBuffers(curBuffer);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Message::Free(void)
|
||||
{
|
||||
return GetMessagePool()->Free(this);
|
||||
}
|
||||
|
||||
Message *Message::GetNext(void) const
|
||||
{
|
||||
return GetMessageList(MessageInfo::kListInterface).mNext;
|
||||
@@ -181,7 +180,7 @@ ThreadError Message::SetLength(uint16_t aLength)
|
||||
bufs -= (((totalLengthCurrent - kHeadBufferDataSize) - 1) / kBufferDataSize) + 1;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = ReclaimBuffers(bufs));
|
||||
SuccessOrExit(error = GetMessagePool()->ReclaimBuffers(bufs));
|
||||
|
||||
SuccessOrExit(error = ResizeMessage(totalLengthRequest));
|
||||
mInfo.mLength = aLength;
|
||||
@@ -292,7 +291,7 @@ uint16_t Message::Read(uint16_t aOffset, uint16_t aLength, void *aBuf) const
|
||||
|
||||
aLength -= bytesToCopy;
|
||||
bytesCopied += bytesToCopy;
|
||||
aBuf = reinterpret_cast<uint8_t *>(aBuf) + bytesToCopy;
|
||||
aBuf = static_cast<uint8_t *>(aBuf) + bytesToCopy;
|
||||
|
||||
aOffset = 0;
|
||||
}
|
||||
@@ -328,7 +327,7 @@ uint16_t Message::Read(uint16_t aOffset, uint16_t aLength, void *aBuf) const
|
||||
|
||||
aLength -= bytesToCopy;
|
||||
bytesCopied += bytesToCopy;
|
||||
aBuf = reinterpret_cast<uint8_t *>(aBuf) + bytesToCopy;
|
||||
aBuf = static_cast<uint8_t *>(aBuf) + bytesToCopy;
|
||||
|
||||
curBuffer = curBuffer->GetNextBuffer();
|
||||
aOffset = 0;
|
||||
@@ -367,7 +366,7 @@ int Message::Write(uint16_t aOffset, uint16_t aLength, const void *aBuf)
|
||||
|
||||
aLength -= bytesToCopy;
|
||||
bytesCopied += bytesToCopy;
|
||||
aBuf = reinterpret_cast<const uint8_t *>(aBuf) + bytesToCopy;
|
||||
aBuf = static_cast<const uint8_t *>(aBuf) + bytesToCopy;
|
||||
|
||||
aOffset = 0;
|
||||
}
|
||||
@@ -403,7 +402,7 @@ int Message::Write(uint16_t aOffset, uint16_t aLength, const void *aBuf)
|
||||
|
||||
aLength -= bytesToCopy;
|
||||
bytesCopied += bytesToCopy;
|
||||
aBuf = reinterpret_cast<const uint8_t *>(aBuf) + bytesToCopy;
|
||||
aBuf = static_cast<const uint8_t *>(aBuf) + bytesToCopy;
|
||||
|
||||
curBuffer = curBuffer->GetNextBuffer();
|
||||
aOffset = 0;
|
||||
@@ -694,7 +693,7 @@ Message *MessageQueue::GetHead(void) const
|
||||
|
||||
ThreadError MessageQueue::Enqueue(Message &aMessage)
|
||||
{
|
||||
aMessage.GetMessageList(MessageInfo::kListAll).mList = &sAll;
|
||||
aMessage.GetMessageList(MessageInfo::kListAll).mList = &aMessage.GetMessagePool()->mAll;
|
||||
aMessage.GetMessageList(MessageInfo::kListInterface).mList = &mInterface;
|
||||
AddToList(MessageInfo::kListAll, aMessage);
|
||||
AddToList(MessageInfo::kListInterface, aMessage);
|
||||
|
||||
+58
-28
@@ -61,6 +61,7 @@ enum
|
||||
};
|
||||
|
||||
class Message;
|
||||
class MessagePool;
|
||||
|
||||
/**
|
||||
* This structure contains pointers to the head and tail of a Message list.
|
||||
@@ -98,6 +99,7 @@ struct BufferHeader
|
||||
*/
|
||||
struct MessageInfo
|
||||
{
|
||||
MessagePool *mMessagePool; ///< Identifies the message pool for this message.
|
||||
enum
|
||||
{
|
||||
kListAll = 0, ///< Identifies the all messages list.
|
||||
@@ -200,6 +202,7 @@ private:
|
||||
*/
|
||||
class Message: private Buffer
|
||||
{
|
||||
friend class MessagePool;
|
||||
friend class MessageQueue;
|
||||
|
||||
public:
|
||||
@@ -210,6 +213,12 @@ public:
|
||||
kTypeMacDataPoll = 2, ///< A MAC data poll message
|
||||
};
|
||||
|
||||
/**
|
||||
* This method frees this message buffer.
|
||||
*
|
||||
*/
|
||||
ThreadError Free(void);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the next message in the same interface list.
|
||||
*
|
||||
@@ -508,35 +517,11 @@ public:
|
||||
*/
|
||||
uint16_t UpdateChecksum(uint16_t aChecksum, uint16_t aOffset, uint16_t aLength) const;
|
||||
|
||||
/**
|
||||
* This static method is used to initialize the message buffer pool.
|
||||
*
|
||||
*/
|
||||
static ThreadError Init(void);
|
||||
|
||||
/**
|
||||
* This static method is used to obtain a new message.
|
||||
*
|
||||
* @param[in] aType The message type.
|
||||
* @param[in] aReserveHeader The number of header bytes to reserve.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if no message buffers are available.
|
||||
*
|
||||
*/
|
||||
static Message *New(uint8_t aType, uint16_t aReserveHeader);
|
||||
|
||||
/**
|
||||
* This static method is used to free a message and return all message buffers to the buffer pool.
|
||||
*
|
||||
* @param[in] aMessage The message to free.
|
||||
*
|
||||
* @retval kThreadError_None Successfully freed the message.
|
||||
* @retval kThreadError_InvalidArgs The message is already freed.
|
||||
*
|
||||
*/
|
||||
static ThreadError Free(Message &aMessage);
|
||||
|
||||
private:
|
||||
MessagePool *GetMessagePool(void) { return mInfo.mMessagePool; }
|
||||
|
||||
void SetMessagePool(MessagePool *aMessagePool) { mInfo.mMessagePool = aMessagePool; }
|
||||
|
||||
/**
|
||||
* This method returns a reference to a message list.
|
||||
*
|
||||
@@ -664,6 +649,51 @@ private:
|
||||
MessageList mInterface; ///< The instance-specific message list.
|
||||
};
|
||||
|
||||
class MessagePool
|
||||
{
|
||||
friend class Message;
|
||||
friend class MessageQueue;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
*/
|
||||
MessagePool(void);
|
||||
|
||||
/**
|
||||
* This method is used to obtain a new message.
|
||||
*
|
||||
* @param[in] aType The message type.
|
||||
* @param[in] aReserveHeader The number of header bytes to reserve.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if no message buffers are available.
|
||||
*
|
||||
*/
|
||||
Message *New(uint8_t aType, uint16_t aReserveHeader);
|
||||
|
||||
/**
|
||||
* This method is used to free a message and return all message buffers to the buffer pool.
|
||||
*
|
||||
* @param[in] aMessage The message to free.
|
||||
*
|
||||
* @retval kThreadError_None Successfully freed the message.
|
||||
* @retval kThreadError_InvalidArgs The message is already freed.
|
||||
*
|
||||
*/
|
||||
ThreadError Free(Message *aMessage);
|
||||
|
||||
private:
|
||||
Buffer *NewBuffer(void);
|
||||
ThreadError FreeBuffers(Buffer *aBuffer);
|
||||
ThreadError ReclaimBuffers(int aNumBuffers);
|
||||
|
||||
int mNumFreeBuffers;
|
||||
Buffer mBuffers[kNumBuffers];
|
||||
Buffer *mFreeBuffers;
|
||||
MessageList mAll;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
+23
-19
@@ -38,37 +38,41 @@
|
||||
|
||||
namespace Thread {
|
||||
|
||||
Tasklet *TaskletScheduler::sHead = NULL;
|
||||
Tasklet *TaskletScheduler::sTail = NULL;
|
||||
|
||||
Tasklet::Tasklet(Handler aHandler, void *aContext)
|
||||
Tasklet::Tasklet(TaskletScheduler &aScheduler, Handler aHandler, void *aContext):
|
||||
mScheduler(aScheduler),
|
||||
mHandler(aHandler),
|
||||
mContext(aContext),
|
||||
mNext(NULL)
|
||||
{
|
||||
mHandler = aHandler;
|
||||
mContext = aContext;
|
||||
mNext = NULL;
|
||||
}
|
||||
|
||||
ThreadError Tasklet::Post(void)
|
||||
{
|
||||
return TaskletScheduler::Post(*this);
|
||||
return mScheduler.Post(*this);
|
||||
}
|
||||
|
||||
TaskletScheduler::TaskletScheduler(void):
|
||||
mHead(NULL),
|
||||
mTail(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
ThreadError TaskletScheduler::Post(Tasklet &aTasklet)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(sTail != &aTasklet && aTasklet.mNext == NULL, error = kThreadError_Busy);
|
||||
VerifyOrExit(mTail != &aTasklet && aTasklet.mNext == NULL, error = kThreadError_Busy);
|
||||
|
||||
if (sTail == NULL)
|
||||
if (mTail == NULL)
|
||||
{
|
||||
sHead = &aTasklet;
|
||||
sTail = &aTasklet;
|
||||
mHead = &aTasklet;
|
||||
mTail = &aTasklet;
|
||||
otSignalTaskletPending();
|
||||
}
|
||||
else
|
||||
{
|
||||
sTail->mNext = &aTasklet;
|
||||
sTail = &aTasklet;
|
||||
mTail->mNext = &aTasklet;
|
||||
mTail = &aTasklet;
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -77,15 +81,15 @@ exit:
|
||||
|
||||
Tasklet *TaskletScheduler::PopTasklet(void)
|
||||
{
|
||||
Tasklet *task = sHead;
|
||||
Tasklet *task = mHead;
|
||||
|
||||
if (task != NULL)
|
||||
{
|
||||
sHead = sHead->mNext;
|
||||
mHead = mHead->mNext;
|
||||
|
||||
if (sHead == NULL)
|
||||
if (mHead == NULL)
|
||||
{
|
||||
sTail = NULL;
|
||||
mTail = NULL;
|
||||
}
|
||||
|
||||
task->mNext = NULL;
|
||||
@@ -96,7 +100,7 @@ Tasklet *TaskletScheduler::PopTasklet(void)
|
||||
|
||||
bool TaskletScheduler::AreTaskletsPending(void)
|
||||
{
|
||||
return sHead != NULL;
|
||||
return mHead != NULL;
|
||||
}
|
||||
|
||||
void TaskletScheduler::RunNextTasklet(void)
|
||||
|
||||
+25
-19
@@ -38,6 +38,8 @@
|
||||
|
||||
namespace Thread {
|
||||
|
||||
class TaskletScheduler;
|
||||
|
||||
/**
|
||||
* @addtogroup core-tasklet
|
||||
*
|
||||
@@ -68,11 +70,12 @@ public:
|
||||
/**
|
||||
* This constructor creates a tasklet instance.
|
||||
*
|
||||
* @param[in] aHandler A pointer to a function that is called when the tasklet is run.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aScheduler A reference to the tasklet scheduler.
|
||||
* @param[in] aHandler A pointer to a function that is called when the tasklet is run.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
Tasklet(Handler aHandler, void *aContext);
|
||||
Tasklet(TaskletScheduler &aScheduler, Handler aHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* This method puts the tasklet on the run queue.
|
||||
@@ -81,15 +84,12 @@ public:
|
||||
ThreadError Post(void);
|
||||
|
||||
private:
|
||||
/**
|
||||
* This method is called when the tasklet is run.
|
||||
*
|
||||
*/
|
||||
void RunTask(void) { mHandler(mContext); }
|
||||
|
||||
Handler mHandler; ///< A pointer to a function that is called when the tasklet is run.
|
||||
void *mContext; ///< A pointer to arbitrary context information.
|
||||
Tasklet *mNext; ///< A pointer to the next tasklet in the run queue.
|
||||
TaskletScheduler &mScheduler;
|
||||
Handler mHandler;
|
||||
void *mContext;
|
||||
Tasklet *mNext;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -100,34 +100,40 @@ class TaskletScheduler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This static method enqueues a tasklet into the run queue.
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
*/
|
||||
TaskletScheduler(void);
|
||||
|
||||
/**
|
||||
* This method enqueues a tasklet into the run queue.
|
||||
*
|
||||
* @param[in] aTasklet A reference to the tasklet to enqueue.
|
||||
*
|
||||
* @retval kThreadError_None Successfully enqueued the tasklet.
|
||||
* @retval kThreadError_Busy The tasklet was already enqueued.
|
||||
*/
|
||||
static ThreadError Post(Tasklet &aTasklet);
|
||||
ThreadError Post(Tasklet &aTasklet);
|
||||
|
||||
/**
|
||||
* This static method indicates whether or not there are tasklets pending.
|
||||
* This method indicates whether or not there are tasklets pending.
|
||||
*
|
||||
* @retval TRUE If there are tasklets pending.
|
||||
* @retval FALSE If there are no tasklets pending.
|
||||
*
|
||||
*/
|
||||
static bool AreTaskletsPending(void);
|
||||
bool AreTaskletsPending(void);
|
||||
|
||||
/**
|
||||
* This static method runs the next tasklet.
|
||||
* This method runs the next tasklet.
|
||||
*
|
||||
*/
|
||||
static void RunNextTasklet(void);
|
||||
void RunNextTasklet(void);
|
||||
|
||||
private:
|
||||
static Tasklet *PopTasklet(void);
|
||||
static Tasklet *sHead;
|
||||
static Tasklet *sTail;
|
||||
Tasklet *PopTasklet(void);
|
||||
Tasklet *mHead;
|
||||
Tasklet *mTail;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+26
-39
@@ -33,21 +33,27 @@
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <platform/alarm.h>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
static Timer *sHead = NULL;
|
||||
static Timer *sTail = NULL;
|
||||
// FIXME: the otPlatAlarm callback should provide the context
|
||||
static TimerScheduler *sTimerScheduler;
|
||||
|
||||
TimerScheduler::TimerScheduler(void):
|
||||
mHead(NULL)
|
||||
{
|
||||
sTimerScheduler = this;
|
||||
}
|
||||
|
||||
void TimerScheduler::Add(Timer &aTimer)
|
||||
{
|
||||
Remove(aTimer);
|
||||
|
||||
if (sHead == NULL)
|
||||
if (mHead == NULL)
|
||||
{
|
||||
sHead = &aTimer;
|
||||
sTail = &aTimer;
|
||||
mHead = &aTimer;
|
||||
SetAlarm();
|
||||
}
|
||||
else
|
||||
@@ -55,7 +61,7 @@ void TimerScheduler::Add(Timer &aTimer)
|
||||
Timer *prev = NULL;
|
||||
Timer *cur;
|
||||
|
||||
for (cur = sHead; cur; cur = cur->mNext)
|
||||
for (cur = mHead; cur; cur = cur->mNext)
|
||||
{
|
||||
if (TimerCompare(aTimer, *cur))
|
||||
{
|
||||
@@ -66,8 +72,8 @@ void TimerScheduler::Add(Timer &aTimer)
|
||||
}
|
||||
else
|
||||
{
|
||||
aTimer.mNext = sHead;
|
||||
sHead = &aTimer;
|
||||
aTimer.mNext = mHead;
|
||||
mHead = &aTimer;
|
||||
SetAlarm();
|
||||
}
|
||||
|
||||
@@ -79,56 +85,38 @@ void TimerScheduler::Add(Timer &aTimer)
|
||||
|
||||
if (cur == NULL)
|
||||
{
|
||||
sTail->mNext = &aTimer;
|
||||
sTail = &aTimer;
|
||||
prev->mNext = &aTimer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerScheduler::Remove(Timer &aTimer)
|
||||
{
|
||||
VerifyOrExit(aTimer.mNext != NULL || sTail == &aTimer, ;);
|
||||
|
||||
if (sHead == &aTimer)
|
||||
if (mHead == &aTimer)
|
||||
{
|
||||
sHead = aTimer.mNext;
|
||||
|
||||
if (sTail == &aTimer)
|
||||
{
|
||||
sTail = NULL;
|
||||
}
|
||||
|
||||
mHead = aTimer.mNext;
|
||||
aTimer.mNext = NULL;
|
||||
SetAlarm();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Timer *cur = sHead; cur; cur = cur->mNext)
|
||||
for (Timer *cur = mHead; cur; cur = cur->mNext)
|
||||
{
|
||||
if (cur->mNext == &aTimer)
|
||||
{
|
||||
cur->mNext = aTimer.mNext;
|
||||
|
||||
if (sTail == &aTimer)
|
||||
{
|
||||
sTail = cur;
|
||||
}
|
||||
|
||||
aTimer.mNext = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aTimer.mNext = NULL;
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
bool TimerScheduler::IsAdded(const Timer &aTimer)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
for (Timer *cur = sHead; cur; cur = cur->mNext)
|
||||
for (Timer *cur = mHead; cur; cur = cur->mNext)
|
||||
{
|
||||
if (cur == &aTimer)
|
||||
{
|
||||
@@ -145,16 +133,15 @@ void TimerScheduler::SetAlarm(void)
|
||||
uint32_t now = otPlatAlarmGetNow();
|
||||
uint32_t elapsed;
|
||||
uint32_t remaining;
|
||||
Timer *timer = sHead;
|
||||
|
||||
if (timer == NULL)
|
||||
if (mHead == NULL)
|
||||
{
|
||||
otPlatAlarmStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
elapsed = now - timer->mT0;
|
||||
remaining = (timer->mDt > elapsed) ? timer->mDt - elapsed : 0;
|
||||
elapsed = now - mHead->mT0;
|
||||
remaining = (mHead->mDt > elapsed) ? mHead->mDt - elapsed : 0;
|
||||
|
||||
otPlatAlarmStartAt(now, remaining);
|
||||
}
|
||||
@@ -162,14 +149,14 @@ void TimerScheduler::SetAlarm(void)
|
||||
|
||||
extern "C" void otPlatAlarmFired(void)
|
||||
{
|
||||
TimerScheduler::FireTimers();
|
||||
sTimerScheduler->FireTimers();
|
||||
}
|
||||
|
||||
void TimerScheduler::FireTimers(void)
|
||||
{
|
||||
uint32_t now = otPlatAlarmGetNow();
|
||||
uint32_t elapsed;
|
||||
Timer *timer = sHead;
|
||||
Timer *timer = mHead;
|
||||
|
||||
if (timer)
|
||||
{
|
||||
|
||||
+37
-26
@@ -65,43 +65,49 @@ class TimerScheduler
|
||||
|
||||
public:
|
||||
/**
|
||||
* This static method adds a timer instance to the timer scheduler.
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
*/
|
||||
TimerScheduler(void);
|
||||
|
||||
/**
|
||||
* This method adds a timer instance to the timer scheduler.
|
||||
*
|
||||
* @param[in] aTimer A reference to the timer instance.
|
||||
*
|
||||
*/
|
||||
static void Add(Timer &aTimer);
|
||||
void Add(Timer &aTimer);
|
||||
|
||||
/**
|
||||
* This static method removes a timer instance to the timer scheduler.
|
||||
* This method removes a timer instance to the timer scheduler.
|
||||
*
|
||||
* @param[in] aTimer A reference to the timer instance.
|
||||
*
|
||||
*/
|
||||
static void Remove(Timer &aTimer);
|
||||
void Remove(Timer &aTimer);
|
||||
|
||||
/**
|
||||
* This static method returns whether or not the timer instance is already added.
|
||||
* This method returns whether or not the timer instance is already added.
|
||||
*
|
||||
* @retval TRUE If the timer instance is already added.
|
||||
* @retval FALSE If the timer instance is not added.
|
||||
*
|
||||
*/
|
||||
static bool IsAdded(const Timer &aTimer);
|
||||
bool IsAdded(const Timer &aTimer);
|
||||
|
||||
/**
|
||||
* This static method processes all running timers.
|
||||
* This method processes all running timers.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
static void FireTimers(void);
|
||||
void FireTimers(void);
|
||||
|
||||
private:
|
||||
static void SetAlarm(void);
|
||||
void SetAlarm(void);
|
||||
|
||||
/**
|
||||
* This static method compares two timers and returns a value to indicate
|
||||
* This method compares two timers and returns a value to indicate
|
||||
* which timer will fire earlier.
|
||||
*
|
||||
* @param[in] aTimerA The first timer for comparison.
|
||||
@@ -111,6 +117,8 @@ private:
|
||||
* @returns false if aTimerA will fire at the same time or after aTimerB.
|
||||
*/
|
||||
static bool TimerCompare(const Timer &aTimerA, const Timer &aTimerB);
|
||||
|
||||
Timer *mHead;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -132,16 +140,18 @@ public:
|
||||
/**
|
||||
* This constructor creates a timer instance.
|
||||
*
|
||||
* @param[in] aHandler A pointer to a function that is called when the timer expires.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aScheduler A refrence to the timer scheduler.
|
||||
* @param[in] aHandler A pointer to a function that is called when the timer expires.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
Timer(Handler aHandler, void *aContext) {
|
||||
mHandler = aHandler;
|
||||
mContext = aContext;
|
||||
mT0 = 0;
|
||||
mDt = 0;
|
||||
mNext = NULL;
|
||||
Timer(TimerScheduler &aScheduler, Handler aHandler, void *aContext):
|
||||
mScheduler(aScheduler),
|
||||
mHandler(aHandler),
|
||||
mContext(aContext),
|
||||
mT0(0),
|
||||
mDt(0),
|
||||
mNext(NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +176,7 @@ public:
|
||||
* @retval TRUE If the timer is running.
|
||||
* @retval FALSE If the timer is not running.
|
||||
*/
|
||||
bool IsRunning(void) const { return TimerScheduler::IsAdded(*this); }
|
||||
bool IsRunning(void) const { return mScheduler.IsAdded(*this); }
|
||||
|
||||
/**
|
||||
* This method schedules the timer to fire a @p dt milliseconds from now.
|
||||
@@ -181,13 +191,13 @@ public:
|
||||
* @param[in] aT0 The start time in milliseconds.
|
||||
* @param[in] aDt The expire time in milliseconds from @p t0.
|
||||
*/
|
||||
void StartAt(uint32_t aT0, uint32_t aDt) { mT0 = aT0; mDt = aDt; TimerScheduler::Add(*this); }
|
||||
void StartAt(uint32_t aT0, uint32_t aDt) { mT0 = aT0; mDt = aDt; mScheduler.Add(*this); }
|
||||
|
||||
/**
|
||||
* This method stops the timer.
|
||||
*
|
||||
*/
|
||||
void Stop(void) { TimerScheduler::Remove(*this); }
|
||||
void Stop(void) { mScheduler.Remove(*this); }
|
||||
|
||||
/**
|
||||
* This static method returns the current time in milliseconds.
|
||||
@@ -216,11 +226,12 @@ public:
|
||||
private:
|
||||
void Fired(void) { mHandler(mContext); }
|
||||
|
||||
Handler mHandler; ///< A pointer to the function that is called when the timer expires.
|
||||
void *mContext; ///< A pointer to arbitrary context information.
|
||||
uint32_t mT0; ///< The start time of the timer in milliseconds.
|
||||
uint32_t mDt; ///< The time delay from the start time in milliseconds.
|
||||
Timer *mNext; ///< The next timer in the scheduler list.
|
||||
TimerScheduler &mScheduler;
|
||||
Handler mHandler;
|
||||
void *mContext;
|
||||
uint32_t mT0;
|
||||
uint32_t mDt;
|
||||
Timer *mNext;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Crypto {
|
||||
|
||||
ThreadError AesCcm::SetKey(const uint8_t *aKey, uint16_t aKeyLength)
|
||||
{
|
||||
otCryptoAesEcbSetKey(aKey, 8 * aKeyLength);
|
||||
mEcb.SetKey(aKey, 8 * aKeyLength);
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ void AesCcm::Init(uint32_t aHeaderLength, uint32_t aPlainTextLength, uint8_t aTa
|
||||
}
|
||||
|
||||
// encrypt initial block
|
||||
otCryptoAesEcbEncrypt(mBlock, mBlock);
|
||||
mEcb.Encrypt(mBlock, mBlock);
|
||||
|
||||
// process header
|
||||
if (aHeaderLength > 0)
|
||||
@@ -169,7 +169,7 @@ void AesCcm::Header(const void *aHeader, uint32_t aHeaderLength)
|
||||
{
|
||||
if (mBlockLength == sizeof(mBlock))
|
||||
{
|
||||
otCryptoAesEcbEncrypt(mBlock, mBlock);
|
||||
mEcb.Encrypt(mBlock, mBlock);
|
||||
mBlockLength = 0;
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ void AesCcm::Header(const void *aHeader, uint32_t aHeaderLength)
|
||||
// process remainder
|
||||
if (mBlockLength != 0)
|
||||
{
|
||||
otCryptoAesEcbEncrypt(mBlock, mBlock);
|
||||
mEcb.Encrypt(mBlock, mBlock);
|
||||
}
|
||||
|
||||
mBlockLength = 0;
|
||||
@@ -210,7 +210,7 @@ void AesCcm::Payload(void *plaintext, void *ciphertext, uint32_t len, bool aEncr
|
||||
}
|
||||
}
|
||||
|
||||
otCryptoAesEcbEncrypt(mCtr, mCtrPad);
|
||||
mEcb.Encrypt(mCtr, mCtrPad);
|
||||
mCtrLength = 0;
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ void AesCcm::Payload(void *plaintext, void *ciphertext, uint32_t len, bool aEncr
|
||||
|
||||
if (mBlockLength == sizeof(mBlock))
|
||||
{
|
||||
otCryptoAesEcbEncrypt(mBlock, mBlock);
|
||||
mEcb.Encrypt(mBlock, mBlock);
|
||||
mBlockLength = 0;
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ void AesCcm::Payload(void *plaintext, void *ciphertext, uint32_t len, bool aEncr
|
||||
{
|
||||
if (mBlockLength != 0)
|
||||
{
|
||||
otCryptoAesEcbEncrypt(mBlock, mBlock);
|
||||
mEcb.Encrypt(mBlock, mBlock);
|
||||
}
|
||||
|
||||
// reset counter
|
||||
@@ -259,7 +259,7 @@ void AesCcm::Finalize(void *tag, uint8_t *aTagLength)
|
||||
|
||||
if (mTagLength > 0)
|
||||
{
|
||||
otCryptoAesEcbEncrypt(mCtr, mCtrPad);
|
||||
mEcb.Encrypt(mCtr, mCtrPad);
|
||||
|
||||
for (int i = 0; i < mTagLength; i++)
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <crypto/aes_ecb.h>
|
||||
#include <crypto/aes_ecb.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Crypto {
|
||||
@@ -108,9 +108,10 @@ public:
|
||||
void Finalize(void *aTag, uint8_t *aTagLength);
|
||||
|
||||
private:
|
||||
uint8_t mBlock[otAesBlockSize];
|
||||
uint8_t mCtr[otAesBlockSize];
|
||||
uint8_t mCtrPad[otAesBlockSize];
|
||||
AesEcb mEcb;
|
||||
uint8_t mBlock[AesEcb::kBlockSize];
|
||||
uint8_t mCtr[AesEcb::kBlockSize];
|
||||
uint8_t mCtrPad[AesEcb::kBlockSize];
|
||||
uint8_t mNonceLength;
|
||||
uint32_t mHeaderLength;
|
||||
uint32_t mHeaderCur;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 AES-ECB.
|
||||
*/
|
||||
|
||||
#include <crypto/aes_ecb.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Crypto {
|
||||
|
||||
void AesEcb::SetKey(const uint8_t *aKey, uint16_t aKeyLength)
|
||||
{
|
||||
mbedtls_aes_init(&mContext);
|
||||
mbedtls_aes_setkey_enc(&mContext, aKey, aKeyLength);
|
||||
}
|
||||
|
||||
void AesEcb::Encrypt(const uint8_t aInput[kBlockSize], uint8_t aOutput[kBlockSize])
|
||||
{
|
||||
mbedtls_aes_crypt_ecb(&mContext, MBEDTLS_AES_ENCRYPT, aInput, aOutput);
|
||||
}
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Thread
|
||||
@@ -28,18 +28,16 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file includes the platform abstraction for HMAC SHA-256 computations.
|
||||
* This file includes definitions for performing AES-ECB computations.
|
||||
*/
|
||||
|
||||
#ifndef HMAC_SHA256_H_
|
||||
#define HMAC_SHA256_H_
|
||||
#ifndef AES_ECB_HPP_
|
||||
#define AES_ECB_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <mbedtls/aes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
namespace Thread {
|
||||
namespace Crypto {
|
||||
|
||||
/**
|
||||
* @addtogroup core-security
|
||||
@@ -48,44 +46,46 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
enum
|
||||
/**
|
||||
* This class implements AES ECB computation.
|
||||
*
|
||||
*/
|
||||
class AesEcb
|
||||
{
|
||||
otCryptoSha256Size = 32, ///< SHA-256 hash size (bytes)
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kBlockSize = 16, ///< AES-128 block size (bytes).
|
||||
};
|
||||
|
||||
/**
|
||||
* This method sets the key.
|
||||
*
|
||||
* @param[in] aKey A pointer to the key.
|
||||
* @param[in] aKeyLength The key length in bytes.
|
||||
*
|
||||
*/
|
||||
void SetKey(const uint8_t *aKey, uint16_t aKeyLength);
|
||||
|
||||
/**
|
||||
* This method encrypts data.
|
||||
*
|
||||
* @param[in] aInput A pointer to the input buffer.
|
||||
* @param[out] aOutput A pointer to the output buffer.
|
||||
*
|
||||
*/
|
||||
void Encrypt(const uint8_t aInput[kBlockSize], uint8_t aOutput[kBlockSize]);
|
||||
|
||||
private:
|
||||
mbedtls_aes_context mContext;
|
||||
};
|
||||
|
||||
/**
|
||||
* This method sets the key.
|
||||
*
|
||||
* @param[in] aKey A pointer to the key.
|
||||
* @param[in] aKeyLength The key length in bytes.
|
||||
*
|
||||
*/
|
||||
void otCryptoHmacSha256Start(const void *aKey, uint16_t aKeyLength);
|
||||
|
||||
/**
|
||||
* This method inputs bytes into the HMAC computation.
|
||||
*
|
||||
* @param[in] aBuf A pointer to the input buffer.
|
||||
* @param[in] aBufLength The length of @p aBuf in bytes.
|
||||
*
|
||||
*/
|
||||
void otCryptoHmacSha256Update(const void *aBuf, uint16_t aBufLength);
|
||||
|
||||
/**
|
||||
* This method finalizes the hash computation.
|
||||
*
|
||||
* @param[out] aHash A pointer to the output buffer.
|
||||
*
|
||||
*/
|
||||
void otCryptoHmacSha256Finish(uint8_t aHash[otCryptoSha256Size]);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
} // namespace Crypto
|
||||
} // namespace Thread
|
||||
|
||||
#endif // HMAC_SHA256_H_
|
||||
#endif // AES_ECB_HPP_
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 HMAC SHA-256.
|
||||
*/
|
||||
|
||||
#include <crypto/hmac_sha256.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Crypto {
|
||||
|
||||
void HmacSha256::Start(const uint8_t *aKey, uint16_t aKeyLength)
|
||||
{
|
||||
const mbedtls_md_info_t *mdInfo = NULL;
|
||||
mbedtls_md_init(&mContext);
|
||||
mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||
mbedtls_md_setup(&mContext, mdInfo, 1);
|
||||
mbedtls_md_hmac_starts(&mContext, aKey, aKeyLength);
|
||||
}
|
||||
|
||||
void HmacSha256::Update(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
mbedtls_md_hmac_update(&mContext, aBuf, aBufLength);
|
||||
}
|
||||
|
||||
void HmacSha256::Finish(uint8_t aHash[kHashSize])
|
||||
{
|
||||
mbedtls_md_hmac_finish(&mContext, aHash);
|
||||
mbedtls_md_free(&mContext);
|
||||
}
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 performing HMAC SHA-256 computations.
|
||||
*/
|
||||
|
||||
#ifndef HMAC_SHA256_HPP_
|
||||
#define HMAC_SHA256_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <mbedtls/md.h>
|
||||
|
||||
namespace Thread {
|
||||
namespace Crypto {
|
||||
|
||||
/**
|
||||
* @addtogroup core-security
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class implements HMAC SHA-256 computation.
|
||||
*
|
||||
*/
|
||||
class HmacSha256
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kHashSize = 32, ///< SHA-256 hash size (bytes)
|
||||
};
|
||||
|
||||
/**
|
||||
* This method sets the key.
|
||||
*
|
||||
* @param[in] aKey A pointer to the key.
|
||||
* @param[in] aKeyLength The key length in bytes.
|
||||
*
|
||||
*/
|
||||
void Start(const uint8_t *aKey, uint16_t aKeyLength);
|
||||
|
||||
/**
|
||||
* This method inputs bytes into the HMAC computation.
|
||||
*
|
||||
* @param[in] aBuf A pointer to the input buffer.
|
||||
* @param[in] aBufLength The length of @p aBuf in bytes.
|
||||
*
|
||||
*/
|
||||
void Update(const uint8_t *aBuf, uint16_t aBufLength);
|
||||
|
||||
/**
|
||||
* This method finalizes the hash computation.
|
||||
*
|
||||
* @param[out] aHash A pointer to the output buffer.
|
||||
*
|
||||
*/
|
||||
void Finish(uint8_t aHash[kHashSize]);
|
||||
|
||||
private:
|
||||
mbedtls_md_context_t mContext;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Thread
|
||||
|
||||
#endif // HMAC_SHA256_HPP_
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 the use of mbedTLS.
|
||||
*/
|
||||
|
||||
#include <crypto/mbedtls.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Crypto {
|
||||
|
||||
MbedTls::MbedTls(void)
|
||||
{
|
||||
mbedtls_memory_buffer_alloc_init(mMemory, sizeof(mMemory));
|
||||
}
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Thread
|
||||
@@ -28,20 +28,18 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file includes the platform abstraction for AES ECB computations.
|
||||
* This file includes definitions for using mbedTLS.
|
||||
*/
|
||||
|
||||
#ifndef AES_ECB_H_
|
||||
#define AES_ECB_H_
|
||||
#ifndef OT_MBEDTLS_HPP_
|
||||
#define OT_MBEDTLS_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <mbedtls/memory_buffer_alloc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
namespace Thread {
|
||||
namespace Crypto {
|
||||
|
||||
/**
|
||||
* @addtogroup core-security
|
||||
@@ -50,36 +48,34 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
enum
|
||||
/**
|
||||
* This class implements mbedTLS memory.
|
||||
*
|
||||
*/
|
||||
class MbedTls
|
||||
{
|
||||
otAesBlockSize = 16, ///< AES-128 block size.
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kMemorySize = 512, ///< Size of memory buffer (bytes).
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
*/
|
||||
MbedTls(void);
|
||||
|
||||
private:
|
||||
unsigned char mMemory[kMemorySize];
|
||||
};
|
||||
|
||||
/**
|
||||
* This method sets the key.
|
||||
*
|
||||
* @param[in] aKey A pointer to the key.
|
||||
* @param[in] aKeyLength Length of the key in bytes.
|
||||
*
|
||||
*/
|
||||
void otCryptoAesEcbSetKey(const void *aKey, uint16_t aKeyLength);
|
||||
|
||||
/**
|
||||
* This method encrypts data.
|
||||
*
|
||||
* @param[in] aInput A pointer to the input.
|
||||
* @param[out] aOutput A pointer to the output.
|
||||
*
|
||||
*/
|
||||
void otCryptoAesEcbEncrypt(const uint8_t aInput[otAesBlockSize], uint8_t aOutput[otAesBlockSize]);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
} // namespace Crypto
|
||||
} // namespace Thread
|
||||
|
||||
#endif // AES_ECB_H_
|
||||
#endif // OT_MBEDTLS_HPP_
|
||||
@@ -67,10 +67,10 @@ void Mac::StartCsmaBackoff(void)
|
||||
}
|
||||
|
||||
Mac::Mac(ThreadNetif &aThreadNetif):
|
||||
mBeginTransmit(&HandleBeginTransmit, this),
|
||||
mAckTimer(&HandleAckTimer, this),
|
||||
mBackoffTimer(&HandleBeginTransmit, this),
|
||||
mReceiveTimer(&HandleReceiveTimer, this),
|
||||
mBeginTransmit(aThreadNetif.GetIp6().mTaskletScheduler, &HandleBeginTransmit, this),
|
||||
mAckTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleAckTimer, this),
|
||||
mBackoffTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleBeginTransmit, this),
|
||||
mReceiveTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleReceiveTimer, this),
|
||||
mKeyManager(aThreadNetif.GetKeyManager()),
|
||||
mMle(aThreadNetif.GetMle()),
|
||||
mNetif(aThreadNetif),
|
||||
@@ -925,7 +925,7 @@ void Mac::ReceiveDoneTask(Frame *aFrame, ThreadError aError)
|
||||
|
||||
if (neighbor != NULL)
|
||||
{
|
||||
neighbor->mLinkInfo.AddRss(aFrame->mPower);
|
||||
neighbor->mLinkInfo.AddRss(mNoiseFloor, aFrame->mPower);
|
||||
}
|
||||
|
||||
switch (mState)
|
||||
|
||||
@@ -453,6 +453,14 @@ public:
|
||||
*/
|
||||
otMacCounters &GetCounters(void);
|
||||
|
||||
/**
|
||||
* This method returns the noise floor state.
|
||||
*
|
||||
* @returns A reference to the noise floor state.
|
||||
*
|
||||
*/
|
||||
LinkQualityInfo &GetNoiseFloor(void) { return mNoiseFloor; }
|
||||
|
||||
private:
|
||||
void GenerateNonce(const ExtAddress &aAddress, uint32_t aFrameCounter, uint8_t aSecurityLevel, uint8_t *aNonce);
|
||||
void NextOperation(void);
|
||||
@@ -518,6 +526,8 @@ private:
|
||||
ActiveScanHandler mActiveScanHandler;
|
||||
void *mActiveScanContext;
|
||||
|
||||
LinkQualityInfo mNoiseFloor;
|
||||
|
||||
otLinkPcapCallback mPcapCallback;
|
||||
void *mPcapCallbackContext;
|
||||
|
||||
|
||||
+29
-26
@@ -45,23 +45,26 @@ using Thread::Encoding::BigEndian::HostSwap16;
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
bool Icmp::sIsEchoEnabled = true;
|
||||
|
||||
uint16_t Icmp::sEchoSequence = 1;
|
||||
IcmpHandler *IcmpHandler::sHandlers = NULL;
|
||||
Icmp::EchoReplyHandler Icmp::sEchoReplyHandler = NULL;
|
||||
void *Icmp::sEchoReplyContext = NULL;
|
||||
Icmp::Icmp(Ip6 &aIp6):
|
||||
mHandlers(NULL),
|
||||
mEchoSequence(1),
|
||||
mEchoReplyHandler(NULL),
|
||||
mEchoReplyContext(NULL),
|
||||
mIsEchoEnabled(true),
|
||||
mIp6(aIp6)
|
||||
{
|
||||
}
|
||||
|
||||
Message *Icmp::NewMessage(uint16_t aReserved)
|
||||
{
|
||||
return Ip6::NewMessage(sizeof(IcmpHeader) + aReserved);
|
||||
return mIp6.NewMessage(sizeof(IcmpHeader) + aReserved);
|
||||
}
|
||||
|
||||
ThreadError Icmp::RegisterCallbacks(IcmpHandler &aHandler)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
for (IcmpHandler *cur = IcmpHandler::sHandlers; cur; cur = cur->mNext)
|
||||
for (IcmpHandler *cur = mHandlers; cur; cur = cur->mNext)
|
||||
{
|
||||
if (cur == &aHandler)
|
||||
{
|
||||
@@ -69,8 +72,8 @@ ThreadError Icmp::RegisterCallbacks(IcmpHandler &aHandler)
|
||||
}
|
||||
}
|
||||
|
||||
aHandler.mNext = IcmpHandler::sHandlers;
|
||||
IcmpHandler::sHandlers = &aHandler;
|
||||
aHandler.mNext = mHandlers;
|
||||
mHandlers = &aHandler;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -78,8 +81,8 @@ exit:
|
||||
|
||||
void Icmp::SetEchoReplyHandler(EchoReplyHandler aHandler, void *aContext)
|
||||
{
|
||||
sEchoReplyHandler = aHandler;
|
||||
sEchoReplyContext = aContext;
|
||||
mEchoReplyHandler = aHandler;
|
||||
mEchoReplyContext = aContext;
|
||||
}
|
||||
|
||||
ThreadError Icmp::SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo)
|
||||
@@ -93,11 +96,11 @@ ThreadError Icmp::SendEchoRequest(Message &aMessage, const MessageInfo &aMessage
|
||||
icmpHeader.Init();
|
||||
icmpHeader.SetType(IcmpHeader::kTypeEchoRequest);
|
||||
icmpHeader.SetId(1);
|
||||
icmpHeader.SetSequence(sEchoSequence++);
|
||||
icmpHeader.SetSequence(mEchoSequence++);
|
||||
|
||||
SuccessOrExit(error = aMessage.Prepend(&icmpHeader, sizeof(icmpHeader)));
|
||||
aMessage.SetOffset(0);
|
||||
SuccessOrExit(error = Ip6::SendDatagram(aMessage, messageInfoLocal, kProtoIcmp6));
|
||||
SuccessOrExit(error = mIp6.SendDatagram(aMessage, messageInfoLocal, kProtoIcmp6));
|
||||
|
||||
otLogInfoIcmp("Sent echo request\n");
|
||||
|
||||
@@ -113,7 +116,7 @@ ThreadError Icmp::SendError(const Address &aDestination, IcmpHeader::Type aType,
|
||||
Message *message = NULL;
|
||||
IcmpHeader icmp6Header;
|
||||
|
||||
VerifyOrExit((message = Ip6::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mIp6.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(aHeader)));
|
||||
|
||||
message->Write(sizeof(icmp6Header), sizeof(aHeader), &aHeader);
|
||||
@@ -126,7 +129,7 @@ ThreadError Icmp::SendError(const Address &aDestination, IcmpHeader::Type aType,
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
messageInfo.mPeerAddr = aDestination;
|
||||
|
||||
SuccessOrExit(error = Ip6::SendDatagram(*message, messageInfo, kProtoIcmp6));
|
||||
SuccessOrExit(error = mIp6.SendDatagram(*message, messageInfo, kProtoIcmp6));
|
||||
|
||||
otLogInfoIcmp("Sent ICMPv6 Error\n");
|
||||
|
||||
@@ -134,7 +137,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -180,7 +183,7 @@ ThreadError Icmp::HandleDstUnreach(Message &aMessage, const MessageInfo &aMessag
|
||||
{
|
||||
aMessage.MoveOffset(sizeof(aIcmpheader));
|
||||
|
||||
for (IcmpHandler *handler = IcmpHandler::sHandlers; handler; handler = handler->mNext)
|
||||
for (IcmpHandler *handler = mHandlers; handler; handler = handler->mNext)
|
||||
{
|
||||
handler->HandleDstUnreach(aMessage, aMessageInfo, aIcmpheader);
|
||||
}
|
||||
@@ -196,14 +199,14 @@ ThreadError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo
|
||||
MessageInfo replyMessageInfo;
|
||||
uint16_t payloadLength;
|
||||
|
||||
VerifyOrExit(sIsEchoEnabled, ;);
|
||||
VerifyOrExit(mIsEchoEnabled, ;);
|
||||
|
||||
otLogInfoIcmp("Received Echo Request\n");
|
||||
|
||||
icmp6Header.Init();
|
||||
icmp6Header.SetType(IcmpHeader::kTypeEchoReply);
|
||||
|
||||
VerifyOrExit((replyMessage = Ip6::NewMessage(0)) != NULL, otLogDebgIcmp("icmp fail\n"));
|
||||
VerifyOrExit((replyMessage = mIp6.NewMessage(0)) != NULL, otLogDebgIcmp("icmp fail\n"));
|
||||
payloadLength = aRequestMessage.GetLength() - aRequestMessage.GetOffset() - IcmpHeader::GetDataOffset();
|
||||
SuccessOrExit(replyMessage->SetLength(IcmpHeader::GetDataOffset() + payloadLength));
|
||||
|
||||
@@ -221,7 +224,7 @@ ThreadError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo
|
||||
|
||||
replyMessageInfo.mInterfaceId = aMessageInfo.mInterfaceId;
|
||||
|
||||
SuccessOrExit(error = Ip6::SendDatagram(*replyMessage, replyMessageInfo, kProtoIcmp6));
|
||||
SuccessOrExit(error = mIp6.SendDatagram(*replyMessage, replyMessageInfo, kProtoIcmp6));
|
||||
|
||||
otLogInfoIcmp("Sent Echo Reply\n");
|
||||
|
||||
@@ -229,7 +232,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && replyMessage != NULL)
|
||||
{
|
||||
Message::Free(*replyMessage);
|
||||
replyMessage->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -237,9 +240,9 @@ exit:
|
||||
|
||||
ThreadError Icmp::HandleEchoReply(Message &aMessage, const MessageInfo &aMessageInfo)
|
||||
{
|
||||
VerifyOrExit(sIsEchoEnabled && sEchoReplyHandler, ;);
|
||||
VerifyOrExit(mIsEchoEnabled && mEchoReplyHandler, ;);
|
||||
|
||||
sEchoReplyHandler(sEchoReplyContext, aMessage, aMessageInfo);
|
||||
mEchoReplyHandler(mEchoReplyContext, aMessage, aMessageInfo);
|
||||
|
||||
exit:
|
||||
return kThreadError_None;
|
||||
@@ -262,12 +265,12 @@ ThreadError Icmp::UpdateChecksum(Message &aMessage, uint16_t aChecksum)
|
||||
|
||||
bool Icmp::IsEchoEnabled(void)
|
||||
{
|
||||
return sIsEchoEnabled;
|
||||
return mIsEchoEnabled;
|
||||
}
|
||||
|
||||
void Icmp::SetEchoEnabled(bool aEnabled)
|
||||
{
|
||||
sIsEchoEnabled = aEnabled;
|
||||
mIsEchoEnabled = aEnabled;
|
||||
}
|
||||
|
||||
} // namespace Ip6
|
||||
|
||||
+39
-30
@@ -35,7 +35,7 @@
|
||||
#define ICMP6_HPP_
|
||||
|
||||
#include <common/encoding.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/ip6_headers.hpp>
|
||||
|
||||
using Thread::Encoding::BigEndian::HostSwap16;
|
||||
|
||||
@@ -249,8 +249,6 @@ private:
|
||||
DstUnreachHandler mDstUnreachHandler;
|
||||
void *mContext;
|
||||
IcmpHandler *mNext;
|
||||
|
||||
static IcmpHandler *sHandlers;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -261,17 +259,25 @@ class Icmp
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This static method returns a new ICMP message with sufficient header space reserved.
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aIp6 A reference to the IPv6 network object.
|
||||
*
|
||||
*/
|
||||
Icmp(Ip6 &aIp6);
|
||||
|
||||
/**
|
||||
* This method returns a new ICMP message with sufficient header space reserved.
|
||||
*
|
||||
* @param[in] aReserved The number of header bytes to reserve after the ICMP header.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if no buffers are available.
|
||||
*
|
||||
*/
|
||||
static Message *NewMessage(uint16_t aReserved);
|
||||
Message *NewMessage(uint16_t aReserved);
|
||||
|
||||
/**
|
||||
* This static method registers ICMPv6 handlers.
|
||||
* This method registers ICMPv6 handlers.
|
||||
*
|
||||
* @param[in] aHandler A reference to the ICMPv6 handler.
|
||||
*
|
||||
@@ -279,7 +285,7 @@ public:
|
||||
* @retval kThreadError_Busy The ICMPv6 handler is already registered.
|
||||
*
|
||||
*/
|
||||
static ThreadError RegisterCallbacks(IcmpHandler &aHandler);
|
||||
ThreadError RegisterCallbacks(IcmpHandler &aHandler);
|
||||
|
||||
/**
|
||||
* This function pointer is called when receiving an ICMPv6 Echo Reply in response to an Echo Request.
|
||||
@@ -292,16 +298,16 @@ public:
|
||||
typedef void (*EchoReplyHandler)(void *aContext, Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This static method sets the Echo Reply handler.
|
||||
* This method sets the Echo Reply handler.
|
||||
*
|
||||
* @param[in] aHandler A pointer to a function that is called when receiving an ICMPv6 Echo Reply.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
static void SetEchoReplyHandler(EchoReplyHandler aHandler, void *aContext);
|
||||
void SetEchoReplyHandler(EchoReplyHandler aHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* This static method sends an ICMPv6 Echo Request message.
|
||||
* This method sends an ICMPv6 Echo Request message.
|
||||
*
|
||||
* @param[in] aMessage A reference to the Echo Request payload.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
@@ -310,10 +316,10 @@ public:
|
||||
* @retval kThreadError_NoBufs Insufficient buffers available to generate an ICMPv6 Echo Request message.
|
||||
*
|
||||
*/
|
||||
static ThreadError SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
ThreadError SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This static method sends an ICMPv6 error message.
|
||||
* This method sends an ICMPv6 error message.
|
||||
*
|
||||
* @param[in] aDestination The IPv6 destination address.
|
||||
* @param[in] aType The ICMPv6 message type.
|
||||
@@ -324,11 +330,11 @@ public:
|
||||
* @retval kThreadError_NoBufs Insufficient buffers available.
|
||||
*
|
||||
*/
|
||||
static ThreadError SendError(const Address &aDestination, IcmpHeader::Type aType, IcmpHeader::Code aCode,
|
||||
const Header &aHeader);
|
||||
ThreadError SendError(const Address &aDestination, IcmpHeader::Type aType, IcmpHeader::Code aCode,
|
||||
const Header &aHeader);
|
||||
|
||||
/**
|
||||
* This static method handles an ICMPv6 message.
|
||||
* This method handles an ICMPv6 message.
|
||||
*
|
||||
* @param[in] aMessage A reference to the ICMPv6 message.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
@@ -338,10 +344,10 @@ public:
|
||||
* @retval kThreadError_Drop The ICMPv6 message was invalid and dropped.
|
||||
*
|
||||
*/
|
||||
static ThreadError HandleMessage(Message &aMessage, MessageInfo &aMessageInfo);
|
||||
ThreadError HandleMessage(Message &aMessage, MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This static method updates the ICMPv6 checksum.
|
||||
* This method updates the ICMPv6 checksum.
|
||||
*
|
||||
* @param[in] aMessage A reference to the ICMPv6 message.
|
||||
* @param[in] aPseudoHeaderChecksum The pseudo-header checksum value.
|
||||
@@ -350,35 +356,38 @@ public:
|
||||
* @retval kThreadError_InvalidArgs The message was invalid.
|
||||
*
|
||||
*/
|
||||
static ThreadError UpdateChecksum(Message &aMessage, uint16_t aPseudoHeaderChecksum);
|
||||
ThreadError UpdateChecksum(Message &aMessage, uint16_t aPseudoHeaderChecksum);
|
||||
|
||||
/**
|
||||
* This static method indicates whether or not ICMPv6 Echo processing is enabled.
|
||||
* This method indicates whether or not ICMPv6 Echo processing is enabled.
|
||||
*
|
||||
* @retval TRUE ICMPv6 Echo processing is enabled.
|
||||
* @retval FALSE ICMPv6 Echo processing is disabled.
|
||||
*
|
||||
*/
|
||||
static bool IsEchoEnabled(void);
|
||||
bool IsEchoEnabled(void);
|
||||
|
||||
/**
|
||||
* This static method sets whether or not ICMPv6 Echo processing is enabled.
|
||||
* This method sets whether or not ICMPv6 Echo processing is enabled.
|
||||
*
|
||||
* @param[in] aEnabled TRUE to enable ICMPv6 Echo processing, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
static void SetEchoEnabled(bool aEnabled);
|
||||
void SetEchoEnabled(bool aEnabled);
|
||||
|
||||
private:
|
||||
static ThreadError HandleDstUnreach(Message &aMessage, const MessageInfo &aMessageInfo,
|
||||
const IcmpHeader &aIcmpHeader);
|
||||
static ThreadError HandleEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
static ThreadError HandleEchoReply(Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
ThreadError HandleDstUnreach(Message &aMessage, const MessageInfo &aMessageInfo, const IcmpHeader &aIcmpHeader);
|
||||
ThreadError HandleEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
ThreadError HandleEchoReply(Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
|
||||
static uint16_t sEchoSequence;
|
||||
static EchoReplyHandler sEchoReplyHandler;
|
||||
static void *sEchoReplyContext;
|
||||
static bool sIsEchoEnabled;
|
||||
IcmpHandler *mHandlers;
|
||||
|
||||
uint16_t mEchoSequence;
|
||||
EchoReplyHandler mEchoReplyHandler;
|
||||
void *mEchoReplyContext;
|
||||
bool mIsEchoEnabled;
|
||||
|
||||
Ip6 &mIp6;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+268
-48
@@ -39,7 +39,6 @@
|
||||
#include <net/icmp6.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/ip6_address.hpp>
|
||||
#include <net/ip6_mpl.hpp>
|
||||
#include <net/ip6_routes.hpp>
|
||||
#include <net/netif.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
@@ -48,32 +47,28 @@
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
static otDEFINE_ALIGNED_VAR(sMplBuf, sizeof(Mpl), uint64_t);
|
||||
static Mpl *sMpl;
|
||||
static bool sForwardingEnabled;
|
||||
|
||||
static otReceiveIp6DatagramCallback sReceiveIp6DatagramCallback = NULL;
|
||||
static void *sReceiveIp6DatagramCallbackContext = NULL;
|
||||
static bool sIsReceiveIp6FilterEnabled;
|
||||
|
||||
static ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo);
|
||||
Ip6::Ip6(void):
|
||||
mRoutes(*this),
|
||||
mIcmp(*this),
|
||||
mUdp(*this),
|
||||
mMpl(*this),
|
||||
mForwardingEnabled(false),
|
||||
mReceiveIp6DatagramCallback(NULL),
|
||||
mReceiveIp6DatagramCallbackContext(NULL),
|
||||
mIsReceiveIp6FilterEnabled(false),
|
||||
mNetifListHead(NULL),
|
||||
mNextInterfaceId(1)
|
||||
{
|
||||
}
|
||||
|
||||
Message *Ip6::NewMessage(uint16_t reserved)
|
||||
{
|
||||
return Message::New(Message::kTypeIp6,
|
||||
sizeof(Header) + sizeof(HopByHopHeader) + sizeof(OptionMpl) + reserved);
|
||||
}
|
||||
|
||||
void Ip6::Init(void)
|
||||
{
|
||||
sMpl = new(&sMplBuf) Mpl;
|
||||
sForwardingEnabled = false;
|
||||
sIsReceiveIp6FilterEnabled = true;
|
||||
return mMessagePool.New(Message::kTypeIp6, sizeof(Header) + sizeof(HopByHopHeader) + sizeof(OptionMpl) + reserved);
|
||||
}
|
||||
|
||||
void Ip6::SetForwardingEnabled(bool aEnable)
|
||||
{
|
||||
sForwardingEnabled = aEnable;
|
||||
mForwardingEnabled = aEnable;
|
||||
}
|
||||
|
||||
uint16_t Ip6::UpdateChecksum(uint16_t checksum, uint16_t val)
|
||||
@@ -113,21 +108,21 @@ uint16_t Ip6::ComputePseudoheaderChecksum(const Address &src, const Address &dst
|
||||
|
||||
void Ip6::SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext)
|
||||
{
|
||||
sReceiveIp6DatagramCallback = aCallback;
|
||||
sReceiveIp6DatagramCallbackContext = aCallbackContext;
|
||||
mReceiveIp6DatagramCallback = aCallback;
|
||||
mReceiveIp6DatagramCallbackContext = aCallbackContext;
|
||||
}
|
||||
|
||||
bool Ip6::IsReceiveIp6FilterEnabled(void)
|
||||
{
|
||||
return sIsReceiveIp6FilterEnabled;
|
||||
return mIsReceiveIp6FilterEnabled;
|
||||
}
|
||||
|
||||
void Ip6::SetReceiveIp6FilterEnabled(bool aEnabled)
|
||||
{
|
||||
sIsReceiveIp6FilterEnabled = aEnabled;
|
||||
mIsReceiveIp6FilterEnabled = aEnabled;
|
||||
}
|
||||
|
||||
ThreadError AddMplOption(Message &message, Header &header, IpProto nextHeader, uint16_t payloadLength)
|
||||
ThreadError Ip6::AddMplOption(Message &message, Header &header, IpProto nextHeader, uint16_t payloadLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
HopByHopHeader hbhHeader;
|
||||
@@ -135,7 +130,7 @@ ThreadError AddMplOption(Message &message, Header &header, IpProto nextHeader, u
|
||||
|
||||
hbhHeader.SetNextHeader(nextHeader);
|
||||
hbhHeader.SetLength(0);
|
||||
sMpl->InitOption(mplOption, HostSwap16(header.GetSource().mFields.m16[7]));
|
||||
mMpl.InitOption(mplOption, HostSwap16(header.GetSource().mFields.m16[7]));
|
||||
SuccessOrExit(error = message.Prepend(&mplOption, sizeof(mplOption)));
|
||||
SuccessOrExit(error = message.Prepend(&hbhHeader, sizeof(hbhHeader)));
|
||||
header.SetPayloadLength(sizeof(hbhHeader) + sizeof(mplOption) + payloadLength);
|
||||
@@ -159,7 +154,7 @@ ThreadError Ip6::SendDatagram(Message &message, MessageInfo &messageInfo, IpProt
|
||||
|
||||
if (messageInfo.GetSockAddr().IsUnspecified())
|
||||
{
|
||||
VerifyOrExit((source = Netif::SelectSourceAddress(messageInfo)) != NULL, error = kThreadError_Error);
|
||||
VerifyOrExit((source = SelectSourceAddress(messageInfo)) != NULL, error = kThreadError_Error);
|
||||
header.SetSource(source->GetAddress());
|
||||
}
|
||||
else
|
||||
@@ -188,11 +183,11 @@ ThreadError Ip6::SendDatagram(Message &message, MessageInfo &messageInfo, IpProt
|
||||
switch (ipproto)
|
||||
{
|
||||
case kProtoUdp:
|
||||
SuccessOrExit(error = Udp::UpdateChecksum(message, checksum));
|
||||
SuccessOrExit(error = mUdp.UpdateChecksum(message, checksum));
|
||||
break;
|
||||
|
||||
case kProtoIcmp6:
|
||||
SuccessOrExit(error = Icmp::UpdateChecksum(message, checksum));
|
||||
SuccessOrExit(error = mIcmp.UpdateChecksum(message, checksum));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -209,7 +204,7 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError HandleOptions(Message &message)
|
||||
ThreadError Ip6::HandleOptions(Message &message)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
HopByHopHeader hbhHeader;
|
||||
@@ -228,7 +223,7 @@ ThreadError HandleOptions(Message &message)
|
||||
switch (optionHeader.GetType())
|
||||
{
|
||||
case OptionMpl::kType:
|
||||
SuccessOrExit(error = sMpl->ProcessOption(message));
|
||||
SuccessOrExit(error = mMpl.ProcessOption(message));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -260,7 +255,7 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError HandleFragment(Message &message)
|
||||
ThreadError Ip6::HandleFragment(Message &message)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
FragmentHeader fragmentHeader;
|
||||
@@ -276,7 +271,7 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError HandleExtensionHeaders(Message &message, uint8_t &nextHeader, bool receive)
|
||||
ThreadError Ip6::HandleExtensionHeaders(Message &message, uint8_t &nextHeader, bool receive)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
ExtensionHeader extensionHeader;
|
||||
@@ -317,17 +312,17 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError HandlePayload(Message &message, MessageInfo &messageInfo, uint8_t ipproto)
|
||||
ThreadError Ip6::HandlePayload(Message &message, MessageInfo &messageInfo, uint8_t ipproto)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
switch (ipproto)
|
||||
{
|
||||
case kProtoUdp:
|
||||
ExitNow(error = Udp::HandleMessage(message, messageInfo));
|
||||
ExitNow(error = mUdp.HandleMessage(message, messageInfo));
|
||||
|
||||
case kProtoIcmp6:
|
||||
ExitNow(error = Icmp::HandleMessage(message, messageInfo));
|
||||
ExitNow(error = mIcmp.HandleMessage(message, messageInfo));
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -339,9 +334,9 @@ void Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo &mes
|
||||
ThreadError error = kThreadError_None;
|
||||
Message *messageCopy = NULL;
|
||||
|
||||
VerifyOrExit(sReceiveIp6DatagramCallback != NULL, ;);
|
||||
VerifyOrExit(mReceiveIp6DatagramCallback != NULL, ;);
|
||||
|
||||
if (sIsReceiveIp6FilterEnabled)
|
||||
if (mIsReceiveIp6FilterEnabled)
|
||||
{
|
||||
// do not pass messages sent to/from an RLOC
|
||||
VerifyOrExit(!messageInfo.GetSockAddr().IsRoutingLocator() &&
|
||||
@@ -350,7 +345,7 @@ void Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo &mes
|
||||
switch (aIpProto)
|
||||
{
|
||||
case kProtoIcmp6:
|
||||
if (Icmp::IsEchoEnabled())
|
||||
if (mIcmp.IsEchoEnabled())
|
||||
{
|
||||
IcmpHeader icmp;
|
||||
aMessage.Read(aMessage.GetOffset(), sizeof(icmp), &icmp);
|
||||
@@ -384,13 +379,13 @@ void Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageInfo &mes
|
||||
aMessage.CopyTo(0, 0, aMessage.GetLength(), *messageCopy);
|
||||
messageCopy->SetLinkSecurityEnabled(aMessage.IsLinkSecurityEnabled());
|
||||
|
||||
sReceiveIp6DatagramCallback(messageCopy, sReceiveIp6DatagramCallbackContext);
|
||||
mReceiveIp6DatagramCallback(messageCopy, mReceiveIp6DatagramCallbackContext);
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && messageCopy != NULL)
|
||||
{
|
||||
Message::Free(*messageCopy);
|
||||
messageCopy->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,7 +445,7 @@ ThreadError Ip6::HandleDatagram(Message &message, Netif *netif, int8_t interface
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Netif::IsUnicastAddress(header.GetDestination()))
|
||||
if (IsUnicastAddress(header.GetDestination()))
|
||||
{
|
||||
receive = true;
|
||||
}
|
||||
@@ -464,7 +459,7 @@ ThreadError Ip6::HandleDatagram(Message &message, Netif *netif, int8_t interface
|
||||
}
|
||||
}
|
||||
|
||||
if (!sForwardingEnabled && netif != NULL)
|
||||
if (!mForwardingEnabled && netif != NULL)
|
||||
{
|
||||
forward = false;
|
||||
}
|
||||
@@ -510,13 +505,13 @@ exit:
|
||||
|
||||
if (error != kThreadError_None || !forward)
|
||||
{
|
||||
Message::Free(message);
|
||||
message.Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo)
|
||||
ThreadError Ip6::ForwardMessage(Message &message, MessageInfo &messageInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
int8_t interfaceId;
|
||||
@@ -532,12 +527,12 @@ ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo)
|
||||
// on-link link-local address
|
||||
interfaceId = messageInfo.mInterfaceId;
|
||||
}
|
||||
else if ((interfaceId = Netif::GetOnLinkNetif(messageInfo.GetSockAddr())) > 0)
|
||||
else if ((interfaceId = GetOnLinkNetif(messageInfo.GetSockAddr())) > 0)
|
||||
{
|
||||
// on-link global address
|
||||
;
|
||||
}
|
||||
else if ((interfaceId = Routes::Lookup(messageInfo.GetPeerAddr(), messageInfo.GetSockAddr())) > 0)
|
||||
else if ((interfaceId = mRoutes.Lookup(messageInfo.GetPeerAddr(), messageInfo.GetSockAddr())) > 0)
|
||||
{
|
||||
// route
|
||||
;
|
||||
@@ -549,12 +544,237 @@ ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo)
|
||||
}
|
||||
|
||||
// submit message to interface
|
||||
VerifyOrExit((netif = Netif::GetNetifById(interfaceId)) != NULL, error = kThreadError_NoRoute);
|
||||
VerifyOrExit((netif = GetNetifById(interfaceId)) != NULL, error = kThreadError_NoRoute);
|
||||
SuccessOrExit(error = netif->SendMessage(message));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Ip6::AddNetif(Netif &aNetif)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Netif *netif;
|
||||
|
||||
if (mNetifListHead == NULL)
|
||||
{
|
||||
mNetifListHead = &aNetif;
|
||||
}
|
||||
else
|
||||
{
|
||||
netif = mNetifListHead;
|
||||
|
||||
do
|
||||
{
|
||||
if (netif == &aNetif)
|
||||
{
|
||||
ExitNow(error = kThreadError_Busy);
|
||||
}
|
||||
}
|
||||
while (netif->mNext);
|
||||
|
||||
netif->mNext = &aNetif;
|
||||
}
|
||||
|
||||
aNetif.mNext = NULL;
|
||||
|
||||
if (aNetif.mInterfaceId < 0)
|
||||
{
|
||||
aNetif.mInterfaceId = mNextInterfaceId++;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Ip6::RemoveNetif(Netif &aNetif)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(mNetifListHead != NULL, error = kThreadError_Busy);
|
||||
|
||||
if (mNetifListHead == &aNetif)
|
||||
{
|
||||
mNetifListHead = aNetif.mNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Netif *netif = mNetifListHead; netif->mNext; netif = netif->mNext)
|
||||
{
|
||||
if (netif->mNext != &aNetif)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
netif->mNext = aNetif.mNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aNetif.mNext = NULL;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Netif *Ip6::GetNetifList()
|
||||
{
|
||||
return mNetifListHead;
|
||||
}
|
||||
|
||||
Netif *Ip6::GetNetifById(int8_t aInterfaceId)
|
||||
{
|
||||
Netif *netif;
|
||||
|
||||
for (netif = mNetifListHead; netif; netif = netif->mNext)
|
||||
{
|
||||
if (netif->GetInterfaceId() == aInterfaceId)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return netif;
|
||||
}
|
||||
|
||||
Netif *Ip6::GetNetifByName(char *aName)
|
||||
{
|
||||
Netif *netif;
|
||||
|
||||
for (netif = mNetifListHead; netif; netif = netif->mNext)
|
||||
{
|
||||
if (strcmp(netif->GetName(), aName) == 0)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return netif;
|
||||
}
|
||||
|
||||
bool Ip6::IsUnicastAddress(const Address &aAddress)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
for (Netif *netif = mNetifListHead; netif; netif = netif->mNext)
|
||||
{
|
||||
rval = netif->IsUnicastAddress(aAddress);
|
||||
|
||||
if (rval)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
const NetifUnicastAddress *Ip6::SelectSourceAddress(MessageInfo &aMessageInfo)
|
||||
{
|
||||
Address *destination = &aMessageInfo.GetPeerAddr();
|
||||
int interfaceId = aMessageInfo.mInterfaceId;
|
||||
const NetifUnicastAddress *rvalAddr = NULL;
|
||||
const Address *candidateAddr;
|
||||
int8_t candidateId;
|
||||
int8_t rvalIface = 0;
|
||||
|
||||
for (Netif *netif = GetNetifList(); netif; netif = netif->mNext)
|
||||
{
|
||||
candidateId = netif->GetInterfaceId();
|
||||
|
||||
for (const NetifUnicastAddress *addr = netif->mUnicastAddresses; addr; addr = addr->GetNext())
|
||||
{
|
||||
candidateAddr = &addr->GetAddress();
|
||||
|
||||
if (destination->IsLinkLocal() || destination->IsMulticast())
|
||||
{
|
||||
if (interfaceId != candidateId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (rvalAddr == NULL)
|
||||
{
|
||||
// Rule 0: Prefer any address
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
else if (*candidateAddr == *destination)
|
||||
{
|
||||
// Rule 1: Prefer same address
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
goto exit;
|
||||
}
|
||||
else if (candidateAddr->GetScope() < rvalAddr->GetAddress().GetScope())
|
||||
{
|
||||
// Rule 2: Prefer appropriate scope
|
||||
if (candidateAddr->GetScope() >= destination->GetScope())
|
||||
{
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
}
|
||||
else if (candidateAddr->GetScope() > rvalAddr->GetAddress().GetScope())
|
||||
{
|
||||
if (rvalAddr->GetAddress().GetScope() < destination->GetScope())
|
||||
{
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
}
|
||||
else if (addr->mPreferredLifetime != 0 && rvalAddr->mPreferredLifetime == 0)
|
||||
{
|
||||
// Rule 3: Avoid deprecated addresses
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
else if (aMessageInfo.mInterfaceId != 0 && aMessageInfo.mInterfaceId == candidateId &&
|
||||
rvalIface != candidateId)
|
||||
{
|
||||
// Rule 4: Prefer home address
|
||||
// Rule 5: Prefer outgoing interface
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
else if (destination->PrefixMatch(*candidateAddr) > destination->PrefixMatch(rvalAddr->GetAddress()))
|
||||
{
|
||||
// Rule 6: Prefer matching label
|
||||
// Rule 7: Prefer public address
|
||||
// Rule 8: Use longest prefix matching
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
aMessageInfo.mInterfaceId = rvalIface;
|
||||
return rvalAddr;
|
||||
}
|
||||
|
||||
int8_t Ip6::GetOnLinkNetif(const Address &aAddress)
|
||||
{
|
||||
int8_t rval = -1;
|
||||
|
||||
for (Netif *netif = mNetifListHead; netif; netif = netif->mNext)
|
||||
{
|
||||
for (const NetifUnicastAddress *cur = netif->mUnicastAddresses; cur; cur = cur->GetNext())
|
||||
{
|
||||
if (cur->GetAddress().PrefixMatch(aAddress) >= cur->mPrefixLength)
|
||||
{
|
||||
ExitNow(rval = netif->GetInterfaceId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
} // namespace Ip6
|
||||
} // namespace Thread
|
||||
|
||||
+125
-402
@@ -39,9 +39,14 @@
|
||||
#include <openthread-types.h>
|
||||
#include <common/encoding.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <net/icmp6.hpp>
|
||||
#include <net/ip6_address.hpp>
|
||||
#include <net/ip6_headers.hpp>
|
||||
#include <net/ip6_routes.hpp>
|
||||
#include <net/ip6_mpl.hpp>
|
||||
#include <net/netif.hpp>
|
||||
#include <net/socket.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
|
||||
using Thread::Encoding::BigEndian::HostSwap16;
|
||||
using Thread::Encoding::BigEndian::HostSwap32;
|
||||
@@ -84,393 +89,6 @@ namespace Ip6 {
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internet Protocol Numbers
|
||||
*/
|
||||
enum IpProto
|
||||
{
|
||||
kProtoHopOpts = 0, ///< IPv6 Hop-by-Hop Option
|
||||
kProtoTcp = 6, ///< Transmission Control Protocol
|
||||
kProtoUdp = 17, ///< User Datagram
|
||||
kProtoIp6 = 41, ///< IPv6 encapsulation
|
||||
kProtoRouting = 43, ///< Routing Header for IPv6
|
||||
kProtoFragment = 44, ///< Fragment Header for IPv6
|
||||
kProtoIcmp6 = 58, ///< ICMP for IPv6
|
||||
kProtoNone = 59, ///< No Next Header for IPv6
|
||||
kProtoDstOpts = 60, ///< Destination Options for IPv6
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kVersionClassFlowSize = 4, ///< Combined size of Version, Class, Flow Label in bytes.
|
||||
};
|
||||
|
||||
/**
|
||||
* This structure represents an IPv6 header.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct HeaderPoD
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t m8[kVersionClassFlowSize / sizeof(uint8_t)];
|
||||
uint16_t m16[kVersionClassFlowSize / sizeof(uint16_t)];
|
||||
uint32_t m32[kVersionClassFlowSize / sizeof(uint32_t)];
|
||||
} mVersionClassFlow; ///< Version, Class, Flow Label
|
||||
uint16_t mPayloadLength; ///< Payload Length
|
||||
uint8_t mNextHeader; ///< Next Header
|
||||
uint8_t mHopLimit; ///< Hop Limit
|
||||
otIp6Address mSource; ///< Source
|
||||
otIp6Address mDestination; ///< Destination
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 header generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class Header: private HeaderPoD
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the IPv6 header.
|
||||
*
|
||||
*/
|
||||
void Init() { mVersionClassFlow.m32[0] = 0; mVersionClassFlow.m8[0] = kVersion6; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the IPv6 Version is set to 6.
|
||||
*
|
||||
* @retval TRUE If the IPv6 Version is set to 6.
|
||||
* @retval FALSE If the IPv6 Version is not set to 6.
|
||||
*
|
||||
*/
|
||||
bool IsVersion6() const { return (mVersionClassFlow.m8[0] & kVersionMask) == kVersion6; }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Payload Length value.
|
||||
*
|
||||
* @returns The IPv6 Payload Length value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetPayloadLength() { return HostSwap16(mPayloadLength); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Payload Length value.
|
||||
*
|
||||
* @param[in] aLength The IPv6 Payload Length value.
|
||||
*
|
||||
*/
|
||||
void SetPayloadLength(uint16_t aLength) { mPayloadLength = HostSwap16(aLength); }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Next Header value.
|
||||
*
|
||||
* @returns The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Next Header value.
|
||||
*
|
||||
* @param[in] aNextHeader The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Hop Limit value.
|
||||
*
|
||||
* @returns The IPv6 Hop Limit value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetHopLimit() const { return mHopLimit; }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Hop Limit value.
|
||||
*
|
||||
* @param[in] aHopLimit The IPv6 Hop Limit value.
|
||||
*
|
||||
*/
|
||||
void SetHopLimit(uint8_t aHopLimit) { mHopLimit = aHopLimit; }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Source address.
|
||||
*
|
||||
* @returns A reference to the IPv6 Source address.
|
||||
*
|
||||
*/
|
||||
Address &GetSource() { return static_cast<Address &>(mSource); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Source address.
|
||||
*
|
||||
* @param[in] aSource A reference to the IPv6 Source address.
|
||||
*
|
||||
*/
|
||||
void SetSource(const Address &aSource) { mSource = aSource; }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Destination address.
|
||||
*
|
||||
* @returns A reference to the IPv6 Destination address.
|
||||
*
|
||||
*/
|
||||
Address &GetDestination() { return static_cast<Address &>(mDestination); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Destination address.
|
||||
*
|
||||
* @param[in] aDestination A reference to the IPv6 Destination address.
|
||||
*
|
||||
*/
|
||||
void SetDestination(const Address &aDestination) { mDestination = aDestination; }
|
||||
|
||||
/**
|
||||
* This static method returns the byte offset of the IPv6 Payload Length field.
|
||||
*
|
||||
* @returns The byte offset of the IPv6 Payload Length field.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetPayloadLengthOffset() { return offsetof(HeaderPoD, mPayloadLength); }
|
||||
|
||||
/**
|
||||
* This static method returns the byte offset of the IPv6 Hop Limit field.
|
||||
*
|
||||
* @returns The byte offset of the IPv6 Hop Limit field.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetHopLimitOffset() { return offsetof(HeaderPoD, mHopLimit); }
|
||||
|
||||
/**
|
||||
* This static method returns the size of the IPv6 Hop Limit field.
|
||||
*
|
||||
* @returns The size of the IPv6 Hop Limit field.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetHopLimitSize() { return sizeof(uint8_t); }
|
||||
|
||||
/**
|
||||
* This static method returns the byte offset of the IPv6 Destination field.
|
||||
*
|
||||
* @returns The byte offset of the IPv6 Destination field.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetDestinationOffset() { return offsetof(HeaderPoD, mDestination); }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kVersion6 = 0x60,
|
||||
kVersionMask = 0xf0,
|
||||
};
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 Extension Header generation and processing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class ExtensionHeader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method returns the IPv6 Next Header value.
|
||||
*
|
||||
* @returns The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Next Header value.
|
||||
*
|
||||
* @param[in] aNextHeader The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Header Extension Length value.
|
||||
*
|
||||
* @returns The IPv6 Header Extension Length value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetLength() const { return mLength; }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Header Extension Length value.
|
||||
*
|
||||
* @param[in] aLength The IPv6 Header Extension Length value.
|
||||
*
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
private:
|
||||
uint8_t mNextHeader;
|
||||
uint8_t mLength;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 Hop-by-Hop Options Header generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class HopByHopHeader: public ExtensionHeader
|
||||
{
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 Options generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class OptionHeader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method returns the IPv6 Option Type value.
|
||||
*
|
||||
* @returns The IPv6 Option Type value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetType() const { return mType; }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Option Type value.
|
||||
*
|
||||
* @param[in] aType The IPv6 Option Type value.
|
||||
*
|
||||
*/
|
||||
void SetType(uint8_t aType) { mType = aType; }
|
||||
|
||||
/**
|
||||
* IPv6 Option Type actions for unrecognized IPv6 Options.
|
||||
*
|
||||
*/
|
||||
enum Action
|
||||
{
|
||||
kActionSkip = 0x00, ///< skip over this option and continue processing the header
|
||||
kActionDiscard = 0x40, ///< discard the packet
|
||||
kActionForceIcmp = 0x80, ///< discard the packet and forcibly send an ICMP Parameter Problem
|
||||
kActionIcmp = 0xc0, ///< discard packet and conditionally send an ICMP Parameter Problem
|
||||
kActionMask = 0xc0, ///< mask for action bits
|
||||
};
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Option action for unrecognized IPv6 Options.
|
||||
*
|
||||
* @returns The IPv6 Option action for unrecognized IPv6 Options.
|
||||
*
|
||||
*/
|
||||
Action GetAction() const { return static_cast<Action>(mType & kActionMask); }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Option Length value.
|
||||
*
|
||||
* @returns The IPv6 Option Length value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetLength() const { return mLength; }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Option Length value.
|
||||
*
|
||||
* @param[in] aLength The IPv6 Option Length value.
|
||||
*
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
private:
|
||||
uint8_t mType;
|
||||
uint8_t mLength;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 Fragment Header generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class FragmentHeader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the IPv6 Fragment header.
|
||||
*
|
||||
*/
|
||||
void Init() { mReserved = 0; mIdentification = 0; }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Next Header value.
|
||||
*
|
||||
* @returns The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Next Header value.
|
||||
*
|
||||
* @param[in] aNextHeader The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
|
||||
|
||||
/**
|
||||
* This method returns the Fragment Offset value.
|
||||
*
|
||||
* @returns The Fragment Offset value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetOffset() { return (HostSwap16(mOffsetMore) & kOffsetMask) >> kOffsetOffset; }
|
||||
|
||||
/**
|
||||
* This method sets the Fragment Offset value.
|
||||
*
|
||||
* @param[in] aOffset The Fragment Offset value.
|
||||
*/
|
||||
void SetOffset(uint16_t aOffset) {
|
||||
uint16_t tmp = HostSwap16(mOffsetMore);
|
||||
tmp = (tmp & ~kOffsetMask) | ((aOffset << kOffsetOffset) & kOffsetMask);
|
||||
mOffsetMore = HostSwap16(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the M flag value.
|
||||
*
|
||||
* @returns The M flag value.
|
||||
*
|
||||
*/
|
||||
bool IsMoreFlagSet() { return HostSwap16(mOffsetMore) & kMoreFlag; }
|
||||
|
||||
/**
|
||||
* This method clears the M flag value.
|
||||
*
|
||||
*/
|
||||
void ClearMoreFlag() { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) & ~kMoreFlag); }
|
||||
|
||||
/**
|
||||
* This method sets the M flag value.
|
||||
*
|
||||
*/
|
||||
void SetMoreFlag() { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) | kMoreFlag); }
|
||||
|
||||
private:
|
||||
uint8_t mNextHeader;
|
||||
uint8_t mReserved;
|
||||
|
||||
enum
|
||||
{
|
||||
kOffsetOffset = 3,
|
||||
kOffsetMask = 0xfff8,
|
||||
kMoreFlag = 1,
|
||||
};
|
||||
uint16_t mOffsetMore;
|
||||
uint32_t mIdentification;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements the core IPv6 message processing.
|
||||
*
|
||||
@@ -485,22 +103,22 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* This static method allocates a new message buffer from the buffer pool.
|
||||
* This method allocates a new message buffer from the buffer pool.
|
||||
*
|
||||
* @param[in] aReserved The number of header bytes to reserve following the IPv6 header.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if insufficient message buffers are available.
|
||||
*
|
||||
*/
|
||||
static Message *NewMessage(uint16_t aReserved);
|
||||
Message *NewMessage(uint16_t aReserved);
|
||||
|
||||
/**
|
||||
* This static method for initialization.
|
||||
* This constructor initializes the object.
|
||||
*/
|
||||
static void Init(void);
|
||||
Ip6(void);
|
||||
|
||||
/**
|
||||
* This static method sends an IPv6 datagram.
|
||||
* This method sends an IPv6 datagram.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
@@ -510,10 +128,10 @@ public:
|
||||
* @retval kThreadError_NoBufs Insufficient available buffer to add the IPv6 headers.
|
||||
*
|
||||
*/
|
||||
static ThreadError SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, IpProto aIpProto);
|
||||
ThreadError SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, IpProto aIpProto);
|
||||
|
||||
/**
|
||||
* This static method processes a received IPv6 datagram.
|
||||
* This method processes a received IPv6 datagram.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
* @param[in] aNetif A pointer to the network interface that received the message.
|
||||
@@ -525,8 +143,8 @@ public:
|
||||
* @retval kThreadError_Drop Message processing failed and the message should be dropped.
|
||||
*
|
||||
*/
|
||||
static ThreadError HandleDatagram(Message &aMessage, Netif *aNetif, int8_t aInterfaceId,
|
||||
const void *aLinkMessageInfo, bool aFromNcpHost);
|
||||
ThreadError HandleDatagram(Message &aMessage, Netif *aNetif, int8_t aInterfaceId,
|
||||
const void *aLinkMessageInfo, bool aFromNcpHost);
|
||||
|
||||
/**
|
||||
* This static method updates a checksum.
|
||||
@@ -590,7 +208,7 @@ public:
|
||||
* @sa SetReceiveIp6FilterEnabled
|
||||
*
|
||||
*/
|
||||
static void SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext);
|
||||
void SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not Thread control traffic is filtered out when delivering IPv6 datagrams
|
||||
@@ -602,7 +220,7 @@ public:
|
||||
* @sa SetReceiveIp6FilterEnabled
|
||||
*
|
||||
*/
|
||||
static bool IsReceiveIp6FilterEnabled(void);
|
||||
bool IsReceiveIp6FilterEnabled(void);
|
||||
|
||||
/**
|
||||
* This method sets whether or not Thread control traffic is filtered out when delivering IPv6 datagrams
|
||||
@@ -614,18 +232,123 @@ public:
|
||||
* @sa IsReceiveIp6FilterEnabled
|
||||
*
|
||||
*/
|
||||
static void SetReceiveIp6FilterEnabled(bool aEnabled);
|
||||
void SetReceiveIp6FilterEnabled(bool aEnabled);
|
||||
|
||||
/**
|
||||
* This static method enables/disables IPv6 forwarding.
|
||||
* This method enables/disables IPv6 forwarding.
|
||||
*
|
||||
* @param[in] aEnable TRUE to enable IPv6 forwarding, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
static void SetForwardingEnabled(bool aEnable);
|
||||
void SetForwardingEnabled(bool aEnable);
|
||||
|
||||
/**
|
||||
* This method enables the network interface.
|
||||
*
|
||||
* @param aNetif A reference to the network interface.
|
||||
*
|
||||
* @retval kThreadError_None Successfully enabled the network interface.
|
||||
* @retval KThreadError_Busy The network interface was already enabled.
|
||||
*
|
||||
*/
|
||||
ThreadError AddNetif(Netif &aNetif);
|
||||
|
||||
/**
|
||||
* This method disables the network interface.
|
||||
*
|
||||
* @param aNetif A reference to the network interface.
|
||||
*
|
||||
* @retval kThreadError_None Successfully disabled the network interface.
|
||||
* @retval KThreadError_Busy The network interface was already disabled.
|
||||
*
|
||||
*/
|
||||
ThreadError RemoveNetif(Netif &aNetif);
|
||||
|
||||
/**
|
||||
* This method returns the network interface list.
|
||||
*
|
||||
* @returns A pointer to the network interface list.
|
||||
*
|
||||
*/
|
||||
Netif *GetNetifList(void);
|
||||
|
||||
/**
|
||||
* This method returns the network interface identified by @p aInterfaceId.
|
||||
*
|
||||
* @param[in] aInterfaceId The network interface ID.
|
||||
*
|
||||
* @returns A pointer to the network interface or NULL if none is found.
|
||||
*
|
||||
*/
|
||||
Netif *GetNetifById(int8_t aInterfaceId);
|
||||
|
||||
/**
|
||||
* This method returns the network interface identified by @p aName.
|
||||
*
|
||||
* @param[in] aName A pointer to a NULL-terminated string.
|
||||
*
|
||||
* @returns A pointer to the network interface or NULL if none is found.
|
||||
*
|
||||
*/
|
||||
Netif *GetNetifByName(char *aName);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not @p aAddress is assigned to a network interface.
|
||||
*
|
||||
* @param[in] aAddress A reference to the IPv6 address.
|
||||
*
|
||||
* @retval TRUE If the IPv6 address is assigned to a network interface.
|
||||
* @retval FALSE If the IPv6 address is not assigned to any network interface.
|
||||
*
|
||||
*/
|
||||
bool IsUnicastAddress(const Address &aAddress);
|
||||
|
||||
/**
|
||||
* This method perform default source address selection.
|
||||
*
|
||||
* @param[in] aMessageInfo A reference to the message information.
|
||||
*
|
||||
* @returns A pointer to the selected IPv6 source address or NULL if no source address was found.
|
||||
*
|
||||
*/
|
||||
const NetifUnicastAddress *SelectSourceAddress(MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This method determines which network interface @p aAddress is on-link, if any.
|
||||
*
|
||||
* @param[in] aAddress A reference to the IPv6 address.
|
||||
*
|
||||
* @returns The network interface identifier for the on-link interface or -1 if none is found.
|
||||
*
|
||||
*/
|
||||
int8_t GetOnLinkNetif(const Address &aAddress);
|
||||
|
||||
Routes mRoutes;
|
||||
Icmp mIcmp;
|
||||
Udp mUdp;
|
||||
|
||||
MessagePool mMessagePool;
|
||||
TaskletScheduler mTaskletScheduler;
|
||||
TimerScheduler mTimerScheduler;
|
||||
|
||||
private:
|
||||
static void ProcessReceiveCallback(const Message &aMessage, const MessageInfo &aMessageInfo, uint8_t aIpProto);
|
||||
void ProcessReceiveCallback(const Message &aMessage, const MessageInfo &aMessageInfo, uint8_t aIpProto);
|
||||
ThreadError HandleExtensionHeaders(Message &message, uint8_t &nextHeader, bool receive);
|
||||
ThreadError HandleFragment(Message &message);
|
||||
ThreadError AddMplOption(Message &message, Header &header, IpProto nextHeader, uint16_t payloadLength);
|
||||
ThreadError HandleOptions(Message &message);
|
||||
ThreadError HandlePayload(Message &message, MessageInfo &messageInfo, uint8_t ipproto);
|
||||
ThreadError ForwardMessage(Message &message, MessageInfo &messageInfo);
|
||||
|
||||
Mpl mMpl;
|
||||
bool mForwardingEnabled;
|
||||
|
||||
otReceiveIp6DatagramCallback mReceiveIp6DatagramCallback;
|
||||
void *mReceiveIp6DatagramCallbackContext;
|
||||
bool mIsReceiveIp6FilterEnabled;
|
||||
|
||||
Netif *mNetifListHead;
|
||||
int8_t mNextInterfaceId;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 IPv6 packet processing.
|
||||
*/
|
||||
|
||||
#ifndef IP6_HEADERS_HPP_
|
||||
#define IP6_HEADERS_HPP_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <common/encoding.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <net/ip6_address.hpp>
|
||||
#include <net/netif.hpp>
|
||||
#include <net/socket.hpp>
|
||||
|
||||
using Thread::Encoding::BigEndian::HostSwap16;
|
||||
|
||||
namespace Thread {
|
||||
|
||||
/**
|
||||
* @namespace Thread::Ip6
|
||||
*
|
||||
* @brief
|
||||
* This namespace includes definitions for IPv6 networking.
|
||||
*
|
||||
*/
|
||||
namespace Ip6 {
|
||||
|
||||
/**
|
||||
* @addtogroup core-ipv6
|
||||
*
|
||||
* @brief
|
||||
* This module includes definitions for the IPv6 network layer.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @defgroup core-ip6-icmp6 ICMPv6
|
||||
* @defgroup core-ip6-ip6 IPv6
|
||||
* @defgroup core-ip6-mpl MPL
|
||||
* @defgroup core-ip6-netif Network Interfaces
|
||||
*
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup core-ip6-ip6
|
||||
*
|
||||
* @brief
|
||||
* This module includes definitions for core IPv6 networking.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internet Protocol Numbers
|
||||
*/
|
||||
enum IpProto
|
||||
{
|
||||
kProtoHopOpts = 0, ///< IPv6 Hop-by-Hop Option
|
||||
kProtoTcp = 6, ///< Transmission Control Protocol
|
||||
kProtoUdp = 17, ///< User Datagram
|
||||
kProtoIp6 = 41, ///< IPv6 encapsulation
|
||||
kProtoRouting = 43, ///< Routing Header for IPv6
|
||||
kProtoFragment = 44, ///< Fragment Header for IPv6
|
||||
kProtoIcmp6 = 58, ///< ICMP for IPv6
|
||||
kProtoNone = 59, ///< No Next Header for IPv6
|
||||
kProtoDstOpts = 60, ///< Destination Options for IPv6
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kVersionClassFlowSize = 4, ///< Combined size of Version, Class, Flow Label in bytes.
|
||||
};
|
||||
|
||||
/**
|
||||
* This structure represents an IPv6 header.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct HeaderPoD
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t m8[kVersionClassFlowSize / sizeof(uint8_t)];
|
||||
uint16_t m16[kVersionClassFlowSize / sizeof(uint16_t)];
|
||||
uint32_t m32[kVersionClassFlowSize / sizeof(uint32_t)];
|
||||
} mVersionClassFlow; ///< Version, Class, Flow Label
|
||||
uint16_t mPayloadLength; ///< Payload Length
|
||||
uint8_t mNextHeader; ///< Next Header
|
||||
uint8_t mHopLimit; ///< Hop Limit
|
||||
otIp6Address mSource; ///< Source
|
||||
otIp6Address mDestination; ///< Destination
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 header generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class Header: private HeaderPoD
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the IPv6 header.
|
||||
*
|
||||
*/
|
||||
void Init() { mVersionClassFlow.m32[0] = 0; mVersionClassFlow.m8[0] = kVersion6; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the IPv6 Version is set to 6.
|
||||
*
|
||||
* @retval TRUE If the IPv6 Version is set to 6.
|
||||
* @retval FALSE If the IPv6 Version is not set to 6.
|
||||
*
|
||||
*/
|
||||
bool IsVersion6() const { return (mVersionClassFlow.m8[0] & kVersionMask) == kVersion6; }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Payload Length value.
|
||||
*
|
||||
* @returns The IPv6 Payload Length value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetPayloadLength() { return HostSwap16(mPayloadLength); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Payload Length value.
|
||||
*
|
||||
* @param[in] aLength The IPv6 Payload Length value.
|
||||
*
|
||||
*/
|
||||
void SetPayloadLength(uint16_t aLength) { mPayloadLength = HostSwap16(aLength); }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Next Header value.
|
||||
*
|
||||
* @returns The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Next Header value.
|
||||
*
|
||||
* @param[in] aNextHeader The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Hop Limit value.
|
||||
*
|
||||
* @returns The IPv6 Hop Limit value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetHopLimit() const { return mHopLimit; }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Hop Limit value.
|
||||
*
|
||||
* @param[in] aHopLimit The IPv6 Hop Limit value.
|
||||
*
|
||||
*/
|
||||
void SetHopLimit(uint8_t aHopLimit) { mHopLimit = aHopLimit; }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Source address.
|
||||
*
|
||||
* @returns A reference to the IPv6 Source address.
|
||||
*
|
||||
*/
|
||||
Address &GetSource() { return static_cast<Address &>(mSource); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Source address.
|
||||
*
|
||||
* @param[in] aSource A reference to the IPv6 Source address.
|
||||
*
|
||||
*/
|
||||
void SetSource(const Address &aSource) { mSource = aSource; }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Destination address.
|
||||
*
|
||||
* @returns A reference to the IPv6 Destination address.
|
||||
*
|
||||
*/
|
||||
Address &GetDestination() { return static_cast<Address &>(mDestination); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Destination address.
|
||||
*
|
||||
* @param[in] aDestination A reference to the IPv6 Destination address.
|
||||
*
|
||||
*/
|
||||
void SetDestination(const Address &aDestination) { mDestination = aDestination; }
|
||||
|
||||
/**
|
||||
* This static method returns the byte offset of the IPv6 Payload Length field.
|
||||
*
|
||||
* @returns The byte offset of the IPv6 Payload Length field.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetPayloadLengthOffset() { return offsetof(HeaderPoD, mPayloadLength); }
|
||||
|
||||
/**
|
||||
* This static method returns the byte offset of the IPv6 Hop Limit field.
|
||||
*
|
||||
* @returns The byte offset of the IPv6 Hop Limit field.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetHopLimitOffset() { return offsetof(HeaderPoD, mHopLimit); }
|
||||
|
||||
/**
|
||||
* This static method returns the size of the IPv6 Hop Limit field.
|
||||
*
|
||||
* @returns The size of the IPv6 Hop Limit field.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetHopLimitSize() { return sizeof(uint8_t); }
|
||||
|
||||
/**
|
||||
* This static method returns the byte offset of the IPv6 Destination field.
|
||||
*
|
||||
* @returns The byte offset of the IPv6 Destination field.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetDestinationOffset() { return offsetof(HeaderPoD, mDestination); }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kVersion6 = 0x60,
|
||||
kVersionMask = 0xf0,
|
||||
};
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 Extension Header generation and processing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class ExtensionHeader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method returns the IPv6 Next Header value.
|
||||
*
|
||||
* @returns The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Next Header value.
|
||||
*
|
||||
* @param[in] aNextHeader The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Header Extension Length value.
|
||||
*
|
||||
* @returns The IPv6 Header Extension Length value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetLength() const { return mLength; }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Header Extension Length value.
|
||||
*
|
||||
* @param[in] aLength The IPv6 Header Extension Length value.
|
||||
*
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
private:
|
||||
uint8_t mNextHeader;
|
||||
uint8_t mLength;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 Hop-by-Hop Options Header generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class HopByHopHeader: public ExtensionHeader
|
||||
{
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 Options generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class OptionHeader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method returns the IPv6 Option Type value.
|
||||
*
|
||||
* @returns The IPv6 Option Type value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetType() const { return mType; }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Option Type value.
|
||||
*
|
||||
* @param[in] aType The IPv6 Option Type value.
|
||||
*
|
||||
*/
|
||||
void SetType(uint8_t aType) { mType = aType; }
|
||||
|
||||
/**
|
||||
* IPv6 Option Type actions for unrecognized IPv6 Options.
|
||||
*
|
||||
*/
|
||||
enum Action
|
||||
{
|
||||
kActionSkip = 0x00, ///< skip over this option and continue processing the header
|
||||
kActionDiscard = 0x40, ///< discard the packet
|
||||
kActionForceIcmp = 0x80, ///< discard the packet and forcibly send an ICMP Parameter Problem
|
||||
kActionIcmp = 0xc0, ///< discard packet and conditionally send an ICMP Parameter Problem
|
||||
kActionMask = 0xc0, ///< mask for action bits
|
||||
};
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Option action for unrecognized IPv6 Options.
|
||||
*
|
||||
* @returns The IPv6 Option action for unrecognized IPv6 Options.
|
||||
*
|
||||
*/
|
||||
Action GetAction() const { return static_cast<Action>(mType & kActionMask); }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Option Length value.
|
||||
*
|
||||
* @returns The IPv6 Option Length value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetLength() const { return mLength; }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Option Length value.
|
||||
*
|
||||
* @param[in] aLength The IPv6 Option Length value.
|
||||
*
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
private:
|
||||
uint8_t mType;
|
||||
uint8_t mLength;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IPv6 Fragment Header generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class FragmentHeader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the IPv6 Fragment header.
|
||||
*
|
||||
*/
|
||||
void Init() { mReserved = 0; mIdentification = 0; }
|
||||
|
||||
/**
|
||||
* This method returns the IPv6 Next Header value.
|
||||
*
|
||||
* @returns The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
IpProto GetNextHeader() const { return static_cast<IpProto>(mNextHeader); }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 Next Header value.
|
||||
*
|
||||
* @param[in] aNextHeader The IPv6 Next Header value.
|
||||
*
|
||||
*/
|
||||
void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }
|
||||
|
||||
/**
|
||||
* This method returns the Fragment Offset value.
|
||||
*
|
||||
* @returns The Fragment Offset value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetOffset() { return (HostSwap16(mOffsetMore) & kOffsetMask) >> kOffsetOffset; }
|
||||
|
||||
/**
|
||||
* This method sets the Fragment Offset value.
|
||||
*
|
||||
* @param[in] aOffset The Fragment Offset value.
|
||||
*/
|
||||
void SetOffset(uint16_t aOffset) {
|
||||
uint16_t tmp = HostSwap16(mOffsetMore);
|
||||
tmp = (tmp & ~kOffsetMask) | ((aOffset << kOffsetOffset) & kOffsetMask);
|
||||
mOffsetMore = HostSwap16(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the M flag value.
|
||||
*
|
||||
* @returns The M flag value.
|
||||
*
|
||||
*/
|
||||
bool IsMoreFlagSet() { return HostSwap16(mOffsetMore) & kMoreFlag; }
|
||||
|
||||
/**
|
||||
* This method clears the M flag value.
|
||||
*
|
||||
*/
|
||||
void ClearMoreFlag() { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) & ~kMoreFlag); }
|
||||
|
||||
/**
|
||||
* This method sets the M flag value.
|
||||
*
|
||||
*/
|
||||
void SetMoreFlag() { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) | kMoreFlag); }
|
||||
|
||||
private:
|
||||
uint8_t mNextHeader;
|
||||
uint8_t mReserved;
|
||||
|
||||
enum
|
||||
{
|
||||
kOffsetOffset = 3,
|
||||
kOffsetMask = 0xfff8,
|
||||
kMoreFlag = 1,
|
||||
};
|
||||
uint16_t mOffsetMore;
|
||||
uint32_t mIdentification;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
} // namespace Ip6
|
||||
} // namespace Thread
|
||||
|
||||
#endif // NET_IP6_HEADERS_HPP_
|
||||
@@ -33,13 +33,14 @@
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/ip6_mpl.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
Mpl::Mpl():
|
||||
mTimer(&HandleTimer, this)
|
||||
Mpl::Mpl(Ip6 &aIp6):
|
||||
mTimer(aIp6.mTimerScheduler, &HandleTimer, this)
|
||||
{
|
||||
memset(mEntries, 0, sizeof(mEntries));
|
||||
mSequence = 0;
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <openthread-types.h>
|
||||
#include <common/message.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/ip6_headers.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
@@ -173,8 +173,10 @@ public:
|
||||
/**
|
||||
* This constructor initializes the MPL object.
|
||||
*
|
||||
* @param[in] aIp6 A reference to the IPv6 network object.
|
||||
*
|
||||
*/
|
||||
Mpl(void);
|
||||
Mpl(Ip6 &aIp6);
|
||||
|
||||
/**
|
||||
* This method initializes the MPL option.
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
* This file implements IPv6 route tables.
|
||||
*/
|
||||
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/ip6_routes.hpp>
|
||||
#include <net/netif.hpp>
|
||||
#include <common/code_utils.hpp>
|
||||
@@ -39,19 +40,23 @@
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
static Route *sRoutes = NULL;
|
||||
Routes::Routes(Ip6 &aIp6):
|
||||
mRoutes(NULL),
|
||||
mIp6(aIp6)
|
||||
{
|
||||
}
|
||||
|
||||
ThreadError Routes::Add(Route &aRoute)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
for (Route *cur = sRoutes; cur; cur = cur->mNext)
|
||||
for (Route *cur = mRoutes; cur; cur = cur->mNext)
|
||||
{
|
||||
VerifyOrExit(cur != &aRoute, error = kThreadError_Busy);
|
||||
}
|
||||
|
||||
aRoute.mNext = sRoutes;
|
||||
sRoutes = &aRoute;
|
||||
aRoute.mNext = mRoutes;
|
||||
mRoutes = &aRoute;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -59,13 +64,13 @@ exit:
|
||||
|
||||
ThreadError Routes::Remove(Route &aRoute)
|
||||
{
|
||||
if (&aRoute == sRoutes)
|
||||
if (&aRoute == mRoutes)
|
||||
{
|
||||
sRoutes = aRoute.mNext;
|
||||
mRoutes = aRoute.mNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Route *cur = sRoutes; cur; cur = cur->mNext)
|
||||
for (Route *cur = mRoutes; cur; cur = cur->mNext)
|
||||
{
|
||||
if (cur->mNext == &aRoute)
|
||||
{
|
||||
@@ -86,7 +91,7 @@ int8_t Routes::Lookup(const Address &aSource, const Address &aDestination)
|
||||
uint8_t prefixMatch;
|
||||
int8_t rval = -1;
|
||||
|
||||
for (Route *cur = sRoutes; cur; cur = cur->mNext)
|
||||
for (Route *cur = mRoutes; cur; cur = cur->mNext)
|
||||
{
|
||||
prefixMatch = cur->mPrefix.PrefixMatch(aDestination);
|
||||
|
||||
@@ -109,7 +114,7 @@ int8_t Routes::Lookup(const Address &aSource, const Address &aDestination)
|
||||
rval = cur->mInterfaceId;
|
||||
}
|
||||
|
||||
for (Netif *netif = Netif::GetNetifList(); netif; netif = netif->GetNext())
|
||||
for (Netif *netif = mIp6.GetNetifList(); netif; netif = netif->GetNext())
|
||||
{
|
||||
if (netif->RouteLookup(aSource, aDestination, &prefixMatch) == kThreadError_None &&
|
||||
static_cast<int8_t>(prefixMatch) > maxPrefixMatch)
|
||||
|
||||
@@ -68,7 +68,15 @@ class Routes
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This static method adds an IPv6 route.
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aIp6 A reference to the IPv6 network object.
|
||||
*
|
||||
*/
|
||||
Routes(Ip6 &aIp6);
|
||||
|
||||
/**
|
||||
* This method adds an IPv6 route.
|
||||
*
|
||||
* @param[in] aRoute A reference to the IPv6 route.
|
||||
*
|
||||
@@ -76,10 +84,10 @@ public:
|
||||
* @retval kThreadError_Busy The route was already added.
|
||||
*
|
||||
*/
|
||||
static ThreadError Add(Route &aRoute);
|
||||
ThreadError Add(Route &aRoute);
|
||||
|
||||
/**
|
||||
* This static method removes an IPv6 route.
|
||||
* This method removes an IPv6 route.
|
||||
*
|
||||
* @param[in] aRoute A reference to the IPv6 route.
|
||||
*
|
||||
@@ -87,10 +95,10 @@ public:
|
||||
* @retval kThreadError_InvalidArgs The route was not added.
|
||||
*
|
||||
*/
|
||||
static ThreadError Remove(Route &aRoute);
|
||||
ThreadError Remove(Route &aRoute);
|
||||
|
||||
/**
|
||||
* This static method performs source-destination route lookup.
|
||||
* This method performs source-destination route lookup.
|
||||
*
|
||||
* @param[in] aSource The IPv6 source address.
|
||||
* @param[in] aDestination The IPv6 destination address.
|
||||
@@ -98,7 +106,11 @@ public:
|
||||
* @returns The interface identifier for the best route or -1 if no route is available.
|
||||
*
|
||||
*/
|
||||
static int8_t Lookup(const Address &aSource, const Address &aDestination);
|
||||
int8_t Lookup(const Address &aSource, const Address &aDestination);
|
||||
|
||||
private:
|
||||
Route *mRoutes;
|
||||
Ip6 &mIp6;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+10
-216
@@ -34,16 +34,15 @@
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/debug.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/netif.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
Netif *Netif::sNetifListHead = NULL;
|
||||
int8_t Netif::sNextInterfaceId = 1;
|
||||
|
||||
Netif::Netif() :
|
||||
mStateChangedTask(&HandleStateChangedTask, this)
|
||||
Netif::Netif(Ip6 &aIp6):
|
||||
mIp6(aIp6),
|
||||
mStateChangedTask(aIp6.mTaskletScheduler, &HandleStateChangedTask, this)
|
||||
{
|
||||
mCallbacks = NULL;
|
||||
mUnicastAddresses = NULL;
|
||||
@@ -75,107 +74,14 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Netif::AddNetif()
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Netif *netif;
|
||||
|
||||
if (sNetifListHead == NULL)
|
||||
{
|
||||
sNetifListHead = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
netif = sNetifListHead;
|
||||
|
||||
do
|
||||
{
|
||||
if (netif == this)
|
||||
{
|
||||
ExitNow(error = kThreadError_Busy);
|
||||
}
|
||||
}
|
||||
while (netif->mNext);
|
||||
|
||||
netif->mNext = this;
|
||||
}
|
||||
|
||||
mNext = NULL;
|
||||
|
||||
if (mInterfaceId < 0)
|
||||
{
|
||||
mInterfaceId = sNextInterfaceId++;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Netif::RemoveNetif()
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(sNetifListHead != NULL, error = kThreadError_Busy);
|
||||
|
||||
if (sNetifListHead == this)
|
||||
{
|
||||
sNetifListHead = mNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Netif *netif = sNetifListHead; netif->mNext; netif = netif->mNext)
|
||||
{
|
||||
if (netif->mNext != this)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
netif->mNext = mNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mNext = NULL;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Netif *Netif::GetNext() const
|
||||
{
|
||||
return mNext;
|
||||
}
|
||||
|
||||
Netif *Netif::GetNetifById(int8_t aInterfaceId)
|
||||
Ip6 &Netif::GetIp6(void)
|
||||
{
|
||||
Netif *netif;
|
||||
|
||||
for (netif = sNetifListHead; netif; netif = netif->mNext)
|
||||
{
|
||||
if (netif->mInterfaceId == aInterfaceId)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return netif;
|
||||
}
|
||||
|
||||
Netif *Netif::GetNetifByName(char *aName)
|
||||
{
|
||||
Netif *netif;
|
||||
|
||||
for (netif = sNetifListHead; netif; netif = netif->mNext)
|
||||
{
|
||||
if (strcmp(netif->GetName(), aName) == 0)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return netif;
|
||||
return mIp6;
|
||||
}
|
||||
|
||||
int8_t Netif::GetInterfaceId() const
|
||||
@@ -326,7 +232,6 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
ThreadError Netif::AddExternalUnicastAddress(const NetifUnicastAddress &aAddress)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
@@ -416,23 +321,15 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Netif *Netif::GetNetifList()
|
||||
{
|
||||
return sNetifListHead;
|
||||
}
|
||||
|
||||
bool Netif::IsUnicastAddress(const Address &aAddress)
|
||||
bool Netif::IsUnicastAddress(const Address &aAddress) const
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
for (Netif *netif = sNetifListHead; netif; netif = netif->mNext)
|
||||
for (const NetifUnicastAddress *cur = mUnicastAddresses; cur; cur = cur->GetNext())
|
||||
{
|
||||
for (NetifUnicastAddress *cur = netif->mUnicastAddresses; cur; cur = cur->GetNext())
|
||||
if (cur->GetAddress() == aAddress)
|
||||
{
|
||||
if (cur->GetAddress() == aAddress)
|
||||
{
|
||||
ExitNow(rval = true);
|
||||
}
|
||||
ExitNow(rval = true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,109 +337,6 @@ exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
const NetifUnicastAddress *Netif::SelectSourceAddress(MessageInfo &aMessageInfo)
|
||||
{
|
||||
Address *destination = &aMessageInfo.GetPeerAddr();
|
||||
int interfaceId = aMessageInfo.mInterfaceId;
|
||||
const NetifUnicastAddress *rvalAddr = NULL;
|
||||
const Address *candidateAddr;
|
||||
int8_t candidateId;
|
||||
int8_t rvalIface = 0;
|
||||
|
||||
for (Netif *netif = GetNetifList(); netif; netif = netif->mNext)
|
||||
{
|
||||
candidateId = netif->GetInterfaceId();
|
||||
|
||||
for (const NetifUnicastAddress *addr = netif->GetUnicastAddresses(); addr; addr = addr->GetNext())
|
||||
{
|
||||
candidateAddr = &addr->GetAddress();
|
||||
|
||||
if (destination->IsLinkLocal() || destination->IsMulticast())
|
||||
{
|
||||
if (interfaceId != candidateId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (rvalAddr == NULL)
|
||||
{
|
||||
// Rule 0: Prefer any address
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
else if (*candidateAddr == *destination)
|
||||
{
|
||||
// Rule 1: Prefer same address
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
goto exit;
|
||||
}
|
||||
else if (candidateAddr->GetScope() < rvalAddr->GetAddress().GetScope())
|
||||
{
|
||||
// Rule 2: Prefer appropriate scope
|
||||
if (candidateAddr->GetScope() >= destination->GetScope())
|
||||
{
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
}
|
||||
else if (candidateAddr->GetScope() > rvalAddr->GetAddress().GetScope())
|
||||
{
|
||||
if (rvalAddr->GetAddress().GetScope() < destination->GetScope())
|
||||
{
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
}
|
||||
else if (addr->mPreferredLifetime != 0 && rvalAddr->mPreferredLifetime == 0)
|
||||
{
|
||||
// Rule 3: Avoid deprecated addresses
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
else if (aMessageInfo.mInterfaceId != 0 && aMessageInfo.mInterfaceId == candidateId &&
|
||||
rvalIface != candidateId)
|
||||
{
|
||||
// Rule 4: Prefer home address
|
||||
// Rule 5: Prefer outgoing interface
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
else if (destination->PrefixMatch(*candidateAddr) > destination->PrefixMatch(rvalAddr->GetAddress()))
|
||||
{
|
||||
// Rule 6: Prefer matching label
|
||||
// Rule 7: Prefer public address
|
||||
// Rule 8: Use longest prefix matching
|
||||
rvalAddr = addr;
|
||||
rvalIface = candidateId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
aMessageInfo.mInterfaceId = rvalIface;
|
||||
return rvalAddr;
|
||||
}
|
||||
|
||||
int8_t Netif::GetOnLinkNetif(const Address &aAddress)
|
||||
{
|
||||
int8_t rval = -1;
|
||||
|
||||
for (Netif *netif = sNetifListHead; netif; netif = netif->mNext)
|
||||
{
|
||||
for (NetifUnicastAddress *cur = netif->mUnicastAddresses; cur; cur = cur->GetNext())
|
||||
{
|
||||
if (cur->GetAddress().PrefixMatch(aAddress) >= cur->mPrefixLength)
|
||||
{
|
||||
ExitNow(rval = netif->mInterfaceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool Netif::IsStateChangedCallbackPending(void)
|
||||
{
|
||||
|
||||
+22
-72
@@ -43,6 +43,8 @@
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
class Ip6;
|
||||
|
||||
/**
|
||||
* @addtogroup core-ip6-netif
|
||||
*
|
||||
@@ -192,30 +194,24 @@ private:
|
||||
*/
|
||||
class Netif
|
||||
{
|
||||
friend class Ip6;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the network interface.
|
||||
*
|
||||
* @param[in] aIp6 A reference to the IPv6 network object.
|
||||
*
|
||||
*/
|
||||
Netif(void);
|
||||
Netif(Ip6 &aIp6);
|
||||
|
||||
/**
|
||||
* This method enables the network interface.
|
||||
* This method returns a reference to the IPv6 network object.
|
||||
*
|
||||
* @retval kThreadError_None Successfully enabled the network interface.
|
||||
* @retval KThreadError_Busy The network interface was already enabled.
|
||||
* @returns A reference to the IPv6 network object.
|
||||
*
|
||||
*/
|
||||
ThreadError AddNetif(void);
|
||||
|
||||
/**
|
||||
* This method disables the network interface.
|
||||
*
|
||||
* @retval kThreadError_None Successfully disabled the network interface.
|
||||
* @retval KThreadError_Busy The network interface was already disabled.
|
||||
*
|
||||
*/
|
||||
ThreadError RemoveNetif(void);
|
||||
Ip6 &GetIp6(void);
|
||||
|
||||
/**
|
||||
* This method returns the next network interface in the list.
|
||||
@@ -286,6 +282,16 @@ public:
|
||||
*/
|
||||
ThreadError RemoveExternalUnicastAddress(const Address &aAddress);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not an address is assigned to this interface.
|
||||
*
|
||||
* @param[in] aAddress A reference to the unicast address.
|
||||
*
|
||||
* @returns TRUE if @p aAddress is assigned to this interface, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsUnicastAddress(const Address &aAddress) const;
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the network interface is subscribed to a multicast address.
|
||||
*
|
||||
@@ -401,64 +407,8 @@ public:
|
||||
virtual ThreadError RouteLookup(const Address &aSource, const Address &aDestination,
|
||||
uint8_t *aPrefixMatch) = 0;
|
||||
|
||||
/**
|
||||
* This static method returns the network interface list.
|
||||
*
|
||||
* @returns A pointer to the network interface list.
|
||||
*
|
||||
*/
|
||||
static Netif *GetNetifList(void);
|
||||
|
||||
/**
|
||||
* This static method returns the network interface identified by @p aInterfaceId.
|
||||
*
|
||||
* @param[in] aInterfaceId The network interface ID.
|
||||
*
|
||||
* @returns A pointer to the network interface or NULL if none is found.
|
||||
*
|
||||
*/
|
||||
static Netif *GetNetifById(int8_t aInterfaceId);
|
||||
|
||||
/**
|
||||
* This static method returns the network interface identified by @p aName.
|
||||
*
|
||||
* @param[in] aName A pointer to a NULL-terminated string.
|
||||
*
|
||||
* @returns A pointer to the network interface or NULL if none is found.
|
||||
*
|
||||
*/
|
||||
static Netif *GetNetifByName(char *aName);
|
||||
|
||||
/**
|
||||
* This static method indicates whether or not @p aAddress is assigned to a network interface.
|
||||
*
|
||||
* @param[in] aAddress A reference to the IPv6 address.
|
||||
*
|
||||
* @retval TRUE If the IPv6 address is assigned to a network interface.
|
||||
* @retval FALSE If the IPv6 address is not assigned to any network interface.
|
||||
*
|
||||
*/
|
||||
static bool IsUnicastAddress(const Address &aAddress);
|
||||
|
||||
/**
|
||||
* This static method perform default source address selection.
|
||||
*
|
||||
* @param[in] aMessageInfo A reference to the message information.
|
||||
*
|
||||
* @returns A pointer to the selected IPv6 source address or NULL if no source address was found.
|
||||
*
|
||||
*/
|
||||
static const NetifUnicastAddress *SelectSourceAddress(MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This static method determines which network interface @p aAddress is on-link, if any.
|
||||
*
|
||||
* @param[in] aAddress A reference to the IPv6 address.
|
||||
*
|
||||
* @returns The network interface identifier for the on-link interface or -1 if none is found.
|
||||
*
|
||||
*/
|
||||
static int8_t GetOnLinkNetif(const Address &aAddress);
|
||||
protected:
|
||||
Ip6 &mIp6;
|
||||
|
||||
private:
|
||||
static void HandleStateChangedTask(void *aContext);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#define TCP_HPP_
|
||||
|
||||
#include <openthread.h>
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/ip6_headers.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
+86
-47
@@ -43,31 +43,24 @@ using Thread::Encoding::BigEndian::HostSwap16;
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
UdpSocket *Udp::sSockets = NULL;
|
||||
uint16_t Udp::sEphemeralPort = kDynamicPortMin;
|
||||
UdpSocket::UdpSocket(Udp &aUdp)
|
||||
{
|
||||
mTransport = &aUdp;
|
||||
}
|
||||
|
||||
Message *UdpSocket::NewMessage(uint16_t aReserved)
|
||||
{
|
||||
return static_cast<Udp *>(mTransport)->NewMessage(aReserved);
|
||||
}
|
||||
|
||||
ThreadError UdpSocket::Open(otUdpReceive aHandler, void *aContext)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
for (UdpSocket *cur = Udp::sSockets; cur; cur = cur->GetNext())
|
||||
{
|
||||
if (cur == this)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
memset(&mSockName, 0, sizeof(mSockName));
|
||||
memset(&mPeerName, 0, sizeof(mPeerName));
|
||||
mHandler = aHandler;
|
||||
mContext = aContext;
|
||||
|
||||
SetNext(Udp::sSockets);
|
||||
Udp::sSockets = this;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
return static_cast<Udp *>(mTransport)->AddSocket(*this);
|
||||
}
|
||||
|
||||
ThreadError UdpSocket::Bind(const SockAddr &aSockAddr)
|
||||
@@ -78,27 +71,14 @@ ThreadError UdpSocket::Bind(const SockAddr &aSockAddr)
|
||||
|
||||
ThreadError UdpSocket::Close(void)
|
||||
{
|
||||
if (Udp::sSockets == this)
|
||||
{
|
||||
Udp::sSockets = Udp::sSockets->GetNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UdpSocket *socket = Udp::sSockets; socket; socket = socket->GetNext())
|
||||
{
|
||||
if (socket->GetNext() == this)
|
||||
{
|
||||
socket->SetNext(GetNext());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
SuccessOrExit(error = static_cast<Udp *>(mTransport)->RemoveSocket(*this));
|
||||
memset(&mSockName, 0, sizeof(mSockName));
|
||||
memset(&mPeerName, 0, sizeof(mPeerName));
|
||||
SetNext(NULL);
|
||||
|
||||
return kThreadError_None;
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError UdpSocket::SendTo(Message &aMessage, const MessageInfo &aMessageInfo)
|
||||
@@ -116,16 +96,7 @@ ThreadError UdpSocket::SendTo(Message &aMessage, const MessageInfo &aMessageInfo
|
||||
|
||||
if (GetSockName().mPort == 0)
|
||||
{
|
||||
GetSockName().mPort = Udp::sEphemeralPort;
|
||||
|
||||
if (Udp::sEphemeralPort < Udp::kDynamicPortMax)
|
||||
{
|
||||
Udp::sEphemeralPort++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Udp::sEphemeralPort = Udp::kDynamicPortMin;
|
||||
}
|
||||
GetSockName().mPort = static_cast<Udp *>(mTransport)->GetEphemeralPort();
|
||||
}
|
||||
|
||||
udpHeader.SetSourcePort(GetSockName().mPort);
|
||||
@@ -135,15 +106,83 @@ ThreadError UdpSocket::SendTo(Message &aMessage, const MessageInfo &aMessageInfo
|
||||
|
||||
SuccessOrExit(error = aMessage.Prepend(&udpHeader, sizeof(udpHeader)));
|
||||
aMessage.SetOffset(0);
|
||||
SuccessOrExit(error = Ip6::SendDatagram(aMessage, messageInfoLocal, kProtoUdp));
|
||||
SuccessOrExit(error = static_cast<Udp *>(mTransport)->SendDatagram(aMessage, messageInfoLocal, kProtoUdp));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Udp::Udp(Ip6 &aIp6):
|
||||
mEphemeralPort(kDynamicPortMin),
|
||||
mSockets(NULL),
|
||||
mIp6(aIp6)
|
||||
{
|
||||
}
|
||||
|
||||
ThreadError Udp::AddSocket(UdpSocket &aSocket)
|
||||
{
|
||||
for (UdpSocket *cur = mSockets; cur; cur = cur->GetNext())
|
||||
{
|
||||
if (cur == &aSocket)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
aSocket.SetNext(mSockets);
|
||||
mSockets = &aSocket;
|
||||
|
||||
exit:
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError Udp::RemoveSocket(UdpSocket &aSocket)
|
||||
{
|
||||
if (mSockets == &aSocket)
|
||||
{
|
||||
mSockets = mSockets->GetNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (UdpSocket *socket = mSockets; socket; socket = socket->GetNext())
|
||||
{
|
||||
if (socket->GetNext() == &aSocket)
|
||||
{
|
||||
socket->SetNext(socket->GetNext());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aSocket.SetNext(NULL);
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
uint16_t Udp::GetEphemeralPort(void)
|
||||
{
|
||||
uint16_t rval = mEphemeralPort;
|
||||
|
||||
if (mEphemeralPort < kDynamicPortMax)
|
||||
{
|
||||
mEphemeralPort++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEphemeralPort = kDynamicPortMin;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
Message *Udp::NewMessage(uint16_t aReserved)
|
||||
{
|
||||
return Ip6::NewMessage(sizeof(UdpHeader) + aReserved);
|
||||
return mIp6.NewMessage(sizeof(UdpHeader) + aReserved);
|
||||
}
|
||||
|
||||
ThreadError Udp::SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, IpProto aIpProto)
|
||||
{
|
||||
return mIp6.SendDatagram(aMessage, aMessageInfo, aIpProto);
|
||||
}
|
||||
|
||||
ThreadError Udp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo)
|
||||
@@ -170,7 +209,7 @@ ThreadError Udp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo)
|
||||
aMessageInfo.mSockPort = udpHeader.GetDestinationPort();
|
||||
|
||||
// find socket
|
||||
for (UdpSocket *socket = Udp::sSockets; socket; socket = socket->GetNext())
|
||||
for (UdpSocket *socket = mSockets; socket; socket = socket->GetNext())
|
||||
{
|
||||
if (socket->GetSockName().mPort != udpHeader.GetDestinationPort())
|
||||
{
|
||||
|
||||
+80
-9
@@ -35,11 +35,13 @@
|
||||
#define UDP6_HPP_
|
||||
|
||||
#include <openthread.h>
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/ip6_headers.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Ip6 {
|
||||
|
||||
class Udp;
|
||||
|
||||
/**
|
||||
* @addtogroup core-udp
|
||||
*
|
||||
@@ -59,6 +61,24 @@ class UdpSocket: public otUdpSocket
|
||||
friend class Udp;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aUdp A reference to the UDP transport object.
|
||||
*
|
||||
*/
|
||||
UdpSocket(Udp &aUdp);
|
||||
|
||||
/**
|
||||
* This method returns a new UDP message with sufficient header space reserved.
|
||||
*
|
||||
* @param[in] aReserved The number of header bytes to reserve after the UDP header.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if no buffers are available.
|
||||
*
|
||||
*/
|
||||
Message *NewMessage(uint16_t aReserved);
|
||||
|
||||
/**
|
||||
* This method opens the UDP socket.
|
||||
*
|
||||
@@ -124,17 +144,66 @@ class Udp
|
||||
|
||||
public:
|
||||
/**
|
||||
* This static method returns a new UDP message with sufficient header space reserved.
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aIp6 A reference to the IPv6 network object.
|
||||
*
|
||||
*/
|
||||
Udp(Ip6 &aIp6);
|
||||
|
||||
/**
|
||||
* This method adds a UDP socket.
|
||||
*
|
||||
* @param[in] aSocket A reference to the UDP socket.
|
||||
*
|
||||
* @retval kThreadError_None Successfully added the UDP socket.
|
||||
*
|
||||
*/
|
||||
ThreadError AddSocket(UdpSocket &aSocket);
|
||||
|
||||
/**
|
||||
* This method removes a UDP socket.
|
||||
*
|
||||
* @param[in] aSocket A reference to the UDP socket.
|
||||
*
|
||||
* @retval kThreadError_None Successfully removed the UDP socket.
|
||||
*
|
||||
*/
|
||||
ThreadError RemoveSocket(UdpSocket &aSocket);
|
||||
|
||||
/**
|
||||
* This method returns a new ephemeral port.
|
||||
*
|
||||
* @returns A new ephemeral port.
|
||||
*
|
||||
*/
|
||||
uint16_t GetEphemeralPort(void);
|
||||
|
||||
/**
|
||||
* This method returns a new UDP message with sufficient header space reserved.
|
||||
*
|
||||
* @param[in] aReserved The number of header bytes to reserve after the UDP header.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if no buffers are available.
|
||||
*
|
||||
*/
|
||||
static Message *NewMessage(uint16_t aReserved);
|
||||
Message *NewMessage(uint16_t aReserved);
|
||||
|
||||
/**
|
||||
* This static method handles a received UDP message.
|
||||
* This method sends an IPv6 datagram.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
* @param[in] aIpProto The Internet Protocol value.
|
||||
*
|
||||
* @retval kThreadError_None Successfully enqueued the message into an output interface.
|
||||
* @retval kThreadError_NoBufs Insufficient available buffer to add the IPv6 headers.
|
||||
*
|
||||
*/
|
||||
ThreadError SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, IpProto aIpProto);
|
||||
|
||||
/**
|
||||
* This method handles a received UDP message.
|
||||
*
|
||||
* @param[in] aMessage A reference to the UDP message to process.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
@@ -143,10 +212,10 @@ public:
|
||||
* @retval kThreadError_Drop Could not fully process the UDP message.
|
||||
*
|
||||
*/
|
||||
static ThreadError HandleMessage(Message &aMessage, MessageInfo &aMessageInfo);
|
||||
ThreadError HandleMessage(Message &aMessage, MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This static method updates the UDP checksum.
|
||||
* This method updates the UDP checksum.
|
||||
*
|
||||
* @param[in] aMessage A reference to the UDP message.
|
||||
* @param[in] aPseudoHeaderChecksum The pseudo-header checksum value.
|
||||
@@ -155,7 +224,7 @@ public:
|
||||
* @retval kThreadError_InvalidArgs The message was invalid.
|
||||
*
|
||||
*/
|
||||
static ThreadError UpdateChecksum(Message &aMessage, uint16_t aPseudoHeaderChecksum);
|
||||
ThreadError UpdateChecksum(Message &aMessage, uint16_t aPseudoHeaderChecksum);
|
||||
|
||||
private:
|
||||
enum
|
||||
@@ -163,8 +232,10 @@ private:
|
||||
kDynamicPortMin = 49152, ///< Service Name and Transport Protocol Port Number Registry
|
||||
kDynamicPortMax = 65535, ///< Service Name and Transport Protocol Port Number Registry
|
||||
};
|
||||
static uint16_t sEphemeralPort;
|
||||
static UdpSocket *sSockets;
|
||||
uint16_t mEphemeralPort;
|
||||
UdpSocket *mSockets;
|
||||
|
||||
Ip6 &mIp6;
|
||||
};
|
||||
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
|
||||
+19
-14
@@ -40,6 +40,7 @@
|
||||
#include <common/new.hpp>
|
||||
#include <common/tasklet.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <crypto/mbedtls.hpp>
|
||||
#include <net/icmp6.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <platform/random.h>
|
||||
@@ -57,6 +58,11 @@ ThreadNetif *sThreadNetif;
|
||||
static Ip6::NetifCallback sNetifCallback;
|
||||
static bool mEnabled = false;
|
||||
|
||||
static otDEFINE_ALIGNED_VAR(sMbedTlsRaw, sizeof(Crypto::MbedTls), uint64_t);
|
||||
|
||||
static otDEFINE_ALIGNED_VAR(sIp6Raw, sizeof(Ip6::Ip6), uint64_t);
|
||||
Ip6::Ip6 *sIp6;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -77,12 +83,12 @@ static void *sDiscoverCallbackContext = NULL;
|
||||
|
||||
void otProcessNextTasklet(void)
|
||||
{
|
||||
TaskletScheduler::RunNextTasklet();
|
||||
sIp6->mTaskletScheduler.RunNextTasklet();
|
||||
}
|
||||
|
||||
bool otAreTaskletsPending(void)
|
||||
{
|
||||
return TaskletScheduler::AreTaskletsPending();
|
||||
return sIp6->mTaskletScheduler.AreTaskletsPending();
|
||||
}
|
||||
|
||||
uint8_t otGetChannel(void)
|
||||
@@ -869,9 +875,9 @@ ThreadError otEnable(void)
|
||||
VerifyOrExit(!mEnabled, error = kThreadError_InvalidState);
|
||||
|
||||
otLogInfoApi("otEnable\n");
|
||||
Message::Init();
|
||||
sThreadNetif = new(&sThreadNetifRaw) ThreadNetif;
|
||||
Ip6::Ip6::Init();
|
||||
new(&sMbedTlsRaw) Crypto::MbedTls;
|
||||
sIp6 = new(&sIp6Raw) Ip6::Ip6;
|
||||
sThreadNetif = new(&sThreadNetifRaw) ThreadNetif(*sIp6);
|
||||
mEnabled = true;
|
||||
|
||||
exit:
|
||||
@@ -1047,33 +1053,32 @@ void HandleMleDiscover(otActiveScanResult *aResult, void *aContext)
|
||||
|
||||
void otSetReceiveIp6DatagramCallback(otReceiveIp6DatagramCallback aCallback, void *aCallbackContext)
|
||||
{
|
||||
Ip6::Ip6::SetReceiveDatagramCallback(aCallback, aCallbackContext);
|
||||
sIp6->SetReceiveDatagramCallback(aCallback, aCallbackContext);
|
||||
}
|
||||
|
||||
bool otIsReceiveIp6DatagramFilterEnabled(void)
|
||||
{
|
||||
return Ip6::Ip6::IsReceiveIp6FilterEnabled();
|
||||
return sIp6->IsReceiveIp6FilterEnabled();
|
||||
}
|
||||
|
||||
void otSetReceiveIp6DatagramFilterEnabled(bool aEnabled)
|
||||
{
|
||||
Ip6::Ip6::SetReceiveIp6FilterEnabled(aEnabled);
|
||||
sIp6->SetReceiveIp6FilterEnabled(aEnabled);
|
||||
}
|
||||
|
||||
ThreadError otSendIp6Datagram(otMessage aMessage)
|
||||
{
|
||||
return Ip6::Ip6::HandleDatagram(*static_cast<Message *>(aMessage), NULL, sThreadNetif->GetInterfaceId(),
|
||||
NULL, true);
|
||||
return sIp6->HandleDatagram(*static_cast<Message *>(aMessage), NULL, sThreadNetif->GetInterfaceId(), NULL, true);
|
||||
}
|
||||
|
||||
otMessage otNewUdpMessage(void)
|
||||
{
|
||||
return Ip6::Udp::NewMessage(0);
|
||||
return sIp6->mUdp.NewMessage(0);
|
||||
}
|
||||
|
||||
ThreadError otFreeMessage(otMessage aMessage)
|
||||
{
|
||||
return Message::Free(*static_cast<Message *>(aMessage));
|
||||
return static_cast<Message *>(aMessage)->Free();
|
||||
}
|
||||
|
||||
uint16_t otGetMessageLength(otMessage aMessage)
|
||||
@@ -1145,12 +1150,12 @@ ThreadError otSendUdp(otUdpSocket *aSocket, otMessage aMessage, const otMessageI
|
||||
|
||||
bool otIsIcmpEchoEnabled(void)
|
||||
{
|
||||
return Ip6::Icmp::IsEchoEnabled();
|
||||
return sIp6->mIcmp.IsEchoEnabled();
|
||||
}
|
||||
|
||||
void otSetIcmpEchoEnabled(bool aEnabled)
|
||||
{
|
||||
Ip6::Icmp::SetEchoEnabled(aEnabled);
|
||||
sIp6->mIcmp.SetEchoEnabled(aEnabled);
|
||||
}
|
||||
|
||||
uint8_t otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond)
|
||||
|
||||
@@ -54,7 +54,8 @@ AddressResolver::AddressResolver(ThreadNetif &aThreadNetif) :
|
||||
mAddressQuery(OPENTHREAD_URI_ADDRESS_QUERY, &HandleAddressQuery, this),
|
||||
mAddressNotification(OPENTHREAD_URI_ADDRESS_NOTIFY, &HandleAddressNotification, this),
|
||||
mIcmpHandler(&HandleDstUnreach, this),
|
||||
mTimer(&HandleTimer, this),
|
||||
mSocket(aThreadNetif.GetIp6().mUdp),
|
||||
mTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleTimer, this),
|
||||
mMeshForwarder(aThreadNetif.GetMeshForwarder()),
|
||||
mCoapServer(aThreadNetif.GetCoapServer()),
|
||||
mMle(aThreadNetif.GetMle()),
|
||||
@@ -67,7 +68,7 @@ AddressResolver::AddressResolver(ThreadNetif &aThreadNetif) :
|
||||
mCoapServer.AddResource(mAddressNotification);
|
||||
mCoapMessageId = static_cast<uint8_t>(otPlatRandomGet());
|
||||
|
||||
Ip6::Icmp::RegisterCallbacks(mIcmpHandler);
|
||||
mNetif.GetIp6().mIcmp.RegisterCallbacks(mIcmpHandler);
|
||||
}
|
||||
|
||||
void AddressResolver::Clear()
|
||||
@@ -175,7 +176,7 @@ ThreadError AddressResolver::SendAddressQuery(const Ip6::Address &aEid)
|
||||
mSocket.Open(&HandleUdpReceive, this);
|
||||
mSocket.Bind(sockaddr);
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
header.Init();
|
||||
header.SetVersion(1);
|
||||
@@ -212,7 +213,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -316,7 +317,7 @@ void AddressResolver::SendAddressNotificationResponse(const Coap::Header &aReque
|
||||
Coap::Header responseHeader;
|
||||
Ip6::MessageInfo responseInfo;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
@@ -337,7 +338,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,7 +355,7 @@ ThreadError AddressResolver::SendAddressError(const ThreadTargetTlv &aTarget, co
|
||||
mSocket.Open(&HandleUdpReceive, this);
|
||||
mSocket.Bind(sockaddr);
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
header.Init();
|
||||
header.SetVersion(1);
|
||||
@@ -392,7 +393,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -406,7 +407,7 @@ void AddressResolver::SendAddressErrorResponse(const Coap::Header &aRequestHeade
|
||||
Coap::Header responseHeader;
|
||||
Ip6::MessageInfo responseInfo;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
@@ -427,7 +428,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,7 +586,7 @@ void AddressResolver::SendAddressQueryResponse(const ThreadTargetTlv &aTargetTlv
|
||||
ThreadRloc16Tlv rloc16Tlv;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
header.Init();
|
||||
header.SetVersion(1);
|
||||
@@ -623,7 +624,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <crypto/hmac_sha256.h>
|
||||
#include <crypto/hmac_sha256.hpp>
|
||||
#include <thread/key_manager.hpp>
|
||||
#include <thread/mle_router.hpp>
|
||||
#include <thread/thread_netif.hpp>
|
||||
@@ -83,18 +83,19 @@ exit:
|
||||
|
||||
ThreadError KeyManager::ComputeKey(uint32_t aKeySequence, uint8_t *aKey)
|
||||
{
|
||||
Crypto::HmacSha256 hmac;
|
||||
uint8_t keySequenceBytes[4];
|
||||
|
||||
otCryptoHmacSha256Start(mMasterKey, mMasterKeyLength);
|
||||
hmac.Start(mMasterKey, mMasterKeyLength);
|
||||
|
||||
keySequenceBytes[0] = (aKeySequence >> 24) & 0xff;
|
||||
keySequenceBytes[1] = (aKeySequence >> 16) & 0xff;
|
||||
keySequenceBytes[2] = (aKeySequence >> 8) & 0xff;
|
||||
keySequenceBytes[3] = aKeySequence & 0xff;
|
||||
otCryptoHmacSha256Update(keySequenceBytes, sizeof(keySequenceBytes));
|
||||
otCryptoHmacSha256Update(kThreadString, sizeof(kThreadString));
|
||||
hmac.Update(keySequenceBytes, sizeof(keySequenceBytes));
|
||||
hmac.Update(kThreadString, sizeof(kThreadString));
|
||||
|
||||
otCryptoHmacSha256Finish(aKey);
|
||||
hmac.Finish(aKey);
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <crypto/hmac_sha256.h>
|
||||
#include <crypto/hmac_sha256.hpp>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
@@ -181,9 +181,9 @@ private:
|
||||
uint8_t mMasterKeyLength;
|
||||
|
||||
uint32_t mKeySequence;
|
||||
uint8_t mKey[otCryptoSha256Size];
|
||||
uint8_t mKey[Crypto::HmacSha256::kHashSize];
|
||||
|
||||
uint8_t mTemporaryKey[otCryptoSha256Size];
|
||||
uint8_t mTemporaryKey[Crypto::HmacSha256::kHashSize];
|
||||
|
||||
uint32_t mMacFrameCounter;
|
||||
uint32_t mMleFrameCounter;
|
||||
|
||||
@@ -54,8 +54,6 @@ static const char *const kLinkQualityDecimalDigitsString[8] =
|
||||
|
||||
const char LinkQualityInfo::kUnknownRssString[] = "Unknown RSS";
|
||||
|
||||
static LinkQualityInfo sNoiseFloorAverage; // Store the noise floor average.
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
LinkQualityInfo::LinkQualityInfo(void)
|
||||
@@ -70,7 +68,7 @@ void LinkQualityInfo::Clear(void)
|
||||
mLinkQuality = 0;
|
||||
}
|
||||
|
||||
void LinkQualityInfo::AddRss(int8_t anRss)
|
||||
void LinkQualityInfo::AddRss(LinkQualityInfo &aNoiseFloor, int8_t anRss)
|
||||
{
|
||||
uint16_t newValue;
|
||||
uint16_t oldAverage;
|
||||
@@ -114,7 +112,7 @@ void LinkQualityInfo::AddRss(int8_t anRss)
|
||||
mCount++;
|
||||
}
|
||||
|
||||
UpdateLinkQuality();
|
||||
UpdateLinkQuality(aNoiseFloor);
|
||||
}
|
||||
|
||||
int8_t LinkQualityInfo::GetAverageRss(void) const
|
||||
@@ -167,33 +165,33 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
uint8_t LinkQualityInfo::GetLinkMargin(void) const
|
||||
uint8_t LinkQualityInfo::GetLinkMargin(LinkQualityInfo &aNoiseFloor) const
|
||||
{
|
||||
return ConvertRssToLinkMargin(GetAverageRss());
|
||||
return ConvertRssToLinkMargin(aNoiseFloor, GetAverageRss());
|
||||
}
|
||||
|
||||
uint8_t LinkQualityInfo::GetLinkQuality(void)
|
||||
uint8_t LinkQualityInfo::GetLinkQuality(LinkQualityInfo &aNoiseFloor)
|
||||
{
|
||||
UpdateLinkQuality();
|
||||
UpdateLinkQuality(aNoiseFloor);
|
||||
|
||||
return mLinkQuality;
|
||||
}
|
||||
|
||||
void LinkQualityInfo::UpdateLinkQuality(void)
|
||||
void LinkQualityInfo::UpdateLinkQuality(LinkQualityInfo &aNoiseFloor)
|
||||
{
|
||||
if (mCount != 0)
|
||||
{
|
||||
mLinkQuality = CalculateLinkQuality(GetLinkMargin(), mLinkQuality);
|
||||
mLinkQuality = CalculateLinkQuality(GetLinkMargin(aNoiseFloor), mLinkQuality);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLinkQuality = CalculateLinkQuality(GetLinkMargin(), kNoLastLinkQualityValue);
|
||||
mLinkQuality = CalculateLinkQuality(GetLinkMargin(aNoiseFloor), kNoLastLinkQualityValue);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LinkQualityInfo::ConvertRssToLinkMargin(int8_t anRss)
|
||||
uint8_t LinkQualityInfo::ConvertRssToLinkMargin(LinkQualityInfo &aNoiseFloor, int8_t anRss)
|
||||
{
|
||||
int8_t linkMargin = anRss - GetAverageNoiseFloor();
|
||||
int8_t linkMargin = anRss - GetAverageNoiseFloor(aNoiseFloor);
|
||||
|
||||
if (linkMargin < 0 || anRss == kUnknownRss)
|
||||
{
|
||||
@@ -208,9 +206,9 @@ uint8_t LinkQualityInfo::ConvertLinkMarginToLinkQuality(uint8_t aLinkMargin)
|
||||
return CalculateLinkQuality(aLinkMargin, kNoLastLinkQualityValue);
|
||||
}
|
||||
|
||||
uint8_t LinkQualityInfo::ConvertRssToLinkQuality(int8_t anRss)
|
||||
uint8_t LinkQualityInfo::ConvertRssToLinkQuality(LinkQualityInfo &aNoiseFloor, int8_t anRss)
|
||||
{
|
||||
return ConvertLinkMarginToLinkQuality(ConvertRssToLinkMargin(anRss));
|
||||
return ConvertLinkMarginToLinkQuality(ConvertRssToLinkMargin(aNoiseFloor, anRss));
|
||||
}
|
||||
|
||||
uint8_t LinkQualityInfo::CalculateLinkQuality(uint8_t aLinkMargin, uint8_t aLastLinkQuality)
|
||||
@@ -261,9 +259,9 @@ uint8_t LinkQualityInfo::CalculateLinkQuality(uint8_t aLinkMargin, uint8_t aLast
|
||||
return linkQuality;
|
||||
}
|
||||
|
||||
int8_t GetAverageNoiseFloor(void)
|
||||
int8_t GetAverageNoiseFloor(LinkQualityInfo &aNoiseFloor)
|
||||
{
|
||||
int8_t averageNoiseFloor = sNoiseFloorAverage.GetAverageRss();
|
||||
int8_t averageNoiseFloor = aNoiseFloor.GetAverageRss();
|
||||
|
||||
if (averageNoiseFloor == LinkQualityInfo::kUnknownRss)
|
||||
{
|
||||
@@ -273,14 +271,14 @@ int8_t GetAverageNoiseFloor(void)
|
||||
return averageNoiseFloor;
|
||||
}
|
||||
|
||||
void AddNoiseFloor(int8_t aNoiseFloor)
|
||||
void AddNoiseFloor(LinkQualityInfo &aNoiseFloor, int8_t aNoise)
|
||||
{
|
||||
sNoiseFloorAverage.AddRss(aNoiseFloor);
|
||||
aNoiseFloor.AddRss(aNoiseFloor, aNoise);
|
||||
}
|
||||
|
||||
void ClearNoiseFloorAverage(void)
|
||||
void ClearNoiseFloorAverage(LinkQualityInfo &aNoiseFloor)
|
||||
{
|
||||
sNoiseFloorAverage.Clear();
|
||||
aNoiseFloor.Clear();
|
||||
}
|
||||
|
||||
} // namespace Thread
|
||||
|
||||
@@ -76,10 +76,11 @@ public:
|
||||
/**
|
||||
* This method adds a new received signal strength (RSS) value to the average.
|
||||
*
|
||||
* @param[in] anRss A new received signal strength value (in dBm) to be added to the average.
|
||||
* @param[in] aNoiseFloor A reference to the noise floor state.
|
||||
* @param[in] anRss A new received signal strength value (in dBm) to be added to the average.
|
||||
*
|
||||
*/
|
||||
void AddRss(int8_t anRss);
|
||||
void AddRss(LinkQualityInfo &aNoiseFloor, int8_t anRss);
|
||||
|
||||
/**
|
||||
* This method returns the current average signal strength value.
|
||||
@@ -115,10 +116,12 @@ public:
|
||||
* This method returns the link margin. The link margin is calculated using the link's current average received
|
||||
* signal strength (RSS) and average noise floor.
|
||||
*
|
||||
* @param[in] aNoiseFloor A reference to the noise state.
|
||||
*
|
||||
* @returns Link margin derived from average received signal strength and average noise floor.
|
||||
*
|
||||
*/
|
||||
uint8_t GetLinkMargin(void) const;
|
||||
uint8_t GetLinkMargin(LinkQualityInfo &aNoiseFloor) const;
|
||||
|
||||
/**
|
||||
* Returns the current one-way link quality value. The link quality value is a number 0-3.
|
||||
@@ -131,19 +134,22 @@ public:
|
||||
* frequent changes, a hysteresis of 2 dB is applied when determining the link quality. For example, the average
|
||||
* link margin must be at least 12 dB to change a quality 1 link to a quality 2 link.
|
||||
*
|
||||
* @param[in] aNoiseFloor A reference to the noise state.
|
||||
*
|
||||
* @returns The current link quality value (value 0-3 as per Thread specification).
|
||||
*/
|
||||
uint8_t GetLinkQuality(void);
|
||||
uint8_t GetLinkQuality(LinkQualityInfo &aNoiseFloor);
|
||||
|
||||
/**
|
||||
* This method converts a received signal strength value to a link margin value.
|
||||
*
|
||||
* @param[in] anRss The received signal strength value (in dBm).
|
||||
* @param[in] aNoiseFloor A reference to the noise state.
|
||||
* @param[in] anRss The received signal strength value (in dBm).
|
||||
*
|
||||
* @returns The link margin value.
|
||||
*
|
||||
*/
|
||||
static uint8_t ConvertRssToLinkMargin(int8_t anRss);
|
||||
static uint8_t ConvertRssToLinkMargin(LinkQualityInfo &aNoiseFloor, int8_t anRss);
|
||||
|
||||
/**
|
||||
* This method converts a link margin value to a link quality value.
|
||||
@@ -158,12 +164,13 @@ public:
|
||||
/**
|
||||
* This method converts a received signal strength value to a link quality value.
|
||||
*
|
||||
* @param[in] anRss The received signal strength value (in dBm).
|
||||
* @param[in] aNoiseFloor A reference to the noise state.
|
||||
* @param[in] anRss The received signal strength value (in dBm).
|
||||
*
|
||||
* @returns The link quality value (0-3).
|
||||
*
|
||||
*/
|
||||
static uint8_t ConvertRssToLinkQuality(int8_t anRss);
|
||||
static uint8_t ConvertRssToLinkQuality(LinkQualityInfo &aNoiseFloor, int8_t anRss);
|
||||
|
||||
private:
|
||||
enum
|
||||
@@ -193,7 +200,7 @@ private:
|
||||
/* Private method to update the mLinkQuality value. This is called when a new RSS value is added to average
|
||||
* or when GetLinkQuality() is invoked.
|
||||
*/
|
||||
void UpdateLinkQuality(void);
|
||||
void UpdateLinkQuality(LinkQualityInfo &aNoiseFloor);
|
||||
|
||||
/* Static private method to calculate the link quality from a given link margin while taking into account the last
|
||||
* link quality value and adding the hysteresis value to the thresholds. If there is no previous value for link
|
||||
@@ -214,23 +221,28 @@ private:
|
||||
/**
|
||||
* This function returns the current average noise floor level (in dBm).
|
||||
*
|
||||
* @param[in] aNoiseFloor A reference to the noise state.
|
||||
*
|
||||
* @returns The current average noise floor level (in dBm).
|
||||
*/
|
||||
int8_t GetAverageNoiseFloor(void);
|
||||
int8_t GetAverageNoiseFloor(LinkQualityInfo &aNoiseFloor);
|
||||
|
||||
/**
|
||||
* This method adds a new noise floor value (in dBm) to the running average.
|
||||
*
|
||||
* @param[in] aNoiseFloor A new noise floor value (in dBm) to be added to the average.
|
||||
* @param[in] aNoiseFloor A reference to the noise state.
|
||||
* @param[in] aNoise A new noise floor value (in dBm) to be added to the average.
|
||||
*
|
||||
*/
|
||||
void AddNoiseFloor(int8_t aNoiseFloor);
|
||||
void AddNoiseFloor(LinkQualityInfo &aNoiseFloor, int8_t aNoise);
|
||||
|
||||
/**
|
||||
* This method clears the current average noise floor value.
|
||||
*
|
||||
* @param[in] aNoiseFloor A reference to the noise state.
|
||||
*
|
||||
*/
|
||||
void ClearNoiseFloorAverage(void);
|
||||
void ClearNoiseFloorAverage(LinkQualityInfo &aNoiseFloor);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,10 +53,10 @@ namespace Thread {
|
||||
MeshForwarder::MeshForwarder(ThreadNetif &aThreadNetif):
|
||||
mMacReceiver(&HandleReceivedFrame, this),
|
||||
mMacSender(&HandleFrameRequest, &HandleSentFrame, this),
|
||||
mDiscoverTimer(&HandleDiscoverTimer, this),
|
||||
mPollTimer(&HandlePollTimer, this),
|
||||
mReassemblyTimer(&HandleReassemblyTimer, this),
|
||||
mScheduleTransmissionTask(ScheduleTransmissionTask, this),
|
||||
mDiscoverTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleDiscoverTimer, this),
|
||||
mPollTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandlePollTimer, this),
|
||||
mReassemblyTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleReassemblyTimer, this),
|
||||
mScheduleTransmissionTask(aThreadNetif.GetIp6().mTaskletScheduler, ScheduleTransmissionTask, this),
|
||||
mNetif(aThreadNetif),
|
||||
mAddressResolver(aThreadNetif.GetAddressResolver()),
|
||||
mLowpan(aThreadNetif.GetLowpan()),
|
||||
@@ -113,13 +113,13 @@ ThreadError MeshForwarder::Stop()
|
||||
while ((message = mSendQueue.GetHead()) != NULL)
|
||||
{
|
||||
mSendQueue.Dequeue(*message);
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
while ((message = mReassemblyList.GetHead()) != NULL)
|
||||
{
|
||||
mReassemblyList.Dequeue(*message);
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
mEnabled = false;
|
||||
@@ -157,7 +157,7 @@ void MeshForwarder::HandleResolved(const Ip6::Address &aEid, ThreadError aError)
|
||||
}
|
||||
else
|
||||
{
|
||||
Message::Free(*cur);
|
||||
cur->Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,7 +347,7 @@ Message *MeshForwarder::GetDirectTransmission()
|
||||
case kThreadError_Drop:
|
||||
case kThreadError_NoBufs:
|
||||
mSendQueue.Dequeue(*curMessage);
|
||||
Message::Free(*curMessage);
|
||||
curMessage->Free();
|
||||
continue;
|
||||
|
||||
default:
|
||||
@@ -620,7 +620,7 @@ void MeshForwarder::HandlePollTimer()
|
||||
{
|
||||
Message *message;
|
||||
|
||||
if ((message = Message::New(Message::kTypeMacDataPoll, 0)) != NULL)
|
||||
if ((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeMacDataPoll, 0)) != NULL)
|
||||
{
|
||||
SendMessage(*message);
|
||||
otLogInfoMac("Sent poll\n");
|
||||
@@ -1048,7 +1048,7 @@ void MeshForwarder::HandleSentFrame(Mac::Frame &aFrame)
|
||||
if (mSendMessage->GetDirectTransmission() == false && mSendMessage->IsChildPending() == false)
|
||||
{
|
||||
mSendQueue.Dequeue(*mSendMessage);
|
||||
Message::Free(*mSendMessage);
|
||||
mSendMessage->Free();
|
||||
}
|
||||
|
||||
mScheduleTransmissionTask.Post();
|
||||
@@ -1079,7 +1079,7 @@ void MeshForwarder::HandleDiscoverTimer(void)
|
||||
if (mScanChannel > kPhyMaxChannel)
|
||||
{
|
||||
mSendQueue.Dequeue(*mSendMessage);
|
||||
Message::Free(*mSendMessage);
|
||||
mSendMessage->Free();
|
||||
mMac.SetChannel(mRestoreChannel);
|
||||
mScanning = false;
|
||||
mMle.HandleDiscoverComplete();
|
||||
@@ -1235,7 +1235,8 @@ void MeshForwarder::HandleMesh(uint8_t *aFrame, uint8_t aFrameLength, const Thre
|
||||
|
||||
meshHeader->SetHopsLeft(meshHeader->GetHopsLeft() - 1);
|
||||
|
||||
VerifyOrExit((message = Message::New(Message::kType6lowpan, 0)) != NULL, error = kThreadError_Drop);
|
||||
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kType6lowpan, 0)) != NULL,
|
||||
error = kThreadError_Drop);
|
||||
SuccessOrExit(error = message->SetLength(aFrameLength));
|
||||
message->Write(0, aFrameLength, aFrame);
|
||||
message->SetLinkSecurityEnabled(aMessageInfo.mLinkSecurity);
|
||||
@@ -1248,7 +1249,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1296,7 +1297,8 @@ void MeshForwarder::HandleFragment(uint8_t *aFrame, uint8_t aFrameLength,
|
||||
aFrame += fragmentHeader->GetHeaderLength();
|
||||
aFrameLength -= fragmentHeader->GetHeaderLength();
|
||||
|
||||
VerifyOrExit((message = Message::New(Message::kTypeIp6, 0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL,
|
||||
error = kThreadError_NoBufs);
|
||||
message->SetLinkSecurityEnabled(aMessageInfo.mLinkSecurity);
|
||||
message->SetPanId(aMessageInfo.mPanId);
|
||||
headerLength = mLowpan.Decompress(*message, aMacSource, aMacDest, aFrame, aFrameLength, datagramLength);
|
||||
@@ -1361,7 +1363,7 @@ exit:
|
||||
}
|
||||
else if (message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1388,7 +1390,7 @@ void MeshForwarder::HandleReassemblyTimer()
|
||||
else
|
||||
{
|
||||
mReassemblyList.Dequeue(*message);
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1407,7 +1409,8 @@ void MeshForwarder::HandleLowpanHC(uint8_t *aFrame, uint8_t aFrameLength,
|
||||
int headerLength;
|
||||
uint16_t ip6PayloadLength;
|
||||
|
||||
VerifyOrExit((message = Message::New(Message::kTypeIp6, 0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL,
|
||||
error = kThreadError_NoBufs);
|
||||
message->SetLinkSecurityEnabled(aMessageInfo.mLinkSecurity);
|
||||
message->SetPanId(aMessageInfo.mPanId);
|
||||
|
||||
@@ -1435,13 +1438,13 @@ exit:
|
||||
}
|
||||
else if (message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
ThreadError MeshForwarder::HandleDatagram(Message &aMessage, const ThreadMessageInfo &aMessageInfo)
|
||||
{
|
||||
return Ip6::Ip6::HandleDatagram(aMessage, &mNetif, mNetif.GetInterfaceId(), &aMessageInfo, false);
|
||||
return mNetif.GetIp6().HandleDatagram(aMessage, &mNetif, mNetif.GetInterfaceId(), &aMessageInfo, false);
|
||||
}
|
||||
|
||||
void MeshForwarder::UpdateFramePending()
|
||||
|
||||
@@ -55,7 +55,8 @@ DatasetManager::DatasetManager(ThreadNetif &aThreadNetif, const char *aUriSet, c
|
||||
mNetworkDataLeader(aThreadNetif.GetNetworkDataLeader()),
|
||||
mResourceSet(aUriSet, &HandleSet, this),
|
||||
mResourceGet(aUriGet, &HandleGet, this),
|
||||
mTimer(&HandleTimer, this),
|
||||
mTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleTimer, this),
|
||||
mSocket(aThreadNetif.GetIp6().mUdp),
|
||||
mUriSet(aUriSet),
|
||||
mUriGet(aUriGet),
|
||||
mCoapServer(aThreadNetif.GetCoapServer())
|
||||
@@ -176,7 +177,7 @@ ThreadError DatasetManager::Register(void)
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
timestamp.Init();
|
||||
@@ -197,7 +198,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -332,7 +333,7 @@ ThreadError DatasetManager::SendSetRequest(const otOperationalDataset &aDataset,
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
if (aDataset.mIsActiveTimestampSet)
|
||||
@@ -425,7 +426,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -456,7 +457,7 @@ ThreadError DatasetManager::SendGetRequest(const uint8_t *aTlvTypes, const uint8
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
if (aLength > 0)
|
||||
@@ -478,7 +479,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -492,7 +493,7 @@ void DatasetManager::SendSetResponse(const Coap::Header &aRequestHeader, const I
|
||||
Message *message;
|
||||
StateTlv state;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
responseHeader.SetType(Coap::Header::kTypeAcknowledgment);
|
||||
@@ -514,7 +515,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,7 +528,7 @@ void DatasetManager::SendGetResponse(const Coap::Header &aRequestHeader, const I
|
||||
Message *message;
|
||||
uint8_t index;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
responseHeader.SetType(Coap::Header::kTypeAcknowledgment);
|
||||
@@ -561,7 +562,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,7 +688,7 @@ ThreadError ActiveDataset::ApplyConfiguration(void)
|
||||
|
||||
PendingDataset::PendingDataset(ThreadNetif &aThreadNetif):
|
||||
DatasetManager(aThreadNetif, OPENTHREAD_URI_PENDING_SET, OPENTHREAD_URI_PENDING_GET),
|
||||
mTimer(HandleTimer, this)
|
||||
mTimer(aThreadNetif.GetIp6().mTimerScheduler, HandleTimer, this)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+21
-19
@@ -61,8 +61,9 @@ Mle::Mle(ThreadNetif &aThreadNetif) :
|
||||
mMesh(aThreadNetif.GetMeshForwarder()),
|
||||
mMleRouter(aThreadNetif.GetMle()),
|
||||
mNetworkData(aThreadNetif.GetNetworkDataLeader()),
|
||||
mParentRequestTimer(&HandleParentRequestTimer, this),
|
||||
mSendChildUpdateRequest(&HandleSendChildUpdateRequest, this)
|
||||
mParentRequestTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleParentRequestTimer, this),
|
||||
mSocket(aThreadNetif.GetIp6().mUdp),
|
||||
mSendChildUpdateRequest(aThreadNetif.GetIp6().mTaskletScheduler, &HandleSendChildUpdateRequest, this)
|
||||
{
|
||||
mDeviceState = kDeviceStateDisabled;
|
||||
mDeviceMode = ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeSecureDataRequest | ModeTlv::kModeFFD |
|
||||
@@ -233,7 +234,7 @@ ThreadError Mle::Discover(uint32_t aScanChannels, uint16_t aScanDuration, uint16
|
||||
mDiscoverContext = aContext;
|
||||
mMesh.SetDiscoverParameters(aScanChannels, aScanDuration);
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
message->SetMleDiscoverRequest(true);
|
||||
message->SetPanId(aPanId);
|
||||
@@ -266,7 +267,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -344,7 +345,7 @@ ThreadError Mle::SetStateDetached(void)
|
||||
mParentRequestTimer.Stop();
|
||||
mMesh.SetRxOnWhenIdle(true);
|
||||
mMleRouter.HandleDetachStart();
|
||||
Ip6::Ip6::SetForwardingEnabled(false);
|
||||
mNetif.GetIp6().SetForwardingEnabled(false);
|
||||
|
||||
otLogInfoMle("Mode -> Detached\n");
|
||||
return kThreadError_None;
|
||||
@@ -371,7 +372,7 @@ ThreadError Mle::SetStateChild(uint16_t aRloc16)
|
||||
mMleRouter.HandleChildStart(mParentRequestMode);
|
||||
}
|
||||
|
||||
Ip6::Ip6::SetForwardingEnabled(false);
|
||||
mNetif.GetIp6().SetForwardingEnabled(false);
|
||||
|
||||
otLogInfoMle("Mode -> Child\n");
|
||||
return kThreadError_None;
|
||||
@@ -1079,7 +1080,7 @@ ThreadError Mle::SendParentRequest(void)
|
||||
mParentRequest.mChallenge[i] = static_cast<uint8_t>(otPlatRandomGet());
|
||||
}
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandParentRequest));
|
||||
SuccessOrExit(error = AppendMode(*message, mDeviceMode));
|
||||
@@ -1133,7 +1134,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return kThreadError_None;
|
||||
@@ -1146,7 +1147,7 @@ ThreadError Mle::SendChildIdRequest(void)
|
||||
Message *message;
|
||||
Ip6::Address destination;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildIdRequest));
|
||||
SuccessOrExit(error = AppendResponse(*message, mChildIdRequest.mChallenge, mChildIdRequest.mChallengeLength));
|
||||
@@ -1181,7 +1182,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -1192,7 +1193,7 @@ ThreadError Mle::SendDataRequest(const Ip6::Address &aDestination, const uint8_t
|
||||
ThreadError error = kThreadError_None;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandDataRequest));
|
||||
SuccessOrExit(error = AppendTlvRequest(*message, aTlvs, aTlvsLength));
|
||||
@@ -1207,7 +1208,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -1239,7 +1240,7 @@ ThreadError Mle::SendChildUpdateRequest(void)
|
||||
Ip6::Address destination;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildUpdateRequest));
|
||||
SuccessOrExit(error = AppendMode(*message, mDeviceMode));
|
||||
@@ -1291,7 +1292,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -1808,7 +1809,7 @@ ThreadError Mle::HandleParentResponse(const Message &aMessage, const Ip6::Messag
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLinkMargin, sizeof(linkMarginTlv), linkMarginTlv));
|
||||
VerifyOrExit(linkMarginTlv.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
linkMargin = LinkQualityInfo::ConvertRssToLinkMargin(threadMessageInfo->mRss);
|
||||
linkMargin = LinkQualityInfo::ConvertRssToLinkMargin(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
|
||||
if (linkMargin > linkMarginTlv.GetLinkMargin())
|
||||
{
|
||||
@@ -1888,7 +1889,7 @@ ThreadError Mle::HandleParentResponse(const Message &aMessage, const Ip6::Messag
|
||||
mParent.mValid.mMleFrameCounter = mleFrameCounter.GetFrameCounter();
|
||||
mParent.mMode = ModeTlv::kModeFFD | ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeFullNetworkData;
|
||||
mParent.mLinkInfo.Clear();
|
||||
mParent.mLinkInfo.AddRss(threadMessageInfo->mRss);
|
||||
mParent.mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
mParent.mState = Neighbor::kStateValid;
|
||||
mParent.mKeySequence = aKeySequence;
|
||||
|
||||
@@ -2176,7 +2177,7 @@ ThreadError Mle::SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_
|
||||
MeshCoP::ExtendedPanIdTlv extPanId;
|
||||
MeshCoP::NetworkNameTlv networkName;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
message->SetMleDiscoverResponse(true);
|
||||
message->SetPanId(aPanId);
|
||||
@@ -2214,7 +2215,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -2374,7 +2375,8 @@ ThreadError Mle::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6
|
||||
|
||||
memcpy(&dst, GetMeshLocal16(), kRlocPrefixLength);
|
||||
dst.mFields.m16[7] = HostSwap16(aMeshSource);
|
||||
Ip6::Icmp::SendError(dst, Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute, aIp6Header);
|
||||
mNetif.GetIp6().mIcmp.SendError(dst, Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute,
|
||||
aIp6Header);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -50,8 +50,9 @@ namespace Mle {
|
||||
|
||||
MleRouter::MleRouter(ThreadNetif &aThreadNetif):
|
||||
Mle(aThreadNetif),
|
||||
mAdvertiseTimer(&HandleAdvertiseTimer, this),
|
||||
mStateUpdateTimer(&HandleStateUpdateTimer, this),
|
||||
mAdvertiseTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleAdvertiseTimer, this),
|
||||
mStateUpdateTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleStateUpdateTimer, this),
|
||||
mSocket(aThreadNetif.GetIp6().mUdp),
|
||||
mAddressSolicit(OPENTHREAD_URI_ADDRESS_SOLICIT, &HandleAddressSolicit, this),
|
||||
mAddressRelease(OPENTHREAD_URI_ADDRESS_RELEASE, &HandleAddressRelease, this),
|
||||
mCoapServer(aThreadNetif.GetCoapServer())
|
||||
@@ -340,7 +341,7 @@ ThreadError MleRouter::SetStateRouter(uint16_t aRloc16)
|
||||
mRouters[mRouterId].mNextHop = mRouterId;
|
||||
mNetworkData.Stop();
|
||||
mStateUpdateTimer.Start(kStateUpdatePeriod);
|
||||
Ip6::Ip6::SetForwardingEnabled(true);
|
||||
mNetif.GetIp6().SetForwardingEnabled(true);
|
||||
|
||||
otLogInfoMle("Mode -> Router\n");
|
||||
return kThreadError_None;
|
||||
@@ -367,7 +368,7 @@ ThreadError MleRouter::SetStateLeader(uint16_t aRloc16)
|
||||
mNetif.GetPendingDataset().ApplyLocalToNetwork();
|
||||
mCoapServer.AddResource(mAddressSolicit);
|
||||
mCoapServer.AddResource(mAddressRelease);
|
||||
Ip6::Ip6::SetForwardingEnabled(true);
|
||||
mNetif.GetIp6().SetForwardingEnabled(true);
|
||||
|
||||
otLogInfoMle("Mode -> Leader %d\n", mLeaderData.GetPartitionId());
|
||||
return kThreadError_None;
|
||||
@@ -463,7 +464,7 @@ ThreadError MleRouter::SendAdvertisement(void)
|
||||
Ip6::Address destination;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandAdvertisement));
|
||||
SuccessOrExit(error = AppendSourceAddress(*message));
|
||||
@@ -496,7 +497,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -512,7 +513,7 @@ ThreadError MleRouter::SendLinkRequest(Neighbor *aNeighbor)
|
||||
|
||||
memset(&destination, 0, sizeof(destination));
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandLinkRequest));
|
||||
SuccessOrExit(error = AppendVersion(*message));
|
||||
@@ -572,7 +573,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -640,7 +641,7 @@ ThreadError MleRouter::HandleLinkRequest(const Message &aMessage, const Ip6::Mes
|
||||
|
||||
memcpy(&neighbor->mMacAddr, &macAddr, sizeof(neighbor->mMacAddr));
|
||||
neighbor->mLinkInfo.Clear();
|
||||
neighbor->mLinkInfo.AddRss(threadMessageInfo->mRss);
|
||||
neighbor->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
neighbor->mState = Neighbor::kStateLinkRequest;
|
||||
}
|
||||
else
|
||||
@@ -684,7 +685,7 @@ ThreadError MleRouter::SendLinkAccept(const Ip6::MessageInfo &aMessageInfo, Neig
|
||||
command = (aNeighbor == NULL || aNeighbor->mState == Neighbor::kStateValid) ?
|
||||
Header::kCommandLinkAccept : Header::kCommandLinkAcceptAndRequest;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, command));
|
||||
SuccessOrExit(error = AppendVersion(*message));
|
||||
@@ -694,7 +695,7 @@ ThreadError MleRouter::SendLinkAccept(const Ip6::MessageInfo &aMessageInfo, Neig
|
||||
SuccessOrExit(error = AppendMleFrameCounter(*message));
|
||||
|
||||
// always append a link margin, regardless of whether or not it was requested
|
||||
linkMargin = LinkQualityInfo::ConvertRssToLinkMargin(threadMessageInfo->mRss);
|
||||
linkMargin = LinkQualityInfo::ConvertRssToLinkMargin(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
|
||||
// add for certification testing
|
||||
if (isAssignLinkQuality &&
|
||||
@@ -757,7 +758,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -929,7 +930,7 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess
|
||||
neighbor->mLastHeard = Timer::GetNow();
|
||||
neighbor->mMode = ModeTlv::kModeFFD | ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeFullNetworkData;
|
||||
neighbor->mLinkInfo.Clear();
|
||||
neighbor->mLinkInfo.AddRss(threadMessageInfo->mRss);
|
||||
neighbor->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
neighbor->mState = Neighbor::kStateValid;
|
||||
neighbor->mKeySequence = aKeySequence;
|
||||
|
||||
@@ -961,7 +962,7 @@ ThreadError MleRouter::SendLinkReject(const Ip6::Address &aDestination)
|
||||
ThreadError error = kThreadError_None;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandLinkReject));
|
||||
SuccessOrExit(error = AppendStatus(*message, StatusTlv::kError));
|
||||
@@ -974,7 +975,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -1069,7 +1070,7 @@ uint8_t MleRouter::GetLinkCost(uint8_t aRouterId)
|
||||
mRouters[aRouterId].mState == Neighbor::kStateValid,
|
||||
rval = kMaxRouteCost);
|
||||
|
||||
rval = mRouters[aRouterId].mLinkInfo.GetLinkQuality();
|
||||
rval = mRouters[aRouterId].mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
|
||||
|
||||
if (rval > mRouters[aRouterId].mLinkQualityOut)
|
||||
{
|
||||
@@ -1358,7 +1359,7 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
{
|
||||
memcpy(&router->mMacAddr, &macAddr, sizeof(router->mMacAddr));
|
||||
router->mLinkInfo.Clear();
|
||||
router->mLinkInfo.AddRss(threadMessageInfo->mRss);
|
||||
router->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
router->mState = Neighbor::kStateLinkRequest;
|
||||
SendLinkRequest(router);
|
||||
ExitNow(error = kThreadError_NoRoute);
|
||||
@@ -1384,7 +1385,7 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
{
|
||||
memcpy(&router->mMacAddr, &macAddr, sizeof(router->mMacAddr));
|
||||
router->mLinkInfo.Clear();
|
||||
router->mLinkInfo.AddRss(threadMessageInfo->mRss);
|
||||
router->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
router->mState = Neighbor::kStateLinkRequest;
|
||||
router->mDataRequest = false;
|
||||
SendLinkRequest(router);
|
||||
@@ -1521,7 +1522,7 @@ void MleRouter::UpdateRoutes(const RouteTlv &aRoute, uint8_t aRouterId)
|
||||
}
|
||||
|
||||
otLogDebgMle("%x: %x %d %d %d %d\n", GetRloc16(i), GetRloc16(mRouters[i].mNextHop),
|
||||
mRouters[i].mCost, GetLinkCost(i), mRouters[i].mLinkInfo.GetLinkQuality(),
|
||||
mRouters[i].mCost, GetLinkCost(i), mRouters[i].mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor()),
|
||||
mRouters[i].mLinkQualityOut);
|
||||
}
|
||||
|
||||
@@ -1590,7 +1591,7 @@ ThreadError MleRouter::HandleParentRequest(const Message &aMessage, const Ip6::M
|
||||
// MAC Address
|
||||
memcpy(&child->mMacAddr, &macAddr, sizeof(child->mMacAddr));
|
||||
child->mLinkInfo.Clear();
|
||||
child->mLinkInfo.AddRss(threadMessageInfo->mRss);
|
||||
child->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
child->mState = Neighbor::kStateParentRequest;
|
||||
child->mDataRequest = false;
|
||||
|
||||
@@ -1706,7 +1707,7 @@ ThreadError MleRouter::SendParentResponse(Child *aChild, const ChallengeTlv &cha
|
||||
Ip6::Address destination;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandParentResponse));
|
||||
SuccessOrExit(error = AppendSourceAddress(*message));
|
||||
@@ -1730,7 +1731,7 @@ ThreadError MleRouter::SendParentResponse(Child *aChild, const ChallengeTlv &cha
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = AppendLinkMargin(*message, aChild->mLinkInfo.GetLinkMargin()));
|
||||
SuccessOrExit(error = AppendLinkMargin(*message, aChild->mLinkInfo.GetLinkMargin(mMac.GetNoiseFloor())));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = AppendConnectivity(*message));
|
||||
@@ -1747,7 +1748,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return kThreadError_None;
|
||||
@@ -1884,7 +1885,7 @@ ThreadError MleRouter::HandleChildIdRequest(const Message &aMessage, const Ip6::
|
||||
child->mValid.mMleFrameCounter = mleFrameCounter.GetFrameCounter();
|
||||
child->mKeySequence = aKeySequence;
|
||||
child->mMode = mode.GetMode();
|
||||
child->mLinkInfo.AddRss(threadMessageInfo->mRss);
|
||||
child->mLinkInfo.AddRss(mMac.GetNoiseFloor(), threadMessageInfo->mRss);
|
||||
child->mTimeout = timeout.GetTimeout();
|
||||
|
||||
if (mode.GetMode() & ModeTlv::kModeFullNetworkData)
|
||||
@@ -2093,7 +2094,7 @@ ThreadError MleRouter::SendChildIdResponse(Child *aChild)
|
||||
Ip6::Address destination;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildIdResponse));
|
||||
SuccessOrExit(error = AppendSourceAddress(*message));
|
||||
@@ -2157,7 +2158,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return kThreadError_None;
|
||||
@@ -2170,7 +2171,7 @@ ThreadError MleRouter::SendChildUpdateResponse(Child *aChild, const Ip6::Message
|
||||
ThreadError error = kThreadError_None;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildUpdateResponse));
|
||||
|
||||
@@ -2216,7 +2217,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return kThreadError_None;
|
||||
@@ -2229,7 +2230,7 @@ ThreadError MleRouter::SendDataResponse(const Ip6::Address &aDestination, const
|
||||
Neighbor *neighbor;
|
||||
bool stableOnly;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, ;);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandDataResponse));
|
||||
SuccessOrExit(error = AppendSourceAddress(*message));
|
||||
@@ -2265,7 +2266,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -2718,7 +2719,7 @@ void MleRouter::GetChildInfo(Child &aChild, otChildInfo &aChildInfo)
|
||||
aChildInfo.mChildId = GetChildId(aChild.mValid.mRloc16);
|
||||
aChildInfo.mNetworkDataVersion = aChild.mNetworkDataVersion;
|
||||
aChildInfo.mAge = Timer::MsecToSec(Timer::GetNow() - aChild.mLastHeard);
|
||||
aChildInfo.mLinkQualityIn = aChild.mLinkInfo.GetLinkQuality();
|
||||
aChildInfo.mLinkQualityIn = aChild.mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
|
||||
aChildInfo.mAverageRssi = aChild.mLinkInfo.GetAverageRss();
|
||||
|
||||
aChildInfo.mRxOnWhenIdle = (aChild.mMode & ModeTlv::kModeRxOnWhenIdle) != 0;
|
||||
@@ -2751,7 +2752,7 @@ ThreadError MleRouter::GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterIn
|
||||
aRouterInfo.mNextHop = mRouters[routerId].mNextHop;
|
||||
aRouterInfo.mLinkEstablished = mRouters[routerId].mState == Neighbor::kStateValid;
|
||||
aRouterInfo.mPathCost = mRouters[routerId].mCost;
|
||||
aRouterInfo.mLinkQualityIn = mRouters[routerId].mLinkInfo.GetLinkQuality();
|
||||
aRouterInfo.mLinkQualityIn = mRouters[routerId].mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
|
||||
aRouterInfo.mLinkQualityOut = mRouters[routerId].mLinkQualityOut;
|
||||
aRouterInfo.mAge = static_cast<uint8_t>(Timer::MsecToSec(Timer::GetNow() - mRouters[routerId].mLastHeard));
|
||||
|
||||
@@ -2798,8 +2799,8 @@ ThreadError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDes
|
||||
|
||||
memcpy(&destination, GetMeshLocal16(), 14);
|
||||
destination.mFields.m16[7] = HostSwap16(aMeshSource);
|
||||
Ip6::Icmp::SendError(destination, Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute,
|
||||
aIp6Header);
|
||||
mNetif.GetIp6().mIcmp.SendError(destination, Ip6::IcmpHeader::kTypeDstUnreach,
|
||||
Ip6::IcmpHeader::kCodeDstUnreachNoRoute, aIp6Header);
|
||||
|
||||
return kThreadError_Drop;
|
||||
}
|
||||
@@ -2829,7 +2830,7 @@ ThreadError MleRouter::SendAddressSolicit(ThreadStatusTlv::Status aStatus)
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
macAddr64Tlv.Init();
|
||||
@@ -2882,7 +2883,7 @@ ThreadError MleRouter::SendAddressRelease(void)
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
rlocTlv.Init();
|
||||
@@ -3119,7 +3120,7 @@ void MleRouter::SendAddressSolicitResponse(const Coap::Header &aRequestHeader, u
|
||||
ThreadRloc16Tlv rlocTlv;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
responseHeader.SetType(Coap::Header::kTypeAcknowledgment);
|
||||
@@ -3163,7 +3164,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3212,7 +3213,7 @@ void MleRouter::SendAddressReleaseResponse(const Coap::Header &aRequestHeader, c
|
||||
Coap::Header responseHeader;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
responseHeader.SetType(Coap::Header::kTypeAcknowledgment);
|
||||
@@ -3230,7 +3231,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3276,7 +3277,7 @@ ThreadError MleRouter::AppendConnectivity(Message &aMessage)
|
||||
break;
|
||||
|
||||
case kDeviceStateChild:
|
||||
switch (mParent.mLinkInfo.GetLinkQuality())
|
||||
switch (mParent.mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor()))
|
||||
{
|
||||
case 1:
|
||||
tlv.SetLinkQuality1(tlv.GetLinkQuality1() + 1);
|
||||
@@ -3291,7 +3292,7 @@ ThreadError MleRouter::AppendConnectivity(Message &aMessage)
|
||||
break;
|
||||
}
|
||||
|
||||
cost += LqiToCost(mParent.mLinkInfo.GetLinkQuality());
|
||||
cost += LqiToCost(mParent.mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor()));
|
||||
break;
|
||||
|
||||
case kDeviceStateRouter:
|
||||
@@ -3317,7 +3318,7 @@ ThreadError MleRouter::AppendConnectivity(Message &aMessage)
|
||||
continue;
|
||||
}
|
||||
|
||||
lqi = mRouters[i].mLinkInfo.GetLinkQuality();
|
||||
lqi = mRouters[i].mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
|
||||
|
||||
if (lqi > mRouters[i].mLinkQualityOut)
|
||||
{
|
||||
@@ -3446,7 +3447,7 @@ ThreadError MleRouter::AppendRoute(Message &aMessage)
|
||||
}
|
||||
else
|
||||
{
|
||||
tlv.SetLinkQualityIn(routeCount, mRouters[i].mLinkInfo.GetLinkQuality());
|
||||
tlv.SetLinkQualityIn(routeCount, mRouters[i].mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ namespace Thread {
|
||||
namespace NetworkData {
|
||||
|
||||
NetworkData::NetworkData(ThreadNetif &aThreadNetif):
|
||||
mMle(aThreadNetif.GetMle())
|
||||
mMle(aThreadNetif.GetMle()),
|
||||
mSocket(aThreadNetif.GetIp6().mUdp)
|
||||
{
|
||||
mLength = 0;
|
||||
mCoapMessageId = 0;
|
||||
@@ -608,7 +609,7 @@ ThreadError NetworkData::SendServerDataNotification(bool aLocal, uint16_t aRloc1
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
if (aLocal)
|
||||
@@ -639,7 +640,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace NetworkData {
|
||||
|
||||
Leader::Leader(ThreadNetif &aThreadNetif):
|
||||
NetworkData(aThreadNetif),
|
||||
mTimer(&HandleTimer, this),
|
||||
mTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleTimer, this),
|
||||
mServerData(OPENTHREAD_URI_SERVER_DATA, &HandleServerData, this),
|
||||
mCoapServer(aThreadNetif.GetCoapServer()),
|
||||
mNetif(aThreadNetif)
|
||||
@@ -497,7 +497,7 @@ void Leader::SendServerDataResponse(const Coap::Header &aRequestHeader, const Ip
|
||||
Coap::Header responseHeader;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = Ip6::Udp::NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
responseHeader.SetType(Coap::Header::kTypeAcknowledgment);
|
||||
@@ -517,7 +517,7 @@ exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,8 +54,9 @@ static const uint8_t kThreadMasterKey[] =
|
||||
|
||||
static const char name[] = "thread";
|
||||
|
||||
ThreadNetif::ThreadNetif(void):
|
||||
mCoapServer(kCoapUdpPort),
|
||||
ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
|
||||
Netif(aIp6),
|
||||
mCoapServer(aIp6.mUdp, kCoapUdpPort),
|
||||
mAddressResolver(*this),
|
||||
mActiveDataset(*this),
|
||||
mPendingDataset(*this),
|
||||
@@ -81,7 +82,7 @@ ThreadError ThreadNetif::Up(void)
|
||||
|
||||
VerifyOrExit(!mIsUp, error = kThreadError_Already);
|
||||
|
||||
Netif::AddNetif();
|
||||
mIp6.AddNetif(*this);
|
||||
mMeshForwarder.Start();
|
||||
mCoapServer.Start();
|
||||
mMleRouter.Enable();
|
||||
@@ -96,7 +97,7 @@ ThreadError ThreadNetif::Down(void)
|
||||
mCoapServer.Stop();
|
||||
mMleRouter.Disable();
|
||||
mMeshForwarder.Stop();
|
||||
Netif::RemoveNetif();
|
||||
mIp6.RemoveNetif(*this);
|
||||
mIsUp = false;
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
@@ -63,8 +63,10 @@ public:
|
||||
/**
|
||||
* This constructor initializes the Thread network interface.
|
||||
*
|
||||
* @param[in] aIp6 A reference to the IPv6 network object.
|
||||
*
|
||||
*/
|
||||
ThreadNetif(void);
|
||||
ThreadNetif(Ip6::Ip6 &aIp6);
|
||||
|
||||
/**
|
||||
* This method enables the Thread network interface.
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace Thread
|
||||
{
|
||||
|
||||
extern ThreadNetif *sThreadNetif;
|
||||
extern Ip6::Ip6 *sIp6;
|
||||
|
||||
static NcpBase *sNcpContext = NULL;
|
||||
|
||||
@@ -405,7 +406,7 @@ static uint8_t BorderRouterConfigToFlagByte(const otBorderRouterConfig &config)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
NcpBase::NcpBase():
|
||||
mUpdateChangedPropsTask(&UpdateChangedProps, this)
|
||||
mUpdateChangedPropsTask(sIp6->mTaskletScheduler, &UpdateChangedProps, this)
|
||||
{
|
||||
mSupportedChannelMask = kPhySupportedChannelMask;
|
||||
mChannelMask = mSupportedChannelMask;
|
||||
@@ -477,7 +478,7 @@ exit:
|
||||
|
||||
if (message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
if (errorCode != kThreadError_None)
|
||||
@@ -1075,7 +1076,7 @@ exit:
|
||||
|
||||
if (message != NULL)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
@@ -3102,7 +3103,7 @@ ThreadError NcpBase::SetPropertyHandler_STREAM_NET_INSECURE(uint8_t header, spin
|
||||
unsigned int frame_len(0);
|
||||
const uint8_t *meta_ptr(NULL);
|
||||
unsigned int meta_len(0);
|
||||
Message *message(Ip6::Ip6::NewMessage(0));
|
||||
Message *message(sIp6->mMessagePool.New(Message::kTypeIp6, 0));
|
||||
|
||||
if (message == NULL)
|
||||
{
|
||||
@@ -3138,7 +3139,7 @@ ThreadError NcpBase::SetPropertyHandler_STREAM_NET_INSECURE(uint8_t header, spin
|
||||
}
|
||||
else if (message)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
if (errorCode == kThreadError_None)
|
||||
@@ -3173,7 +3174,7 @@ ThreadError NcpBase::SetPropertyHandler_STREAM_NET(uint8_t header, spinel_prop_k
|
||||
unsigned int frame_len(0);
|
||||
const uint8_t *meta_ptr(NULL);
|
||||
unsigned int meta_len(0);
|
||||
Message *message(Ip6::Ip6::NewMessage(0));
|
||||
Message *message(sIp6->mMessagePool.New(Message::kTypeIp6, 0));
|
||||
|
||||
if (message == NULL)
|
||||
{
|
||||
@@ -3209,7 +3210,7 @@ ThreadError NcpBase::SetPropertyHandler_STREAM_NET(uint8_t header, spinel_prop_k
|
||||
}
|
||||
else if (message)
|
||||
{
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
if (errorCode == kThreadError_None)
|
||||
|
||||
@@ -78,13 +78,13 @@ void NcpFrameBuffer::Clear(void)
|
||||
while ((message = mWriteFrameMessageQueue.GetHead()) != NULL)
|
||||
{
|
||||
mWriteFrameMessageQueue.Dequeue(*message);
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
while ((message = mMessageQueue.GetHead()) != NULL)
|
||||
{
|
||||
mMessageQueue.Dequeue(*message);
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
|
||||
if (!wasEmpty)
|
||||
@@ -249,7 +249,7 @@ void NcpFrameBuffer::InFrameDiscard(void)
|
||||
while ((message = mWriteFrameMessageQueue.GetHead()) != NULL)
|
||||
{
|
||||
mWriteFrameMessageQueue.Dequeue(*message);
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +572,7 @@ ThreadError NcpFrameBuffer::OutFrameRemove(void)
|
||||
if ((message = mMessageQueue.GetHead()) != NULL)
|
||||
{
|
||||
mMessageQueue.Dequeue(*message);
|
||||
Message::Free(*message);
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -47,6 +47,8 @@ namespace Thread {
|
||||
static otDEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpSpi), uint64_t);
|
||||
static NcpSpi *sNcpSpi;
|
||||
|
||||
extern Ip6::Ip6 *sIp6;
|
||||
|
||||
extern "C" void otNcpInit(void)
|
||||
{
|
||||
sNcpSpi = new(&sNcpRaw) NcpSpi;
|
||||
@@ -86,8 +88,8 @@ static uint16_t spi_header_get_data_len(const uint8_t *header)
|
||||
|
||||
NcpSpi::NcpSpi():
|
||||
NcpBase(),
|
||||
mHandleRxFrameTask(&HandleRxFrame, this),
|
||||
mPrepareTxFrameTask(&PrepareTxFrame, this),
|
||||
mHandleRxFrameTask(sIp6->mTaskletScheduler, &HandleRxFrame, this),
|
||||
mPrepareTxFrameTask(sIp6->mTaskletScheduler, &PrepareTxFrame, this),
|
||||
mTxFrameBuffer(mTxBuffer, sizeof(mTxBuffer))
|
||||
{
|
||||
memset(mEmptySendFrame, 0, kSpiHeaderLength);
|
||||
|
||||
@@ -44,6 +44,8 @@ namespace Thread {
|
||||
static otDEFINE_ALIGNED_VAR(sNcpRaw, sizeof(NcpUart), uint64_t);
|
||||
static NcpUart *sNcpUart;
|
||||
|
||||
extern Ip6::Ip6 *sIp6;
|
||||
|
||||
extern "C" void otNcpInit(void)
|
||||
{
|
||||
sNcpUart = new(&sNcpRaw) NcpUart;
|
||||
@@ -81,7 +83,7 @@ NcpUart::NcpUart():
|
||||
mFrameDecoder(mRxBuffer, sizeof(mRxBuffer), &HandleFrame, &HandleError, this),
|
||||
mUartBuffer(),
|
||||
mTxFrameBuffer(mTxBuffer, sizeof(mTxBuffer)),
|
||||
mUartSendTask(EncodeAndSendToUart, this)
|
||||
mUartSendTask(sIp6->mTaskletScheduler, EncodeAndSendToUart, this)
|
||||
{
|
||||
mState = kStartingFrame;
|
||||
|
||||
|
||||
@@ -30,8 +30,11 @@
|
||||
#include <openthread.h>
|
||||
#include <common/debug.hpp>
|
||||
#include <crypto/aes_ccm.hpp>
|
||||
#include <crypto/mbedtls.hpp>
|
||||
#include <string.h>
|
||||
|
||||
static Thread::Crypto::MbedTls mbedtls;
|
||||
|
||||
extern"C" void otSignalTaskletPending(void)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -31,7 +31,10 @@
|
||||
#include <common/debug.hpp>
|
||||
#include <string.h>
|
||||
|
||||
#include <crypto/hmac_sha256.h>
|
||||
#include <crypto/hmac_sha256.hpp>
|
||||
#include <crypto/mbedtls.hpp>
|
||||
|
||||
static Thread::Crypto::MbedTls mbedtls;
|
||||
|
||||
extern"C" void otSignalTaskletPending(void)
|
||||
{
|
||||
@@ -43,7 +46,7 @@ void TestHmacSha256(void)
|
||||
{
|
||||
const char *key;
|
||||
const char *data;
|
||||
uint8_t hash[otCryptoSha256Size];
|
||||
uint8_t hash[Thread::Crypto::HmacSha256::kHashSize];
|
||||
} tests[] =
|
||||
{
|
||||
{
|
||||
@@ -63,13 +66,14 @@ void TestHmacSha256(void)
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t hash[otCryptoSha256Size];
|
||||
Thread::Crypto::HmacSha256 hmac;
|
||||
uint8_t hash[Thread::Crypto::HmacSha256::kHashSize];
|
||||
|
||||
for (int i = 0; tests[i].key != NULL; i++)
|
||||
{
|
||||
otCryptoHmacSha256Start(tests[i].key, static_cast<uint16_t>(strlen(tests[i].key)));
|
||||
otCryptoHmacSha256Update(tests[i].data, static_cast<uint16_t>(strlen(tests[i].data)));
|
||||
otCryptoHmacSha256Finish(hash);
|
||||
hmac.Start(reinterpret_cast<const uint8_t *>(tests[i].key), static_cast<uint16_t>(strlen(tests[i].key)));
|
||||
hmac.Update(reinterpret_cast<const uint8_t *>(tests[i].data), static_cast<uint16_t>(strlen(tests[i].data)));
|
||||
hmac.Finish(hash);
|
||||
|
||||
VerifyOrQuit(memcmp(hash, tests[i].hash, sizeof(tests[i].hash)) == 0,
|
||||
"HMAC-SHA-256 failed\n");
|
||||
|
||||
@@ -65,6 +65,8 @@ struct RssTestData
|
||||
uint8_t mExpectedLinkQuality; // Expected final link quality value.
|
||||
};
|
||||
|
||||
static LinkQualityInfo sNoiseFloor;
|
||||
|
||||
// Checks the encoded average RSS value to match the value from GetAverageRss().
|
||||
void VerifyEncodedRssValue(LinkQualityInfo &aLinkInfo)
|
||||
{
|
||||
@@ -92,7 +94,8 @@ void PrintOutcome(LinkQualityInfo &aLinkInfo)
|
||||
"TestLinkQualityInfo failed - GetAverageRssAsString() failed.");
|
||||
|
||||
printf("AveRss = %-4d, \"%-14s\", ", aLinkInfo.GetAverageRss(), stringBuf);
|
||||
printf("LinkMargin = %-4d, LinkQuality = %d", aLinkInfo.GetLinkMargin(), aLinkInfo.GetLinkQuality());
|
||||
printf("LinkMargin = %-4d, LinkQuality = %d", aLinkInfo.GetLinkMargin(sNoiseFloor),
|
||||
aLinkInfo.GetLinkQuality(sNoiseFloor));
|
||||
|
||||
// This test-case succeeded.
|
||||
printf(" -> PASS\n");
|
||||
@@ -113,7 +116,7 @@ void TestLinkQualityData(RssTestData anRssData)
|
||||
rss = anRssData.mRssList[i];
|
||||
min = MIN_RSS(rss, min);
|
||||
max = MAX_RSS(rss, max);
|
||||
linkInfo.AddRss(rss);
|
||||
linkInfo.AddRss(sNoiseFloor, rss);
|
||||
ave = linkInfo.GetAverageRss();
|
||||
VerifyOrQuit(ave >= min,
|
||||
"TestLinkQualityInfo failed - GetAverageRss() is smaller than min value.");
|
||||
@@ -124,7 +127,7 @@ void TestLinkQualityData(RssTestData anRssData)
|
||||
PrintOutcome(linkInfo);
|
||||
}
|
||||
|
||||
VerifyOrQuit(linkInfo.GetLinkQuality() == anRssData.mExpectedLinkQuality,
|
||||
VerifyOrQuit(linkInfo.GetLinkQuality(sNoiseFloor) == anRssData.mExpectedLinkQuality,
|
||||
"TestLinkQualityInfo failed - GetLinkQuality() is incorrect");
|
||||
}
|
||||
|
||||
@@ -142,7 +145,7 @@ void TestRssAveraging(void)
|
||||
printf("\nAfter Initialization: ");
|
||||
VerifyOrQuit(linkInfo.GetAverageRss() == LinkQualityInfo::kUnknownRss,
|
||||
"TestLinkQualityInfo failed - Inital value from GetAverageRss() is incorrect.");
|
||||
VerifyOrQuit(linkInfo.GetLinkMargin() == 0,
|
||||
VerifyOrQuit(linkInfo.GetLinkMargin(sNoiseFloor) == 0,
|
||||
"TestLinkQualityInfo failed - Inital value for link margin is incorrect.");
|
||||
VerifyEncodedRssValue(linkInfo);
|
||||
PrintOutcome(linkInfo);
|
||||
@@ -151,7 +154,7 @@ void TestRssAveraging(void)
|
||||
// Adding a single value
|
||||
rss = -70;
|
||||
printf("AddRss(%d): ", rss);
|
||||
linkInfo.AddRss(rss);
|
||||
linkInfo.AddRss(sNoiseFloor, rss);
|
||||
VerifyOrQuit(linkInfo.GetAverageRss() == rss,
|
||||
"TestLinkQualityInfo - GetAverageRss() failed after a single AddRss().");
|
||||
VerifyEncodedRssValue(linkInfo);
|
||||
@@ -164,7 +167,7 @@ void TestRssAveraging(void)
|
||||
linkInfo.Clear();
|
||||
VerifyOrQuit(linkInfo.GetAverageRss() == LinkQualityInfo::kUnknownRss,
|
||||
"TestLinkQualityInfo failed - GetAverageRss() after Clear() is incorrect.");
|
||||
VerifyOrQuit(linkInfo.GetLinkMargin() == 0,
|
||||
VerifyOrQuit(linkInfo.GetLinkMargin(sNoiseFloor) == 0,
|
||||
"TestLinkQualityInfo failed - link margin value after Clear() is incorrect.");
|
||||
VerifyEncodedRssValue(linkInfo);
|
||||
PrintOutcome(linkInfo);
|
||||
@@ -182,7 +185,7 @@ void TestRssAveraging(void)
|
||||
|
||||
for (i = 0; i < kNumRssAdds; i++)
|
||||
{
|
||||
linkInfo.AddRss(rss);
|
||||
linkInfo.AddRss(sNoiseFloor, rss);
|
||||
VerifyOrQuit(linkInfo.GetAverageRss() == rss,
|
||||
"TestLinkQualityInfo failed - GetAverageRss() returned incorrect value.");
|
||||
VerifyEncodedRssValue(linkInfo);
|
||||
@@ -210,8 +213,8 @@ void TestRssAveraging(void)
|
||||
|
||||
rss2 = rssValues[k];
|
||||
linkInfo.Clear();
|
||||
linkInfo.AddRss(rss);
|
||||
linkInfo.AddRss(rss2);
|
||||
linkInfo.AddRss(sNoiseFloor, rss);
|
||||
linkInfo.AddRss(sNoiseFloor, rss2);
|
||||
printf("AddRss(%4d), AddRss(%4d): ", rss, rss2);
|
||||
VerifyOrQuit(linkInfo.GetAverageRss() == ((rss + rss2) >> 1),
|
||||
"TestLinkQualityInfo failed - GetAverageRss() returned incorrect value.");
|
||||
@@ -241,10 +244,10 @@ void TestRssAveraging(void)
|
||||
|
||||
for (i = 0; i < kNumRssAdds; i++)
|
||||
{
|
||||
linkInfo.AddRss(rss);
|
||||
linkInfo.AddRss(sNoiseFloor, rss);
|
||||
}
|
||||
|
||||
linkInfo.AddRss(rss2);
|
||||
linkInfo.AddRss(sNoiseFloor, rss2);
|
||||
printf("AddRss(%4d) %d times, AddRss(%4d): ", rss, kNumRssAdds, rss2);
|
||||
ave = linkInfo.GetAverageRss();
|
||||
VerifyOrQuit(ave >= MIN_RSS(rss, rss2),
|
||||
@@ -277,8 +280,8 @@ void TestRssAveraging(void)
|
||||
|
||||
for (i = 0; i < kNumRssAdds; i++)
|
||||
{
|
||||
linkInfo.AddRss(rss);
|
||||
linkInfo.AddRss(rss2);
|
||||
linkInfo.AddRss(sNoiseFloor, rss);
|
||||
linkInfo.AddRss(sNoiseFloor, rss2);
|
||||
ave = linkInfo.GetAverageRss();
|
||||
VerifyOrQuit(ave >= MIN_RSS(rss, rss2),
|
||||
"TestLinkQualityInfo failed - GetAverageRss() is smaller than min value.");
|
||||
|
||||
@@ -75,7 +75,8 @@ extern "C" void otPlatDiagRadioReceiveDone(RadioPacket *aFrame, ThreadError aErr
|
||||
(void)aError;
|
||||
}
|
||||
|
||||
ThreadNetif sMockThreadNetif;
|
||||
Ip6::Ip6 sIp6;
|
||||
ThreadNetif sMockThreadNetif(sIp6);
|
||||
Lowpan::Lowpan sMockLowpan(sMockThreadNetif);
|
||||
|
||||
void TestLowpanIphc(void)
|
||||
@@ -116,7 +117,7 @@ void TestLowpanIphc(void)
|
||||
frame.GetSrcAddr(macSource);
|
||||
frame.GetDstAddr(macDest);
|
||||
|
||||
VerifyOrQuit((message = Ip6::Ip6::NewMessage(0)) != NULL,
|
||||
VerifyOrQuit((message = sIp6.mMessagePool.New(Message::kTypeIp6, 0)) != NULL,
|
||||
"6lo: Ip6::NewMessage failed");
|
||||
|
||||
// ===> Test Lowpan::Decompress
|
||||
@@ -153,7 +154,7 @@ void TestLowpanIphc(void)
|
||||
VerifyOrQuit(memcmp(frame.GetPayload(), result, static_cast<size_t>(compressBytes)) == 0,
|
||||
"6lo: Lowpan::Compress failed");
|
||||
|
||||
SuccessOrQuit(Message::Free(*message), "6lo: Message:Free failed");
|
||||
SuccessOrQuit(message->Free(), "6lo: Message:Free failed");
|
||||
printf("PASS\n\n");
|
||||
|
||||
}
|
||||
@@ -164,8 +165,6 @@ void TestLowpanIphc(void)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Message::Init();
|
||||
|
||||
TestLowpanIphc();
|
||||
|
||||
printf("All tests passed\n");
|
||||
|
||||
@@ -42,18 +42,17 @@ extern "C" void otPlatDiagAlarmFired(void)
|
||||
|
||||
void TestMessage(void)
|
||||
{
|
||||
Thread::MessagePool messagePool;
|
||||
Thread::Message *message;
|
||||
uint8_t writeBuffer[1024];
|
||||
uint8_t readBuffer[1024];
|
||||
|
||||
Thread::Message::Init();
|
||||
|
||||
for (unsigned i = 0; i < sizeof(writeBuffer); i++)
|
||||
{
|
||||
writeBuffer[i] = static_cast<uint8_t>(random());
|
||||
}
|
||||
|
||||
VerifyOrQuit((message = Thread::Message::New(Thread::Message::kTypeIp6, 0)) != NULL,
|
||||
VerifyOrQuit((message = messagePool.New(Thread::Message::kTypeIp6, 0)) != NULL,
|
||||
"Message::New failed\n");
|
||||
SuccessOrQuit(message->SetLength(sizeof(writeBuffer)),
|
||||
"Message::SetLength failed\n");
|
||||
@@ -65,7 +64,7 @@ void TestMessage(void)
|
||||
"Message compare failed\n");
|
||||
VerifyOrQuit(message->GetLength() == 1024,
|
||||
"Message::GetLength failed\n");
|
||||
SuccessOrQuit(Thread::Message::Free(*message),
|
||||
SuccessOrQuit(message->Free(),
|
||||
"Message::Free failed\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ static const uint8_t sHelloText[] = "Hello there!";
|
||||
static const uint8_t sMottoText[] = "Think good thoughts, say good words, do good deeds!";
|
||||
static const uint8_t sMysteryText[] = "4871(\\):|(3$}{4|/4/2%14(\\)";
|
||||
|
||||
static MessagePool sMessagePool;
|
||||
|
||||
struct CallbackContext
|
||||
{
|
||||
@@ -63,12 +64,6 @@ struct CallbackContext
|
||||
uint16_t mNonEmptyCount; // Number of times BufferNonEmptyCallback is invoked.
|
||||
};
|
||||
|
||||
// Initialize the test
|
||||
void InitTest(void)
|
||||
{
|
||||
Message::Init();
|
||||
}
|
||||
|
||||
void BufferDidGetEmptyCallback(void *aContext, NcpFrameBuffer *aNcpBuffer)
|
||||
{
|
||||
CallbackContext *callbackContext = reinterpret_cast<CallbackContext *>(aContext);
|
||||
@@ -147,7 +142,7 @@ void WriteTestFrame1(NcpFrameBuffer &aNcpBuffer)
|
||||
{
|
||||
Message *message;
|
||||
|
||||
message = Message::New(Message::kTypeIp6, 0);
|
||||
message = sMessagePool.New(Message::kTypeIp6, 0);
|
||||
VerifyOrQuit(message != NULL, "Null Message");
|
||||
SuccessOrQuit(message->SetLength(sizeof(sMottoText)), "Could not set the length of message.");
|
||||
message->Write(0, sizeof(sMottoText), sMottoText);
|
||||
@@ -182,12 +177,12 @@ void WriteTestFrame2(NcpFrameBuffer &aNcpBuffer)
|
||||
Message *message1;
|
||||
Message *message2;
|
||||
|
||||
message1 = Message::New(Message::kTypeIp6, 0);
|
||||
message1 = sMessagePool.New(Message::kTypeIp6, 0);
|
||||
VerifyOrQuit(message1 != NULL, "Null Message");
|
||||
SuccessOrQuit(message1->SetLength(sizeof(sMysteryText)), "Could not set the length of message.");
|
||||
message1->Write(0, sizeof(sMysteryText), sMysteryText);
|
||||
|
||||
message2 = Message::New(Message::kTypeIp6, 0);
|
||||
message2 = sMessagePool.New(Message::kTypeIp6, 0);
|
||||
VerifyOrQuit(message2 != NULL, "Null Message");
|
||||
SuccessOrQuit(message2->SetLength(sizeof(sHelloText)), "Could not set the length of message.");
|
||||
message2->Write(0, sizeof(sHelloText), sHelloText);
|
||||
@@ -219,7 +214,7 @@ void WriteTestFrame3(NcpFrameBuffer &aNcpBuffer)
|
||||
{
|
||||
Message *message1;
|
||||
|
||||
message1 = Message::New(Message::kTypeIp6, 0);
|
||||
message1 = sMessagePool.New(Message::kTypeIp6, 0);
|
||||
VerifyOrQuit(message1 != NULL, "Null Message");
|
||||
|
||||
// An empty message with no content.
|
||||
@@ -344,7 +339,7 @@ void TestNcpFrameBuffer(void)
|
||||
ncpBuffer.InFrameBegin();
|
||||
ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText));
|
||||
|
||||
message = Message::New(Message::kTypeIp6, 0);
|
||||
message = sMessagePool.New(Message::kTypeIp6, 0);
|
||||
VerifyOrQuit(message != NULL, "Null Message");
|
||||
SuccessOrQuit(message->SetLength(sizeof(sMysteryText)), "Could not set the length of message.");
|
||||
message->Write(0, sizeof(sMysteryText), sMysteryText);
|
||||
@@ -475,7 +470,6 @@ void TestNcpFrameBuffer(void)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Thread::InitTest();
|
||||
Thread::TestNcpFrameBuffer();
|
||||
printf("\nAll tests passed.\n");
|
||||
return 0;
|
||||
|
||||
+12
-11
@@ -42,6 +42,7 @@ enum
|
||||
kCallCountIndexMax
|
||||
};
|
||||
|
||||
static Thread::TimerScheduler sTimerScheduler;
|
||||
static uint32_t sNow;
|
||||
static uint32_t sPlatT0;
|
||||
static uint32_t sPlatDt;
|
||||
@@ -93,7 +94,7 @@ int TestOneTimer(void)
|
||||
{
|
||||
const uint32_t kTimeT0 = 1000;
|
||||
const uint32_t kTimerInterval = 10;
|
||||
Thread::Timer timer(TestTimerHandler, NULL);
|
||||
Thread::Timer timer(sTimerScheduler, TestTimerHandler, NULL);
|
||||
|
||||
// Test one Timer basic operation.
|
||||
|
||||
@@ -325,16 +326,16 @@ int TestTenTimers(void)
|
||||
};
|
||||
|
||||
uint32_t timerContextHandleCounter[kNumTimers] = {0};
|
||||
Thread::Timer timer0(TestTimerHandler, &timerContextHandleCounter[0]);
|
||||
Thread::Timer timer1(TestTimerHandler, &timerContextHandleCounter[1]);
|
||||
Thread::Timer timer2(TestTimerHandler, &timerContextHandleCounter[2]);
|
||||
Thread::Timer timer3(TestTimerHandler, &timerContextHandleCounter[3]);
|
||||
Thread::Timer timer4(TestTimerHandler, &timerContextHandleCounter[4]);
|
||||
Thread::Timer timer5(TestTimerHandler, &timerContextHandleCounter[5]);
|
||||
Thread::Timer timer6(TestTimerHandler, &timerContextHandleCounter[6]);
|
||||
Thread::Timer timer7(TestTimerHandler, &timerContextHandleCounter[7]);
|
||||
Thread::Timer timer8(TestTimerHandler, &timerContextHandleCounter[8]);
|
||||
Thread::Timer timer9(TestTimerHandler, &timerContextHandleCounter[9]);
|
||||
Thread::Timer timer0(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[0]);
|
||||
Thread::Timer timer1(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[1]);
|
||||
Thread::Timer timer2(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[2]);
|
||||
Thread::Timer timer3(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[3]);
|
||||
Thread::Timer timer4(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[4]);
|
||||
Thread::Timer timer5(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[5]);
|
||||
Thread::Timer timer6(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[6]);
|
||||
Thread::Timer timer7(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[7]);
|
||||
Thread::Timer timer8(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[8]);
|
||||
Thread::Timer timer9(sTimerScheduler, TestTimerHandler, &timerContextHandleCounter[9]);
|
||||
Thread::Timer *timers[kNumTimers] = {&timer0, &timer1, &timer2, &timer3, &timer4, &timer5, &timer6, &timer7, &timer8, &timer9};
|
||||
size_t i;
|
||||
|
||||
|
||||
Vendored
-1
@@ -38,7 +38,6 @@ libmbedcrypto_a_CPPFLAGS = \
|
||||
$(NULL)
|
||||
|
||||
libmbedcrypto_a_SOURCES = \
|
||||
mbedcrypto.c \
|
||||
repo/library/aes.c \
|
||||
repo/library/md.c \
|
||||
repo/library/md_wrap.c \
|
||||
|
||||
Vendored
-89
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Nest Labs Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openthread-types.h>
|
||||
|
||||
#include <mbedtls/memory_buffer_alloc.h>
|
||||
#include <mbedtls/aes.h>
|
||||
#include <mbedtls/md.h>
|
||||
|
||||
#include <crypto/aes_ecb.h>
|
||||
#include <crypto/hmac_sha256.h>
|
||||
|
||||
/**
|
||||
* @def MBED_MEMORY_BUF_SIZE
|
||||
*
|
||||
* The size of the memory buffer used by mbedtls.
|
||||
*
|
||||
*/
|
||||
#define MBED_MEMORY_BUF_SIZE 512
|
||||
|
||||
void mbedInit(void);
|
||||
|
||||
static bool sIsInitialized = false;
|
||||
static unsigned char sMemoryBuf[MBED_MEMORY_BUF_SIZE];
|
||||
|
||||
static mbedtls_aes_context sAesContext;
|
||||
static mbedtls_md_context_t sSha256Context;
|
||||
|
||||
void mbedInit(void)
|
||||
{
|
||||
if (sIsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_memory_buffer_alloc_init(sMemoryBuf, sizeof(sMemoryBuf));
|
||||
sIsInitialized = true;
|
||||
}
|
||||
|
||||
void otCryptoHmacSha256Start(const void *aKey, uint16_t aKeyLength)
|
||||
{
|
||||
const mbedtls_md_info_t *mdInfo = NULL;
|
||||
|
||||
mbedInit();
|
||||
|
||||
mbedtls_md_init(&sSha256Context);
|
||||
mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||
mbedtls_md_setup(&sSha256Context, mdInfo, 1);
|
||||
mbedtls_md_hmac_starts(&sSha256Context, aKey, aKeyLength);
|
||||
}
|
||||
|
||||
void otCryptoHmacSha256Update(const void *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
mbedtls_md_hmac_update(&sSha256Context, aBuf, aBufLength);
|
||||
}
|
||||
|
||||
void otCryptoHmacSha256Finish(uint8_t aHash[otCryptoSha256Size])
|
||||
{
|
||||
mbedtls_md_hmac_finish(&sSha256Context, aHash);
|
||||
mbedtls_md_free(&sSha256Context);
|
||||
}
|
||||
|
||||
void otCryptoAesEcbSetKey(const void *aKey, uint16_t aKeyLength)
|
||||
{
|
||||
mbedtls_aes_init(&sAesContext);
|
||||
mbedtls_aes_setkey_enc(&sAesContext, aKey, aKeyLength);
|
||||
}
|
||||
|
||||
void otCryptoAesEcbEncrypt(const uint8_t aInput[otAesBlockSize], uint8_t aOutput[otAesBlockSize])
|
||||
{
|
||||
mbedtls_aes_crypt_ecb(&sAesContext, MBEDTLS_AES_ENCRYPT, aInput, aOutput);
|
||||
}
|
||||
Reference in New Issue
Block a user