/src/openthread/src/core/thread/panid_query_server.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2016, The OpenThread Authors. |
3 | | * All rights reserved. |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that the following conditions are met: |
7 | | * 1. Redistributions of source code must retain the above copyright |
8 | | * notice, this list of conditions and the following disclaimer. |
9 | | * 2. Redistributions in binary form must reproduce the above copyright |
10 | | * notice, this list of conditions and the following disclaimer in the |
11 | | * documentation and/or other materials provided with the distribution. |
12 | | * 3. Neither the name of the copyright holder nor the |
13 | | * names of its contributors may be used to endorse or promote products |
14 | | * derived from this software without specific prior written permission. |
15 | | * |
16 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
17 | | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
20 | | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | | * POSSIBILITY OF SUCH DAMAGE. |
27 | | */ |
28 | | |
29 | | /** |
30 | | * @file |
31 | | * This file implements the PAN ID Query Server. |
32 | | */ |
33 | | |
34 | | #include "panid_query_server.hpp" |
35 | | |
36 | | #include "coap/coap_message.hpp" |
37 | | #include "common/as_core_type.hpp" |
38 | | #include "common/code_utils.hpp" |
39 | | #include "common/debug.hpp" |
40 | | #include "common/instance.hpp" |
41 | | #include "common/locator_getters.hpp" |
42 | | #include "common/log.hpp" |
43 | | #include "meshcop/meshcop.hpp" |
44 | | #include "meshcop/meshcop_tlvs.hpp" |
45 | | #include "thread/thread_netif.hpp" |
46 | | #include "thread/uri_paths.hpp" |
47 | | |
48 | | namespace ot { |
49 | | |
50 | | RegisterLogModule("MeshCoP"); |
51 | | |
52 | | PanIdQueryServer::PanIdQueryServer(Instance &aInstance) |
53 | | : InstanceLocator(aInstance) |
54 | | , mChannelMask(0) |
55 | | , mPanId(Mac::kPanIdBroadcast) |
56 | | , mTimer(aInstance) |
57 | 15.5k | { |
58 | 15.5k | } |
59 | | |
60 | | template <> |
61 | | void PanIdQueryServer::HandleTmf<kUriPanIdQuery>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) |
62 | 0 | { |
63 | 0 | uint16_t panId; |
64 | 0 | Ip6::MessageInfo responseInfo(aMessageInfo); |
65 | 0 | uint32_t mask; |
66 | |
|
67 | 0 | VerifyOrExit(aMessage.IsPostRequest()); |
68 | 0 | VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0); |
69 | | |
70 | 0 | SuccessOrExit(Tlv::Find<MeshCoP::PanIdTlv>(aMessage, panId)); |
71 | | |
72 | 0 | mChannelMask = mask; |
73 | 0 | mCommissioner = aMessageInfo.GetPeerAddr(); |
74 | 0 | mPanId = panId; |
75 | 0 | mTimer.Start(kScanDelay); |
76 | |
|
77 | 0 | if (aMessage.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast()) |
78 | 0 | { |
79 | 0 | SuccessOrExit(Get<Tmf::Agent>().SendEmptyAck(aMessage, responseInfo)); |
80 | 0 | LogInfo("sent panid query response"); |
81 | 0 | } |
82 | | |
83 | 0 | exit: |
84 | 0 | return; |
85 | 0 | } |
86 | | |
87 | | void PanIdQueryServer::HandleScanResult(Mac::ActiveScanResult *aScanResult, void *aContext) |
88 | 0 | { |
89 | 0 | static_cast<PanIdQueryServer *>(aContext)->HandleScanResult(aScanResult); |
90 | 0 | } |
91 | | |
92 | | void PanIdQueryServer::HandleScanResult(Mac::ActiveScanResult *aScanResult) |
93 | 0 | { |
94 | 0 | if (aScanResult != nullptr) |
95 | 0 | { |
96 | 0 | if (aScanResult->mPanId == mPanId) |
97 | 0 | { |
98 | 0 | mChannelMask |= 1 << aScanResult->mChannel; |
99 | 0 | } |
100 | 0 | } |
101 | 0 | else if (mChannelMask != 0) |
102 | 0 | { |
103 | 0 | SendConflict(); |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | | void PanIdQueryServer::SendConflict(void) |
108 | 0 | { |
109 | 0 | Error error = kErrorNone; |
110 | 0 | MeshCoP::ChannelMaskTlv channelMask; |
111 | 0 | Tmf::MessageInfo messageInfo(GetInstance()); |
112 | 0 | Coap::Message *message; |
113 | |
|
114 | 0 | message = Get<Tmf::Agent>().NewPriorityConfirmablePostMessage(kUriPanIdConflict); |
115 | 0 | VerifyOrExit(message != nullptr, error = kErrorNoBufs); |
116 | | |
117 | 0 | channelMask.Init(); |
118 | 0 | channelMask.SetChannelMask(mChannelMask); |
119 | 0 | SuccessOrExit(error = channelMask.AppendTo(*message)); |
120 | | |
121 | 0 | SuccessOrExit(error = Tlv::Append<MeshCoP::PanIdTlv>(*message, mPanId)); |
122 | | |
123 | 0 | messageInfo.SetSockAddrToRlocPeerAddrTo(mCommissioner); |
124 | |
|
125 | 0 | SuccessOrExit(error = Get<Tmf::Agent>().SendMessage(*message, messageInfo)); |
126 | | |
127 | 0 | LogInfo("sent panid conflict"); |
128 | |
|
129 | 0 | exit: |
130 | 0 | FreeMessageOnError(message, error); |
131 | 0 | MeshCoP::LogError("send panid conflict", error); |
132 | 0 | } |
133 | | |
134 | | void PanIdQueryServer::HandleTimer(void) |
135 | 0 | { |
136 | 0 | IgnoreError(Get<Mac::Mac>().ActiveScan(mChannelMask, 0, HandleScanResult, this)); |
137 | 0 | mChannelMask = 0; |
138 | 0 | } |
139 | | |
140 | | } // namespace ot |