1 /* 2 * Copyright (c) 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" 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 locator class for OpenThread objects. 32 */ 33 34 #ifndef LOCATOR_HPP_ 35 #define LOCATOR_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <openthread/platform/toolchain.h> 40 41 #include <stdint.h> 42 43 namespace ot { 44 45 class Instance; 46 47 #if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE 48 extern uint64_t gInstanceRaw[]; 49 #endif 50 51 /** 52 * @addtogroup core-locator 53 * 54 * @brief 55 * This module includes definitions for OpenThread instance locator. 56 * 57 * @{ 58 * 59 */ 60 61 /** 62 * Implements `Get<Type>()` method for different `Type` objects belonging to the OpenThread 63 * instance. 64 * 65 * Users of this class MUST follow CRTP-style inheritance, i.e., the class `Class` itself should publicly inherit 66 * from `GetProvider<Class>`. 67 * 68 * @tparam InstanceGetProvider The template sub-lass used in CRTP style inheritance. 69 * `InstanceGetProvider` MUST provide a method with the following signature: 70 * `Instance &GetInstance(void) const` 71 * 72 */ 73 template <class InstanceGetProvider> class GetProvider 74 { 75 public: 76 /** 77 * Returns a reference to a given `Type` object belonging to the OpenThread instance. 78 * 79 * For example, `Get<MeshForwarder>()` returns a reference to the `MeshForwarder` object of the instance. 80 * 81 * Note that any `Type` for which the `Get<Type>` is defined MUST be uniquely accessible from the OpenThread 82 * `Instance` through the member variable property hierarchy. 83 * 84 * @returns A reference to the `Type` object of the instance. 85 * 86 */ 87 template <typename Type> inline Type &Get(void) const; // Implemented in `locator_getters.hpp`. 88 89 protected: 90 GetProvider(void) = default; 91 }; 92 93 /** 94 * Implements a locator for an OpenThread Instance object. 95 * 96 * The `InstanceLocator` is used as base class of almost all other OpenThread classes. It provides a way for an object 97 * to get to its owning/parent OpenThread `Instance` and also any other `Type` within the `Instance` member variable 98 * property hierarchy (using `Get<Type>()` method). 99 * 100 * If multiple-instance feature is supported, the owning/parent OpenThread `Instance` is tracked as a reference. In the 101 * single-instance case, this class becomes an empty base class. 102 * 103 */ 104 class InstanceLocator : public GetProvider<InstanceLocator> 105 { 106 friend class InstanceLocatorInit; 107 108 public: 109 /** 110 * Returns a reference to the parent OpenThread Instance. 111 * 112 * @returns A reference to the parent otInstance. 113 * 114 */ 115 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE GetInstance(void) const116 Instance &GetInstance(void) const { return *mInstance; } 117 #else 118 Instance &GetInstance(void) const { return *reinterpret_cast<Instance *>(&gInstanceRaw); } 119 #endif 120 121 protected: 122 /** 123 * Initializes the object. 124 * 125 * @param[in] aInstance A reference to the OpenThread Instance. 126 * 127 */ InstanceLocator(Instance & aInstance)128 explicit InstanceLocator(Instance &aInstance) 129 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE 130 : mInstance(&aInstance) 131 #endif 132 { 133 OT_UNUSED_VARIABLE(aInstance); 134 } 135 136 private: 137 InstanceLocator(void) = default; 138 139 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE 140 Instance *mInstance; 141 #endif 142 }; 143 144 /** 145 * Implements a locator for an OpenThread Instance object. 146 * 147 * The `InstanceLocatorInit` is similar to `InstanceLocator` but provides a default constructor (instead of a 148 * parameterized one) and allows an inheriting class to initialize the object (set the OpenThread Instance) post 149 * constructor call using the `Init()` method. This class is intended for types that require a default constructor and 150 * cannot use a parameterized one. (e.g., `Neighbor`/`Child`/`Router` classes which are used as a C array element type 151 * in`ChildTable`/`RouterTable`). 152 * 153 * The inheriting class from `InstanceLocatorInit` should ensure that object is properly initialized after the object 154 * is created and more importantly that it is re-initialized when/if it is cleared or reset. 155 * 156 */ 157 class InstanceLocatorInit : public InstanceLocator 158 { 159 protected: 160 /** 161 * This is the default constructor for the `InstanceLocatorInit` object. 162 * 163 */ InstanceLocatorInit(void)164 InstanceLocatorInit(void) 165 : InstanceLocator() 166 { 167 } 168 169 /** 170 * This method (re)initializes the object and sets the OpenThread Instance. 171 * 172 * @param[in] aInstance A reference to the OpenThread Instance. 173 */ Init(Instance & aInstance)174 void Init(Instance &aInstance) 175 { 176 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE 177 mInstance = &aInstance; 178 #endif 179 OT_UNUSED_VARIABLE(aInstance); 180 } 181 }; 182 183 /** 184 * @} 185 * 186 */ 187 188 } // namespace ot 189 190 #endif // LOCATOR_HPP_ 191