mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 14:47:46 +00:00
[ICMPv6] Allow application to register ICMPv6 handler. (#1380)
This commit is contained in:
committed by
Jonathan Hui
parent
fc45943f8c
commit
4f35cdb854
@@ -786,7 +786,7 @@ otLwfEventWorkerThread(
|
||||
NT_ASSERT(otCtxToFilter(pFilter->otCtx) == pFilter);
|
||||
|
||||
// Disable Icmp (ping) handling
|
||||
otSetIcmpEchoEnabled(pFilter->otCtx, FALSE);
|
||||
otIcmp6SetEchoEnabled(pFilter->otCtx, FALSE);
|
||||
|
||||
// Register callbacks with OpenThread
|
||||
otSetStateChangedCallback(pFilter->otCtx, otLwfStateChangedCallback, pFilter);
|
||||
|
||||
@@ -62,6 +62,7 @@ RtlCopyBufferToMdl(
|
||||
#include <openthread-windows-config.h>
|
||||
#include <openthread-core-config.h>
|
||||
#include <openthread.h>
|
||||
#include <openthread-icmp6.h>
|
||||
#include <openthread-ip6.h>
|
||||
#include <openthread-tasklet.h>
|
||||
#include <commissioning/commissioner.h>
|
||||
|
||||
@@ -85,7 +85,7 @@ otPlatReset(
|
||||
NT_ASSERT(otCtxToFilter(pFilter->otCtx) == pFilter);
|
||||
|
||||
// Disable Icmp (ping) handling
|
||||
otSetIcmpEchoEnabled(pFilter->otCtx, FALSE);
|
||||
otIcmp6SetEchoEnabled(pFilter->otCtx, FALSE);
|
||||
|
||||
// Register callbacks with OpenThread
|
||||
otSetStateChangedCallback(pFilter->otCtx, otLwfStateChangedCallback, pFilter);
|
||||
|
||||
@@ -64,6 +64,7 @@ include_HEADERS = \
|
||||
openthread-coap.h \
|
||||
openthread-crypto.h \
|
||||
openthread-diag.h \
|
||||
openthread-icmp6.h \
|
||||
openthread-ip6.h \
|
||||
openthread-jam-detection.h \
|
||||
openthread-message.h \
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file defines the top-level icmp6 functions for the OpenThread library.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_ICMP6_H_
|
||||
#define OPENTHREAD_ICMP6_H_
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <openthread-message.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup icmp6 ICMPv6
|
||||
*
|
||||
* @brief
|
||||
* This module includes functions that control ICMPv6 communication.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This function indicates whether or not ICMPv6 Echo processing is enabled.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval TRUE ICMPv6 Echo processing is enabled.
|
||||
* @retval FALSE ICMPv6 Echo processing is disabled.
|
||||
*
|
||||
*/
|
||||
bool otIcmp6IsEchoEnabled(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function sets whether or not ICMPv6 Echo processing is enabled.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aEnabled TRUE to enable ICMPv6 Echo processing, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
void otIcmp6SetEchoEnabled(otInstance *aInstance, bool aEnabled);
|
||||
|
||||
/**
|
||||
* This function registers a handler to provide received ICMPv6 messages.
|
||||
*
|
||||
* @note A handler structure @p aHandler has to be stored in persistant (static) memory.
|
||||
* OpenThread does not make a copy of handler structure.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aHandler A pointer to a handler conitaining callback that is called when
|
||||
* an ICMPv6 message is received.
|
||||
*
|
||||
*/
|
||||
ThreadError otIcmp6RegisterHandler(otInstance *aInstance, otIcmp6Handler *aHandler);
|
||||
|
||||
/**
|
||||
* This function sends an ICMPv6 Echo Request via the Thread interface.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aMessage A pointer to the message buffer containing the ICMPv6 payload.
|
||||
* @param[in] aMessageInfo A reference to message information associated with @p aMessage.
|
||||
* @param[in] aIdentifier An identifier to aid in matching Echo Replies to this Echo Request.
|
||||
* May be zero.
|
||||
*
|
||||
*/
|
||||
ThreadError otIcmp6SendEchoRequest(otInstance *aInstance, otMessage aMessage,
|
||||
const otMessageInfo *aMessageInfo, uint16_t aIdentifier);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_ICMP6_H_
|
||||
@@ -342,26 +342,6 @@ void otSetReceiveIp6DatagramFilterEnabled(otInstance *aInstance, bool aEnabled);
|
||||
*/
|
||||
ThreadError otSendIp6Datagram(otInstance *aInstance, otMessage aMessage);
|
||||
|
||||
/**
|
||||
* This function indicates whether or not ICMPv6 Echo processing is enabled.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval TRUE ICMPv6 Echo processing is enabled.
|
||||
* @retval FALSE ICMPv6 Echo processing is disabled.
|
||||
*
|
||||
*/
|
||||
bool otIsIcmpEchoEnabled(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function sets whether or not ICMPv6 Echo processing is enabled.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aEnabled TRUE to enable ICMPv6 Echo processing, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
void otSetIcmpEchoEnabled(otInstance *aInstance, bool aEnabled);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
+95
-14
@@ -329,6 +329,21 @@ struct otIp6Address
|
||||
|
||||
typedef struct otIp6Address otIp6Address;
|
||||
|
||||
|
||||
/**
|
||||
* This structure represents the local and peer IPv6 socket addresses.
|
||||
*/
|
||||
typedef struct otMessageInfo
|
||||
{
|
||||
otIp6Address mSockAddr; ///< The local IPv6 address.
|
||||
otIp6Address mPeerAddr; ///< The peer IPv6 address.
|
||||
uint16_t mSockPort; ///< The local transport-layer port.
|
||||
uint16_t mPeerPort; ///< The peer transport-layer port.
|
||||
int8_t mInterfaceId; ///< An IPv6 interface identifier.
|
||||
uint8_t mHopLimit; ///< The IPv6 Hop Limit.
|
||||
const void *mLinkInfo; ///< A pointer to link-specific information.
|
||||
} otMessageInfo;
|
||||
|
||||
/**
|
||||
* @addtogroup commands Commands
|
||||
*
|
||||
@@ -982,6 +997,86 @@ typedef struct
|
||||
void *mData; ///< Opaque data used by the implementation.
|
||||
} otMessageQueue;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup icmp6 ICMPv6
|
||||
*
|
||||
* @brief
|
||||
* This module includes functions that control ICMPv6 communication.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* ICMPv6 Message Types
|
||||
*
|
||||
*/
|
||||
typedef enum otIcmp6Type
|
||||
{
|
||||
kIcmp6TypeDstUnreach = 1, ///< Destination Unreachable
|
||||
kIcmp6TypeEchoRequest = 128, ///< Echo Request
|
||||
kIcmp6TypeEchoReply = 129, ///< Echo Reply
|
||||
} otIcmp6Type;
|
||||
|
||||
/**
|
||||
* ICMPv6 Message Codes
|
||||
*
|
||||
*/
|
||||
typedef enum otIcmp6Code
|
||||
{
|
||||
kIcmp6CodeDstUnreachNoRoute = 0, ///< Destination Unreachable No Route
|
||||
} otIcmp6Code;
|
||||
|
||||
#define OT_ICMP6_HEADER_DATA_SIZE 4 ///< Size of an message specific data of ICMPv6 Header.
|
||||
|
||||
/**
|
||||
* This structure represents an ICMPv6 header.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct otIcmp6Header
|
||||
{
|
||||
uint8_t mType; ///< Type
|
||||
uint8_t mCode; ///< Code
|
||||
uint16_t mChecksum; ///< Checksum
|
||||
union
|
||||
{
|
||||
uint8_t m8[OT_ICMP6_HEADER_DATA_SIZE / sizeof(uint8_t)];
|
||||
uint16_t m16[OT_ICMP6_HEADER_DATA_SIZE / sizeof(uint16_t)];
|
||||
uint32_t m32[OT_ICMP6_HEADER_DATA_SIZE / sizeof(uint32_t)];
|
||||
} mData; ///< Message-specific data
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
typedef struct otIcmp6Header otIcmp6Header;
|
||||
|
||||
/**
|
||||
* This callback allows OpenThread to inform the application of a received ICMPv6 message.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aMessage A pointer to the received message.
|
||||
* @param[in] aMessageInfo A pointer to message information associated with @p aMessage.
|
||||
* @param[in] aIcmpHeader A pointer to the received ICMPv6 header.
|
||||
*
|
||||
*/
|
||||
typedef void (*otIcmp6ReceiveCallback)(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader);
|
||||
|
||||
/**
|
||||
* This structure implements ICMPv6 message handler.
|
||||
*
|
||||
*/
|
||||
typedef struct otIcmp6Handler
|
||||
{
|
||||
otIcmp6ReceiveCallback mReceiveCallback;
|
||||
void *mContext;
|
||||
struct otIcmp6Handler *mNext;
|
||||
} otIcmp6Handler;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
@@ -1007,20 +1102,6 @@ typedef struct otSockAddr
|
||||
int8_t mScopeId; ///< An IPv6 scope identifier.
|
||||
} otSockAddr;
|
||||
|
||||
/**
|
||||
* This structure represents the local and peer IPv6 socket addresses.
|
||||
*/
|
||||
typedef struct otMessageInfo
|
||||
{
|
||||
otIp6Address mSockAddr; ///< The local IPv6 address.
|
||||
otIp6Address mPeerAddr; ///< The peer IPv6 address.
|
||||
uint16_t mSockPort; ///< The local transport-layer port.
|
||||
uint16_t mPeerPort; ///< The peer transport-layer port.
|
||||
int8_t mInterfaceId; ///< An IPv6 interface identifier.
|
||||
uint8_t mHopLimit; ///< The IPv6 Hop Limit.
|
||||
const void *mLinkInfo; ///< A pointer to link-specific information.
|
||||
} otMessageInfo;
|
||||
|
||||
/**
|
||||
* This callback allows OpenThread to inform the application of a received UDP message.
|
||||
*/
|
||||
|
||||
+26
-14
@@ -44,6 +44,7 @@
|
||||
#include <openthread.h>
|
||||
#include <openthread-instance.h>
|
||||
#include <openthread-diag.h>
|
||||
#include <openthread-icmp6.h>
|
||||
#include <commissioning/commissioner.h>
|
||||
#include <commissioning/joiner.h>
|
||||
#include <dhcp6/dhcp6_server.h>
|
||||
@@ -144,10 +145,13 @@ Interpreter::Interpreter(otInstance *aInstance):
|
||||
mInstance(aInstance)
|
||||
{
|
||||
memset(mSlaacAddresses, 0, sizeof(mSlaacAddresses));
|
||||
mInstance->mIp6.mIcmp.SetEchoReplyHandler(&s_HandleEchoResponse, this);
|
||||
otSetStateChangedCallback(mInstance, &Interpreter::s_HandleNetifStateChanged, this);
|
||||
otSetReceiveDiagnosticGetCallback(mInstance, &Interpreter::s_HandleDiagnosticGetResponse, this);
|
||||
|
||||
mIcmpHandler.mReceiveCallback = Interpreter::s_HandleIcmpReceive;
|
||||
mIcmpHandler.mContext = this;
|
||||
otIcmp6RegisterHandler(mInstance, &mIcmpHandler);
|
||||
|
||||
#if OPENTHREAD_ENABLE_DHCP6_CLIENT
|
||||
memset(mDhcpAddresses, 0, sizeof(mDhcpAddresses));
|
||||
#endif // OPENTHREAD_ENABLE_DHCP6_CLIENT
|
||||
@@ -1270,17 +1274,20 @@ exit:
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
void Interpreter::s_HandleEchoResponse(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
void Interpreter::s_HandleIcmpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader)
|
||||
{
|
||||
static_cast<Interpreter *>(aContext)->HandleEchoResponse(aMessage, aMessageInfo);
|
||||
static_cast<Interpreter *>(aContext)->HandleIcmpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo),
|
||||
*static_cast<const Ip6::IcmpHeader *>(aIcmpHeader));
|
||||
}
|
||||
|
||||
void Interpreter::HandleEchoResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
void Interpreter::HandleIcmpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
|
||||
const Ip6::IcmpHeader &aIcmpHeader)
|
||||
{
|
||||
Ip6::IcmpHeader icmp6Header;
|
||||
uint32_t timestamp = 0;
|
||||
|
||||
aMessage.Read(aMessage.GetOffset(), sizeof(icmp6Header), &icmp6Header);
|
||||
VerifyOrExit(aIcmpHeader.GetType() == kIcmp6TypeEchoReply, ;);
|
||||
|
||||
sServer->OutputFormat("%d bytes from ", aMessage.GetLength() - aMessage.GetOffset());
|
||||
sServer->OutputFormat("%x:%x:%x:%x:%x:%x:%x:%x",
|
||||
@@ -1292,15 +1299,18 @@ void Interpreter::HandleEchoResponse(Message &aMessage, const Ip6::MessageInfo &
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[5]),
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[6]),
|
||||
HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[7]));
|
||||
sServer->OutputFormat(": icmp_seq=%d hlim=%d", icmp6Header.GetSequence(), aMessageInfo.mHopLimit);
|
||||
sServer->OutputFormat(": icmp_seq=%d hlim=%d", aIcmpHeader.GetSequence(), aMessageInfo.mHopLimit);
|
||||
|
||||
if (aMessage.Read(aMessage.GetOffset() + sizeof(icmp6Header), sizeof(uint32_t), ×tamp) >=
|
||||
if (aMessage.Read(aMessage.GetOffset(), sizeof(uint32_t), ×tamp) >=
|
||||
static_cast<int>(sizeof(uint32_t)))
|
||||
{
|
||||
sServer->OutputFormat(" time=%dms", Timer::GetNow() - HostSwap32(timestamp));
|
||||
}
|
||||
|
||||
sServer->OutputFormat("\r\n");
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Interpreter::ProcessPing(int argc, char *argv[])
|
||||
@@ -1363,20 +1373,22 @@ void Interpreter::HandlePingTimer()
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
uint32_t timestamp = HostSwap32(Timer::GetNow());
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = mInstance->mIp6.mIcmp.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(×tamp, sizeof(timestamp)));
|
||||
SuccessOrExit(error = message->SetLength(sLength));
|
||||
otMessage message;
|
||||
const otMessageInfo *messageInfo = static_cast<const otMessageInfo *>(&sMessageInfo);
|
||||
|
||||
VerifyOrExit((message = otNewIp6Message(mInstance, true)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = otAppendMessage(message, ×tamp, sizeof(timestamp)));
|
||||
SuccessOrExit(error = otSetMessageLength(message, sLength));
|
||||
SuccessOrExit(error = otIcmp6SendEchoRequest(mInstance, message, messageInfo, 1));
|
||||
|
||||
SuccessOrExit(error = mInstance->mIp6.mIcmp.SendEchoRequest(*message, sMessageInfo));
|
||||
sCount--;
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
otFreeMessage(message);
|
||||
}
|
||||
|
||||
if (sCount)
|
||||
|
||||
+6
-2
@@ -218,7 +218,8 @@ private:
|
||||
void ProcessVersion(int argc, char *argv[]);
|
||||
void ProcessWhitelist(int argc, char *argv[]);
|
||||
|
||||
static void s_HandleEchoResponse(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
static void s_HandleIcmpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader);
|
||||
static void s_HandlePingTimer(void *aContext);
|
||||
static void s_HandleActiveScanResult(otActiveScanResult *aResult, void *aContext);
|
||||
static void s_HandleNetifStateChanged(uint32_t aFlags, void *aContext);
|
||||
@@ -229,7 +230,8 @@ private:
|
||||
static void s_HandleDiagnosticGetResponse(otMessage aMessage, const otMessageInfo *aMessageInfo, void *aContext);
|
||||
static void s_HandleJoinerCallback(ThreadError aError, void *aContext);
|
||||
|
||||
void HandleEchoResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandleIcmpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
|
||||
const Ip6::IcmpHeader &aIcmpHeader);
|
||||
void HandlePingTimer();
|
||||
void HandleActiveScanResult(otActiveScanResult *aResult);
|
||||
void HandleNetifStateChanged(uint32_t aFlags);
|
||||
@@ -242,6 +244,7 @@ private:
|
||||
static const struct Command sCommands[];
|
||||
|
||||
Ip6::MessageInfo sMessageInfo;
|
||||
|
||||
Server *sServer;
|
||||
uint16_t sLength;
|
||||
uint16_t sCount;
|
||||
@@ -253,6 +256,7 @@ private:
|
||||
otDhcpAddress mDhcpAddresses[OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES];
|
||||
#endif // OPENTHREAD_ENABLE_DHCP6_CLIENT
|
||||
|
||||
otIcmp6Handler mIcmpHandler;
|
||||
otInstance *mInstance;
|
||||
};
|
||||
|
||||
|
||||
+15
-47
@@ -50,8 +50,6 @@ namespace Ip6 {
|
||||
Icmp::Icmp(Ip6 &aIp6):
|
||||
mHandlers(NULL),
|
||||
mEchoSequence(1),
|
||||
mEchoReplyHandler(NULL),
|
||||
mEchoReplyContext(NULL),
|
||||
mIsEchoEnabled(true),
|
||||
mIp6(aIp6)
|
||||
{
|
||||
@@ -62,11 +60,11 @@ Message *Icmp::NewMessage(uint16_t aReserved)
|
||||
return mIp6.NewMessage(sizeof(IcmpHeader) + aReserved);
|
||||
}
|
||||
|
||||
ThreadError Icmp::RegisterCallbacks(IcmpHandler &aHandler)
|
||||
ThreadError Icmp::RegisterHandler(IcmpHandler &aHandler)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
for (IcmpHandler *cur = mHandlers; cur; cur = cur->mNext)
|
||||
for (IcmpHandler *cur = mHandlers; cur; cur = cur->GetNext())
|
||||
{
|
||||
if (cur == &aHandler)
|
||||
{
|
||||
@@ -81,13 +79,8 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Icmp::SetEchoReplyHandler(EchoReplyHandler aHandler, void *aContext)
|
||||
{
|
||||
mEchoReplyHandler = aHandler;
|
||||
mEchoReplyContext = aContext;
|
||||
}
|
||||
|
||||
ThreadError Icmp::SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo)
|
||||
ThreadError Icmp::SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo,
|
||||
uint16_t aIdentifier)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
MessageInfo messageInfoLocal;
|
||||
@@ -96,8 +89,8 @@ ThreadError Icmp::SendEchoRequest(Message &aMessage, const MessageInfo &aMessage
|
||||
messageInfoLocal = aMessageInfo;
|
||||
|
||||
icmpHeader.Init();
|
||||
icmpHeader.SetType(IcmpHeader::kTypeEchoRequest);
|
||||
icmpHeader.SetId(1);
|
||||
icmpHeader.SetType(kIcmp6TypeEchoRequest);
|
||||
icmpHeader.SetId(aIdentifier);
|
||||
icmpHeader.SetSequence(mEchoSequence++);
|
||||
|
||||
SuccessOrExit(error = aMessage.Prepend(&icmpHeader, sizeof(icmpHeader)));
|
||||
@@ -160,35 +153,22 @@ ThreadError Icmp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo)
|
||||
checksum = aMessage.UpdateChecksum(checksum, aMessage.GetOffset(), payloadLength);
|
||||
VerifyOrExit(checksum == 0xffff, ;);
|
||||
|
||||
switch (icmp6Header.GetType())
|
||||
if (mIsEchoEnabled && (icmp6Header.GetType() == kIcmp6TypeEchoRequest))
|
||||
{
|
||||
case IcmpHeader::kTypeEchoRequest:
|
||||
return HandleEchoRequest(aMessage, aMessageInfo);
|
||||
HandleEchoRequest(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
case IcmpHeader::kTypeEchoReply:
|
||||
return HandleEchoReply(aMessage, aMessageInfo);
|
||||
aMessage.MoveOffset(sizeof(icmp6Header));
|
||||
|
||||
case IcmpHeader::kTypeDstUnreach:
|
||||
return HandleDstUnreach(aMessage, aMessageInfo, icmp6Header);
|
||||
for (IcmpHandler *handler = mHandlers; handler; handler = handler->GetNext())
|
||||
{
|
||||
handler->HandleReceiveMessage(aMessage, aMessageInfo, icmp6Header);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Icmp::HandleDstUnreach(Message &aMessage, const MessageInfo &aMessageInfo,
|
||||
const IcmpHeader &aIcmpheader)
|
||||
{
|
||||
aMessage.MoveOffset(sizeof(aIcmpheader));
|
||||
|
||||
for (IcmpHandler *handler = mHandlers; handler; handler = handler->mNext)
|
||||
{
|
||||
handler->HandleDstUnreach(aMessage, aMessageInfo, aIcmpheader);
|
||||
}
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
@@ -197,16 +177,14 @@ ThreadError Icmp::HandleEchoRequest(Message &aRequestMessage, const MessageInfo
|
||||
MessageInfo replyMessageInfo;
|
||||
uint16_t payloadLength;
|
||||
|
||||
VerifyOrExit(mIsEchoEnabled, ;);
|
||||
|
||||
otLogInfoIcmp("Received Echo Request");
|
||||
|
||||
icmp6Header.Init();
|
||||
icmp6Header.SetType(IcmpHeader::kTypeEchoReply);
|
||||
icmp6Header.SetType(kIcmp6TypeEchoReply);
|
||||
|
||||
if ((replyMessage = mIp6.NewMessage(0)) == NULL)
|
||||
{
|
||||
otLogDebgIcmp("icmp fail");
|
||||
otLogDebgIcmp("Failed to allocate a new message");
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
@@ -241,16 +219,6 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Icmp::HandleEchoReply(Message &aMessage, const MessageInfo &aMessageInfo)
|
||||
{
|
||||
VerifyOrExit(mIsEchoEnabled && mEchoReplyHandler, ;);
|
||||
|
||||
mEchoReplyHandler(mEchoReplyContext, aMessage, aMessageInfo);
|
||||
|
||||
exit:
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError Icmp::UpdateChecksum(Message &aMessage, uint16_t aChecksum)
|
||||
{
|
||||
aChecksum = aMessage.UpdateChecksum(aChecksum, aMessage.GetOffset(),
|
||||
|
||||
+28
-94
@@ -34,6 +34,7 @@
|
||||
#ifndef ICMP6_HPP_
|
||||
#define ICMP6_HPP_
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <common/encoding.hpp>
|
||||
#include <net/ip6_headers.hpp>
|
||||
|
||||
@@ -52,35 +53,12 @@ namespace Ip6 {
|
||||
*
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
kIcmp6DataSize = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* This structure represents an ICMPv6 header.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct IcmpHeaderPoD
|
||||
{
|
||||
uint8_t mType; ///< Type
|
||||
uint8_t mCode; ///< Code
|
||||
uint16_t mChecksum; ///< Checksum
|
||||
union
|
||||
{
|
||||
uint8_t m8[kIcmp6DataSize / sizeof(uint8_t)];
|
||||
uint16_t m16[kIcmp6DataSize / sizeof(uint16_t)];
|
||||
uint32_t m32[kIcmp6DataSize / sizeof(uint32_t)];
|
||||
} mData; ///< Message-specific data
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
/*
|
||||
* This class implements ICMPv6 header generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class IcmpHeader: private IcmpHeaderPoD
|
||||
class IcmpHeader: public otIcmp6Header
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -93,12 +71,13 @@ public:
|
||||
* ICMPv6 Message Types
|
||||
*
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
kTypeDstUnreach = 1, ///< Destination Unreachable
|
||||
kTypeEchoRequest = 128, ///< Echo Request
|
||||
kTypeEchoReply = 129, ///< Echo Reply
|
||||
};
|
||||
typedef otIcmp6Type Type;
|
||||
|
||||
/**
|
||||
* ICMPv6 Message Codes
|
||||
*
|
||||
*/
|
||||
typedef otIcmp6Code Code;
|
||||
|
||||
/**
|
||||
* This method returns the ICMPv6 message type.
|
||||
@@ -116,15 +95,6 @@ public:
|
||||
*/
|
||||
void SetType(Type aType) { mType = static_cast<uint8_t>(aType); }
|
||||
|
||||
/**
|
||||
* ICMPv6 Message Codes
|
||||
*
|
||||
*/
|
||||
enum Code
|
||||
{
|
||||
kCodeDstUnreachNoRoute = 0, ///< Destination Unreachable No Route
|
||||
};
|
||||
|
||||
/**
|
||||
* This method returns the ICMPv6 message code.
|
||||
*
|
||||
@@ -194,7 +164,7 @@ public:
|
||||
* @returns The byte offset of the Checksum field.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetChecksumOffset(void) { return offsetof(IcmpHeaderPoD, mChecksum); }
|
||||
static uint8_t GetChecksumOffset(void) { return offsetof(otIcmp6Header, mChecksum); }
|
||||
|
||||
/**
|
||||
* This static method returns the byte offset of the ICMPv6 payload.
|
||||
@@ -202,7 +172,7 @@ public:
|
||||
* @returns The Byte offset of the ICMPv6 payload.
|
||||
*
|
||||
*/
|
||||
static uint8_t GetDataOffset(void) { return offsetof(IcmpHeaderPoD, mData); }
|
||||
static uint8_t GetDataOffset(void) { return offsetof(otIcmp6Header, mData); }
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
@@ -210,45 +180,30 @@ public:
|
||||
* This class implements ICMPv6 message handlers.
|
||||
*
|
||||
*/
|
||||
class IcmpHandler
|
||||
class IcmpHandler : public otIcmp6Handler
|
||||
{
|
||||
friend class Icmp;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This function pointer is called when receiving an ICMPv6 Destination Unreachable message.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aMessage A reference to the received message.
|
||||
* @param[in] aMessageInfo A reference to message information associated with @p aMessage.
|
||||
* @param[in] aIcmpHeader A reference to the received ICMPv6 header.
|
||||
*
|
||||
*/
|
||||
typedef void (*DstUnreachHandler)(void *aContext, Message &aMesage, const MessageInfo &aMessageInfo,
|
||||
const IcmpHeader &aIcmpHeader);
|
||||
|
||||
/**
|
||||
* This constructor creates an ICMPv6 message handler.
|
||||
*
|
||||
* @param[in] aDstUnreachHandler A pointer to the function that is called when receiving a Destination
|
||||
* Unreachable message.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aCallback A pointer to the function that is called when receiving an ICMPv6 message.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
IcmpHandler(DstUnreachHandler aDstUnreachHandler, void *aContext) {
|
||||
mDstUnreachHandler = aDstUnreachHandler;
|
||||
mContext = aContext;
|
||||
mNext = NULL;
|
||||
IcmpHandler(otIcmp6ReceiveCallback aCallback, void *aContext) {
|
||||
mReceiveCallback = aCallback;
|
||||
mContext = aContext;
|
||||
mNext = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
void HandleDstUnreach(Message &message, const MessageInfo &messageInfo, const IcmpHeader &icmp6Header) {
|
||||
mDstUnreachHandler(mContext, message, messageInfo, icmp6Header);
|
||||
void HandleReceiveMessage(Message &message, const MessageInfo &messageInfo, const IcmpHeader &icmp6Header) {
|
||||
mReceiveCallback(mContext, &message, &messageInfo, &icmp6Header);
|
||||
}
|
||||
|
||||
DstUnreachHandler mDstUnreachHandler;
|
||||
void *mContext;
|
||||
IcmpHandler *mNext;
|
||||
IcmpHandler *GetNext(void) { return static_cast<IcmpHandler *>(mNext); }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -277,46 +232,29 @@ public:
|
||||
Message *NewMessage(uint16_t aReserved);
|
||||
|
||||
/**
|
||||
* This method registers ICMPv6 handlers.
|
||||
* This method registers ICMPv6 handler.
|
||||
*
|
||||
* @param[in] aHandler A reference to the ICMPv6 handler.
|
||||
*
|
||||
* @retval kThreadError_None Successfully registered the ICMPv6 handler.
|
||||
* @retval kThreadError_None Successfully registered the ICMPv6 handler.
|
||||
* @retval kThreadError_Already The ICMPv6 handler is already registered.
|
||||
*
|
||||
*/
|
||||
ThreadError RegisterCallbacks(IcmpHandler &aHandler);
|
||||
|
||||
/**
|
||||
* This function pointer is called when receiving an ICMPv6 Echo Reply in response to an Echo Request.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aMessage A reference to the received message.
|
||||
* @param[in] aMessageInfo A reference to message information associated with @p aMessage.
|
||||
*
|
||||
*/
|
||||
typedef void (*EchoReplyHandler)(void *aContext, Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
void SetEchoReplyHandler(EchoReplyHandler aHandler, void *aContext);
|
||||
ThreadError RegisterHandler(IcmpHandler &aHandler);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param[in] aIdentifier An identifier to aid in matching Echo Replies to this Echo Request.
|
||||
* May be zero.
|
||||
*
|
||||
* @retval kThreadError_None Successfully enqueued the ICMPv6 Echo Request message.
|
||||
* @retval kThreadError_NoBufs Insufficient buffers available to generate an ICMPv6 Echo Request message.
|
||||
*
|
||||
*/
|
||||
ThreadError SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
ThreadError SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo, uint16_t aIdentifier);
|
||||
|
||||
/**
|
||||
* This method sends an ICMPv6 error message.
|
||||
@@ -376,15 +314,11 @@ public:
|
||||
void SetEchoEnabled(bool aEnabled);
|
||||
|
||||
private:
|
||||
ThreadError HandleDstUnreach(Message &aMessage, const MessageInfo &aMessageInfo, const IcmpHeader &aIcmpHeader);
|
||||
ThreadError HandleEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
ThreadError HandleEchoReply(Message &aMessage, const MessageInfo &aMessageInfo);
|
||||
|
||||
IcmpHandler *mHandlers;
|
||||
|
||||
uint16_t mEchoSequence;
|
||||
EchoReplyHandler mEchoReplyHandler;
|
||||
void *mEchoReplyContext;
|
||||
bool mIsEchoEnabled;
|
||||
|
||||
Ip6 &mIp6;
|
||||
|
||||
@@ -617,7 +617,7 @@ ThreadError Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageIn
|
||||
aMessage.Read(aMessage.GetOffset(), sizeof(icmp), &icmp);
|
||||
|
||||
// do not pass ICMP Echo Request messages
|
||||
VerifyOrExit(icmp.GetType() != IcmpHeader::kTypeEchoRequest, error = kThreadError_NoRoute);
|
||||
VerifyOrExit(icmp.GetType() != kIcmp6TypeEchoRequest, error = kThreadError_NoRoute);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
+15
-2
@@ -1752,16 +1752,29 @@ ThreadError otSendUdp(otUdpSocket *aSocket, otMessage aMessage, const otMessageI
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
bool otIsIcmpEchoEnabled(otInstance *aInstance)
|
||||
bool otIcmp6IsEchoEnabled(otInstance *aInstance)
|
||||
{
|
||||
return aInstance->mIp6.mIcmp.IsEchoEnabled();
|
||||
}
|
||||
|
||||
void otSetIcmpEchoEnabled(otInstance *aInstance, bool aEnabled)
|
||||
void otIcmp6SetEchoEnabled(otInstance *aInstance, bool aEnabled)
|
||||
{
|
||||
aInstance->mIp6.mIcmp.SetEchoEnabled(aEnabled);
|
||||
}
|
||||
|
||||
ThreadError otIcmp6RegisterHandler(otInstance *aInstance, otIcmp6Handler *aHandler)
|
||||
{
|
||||
return aInstance->mIp6.mIcmp.RegisterHandler(*static_cast<Ip6::IcmpHandler *>(aHandler));
|
||||
}
|
||||
|
||||
ThreadError otIcmp6SendEchoRequest(otInstance *aInstance, otMessage aMessage,
|
||||
const otMessageInfo *aMessageInfo, uint16_t aIdentifier)
|
||||
{
|
||||
return aInstance->mIp6.mIcmp.SendEchoRequest(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo),
|
||||
aIdentifier);
|
||||
}
|
||||
|
||||
uint8_t otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond)
|
||||
{
|
||||
uint8_t rval;
|
||||
|
||||
@@ -55,7 +55,7 @@ AddressResolver::AddressResolver(ThreadNetif &aThreadNetif) :
|
||||
mAddressError(OPENTHREAD_URI_ADDRESS_ERROR, &AddressResolver::HandleAddressError, this),
|
||||
mAddressQuery(OPENTHREAD_URI_ADDRESS_QUERY, &AddressResolver::HandleAddressQuery, this),
|
||||
mAddressNotification(OPENTHREAD_URI_ADDRESS_NOTIFY, &AddressResolver::HandleAddressNotification, this),
|
||||
mIcmpHandler(&AddressResolver::HandleDstUnreach, this),
|
||||
mIcmpHandler(&AddressResolver::HandleIcmpReceive, this),
|
||||
mTimer(aThreadNetif.GetIp6().mTimerScheduler, &AddressResolver::HandleTimer, this),
|
||||
mNetif(aThreadNetif)
|
||||
{
|
||||
@@ -65,7 +65,7 @@ AddressResolver::AddressResolver(ThreadNetif &aThreadNetif) :
|
||||
mNetif.GetCoapServer().AddResource(mAddressQuery);
|
||||
mNetif.GetCoapServer().AddResource(mAddressNotification);
|
||||
|
||||
mNetif.GetIp6().mIcmp.RegisterCallbacks(mIcmpHandler);
|
||||
mNetif.GetIp6().mIcmp.RegisterHandler(mIcmpHandler);
|
||||
}
|
||||
|
||||
void AddressResolver::Clear()
|
||||
@@ -645,20 +645,23 @@ void AddressResolver::HandleTimer()
|
||||
}
|
||||
}
|
||||
|
||||
void AddressResolver::HandleDstUnreach(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
|
||||
const Ip6::IcmpHeader &aIcmpHeader)
|
||||
void AddressResolver::HandleIcmpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader)
|
||||
{
|
||||
static_cast<AddressResolver *>(aContext)->HandleDstUnreach(aMessage, aMessageInfo, aIcmpHeader);
|
||||
static_cast<AddressResolver *>(aContext)->HandleIcmpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo),
|
||||
*static_cast<const Ip6::IcmpHeader *>(aIcmpHeader));
|
||||
|
||||
(void)aMessageInfo;
|
||||
}
|
||||
|
||||
void AddressResolver::HandleDstUnreach(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
|
||||
const Ip6::IcmpHeader &aIcmpHeader)
|
||||
void AddressResolver::HandleIcmpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
|
||||
const Ip6::IcmpHeader &aIcmpHeader)
|
||||
{
|
||||
Ip6::Header ip6Header;
|
||||
|
||||
VerifyOrExit(aIcmpHeader.GetCode() == Ip6::IcmpHeader::kCodeDstUnreachNoRoute, ;);
|
||||
VerifyOrExit(aIcmpHeader.GetType() == kIcmp6TypeDstUnreach, ;);
|
||||
VerifyOrExit(aIcmpHeader.GetCode() == kIcmp6CodeDstUnreachNoRoute, ;);
|
||||
VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(ip6Header), &ip6Header) == sizeof(ip6Header), ;);
|
||||
|
||||
for (int i = 0; i < kCacheEntries; i++)
|
||||
|
||||
@@ -174,9 +174,9 @@ private:
|
||||
const otMessageInfo *aMessageInfo);
|
||||
void HandleAddressNotification(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void HandleDstUnreach(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
|
||||
const Ip6::IcmpHeader &aIcmpHeader);
|
||||
void HandleDstUnreach(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Ip6::IcmpHeader &aIcmpHeader);
|
||||
static void HandleIcmpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo,
|
||||
const otIcmp6Header *aIcmpHeader);
|
||||
void HandleIcmpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Ip6::IcmpHeader &aIcmpHeader);
|
||||
|
||||
static void HandleTimer(void *aContext);
|
||||
void HandleTimer(void);
|
||||
|
||||
@@ -3203,8 +3203,8 @@ ThreadError Mle::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDest, Ip6
|
||||
messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aMeshSource);
|
||||
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
|
||||
|
||||
mNetif.GetIp6().mIcmp.SendError(Ip6::IcmpHeader::kTypeDstUnreach,
|
||||
Ip6::IcmpHeader::kCodeDstUnreachNoRoute,
|
||||
mNetif.GetIp6().mIcmp.SendError(kIcmp6TypeDstUnreach,
|
||||
kIcmp6CodeDstUnreachNoRoute,
|
||||
messageInfo, aIp6Header);
|
||||
|
||||
exit:
|
||||
|
||||
@@ -3632,8 +3632,8 @@ ThreadError MleRouter::CheckReachability(uint16_t aMeshSource, uint16_t aMeshDes
|
||||
messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aMeshSource);
|
||||
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
|
||||
|
||||
mNetif.GetIp6().mIcmp.SendError(Ip6::IcmpHeader::kTypeDstUnreach,
|
||||
Ip6::IcmpHeader::kCodeDstUnreachNoRoute,
|
||||
mNetif.GetIp6().mIcmp.SendError(kIcmp6TypeDstUnreach,
|
||||
kIcmp6CodeDstUnreachNoRoute,
|
||||
messageInfo, aIp6Header);
|
||||
|
||||
return kThreadError_Drop;
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <net/ip6.hpp>
|
||||
#include <openthread.h>
|
||||
#include <openthread-diag.h>
|
||||
#include <openthread-icmp6.h>
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
#include <openthread-jam-detection.h>
|
||||
#endif
|
||||
@@ -515,7 +516,7 @@ NcpBase::NcpBase(otInstance *aInstance):
|
||||
otSetStateChangedCallback(mInstance, &NcpBase::HandleNetifStateChanged, this);
|
||||
otSetReceiveIp6DatagramCallback(mInstance, &NcpBase::HandleDatagramFromStack, this);
|
||||
otSetLinkPcapCallback(mInstance, &NcpBase::HandleRawFrame, static_cast<void*>(this));
|
||||
otSetIcmpEchoEnabled(mInstance, false);
|
||||
otIcmp6SetEchoEnabled(mInstance, false);
|
||||
otSetReceiveIp6DatagramFilterEnabled(mInstance, true);
|
||||
|
||||
mUpdateChangedPropsTask.Post();
|
||||
@@ -2711,7 +2712,7 @@ ThreadError NcpBase::GetPropertyHandler_IPV6_ICMP_PING_OFFLOAD(uint8_t header, s
|
||||
SPINEL_CMD_PROP_VALUE_IS,
|
||||
key,
|
||||
SPINEL_DATATYPE_BOOL_S,
|
||||
otIsIcmpEchoEnabled(mInstance)
|
||||
otIcmp6IsEchoEnabled(mInstance)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4379,7 +4380,7 @@ ThreadError NcpBase::SetPropertyHandler_IPV6_ICMP_PING_OFFLOAD(uint8_t header, s
|
||||
|
||||
if (parsedLength > 0)
|
||||
{
|
||||
otSetIcmpEchoEnabled(mInstance, isEnabled);
|
||||
otIcmp6SetEchoEnabled(mInstance, isEnabled);
|
||||
|
||||
errorCode = HandleCommandPropertyGet(header, key);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user