[scheduler] move schedulers into otInstance (#1997)

diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp
index d0c17c9..e35b311 100644
--- a/src/cli/cli.cpp
+++ b/src/cli/cli.cpp
@@ -244,7 +244,7 @@
     mLength(8),
     mCount(1),
     mInterval(1000),
-    mPingTimer(aInstance->mIp6, &Interpreter::s_HandlePingTimer, this),
+    mPingTimer(aInstance, &Interpreter::s_HandlePingTimer, this),
 #if OPENTHREAD_ENABLE_DNS_CLIENT
     mResolvingInProgress(0),
 #endif
diff --git a/src/core/api/instance_api.cpp b/src/core/api/instance_api.cpp
index 60987ec..0fde741 100644
--- a/src/core/api/instance_api.cpp
+++ b/src/core/api/instance_api.cpp
@@ -66,7 +66,7 @@
 
 ot::TaskletScheduler &otGetTaskletScheduler(void)
 {
-    return sInstance->mIp6.mTaskletScheduler;
+    return sInstance->mTaskletScheduler;
 }
 
 ot::Ip6::Ip6 &otGetIp6(void)
@@ -82,6 +82,10 @@
     mActiveScanCallbackContext(NULL),
     mEnergyScanCallback(NULL),
     mEnergyScanCallbackContext(NULL),
+    mTimerMilliScheduler(this),
+#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
+    mTimerMicroScheduler(this),
+#endif
     mThreadNetif(mIp6)
 #if OPENTHREAD_ENABLE_RAW_LINK_API
     , mLinkRaw(*this)
diff --git a/src/core/api/link_raw_api.cpp b/src/core/api/link_raw_api.cpp
index 558be9f..ee1c986 100644
--- a/src/core/api/link_raw_api.cpp
+++ b/src/core/api/link_raw_api.cpp
@@ -269,14 +269,14 @@
     mTransmitDoneCallback(NULL),
     mEnergyScanDoneCallback(NULL)
 #if OPENTHREAD_LINKRAW_TIMER_REQUIRED
-    , mTimer(aInstance.mIp6, &LinkRaw::HandleTimer, this)
+    , mTimer(&aInstance, &LinkRaw::HandleTimer, this)
     , mTimerReason(kTimerReasonNone)
 #if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
-    , mTimerMicro(aInstance.mIp6, &LinkRaw::HandleTimer, this)
+    , mTimerMicro(&aInstance, &LinkRaw::HandleTimer, this)
 #endif
 #endif // OPENTHREAD_LINKRAW_TIMER_REQUIRED
 #if OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN
-    , mEnergyScanTask(aInstance.mIp6.mTaskletScheduler, &LinkRaw::HandleEnergyScanTask, this)
+    , mEnergyScanTask(&aInstance, &LinkRaw::HandleEnergyScanTask, this)
 #endif // OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN
 {
     // Query the capabilities to check asserts
diff --git a/src/core/api/tasklet_api.cpp b/src/core/api/tasklet_api.cpp
index 39f53f4..20d5b27 100644
--- a/src/core/api/tasklet_api.cpp
+++ b/src/core/api/tasklet_api.cpp
@@ -44,13 +44,13 @@
 void otTaskletsProcess(otInstance *aInstance)
 {
     otLogFuncEntry();
-    aInstance->mIp6.mTaskletScheduler.ProcessQueuedTasklets();
+    aInstance->mTaskletScheduler.ProcessQueuedTasklets();
     otLogFuncExit();
 }
 
 bool otTaskletsArePending(otInstance *aInstance)
 {
-    return aInstance->mIp6.mTaskletScheduler.AreTaskletsPending();
+    return aInstance->mTaskletScheduler.AreTaskletsPending();
 }
 
 #ifndef _MSC_VER
diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp
index 2fd2cfa..c7e0d3a 100644
--- a/src/core/coap/coap.cpp
+++ b/src/core/coap/coap.cpp
@@ -52,7 +52,7 @@
 Coap::Coap(ThreadNetif &aNetif):
     ThreadNetifLocator(aNetif),
     mSocket(aNetif.GetIp6().mUdp),
-    mRetransmissionTimer(aNetif.GetIp6(), &Coap::HandleRetransmissionTimer, this),
+    mRetransmissionTimer(aNetif.GetInstance(), &Coap::HandleRetransmissionTimer, this),
     mResources(NULL),
     mContext(NULL),
     mInterceptor(NULL),
@@ -761,7 +761,7 @@
 }
 
 ResponsesQueue::ResponsesQueue(ThreadNetif &aNetif):
-    mTimer(aNetif.GetIp6(), &ResponsesQueue::HandleTimer, this)
+    mTimer(aNetif.GetInstance(), &ResponsesQueue::HandleTimer, this)
 {
 }
 
diff --git a/src/core/coap/coap_secure.cpp b/src/core/coap/coap_secure.cpp
index e117639..01ebadc 100644
--- a/src/core/coap/coap_secure.cpp
+++ b/src/core/coap/coap_secure.cpp
@@ -53,7 +53,7 @@
     mTransportCallback(NULL),
     mTransportContext(NULL),
     mTransmitMessage(NULL),
-    mTransmitTask(aNetif.GetIp6().mTaskletScheduler, &CoapSecure::HandleUdpTransmit, this)
+    mTransmitTask(aNetif.GetInstance(), &CoapSecure::HandleUdpTransmit, this)
 {
 }
 
diff --git a/src/core/common/locator.cpp b/src/core/common/locator.cpp
index 1662270..1daa80f 100644
--- a/src/core/common/locator.cpp
+++ b/src/core/common/locator.cpp
@@ -54,11 +54,6 @@
     return otInstanceFromThreadNetif(&GetMeshForwarder().GetNetif());
 }
 
-otInstance *TaskletSchedulerLocator::GetInstance(void) const
-{
-    return otInstanceFromIp6(Ip6::Ip6FromTaskletScheduler(&GetTaskletScheduler()));
-}
-
 otInstance *Ip6Locator::GetInstance(void) const
 {
     return otInstanceFromIp6(&GetIp6());
diff --git a/src/core/common/locator.hpp b/src/core/common/locator.hpp
index e65524b..d4c85aa 100644
--- a/src/core/common/locator.hpp
+++ b/src/core/common/locator.hpp
@@ -168,47 +168,6 @@
 };
 
 /**
- * This class implements a locator for TaskletScheduler object.
- *
- */
-class TaskletSchedulerLocator: private Locator<TaskletScheduler>
-{
-public:
-    /**
-     * This method returns a reference to the TaskletScheduler.
-     *
-     * @returns   A reference to the TaskletScheduler.
-     *
-     */
-#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
-    TaskletScheduler &GetTaskletScheduler(void) const { return mLocatorObject; }
-#else
-    TaskletScheduler &GetTaskletScheduler(void) const { return otGetTaskletScheduler(); }
-#endif
-
-    /**
-     * This method returns the pointer to the parent otInstance structure.
-     *
-     * @returns The pointer to the parent otInstance structure, or NULL if the instance has been finalized.
-     *
-     */
-#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
-    otInstance *GetInstance(void) const;
-#else
-    otInstance *GetInstance(void) const { return otGetInstance(); }
-#endif
-
-protected:
-    /**
-     * This constructor initializes the object.
-     *
-     * @param[in]  aTaskletScheduler  A reference to the TaskletScheduler.
-     *
-     */
-    TaskletSchedulerLocator(TaskletScheduler &aTaskletScheduler): Locator(aTaskletScheduler) { }
-};
-
-/**
  * This class implements a locator for Ip6 object.
  *
  */
diff --git a/src/core/common/tasklet.cpp b/src/core/common/tasklet.cpp
index 08ad90c..44e1da6 100644
--- a/src/core/common/tasklet.cpp
+++ b/src/core/common/tasklet.cpp
@@ -44,8 +44,8 @@
 
 namespace ot {
 
-Tasklet::Tasklet(TaskletScheduler &aScheduler, Handler aHandler, void *aContext):
-    TaskletSchedulerLocator(aScheduler),
+Tasklet::Tasklet(otInstance *aInstance, Handler aHandler, void *aContext):
+    InstanceLocator(aInstance),
     Context(aContext),
     mHandler(aHandler),
     mNext(NULL)
@@ -54,7 +54,7 @@
 
 otError Tasklet::Post(void)
 {
-    return GetTaskletScheduler().Post(*this);
+    return GetInstance()->mTaskletScheduler.Post(*this);
 }
 
 TaskletScheduler::TaskletScheduler(void):
diff --git a/src/core/common/tasklet.hpp b/src/core/common/tasklet.hpp
index 68fb029..3d39d6b 100644
--- a/src/core/common/tasklet.hpp
+++ b/src/core/common/tasklet.hpp
@@ -59,7 +59,7 @@
  * This class is used to represent a tasklet.
  *
  */
-class Tasklet: public TaskletSchedulerLocator, public Context
+class Tasklet: public InstanceLocator, public Context
 {
     friend class TaskletScheduler;
 
@@ -75,12 +75,12 @@
     /**
      * This constructor creates a tasklet instance.
      *
-     * @param[in]  aScheduler  A reference to the tasklet scheduler.
+     * @param[in]  aInstance   A pointer to the instance object.
      * @param[in]  aHandler    A pointer to a function that is called when the tasklet is run.
      * @param[in]  aContext    A pointer to arbitrary context information.
      *
      */
-    Tasklet(TaskletScheduler &aScheduler, Handler aHandler, void *aContext);
+    Tasklet(otInstance *aInstance, Handler aHandler, void *aContext);
 
     /**
      * This method puts the tasklet on the run queue.
diff --git a/src/core/common/timer.cpp b/src/core/common/timer.cpp
index d83d2e7..d50c788 100644
--- a/src/core/common/timer.cpp
+++ b/src/core/common/timer.cpp
@@ -41,7 +41,6 @@
 #include "common/code_utils.hpp"
 #include "common/debug.hpp"
 #include "common/logging.hpp"
-#include "net/ip6.hpp"
 
 namespace ot {
 
@@ -90,7 +89,7 @@
 
 TimerMilliScheduler &TimerMilli::GetTimerMilliScheduler(void) const
 {
-    return GetIp6().mTimerMilliScheduler;
+    return GetInstance()->mTimerMilliScheduler;
 }
 
 void TimerScheduler::Add(Timer &aTimer, const AlarmApi &aAlarmApi)
@@ -169,14 +168,14 @@
 {
     if (mHead == NULL)
     {
-        aAlarmApi.AlarmStop(GetIp6().GetInstance());
+        aAlarmApi.AlarmStop(GetInstance());
     }
     else
     {
         uint32_t now = aAlarmApi.AlarmGetNow();
         uint32_t remaining = IsStrictlyBefore(now, mHead->mFireTime) ? (mHead->mFireTime - now) : 0;
 
-        aAlarmApi.AlarmStartAt(GetIp6().GetInstance(), now, remaining);
+        aAlarmApi.AlarmStartAt(GetInstance(), now, remaining);
     }
 }
 
@@ -217,7 +216,7 @@
 extern "C" void otPlatAlarmMilliFired(otInstance *aInstance)
 {
     otLogFuncEntry();
-    aInstance->mIp6.mTimerMilliScheduler.ProcessTimers();
+    aInstance->mTimerMilliScheduler.ProcessTimers();
     otLogFuncExit();
 }
 
@@ -243,13 +242,13 @@
 
 TimerMicroScheduler &TimerMicro::GetTimerMicroScheduler(void) const
 {
-    return GetIp6().mTimerMicroScheduler;
+    return GetInstance()->mTimerMicroScheduler;
 }
 
 extern "C" void otPlatAlarmMicroFired(otInstance *aInstance)
 {
     otLogFuncEntry();
-    aInstance->mIp6.mTimerMicroScheduler.ProcessTimers();
+    aInstance->mTimerMicroScheduler.ProcessTimers();
     otLogFuncExit();
 }
 #endif // OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
diff --git a/src/core/common/timer.hpp b/src/core/common/timer.hpp
index 57492e8..cce2086 100644
--- a/src/core/common/timer.hpp
+++ b/src/core/common/timer.hpp
@@ -48,8 +48,6 @@
 
 namespace ot {
 
-namespace Ip6 { class Ip6; }
-
 class TimerMilliScheduler;
 
 /**
@@ -66,7 +64,7 @@
  * This class implements a timer.
  *
  */
-class Timer: public Ip6Locator, public Context
+class Timer: public InstanceLocator, public Context
 {
     friend class TimerScheduler;
 
@@ -88,13 +86,13 @@
     /**
      * This constructor creates a timer instance.
      *
-     * @param[in]  aIp6        A reference to the IPv6 network object.
+     * @param[in]  aInstance   A pointer to the instance.
      * @param[in]  aHandler    A pointer to a function that is called when the timer expires.
      * @param[in]  aContext    A pointer to arbitrary context information.
      *
      */
-    Timer(Ip6::Ip6 &aIp6, Handler aHandler, void *aContext):
-        Ip6Locator(aIp6),
+    Timer(otInstance *aInstance, Handler aHandler, void *aContext):
+        InstanceLocator(aInstance),
         Context(aContext),
         mHandler(aHandler),
         mFireTime(0),
@@ -148,13 +146,13 @@
     /**
      * This constructor creates a millisecond timer instance.
      *
-     * @param[in]  aIp6        A reference to the IPv6 network object.
+     * @param[in]  aInstance   A pointer to the instance.
      * @param[in]  aHandler    A pointer to a function that is called when the timer expires.
      * @param[in]  aContext    A pointer to arbitrary context information.
      *
      */
-    TimerMilli(Ip6::Ip6 &aIp6, Handler aHandler, void *aContext):
-        Timer(aIp6, aHandler, aContext) {
+    TimerMilli(otInstance *aInstance, Handler aHandler, void *aContext):
+        Timer(aInstance, aHandler, aContext) {
     }
 
     /**
@@ -221,7 +219,7 @@
  * This class implements the base timer scheduler.
  *
  */
-class TimerScheduler: public Ip6Locator
+class TimerScheduler: public InstanceLocator
 {
     friend class Timer;
 
@@ -240,11 +238,11 @@
     /**
      * This constructor initializes the object.
      *
-     * @param[in]  aIp6  A reference to the IPv6 network object.
+     * @param[in]  aInstance  A pointer to the instance object.
      *
      */
-    TimerScheduler(Ip6::Ip6 &aIp6):
-        Ip6Locator(aIp6),
+    TimerScheduler(otInstance *aInstance):
+        InstanceLocator(aInstance),
         mHead(NULL) {
     }
 
@@ -310,11 +308,11 @@
     /**
      * This constructor initializes the object.
      *
-     * @param[in]  aIp6  A reference to the IPv6 network object.
+     * @param[in]  aInstance  A pointer to the instance object.
      *
      */
-    TimerMilliScheduler(Ip6::Ip6 &aIp6):
-        TimerScheduler(aIp6) {
+    TimerMilliScheduler(otInstance *aInstance):
+        TimerScheduler(aInstance) {
     }
 
     /**
@@ -356,13 +354,13 @@
     /**
      * This constructor creates a timer instance.
      *
-     * @param[in]  aIp6        A reference to the IPv6 network object.
+     * @param[in]  aInstance   A pointer to the instance object.
      * @param[in]  aHandler    A pointer to a function that is called when the timer expires.
      * @param[in]  aContext    A pointer to arbitrary context information.
      *
      */
-    TimerMicro(Ip6::Ip6 &aIp6, Handler aHandler, void *aContext):
-        Timer(aIp6, aHandler, aContext) {
+    TimerMicro(otInstance *aInstance, Handler aHandler, void *aContext):
+        Timer(aInstance, aHandler, aContext) {
     }
 
     /**
@@ -418,11 +416,11 @@
     /**
      * This constructor initializes the object.
      *
-     * @param[in]  aIp6  A reference to the IPv6 network object.
+     * @param[in]  aInstance  A pointer to the instance object.
      *
      */
-    TimerMicroScheduler(Ip6::Ip6 &aIp6):
-        TimerScheduler(aIp6) {
+    TimerMicroScheduler(otInstance *aInstance):
+        TimerScheduler(aInstance) {
     }
 
     /**
diff --git a/src/core/common/trickle_timer.cpp b/src/core/common/trickle_timer.cpp
index 79e878e..ef82804 100644
--- a/src/core/common/trickle_timer.cpp
+++ b/src/core/common/trickle_timer.cpp
@@ -37,20 +37,19 @@
 
 #include <openthread/platform/random.h>
 
-#include "openthread-instance.h"
 #include "common/code_utils.hpp"
 #include "common/debug.hpp"
 
 namespace ot {
 
 TrickleTimer::TrickleTimer(
-    Ip6::Ip6 &aIp6,
+    otInstance *aInstance,
 #ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
     uint32_t aRedundancyConstant,
 #endif
     Handler aTransmitHandler, Handler aIntervalExpiredHandler, void *aContext)
     :
-    TimerMilli(aIp6, HandleTimerFired, aContext),
+    TimerMilli(aInstance, HandleTimerFired, aContext),
 #ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
     k(aRedundancyConstant),
     c(0),
diff --git a/src/core/common/trickle_timer.hpp b/src/core/common/trickle_timer.hpp
index 5c812d5..10e4cc0 100644
--- a/src/core/common/trickle_timer.hpp
+++ b/src/core/common/trickle_timer.hpp
@@ -80,14 +80,14 @@
     /**
      * This constructor creates a trickle timer instance.
      *
-     * @param[in]  aIp6                     A reference to the IPv6 network object.
+     * @param[in]  aInstance                A pointer to the instance.
      * @param[in]  aRedundancyConstant      The redundancy constant for the timer, k.
      * @param[in]  aTransmitHandler         A pointer to a function that is called when transmission should occur.
      * @param[in]  aIntervalExpiredHandler  An optional pointer to a function that is called when the interval expires.
      * @param[in]  aContext                 A pointer to arbitrary context information.
      *
      */
-    TrickleTimer(Ip6::Ip6 &aIp6,
+    TrickleTimer(otInstance *aInstance,
 #ifdef ENABLE_TRICKLE_TIMER_SUPPRESSION_SUPPORT
                  uint32_t aRedundancyConstant,
 #endif
diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp
index 384cc2a..d259ac5 100644
--- a/src/core/mac/mac.cpp
+++ b/src/core/mac/mac.cpp
@@ -107,9 +107,9 @@
 
 Mac::Mac(ThreadNetif &aThreadNetif):
     ThreadNetifLocator(aThreadNetif),
-    mMacTimer(aThreadNetif.GetIp6(), &Mac::HandleMacTimer, this),
-    mBackoffTimer(aThreadNetif.GetIp6(), &Mac::HandleBeginTransmit, this),
-    mReceiveTimer(aThreadNetif.GetIp6(), &Mac::HandleReceiveTimer, this),
+    mMacTimer(aThreadNetif.GetInstance(), &Mac::HandleMacTimer, this),
+    mBackoffTimer(aThreadNetif.GetInstance(), &Mac::HandleBeginTransmit, this),
+    mReceiveTimer(aThreadNetif.GetInstance(), &Mac::HandleReceiveTimer, this),
     mShortAddress(kShortAddrInvalid),
     mPanId(kPanIdBroadcast),
     mChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL),
@@ -133,7 +133,7 @@
     mScanContext(NULL),
     mActiveScanHandler(NULL), // initialize mActiveScanHandler and mEnergyScanHandler union
     mEnergyScanCurrentMaxRssi(kInvalidRssiValue),
-    mEnergyScanSampleRssiTask(aThreadNetif.GetIp6().mTaskletScheduler, &Mac::HandleEnergyScanSampleRssi, this),
+    mEnergyScanSampleRssiTask(aThreadNetif.GetInstance(), &Mac::HandleEnergyScanSampleRssi, this),
     mPcapCallback(NULL),
     mPcapCallbackContext(NULL),
 #if OPENTHREAD_ENABLE_MAC_FILTER
diff --git a/src/core/meshcop/commissioner.cpp b/src/core/meshcop/commissioner.cpp
index edbfbad..06c6ba4 100644
--- a/src/core/meshcop/commissioner.cpp
+++ b/src/core/meshcop/commissioner.cpp
@@ -70,8 +70,8 @@
     mState(OT_COMMISSIONER_STATE_DISABLED),
     mJoinerPort(0),
     mJoinerRloc(0),
-    mJoinerExpirationTimer(aThreadNetif.GetIp6(), HandleJoinerExpirationTimer, this),
-    mTimer(aThreadNetif.GetIp6(), HandleTimer, this),
+    mJoinerExpirationTimer(aThreadNetif.GetInstance(), HandleJoinerExpirationTimer, this),
+    mTimer(aThreadNetif.GetInstance(), HandleTimer, this),
     mSessionId(0),
     mTransmitAttempts(0),
     mRelayReceive(OT_URI_PATH_RELAY_RX, &Commissioner::HandleRelayReceive, this),
diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp
index c1d871c..c885c08 100644
--- a/src/core/meshcop/dataset_manager.cpp
+++ b/src/core/meshcop/dataset_manager.cpp
@@ -66,7 +66,7 @@
     ThreadNetifLocator(aThreadNetif),
     mLocal(aThreadNetif.GetInstance(), aType),
     mNetwork(aType),
-    mTimer(aThreadNetif.GetIp6(), aTimerHander, this),
+    mTimer(aThreadNetif.GetInstance(), aTimerHander, this),
     mUriSet(aUriSet),
     mUriGet(aUriGet)
 {
@@ -1022,7 +1022,7 @@
 PendingDatasetBase::PendingDatasetBase(ThreadNetif &aThreadNetif):
     DatasetManager(aThreadNetif, Tlv::kPendingTimestamp, OT_URI_PATH_PENDING_SET, OT_URI_PATH_PENDING_GET,
                    &PendingDatasetBase::HandleTimer),
-    mDelayTimer(aThreadNetif.GetIp6(), &PendingDatasetBase::HandleDelayTimer, this),
+    mDelayTimer(aThreadNetif.GetInstance(), &PendingDatasetBase::HandleDelayTimer, this),
     mResourceGet(OT_URI_PATH_PENDING_GET, &PendingDatasetBase::HandleGet, this)
 {
     aThreadNetif.GetCoap().AddResource(mResourceGet);
diff --git a/src/core/meshcop/dtls.cpp b/src/core/meshcop/dtls.cpp
index 73d064c..d94153a 100644
--- a/src/core/meshcop/dtls.cpp
+++ b/src/core/meshcop/dtls.cpp
@@ -57,7 +57,7 @@
     ThreadNetifLocator(aNetif),
     mPskLength(0),
     mStarted(false),
-    mTimer(aNetif.GetIp6(), &Dtls::HandleTimer, this),
+    mTimer(aNetif.GetInstance(), &Dtls::HandleTimer, this),
     mTimerIntermediate(0),
     mTimerSet(false),
     mReceiveMessage(NULL),
diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp
index c8a68d1..74eeef8 100644
--- a/src/core/meshcop/joiner.cpp
+++ b/src/core/meshcop/joiner.cpp
@@ -74,7 +74,7 @@
     mVendorModel(NULL),
     mVendorSwVersion(NULL),
     mVendorData(NULL),
-    mTimer(aNetif.GetIp6(), &Joiner::HandleTimer, this),
+    mTimer(aNetif.GetInstance(), &Joiner::HandleTimer, this),
     mJoinerEntrust(OT_URI_PATH_JOINER_ENTRUST, &Joiner::HandleJoinerEntrust, this)
 {
     aNetif.GetCoap().AddResource(mJoinerEntrust);
diff --git a/src/core/meshcop/joiner_router.cpp b/src/core/meshcop/joiner_router.cpp
index b00f9da..bf21895 100644
--- a/src/core/meshcop/joiner_router.cpp
+++ b/src/core/meshcop/joiner_router.cpp
@@ -61,7 +61,7 @@
     ThreadNetifLocator(aNetif),
     mSocket(aNetif.GetIp6().mUdp),
     mRelayTransmit(OT_URI_PATH_RELAY_TX, &JoinerRouter::HandleRelayTransmit, this),
-    mTimer(aNetif.GetIp6(), &JoinerRouter::HandleTimer, this),
+    mTimer(aNetif.GetInstance(), &JoinerRouter::HandleTimer, this),
     mJoinerUdpPort(0),
     mIsJoinerPortConfigured(false),
     mExpectJoinEntRsp(false)
diff --git a/src/core/meshcop/leader.cpp b/src/core/meshcop/leader.cpp
index de433ac..4e164bb 100644
--- a/src/core/meshcop/leader.cpp
+++ b/src/core/meshcop/leader.cpp
@@ -60,7 +60,7 @@
     ThreadNetifLocator(aThreadNetif),
     mPetition(OT_URI_PATH_LEADER_PETITION, Leader::HandlePetition, this),
     mKeepAlive(OT_URI_PATH_LEADER_KEEP_ALIVE, Leader::HandleKeepAlive, this),
-    mTimer(aThreadNetif.GetIp6(), HandleTimer, this),
+    mTimer(aThreadNetif.GetInstance(), HandleTimer, this),
     mDelayTimerMinimal(DelayTimerTlv::kDelayTimerMinimal),
     mSessionId(0xffff)
 {
diff --git a/src/core/net/dhcp6_client.cpp b/src/core/net/dhcp6_client.cpp
index 44f6ad3..5139ea8 100644
--- a/src/core/net/dhcp6_client.cpp
+++ b/src/core/net/dhcp6_client.cpp
@@ -59,7 +59,7 @@
 
 Dhcp6Client::Dhcp6Client(ThreadNetif &aThreadNetif) :
     ThreadNetifLocator(aThreadNetif),
-    mTrickleTimer(aThreadNetif.GetIp6(), &Dhcp6Client::HandleTrickleTimer, NULL, this),
+    mTrickleTimer(aThreadNetif.GetInstance(), &Dhcp6Client::HandleTrickleTimer, NULL, this),
     mSocket(aThreadNetif.GetIp6().mUdp),
     mStartTime(0),
     mAddresses(NULL),
diff --git a/src/core/net/dns_client.hpp b/src/core/net/dns_client.hpp
index e3fc4a6..b5dba6c 100644
--- a/src/core/net/dns_client.hpp
+++ b/src/core/net/dns_client.hpp
@@ -159,7 +159,7 @@
     Client(Ip6::Netif &aNetif):
         mSocket(aNetif.GetIp6().mUdp),
         mMessageId(0),
-        mRetransmissionTimer(aNetif.GetIp6(), &Client::HandleRetransmissionTimer, this) {
+        mRetransmissionTimer(aNetif.GetInstance(), &Client::HandleRetransmissionTimer, this) {
     };
 
     /**
diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp
index 09de30c..ef33795 100644
--- a/src/core/net/ip6.cpp
+++ b/src/core/net/ip6.cpp
@@ -58,12 +58,8 @@
     mUdp(*this),
     mMpl(*this),
     mMessagePool(GetInstance()),
-    mTimerMilliScheduler(*this),
-#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
-    mTimerMicroScheduler(*this),
-#endif
     mForwardingEnabled(false),
-    mSendQueueTask(mTaskletScheduler, HandleSendQueue, this),
+    mSendQueueTask(GetInstance(), HandleSendQueue, this),
     mReceiveIp6DatagramCallback(NULL),
     mReceiveIp6DatagramCallbackContext(NULL),
     mIsReceiveIp6FilterEnabled(false),
diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp
index abddda7..b9f4b27 100644
--- a/src/core/net/ip6.hpp
+++ b/src/core/net/ip6.hpp
@@ -373,11 +373,6 @@
     Mpl mMpl;
 
     MessagePool mMessagePool;
-    TaskletScheduler mTaskletScheduler;
-    TimerMilliScheduler mTimerMilliScheduler;
-#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
-    TimerMicroScheduler mTimerMicroScheduler;
-#endif
 
 private:
     static void HandleSendQueue(Tasklet &aTasklet);
@@ -410,11 +405,6 @@
     Netif *mNetifListHead;
 };
 
-static inline Ip6 *Ip6FromTaskletScheduler(TaskletScheduler *aTaskletScheduler)
-{
-    return (Ip6 *)CONTAINING_RECORD(aTaskletScheduler, Ip6, mTaskletScheduler);
-}
-
 /**
  * @}
  *
diff --git a/src/core/net/ip6_mpl.cpp b/src/core/net/ip6_mpl.cpp
index b38924e..2bd5ac2 100644
--- a/src/core/net/ip6_mpl.cpp
+++ b/src/core/net/ip6_mpl.cpp
@@ -57,8 +57,8 @@
 
 Mpl::Mpl(Ip6 &aIp6):
     Ip6Locator(aIp6),
-    mSeedSetTimer(aIp6, &Mpl::HandleSeedSetTimer, this),
-    mRetransmissionTimer(aIp6, &Mpl::HandleRetransmissionTimer, this),
+    mSeedSetTimer(aIp6.GetInstance(), &Mpl::HandleSeedSetTimer, this),
+    mRetransmissionTimer(aIp6.GetInstance(), &Mpl::HandleRetransmissionTimer, this),
     mTimerExpirations(0),
     mSequence(0),
     mSeedId(0),
diff --git a/src/core/net/netif.cpp b/src/core/net/netif.cpp
index 6652b19..31a04ba 100644
--- a/src/core/net/netif.cpp
+++ b/src/core/net/netif.cpp
@@ -51,7 +51,7 @@
     mInterfaceId(aInterfaceId),
     mAllRoutersSubscribed(false),
     mMulticastPromiscuous(false),
-    mStateChangedTask(aIp6.mTaskletScheduler, &Netif::HandleStateChangedTask, this),
+    mStateChangedTask(aIp6.GetInstance(), &Netif::HandleStateChangedTask, this),
     mNext(NULL),
     mStateChangedFlags(0)
 {
diff --git a/src/core/openthread-instance.h b/src/core/openthread-instance.h
index 5c4cd89..bc2bd71 100644
--- a/src/core/openthread-instance.h
+++ b/src/core/openthread-instance.h
@@ -78,6 +78,12 @@
     // State
     //
 
+    ot::TaskletScheduler mTaskletScheduler;
+    ot::TimerMilliScheduler mTimerMilliScheduler;
+#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
+    ot::TimerMicroScheduler mTimerMicroScheduler;
+#endif
+
 #if !OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
     ot::Crypto::MbedTls mMbedTls;
     ot::Crypto::Heap    mMbedTlsHeap;
diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp
index 4fe2b83..a363fc3 100644
--- a/src/core/thread/address_resolver.cpp
+++ b/src/core/thread/address_resolver.cpp
@@ -64,7 +64,7 @@
     mAddressQuery(OT_URI_PATH_ADDRESS_QUERY, &AddressResolver::HandleAddressQuery, this),
     mAddressNotification(OT_URI_PATH_ADDRESS_NOTIFY, &AddressResolver::HandleAddressNotification, this),
     mIcmpHandler(&AddressResolver::HandleIcmpReceive, this),
-    mTimer(aThreadNetif.GetIp6(), &AddressResolver::HandleTimer, this)
+    mTimer(aThreadNetif.GetInstance(), &AddressResolver::HandleTimer, this)
 {
     Clear();
 
diff --git a/src/core/thread/announce_begin_server.cpp b/src/core/thread/announce_begin_server.cpp
index 61579c0..688ef1a 100644
--- a/src/core/thread/announce_begin_server.cpp
+++ b/src/core/thread/announce_begin_server.cpp
@@ -58,7 +58,7 @@
     mPeriod(0),
     mCount(0),
     mChannel(0),
-    mTimer(aThreadNetif.GetIp6(), &AnnounceBeginServer::HandleTimer, this),
+    mTimer(aThreadNetif.GetInstance(), &AnnounceBeginServer::HandleTimer, this),
     mAnnounceBegin(OT_URI_PATH_ANNOUNCE_BEGIN, &AnnounceBeginServer::HandleRequest, this)
 {
     aThreadNetif.GetCoap().AddResource(mAnnounceBegin);
diff --git a/src/core/thread/data_poll_manager.cpp b/src/core/thread/data_poll_manager.cpp
index 3867bee..5eb7250 100644
--- a/src/core/thread/data_poll_manager.cpp
+++ b/src/core/thread/data_poll_manager.cpp
@@ -51,7 +51,7 @@
 
 DataPollManager::DataPollManager(MeshForwarder &aMeshForwarder):
     MeshForwarderLocator(aMeshForwarder),
-    mTimer(aMeshForwarder.GetNetif().GetIp6(), &DataPollManager::HandlePollTimer, this),
+    mTimer(aMeshForwarder.GetInstance(), &DataPollManager::HandlePollTimer, this),
     mTimerStartTime(0),
     mExternalPollPeriod(0),
     mPollPeriod(0),
diff --git a/src/core/thread/energy_scan_server.cpp b/src/core/thread/energy_scan_server.cpp
index 2c475d6..5a58d28 100644
--- a/src/core/thread/energy_scan_server.cpp
+++ b/src/core/thread/energy_scan_server.cpp
@@ -59,7 +59,7 @@
     mCount(0),
     mActive(false),
     mScanResultsLength(0),
-    mTimer(aThreadNetif.GetIp6(), &EnergyScanServer::HandleTimer, this),
+    mTimer(aThreadNetif.GetInstance(), &EnergyScanServer::HandleTimer, this),
     mEnergyScan(OT_URI_PATH_ENERGY_SCAN, &EnergyScanServer::HandleRequest, this)
 {
     mNetifCallback.Set(&EnergyScanServer::HandleNetifStateChanged, this);
diff --git a/src/core/thread/key_manager.cpp b/src/core/thread/key_manager.cpp
index da8b727..9f4d51c 100644
--- a/src/core/thread/key_manager.cpp
+++ b/src/core/thread/key_manager.cpp
@@ -61,7 +61,7 @@
     mKeyRotationTime(kDefaultKeyRotationTime),
     mKeySwitchGuardTime(kDefaultKeySwitchGuardTime),
     mKeySwitchGuardEnabled(false),
-    mKeyRotationTimer(aThreadNetif.GetIp6(), &KeyManager::HandleKeyRotationTimer, this),
+    mKeyRotationTimer(aThreadNetif.GetInstance(), &KeyManager::HandleKeyRotationTimer, this),
     mKekFrameCounter(0),
     mSecurityPolicyFlags(0xff)
 {
diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp
index 06b1300..0c37e92 100644
--- a/src/core/thread/mesh_forwarder.cpp
+++ b/src/core/thread/mesh_forwarder.cpp
@@ -62,8 +62,8 @@
     ThreadNetifLocator(aThreadNetif),
     mMacReceiver(&MeshForwarder::HandleReceivedFrame, &MeshForwarder::HandleDataPollTimeout, this),
     mMacSender(&MeshForwarder::HandleFrameRequest, &MeshForwarder::HandleSentFrame, this),
-    mDiscoverTimer(aThreadNetif.GetIp6(), &MeshForwarder::HandleDiscoverTimer, this),
-    mReassemblyTimer(aThreadNetif.GetIp6(), &MeshForwarder::HandleReassemblyTimer, this),
+    mDiscoverTimer(aThreadNetif.GetInstance(), &MeshForwarder::HandleDiscoverTimer, this),
+    mReassemblyTimer(aThreadNetif.GetInstance(), &MeshForwarder::HandleReassemblyTimer, this),
     mMessageNextOffset(0),
     mSendMessageFrameCounter(0),
     mSendMessage(NULL),
@@ -76,7 +76,7 @@
     mMeshDest(Mac::kShortAddrInvalid),
     mAddMeshHeader(false),
     mSendBusy(false),
-    mScheduleTransmissionTask(aThreadNetif.GetIp6().mTaskletScheduler, ScheduleTransmissionTask, this),
+    mScheduleTransmissionTask(aThreadNetif.GetInstance(), ScheduleTransmissionTask, this),
     mEnabled(false),
     mScanChannels(0),
     mScanChannel(0),
diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp
index 99d1bcd..4361762 100644
--- a/src/core/thread/mle.cpp
+++ b/src/core/thread/mle.cpp
@@ -68,8 +68,8 @@
     mDeviceMode(ModeTlv::kModeRxOnWhenIdle | ModeTlv::kModeSecureDataRequest),
     mParentRequestState(kParentIdle),
     mReattachState(kReattachStop),
-    mParentRequestTimer(aThreadNetif.GetIp6(), &Mle::HandleParentRequestTimer, this),
-    mDelayedResponseTimer(aThreadNetif.GetIp6(), &Mle::HandleDelayedResponseTimer, this),
+    mParentRequestTimer(aThreadNetif.GetInstance(), &Mle::HandleParentRequestTimer, this),
+    mDelayedResponseTimer(aThreadNetif.GetInstance(), &Mle::HandleDelayedResponseTimer, this),
     mLastPartitionRouterIdSequence(0),
     mLastPartitionId(0),
     mParentLeaderCost(0),
@@ -82,7 +82,7 @@
     mParentIsSingleton(false),
     mSocket(aThreadNetif.GetIp6().mUdp),
     mTimeout(kMleEndDeviceTimeout),
-    mSendChildUpdateRequest(aThreadNetif.GetIp6().mTaskletScheduler, &Mle::HandleSendChildUpdateRequest, this),
+    mSendChildUpdateRequest(aThreadNetif.GetInstance(), &Mle::HandleSendChildUpdateRequest, this),
     mDiscoverHandler(NULL),
     mDiscoverContext(NULL),
     mIsDiscoverInProgress(false),
diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp
index e17fd58..2e376d1 100644
--- a/src/core/thread/mle_router.cpp
+++ b/src/core/thread/mle_router.cpp
@@ -60,8 +60,8 @@
 
 MleRouter::MleRouter(ThreadNetif &aThreadNetif):
     Mle(aThreadNetif),
-    mAdvertiseTimer(aThreadNetif.GetIp6(), &MleRouter::HandleAdvertiseTimer, NULL, this),
-    mStateUpdateTimer(aThreadNetif.GetIp6(), &MleRouter::HandleStateUpdateTimer, this),
+    mAdvertiseTimer(aThreadNetif.GetInstance(), &MleRouter::HandleAdvertiseTimer, NULL, this),
+    mStateUpdateTimer(aThreadNetif.GetInstance(), &MleRouter::HandleStateUpdateTimer, this),
     mAddressSolicit(OT_URI_PATH_ADDRESS_SOLICIT, &MleRouter::HandleAddressSolicit, this),
     mAddressRelease(OT_URI_PATH_ADDRESS_RELEASE, &MleRouter::HandleAddressRelease, this),
     mRouterIdSequence(0),
diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp
index af14ad5..ff8ef44 100644
--- a/src/core/thread/network_data_leader_ftd.cpp
+++ b/src/core/thread/network_data_leader_ftd.cpp
@@ -63,7 +63,7 @@
 
 Leader::Leader(ThreadNetif &aThreadNetif):
     LeaderBase(aThreadNetif),
-    mTimer(aThreadNetif.GetIp6(), &Leader::HandleTimer, this),
+    mTimer(aThreadNetif.GetInstance(), &Leader::HandleTimer, this),
     mServerData(OT_URI_PATH_SERVER_DATA, &Leader::HandleServerData, this),
     mCommissioningDataGet(OT_URI_PATH_COMMISSIONER_GET, &Leader::HandleCommissioningGet, this),
     mCommissioningDataSet(OT_URI_PATH_COMMISSIONER_SET, &Leader::HandleCommissioningSet, this)
diff --git a/src/core/thread/panid_query_server.cpp b/src/core/thread/panid_query_server.cpp
index 201be78..8dc7439 100644
--- a/src/core/thread/panid_query_server.cpp
+++ b/src/core/thread/panid_query_server.cpp
@@ -55,7 +55,7 @@
     ThreadNetifLocator(aThreadNetif),
     mChannelMask(0),
     mPanId(Mac::kPanIdBroadcast),
-    mTimer(aThreadNetif.GetIp6(), &PanIdQueryServer::HandleTimer, this),
+    mTimer(aThreadNetif.GetInstance(), &PanIdQueryServer::HandleTimer, this),
     mPanIdQuery(OT_URI_PATH_PANID_QUERY, &PanIdQueryServer::HandleQuery, this)
 {
     aThreadNetif.GetCoap().AddResource(mPanIdQuery);
diff --git a/src/core/utils/child_supervision.cpp b/src/core/utils/child_supervision.cpp
index c422cbf..15c6e55 100644
--- a/src/core/utils/child_supervision.cpp
+++ b/src/core/utils/child_supervision.cpp
@@ -52,7 +52,7 @@
 
 ChildSupervisor::ChildSupervisor(ThreadNetif &aThreadNetif) :
     ThreadNetifLocator(aThreadNetif),
-    mTimer(aThreadNetif.GetIp6(), &ChildSupervisor::HandleTimer, this),
+    mTimer(aThreadNetif.GetInstance(), &ChildSupervisor::HandleTimer, this),
     mSupervisionInterval(kDefaultSupervisionInterval)
 {
 }
@@ -183,7 +183,7 @@
 
 SupervisionListener::SupervisionListener(ThreadNetif &aThreadNetif) :
     ThreadNetifLocator(aThreadNetif),
-    mTimer(aThreadNetif.GetIp6(), &SupervisionListener::HandleTimer, this),
+    mTimer(aThreadNetif.GetInstance(), &SupervisionListener::HandleTimer, this),
     mTimeout(0)
 {
     SetTimeout(kDefaultTimeout);
diff --git a/src/core/utils/jam_detector.cpp b/src/core/utils/jam_detector.cpp
index d332dfd..115b142 100644
--- a/src/core/utils/jam_detector.cpp
+++ b/src/core/utils/jam_detector.cpp
@@ -52,7 +52,7 @@
     mHandler(NULL),
     mContext(NULL),
     mRssiThreshold(kDefaultRssiThreshold),
-    mTimer(aNetif.GetIp6(), &JamDetector::HandleTimer, this),
+    mTimer(aNetif.GetInstance(), &JamDetector::HandleTimer, this),
     mHistoryBitmap(0),
     mCurSecondStartTime(0),
     mSampleInterval(0),
diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp
index 5871fc8..a8739b2 100644
--- a/src/ncp/ncp_base.cpp
+++ b/src/ncp/ncp_base.cpp
@@ -666,7 +666,7 @@
     mDiscoveryScanJoinerFlag(false),
     mDiscoveryScanEnableFiltering(false),
     mDiscoveryScanPanId(0xffff),
-    mUpdateChangedPropsTask(aInstance->mIp6.mTaskletScheduler, &NcpBase::UpdateChangedProps, this),
+    mUpdateChangedPropsTask(aInstance, &NcpBase::UpdateChangedProps, this),
     mChangedFlags(NCP_CHANGED_PLATFORM_RESET),
     mShouldSignalEndOfScan(false),
     mHostPowerState(SPINEL_HOST_POWER_STATE_ONLINE),
diff --git a/src/ncp/ncp_spi.cpp b/src/ncp/ncp_spi.cpp
index 4e29194..0273056 100644
--- a/src/ncp/ncp_spi.cpp
+++ b/src/ncp/ncp_spi.cpp
@@ -105,7 +105,7 @@
     mTxState(kTxStateIdle),
     mHandlingRxFrame(false),
     mResetFlag(true),
-    mPrepareTxFrameTask(aInstance->mIp6.mTaskletScheduler, &NcpSpi::PrepareTxFrame, this),
+    mPrepareTxFrameTask(aInstance, &NcpSpi::PrepareTxFrame, this),
     mSendFrameLen(0)
 {
     memset(mSendFrame, 0, kSpiHeaderLength);
diff --git a/src/ncp/ncp_uart.cpp b/src/ncp/ncp_uart.cpp
index 53b30d5..1189c16 100644
--- a/src/ncp/ncp_uart.cpp
+++ b/src/ncp/ncp_uart.cpp
@@ -98,7 +98,7 @@
     mUartBuffer(),
     mState(kStartingFrame),
     mByte(0),
-    mUartSendTask(aInstance->mIp6.mTaskletScheduler, EncodeAndSendToUart, this)
+    mUartSendTask(aInstance, EncodeAndSendToUart, this)
 {
     mTxFrameBuffer.SetFrameAddedCallback(HandleFrameAddedToNcpBuffer, this);
 
diff --git a/tests/unit/test_timer.cpp b/tests/unit/test_timer.cpp
index 801f303..333598e 100644
--- a/tests/unit/test_timer.cpp
+++ b/tests/unit/test_timer.cpp
@@ -86,7 +86,7 @@
 {
 public:
     TestTimer(otInstance *aInstance):
-        ot::TimerMilli(aInstance->mIp6, TestTimer::HandleTimerFired, NULL),
+        ot::TimerMilli(aInstance, TestTimer::HandleTimerFired, NULL),
         mFiredCounter(0)
     { }