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