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 includes definitions for jam detector.
32  */
33 
34 #ifndef JAM_DETECTOR_HPP_
35 #define JAM_DETECTOR_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
40 
41 #include <stdint.h>
42 
43 #include "common/callback.hpp"
44 #include "common/locator.hpp"
45 #include "common/non_copyable.hpp"
46 #include "common/notifier.hpp"
47 #include "common/timer.hpp"
48 
49 namespace ot {
50 
51 class ThreadNetif;
52 
53 namespace Utils {
54 
55 class JamDetector : public InstanceLocator, private NonCopyable
56 {
57     friend class ot::Notifier;
58 
59 public:
60     /**
61      * Pointer is called if jam state changes (assuming jamming detection is enabled).
62      *
63      * @param[in]  aJamState  `true` if jam is detected, `false` if jam is cleared.
64      * @param[in]  aContext  A pointer to application-specific context.
65      *
66      */
67     typedef void (*Handler)(bool aJamState, void *aContext);
68 
69     /**
70      * Initializes the object.
71      *
72      * @param[in]  aInstance     A reference to the OpenThread instance.
73      *
74      */
75     explicit JamDetector(Instance &aInstance);
76 
77     /**
78      * Start the jamming detection.
79      *
80      * @param[in]  aHandler             A pointer to a function called when jamming is detected.
81      * @param[in]  aContext             A pointer to application-specific context.
82      *
83      * @retval kErrorNone            Successfully started the jamming detection.
84      * @retval kErrorAlready         Jam detection has been started before.
85      *
86      */
87     Error Start(Handler aHandler, void *aContext);
88 
89     /**
90      * Stop the jamming detection.
91      *
92      * @retval kErrorNone            Successfully stopped the jamming detection.
93      * @retval kErrorAlready         Jam detection is already stopped.
94      *
95      */
96     Error Stop(void);
97 
98     /**
99      * Get the Jam Detection Status
100      *
101      * @returns The Jam Detection status (true if enabled, false otherwise).
102      */
IsEnabled(void) const103     bool IsEnabled(void) const { return mEnabled; }
104 
105     /**
106      * Get the current jam state.
107      *
108      * @returns The jamming state (`true` if jam is detected, `false` otherwise).
109      */
GetState(void) const110     bool GetState(void) const { return mJamState; }
111 
112     /**
113      * Set the Jam Detection RSSI Threshold (in dBm).
114      *
115      * @param[in]  aThreshold  The RSSI threshold.
116      *
117      */
118     void SetRssiThreshold(int8_t aThreshold);
119 
120     /**
121      * Get the Jam Detection RSSI Threshold (in dBm).
122      *
123      * @returns The Jam Detection RSSI Threshold.
124      */
GetRssiThreshold(void) const125     int8_t GetRssiThreshold(void) const { return mRssiThreshold; }
126 
127     /**
128      * Set the Jam Detection Detection Window (in seconds).
129      *
130      * @param[in]  aWindow            The Jam Detection window (valid range is 1 to 63)
131      *
132      * @retval kErrorNone          Successfully set the window.
133      * @retval kErrorInvalidArgs   The given input parameter not within valid range (1-63)
134      *
135      */
136     Error SetWindow(uint8_t aWindow);
137 
138     /**
139      * Get the Jam Detection Detection Window (in seconds).
140      *
141      * @returns The Jam Detection Window.
142      */
GetWindow(void) const143     uint8_t GetWindow(void) const { return mWindow; }
144 
145     /**
146      * Set the Jam Detection Busy Period (in seconds).
147      *
148      * The number of aggregate seconds within the detection window where the RSSI must be above
149      * threshold to trigger detection.
150      *
151      * @param[in]  aBusyPeriod          The Jam Detection busy period (should be non-zero and
152                                         less than or equal to Jam Detection Window)
153      *
154      * @retval kErrorNone           Successfully set the window.
155      * @retval kErrorInvalidArgs    The given input is not within the valid range.
156      *
157      */
158     Error SetBusyPeriod(uint8_t aBusyPeriod);
159 
160     /**
161      * Get the Jam Detection Busy Period (in seconds)
162      *
163      * @returns The Jam Detection Busy Period
164      */
GetBusyPeriod(void) const165     uint8_t GetBusyPeriod(void) const { return mBusyPeriod; }
166 
167     /**
168      * Get the current history bitmap.
169      *
170      * This value provides information about current state of jamming detection
171      * module for monitoring/debugging purpose. It provides a 64-bit value where
172      * each bit corresponds to one second interval starting with bit 0 for the
173      * most recent interval and bit 63 for the oldest intervals (63 earlier).
174      * The bit is set to 1 if the jamming detection module observed/detected
175      * high signal level during the corresponding one second interval.
176      *
177      * @returns The current history bitmap.
178      */
GetHistoryBitmap(void) const179     uint64_t GetHistoryBitmap(void) const { return mHistoryBitmap; }
180 
181 private:
182     static constexpr uint8_t kMaxWindow            = 63; // Max window size
183     static constexpr int8_t  kDefaultRssiThreshold = 0;
184 
185     static constexpr uint16_t kMaxSampleInterval = 256; // in ms
186     static constexpr uint16_t kMinSampleInterval = 2;   // in ms
187     static constexpr uint32_t kMaxRandomDelay    = 4;   // in ms
188 
189     void CheckState(void);
190     void SetJamState(bool aNewState);
191     void HandleTimer(void);
192     void UpdateHistory(bool aDidExceedThreshold);
193     void UpdateJamState(void);
194     void HandleNotifierEvents(Events aEvents);
195 
196     using SampleTimer = TimerMilliIn<JamDetector, &JamDetector::HandleTimer>;
197 
198     Callback<Handler> mCallback;                 // Callback to inform about jamming state
199     SampleTimer       mTimer;                    // RSSI sample timer
200     uint64_t          mHistoryBitmap;            // History bitmap, each bit correspond to 1 sec interval
201     TimeMilli         mCurSecondStartTime;       // Start time for current 1 sec interval
202     uint16_t          mSampleInterval;           // Current sample interval
203     uint8_t           mWindow : 6;               // Window (in sec) to monitor jamming
204     uint8_t           mBusyPeriod : 6;           // BusyPeriod (in sec) with mWindow to alert jamming
205     bool              mEnabled : 1;              // If jam detection is enabled
206     bool              mAlwaysAboveThreshold : 1; // State for current 1 sec interval
207     bool              mJamState : 1;             // Current jam state
208     int8_t            mRssiThreshold;            // RSSI threshold for jam detection
209 };
210 
211 /**
212  * @}
213  *
214  */
215 
216 } // namespace Utils
217 } // namespace ot
218 
219 #endif // OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
220 
221 #endif // JAM_DETECTOR_HPP_
222