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 */ 53 class ChangedPropsSet 54 { 55 public: 56 /** 57 * Defines an entry in the set/list. 58 * 59 */ 60 struct Entry 61 { 62 spinel_prop_key_t mPropKey; ///< The spinel property key. 63 spinel_status_t mStatus; ///< The spinel status (used only if prop key is `LAST_STATUS`). 64 bool mFilterable; ///< Indicates whether the entry can be filtered 65 }; 66 67 /** 68 * Initializes the set. 69 * 70 */ ChangedPropsSet(void)71 ChangedPropsSet(void) 72 : mChangedSet(0) 73 , mFilterSet(0) 74 { 75 } 76 77 /** 78 * Clears the set. 79 * 80 */ Clear(void)81 void Clear(void) { mChangedSet = 0; } 82 83 /** 84 * Indicates if the set is empty or not. 85 * 86 * @returns TRUE if the set if empty, FALSE otherwise. 87 * 88 */ IsEmpty(void) const89 bool IsEmpty(void) const { return (mChangedSet == 0); } 90 91 /** 92 * Adds a property to the set. The property added must be in the list of supported properties 93 * capable of sending unsolicited update, otherwise the input is ignored. 94 * 95 * Note that if the property is already in the set, adding it again does not change the set. 96 * 97 * @param[in] aPropKey The spinel property key to be added to the set 98 * 99 */ AddProperty(spinel_prop_key_t aPropKey)100 void AddProperty(spinel_prop_key_t aPropKey) { Add(aPropKey, SPINEL_STATUS_OK); } 101 102 /** 103 * Adds a `LAST_STATUS` update to the set. The update must be in list of supported entries. 104 * 105 * @param[in] aStatus The spinel status update to be added to set. 106 * 107 */ AddLastStatus(spinel_status_t aStatus)108 void AddLastStatus(spinel_status_t aStatus) { Add(SPINEL_PROP_LAST_STATUS, aStatus); } 109 110 /** 111 * Returns a pointer to array of entries of supported property/status updates. The list includes 112 * all properties that can generate unsolicited update. 113 * 114 * @param[out] aNumEntries A reference to output the number of entries in the list. 115 * 116 * @returns A pointer to the supported entries array. 117 * 118 */ GetSupportedEntries(uint8_t & aNumEntries) const119 const Entry *GetSupportedEntries(uint8_t &aNumEntries) const 120 { 121 aNumEntries = GetNumEntries(); 122 return &mSupportedProps[0]; 123 } 124 125 /** 126 * Returns a pointer to the entry associated with a given index. 127 * 128 * @param[in] aIndex The index to an entry. 129 * 130 * @returns A pointer to the entry associated with @p aIndex, or nullptr if the index is beyond end of array. 131 * 132 */ GetEntry(uint8_t aIndex) const133 const Entry *GetEntry(uint8_t aIndex) const 134 { 135 return (aIndex < GetNumEntries()) ? &mSupportedProps[aIndex] : nullptr; 136 } 137 138 /** 139 * Indicates if the entry associated with an index is in the set (i.e., it has been changed and 140 * requires an unsolicited update). 141 * 142 * @param[in] aIndex The index to an entry. 143 * 144 * @returns TRUE if the entry is in the set, FALSE otherwise. 145 * 146 */ IsEntryChanged(uint8_t aIndex) const147 bool IsEntryChanged(uint8_t aIndex) const { return IsBitSet(mChangedSet, aIndex); } 148 149 /** 150 * Removes an entry associated with an index in the set. 151 * 152 * Note that if the property/entry is not in the set, removing it simply does nothing. 153 * 154 * @param[in] aIndex Index of entry to be removed. 155 * 156 */ RemoveEntry(uint8_t aIndex)157 void RemoveEntry(uint8_t aIndex) { ClearBit(mChangedSet, aIndex); } 158 159 /** 160 * Enables/disables filtering of a given property. 161 * 162 * @param[in] aPropKey The property key to filter. 163 * @param[in] aEnable TRUE to enable filtering, FALSE to disable. 164 * 165 * @retval OT_ERROR_NONE Filter state for given property updated successfully. 166 * @retval OT_ERROR_INVALID_ARGS The given property is not valid (i.e., not capable of unsolicited update). 167 * 168 */ 169 otError EnablePropertyFilter(spinel_prop_key_t aPropKey, bool aEnable); 170 171 /** 172 * Determines whether filtering is enabled for an entry associated with an index. 173 * 174 * @param[in] aIndex Index of entry to be checked. 175 * 176 * @returns TRUE if the filter is enabled for the given entry, FALSE otherwise. 177 * 178 */ IsEntryFiltered(uint8_t aIndex) const179 bool IsEntryFiltered(uint8_t aIndex) const { return IsBitSet(mFilterSet, aIndex); } 180 181 /** 182 * Determines whether filtering is enabled for a given property key. 183 * 184 * @param[in] aPropKey The property key to check. 185 * 186 * @returns TRUE if the filter is enabled for the given property, FALSE if the property is not filtered or if 187 * it is not filterable. 188 * 189 */ 190 bool IsPropertyFiltered(spinel_prop_key_t aPropKey) const; 191 192 /** 193 * Clears the filter. 194 * 195 */ ClearFilter(void)196 void ClearFilter(void) { mFilterSet = 0; } 197 198 private: 199 uint8_t GetNumEntries(void) const; 200 void Add(spinel_prop_key_t aPropKey, spinel_status_t aStatus); 201 SetBit(uint64_t & aBitset,uint8_t aBitIndex)202 static void SetBit(uint64_t &aBitset, uint8_t aBitIndex) { aBitset |= (1ULL << aBitIndex); } ClearBit(uint64_t & aBitset,uint8_t aBitIndex)203 static void ClearBit(uint64_t &aBitset, uint8_t aBitIndex) { aBitset &= ~(1ULL << aBitIndex); } IsBitSet(uint64_t aBitset,uint8_t aBitIndex)204 static bool IsBitSet(uint64_t aBitset, uint8_t aBitIndex) { return (aBitset & (1ULL << aBitIndex)) != 0; } 205 206 static const Entry mSupportedProps[]; 207 208 uint64_t mChangedSet; 209 uint64_t mFilterSet; 210 }; 211 212 } // namespace Ncp 213 } // namespace ot 214 215 #endif // CHANGED_PROPS_SET_HPP 216