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