DIAG: Add support for DIAG_GET.qry message. (#1099)

This commit is contained in:
Łukasz Duda
2017-01-04 06:05:59 -08:00
committed by Jonathan Hui
parent 566f0993c3
commit 85ee5e6493
4 changed files with 435 additions and 282 deletions
+8 -7
View File
@@ -1908,9 +1908,10 @@ OTAPI ThreadError OTCALL otGetParentInfo(otInstance *aInstance, otRouterInfo *aP
OTAPI uint8_t OTCALL otGetStableNetworkDataVersion(otInstance *aInstance);
/**
* This function pointer is called when an DIAG_GET.rsp is received.
* This function pointer is called when Network Diagnostic Get response is received.
*
* @param[in] aMessage A pointer to the message buffer containing the received DIAG_GET.rsp payload.
* @param[in] aMessage A pointer to the message buffer containing the received Network Diagnostic
* Get response payload.
* @param[in] aMessageInfo A pointer to the message info for @p aMessage.
* @param[in] aContext A pointer to application-specific context.
*
@@ -1919,11 +1920,11 @@ typedef void (*otReceiveDiagnosticGetCallback)(otMessage aMessage, const otMessa
void *aContext);
/**
* This function registers a callback to provide received raw DIAG_GET.rsp payload.
* This function registers a callback to provide received raw Network Diagnostic Get response payload.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aCallback A pointer to a function that is called when an DIAG_GET.rsp is received or
* NULL to disable the callback.
* @param[in] aCallback A pointer to a function that is called when Network Diagnostic Get response
* is received or NULL to disable the callback.
* @param[in] aCallbackContext A pointer to application-specific context.
*
*/
@@ -1931,7 +1932,7 @@ void otSetReceiveDiagnosticGetCallback(otInstance *aInstance, otReceiveDiagnosti
void *aCallbackContext);
/**
* Send a Network Diagnostic Get request
* Send a Network Diagnostic Get request.
*
* @param[in] aDestination A pointer to destination address.
* @param[in] aTlvTypes An array of Network Diagnostic TLV types.
@@ -1941,7 +1942,7 @@ OTAPI ThreadError OTCALL otSendDiagnosticGet(otInstance *aInstance, const otIp6A
const uint8_t aTlvTypes[], uint8_t aCount);
/**
* Send a Network Diagnostic Reset request
* Send a Network Diagnostic Reset request.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aDestination A pointer to destination address.
+354 -218
View File
@@ -56,7 +56,9 @@ namespace Thread {
namespace NetworkDiagnostic {
NetworkDiagnostic::NetworkDiagnostic(ThreadNetif &aThreadNetif) :
mDiagnosticGet(OPENTHREAD_URI_DIAGNOSTIC_GET, &NetworkDiagnostic::HandleDiagnosticGet, this),
mDiagnosticGetRequest(OPENTHREAD_URI_DIAGNOSTIC_GET_REQUEST, &NetworkDiagnostic::HandleDiagnosticGetRequest, this),
mDiagnosticGetQuery(OPENTHREAD_URI_DIAGNOSTIC_GET_QUERY, &NetworkDiagnostic::HandleDiagnosticGetQuery, this),
mDiagnosticGetAnswer(OPENTHREAD_URI_DIAGNOSTIC_GET_ANSWER, &NetworkDiagnostic::HandleDiagnosticGetAnswer, this),
mDiagnosticReset(OPENTHREAD_URI_DIAGNOSTIC_RESET, &NetworkDiagnostic::HandleDiagnosticReset, this),
mCoapServer(aThreadNetif.GetCoapServer()),
mCoapClient(aThreadNetif.GetCoapClient()),
@@ -66,7 +68,9 @@ NetworkDiagnostic::NetworkDiagnostic(ThreadNetif &aThreadNetif) :
mReceiveDiagnosticGetCallback(NULL),
mReceiveDiagnosticGetCallbackContext(NULL)
{
mCoapServer.AddResource(mDiagnosticGet);
mCoapServer.AddResource(mDiagnosticGetRequest);
mCoapServer.AddResource(mDiagnosticGetQuery);
mCoapServer.AddResource(mDiagnosticGetAnswer);
mCoapServer.AddResource(mDiagnosticReset);
}
@@ -77,20 +81,54 @@ void NetworkDiagnostic::SetReceiveDiagnosticGetCallback(otReceiveDiagnosticGetCa
mReceiveDiagnosticGetCallbackContext = aCallbackContext;
}
ThreadError NetworkDiagnostic::SendEmptyAck(Coap::Header &aHeader, const Ip6::MessageInfo &aMessageInfo)
{
ThreadError error = kThreadError_None;
Message *message = NULL;
Coap::Header header;
Ip6::MessageInfo messageInfo(aMessageInfo);
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
header.SetDefaultResponseHeader(aHeader);
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
SuccessOrExit(error = mCoapServer.SendMessage(*message, messageInfo));
exit:
if (error != kThreadError_None && message != NULL)
{
message->Free();
}
return error;
}
ThreadError NetworkDiagnostic::SendDiagnosticGet(const Ip6::Address &aDestination, const uint8_t aTlvTypes[],
uint8_t aCount)
{
ThreadError error;
Ip6::SockAddr sockaddr;
Message *message;
Coap::Header header;
Ip6::MessageInfo messageInfo;
otCoapResponseHandler handler = NULL;
sockaddr.mPort = kCoapUdpPort;
if (aDestination.IsMulticast())
{
header.Init(kCoapTypeNonConfirmable, kCoapRequestGet);
header.SetToken(Coap::Header::kDefaultTokenLength);
header.AppendUriPathOptions(OPENTHREAD_URI_DIAGNOSTIC_GET_QUERY);
}
else
{
handler = &NetworkDiagnostic::HandleDiagnosticGetResponse;
header.Init(kCoapTypeConfirmable, kCoapRequestGet);
header.SetToken(Coap::Header::kDefaultTokenLength);
header.AppendUriPathOptions(OPENTHREAD_URI_DIAGNOSTIC_GET_REQUEST);
}
header.Init(kCoapTypeConfirmable, kCoapRequestGet);
header.SetToken(Coap::Header::kDefaultTokenLength);
header.AppendUriPathOptions(OPENTHREAD_URI_DIAGNOSTIC_GET);
header.SetPayloadMarker();
VerifyOrExit((message = mCoapClient.NewMessage(header)) != NULL, error = kThreadError_NoBufs);
@@ -102,8 +140,7 @@ ThreadError NetworkDiagnostic::SendDiagnosticGet(const Ip6::Address &aDestinatio
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
SuccessOrExit(error = mCoapClient.SendMessage(*message, messageInfo,
&NetworkDiagnostic::HandleDiagnosticGetResponse, this));
SuccessOrExit(error = mCoapClient.SendMessage(*message, messageInfo, handler, this));
otLogInfoNetDiag("Sent diagnostic get");
@@ -120,72 +157,59 @@ exit:
void NetworkDiagnostic::HandleDiagnosticGetResponse(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo, ThreadError aResult)
{
static_cast<NetworkDiagnostic *>(aContext)->HandleDiagnosticGetResponse(static_cast<Coap::Header *>(aHeader),
static_cast<Message *>(aMessage),
static_cast<const Ip6::MessageInfo *>(aMessageInfo),
static_cast<NetworkDiagnostic *>(aContext)->HandleDiagnosticGetResponse(*static_cast<Coap::Header *>(aHeader),
*static_cast<Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo),
aResult);
}
void NetworkDiagnostic::HandleDiagnosticGetResponse(Coap::Header *aHeader, Message *aMessage,
const Ip6::MessageInfo *aMessageInfo, ThreadError aResult)
void NetworkDiagnostic::HandleDiagnosticGetResponse(Coap::Header &aHeader, Message &aMessage,
const Ip6::MessageInfo &aMessageInfo,
ThreadError aResult)
{
VerifyOrExit(aResult == kThreadError_None, ;);
VerifyOrExit(aHeader->GetCode() == kCoapResponseChanged, ;);
VerifyOrExit(aHeader.GetCode() == kCoapResponseChanged, ;);
otLogInfoNetDiag("Network Diagnostic get response received");
otLogInfoNetDiag("Received diagnostic get response");
VerifyOrExit(mReceiveDiagnosticGetCallback != NULL, ;);
// Call application defined callback.
mReceiveDiagnosticGetCallback(aMessage, aMessageInfo, mReceiveDiagnosticGetCallbackContext);
if (mReceiveDiagnosticGetCallback)
{
mReceiveDiagnosticGetCallback(&aMessage, &aMessageInfo, mReceiveDiagnosticGetCallbackContext);
}
exit:
return;
}
ThreadError NetworkDiagnostic::SendDiagnosticReset(const Ip6::Address &aDestination, const uint8_t aTlvTypes[],
uint8_t aCount)
void NetworkDiagnostic::HandleDiagnosticGetAnswer(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo)
{
ThreadError error;
Ip6::SockAddr sockaddr;
Message *message;
Coap::Header header;
Ip6::MessageInfo messageInfo;
header.Init(kCoapTypeConfirmable, kCoapRequestPost);
header.SetToken(Coap::Header::kDefaultTokenLength);
header.AppendUriPathOptions(OPENTHREAD_URI_DIAGNOSTIC_RESET);
header.SetPayloadMarker();
VerifyOrExit((message = mCoapClient.NewMessage(header)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = message->Append(aTlvTypes, aCount));
messageInfo.SetPeerAddr(aDestination);
messageInfo.SetSockAddr(mMle.GetMeshLocal16());
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
SuccessOrExit(error = mCoapClient.SendMessage(*message, messageInfo));
otLogInfoNetDiag("Sent network diagnostic reset");
exit:
if (error != kThreadError_None && message != NULL)
{
message->Free();
}
return error;
static_cast<NetworkDiagnostic *>(aContext)->HandleDiagnosticGetAnswer(*static_cast<Coap::Header *>(aHeader),
*static_cast<Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
}
void NetworkDiagnostic::HandleDiagnosticGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo)
void NetworkDiagnostic::HandleDiagnosticGetAnswer(Coap::Header &aHeader, Message &aMessage,
const Ip6::MessageInfo &aMessageInfo)
{
static_cast<NetworkDiagnostic *>(aContext)->HandleDiagnosticGet(
*static_cast<Coap::Header *>(aHeader), *static_cast<Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
ThreadError error = kThreadError_None;
VerifyOrExit(aHeader.GetType() == kCoapTypeConfirmable &&
aHeader.GetCode() == kCoapRequestPost, ;);
otLogInfoNetDiag("Diagnostic get answer received");
if (mReceiveDiagnosticGetCallback)
{
mReceiveDiagnosticGetCallback(&aMessage, &aMessageInfo, mReceiveDiagnosticGetCallbackContext);
}
SuccessOrExit(error = SendEmptyAck(aHeader, aMessageInfo));
otLogInfoNetDiag("Sent diagnostic answer acknowledgment");
exit:
return;
}
ThreadError NetworkDiagnostic::AppendIPv6AddressList(Message &aMessage)
@@ -260,13 +284,241 @@ exit:
return error;
}
void NetworkDiagnostic::HandleDiagnosticGet(Coap::Header &aHeader, Message &aMessage,
const Ip6::MessageInfo &aMessageInfo)
ThreadError NetworkDiagnostic::FillRequestedTlvs(Message &aRequest, Message &aResponse,
NetworkDiagnosticTlv &aNetworkDiagnosticTlv)
{
ThreadError error = kThreadError_None;
uint16_t offset = 0;
uint8_t type;
offset = aRequest.GetOffset() + sizeof(NetworkDiagnosticTlv);
for (uint32_t i = 0; i < aNetworkDiagnosticTlv.GetLength(); i++)
{
VerifyOrExit(aRequest.Read(offset, sizeof(type), &type) == sizeof(type), error = kThreadError_Drop);
otLogInfoNetDiag("Received diagnostic get type %d", type);
switch (type)
{
case NetworkDiagnosticTlv::kExtMacAddress:
{
ExtMacAddressTlv tlv;
tlv.Init();
tlv.SetMacAddr(*mNetif.GetMac().GetExtAddress());
SuccessOrExit(error = aResponse.Append(&tlv, sizeof(tlv)));
break;
}
case NetworkDiagnosticTlv::kAddress16:
{
Address16Tlv tlv;
tlv.Init();
tlv.SetRloc16(mMle.GetRloc16());
SuccessOrExit(error = aResponse.Append(&tlv, sizeof(tlv)));
break;
}
case NetworkDiagnosticTlv::kMode:
{
ModeTlv tlv;
tlv.Init();
tlv.SetMode(mMle.GetDeviceMode());
SuccessOrExit(error = aResponse.Append(&tlv, sizeof(tlv)));
break;
}
case NetworkDiagnosticTlv::kTimeout:
{
if ((mMle.GetDeviceMode() & ModeTlv::kModeRxOnWhenIdle) == 0)
{
TimeoutTlv tlv;
tlv.Init();
tlv.SetTimeout(mMle.GetTimeout());
SuccessOrExit(error = aResponse.Append(&tlv, sizeof(tlv)));
}
break;
}
case NetworkDiagnosticTlv::kConnectivity:
{
ConnectivityTlv tlv;
tlv.Init();
mMle.FillConnectivityTlv(*reinterpret_cast<Mle::ConnectivityTlv *>(&tlv));
SuccessOrExit(error = aResponse.Append(&tlv, sizeof(tlv)));
break;
}
case NetworkDiagnosticTlv::kRoute:
{
RouteTlv tlv;
tlv.Init();
mMle.FillRouteTlv(*reinterpret_cast<Mle::RouteTlv *>(&tlv));
SuccessOrExit(error = aResponse.Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kLeaderData:
{
LeaderDataTlv tlv;
memcpy(&tlv, &mMle.GetLeaderDataTlv(), sizeof(tlv));
tlv.Init();
SuccessOrExit(error = aResponse.Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kNetworkData:
{
NetworkDataTlv tlv;
tlv.Init();
mMle.FillNetworkDataTlv((*reinterpret_cast<Mle::NetworkDataTlv *>(&tlv)), true);
SuccessOrExit(error = aResponse.Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kIPv6AddressList:
{
SuccessOrExit(error = AppendIPv6AddressList(aResponse));
break;
}
case NetworkDiagnosticTlv::kMacCounters:
{
MacCountersTlv tlv;
memset(&tlv, 0, sizeof(tlv));
tlv.Init();
mMac.FillMacCountersTlv(tlv);
SuccessOrExit(error = aResponse.Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kBatteryLevel:
{
// TODO Need more api from driver
BatteryLevelTlv tlv;
tlv.Init();
tlv.SetBatteryLevel(100);
SuccessOrExit(error = aResponse.Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kSupplyVoltage:
{
// TODO Need more api from driver
SupplyVoltageTlv tlv;
tlv.Init();
tlv.SetSupplyVoltage(0);
SuccessOrExit(error = aResponse.Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kChildTable:
{
SuccessOrExit(error = AppendChildTable(aResponse));
break;
}
case NetworkDiagnosticTlv::kChannelPages:
{
ChannelPagesTlv tlv;
tlv.Init();
tlv.GetChannelPages()[0] = 0;
tlv.SetLength(1);
SuccessOrExit(error = aResponse.Append(&tlv, tlv.GetSize()));
break;
}
default:
ExitNow(error = kThreadError_Drop);
}
offset += sizeof(type);
}
exit:
return error;
}
void NetworkDiagnostic::HandleDiagnosticGetQuery(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo)
{
static_cast<NetworkDiagnostic *>(aContext)->HandleDiagnosticGetQuery(
*static_cast<Coap::Header *>(aHeader), *static_cast<Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
}
void NetworkDiagnostic::HandleDiagnosticGetQuery(Coap::Header &aHeader, Message &aMessage,
const Ip6::MessageInfo &aMessageInfo)
{
ThreadError error = kThreadError_None;
Message *message = NULL;
NetworkDiagnosticTlv networkDiagnosticTlv;
Coap::Header header;
Ip6::MessageInfo messageInfo;
VerifyOrExit(aHeader.GetCode() == kCoapRequestGet, error = kThreadError_Drop);
otLogInfoNetDiag("Received diagnostic get query");
VerifyOrExit((aMessage.Read(aMessage.GetOffset(), sizeof(NetworkDiagnosticTlv),
&networkDiagnosticTlv) == sizeof(NetworkDiagnosticTlv)), error = kThreadError_Drop);
VerifyOrExit(networkDiagnosticTlv.GetType() == NetworkDiagnosticTlv::kTypeList, error = kThreadError_Drop);
VerifyOrExit((static_cast<TypeListTlv *>(&networkDiagnosticTlv)->IsValid()), error = kThreadError_Drop);
// DIAG_GET.qry may be sent as a confirmable message.
if (aHeader.GetType() == kCoapTypeConfirmable)
{
SuccessOrExit(error = SendEmptyAck(aHeader, aMessageInfo));
otLogInfoNetDiag("Sent diagnostic get query acknowledgment");
}
header.Init(kCoapTypeConfirmable, kCoapRequestPost);
header.SetToken(Coap::Header::kDefaultTokenLength);
header.AppendUriPathOptions(OPENTHREAD_URI_DIAGNOSTIC_GET_ANSWER);
if (networkDiagnosticTlv.GetLength() > 0)
{
header.SetPayloadMarker();
}
VerifyOrExit((message = mCoapClient.NewMessage(header)) != NULL, error = kThreadError_NoBufs);
messageInfo.SetPeerAddr(aMessageInfo.GetPeerAddr());
messageInfo.SetSockAddr(mMle.GetMeshLocal16());
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
SuccessOrExit(error = FillRequestedTlvs(aMessage, *message, networkDiagnosticTlv));
SuccessOrExit(error = mCoapClient.SendMessage(*message, messageInfo, NULL, this));
otLogInfoNetDiag("Sent diagnostic get answer");
exit:
if (error != kThreadError_None && message != NULL)
{
message->Free();
}
}
void NetworkDiagnostic::HandleDiagnosticGetRequest(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo)
{
static_cast<NetworkDiagnostic *>(aContext)->HandleDiagnosticGetRequest(
*static_cast<Coap::Header *>(aHeader), *static_cast<Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
}
void NetworkDiagnostic::HandleDiagnosticGetRequest(Coap::Header &aHeader, Message &aMessage,
const Ip6::MessageInfo &aMessageInfo)
{
ThreadError error = kThreadError_None;
Message *message = NULL;
uint16_t offset = 0;
uint8_t type;
NetworkDiagnosticTlv networkDiagnosticTlv;
Coap::Header header;
Ip6::MessageInfo messageInfo(aMessageInfo);
@@ -294,155 +546,11 @@ void NetworkDiagnostic::HandleDiagnosticGet(Coap::Header &aHeader, Message &aMes
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
offset = aMessage.GetOffset() + sizeof(NetworkDiagnosticTlv);
for (uint8_t i = 0; i < networkDiagnosticTlv.GetLength(); i++)
{
VerifyOrExit(aMessage.Read(offset, sizeof(type), &type) == sizeof(type), error = kThreadError_Drop);
otLogInfoNetDiag("Received diagnostic get type %d", type);
switch (type)
{
case NetworkDiagnosticTlv::kExtMacAddress:
{
ExtMacAddressTlv tlv;
tlv.Init();
tlv.SetMacAddr(*mNetif.GetMac().GetExtAddress());
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
break;
}
case NetworkDiagnosticTlv::kAddress16:
{
Address16Tlv tlv;
tlv.Init();
tlv.SetRloc16(mMle.GetRloc16());
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
break;
}
case NetworkDiagnosticTlv::kMode:
{
ModeTlv tlv;
tlv.Init();
tlv.SetMode(mMle.GetDeviceMode());
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
break;
}
case NetworkDiagnosticTlv::kTimeout:
{
if ((mMle.GetDeviceMode() & ModeTlv::kModeRxOnWhenIdle) == 0)
{
TimeoutTlv tlv;
tlv.Init();
tlv.SetTimeout(mMle.GetTimeout());
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
}
break;
}
case NetworkDiagnosticTlv::kConnectivity:
{
ConnectivityTlv tlv;
tlv.Init();
mMle.FillConnectivityTlv(*reinterpret_cast<Mle::ConnectivityTlv *>(&tlv));
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
break;
}
case NetworkDiagnosticTlv::kRoute:
{
RouteTlv tlv;
tlv.Init();
mMle.FillRouteTlv(*reinterpret_cast<Mle::RouteTlv *>(&tlv));
SuccessOrExit(error = message->Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kLeaderData:
{
LeaderDataTlv tlv;
memcpy(&tlv, &mMle.GetLeaderDataTlv(), sizeof(tlv));
tlv.Init();
SuccessOrExit(error = message->Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kNetworkData:
{
NetworkDataTlv tlv;
tlv.Init();
mMle.FillNetworkDataTlv((*reinterpret_cast<Mle::NetworkDataTlv *>(&tlv)), true);
SuccessOrExit(error = message->Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kIPv6AddressList:
{
SuccessOrExit(error = AppendIPv6AddressList(*message));
break;
}
case NetworkDiagnosticTlv::kMacCounters:
{
MacCountersTlv tlv;
memset(&tlv, 0, sizeof(tlv));
tlv.Init();
mMac.FillMacCountersTlv(tlv);
SuccessOrExit(error = message->Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kBatteryLevel:
{
// TODO Need more api from driver
BatteryLevelTlv tlv;
tlv.Init();
tlv.SetBatteryLevel(100);
SuccessOrExit(error = message->Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kSupplyVoltage:
{
// TODO Need more api from driver
SupplyVoltageTlv tlv;
tlv.Init();
tlv.SetSupplyVoltage(0);
SuccessOrExit(error = message->Append(&tlv, tlv.GetSize()));
break;
}
case NetworkDiagnosticTlv::kChildTable:
{
SuccessOrExit(error = AppendChildTable(*message));
break;
}
case NetworkDiagnosticTlv::kChannelPages:
{
ChannelPagesTlv tlv;
tlv.Init();
tlv.GetChannelPages()[0] = 0;
tlv.SetLength(1);
SuccessOrExit(error = message->Append(&tlv, tlv.GetSize()));
break;
}
default:
ExitNow();
}
offset += sizeof(type);
}
SuccessOrExit(error = FillRequestedTlvs(aMessage, *message, networkDiagnosticTlv));
SuccessOrExit(error = mCoapServer.SendMessage(*message, messageInfo));
otLogInfoNetDiag("Sent diagnostic get acknowledgment");
otLogInfoNetDiag("Sent diagnostic get response");
exit:
@@ -452,6 +560,42 @@ exit:
}
}
ThreadError NetworkDiagnostic::SendDiagnosticReset(const Ip6::Address &aDestination, const uint8_t aTlvTypes[],
uint8_t aCount)
{
ThreadError error;
Message *message;
Coap::Header header;
Ip6::MessageInfo messageInfo;
header.Init(kCoapTypeConfirmable, kCoapRequestPost);
header.SetToken(Coap::Header::kDefaultTokenLength);
header.AppendUriPathOptions(OPENTHREAD_URI_DIAGNOSTIC_RESET);
header.SetPayloadMarker();
VerifyOrExit((message = mCoapClient.NewMessage(header)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = message->Append(aTlvTypes, aCount));
messageInfo.SetPeerAddr(aDestination);
messageInfo.SetSockAddr(mMle.GetMeshLocal16());
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
SuccessOrExit(error = mCoapClient.SendMessage(*message, messageInfo));
otLogInfoNetDiag("Sent network diagnostic reset");
exit:
if (error != kThreadError_None && message != NULL)
{
message->Free();
}
return error;
}
void NetworkDiagnostic::HandleDiagnosticReset(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo)
{
@@ -468,8 +612,6 @@ void NetworkDiagnostic::HandleDiagnosticReset(Coap::Header &aHeader, Message &aM
uint16_t offset = 0;
uint8_t type;
NetworkDiagnosticTlv networkDiagnosticTlv;
Coap::Header header;
Ip6::MessageInfo messageInfo(aMessageInfo);
otLogInfoNetDiag("Received diagnostic reset request");
@@ -483,12 +625,6 @@ void NetworkDiagnostic::HandleDiagnosticReset(Coap::Header &aHeader, Message &aM
VerifyOrExit((static_cast<TypeListTlv *>(&networkDiagnosticTlv)->IsValid()), error = kThreadError_Drop);
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
header.SetDefaultResponseHeader(aHeader);
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
offset = aMessage.GetOffset() + sizeof(NetworkDiagnosticTlv);
for (uint8_t i = 0; i < networkDiagnosticTlv.GetLength(); i++)
@@ -508,7 +644,7 @@ void NetworkDiagnostic::HandleDiagnosticReset(Coap::Header &aHeader, Message &aM
}
}
SuccessOrExit(error = mCoapServer.SendMessage(*message, messageInfo));
SuccessOrExit(error = SendEmptyAck(aHeader, aMessageInfo));
otLogInfoNetDiag("Sent diagnostic reset acknowledgment");
+29 -29
View File
@@ -49,6 +49,7 @@ namespace NetworkDiagnostic {
class IPv6AddressListTlv;
class ChildTableTlv;
class NetworkDiagnosticTlv;
/**
* @addtogroup core-netdiag
@@ -73,17 +74,18 @@ public:
explicit NetworkDiagnostic(ThreadNetif &aThreadNetif);
/**
* This method registers a callback to provide received raw DIAG_GET.rsp payload.
* This method registers a callback to provide received raw DIAG_GET.rsp or an DIAG_GET.ans payload.
*
* @param[in] aCallback A pointer to a function that is called when an DIAG_GET.rsp is received or
* NULL to disable the callback.
* @param[in] aCallback A pointer to a function that is called when an DIAG_GET.rsp or an DIAG_GET.ans
* is received or NULL to disable the callback.
* @param[in] aCallbackContext A pointer to application-specific context.
*
*/
void SetReceiveDiagnosticGetCallback(otReceiveDiagnosticGetCallback aCallback, void *aCallbackContext);
/**
* This method sends Diagnostic Get request.
* This method sends Diagnostic Get request. If the @p aDestination is of multicast type, the DIAG_GET.qry
* message is sent or the DIAG_GET.req otherwise.
*
* @param[in] aDestination A reference to the destination address.
* @param[in] aTlvTypes An array of Network Diagnostic TLV types.
@@ -102,39 +104,37 @@ public:
*/
ThreadError SendDiagnosticReset(const Ip6::Address &aDestination, const uint8_t aTlvTypes[], uint8_t aCount);
/**
* This method fills IPv6AddressListTlv.
*
* @param[out] aTlv A reference to the tlv.
*
*/
ThreadError AppendIPv6AddressList(Message &aMessage);
/**
* This method fills ChildTableTlv.
*
* @param[out] aTlv A reference to the tlv.
*
*/
ThreadError AppendChildTable(Message &aMessage);
private:
ThreadError AppendIPv6AddressList(Message &aMessage);
ThreadError AppendChildTable(Message &aMessage);
ThreadError FillRequestedTlvs(Message &aRequest, Message &aResponse, NetworkDiagnosticTlv &aNetworkDiagnosticTlv);
ThreadError SendEmptyAck(Coap::Header &aHeader, const Ip6::MessageInfo &aMessageInfo);
static void HandleDiagnosticGetRequest(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo);
void HandleDiagnosticGetRequest(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleDiagnosticGetQuery(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo);
void HandleDiagnosticGetQuery(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleDiagnosticGetResponse(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo, ThreadError aResult);
void HandleDiagnosticGetResponse(Coap::Header *aHeader, Message *aMessage,
const Ip6::MessageInfo *aMessageInfo, ThreadError aResult);
void HandleDiagnosticGetResponse(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
ThreadError aResult);
static void HandleDiagnosticGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo);
void HandleDiagnosticGet(Thread::Coap::Header &aHeader, Thread::Message &aMessage,
const Thread::Ip6::MessageInfo &aMessageInfo);
static void HandleDiagnosticGetAnswer(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo);
void HandleDiagnosticGetAnswer(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleDiagnosticReset(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
const otMessageInfo *aMessageInfo);
void HandleDiagnosticReset(Coap::Header &aHeader, Message &aMessage,
const Ip6::MessageInfo &aMessageInfo);
void HandleDiagnosticReset(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
Coap::Resource mDiagnosticGet;
Coap::Resource mDiagnosticGetRequest;
Coap::Resource mDiagnosticGetQuery;
Coap::Resource mDiagnosticGetAnswer;
Coap::Resource mDiagnosticReset;
Coap::Server &mCoapServer;
Coap::Client &mCoapClient;
+44 -28
View File
@@ -40,7 +40,7 @@ namespace Thread {
* The URI Path for Address Query.
*
*/
#define OPENTHREAD_URI_ADDRESS_QUERY "a/aq"
#define OPENTHREAD_URI_ADDRESS_QUERY "a/aq"
/**
* @def OPENTHREAD_URI_ADDRESS_NOTIFY
@@ -48,7 +48,7 @@ namespace Thread {
* The URI Path for Address Notify.
*
*/
#define OPENTHREAD_URI_ADDRESS_NOTIFY "a/an"
#define OPENTHREAD_URI_ADDRESS_NOTIFY "a/an"
/**
* @def OPENTHREAD_URI_ADDRESS_ERROR
@@ -56,7 +56,7 @@ namespace Thread {
* The URI Path for Address Error.
*
*/
#define OPENTHREAD_URI_ADDRESS_ERROR "a/ae"
#define OPENTHREAD_URI_ADDRESS_ERROR "a/ae"
/**
* @def OPENTHREAD_URI_ADDRESS_RELEASE
@@ -64,7 +64,7 @@ namespace Thread {
* The URI Path for Address Release.
*
*/
#define OPENTHREAD_URI_ADDRESS_RELEASE "a/ar"
#define OPENTHREAD_URI_ADDRESS_RELEASE "a/ar"
/**
* @def OPENTHREAD_URI_ADDRESS_SOLICIT
@@ -72,7 +72,7 @@ namespace Thread {
* The URI Path for Address Solicit.
*
*/
#define OPENTHREAD_URI_ADDRESS_SOLICIT "a/as"
#define OPENTHREAD_URI_ADDRESS_SOLICIT "a/as"
/**
* @def OPENTHREAD_URI_ACTIVE_GET
@@ -80,7 +80,7 @@ namespace Thread {
* The URI Path for MGMT_ACTIVE_GET
*
*/
#define OPENTHREAD_URI_ACTIVE_GET "c/ag"
#define OPENTHREAD_URI_ACTIVE_GET "c/ag"
/**
* @def OPENTHREAD_URI_ACTIVE_SET
@@ -88,7 +88,7 @@ namespace Thread {
* The URI Path for MGMT_ACTIVE_SET
*
*/
#define OPENTHREAD_URI_ACTIVE_SET "c/as"
#define OPENTHREAD_URI_ACTIVE_SET "c/as"
/**
* @def OPENTHREAD_URI_DATASET_CHANGED
@@ -96,7 +96,7 @@ namespace Thread {
* The URI Path for MGMT_DATASET_CHANGED
*
*/
#define OPENTHREAD_URI_DATASET_CHANGED "c/dc"
#define OPENTHREAD_URI_DATASET_CHANGED "c/dc"
/**
* @def OPENTHREAD_URI_ENERGY_SCAN
@@ -104,7 +104,7 @@ namespace Thread {
* The URI Path for Energy Scan
*
*/
#define OPENTHREAD_URI_ENERGY_SCAN "c/es"
#define OPENTHREAD_URI_ENERGY_SCAN "c/es"
/**
* @def OPENTHREAD_URI_ENERGY_REPORT
@@ -112,7 +112,7 @@ namespace Thread {
* The URI Path for Energy Report
*
*/
#define OPENTHREAD_URI_ENERGY_REPORT "c/er"
#define OPENTHREAD_URI_ENERGY_REPORT "c/er"
/**
* @def OPENTHREAD_URI_PENDING_GET
@@ -120,7 +120,7 @@ namespace Thread {
* The URI Path for MGMT_PENDING_GET
*
*/
#define OPENTHREAD_URI_PENDING_GET "c/pg"
#define OPENTHREAD_URI_PENDING_GET "c/pg"
/**
* @def OPENTHREAD_URI_PENDING_SET
@@ -128,7 +128,7 @@ namespace Thread {
* The URI Path for MGMT_PENDING_SET
*
*/
#define OPENTHREAD_URI_PENDING_SET "c/ps"
#define OPENTHREAD_URI_PENDING_SET "c/ps"
/**
* @def OPENTHREAD_URI_SERVER_DATA
@@ -136,7 +136,7 @@ namespace Thread {
* The URI Path for Server Data Registration.
*
*/
#define OPENTHREAD_URI_SERVER_DATA "a/sd"
#define OPENTHREAD_URI_SERVER_DATA "a/sd"
/**
* @def OPENTHREAD_URI_ANNOUNCE_BEGIN
@@ -144,7 +144,7 @@ namespace Thread {
* The URI Path for Announce Begin.
*
*/
#define OPENTHREAD_URI_ANNOUNCE_BEGIN "c/ab"
#define OPENTHREAD_URI_ANNOUNCE_BEGIN "c/ab"
/**
* @def OPENTHREAD_URI_RELAY_RX
@@ -152,7 +152,7 @@ namespace Thread {
* The URI Path for Relay RX.
*
*/
#define OPENTHREAD_URI_RELAY_RX "c/rx"
#define OPENTHREAD_URI_RELAY_RX "c/rx"
/**
* @def OPENTHREAD_URI_RELAY_TX
@@ -160,7 +160,7 @@ namespace Thread {
* The URI Path for Relay TX.
*
*/
#define OPENTHREAD_URI_RELAY_TX "c/tx"
#define OPENTHREAD_URI_RELAY_TX "c/tx"
/**
* @def OPENTHREAD_URI_JOINER_FINALIZE
@@ -168,7 +168,7 @@ namespace Thread {
* The URI Path for Joiner Finalize
*
*/
#define OPENTHREAD_URI_JOINER_FINALIZE "c/jf"
#define OPENTHREAD_URI_JOINER_FINALIZE "c/jf"
/**
* @def OPENTHREAD_URI_JOINER_ENTRUST
@@ -176,7 +176,7 @@ namespace Thread {
* The URI Path for Joiner Entrust
*
*/
#define OPENTHREAD_URI_JOINER_ENTRUST "c/je"
#define OPENTHREAD_URI_JOINER_ENTRUST "c/je"
/**
* @def OPENTHREAD_URI_LEADER_PETITION
@@ -184,7 +184,7 @@ namespace Thread {
* The URI Path for Leader Petition
*
*/
#define OPENTHREAD_URI_LEADER_PETITION "c/lp"
#define OPENTHREAD_URI_LEADER_PETITION "c/lp"
/**
* @def OPENTHREAD_URI_LEADER_KEEP_ALIVE
@@ -192,7 +192,7 @@ namespace Thread {
* The URI Path for Leader Keep Alive
*
*/
#define OPENTHREAD_URI_LEADER_KEEP_ALIVE "c/la"
#define OPENTHREAD_URI_LEADER_KEEP_ALIVE "c/la"
/**
* @def OPENTHREAD_URI_PANID_CONFLICT
@@ -200,7 +200,7 @@ namespace Thread {
* The URI Path for PAN ID Conflict
*
*/
#define OPENTHREAD_URI_PANID_CONFLICT "c/pc"
#define OPENTHREAD_URI_PANID_CONFLICT "c/pc"
/**
* @def OPENTHREAD_URI_PANID_QUERY
@@ -208,7 +208,7 @@ namespace Thread {
* The URI Path for PAN ID Query
*
*/
#define OPENTHREAD_URI_PANID_QUERY "c/pq"
#define OPENTHREAD_URI_PANID_QUERY "c/pq"
/**
* @def OPENTHREAD_URI_COMMISSIONER_GET
@@ -216,7 +216,7 @@ namespace Thread {
* The URI Path for MGMT_COMMISSIONER_GET
*
*/
#define OPENTHREAD_URI_COMMISSIONER_GET "c/cg"
#define OPENTHREAD_URI_COMMISSIONER_GET "c/cg"
/**
* @def OPENTHREAD_URI_COMMISSIONER_SET
@@ -224,15 +224,31 @@ namespace Thread {
* The URI Path for MGMT_COMMISSIONER_SET
*
*/
#define OPENTHREAD_URI_COMMISSIONER_SET "c/cs"
#define OPENTHREAD_URI_COMMISSIONER_SET "c/cs"
/**
* @def OPENTHREAD_URI_DIAGNOSTIC_GET
* @def OPENTHREAD_URI_DIAGNOSTIC_GET_REQUEST
*
* The URI Path for Network Diagnostic Get.
* The URI Path for Network Diagnostic Get Request.
*
*/
#define OPENTHREAD_URI_DIAGNOSTIC_GET "d/dg"
#define OPENTHREAD_URI_DIAGNOSTIC_GET_REQUEST "d/dg"
/**
* @def OPENTHREAD_URI_DIAGNOSTIC_GET_QUERY
*
* The URI Path for Network Diagnostic Get Query.
*
*/
#define OPENTHREAD_URI_DIAGNOSTIC_GET_QUERY "d/dq"
/**
* @def OPENTHREAD_URI_DIAGNOSTIC_GET_ANSWER
*
* The URI Path for Network Diagnostic Get Answer.
*
*/
#define OPENTHREAD_URI_DIAGNOSTIC_GET_ANSWER "d/da"
/**
* @def OPENTHREAD_URI_DIAG_RST
@@ -240,7 +256,7 @@ namespace Thread {
* The URI Path for Network Diagnostic Reset.
*
*/
#define OPENTHREAD_URI_DIAGNOSTIC_RESET "d/dr"
#define OPENTHREAD_URI_DIAGNOSTIC_RESET "d/dr"
} // namespace Thread