• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *    Copyright (c) 2016-2017, 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" AND
17  *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20  *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * @file
30  *   This file contains definitions a spinel interface to the OpenThread stack.
31  */
32 
33 #ifndef CHANGED_PROPS_SET_HPP_
34 #define CHANGED_PROPS_SET_HPP_
35 
36 #include "openthread-core-config.h"
37 
38 #include <stddef.h>
39 
40 #include <openthread/error.h>
41 
42 #include "lib/spinel/spinel.h"
43 
44 namespace ot {
45 namespace Ncp {
46 
47 /**
48  * Defines a class to track a set of property/status changes that require update to host. The properties that can
49  * be added to this set must support sending unsolicited updates. This class also provides mechanism for user
50  * to block certain filterable properties disallowing the unsolicited update from them.
51  */
52 class ChangedPropsSet
53 {
54 public:
55     /**
56      * Defines an entry in the set/list.
57      */
58     struct Entry
59     {
60         spinel_prop_key_t mPropKey;    ///< The spinel property key.
61         spinel_status_t   mStatus;     ///< The spinel status (used only if prop key is `LAST_STATUS`).
62         bool              mFilterable; ///< Indicates whether the entry can be filtered
63     };
64 
65     /**
66      * Initializes the set.
67      */
ChangedPropsSet(void)68     ChangedPropsSet(void)
69         : mChangedSet(0)
70         , mFilterSet(0)
71     {
72     }
73 
74     /**
75      * Clears the set.
76      */
Clear(void)77     void Clear(void) { mChangedSet = 0; }
78 
79     /**
80      * Indicates if the set is empty or not.
81      *
82      * @returns TRUE if the set if empty, FALSE otherwise.
83      */
IsEmpty(void) const84     bool IsEmpty(void) const { return (mChangedSet == 0); }
85 
86     /**
87      * Adds a property to the set. The property added must be in the list of supported properties
88      * capable of sending unsolicited update, otherwise the input is ignored.
89      *
90      * Note that if the property is already in the set, adding it again does not change the set.
91      *
92      * @param[in] aPropKey    The spinel property key to be added to the set
93      */
AddProperty(spinel_prop_key_t aPropKey)94     void AddProperty(spinel_prop_key_t aPropKey) { Add(aPropKey, SPINEL_STATUS_OK); }
95 
96     /**
97      * Adds a `LAST_STATUS` update to the set. The update must be in list of supported entries.
98      *
99      * @param[in] aStatus     The spinel status update to be added to set.
100      */
AddLastStatus(spinel_status_t aStatus)101     void AddLastStatus(spinel_status_t aStatus) { Add(SPINEL_PROP_LAST_STATUS, aStatus); }
102 
103     /**
104      * Returns a pointer to array of entries of supported property/status updates. The list includes
105      * all properties that can generate unsolicited update.
106      *
107      * @param[out]  aNumEntries  A reference to output the number of entries in the list.
108      *
109      * @returns A pointer to the supported entries array.
110      */
GetSupportedEntries(uint8_t & aNumEntries) const111     const Entry *GetSupportedEntries(uint8_t &aNumEntries) const
112     {
113         aNumEntries = GetNumEntries();
114         return &mSupportedProps[0];
115     }
116 
117     /**
118      * Returns a pointer to the entry associated with a given index.
119      *
120      * @param[in] aIndex     The index to an entry.
121      *
122      * @returns A pointer to the entry associated with @p aIndex, or nullptr if the index is beyond end of array.
123      */
GetEntry(uint8_t aIndex) const124     const Entry *GetEntry(uint8_t aIndex) const
125     {
126         return (aIndex < GetNumEntries()) ? &mSupportedProps[aIndex] : nullptr;
127     }
128 
129     /**
130      * Indicates if the entry associated with an index is in the set (i.e., it has been changed and
131      * requires an unsolicited update).
132      *
133      * @param[in] aIndex     The index to an entry.
134      *
135      * @returns TRUE if the entry is in the set, FALSE otherwise.
136      */
IsEntryChanged(uint8_t aIndex) const137     bool IsEntryChanged(uint8_t aIndex) const { return IsBitSet(mChangedSet, aIndex); }
138 
139     /**
140      * Removes an entry associated with an index in the set.
141      *
142      * Note that if the property/entry is not in the set, removing it simply does nothing.
143      *
144      * @param[in] aIndex               Index of entry to be removed.
145      */
RemoveEntry(uint8_t aIndex)146     void RemoveEntry(uint8_t aIndex) { ClearBit(mChangedSet, aIndex); }
147 
148     /**
149      * Enables/disables filtering of a given property.
150      *
151      * @param[in] aPropKey             The property key to filter.
152      * @param[in] aEnable              TRUE to enable filtering, FALSE to disable.
153      *
154      * @retval OT_ERROR_NONE           Filter state for given property updated successfully.
155      * @retval OT_ERROR_INVALID_ARGS   The given property is not valid (i.e., not capable of unsolicited update).
156      */
157     otError EnablePropertyFilter(spinel_prop_key_t aPropKey, bool aEnable);
158 
159     /**
160      * Determines whether filtering is enabled for an entry associated with an index.
161      *
162      * @param[in] aIndex               Index of entry to be checked.
163      *
164      * @returns TRUE if the filter is enabled for the given entry, FALSE otherwise.
165      */
IsEntryFiltered(uint8_t aIndex) const166     bool IsEntryFiltered(uint8_t aIndex) const { return IsBitSet(mFilterSet, aIndex); }
167 
168     /**
169      * Determines whether filtering is enabled for a given property key.
170      *
171      * @param[in] aPropKey             The property key to check.
172      *
173      * @returns TRUE if the filter is enabled for the given property, FALSE if the property is not filtered or if
174      *          it is not filterable.
175      */
176     bool IsPropertyFiltered(spinel_prop_key_t aPropKey) const;
177 
178     /**
179      * Clears the filter.
180      */
ClearFilter(void)181     void ClearFilter(void) { mFilterSet = 0; }
182 
183 private:
184     uint8_t GetNumEntries(void) const;
185     void    Add(spinel_prop_key_t aPropKey, spinel_status_t aStatus);
186 
SetBit(uint64_t & aBitset,uint8_t aBitIndex)187     static void SetBit(uint64_t &aBitset, uint8_t aBitIndex) { aBitset |= (1ULL << aBitIndex); }
ClearBit(uint64_t & aBitset,uint8_t aBitIndex)188     static void ClearBit(uint64_t &aBitset, uint8_t aBitIndex) { aBitset &= ~(1ULL << aBitIndex); }
IsBitSet(uint64_t aBitset,uint8_t aBitIndex)189     static bool IsBitSet(uint64_t aBitset, uint8_t aBitIndex) { return (aBitset & (1ULL << aBitIndex)) != 0; }
190 
191     static const Entry mSupportedProps[];
192 
193     uint64_t mChangedSet;
194     uint64_t mFilterSet;
195 };
196 
197 } // namespace Ncp
198 } // namespace ot
199 
200 #endif // CHANGED_PROPS_SET_HPP
201