| /* |
| * Copyright (c) 2016, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /** |
| * @file |
| * This file implements the top-level interface to the OpenThread stack. |
| */ |
| |
| #define WPP_NAME "openthread.tmh" |
| |
| #ifdef OPENTHREAD_CONFIG_FILE |
| #include OPENTHREAD_CONFIG_FILE |
| #else |
| #include <openthread-config.h> |
| #endif |
| |
| #include <openthread.h> |
| #if OPENTHREAD_ENABLE_JAM_DETECTION |
| #include <openthread-jam-detection.h> |
| #endif |
| |
| #include <common/code_utils.hpp> |
| #include <common/debug.hpp> |
| #include <common/logging.hpp> |
| #include <common/message.hpp> |
| #include <common/new.hpp> |
| #include <common/tasklet.hpp> |
| #include <common/timer.hpp> |
| #include <crypto/mbedtls.hpp> |
| #include <net/icmp6.hpp> |
| #include <net/ip6.hpp> |
| #include <platform/settings.h> |
| #include <platform/radio.h> |
| #include <platform/random.h> |
| #include <platform/misc.h> |
| #include <thread/thread_netif.hpp> |
| #include <thread/thread_uris.hpp> |
| #include <utils/slaac_address.hpp> |
| #include <openthread-instance.h> |
| #include <openthread-coap.h> |
| #include <coap/coap_header.hpp> |
| #include <coap/coap_client.hpp> |
| #include <coap/coap_server.hpp> |
| |
| using namespace Thread; |
| |
| #ifndef OPENTHREAD_MULTIPLE_INSTANCE |
| static otDEFINE_ALIGNED_VAR(sInstanceRaw, sizeof(otInstance), uint64_t); |
| otInstance *sInstance = NULL; |
| #endif |
| |
| otInstance::otInstance(void) : |
| mReceiveIp6DatagramCallback(NULL), |
| mReceiveIp6DatagramCallbackContext(NULL), |
| mActiveScanCallback(NULL), |
| mActiveScanCallbackContext(NULL), |
| mEnergyScanCallback(NULL), |
| mEnergyScanCallbackContext(NULL), |
| mThreadNetif(mIp6) |
| #if OPENTHREAD_ENABLE_RAW_LINK_API |
| , mLinkRaw(*this) |
| #endif // OPENTHREAD_ENABLE_RAW_LINK_API |
| #if OPENTHREAD_ENABLE_APPLICATION_COAP |
| , mApplicationCoapServer(mIp6.mUdp, OT_DEFAULT_COAP_PORT) |
| #endif // OPENTHREAD_ENABLE_APPLICATION_COAP |
| { |
| } |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| static void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame); |
| static void HandleEnergyScanResult(void *aContext, otEnergyScanResult *aResult); |
| |
| void otProcessQueuedTasklets(otInstance *aInstance) |
| { |
| otLogFuncEntry(); |
| aInstance->mIp6.mTaskletScheduler.ProcessQueuedTasklets(); |
| otLogFuncExit(); |
| } |
| |
| bool otAreTaskletsPending(otInstance *aInstance) |
| { |
| return aInstance->mIp6.mTaskletScheduler.AreTaskletsPending(); |
| } |
| |
| uint8_t otGetChannel(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().GetChannel(); |
| } |
| |
| ThreadError otSetChannel(otInstance *aInstance, uint8_t aChannel) |
| { |
| return aInstance->mThreadNetif.GetMac().SetChannel(aChannel); |
| } |
| |
| ThreadError otSetDelayTimerMinimal(otInstance *aInstance, uint32_t aDelayTimerMinimal) |
| { |
| return aInstance->mThreadNetif.GetLeader().SetDelayTimerMinimal(aDelayTimerMinimal); |
| } |
| |
| uint32_t otGetDelayTimerMinimal(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetLeader().GetDelayTimerMinimal(); |
| } |
| |
| uint8_t otGetMaxAllowedChildren(otInstance *aInstance) |
| { |
| uint8_t aNumChildren; |
| |
| (void)aInstance->mThreadNetif.GetMle().GetChildren(&aNumChildren); |
| |
| return aNumChildren; |
| } |
| |
| ThreadError otSetMaxAllowedChildren(otInstance *aInstance, uint8_t aMaxChildren) |
| { |
| return aInstance->mThreadNetif.GetMle().SetMaxAllowedChildren(aMaxChildren); |
| } |
| |
| uint32_t otGetChildTimeout(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetTimeout(); |
| } |
| |
| void otSetChildTimeout(otInstance *aInstance, uint32_t aTimeout) |
| { |
| aInstance->mThreadNetif.GetMle().SetTimeout(aTimeout); |
| } |
| |
| const uint8_t *otGetExtendedAddress(otInstance *aInstance) |
| { |
| return reinterpret_cast<const uint8_t *>(aInstance->mThreadNetif.GetMac().GetExtAddress()); |
| } |
| |
| ThreadError otSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aExtAddress != NULL, error = kThreadError_InvalidArgs); |
| |
| aInstance->mThreadNetif.GetMac().SetExtAddress(*static_cast<const Mac::ExtAddress *>(aExtAddress)); |
| |
| SuccessOrExit(error = aInstance->mThreadNetif.GetMle().UpdateLinkLocalAddress()); |
| |
| exit: |
| return error; |
| } |
| |
| const uint8_t *otGetExtendedPanId(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().GetExtendedPanId(); |
| } |
| |
| void otSetExtendedPanId(otInstance *aInstance, const uint8_t *aExtendedPanId) |
| { |
| uint8_t mlPrefix[8]; |
| |
| aInstance->mThreadNetif.GetMac().SetExtendedPanId(aExtendedPanId); |
| |
| mlPrefix[0] = 0xfd; |
| memcpy(mlPrefix + 1, aExtendedPanId, 5); |
| mlPrefix[6] = 0x00; |
| mlPrefix[7] = 0x00; |
| aInstance->mThreadNetif.GetMle().SetMeshLocalPrefix(mlPrefix); |
| } |
| |
| void otGetFactoryAssignedIeeeEui64(otInstance *aInstance, otExtAddress *aEui64) |
| { |
| otPlatRadioGetIeeeEui64(aInstance, aEui64->m8); |
| } |
| |
| void otGetHashMacAddress(otInstance *aInstance, otExtAddress *aHashMacAddress) |
| { |
| aInstance->mThreadNetif.GetMac().GetHashMacAddress(static_cast<Mac::ExtAddress *>(aHashMacAddress)); |
| } |
| |
| ThreadError otGetLeaderRloc(otInstance *aInstance, otIp6Address *aAddress) |
| { |
| ThreadError error; |
| |
| VerifyOrExit(aAddress != NULL, error = kThreadError_InvalidArgs); |
| |
| error = aInstance->mThreadNetif.GetMle().GetLeaderAddress(*static_cast<Ip6::Address *>(aAddress)); |
| |
| exit: |
| return error; |
| } |
| |
| otLinkModeConfig otGetLinkMode(otInstance *aInstance) |
| { |
| otLinkModeConfig config; |
| uint8_t mode = aInstance->mThreadNetif.GetMle().GetDeviceMode(); |
| |
| memset(&config, 0, sizeof(otLinkModeConfig)); |
| |
| if (mode & Mle::ModeTlv::kModeRxOnWhenIdle) |
| { |
| config.mRxOnWhenIdle = 1; |
| } |
| |
| if (mode & Mle::ModeTlv::kModeSecureDataRequest) |
| { |
| config.mSecureDataRequests = 1; |
| } |
| |
| if (mode & Mle::ModeTlv::kModeFFD) |
| { |
| config.mDeviceType = 1; |
| } |
| |
| if (mode & Mle::ModeTlv::kModeFullNetworkData) |
| { |
| config.mNetworkData = 1; |
| } |
| |
| return config; |
| } |
| |
| ThreadError otSetLinkMode(otInstance *aInstance, otLinkModeConfig aConfig) |
| { |
| uint8_t mode = 0; |
| |
| if (aConfig.mRxOnWhenIdle) |
| { |
| mode |= Mle::ModeTlv::kModeRxOnWhenIdle; |
| } |
| |
| if (aConfig.mSecureDataRequests) |
| { |
| mode |= Mle::ModeTlv::kModeSecureDataRequest; |
| } |
| |
| if (aConfig.mDeviceType) |
| { |
| mode |= Mle::ModeTlv::kModeFFD; |
| } |
| |
| if (aConfig.mNetworkData) |
| { |
| mode |= Mle::ModeTlv::kModeFullNetworkData; |
| } |
| |
| return aInstance->mThreadNetif.GetMle().SetDeviceMode(mode); |
| } |
| |
| const uint8_t *otGetMasterKey(otInstance *aInstance, uint8_t *aKeyLength) |
| { |
| return aInstance->mThreadNetif.GetKeyManager().GetMasterKey(aKeyLength); |
| } |
| |
| ThreadError otSetMasterKey(otInstance *aInstance, const uint8_t *aKey, uint8_t aKeyLength) |
| { |
| return aInstance->mThreadNetif.GetKeyManager().SetMasterKey(aKey, aKeyLength); |
| } |
| |
| int8_t otGetMaxTransmitPower(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().GetMaxTransmitPower(); |
| } |
| |
| void otSetMaxTransmitPower(otInstance *aInstance, int8_t aPower) |
| { |
| aInstance->mThreadNetif.GetMac().SetMaxTransmitPower(aPower); |
| } |
| |
| const otIp6Address *otGetMeshLocalEid(otInstance *aInstance) |
| { |
| return &aInstance->mThreadNetif.GetMle().GetMeshLocal64(); |
| } |
| |
| const uint8_t *otGetMeshLocalPrefix(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetMeshLocalPrefix(); |
| } |
| |
| ThreadError otSetMeshLocalPrefix(otInstance *aInstance, const uint8_t *aMeshLocalPrefix) |
| { |
| return aInstance->mThreadNetif.GetMle().SetMeshLocalPrefix(aMeshLocalPrefix); |
| } |
| |
| ThreadError otGetNetworkDataLeader(otInstance *aInstance, bool aStable, uint8_t *aData, uint8_t *aDataLength) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aData != NULL && aDataLength != NULL, error = kThreadError_InvalidArgs); |
| |
| aInstance->mThreadNetif.GetNetworkDataLeader().GetNetworkData(aStable, aData, *aDataLength); |
| |
| exit: |
| return error; |
| } |
| |
| ThreadError otGetNetworkDataLocal(otInstance *aInstance, bool aStable, uint8_t *aData, uint8_t *aDataLength) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aData != NULL && aDataLength != NULL, error = kThreadError_InvalidArgs); |
| |
| aInstance->mThreadNetif.GetNetworkDataLocal().GetNetworkData(aStable, aData, *aDataLength); |
| |
| exit: |
| return error; |
| } |
| |
| const char *otGetNetworkName(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().GetNetworkName(); |
| } |
| |
| ThreadError otSetNetworkName(otInstance *aInstance, const char *aNetworkName) |
| { |
| return aInstance->mThreadNetif.GetMac().SetNetworkName(aNetworkName); |
| } |
| |
| otPanId otGetPanId(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().GetPanId(); |
| } |
| |
| ThreadError otSetPanId(otInstance *aInstance, otPanId aPanId) |
| { |
| ThreadError error = kThreadError_None; |
| |
| // do not allow setting PAN ID to broadcast if Thread is running |
| VerifyOrExit(aPanId != Mac::kPanIdBroadcast || |
| aInstance->mThreadNetif.GetMle().GetDeviceState() != Mle::kDeviceStateDisabled, |
| error = kThreadError_InvalidState); |
| |
| error = aInstance->mThreadNetif.GetMac().SetPanId(aPanId); |
| |
| exit: |
| return error; |
| } |
| |
| bool otIsRouterRoleEnabled(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().IsRouterRoleEnabled(); |
| } |
| |
| void otSetRouterRoleEnabled(otInstance *aInstance, bool aEnabled) |
| { |
| aInstance->mThreadNetif.GetMle().SetRouterRoleEnabled(aEnabled); |
| } |
| |
| otShortAddress otGetShortAddress(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().GetShortAddress(); |
| } |
| |
| uint8_t otGetLocalLeaderWeight(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetLeaderWeight(); |
| } |
| |
| void otSetLocalLeaderWeight(otInstance *aInstance, uint8_t aWeight) |
| { |
| aInstance->mThreadNetif.GetMle().SetLeaderWeight(aWeight); |
| } |
| |
| uint32_t otGetLocalLeaderPartitionId(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetLeaderPartitionId(); |
| } |
| |
| void otSetLocalLeaderPartitionId(otInstance *aInstance, uint32_t aPartitionId) |
| { |
| return aInstance->mThreadNetif.GetMle().SetLeaderPartitionId(aPartitionId); |
| } |
| |
| uint16_t otGetJoinerUdpPort(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetJoinerRouter().GetJoinerUdpPort(); |
| } |
| |
| ThreadError otSetJoinerUdpPort(otInstance *aInstance, uint16_t aJoinerUdpPort) |
| { |
| return aInstance->mThreadNetif.GetJoinerRouter().SetJoinerUdpPort(aJoinerUdpPort); |
| } |
| |
| ThreadError otAddBorderRouter(otInstance *aInstance, const otBorderRouterConfig *aConfig) |
| { |
| uint8_t flags = 0; |
| |
| if (aConfig->mPreferred) |
| { |
| flags |= NetworkData::BorderRouterEntry::kPreferredFlag; |
| } |
| |
| if (aConfig->mSlaac) |
| { |
| flags |= NetworkData::BorderRouterEntry::kSlaacFlag; |
| } |
| |
| if (aConfig->mDhcp) |
| { |
| flags |= NetworkData::BorderRouterEntry::kDhcpFlag; |
| } |
| |
| if (aConfig->mConfigure) |
| { |
| flags |= NetworkData::BorderRouterEntry::kConfigureFlag; |
| } |
| |
| if (aConfig->mDefaultRoute) |
| { |
| flags |= NetworkData::BorderRouterEntry::kDefaultRouteFlag; |
| } |
| |
| if (aConfig->mOnMesh) |
| { |
| flags |= NetworkData::BorderRouterEntry::kOnMeshFlag; |
| } |
| |
| return aInstance->mThreadNetif.GetNetworkDataLocal().AddOnMeshPrefix(aConfig->mPrefix.mPrefix.mFields.m8, |
| aConfig->mPrefix.mLength, |
| aConfig->mPreference, flags, aConfig->mStable); |
| } |
| |
| ThreadError otRemoveBorderRouter(otInstance *aInstance, const otIp6Prefix *aPrefix) |
| { |
| return aInstance->mThreadNetif.GetNetworkDataLocal().RemoveOnMeshPrefix(aPrefix->mPrefix.mFields.m8, aPrefix->mLength); |
| } |
| |
| ThreadError otGetNextOnMeshPrefix(otInstance *aInstance, bool aLocal, otNetworkDataIterator *aIterator, |
| otBorderRouterConfig *aConfig) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aIterator && aConfig, error = kThreadError_InvalidArgs); |
| |
| if (aLocal) |
| { |
| error = aInstance->mThreadNetif.GetNetworkDataLocal().GetNextOnMeshPrefix(aIterator, aConfig); |
| } |
| else |
| { |
| error = aInstance->mThreadNetif.GetNetworkDataLeader().GetNextOnMeshPrefix(aIterator, aConfig); |
| } |
| |
| exit: |
| return error; |
| } |
| |
| ThreadError otAddExternalRoute(otInstance *aInstance, const otExternalRouteConfig *aConfig) |
| { |
| return aInstance->mThreadNetif.GetNetworkDataLocal().AddHasRoutePrefix(aConfig->mPrefix.mPrefix.mFields.m8, |
| aConfig->mPrefix.mLength, |
| aConfig->mPreference, aConfig->mStable); |
| } |
| |
| ThreadError otRemoveExternalRoute(otInstance *aInstance, const otIp6Prefix *aPrefix) |
| { |
| return aInstance->mThreadNetif.GetNetworkDataLocal().RemoveHasRoutePrefix(aPrefix->mPrefix.mFields.m8, |
| aPrefix->mLength); |
| } |
| |
| ThreadError otSendServerData(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetNetworkDataLocal().SendServerDataNotification(); |
| } |
| |
| ThreadError otAddUnsecurePort(otInstance *aInstance, uint16_t aPort) |
| { |
| return aInstance->mThreadNetif.GetIp6Filter().AddUnsecurePort(aPort); |
| } |
| |
| ThreadError otRemoveUnsecurePort(otInstance *aInstance, uint16_t aPort) |
| { |
| return aInstance->mThreadNetif.GetIp6Filter().RemoveUnsecurePort(aPort); |
| } |
| |
| const uint16_t *otGetUnsecurePorts(otInstance *aInstance, uint8_t *aNumEntries) |
| { |
| return aInstance->mThreadNetif.GetIp6Filter().GetUnsecurePorts(*aNumEntries); |
| } |
| |
| uint32_t otGetContextIdReuseDelay(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetNetworkDataLeader().GetContextIdReuseDelay(); |
| } |
| |
| void otSetContextIdReuseDelay(otInstance *aInstance, uint32_t aDelay) |
| { |
| aInstance->mThreadNetif.GetNetworkDataLeader().SetContextIdReuseDelay(aDelay); |
| } |
| |
| uint32_t otGetKeySequenceCounter(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetKeyManager().GetCurrentKeySequence(); |
| } |
| |
| void otSetKeySequenceCounter(otInstance *aInstance, uint32_t aKeySequenceCounter) |
| { |
| aInstance->mThreadNetif.GetKeyManager().SetCurrentKeySequence(aKeySequenceCounter); |
| } |
| |
| uint32_t otGetKeySwitchGuardTime(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetKeyManager().GetKeySwitchGuardTime(); |
| } |
| |
| void otSetKeySwitchGuardTime(otInstance *aInstance, uint32_t aKeySwitchGuardTime) |
| { |
| aInstance->mThreadNetif.GetKeyManager().SetKeySwitchGuardTime(aKeySwitchGuardTime); |
| } |
| |
| uint8_t otGetNetworkIdTimeout(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetNetworkIdTimeout(); |
| } |
| |
| void otSetNetworkIdTimeout(otInstance *aInstance, uint8_t aTimeout) |
| { |
| aInstance->mThreadNetif.GetMle().SetNetworkIdTimeout((uint8_t)aTimeout); |
| } |
| |
| uint8_t otGetRouterUpgradeThreshold(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetRouterUpgradeThreshold(); |
| } |
| |
| void otSetRouterUpgradeThreshold(otInstance *aInstance, uint8_t aThreshold) |
| { |
| aInstance->mThreadNetif.GetMle().SetRouterUpgradeThreshold(aThreshold); |
| } |
| |
| ThreadError otReleaseRouterId(otInstance *aInstance, uint8_t aRouterId) |
| { |
| return aInstance->mThreadNetif.GetMle().ReleaseRouterId(aRouterId); |
| } |
| |
| ThreadError otAddMacWhitelist(otInstance *aInstance, const uint8_t *aExtAddr) |
| { |
| ThreadError error = kThreadError_None; |
| |
| if (aInstance->mThreadNetif.GetMac().GetWhitelist().Add(*reinterpret_cast<const Mac::ExtAddress *>(aExtAddr)) == NULL) |
| { |
| error = kThreadError_NoBufs; |
| } |
| |
| return error; |
| } |
| |
| ThreadError otAddMacWhitelistRssi(otInstance *aInstance, const uint8_t *aExtAddr, int8_t aRssi) |
| { |
| ThreadError error = kThreadError_None; |
| otMacWhitelistEntry *entry; |
| |
| entry = aInstance->mThreadNetif.GetMac().GetWhitelist().Add(*reinterpret_cast<const Mac::ExtAddress *>(aExtAddr)); |
| VerifyOrExit(entry != NULL, error = kThreadError_NoBufs); |
| aInstance->mThreadNetif.GetMac().GetWhitelist().SetFixedRssi(*entry, aRssi); |
| |
| exit: |
| return error; |
| } |
| |
| void otRemoveMacWhitelist(otInstance *aInstance, const uint8_t *aExtAddr) |
| { |
| aInstance->mThreadNetif.GetMac().GetWhitelist().Remove(*reinterpret_cast<const Mac::ExtAddress *>(aExtAddr)); |
| } |
| |
| void otClearMacWhitelist(otInstance *aInstance) |
| { |
| aInstance->mThreadNetif.GetMac().GetWhitelist().Clear(); |
| } |
| |
| ThreadError otGetMacWhitelistEntry(otInstance *aInstance, uint8_t aIndex, otMacWhitelistEntry *aEntry) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aEntry != NULL, error = kThreadError_InvalidArgs); |
| error = aInstance->mThreadNetif.GetMac().GetWhitelist().GetEntry(aIndex, *aEntry); |
| |
| exit: |
| return error; |
| } |
| |
| void otDisableMacWhitelist(otInstance *aInstance) |
| { |
| aInstance->mThreadNetif.GetMac().GetWhitelist().Disable(); |
| } |
| |
| void otEnableMacWhitelist(otInstance *aInstance) |
| { |
| aInstance->mThreadNetif.GetMac().GetWhitelist().Enable(); |
| } |
| |
| bool otIsMacWhitelistEnabled(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().GetWhitelist().IsEnabled(); |
| } |
| |
| ThreadError otBecomeDetached(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().BecomeDetached(); |
| } |
| |
| ThreadError otBecomeChild(otInstance *aInstance, otMleAttachFilter aFilter) |
| { |
| return aInstance->mThreadNetif.GetMle().BecomeChild(aFilter); |
| } |
| |
| ThreadError otBecomeRouter(otInstance *aInstance) |
| { |
| ThreadError error = kThreadError_InvalidState; |
| |
| switch (aInstance->mThreadNetif.GetMle().GetDeviceState()) |
| { |
| case Mle::kDeviceStateDisabled: |
| case Mle::kDeviceStateDetached: |
| break; |
| |
| case Mle::kDeviceStateChild: |
| error = aInstance->mThreadNetif.GetMle().BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest); |
| break; |
| |
| case Mle::kDeviceStateRouter: |
| case Mle::kDeviceStateLeader: |
| error = kThreadError_None; |
| break; |
| } |
| |
| return error; |
| } |
| |
| ThreadError otBecomeLeader(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().BecomeLeader(); |
| } |
| |
| ThreadError otAddMacBlacklist(otInstance *aInstance, const uint8_t *aExtAddr) |
| { |
| ThreadError error = kThreadError_None; |
| |
| if (aInstance->mThreadNetif.GetMac().GetBlacklist().Add(*reinterpret_cast<const Mac::ExtAddress *>(aExtAddr)) == NULL) |
| { |
| error = kThreadError_NoBufs; |
| } |
| |
| return error; |
| } |
| |
| void otRemoveMacBlacklist(otInstance *aInstance, const uint8_t *aExtAddr) |
| { |
| aInstance->mThreadNetif.GetMac().GetBlacklist().Remove(*reinterpret_cast<const Mac::ExtAddress *>(aExtAddr)); |
| } |
| |
| void otClearMacBlacklist(otInstance *aInstance) |
| { |
| aInstance->mThreadNetif.GetMac().GetBlacklist().Clear(); |
| } |
| |
| ThreadError otGetMacBlacklistEntry(otInstance *aInstance, uint8_t aIndex, otMacBlacklistEntry *aEntry) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aEntry != NULL, error = kThreadError_InvalidArgs); |
| error = aInstance->mThreadNetif.GetMac().GetBlacklist().GetEntry(aIndex, *aEntry); |
| |
| exit: |
| return error; |
| } |
| |
| void otDisableMacBlacklist(otInstance *aInstance) |
| { |
| aInstance->mThreadNetif.GetMac().GetBlacklist().Disable(); |
| } |
| |
| void otEnableMacBlacklist(otInstance *aInstance) |
| { |
| aInstance->mThreadNetif.GetMac().GetBlacklist().Enable(); |
| } |
| |
| bool otIsMacBlacklistEnabled(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().GetBlacklist().IsEnabled(); |
| } |
| |
| ThreadError otGetAssignLinkQuality(otInstance *aInstance, const uint8_t *aExtAddr, uint8_t *aLinkQuality) |
| { |
| Mac::ExtAddress extAddress; |
| |
| memset(&extAddress, 0, sizeof(extAddress)); |
| memcpy(extAddress.m8, aExtAddr, OT_EXT_ADDRESS_SIZE); |
| |
| return aInstance->mThreadNetif.GetMle().GetAssignLinkQuality(extAddress, *aLinkQuality); |
| } |
| |
| void otSetAssignLinkQuality(otInstance *aInstance, const uint8_t *aExtAddr, uint8_t aLinkQuality) |
| { |
| Mac::ExtAddress extAddress; |
| |
| memset(&extAddress, 0, sizeof(extAddress)); |
| memcpy(extAddress.m8, aExtAddr, OT_EXT_ADDRESS_SIZE); |
| |
| aInstance->mThreadNetif.GetMle().SetAssignLinkQuality(extAddress, aLinkQuality); |
| } |
| |
| void otPlatformReset(otInstance *aInstance) |
| { |
| otPlatReset(aInstance); |
| } |
| |
| void otFactoryReset(otInstance *aInstance) |
| { |
| otPlatSettingsWipe(aInstance); |
| otPlatReset(aInstance); |
| } |
| |
| ThreadError otPersistentInfoErase(otInstance *aInstance) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(otGetDeviceRole(aInstance) == kDeviceRoleDisabled, error = kThreadError_InvalidState); |
| otPlatSettingsWipe(aInstance); |
| |
| exit: |
| return error; |
| } |
| |
| uint8_t otGetRouterDowngradeThreshold(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetRouterDowngradeThreshold(); |
| } |
| |
| void otSetRouterDowngradeThreshold(otInstance *aInstance, uint8_t aThreshold) |
| { |
| aInstance->mThreadNetif.GetMle().SetRouterDowngradeThreshold(aThreshold); |
| } |
| |
| uint8_t otGetRouterSelectionJitter(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetRouterSelectionJitter(); |
| } |
| |
| void otSetRouterSelectionJitter(otInstance *aInstance, uint8_t aRouterJitter) |
| { |
| aInstance->mThreadNetif.GetMle().SetRouterSelectionJitter(aRouterJitter); |
| } |
| |
| ThreadError otGetChildInfoById(otInstance *aInstance, uint16_t aChildId, otChildInfo *aChildInfo) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aChildInfo != NULL, error = kThreadError_InvalidArgs); |
| |
| error = aInstance->mThreadNetif.GetMle().GetChildInfoById(aChildId, *aChildInfo); |
| |
| exit: |
| return error; |
| } |
| |
| ThreadError otGetChildInfoByIndex(otInstance *aInstance, uint8_t aChildIndex, otChildInfo *aChildInfo) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aChildInfo != NULL, error = kThreadError_InvalidArgs); |
| |
| error = aInstance->mThreadNetif.GetMle().GetChildInfoByIndex(aChildIndex, *aChildInfo); |
| |
| exit: |
| return error; |
| } |
| |
| ThreadError otGetNextNeighborInfo(otInstance *aInstance, otNeighborInfoIterator *aIterator, otNeighborInfo *aInfo) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit((aInfo != NULL) && (aIterator != NULL), error = kThreadError_InvalidArgs); |
| |
| error = aInstance->mThreadNetif.GetMle().GetNextNeighborInfo(*aIterator, *aInfo); |
| |
| exit: |
| return error; |
| } |
| |
| otDeviceRole otGetDeviceRole(otInstance *aInstance) |
| { |
| otDeviceRole rval = kDeviceRoleDisabled; |
| |
| switch (aInstance->mThreadNetif.GetMle().GetDeviceState()) |
| { |
| case Mle::kDeviceStateDisabled: |
| rval = kDeviceRoleDisabled; |
| break; |
| |
| case Mle::kDeviceStateDetached: |
| rval = kDeviceRoleDetached; |
| break; |
| |
| case Mle::kDeviceStateChild: |
| rval = kDeviceRoleChild; |
| break; |
| |
| case Mle::kDeviceStateRouter: |
| rval = kDeviceRoleRouter; |
| break; |
| |
| case Mle::kDeviceStateLeader: |
| rval = kDeviceRoleLeader; |
| break; |
| } |
| |
| return rval; |
| } |
| |
| ThreadError otGetEidCacheEntry(otInstance *aInstance, uint8_t aIndex, otEidCacheEntry *aEntry) |
| { |
| ThreadError error; |
| |
| VerifyOrExit(aEntry != NULL, error = kThreadError_InvalidArgs); |
| error = aInstance->mThreadNetif.GetAddressResolver().GetEntry(aIndex, *aEntry); |
| |
| exit: |
| return error; |
| } |
| |
| ThreadError otGetLeaderData(otInstance *aInstance, otLeaderData *aLeaderData) |
| { |
| ThreadError error; |
| |
| VerifyOrExit(aLeaderData != NULL, error = kThreadError_InvalidArgs); |
| |
| error = aInstance->mThreadNetif.GetMle().GetLeaderData(*aLeaderData); |
| |
| exit: |
| return error; |
| } |
| |
| uint8_t otGetLeaderRouterId(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetLeaderDataTlv().GetLeaderRouterId(); |
| } |
| |
| uint8_t otGetLeaderWeight(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetLeaderDataTlv().GetWeighting(); |
| } |
| |
| uint8_t otGetNetworkDataVersion(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetLeaderDataTlv().GetDataVersion(); |
| } |
| |
| uint32_t otGetPartitionId(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetLeaderDataTlv().GetPartitionId(); |
| } |
| |
| uint16_t otGetRloc16(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetRloc16(); |
| } |
| |
| uint8_t otGetRouterIdSequence(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetRouterIdSequence(); |
| } |
| |
| ThreadError otGetRouterInfo(otInstance *aInstance, uint16_t aRouterId, otRouterInfo *aRouterInfo) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aRouterInfo != NULL, error = kThreadError_InvalidArgs); |
| |
| error = aInstance->mThreadNetif.GetMle().GetRouterInfo(aRouterId, *aRouterInfo); |
| |
| exit: |
| return error; |
| } |
| |
| ThreadError otGetParentInfo(otInstance *aInstance, otRouterInfo *aParentInfo) |
| { |
| ThreadError error = kThreadError_None; |
| Router *parent; |
| |
| VerifyOrExit(aParentInfo != NULL, error = kThreadError_InvalidArgs); |
| |
| parent = aInstance->mThreadNetif.GetMle().GetParent(); |
| memcpy(aParentInfo->mExtAddress.m8, parent->mMacAddr.m8, OT_EXT_ADDRESS_SIZE); |
| aParentInfo->mRloc16 = parent->mValid.mRloc16; |
| |
| exit: |
| return error; |
| } |
| |
| uint8_t otGetStableNetworkDataVersion(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().GetLeaderDataTlv().GetStableDataVersion(); |
| } |
| |
| void otSetLinkPcapCallback(otInstance *aInstance, otLinkPcapCallback aPcapCallback, void *aCallbackContext) |
| { |
| aInstance->mThreadNetif.GetMac().SetPcapCallback(aPcapCallback, aCallbackContext); |
| } |
| |
| bool otIsLinkPromiscuous(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().IsPromiscuous(); |
| } |
| |
| ThreadError otSetLinkPromiscuous(otInstance *aInstance, bool aPromiscuous) |
| { |
| ThreadError error = kThreadError_None; |
| |
| // cannot enable IEEE 802.15.4 promiscuous mode if the Thread interface is enabled |
| VerifyOrExit(aInstance->mThreadNetif.IsUp() == false, error = kThreadError_InvalidState); |
| |
| aInstance->mThreadNetif.GetMac().SetPromiscuous(aPromiscuous); |
| |
| exit: |
| return error; |
| } |
| |
| const otMacCounters *otGetMacCounters(otInstance *aInstance) |
| { |
| return &aInstance->mThreadNetif.GetMac().GetCounters(); |
| } |
| |
| void otGetMessageBufferInfo(otInstance *aInstance, otBufferInfo *aBufferInfo) |
| { |
| aBufferInfo->mTotalBuffers = OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS; |
| |
| aBufferInfo->mFreeBuffers = aInstance->mThreadNetif.GetIp6().mMessagePool.GetFreeBufferCount(); |
| |
| aInstance->mThreadNetif.GetMeshForwarder().GetSendQueue().GetInfo(aBufferInfo->m6loSendMessages, |
| aBufferInfo->m6loSendBuffers); |
| |
| aInstance->mThreadNetif.GetMeshForwarder().GetReassemblyQueue().GetInfo(aBufferInfo->m6loReassemblyMessages, |
| aBufferInfo->m6loReassemblyBuffers); |
| |
| aInstance->mThreadNetif.GetMeshForwarder().GetResolvingQueue().GetInfo(aBufferInfo->mArpMessages, |
| aBufferInfo->mArpBuffers); |
| |
| aInstance->mThreadNetif.GetIp6().GetSendQueue().GetInfo(aBufferInfo->mIp6Messages, |
| aBufferInfo->mIp6Buffers); |
| |
| aInstance->mThreadNetif.GetIp6().mMpl.GetBufferedMessageSet().GetInfo(aBufferInfo->mMplMessages, |
| aBufferInfo->mMplBuffers); |
| |
| aInstance->mThreadNetif.GetMle().GetMessageQueue().GetInfo(aBufferInfo->mMleMessages, |
| aBufferInfo->mMleBuffers); |
| |
| aInstance->mThreadNetif.GetCoapClient().GetRequestMessages().GetInfo(aBufferInfo->mCoapClientMessages, |
| aBufferInfo->mCoapClientBuffers); |
| } |
| |
| #if OPENTHREAD_ENABLE_JAM_DETECTION |
| ThreadError otSetJamDetectionRssiThreshold(otInstance *aInstance, int8_t aRssiThreshold) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().SetRssiThreshold(aRssiThreshold); |
| } |
| |
| int8_t otGetJamDetectionRssiThreshold(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().GetRssiThreshold(); |
| } |
| |
| ThreadError otSetJamDetectionWindow(otInstance *aInstance, uint8_t aWindow) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().SetWindow(aWindow); |
| } |
| |
| uint8_t otGetJamDetectionWindow(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().GetWindow(); |
| } |
| |
| ThreadError otSetJamDetectionBusyPeriod(otInstance *aInstance, uint8_t aBusyPeriod) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().SetBusyPeriod(aBusyPeriod); |
| } |
| |
| uint8_t otGetJamDetectionBusyPeriod(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().GetBusyPeriod(); |
| } |
| |
| ThreadError otStartJamDetection(otInstance *aInstance, otJamDetectionCallback aCallback, void *aContext) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().Start(aCallback, aContext); |
| } |
| |
| ThreadError otStopJamDetection(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().Stop(); |
| } |
| |
| bool otIsJamDetectionEnabled(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().IsEnabled(); |
| } |
| |
| bool otGetJamDetectionState(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().GetState(); |
| } |
| |
| uint64_t otGetJamDetectionHistoryBitmap(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetJamDetector().GetHistoryBitmap(); |
| } |
| #endif // OPENTHREAD_ENABLE_JAM_DETECTION |
| |
| bool otIsIp6AddressEqual(const otIp6Address *a, const otIp6Address *b) |
| { |
| return *static_cast<const Ip6::Address *>(a) == *static_cast<const Ip6::Address *>(b); |
| } |
| |
| ThreadError otIp6AddressFromString(const char *str, otIp6Address *address) |
| { |
| return static_cast<Ip6::Address *>(address)->FromString(str); |
| } |
| |
| const otNetifAddress *otGetUnicastAddresses(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetUnicastAddresses(); |
| } |
| |
| ThreadError otAddUnicastAddress(otInstance *aInstance, const otNetifAddress *address) |
| { |
| return aInstance->mThreadNetif.AddExternalUnicastAddress(*static_cast<const Ip6::NetifUnicastAddress *>(address)); |
| } |
| |
| ThreadError otRemoveUnicastAddress(otInstance *aInstance, const otIp6Address *address) |
| { |
| return aInstance->mThreadNetif.RemoveExternalUnicastAddress(*static_cast<const Ip6::Address *>(address)); |
| } |
| |
| #if OPENTHREAD_ENABLE_DHCP6_SERVER |
| void otDhcp6ServerUpdate(otInstance *aInstance) |
| { |
| aInstance->mThreadNetif.GetDhcp6Server().UpdateService(); |
| } |
| #endif // OPENTHREAD_ENABLE_DHCP6_SERVER |
| |
| #if OPENTHREAD_ENABLE_DHCP6_CLIENT |
| void otDhcp6ClientUpdate(otInstance *aInstance, otDhcpAddress *aAddresses, uint32_t aNumAddresses, void *aContext) |
| { |
| aInstance->mThreadNetif.GetDhcp6Client().UpdateAddresses(aInstance, aAddresses, aNumAddresses, aContext); |
| } |
| #endif // OPENTHREAD_ENABLE_DHCP6_CLIENT |
| |
| const otNetifMulticastAddress *otGetMulticastAddresses(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMulticastAddresses(); |
| } |
| |
| ThreadError otSubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress) |
| { |
| return aInstance->mThreadNetif.SubscribeExternalMulticast(*static_cast<const Ip6::Address *>(aAddress)); |
| } |
| |
| ThreadError otUnsubscribeMulticastAddress(otInstance *aInstance, const otIp6Address *aAddress) |
| { |
| return aInstance->mThreadNetif.UnsubscribeExternalMulticast(*static_cast<const Ip6::Address *>(aAddress)); |
| } |
| |
| bool otIsMulticastPromiscuousModeEnabled(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.IsMulticastPromiscuousModeEnabled(); |
| } |
| |
| void otEnableMulticastPromiscuousMode(otInstance *aInstance) |
| { |
| aInstance->mThreadNetif.EnableMulticastPromiscuousMode(); |
| } |
| |
| void otDisableMulticastPromiscuousMode(otInstance *aInstance) |
| { |
| aInstance->mThreadNetif.DisableMulticastPromiscuousMode(); |
| } |
| |
| void otSlaacUpdate(otInstance *aInstance, otNetifAddress *aAddresses, uint32_t aNumAddresses, |
| otSlaacIidCreate aIidCreate, void *aContext) |
| { |
| Utils::Slaac::UpdateAddresses(aInstance, aAddresses, aNumAddresses, aIidCreate, aContext); |
| } |
| |
| ThreadError otCreateRandomIid(otInstance *aInstance, otNetifAddress *aAddress, void *aContext) |
| { |
| return Utils::Slaac::CreateRandomIid(aInstance, aAddress, aContext); |
| } |
| |
| ThreadError otCreateMacIid(otInstance *aInstance, otNetifAddress *aAddress, void *) |
| { |
| memcpy(&aAddress->mAddress.mFields.m8[OT_IP6_ADDRESS_SIZE - OT_IP6_IID_SIZE], |
| aInstance->mThreadNetif.GetMac().GetExtAddress(), OT_IP6_IID_SIZE); |
| aAddress->mAddress.mFields.m8[OT_IP6_ADDRESS_SIZE - OT_IP6_IID_SIZE] ^= 0x02; |
| |
| return kThreadError_None; |
| } |
| |
| ThreadError otCreateSemanticallyOpaqueIid(otInstance *aInstance, otNetifAddress *aAddress, void *aContext) |
| { |
| return static_cast<Utils::SemanticallyOpaqueIidGenerator *>(aContext)->CreateIid(aInstance, aAddress); |
| } |
| |
| ThreadError otSetStateChangedCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aCallbackContext) |
| { |
| ThreadError error = kThreadError_NoBufs; |
| |
| for (size_t i = 0; i < OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS; i++) |
| { |
| if (aInstance->mNetifCallback[i].IsFree()) |
| { |
| aInstance->mNetifCallback[i].Set(aCallback, aCallbackContext); |
| error = aInstance->mThreadNetif.RegisterCallback(aInstance->mNetifCallback[i]); |
| break; |
| } |
| } |
| |
| return error; |
| } |
| |
| void otRemoveStateChangeCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aCallbackContext) |
| { |
| for (size_t i = 0; i < OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS; i++) |
| { |
| if (aInstance->mNetifCallback[i].IsServing(aCallback, aCallbackContext)) |
| { |
| aInstance->mThreadNetif.RemoveCallback(aInstance->mNetifCallback[i]); |
| aInstance->mNetifCallback[i].Free(); |
| break; |
| } |
| } |
| } |
| |
| const char *otGetVersionString(void) |
| { |
| /** |
| * PLATFORM_VERSION_ATTR_PREFIX and PLATFORM_VERSION_ATTR_SUFFIX are |
| * intended to be used to specify compiler directives to indicate |
| * what linker section the platform version string should be stored. |
| * |
| * This is useful for specifying an exact locaiton of where the version |
| * string will be located so that it can be easily retrieved from the |
| * raw firmware image. |
| * |
| * If PLATFORM_VERSION_ATTR_PREFIX is unspecified, the keyword `static` |
| * is used instead. |
| * |
| * If both are unspecified, the location of the string in the firmware |
| * image will be undefined and may change. |
| */ |
| |
| #ifdef PLATFORM_VERSION_ATTR_PREFIX |
| PLATFORM_VERSION_ATTR_PREFIX |
| #else |
| static |
| #endif |
| const char sVersion[] = |
| PACKAGE_NAME "/" PACKAGE_VERSION |
| #ifdef PLATFORM_INFO |
| "; " PLATFORM_INFO |
| #endif |
| #if defined(__DATE__) |
| "; " __DATE__ " " __TIME__ |
| #endif |
| #ifdef PLATFORM_VERSION_ATTR_SUFFIX |
| PLATFORM_VERSION_ATTR_SUFFIX |
| #endif |
| ; // Trailing semicolon to end statement. |
| |
| return sVersion; |
| } |
| |
| uint32_t otGetPollPeriod(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMeshForwarder().GetAssignPollPeriod(); |
| } |
| |
| void otSetPollPeriod(otInstance *aInstance, uint32_t aPollPeriod) |
| { |
| aInstance->mThreadNetif.GetMeshForwarder().SetAssignPollPeriod(aPollPeriod); |
| } |
| |
| ThreadError otSetPreferredRouterId(otInstance *aInstance, uint8_t aRouterId) |
| { |
| return aInstance->mThreadNetif.GetMle().SetPreferredRouterId(aRouterId); |
| } |
| |
| #ifdef OPENTHREAD_MULTIPLE_INSTANCE |
| |
| otInstance *otInstanceInit(void *aInstanceBuffer, size_t *aInstanceBufferSize) |
| { |
| otInstance *aInstance = NULL; |
| |
| otLogFuncEntry(); |
| otLogInfoApi("otInstanceInit"); |
| |
| VerifyOrExit(aInstanceBufferSize != NULL, ;); |
| |
| // Make sure the input buffer is big enough |
| VerifyOrExit(sizeof(otInstance) <= *aInstanceBufferSize, *aInstanceBufferSize = sizeof(otInstance)); |
| |
| VerifyOrExit(aInstanceBuffer != NULL, ;); |
| |
| // Construct the context |
| aInstance = new(aInstanceBuffer)otInstance(); |
| |
| // restore datasets and network information |
| otPlatSettingsInit(aInstance); |
| aInstance->mThreadNetif.GetMle().Restore(); |
| |
| exit: |
| |
| otLogFuncExit(); |
| return aInstance; |
| } |
| |
| #else |
| |
| otInstance *otInstanceInit() |
| { |
| otLogFuncEntry(); |
| |
| otLogInfoApi("otInstanceInit"); |
| |
| VerifyOrExit(sInstance == NULL, ;); |
| |
| // Construct the context |
| sInstance = new(&sInstanceRaw)otInstance(); |
| |
| // restore datasets and network information |
| otPlatSettingsInit(sInstance); |
| sInstance->mThreadNetif.GetMle().Restore(); |
| |
| exit: |
| |
| otLogFuncExit(); |
| return sInstance; |
| } |
| |
| #endif |
| |
| |
| void otSetReceiveDiagnosticGetCallback(otInstance *aInstance, otReceiveDiagnosticGetCallback aCallback, |
| void *aCallbackContext) |
| { |
| aInstance->mThreadNetif.GetNetworkDiagnostic().SetReceiveDiagnosticGetCallback(aCallback, aCallbackContext); |
| } |
| |
| ThreadError otSendDiagnosticGet(otInstance *aInstance, const otIp6Address *aDestination, const uint8_t aTlvTypes[], |
| uint8_t aCount) |
| { |
| return aInstance->mThreadNetif.GetNetworkDiagnostic().SendDiagnosticGet(*static_cast<const Ip6::Address *> |
| (aDestination), |
| aTlvTypes, |
| aCount); |
| } |
| |
| ThreadError otSendDiagnosticReset(otInstance *aInstance, const otIp6Address *aDestination, const uint8_t aTlvTypes[], |
| uint8_t aCount) |
| { |
| return aInstance->mThreadNetif.GetNetworkDiagnostic().SendDiagnosticReset(*static_cast<const Ip6::Address *> |
| (aDestination), |
| aTlvTypes, |
| aCount); |
| } |
| |
| void otInstanceFinalize(otInstance *aInstance) |
| { |
| otLogFuncEntry(); |
| |
| // Ensure we are disabled |
| (void)otThreadStop(aInstance); |
| (void)otInterfaceDown(aInstance); |
| |
| #ifndef OPENTHREAD_MULTIPLE_INSTANCE |
| sInstance = NULL; |
| #endif |
| otLogFuncExit(); |
| } |
| |
| ThreadError otInterfaceUp(otInstance *aInstance) |
| { |
| ThreadError error = kThreadError_None; |
| |
| otLogFuncEntry(); |
| |
| #if OPENTHREAD_ENABLE_RAW_LINK_API |
| VerifyOrExit(!aInstance->mLinkRaw.IsEnabled(), error = kThreadError_InvalidState); |
| #endif // OPENTHREAD_ENABLE_RAW_LINK_API |
| |
| error = aInstance->mThreadNetif.Up(); |
| |
| #if OPENTHREAD_ENABLE_RAW_LINK_API |
| exit: |
| #endif // OPENTHREAD_ENABLE_RAW_LINK_API |
| otLogFuncExitErr(error); |
| return error; |
| } |
| |
| ThreadError otInterfaceDown(otInstance *aInstance) |
| { |
| ThreadError error = kThreadError_None; |
| |
| otLogFuncEntry(); |
| |
| #if OPENTHREAD_ENABLE_RAW_LINK_API |
| VerifyOrExit(!aInstance->mLinkRaw.IsEnabled(), error = kThreadError_InvalidState); |
| #endif // OPENTHREAD_ENABLE_RAW_LINK_API |
| |
| error = aInstance->mThreadNetif.Down(); |
| |
| #if OPENTHREAD_ENABLE_RAW_LINK_API |
| exit: |
| #endif // OPENTHREAD_ENABLE_RAW_LINK_API |
| otLogFuncExitErr(error); |
| return error; |
| } |
| |
| bool otIsInterfaceUp(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.IsUp(); |
| } |
| |
| ThreadError otThreadStart(otInstance *aInstance) |
| { |
| ThreadError error = kThreadError_None; |
| |
| otLogFuncEntry(); |
| |
| VerifyOrExit(aInstance->mThreadNetif.GetMac().GetPanId() != Mac::kPanIdBroadcast, error = kThreadError_InvalidState); |
| |
| error = aInstance->mThreadNetif.GetMle().Start(true); |
| |
| exit: |
| otLogFuncExitErr(error); |
| return error; |
| } |
| |
| ThreadError otThreadStop(otInstance *aInstance) |
| { |
| ThreadError error = kThreadError_None; |
| |
| otLogFuncEntry(); |
| |
| error = aInstance->mThreadNetif.GetMle().Stop(true); |
| |
| otLogFuncExitErr(error); |
| return error; |
| } |
| |
| bool otIsSingleton(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().IsSingleton(); |
| } |
| |
| ThreadError otActiveScan(otInstance *aInstance, uint32_t aScanChannels, uint16_t aScanDuration, |
| otHandleActiveScanResult aCallback, void *aCallbackContext) |
| { |
| aInstance->mActiveScanCallback = aCallback; |
| aInstance->mActiveScanCallbackContext = aCallbackContext; |
| return aInstance->mThreadNetif.GetMac().ActiveScan(aScanChannels, aScanDuration, &HandleActiveScanResult, aInstance); |
| } |
| |
| bool otIsActiveScanInProgress(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().IsActiveScanInProgress(); |
| } |
| |
| void HandleActiveScanResult(void *aContext, Mac::Frame *aFrame) |
| { |
| otInstance *aInstance = static_cast<otInstance *>(aContext); |
| otActiveScanResult result; |
| Mac::Address address; |
| Mac::Beacon *beacon; |
| uint8_t payloadLength; |
| |
| memset(&result, 0, sizeof(otActiveScanResult)); |
| |
| if (aFrame == NULL) |
| { |
| aInstance->mActiveScanCallback(NULL, aInstance->mActiveScanCallbackContext); |
| ExitNow(); |
| } |
| |
| SuccessOrExit(aFrame->GetSrcAddr(address)); |
| VerifyOrExit(address.mLength == sizeof(address.mExtAddress), ;); |
| memcpy(&result.mExtAddress, &address.mExtAddress, sizeof(result.mExtAddress)); |
| |
| aFrame->GetSrcPanId(result.mPanId); |
| result.mChannel = aFrame->GetChannel(); |
| result.mRssi = aFrame->GetPower(); |
| result.mLqi = aFrame->GetLqi(); |
| |
| payloadLength = aFrame->GetPayloadLength(); |
| beacon = reinterpret_cast<Mac::Beacon *>(aFrame->GetPayload()); |
| |
| if (payloadLength >= sizeof(*beacon) && beacon->IsValid()) |
| { |
| result.mVersion = beacon->GetProtocolVersion(); |
| result.mIsJoinable = beacon->IsJoiningPermitted(); |
| result.mIsNative = beacon->IsNative(); |
| memcpy(&result.mNetworkName, beacon->GetNetworkName(), sizeof(result.mNetworkName)); |
| memcpy(&result.mExtendedPanId, beacon->GetExtendedPanId(), sizeof(result.mExtendedPanId)); |
| } |
| |
| aInstance->mActiveScanCallback(&result, aInstance->mActiveScanCallbackContext); |
| |
| exit: |
| return; |
| } |
| |
| ThreadError otEnergyScan(otInstance *aInstance, uint32_t aScanChannels, uint16_t aScanDuration, |
| otHandleEnergyScanResult aCallback, void *aCallbackContext) |
| { |
| aInstance->mEnergyScanCallback = aCallback; |
| aInstance->mEnergyScanCallbackContext = aCallbackContext; |
| return aInstance->mThreadNetif.GetMac().EnergyScan(aScanChannels, aScanDuration, &HandleEnergyScanResult, aInstance); |
| } |
| |
| void HandleEnergyScanResult(void *aContext, otEnergyScanResult *aResult) |
| { |
| otInstance *aInstance = static_cast<otInstance *>(aContext); |
| |
| aInstance->mEnergyScanCallback(aResult, aInstance->mEnergyScanCallbackContext); |
| } |
| |
| bool otIsEnergyScanInProgress(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMac().IsEnergyScanInProgress(); |
| } |
| |
| ThreadError otDiscover(otInstance *aInstance, uint32_t aScanChannels, uint16_t aScanDuration, uint16_t aPanId, |
| otHandleActiveScanResult aCallback, void *aCallbackContext) |
| { |
| return aInstance->mThreadNetif.GetMle().Discover(aScanChannels, aScanDuration, aPanId, false, aCallback, |
| aCallbackContext); |
| } |
| |
| bool otIsDiscoverInProgress(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMle().IsDiscoverInProgress(); |
| } |
| |
| ThreadError otSendMacDataRequest(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetMeshForwarder().SendMacDataRequest(); |
| } |
| |
| void otSetReceiveIp6DatagramCallback(otInstance *aInstance, otReceiveIp6DatagramCallback aCallback, |
| void *aCallbackContext) |
| { |
| aInstance->mIp6.SetReceiveDatagramCallback(aCallback, aCallbackContext); |
| } |
| |
| bool otIsReceiveIp6DatagramFilterEnabled(otInstance *aInstance) |
| { |
| return aInstance->mIp6.IsReceiveIp6FilterEnabled(); |
| } |
| |
| void otSetReceiveIp6DatagramFilterEnabled(otInstance *aInstance, bool aEnabled) |
| { |
| aInstance->mIp6.SetReceiveIp6FilterEnabled(aEnabled); |
| } |
| |
| ThreadError otSendIp6Datagram(otInstance *aInstance, otMessage aMessage) |
| { |
| ThreadError error; |
| |
| otLogFuncEntry(); |
| |
| error = aInstance->mIp6.HandleDatagram(*static_cast<Message *>(aMessage), NULL, |
| aInstance->mThreadNetif.GetInterfaceId(), NULL, true); |
| |
| otLogFuncExitErr(error); |
| |
| return error; |
| } |
| |
| otMessage otNewUdpMessage(otInstance *aInstance, bool aLinkSecurityEnabled) |
| { |
| Message *message = aInstance->mIp6.mUdp.NewMessage(0); |
| |
| if (message) |
| { |
| message->SetLinkSecurityEnabled(aLinkSecurityEnabled); |
| } |
| |
| return message; |
| } |
| |
| otMessage otNewIp6Message(otInstance *aInstance, bool aLinkSecurityEnabled) |
| { |
| Message *message = aInstance->mIp6.mMessagePool.New(Message::kTypeIp6, 0); |
| |
| if (message) |
| { |
| message->SetLinkSecurityEnabled(aLinkSecurityEnabled); |
| } |
| |
| return message; |
| } |
| |
| ThreadError otFreeMessage(otMessage aMessage) |
| { |
| return static_cast<Message *>(aMessage)->Free(); |
| } |
| |
| uint16_t otGetMessageLength(otMessage aMessage) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| return message->GetLength(); |
| } |
| |
| ThreadError otSetMessageLength(otMessage aMessage, uint16_t aLength) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| return message->SetLength(aLength); |
| } |
| |
| uint16_t otGetMessageOffset(otMessage aMessage) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| return message->GetOffset(); |
| } |
| |
| ThreadError otSetMessageOffset(otMessage aMessage, uint16_t aOffset) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| return message->SetOffset(aOffset); |
| } |
| |
| bool otIsMessageLinkSecurityEnabled(otMessage aMessage) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| return message->IsLinkSecurityEnabled(); |
| } |
| |
| void otMessageSetDirectTransmission(otMessage aMessage, bool aEnabled) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| |
| if (aEnabled) |
| { |
| message->SetDirectTransmission(); |
| } |
| else |
| { |
| message->ClearDirectTransmission(); |
| } |
| } |
| |
| ThreadError otAppendMessage(otMessage aMessage, const void *aBuf, uint16_t aLength) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| return message->Append(aBuf, aLength); |
| } |
| |
| int otReadMessage(otMessage aMessage, uint16_t aOffset, void *aBuf, uint16_t aLength) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| return message->Read(aOffset, aLength, aBuf); |
| } |
| |
| int otWriteMessage(otMessage aMessage, uint16_t aOffset, const void *aBuf, uint16_t aLength) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| return message->Write(aOffset, aLength, aBuf); |
| } |
| |
| void otMessageQueueInit(otMessageQueue *aQueue) |
| { |
| aQueue->mData = NULL; |
| } |
| |
| ThreadError otMessageQueueEnqueue(otMessageQueue *aQueue, otMessage aMessage) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| MessageQueue *queue = static_cast<MessageQueue *>(aQueue); |
| return queue->Enqueue(*message); |
| } |
| |
| ThreadError otMessageQueueDequeue(otMessageQueue *aQueue, otMessage aMessage) |
| { |
| Message *message = static_cast<Message *>(aMessage); |
| MessageQueue *queue = static_cast<MessageQueue *>(aQueue); |
| return queue->Dequeue(*message); |
| } |
| |
| otMessage otMessageQueueGetHead(otMessageQueue *aQueue) |
| { |
| MessageQueue *queue = static_cast<MessageQueue *>(aQueue); |
| return queue->GetHead(); |
| } |
| |
| otMessage otMessageQueueGetNext(otMessageQueue *aQueue, otMessage aMessage) |
| { |
| Message *next; |
| Message *message = static_cast<Message *>(aMessage); |
| MessageQueue *queue = static_cast<MessageQueue *>(aQueue); |
| |
| VerifyOrExit(message != NULL, next = NULL); |
| VerifyOrExit(message->GetMessageQueue() == queue, next = NULL); |
| next = message->GetNext(); |
| |
| exit: |
| return next; |
| } |
| |
| ThreadError otOpenUdpSocket(otInstance *aInstance, otUdpSocket *aSocket, otUdpReceive aCallback, void *aCallbackContext) |
| { |
| ThreadError error = kThreadError_InvalidArgs; |
| Ip6::UdpSocket *socket = static_cast<Ip6::UdpSocket *>(aSocket); |
| |
| if (socket->mTransport == NULL) |
| { |
| socket->mTransport = &aInstance->mIp6.mUdp; |
| error = socket->Open(aCallback, aCallbackContext); |
| } |
| |
| return error; |
| } |
| |
| ThreadError otCloseUdpSocket(otUdpSocket *aSocket) |
| { |
| ThreadError error = kThreadError_InvalidState; |
| Ip6::UdpSocket *socket = static_cast<Ip6::UdpSocket *>(aSocket); |
| |
| if (socket->mTransport != NULL) |
| { |
| error = socket->Close(); |
| |
| if (error == kThreadError_None) |
| { |
| socket->mTransport = NULL; |
| } |
| } |
| |
| return error; |
| } |
| |
| ThreadError otBindUdpSocket(otUdpSocket *aSocket, otSockAddr *aSockName) |
| { |
| Ip6::UdpSocket *socket = static_cast<Ip6::UdpSocket *>(aSocket); |
| return socket->Bind(*static_cast<const Ip6::SockAddr *>(aSockName)); |
| } |
| |
| ThreadError otSendUdp(otUdpSocket *aSocket, otMessage aMessage, const otMessageInfo *aMessageInfo) |
| { |
| Ip6::UdpSocket *socket = static_cast<Ip6::UdpSocket *>(aSocket); |
| return socket->SendTo(*static_cast<Message *>(aMessage), |
| *static_cast<const Ip6::MessageInfo *>(aMessageInfo)); |
| } |
| |
| bool otIsIcmpEchoEnabled(otInstance *aInstance) |
| { |
| return aInstance->mIp6.mIcmp.IsEchoEnabled(); |
| } |
| |
| void otSetIcmpEchoEnabled(otInstance *aInstance, bool aEnabled) |
| { |
| aInstance->mIp6.mIcmp.SetEchoEnabled(aEnabled); |
| } |
| |
| uint8_t otIp6PrefixMatch(const otIp6Address *aFirst, const otIp6Address *aSecond) |
| { |
| uint8_t rval; |
| |
| VerifyOrExit(aFirst != NULL && aSecond != NULL, rval = 0); |
| |
| rval = static_cast<const Ip6::Address *>(aFirst)->PrefixMatch(*static_cast<const Ip6::Address *>(aSecond)); |
| |
| exit: |
| return rval; |
| } |
| |
| ThreadError otGetActiveDataset(otInstance *aInstance, otOperationalDataset *aDataset) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aDataset != NULL, error = kThreadError_InvalidArgs); |
| |
| aInstance->mThreadNetif.GetActiveDataset().GetLocal().Get(*aDataset); |
| |
| exit: |
| return error; |
| } |
| |
| ThreadError otSetActiveDataset(otInstance *aInstance, const otOperationalDataset *aDataset) |
| { |
| ThreadError error; |
| |
| VerifyOrExit(aDataset != NULL, error = kThreadError_InvalidArgs); |
| |
| error = aInstance->mThreadNetif.GetActiveDataset().Set(*aDataset); |
| |
| exit: |
| return error; |
| } |
| |
| bool otIsNodeCommissioned(otInstance *aInstance) |
| { |
| otOperationalDataset dataset; |
| |
| otGetActiveDataset(aInstance, &dataset); |
| |
| if ((dataset.mIsMasterKeySet) && (dataset.mIsNetworkNameSet) && |
| (dataset.mIsExtendedPanIdSet) && (dataset.mIsPanIdSet) && (dataset.mIsChannelSet)) |
| { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| ThreadError otGetPendingDataset(otInstance *aInstance, otOperationalDataset *aDataset) |
| { |
| ThreadError error = kThreadError_None; |
| |
| VerifyOrExit(aDataset != NULL, error = kThreadError_InvalidArgs); |
| |
| aInstance->mThreadNetif.GetPendingDataset().GetLocal().Get(*aDataset); |
| |
| exit: |
| return error; |
| } |
| |
| ThreadError otSetPendingDataset(otInstance *aInstance, const otOperationalDataset *aDataset) |
| { |
| ThreadError error; |
| |
| VerifyOrExit(aDataset != NULL, error = kThreadError_InvalidArgs); |
| |
| error = aInstance->mThreadNetif.GetPendingDataset().Set(*aDataset); |
| |
| exit: |
| return error; |
| } |
| |
| ThreadError otSendActiveGet(otInstance *aInstance, const uint8_t *aTlvTypes, uint8_t aLength, |
| const otIp6Address *aAddress) |
| { |
| return aInstance->mThreadNetif.GetActiveDataset().SendGetRequest(aTlvTypes, aLength, aAddress); |
| } |
| |
| ThreadError otSendActiveSet(otInstance *aInstance, const otOperationalDataset *aDataset, const uint8_t *aTlvs, |
| uint8_t aLength) |
| { |
| return aInstance->mThreadNetif.GetActiveDataset().SendSetRequest(*aDataset, aTlvs, aLength); |
| } |
| |
| ThreadError otSendPendingGet(otInstance *aInstance, const uint8_t *aTlvTypes, uint8_t aLength, |
| const otIp6Address *aAddress) |
| { |
| return aInstance->mThreadNetif.GetPendingDataset().SendGetRequest(aTlvTypes, aLength, aAddress); |
| } |
| |
| ThreadError otSendPendingSet(otInstance *aInstance, const otOperationalDataset *aDataset, const uint8_t *aTlvs, |
| uint8_t aLength) |
| { |
| return aInstance->mThreadNetif.GetPendingDataset().SendSetRequest(*aDataset, aTlvs, aLength); |
| } |
| |
| #if OPENTHREAD_ENABLE_COMMISSIONER |
| #include <commissioning/commissioner.h> |
| ThreadError otCommissionerStart(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().Start(); |
| } |
| |
| ThreadError otCommissionerStop(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().Stop(); |
| } |
| |
| ThreadError otCommissionerAddJoiner(otInstance *aInstance, const otExtAddress *aExtAddress, const char *aPSKd) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().AddJoiner(static_cast<const Mac::ExtAddress *>(aExtAddress), aPSKd); |
| } |
| |
| ThreadError otCommissionerRemoveJoiner(otInstance *aInstance, const otExtAddress *aExtAddress) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().RemoveJoiner(static_cast<const Mac::ExtAddress *>(aExtAddress)); |
| } |
| |
| ThreadError otCommissionerSetProvisioningUrl(otInstance *aInstance, const char *aProvisioningUrl) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().SetProvisioningUrl(aProvisioningUrl); |
| } |
| |
| ThreadError otCommissionerAnnounceBegin(otInstance *aInstance, uint32_t aChannelMask, uint8_t aCount, uint16_t aPeriod, |
| const otIp6Address *aAddress) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().mAnnounceBegin.SendRequest(aChannelMask, aCount, aPeriod, |
| *static_cast<const Ip6::Address *>(aAddress)); |
| } |
| |
| ThreadError otCommissionerEnergyScan(otInstance *aInstance, uint32_t aChannelMask, uint8_t aCount, uint16_t aPeriod, |
| uint16_t aScanDuration, const otIp6Address *aAddress, |
| otCommissionerEnergyReportCallback aCallback, void *aContext) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().mEnergyScan.SendQuery(aChannelMask, aCount, aPeriod, aScanDuration, |
| *static_cast<const Ip6::Address *>(aAddress), |
| aCallback, aContext); |
| } |
| |
| ThreadError otCommissionerPanIdQuery(otInstance *aInstance, uint16_t aPanId, uint32_t aChannelMask, |
| const otIp6Address *aAddress, |
| otCommissionerPanIdConflictCallback aCallback, void *aContext) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().mPanIdQuery.SendQuery( |
| aPanId, aChannelMask, *static_cast<const Ip6::Address *>(aAddress), aCallback, aContext); |
| } |
| |
| ThreadError otSendMgmtCommissionerGet(otInstance *aInstance, const uint8_t *aTlvs, uint8_t aLength) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().SendMgmtCommissionerGetRequest(aTlvs, aLength); |
| } |
| |
| ThreadError otSendMgmtCommissionerSet(otInstance *aInstance, const otCommissioningDataset *aDataset, |
| const uint8_t *aTlvs, uint8_t aLength) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().SendMgmtCommissionerSetRequest(*aDataset, aTlvs, aLength); |
| } |
| |
| uint16_t otCommissionerGetSessionId(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().GetSessionId(); |
| } |
| |
| ThreadError otCommissionerGeneratePSKc(otInstance *aInstance, const char *aPassPhrase, const char *aNetworkName, |
| const uint8_t *aExtPanId, uint8_t *aPSKc) |
| { |
| return aInstance->mThreadNetif.GetCommissioner().GeneratePSKc(aPassPhrase, aNetworkName, aExtPanId, aPSKc); |
| } |
| #endif // OPENTHREAD_ENABLE_COMMISSIONER |
| |
| #if OPENTHREAD_ENABLE_JOINER |
| ThreadError otJoinerStart(otInstance *aInstance, const char *aPSKd, const char *aProvisioningUrl, |
| const char *aVendorName, const char *aVendorModel, |
| const char *aVendorSwVersion, const char *aVendorData, |
| otJoinerCallback aCallback, void *aContext) |
| { |
| return aInstance->mThreadNetif.GetJoiner().Start(aPSKd, aProvisioningUrl, |
| aVendorName, aVendorModel, aVendorSwVersion, aVendorData, |
| aCallback, aContext); |
| } |
| |
| ThreadError otJoinerStop(otInstance *aInstance) |
| { |
| return aInstance->mThreadNetif.GetJoiner().Stop(); |
| } |
| #endif // OPENTHREAD_ENABLE_JOINER |
| |
| #if OPENTHREAD_ENABLE_APPLICATION_COAP |
| void otCoapHeaderInit(otCoapHeader *aHeader, otCoapType aType, otCoapCode aCode) |
| { |
| Coap::Header *header = static_cast<Coap::Header *>(aHeader); |
| header->Init(aType, aCode); |
| } |
| |
| void otCoapHeaderSetToken(otCoapHeader *aHeader, const uint8_t *aToken, uint8_t aTokenLength) |
| { |
| static_cast<Coap::Header *>(aHeader)->SetToken(aToken, aTokenLength); |
| } |
| |
| void otCoapHeaderGenerateToken(otCoapHeader *aHeader, uint8_t aTokenLength) |
| { |
| static_cast<Coap::Header *>(aHeader)->SetToken(aTokenLength); |
| } |
| |
| ThreadError otCoapHeaderAppendOption(otCoapHeader *aHeader, const otCoapOption *aOption) |
| { |
| return static_cast<Coap::Header *>(aHeader)->AppendOption(*static_cast<const Coap::Header::Option *>(aOption)); |
| } |
| |
| ThreadError otCoapHeaderAppendUriPathOptions(otCoapHeader *aHeader, const char *aUriPath) |
| { |
| return static_cast<Coap::Header *>(aHeader)->AppendUriPathOptions(aUriPath); |
| } |
| |
| void otCoapHeaderSetPayloadMarker(otCoapHeader *aHeader) |
| { |
| static_cast<Coap::Header *>(aHeader)->SetPayloadMarker(); |
| } |
| |
| void otCoapHeaderSetMessageId(otCoapHeader *aHeader, uint16_t aMessageId) |
| { |
| return static_cast<Coap::Header *>(aHeader)->SetMessageId(aMessageId); |
| } |
| |
| otCoapType otCoapHeaderGetType(const otCoapHeader *aHeader) |
| { |
| return static_cast<const Coap::Header *>(aHeader)->GetType(); |
| } |
| |
| otCoapCode otCoapHeaderGetCode(const otCoapHeader *aHeader) |
| { |
| return static_cast<const Coap::Header *>(aHeader)->GetCode(); |
| } |
| |
| uint16_t otCoapHeaderGetMessageId(const otCoapHeader *aHeader) |
| { |
| return static_cast<const Coap::Header *>(aHeader)->GetMessageId(); |
| } |
| |
| uint8_t otCoapHeaderGetTokenLength(const otCoapHeader *aHeader) |
| { |
| return static_cast<const Coap::Header *>(aHeader)->GetTokenLength(); |
| } |
| |
| const uint8_t *otCoapHeaderGetToken(const otCoapHeader *aHeader) |
| { |
| return static_cast<const Coap::Header *>(aHeader)->GetToken(); |
| } |
| |
| const otCoapOption *otCoapHeaderGetCurrentOption(const otCoapHeader *aHeader) |
| { |
| return static_cast<const otCoapOption *>(static_cast<const Coap::Header *>(aHeader)->GetCurrentOption()); |
| } |
| |
| const otCoapOption *otCoapHeaderGetNextOption(otCoapHeader *aHeader) |
| { |
| return static_cast<const otCoapOption *>(static_cast<Coap::Header *>(aHeader)->GetNextOption()); |
| } |
| |
| otMessage otCoapNewMessage(otInstance *aInstance, const otCoapHeader *aHeader) |
| { |
| return aInstance->mThreadNetif.GetCoapClient().NewMessage(*(static_cast<const Coap::Header *>(aHeader))); |
| } |
| |
| ThreadError otCoapSendRequest(otInstance *aInstance, otMessage aMessage, const otMessageInfo *aMessageInfo, |
| otCoapResponseHandler aHandler, void *aContext) |
| { |
| return aInstance->mThreadNetif.GetCoapClient().SendMessage( |
| *static_cast<Message *>(aMessage), |
| *static_cast<const Ip6::MessageInfo *>(aMessageInfo), |
| aHandler, aContext); |
| } |
| |
| ThreadError otCoapServerStart(otInstance *aInstance) |
| { |
| return aInstance->mApplicationCoapServer.Start(); |
| } |
| |
| ThreadError otCoapServerStop(otInstance *aInstance) |
| { |
| return aInstance->mApplicationCoapServer.Stop(); |
| } |
| |
| ThreadError otCoapServerSetPort(otInstance *aInstance, uint16_t aPort) |
| { |
| return aInstance->mApplicationCoapServer.SetPort(aPort); |
| } |
| |
| ThreadError otCoapServerAddResource(otInstance *aInstance, otCoapResource *aResource) |
| { |
| return aInstance->mApplicationCoapServer.AddResource(*static_cast<Coap::Resource *>(aResource)); |
| } |
| |
| void otCoapServerRemoveResource(otInstance *aInstance, otCoapResource *aResource) |
| { |
| aInstance->mApplicationCoapServer.RemoveResource(*static_cast<Coap::Resource *>(aResource)); |
| } |
| |
| ThreadError otCoapSendResponse(otInstance *aInstance, otMessage aMessage, const otMessageInfo *aMessageInfo) |
| { |
| return aInstance->mApplicationCoapServer.SendMessage( |
| *static_cast<Message *>(aMessage), *static_cast<const Ip6::MessageInfo *>(aMessageInfo)); |
| } |
| #endif // OPENTHREAD_ENABLE_APPLICATION_COAP |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |