1 /* 2 * Copyright (c) 2016-2020, 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 includes definitions for MLE Discover Scan process. 32 */ 33 34 #ifndef DISCOVER_SCANNER_HPP_ 35 #define DISCOVER_SCANNER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/callback.hpp" 40 #include "common/locator.hpp" 41 #include "common/non_copyable.hpp" 42 #include "common/tasklet.hpp" 43 #include "common/timer.hpp" 44 #include "mac/channel_mask.hpp" 45 #include "mac/mac.hpp" 46 #include "mac/mac_types.hpp" 47 #include "meshcop/meshcop.hpp" 48 #include "thread/mle.hpp" 49 50 namespace ot { 51 52 class MeshForwarder; 53 54 namespace Mle { 55 56 /** 57 * This class implements MLE Discover Scan. 58 * 59 */ 60 class DiscoverScanner : public InstanceLocator, private NonCopyable 61 { 62 friend class ot::Instance; 63 friend class ot::MeshForwarder; 64 friend class Mle; 65 66 public: 67 /** 68 * Default scan duration (per channel), in milliseconds. 69 * 70 */ 71 static constexpr uint32_t kDefaultScanDuration = Mac::kScanDurationDefault; 72 73 /** 74 * This type represents Discover Scan result. 75 * 76 */ 77 typedef otActiveScanResult ScanResult; 78 79 /** 80 * This type represents the handler function pointer called with any Discover Scan result or when the scan 81 * completes. 82 * 83 * The handler function format is `void (*oHandler)(ScanResult *aResult, void *aContext);`. End of scan is 84 * indicated by `aResult` pointer being set to `nullptr`. 85 * 86 */ 87 typedef otHandleActiveScanResult Handler; 88 89 /** 90 * This type represents the filter indexes, i.e., hash bit index values for the bloom filter (calculated from a 91 * Joiner ID). 92 * 93 * This is used when filtering is enabled during Discover Scan, i.e., received MLE Discovery Responses with steering 94 * data (bloom filter) not containing the given indexes are filtered. 95 * 96 */ 97 typedef MeshCoP::SteeringData::HashBitIndexes FilterIndexes; 98 99 /** 100 * This constructor initializes the object. 101 * 102 * @param[in] aInstance A reference to the OpenThread instance. 103 * 104 */ 105 explicit DiscoverScanner(Instance &aInstance); 106 107 /** 108 * This method starts a Thread Discovery Scan. 109 * 110 * @param[in] aScanChannels Channel mask listing channels to scan (if empty, use all supported channels). 111 * @param[in] aPanId The PAN ID filter (set to Broadcast PAN to disable filter). 112 * @param[in] aJoiner Value of the Joiner Flag in the Discovery Request TLV. 113 * @param[in] aEnableFiltering Enable filtering MLE Discovery Responses with steering data not containing a 114 * given filter indexes. 115 * @param[in] aFilterIndexes A pointer to `FilterIndexes` to use for filtering (when enabled). 116 * If set to `nullptr`, filter indexes are derived from hash of factory-assigned 117 * EUI64. 118 * @param[in] aCallback A pointer to a function that is called on receiving an MLE Discovery Response. 119 * @param[in] aContext A pointer to arbitrary context information. 120 * 121 * @retval kErrorNone Successfully started a Thread Discovery Scan. 122 * @retval kErrorInvalidState The IPv6 interface is not enabled (netif is not up). 123 * @retval kErrorNoBufs Could not allocate message for Discovery Request. 124 * @retval kErrorBusy Thread Discovery Scan is already in progress. 125 * 126 */ 127 Error Discover(const Mac::ChannelMask &aScanChannels, 128 Mac::PanId aPanId, 129 bool aJoiner, 130 bool aEnableFiltering, 131 const FilterIndexes *aFilterIndexes, 132 Handler aCallback, 133 void *aContext); 134 135 /** 136 * This method indicates whether or not an MLE Thread Discovery Scan is currently in progress. 137 * 138 * @returns true if an MLE Thread Discovery Scan is in progress, false otherwise. 139 * 140 */ IsInProgress(void) const141 bool IsInProgress(void) const { return (mState != kStateIdle); } 142 143 /** 144 * This method sets Joiner Advertisement. 145 * 146 * @param[in] aOui The Vendor OUI for Joiner Advertisement. 147 * @param[in] aAdvData A pointer to AdvData for Joiner Advertisement. 148 * @param[in] aAdvDataLength The length of AdvData. 149 * 150 * @retval kErrorNone Successfully set Joiner Advertisement. 151 * @retval kErrorInvalidArgs Invalid AdvData. 152 * 153 */ 154 Error SetJoinerAdvertisement(uint32_t aOui, const uint8_t *aAdvData, uint8_t aAdvDataLength); 155 156 private: 157 enum State : uint8_t 158 { 159 kStateIdle, 160 kStateScanning, 161 kStateScanDone, 162 }; 163 164 static constexpr uint32_t kMaxOui = 0xffffff; 165 166 // Methods used by `MeshForwarder` 167 Mac::TxFrame *PrepareDiscoveryRequestFrame(Mac::TxFrame &aFrame); 168 void HandleDiscoveryRequestFrameTxDone(Message &aMessage); Stop(void)169 void Stop(void) { HandleDiscoverComplete(); } 170 171 // Methods used from `Mle` 172 void HandleDiscoveryResponse(Mle::RxInfo &aRxInfo) const; 173 174 void HandleDiscoverComplete(void); 175 void HandleScanDoneTask(void); 176 void HandleTimer(void); 177 178 using ScanTimer = TimerMilliIn<DiscoverScanner, &DiscoverScanner::HandleTimer>; 179 using ScanDoneTask = TaskletIn<DiscoverScanner, &DiscoverScanner::HandleScanDoneTask>; 180 181 Callback<Handler> mCallback; 182 ScanDoneTask mScanDoneTask; 183 ScanTimer mTimer; 184 FilterIndexes mFilterIndexes; 185 Mac::ChannelMask mScanChannels; 186 State mState; 187 uint32_t mOui; 188 uint8_t mScanChannel; 189 uint8_t mAdvDataLength; 190 uint8_t mAdvData[MeshCoP::JoinerAdvertisementTlv::kAdvDataMaxLength]; 191 bool mEnableFiltering : 1; 192 bool mShouldRestorePanId : 1; 193 }; 194 195 } // namespace Mle 196 } // namespace ot 197 198 #endif // DISCOVER_SCANNER_HPP_ 199