Exemple #1
0
otError ThreadNetif::Down(void)
{
    VerifyOrExit(mIsUp);

#if OPENTHREAD_ENABLE_DTLS
    mDtls.Stop();
#endif
#if OPENTHREAD_ENABLE_DNS_CLIENT
    mDnsClient.Stop();
#endif
#if OPENTHREAD_ENABLE_SNTP_CLIENT
    mSntpClient.Stop();
#endif
    mCoap.Stop();
    mMleRouter.Disable();
    RemoveAllExternalUnicastAddresses();
    UnsubscribeAllExternalMulticastAddresses();
    UnsubscribeAllRoutersMulticast();
    UnsubscribeAllNodesMulticast();

    mIsUp = false;
    GetIp6().RemoveNetif(*this);
    mMeshForwarder.Stop();
#if OPENTHREAD_ENABLE_CHANNEL_MONITOR
    GetInstance().GetChannelMonitor().Stop();
#endif
    GetNotifier().Signal(OT_CHANGED_THREAD_NETIF_STATE);

exit:
    return OT_ERROR_NONE;
}
Exemple #2
0
otError Netif::SubscribeAllRoutersMulticast(void)
{
    otError error = OT_ERROR_NONE;

    if (mMulticastAddresses == &kLinkLocalAllNodesMulticastAddress)
    {
        mMulticastAddresses = static_cast<NetifMulticastAddress *>(
            const_cast<otNetifMulticastAddress *>(&kLinkLocalAllRoutersMulticastAddress));
    }
    else
    {
        for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
        {
            if (cur == &kLinkLocalAllRoutersMulticastAddress)
            {
                ExitNow(error = OT_ERROR_ALREADY);
            }

            if (cur->mNext == &kLinkLocalAllNodesMulticastAddress)
            {
                cur->mNext = &kLinkLocalAllRoutersMulticastAddress;
                break;
            }
        }
    }

    GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED);

exit:
    return error;
}
Exemple #3
0
otError Netif::UnsubscribeMulticast(const NetifMulticastAddress &aAddress)
{
    otError error = OT_ERROR_NONE;

    if (mMulticastAddresses == &aAddress)
    {
        mMulticastAddresses = mMulticastAddresses->GetNext();
        ExitNow();
    }
    else if (mMulticastAddresses != NULL)
    {
        for (NetifMulticastAddress *cur = mMulticastAddresses; cur->GetNext(); cur = cur->GetNext())
        {
            if (cur->mNext == &aAddress)
            {
                cur->mNext = aAddress.mNext;
                ExitNow();
            }
        }
    }

    ExitNow(error = OT_ERROR_NOT_FOUND);

exit:

    if (error != OT_ERROR_NOT_FOUND)
    {
        GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED);
    }

    return error;
}
Exemple #4
0
otError Netif::SubscribeExternalMulticast(const Address &aAddress)
{
    otError                error = OT_ERROR_NONE;
    NetifMulticastAddress *entry;
    size_t                 num = sizeof(mExtMulticastAddresses) / sizeof(mExtMulticastAddresses[0]);

    if (IsMulticastSubscribed(aAddress))
    {
        ExitNow(error = OT_ERROR_ALREADY);
    }

    // Find an available entry in the `mExtMulticastAddresses` array.
    for (entry = &mExtMulticastAddresses[0]; num > 0; num--, entry++)
    {
        // In an unused/available entry, `mNext` points back to the entry itself.
        if (entry->mNext == entry)
        {
            break;
        }
    }

    VerifyOrExit(num > 0, error = OT_ERROR_NO_BUFS);

    // Copy the address into the available entry and add it to linked-list.
    entry->mAddress     = aAddress;
    entry->mNext        = mMulticastAddresses;
    mMulticastAddresses = entry;
    GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED);

exit:
    return error;
}
Exemple #5
0
otError Netif::RemoveUnicastAddress(const NetifUnicastAddress &aAddress)
{
    otError error = OT_ERROR_NONE;

    if (mUnicastAddresses == &aAddress)
    {
        mUnicastAddresses = mUnicastAddresses->GetNext();
        ExitNow();
    }
    else if (mUnicastAddresses != NULL)
    {
        for (NetifUnicastAddress *cur = mUnicastAddresses; cur->GetNext(); cur = cur->GetNext())
        {
            if (cur->mNext == &aAddress)
            {
                cur->mNext = aAddress.mNext;
                ExitNow();
            }
        }
    }

    ExitNow(error = OT_ERROR_NOT_FOUND);

exit:

    if (error != OT_ERROR_NOT_FOUND)
    {
        GetNotifier().SetFlags(aAddress.mRloc ? OT_CHANGED_THREAD_RLOC_REMOVED : OT_CHANGED_IP6_ADDRESS_REMOVED);
    }

    return error;
}
Exemple #6
0
otError Netif::UnsubscribeAllRoutersMulticast(void)
{
    otError error = OT_ERROR_NONE;

    if (mMulticastAddresses == &kLinkLocalAllRoutersMulticastAddress)
    {
        mMulticastAddresses = static_cast<NetifMulticastAddress *>(
            const_cast<otNetifMulticastAddress *>(&kLinkLocalAllNodesMulticastAddress));
        ExitNow();
    }

    for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
    {
        if (cur->mNext == &kLinkLocalAllRoutersMulticastAddress)
        {
            cur->mNext = &kLinkLocalAllNodesMulticastAddress;
            ExitNow();
        }
    }

    error = OT_ERROR_NOT_FOUND;

exit:

    if (error != OT_ERROR_NOT_FOUND)
    {
        GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED);
    }

    return error;
}
Exemple #7
0
otError ThreadNetif::Up(void)
{
    VerifyOrExit(!mIsUp);

    // Enable the MAC just in case it was disabled while the Interface was down.
    mMac.SetEnabled(true);
#if OPENTHREAD_ENABLE_CHANNEL_MONITOR
    GetInstance().GetChannelMonitor().Start();
#endif
    mMeshForwarder.Start();
    GetIp6().AddNetif(*this);

    mIsUp = true;

    SubscribeAllNodesMulticast();
    mMleRouter.Enable();
    mCoap.Start(kCoapUdpPort);
#if OPENTHREAD_ENABLE_DNS_CLIENT
    mDnsClient.Start();
#endif
#if OPENTHREAD_ENABLE_SNTP_CLIENT
    mSntpClient.Start();
#endif
    GetNotifier().Signal(OT_CHANGED_THREAD_NETIF_STATE);

exit:
    return OT_ERROR_NONE;
}
Exemple #8
0
otError Joiner::Start(const char *     aPSKd,
                      const char *     aProvisioningUrl,
                      const char *     aVendorName,
                      const char *     aVendorModel,
                      const char *     aVendorSwVersion,
                      const char *     aVendorData,
                      otJoinerCallback aCallback,
                      void *           aContext)
{
    ThreadNetif &   netif = GetNetif();
    otError         error;
    Mac::ExtAddress joinerId;
    Crc16           ccitt(Crc16::kCcitt);
    Crc16           ansi(Crc16::kAnsi);

    VerifyOrExit(mState == OT_JOINER_STATE_IDLE, error = OT_ERROR_BUSY);

    GetNotifier().Signal(OT_CHANGED_JOINER_STATE);

    // use extended address based on factory-assigned IEEE EUI-64
    GetJoinerId(joinerId);
    netif.GetMac().SetExtAddress(joinerId);
    netif.GetMle().UpdateLinkLocalAddress();

    for (size_t i = 0; i < sizeof(joinerId); i++)
    {
        ccitt.Update(joinerId.m8[i]);
        ansi.Update(joinerId.m8[i]);
    }

    mCcitt = ccitt.Get();
    mAnsi  = ansi.Get();

    error = netif.GetCoapSecure().Start(OPENTHREAD_CONFIG_JOINER_UDP_PORT);
    SuccessOrExit(error);

    error = netif.GetCoapSecure().SetPsk(reinterpret_cast<const uint8_t *>(aPSKd), static_cast<uint8_t>(strlen(aPSKd)));
    SuccessOrExit(error);

    error = netif.GetCoapSecure().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl);
    SuccessOrExit(error);

    memset(mJoinerRouters, 0, sizeof(mJoinerRouters));

    SuccessOrExit(error =
                      netif.GetMle().Discover(0, netif.GetMac().GetPanId(), true, false, HandleDiscoverResult, this));

    mVendorName      = aVendorName;
    mVendorModel     = aVendorModel;
    mVendorSwVersion = aVendorSwVersion;
    mVendorData      = aVendorData;
    mCallback        = aCallback;
    mContext         = aContext;
    mState           = OT_JOINER_STATE_DISCOVER;

exit:
    return error;
}
Exemple #9
0
otError Netif::AddExternalUnicastAddress(const NetifUnicastAddress &aAddress)
{
    otError              error = OT_ERROR_NONE;
    NetifUnicastAddress *entry;
    size_t               num = sizeof(mExtUnicastAddresses) / sizeof(mExtUnicastAddresses[0]);

    VerifyOrExit(!aAddress.GetAddress().IsLinkLocal(), error = OT_ERROR_INVALID_ARGS);

    for (entry = mUnicastAddresses; entry; entry = entry->GetNext())
    {
        if (entry->GetAddress() == aAddress.GetAddress())
        {
            VerifyOrExit((entry >= &mExtUnicastAddresses[0]) && (entry < &mExtUnicastAddresses[num]),
                         error = OT_ERROR_INVALID_ARGS);

            entry->mPrefixLength = aAddress.mPrefixLength;
            entry->mPreferred    = aAddress.mPreferred;
            entry->mValid        = aAddress.mValid;
            ExitNow();
        }
    }

    // Find an available entry in the `mExtUnicastAddresses` array.
    for (entry = &mExtUnicastAddresses[0]; num > 0; num--, entry++)
    {
        // In an unused/available entry, `mNext` points back to the entry itself.
        if (entry->mNext == entry)
        {
            break;
        }
    }

    VerifyOrExit(num > 0, error = OT_ERROR_NO_BUFS);

    // Copy the new address into the available entry and insert it in linked-list.
    *entry            = aAddress;
    entry->mNext      = mUnicastAddresses;
    mUnicastAddresses = entry;

    GetNotifier().SetFlags(OT_CHANGED_IP6_ADDRESS_ADDED);

exit:
    return error;
}
Exemple #10
0
otError Netif::SubscribeMulticast(NetifMulticastAddress &aAddress)
{
    otError error = OT_ERROR_NONE;

    for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
    {
        if (cur == &aAddress)
        {
            ExitNow(error = OT_ERROR_ALREADY);
        }
    }

    aAddress.mNext      = mMulticastAddresses;
    mMulticastAddresses = &aAddress;
    GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED);

exit:
    return error;
}
Exemple #11
0
otError Netif::AddUnicastAddress(NetifUnicastAddress &aAddress)
{
    otError error = OT_ERROR_NONE;

    for (NetifUnicastAddress *cur = mUnicastAddresses; cur; cur = cur->GetNext())
    {
        if (cur == &aAddress)
        {
            ExitNow(error = OT_ERROR_ALREADY);
        }
    }

    aAddress.mNext    = mUnicastAddresses;
    mUnicastAddresses = &aAddress;

    GetNotifier().SetFlags(aAddress.mRloc ? OT_CHANGED_THREAD_RLOC_ADDED : OT_CHANGED_IP6_ADDRESS_ADDED);

exit:
    return error;
}
Exemple #12
0
void Joiner::Complete(otError aError)
{
    ThreadNetif &netif = GetNetif();
    mState             = OT_JOINER_STATE_IDLE;
    otError error      = OT_ERROR_NOT_FOUND;
    GetNotifier().Signal(OT_CHANGED_JOINER_STATE);

    netif.GetCoapSecure().Disconnect();

    if (aError != OT_ERROR_NONE && aError != OT_ERROR_NOT_FOUND)
    {
        error = TryNextJoin();
    }

    if (error == OT_ERROR_NOT_FOUND && mCallback)
    {
        netif.GetCoapSecure().Stop();
        otJoinerCallback callback = mCallback;
        mCallback                 = NULL;
        callback(aError, mContext);
    }
}
Exemple #13
0
otError Netif::RemoveExternalUnicastAddress(const Address &aAddress)
{
    otError              error = OT_ERROR_NONE;
    NetifUnicastAddress *entry;
    NetifUnicastAddress *last = NULL;
    size_t               num  = sizeof(mExtUnicastAddresses) / sizeof(mExtUnicastAddresses[0]);

    for (entry = mUnicastAddresses; entry; entry = entry->GetNext())
    {
        if (entry->GetAddress() == aAddress)
        {
            VerifyOrExit((entry >= &mExtUnicastAddresses[0]) && (entry < &mExtUnicastAddresses[num]),
                         error = OT_ERROR_INVALID_ARGS);

            if (last)
            {
                last->mNext = entry->mNext;
            }
            else
            {
                mUnicastAddresses = entry->GetNext();
            }

            break;
        }

        last = entry;
    }

    VerifyOrExit(entry != NULL, error = OT_ERROR_NOT_FOUND);

    // To mark the address entry as unused/available, set the `mNext` pointer back to the entry itself.
    entry->mNext = entry;

    GetNotifier().SetFlags(OT_CHANGED_IP6_ADDRESS_REMOVED);

exit:
    return error;
}
Exemple #14
0
template <> Notifier &Instance::Get(void)
{
    return GetNotifier();
}
Exemple #15
0
bool Win32Vif::InitTap(const char* vifName, const ProtoAddress& vifAddr, unsigned int maskLen)
{
	HKEY key;
    ULONG status;
	char adapterid[1024];
	char tapname[1024];
    long len;

    /// Open Registry and get a list of network adapters
    status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                          NETWORK_CONNECTIONS_KEY,
                          0,
                          KEY_READ,
                          &key);

    if (status != ERROR_SUCCESS)
    {
        PLOG(PL_ERROR,"Win32Vif::InitTap() Error opening registry key:%s\n",NETWORK_CONNECTIONS_KEY);
        return false;
    }

	/* find the adapter with TAPSUFFIX */
    for (int enum_index = 0; ; enum_index++) 
    {
		len = sizeof(adapterid);
		if (RegEnumKeyEx(key, enum_index, adapterid, (LPDWORD)&len, 
                        NULL, NULL, NULL, NULL) != ERROR_SUCCESS) 
        {
			RegCloseKey(key);
			PLOG(PL_ERROR,"Win32Vif::InitTap() error: Couldn't find TAP-Win32 adapter.\n");
			return false;
		}
		sprintf(tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid);
        // Get the tap handle
		tap_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ,
			    0, 0, OPEN_EXISTING, 
                FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
		
		if (tap_handle != INVALID_HANDLE_VALUE) 
        {
            break;
		}
	}
    
    RegCloseKey(key);
	PLOG(PL_INFO,"win32Vif::InitTap() found tap adapter %s\n",tapname);

    if (!ConfigureTap(adapterid,vifName,vifAddr,maskLen))
        return false;

    if (NULL == (input_handle = CreateEvent(NULL,TRUE,FALSE,NULL)))
    {
        input_handle = INVALID_HANDLE_VALUE;
        PLOG(PL_ERROR,"Win32Vif::InitTap() CreateEvent(input_handle) error: %s\n", ::GetErrorString());
        Close(); // ljt??
        return false;
    }
    if (NULL == (output_handle = CreateEvent(NULL,TRUE,FALSE,NULL)))
    {
        output_handle = INVALID_HANDLE_VALUE;
        PLOG(PL_ERROR,"Win32Vif::InitTap() CreateEvent(output_handle) error: %s\n",::GetErrorString());
        Close(); // ljt??
        return false;
    }
    
    memset(&read_overlapped,0,sizeof(read_overlapped));
    read_overlapped.hEvent = input_handle;
    memset(&write_overlapped,0,sizeof(write_overlapped));
    write_overlapped.hEvent = output_handle;
    
    StartInputNotification();

    // Start overlapped notifications
    if (NULL != GetNotifier())
    {
        // Initiate overlapped I/O ...
        DWORD bytesRead;
        if (0 != ReadFile(tap_handle, read_buffer, BUFFER_MAX, &bytesRead, &read_overlapped))
        {
            input_ready = true;
            read_count = bytesRead;
        }
        else
        {
            switch(GetLastError())
            {
                case ERROR_IO_PENDING:
                  read_count = 0;
                  input_ready = false;
                  break;
                //case ERROR_BROKEN_PIPE: 
                default:
                  PLOG(PL_ERROR,"Win32Vif::InitTap() ReadFile() error: %s\n", ::GetErrorString());
                  Close();
                  return false;
            }
        }
    }

    if (!UpdateNotification())
    {
        PLOG(PL_ERROR, "Win32Vif::InitTap() error updating notification\n");
        Close();
        return false;
    }

    return true;  
    
} // end Win32Vif::InitTap() 
Exemple #16
0
bool Win32Vif::Write(const char* buffer, unsigned int numBytes) 
{
    // ljt is this quite right??

    DWORD bytesWritten = 0;
    OVERLAPPED overlappedPtr;

    // set up overlapped structure fields
    overlappedPtr.Offset     = 0; 
    overlappedPtr.OffsetHigh = 0; 
    overlappedPtr.hEvent     = NULL; 

    const char* bufPtr = buffer;
    
    if (NULL != GetNotifier())
    {
        if (!output_ready)
        {
            if (FALSE != GetOverlappedResult(tap_handle,&write_overlapped,&bytesWritten,FALSE))
            {
                output_ready = true;
                overlappedPtr = write_overlapped;
                bufPtr = write_buffer;
                if (numBytes > BUFFER_MAX) numBytes = BUFFER_MAX;
                memcpy(write_buffer,buffer,numBytes);
            }
            else
            {
                if (GetDebugLevel() >= 2)
                    PLOG(PL_ERROR,"Win32Vif::Write() GetOverlappedResult() error: %s\n",::GetErrorString());
                return false;
            }
        }
    }

    if (0 != WriteFile(tap_handle,bufPtr,numBytes,&bytesWritten,(LPOVERLAPPED)&overlappedPtr))
    {
        numBytes = bytesWritten;
        if (0 == numBytes) 
        {
          output_ready = false;
        }
        return true;
    }
    else
    {
        numBytes = 0;
        switch (GetLastError())
        {
        case ERROR_IO_PENDING:
          return true;
        case ERROR_BROKEN_PIPE:
          OnNotify(NOTIFY_NONE);
          break;
        default:
          PLOG(PL_ERROR,"Win32Vif::Write() WriteFile() error(%d): %s\n",GetLastError(),::GetErrorString());
          break;
        }
        return false;
    }
    
    return true;
}  // end Win32Vif::Write()
Exemple #17
0
bool Win32Vif::Read(char* buffer, unsigned int& numBytes)  
{

    DWORD bytesRead = 0;
    unsigned int len = 0;
    if (NULL != GetNotifier())
    {
        if (!input_ready)
        {
            // We had a pending overlapped read operation
            if (FALSE != GetOverlappedResult(tap_handle,&read_overlapped,&bytesRead,FALSE))
            {
                numBytes = read_count = bytesRead;
                memcpy(buffer,read_buffer,bytesRead);
                input_ready = true;
            }
            else
            {
                numBytes = 0;
                switch (GetLastError())
                {
                case ERROR_BROKEN_PIPE:
                  OnNotify(NOTIFY_NONE);
                  return false;
                default:
                  PLOG(PL_ERROR,"Win32Vif::Read() GetOverlappedResult() error (%d): %s\n",GetLastError(), ::GetErrorString());
                  return false;
                }                
            }
        }  
    }
    // Do we have any data in our "read_buffer"? 
    if (read_count > 0)
    {
        memcpy (buffer,read_buffer,read_count);
        numBytes = read_count;
        read_count = 0;
        return true;
    }
    
    // Read more as needed, triggering overlapped I/O
    memset(&read_overlapped,0,sizeof(read_overlapped));
    read_overlapped.hEvent = input_handle;
    memset(&write_overlapped,0,sizeof(write_overlapped));
    write_overlapped.hEvent = output_handle; // ljt need me?

    bytesRead = 0;
    len = BUFFER_MAX;   
    if (0 != ReadFile(tap_handle,read_buffer,len,&bytesRead,&read_overlapped))
    {
        memcpy(buffer,read_buffer,bytesRead);
        numBytes = bytesRead;
        input_ready = true;
    }
    else
    {
        switch(GetLastError())
        {
        case ERROR_IO_PENDING:
          read_count = 0;
          input_ready = false;
          break;
        case ERROR_BROKEN_PIPE: 
          if (0 == bytesRead)
          {
              OnNotify(NOTIFY_NONE);
              return false;
          }
          break;
        default:
          PLOG(PL_ERROR,"Win32Vif::Read() error: %s\n", ::GetErrorString());
          if (0 == bytesRead) return false;
          break;
        }
    }

    numBytes = bytesRead;   
    return true;
}  // end Win32Vif::Read()