Пример #1
0
void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
    ThreadNetif &          netif = GetNetif();
    otError                error;
    Coap::Message *        message = NULL;
    Ip6::MessageInfo       messageInfo;
    JoinerUdpPortTlv       udpPort;
    JoinerIidTlv           iid;
    JoinerRouterLocatorTlv rloc;
    ExtendedTlv            tlv;
    uint16_t               borderAgentRloc;
    uint16_t               offset;

    otLogInfoMeshCoP("JoinerRouter::HandleUdpReceive");

    SuccessOrExit(error = GetBorderAgentRloc(GetNetif(), borderAgentRloc));

    VerifyOrExit((message = NewMeshCoPMessage(netif.GetCoap())) != NULL, error = OT_ERROR_NO_BUFS);

    message->Init(OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST);
    message->SetToken(Coap::Message::kDefaultTokenLength);
    message->AppendUriPathOptions(OT_URI_PATH_RELAY_RX);
    message->SetPayloadMarker();

    udpPort.Init();
    udpPort.SetUdpPort(aMessageInfo.GetPeerPort());
    SuccessOrExit(error = message->Append(&udpPort, sizeof(udpPort)));

    iid.Init();
    iid.SetIid(aMessageInfo.GetPeerAddr().mFields.m8 + 8);
    SuccessOrExit(error = message->Append(&iid, sizeof(iid)));

    rloc.Init();
    rloc.SetJoinerRouterLocator(netif.GetMle().GetRloc16());
    SuccessOrExit(error = message->Append(&rloc, sizeof(rloc)));

    tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
    tlv.SetLength(aMessage.GetLength() - aMessage.GetOffset());
    SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
    offset = message->GetLength();
    SuccessOrExit(error = message->SetLength(offset + tlv.GetLength()));
    aMessage.CopyTo(aMessage.GetOffset(), offset, tlv.GetLength(), *message);

    messageInfo.SetSockAddr(netif.GetMle().GetMeshLocal16());
    messageInfo.SetPeerAddr(netif.GetMle().GetMeshLocal16());
    messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(borderAgentRloc);
    messageInfo.SetPeerPort(kCoapUdpPort);

    SuccessOrExit(error = netif.GetCoap().SendMessage(*message, messageInfo));

    otLogInfoMeshCoP("Sent relay rx");

exit:

    if (error != OT_ERROR_NONE && message != NULL)
    {
        message->Free();
    }
}
Пример #2
0
Leader::Leader(Instance &aInstance):
    InstanceLocator(aInstance),
    mPetition(OT_URI_PATH_LEADER_PETITION, Leader::HandlePetition, this),
    mKeepAlive(OT_URI_PATH_LEADER_KEEP_ALIVE, Leader::HandleKeepAlive, this),
    mTimer(aInstance, HandleTimer, this),
    mDelayTimerMinimal(DelayTimerTlv::kDelayTimerMinimal),
    mSessionId(0xffff)
{
    GetNetif().GetCoap().AddResource(mPetition);
    GetNetif().GetCoap().AddResource(mKeepAlive);
}
Пример #3
0
void ChildSupervisor::HandleTimer(void)
{
    Child * child;
    uint8_t numChildren;

    VerifyOrExit(mSupervisionInterval != 0);

    child = GetNetif().GetMle().GetChildren(&numChildren);

    for (uint8_t i = 0; i < numChildren; i++, child++)
    {
        if (!child->IsStateValidOrRestoring())
        {
            continue;
        }

        child->IncrementSecondsSinceLastSupervision();

        if ((child->GetSecondsSinceLastSupervision() >= mSupervisionInterval) && (child->IsRxOnWhenIdle() == false))
        {
            SendMessage(*child);
        }
    }

    mTimer.Start(kOneSecond);

exit:
    return;
}
void PanIdQueryClient::HandleConflict(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
    ThreadNetif &netif = GetNetif();
    MeshCoP::PanIdTlv panId;
    MeshCoP::ChannelMask0Tlv channelMask;
    Ip6::MessageInfo responseInfo(aMessageInfo);

    VerifyOrExit(aHeader.GetType() == OT_COAP_TYPE_CONFIRMABLE &&
                 aHeader.GetCode() == OT_COAP_CODE_POST);

    otLogInfoMeshCoP(GetInstance(), "received panid conflict");

    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPanId, sizeof(panId), panId));
    VerifyOrExit(panId.IsValid());

    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask));
    VerifyOrExit(channelMask.IsValid());

    if (mCallback != NULL)
    {
        mCallback(panId.GetPanId(), channelMask.GetMask(), mContext);
    }

    SuccessOrExit(netif.GetCoap().SendEmptyAck(aHeader, responseInfo));

    otLogInfoMeshCoP(GetInstance(), "sent panid query conflict response");

exit:
    return;
}
Пример #5
0
void JoinerRouter::HandleStateChanged(otChangedFlags aFlags)
{
    ThreadNetif &netif = GetNetif();

    VerifyOrExit(netif.GetMle().IsFullThreadDevice());
    VerifyOrExit(aFlags & OT_CHANGED_THREAD_NETDATA);

    netif.GetIp6Filter().RemoveUnsecurePort(mSocket.GetSockName().mPort);

    if (netif.GetNetworkDataLeader().IsJoiningEnabled())
    {
        Ip6::SockAddr sockaddr;

        sockaddr.mPort = GetJoinerUdpPort();

        mSocket.Open(&JoinerRouter::HandleUdpReceive, this);
        mSocket.Bind(sockaddr);
        netif.GetIp6Filter().AddUnsecurePort(sockaddr.mPort);
        otLogInfoMeshCoP("Joiner Router: start");
    }
    else
    {
        mSocket.Close();
    }

exit:
    return;
}
Пример #6
0
void Joiner::HandleTimer(void)
{
    ThreadNetif &netif = GetNetif();
    otError      error = OT_ERROR_NONE;

    switch (mState)
    {
    case OT_JOINER_STATE_IDLE:
    case OT_JOINER_STATE_DISCOVER:
    case OT_JOINER_STATE_CONNECT:
        assert(false);
        break;

    case OT_JOINER_STATE_CONNECTED:
    case OT_JOINER_STATE_ENTRUST:
        error = OT_ERROR_RESPONSE_TIMEOUT;
        break;

    case OT_JOINER_STATE_JOINED:
        Mac::ExtAddress extAddress;

        extAddress.GenerateRandom();
        netif.GetMac().SetExtAddress(extAddress);
        netif.GetMle().UpdateLinkLocalAddress();

        error = OT_ERROR_NONE;
        break;
    }

    Complete(error);
}
Пример #7
0
void Joiner::Close(void)
{
    ThreadNetif &netif = GetNetif();

    netif.GetCoapSecure().Disconnect();
    netif.GetIp6Filter().RemoveUnsecurePort(OPENTHREAD_CONFIG_JOINER_UDP_PORT);
}
Пример #8
0
otError Leader::SendKeepAliveResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo,
                                      StateTlv::State aState)
{
    ThreadNetif &netif = GetNetif();
    otError error = OT_ERROR_NONE;
    Coap::Header responseHeader;
    StateTlv state;
    Message *message;

    responseHeader.SetDefaultResponseHeader(aRequestHeader);
    responseHeader.SetPayloadMarker();

    VerifyOrExit((message = NewMeshCoPMessage(netif.GetCoap(), responseHeader)) != NULL, error = OT_ERROR_NO_BUFS);

    state.Init();
    state.SetState(aState);
    SuccessOrExit(error = message->Append(&state, sizeof(state)));

    SuccessOrExit(error = netif.GetCoap().SendMessage(*message, aMessageInfo));

    otLogInfoMeshCoP(GetInstance(), "sent keep alive response");

exit:

    if (error != OT_ERROR_NONE && message != NULL)
    {
        message->Free();
    }

    return error;
}
Пример #9
0
void EnergyScanClient::HandleReport(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
    ThreadNetif &           netif = GetNetif();
    MeshCoP::ChannelMaskTlv channelMask;
    Ip6::MessageInfo        responseInfo(aMessageInfo);

    OT_TOOL_PACKED_BEGIN
    struct
    {
        MeshCoP::EnergyListTlv tlv;
        uint8_t                list[OPENTHREAD_CONFIG_MAX_ENERGY_RESULTS];
    } OT_TOOL_PACKED_END energyList;

    VerifyOrExit(aMessage.GetType() == OT_COAP_TYPE_CONFIRMABLE && aMessage.GetCode() == OT_COAP_CODE_POST);

    otLogInfoMeshCoP("received energy scan report");

    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask));
    VerifyOrExit(channelMask.IsValid() && channelMask.GetChannelPage() == OT_RADIO_CHANNEL_PAGE);

    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kEnergyList, sizeof(energyList), energyList.tlv));
    VerifyOrExit(energyList.tlv.IsValid());

    if (mCallback != NULL)
    {
        mCallback(channelMask.GetMask(), energyList.list, energyList.tlv.GetLength(), mContext);
    }

    SuccessOrExit(netif.GetCoap().SendEmptyAck(aMessage, responseInfo));

    otLogInfoMeshCoP("sent energy scan report response");

exit:
    return;
}
Пример #10
0
otError Leader::SendDatasetChanged(const Ip6::Address &aAddress)
{
    ThreadNetif &netif = GetNetif();
    otError error = OT_ERROR_NONE;
    Coap::Header header;
    Ip6::MessageInfo messageInfo;
    Message *message;

    header.Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
    header.SetToken(Coap::Header::kDefaultTokenLength);
    header.AppendUriPathOptions(OT_URI_PATH_DATASET_CHANGED);

    VerifyOrExit((message = NewMeshCoPMessage(netif.GetCoap(), header)) != NULL, error = OT_ERROR_NO_BUFS);

    messageInfo.SetSockAddr(netif.GetMle().GetMeshLocal16());
    messageInfo.SetPeerAddr(aAddress);
    messageInfo.SetPeerPort(kCoapUdpPort);
    SuccessOrExit(error = netif.GetCoap().SendMessage(*message, messageInfo));

    otLogInfoMeshCoP(GetInstance(), "sent dataset changed");

exit:

    if (error != OT_ERROR_NONE && message != NULL)
    {
        message->Free();
    }

    return error;
}
Пример #11
0
void AnnounceBeginServer::HandleRequest(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
    MeshCoP::ChannelMask0Tlv channelMask;
    MeshCoP::CountTlv count;
    MeshCoP::PeriodTlv period;
    Ip6::MessageInfo responseInfo(aMessageInfo);

    VerifyOrExit(aHeader.GetCode() == OT_COAP_CODE_POST);

    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kChannelMask, sizeof(channelMask), channelMask));
    VerifyOrExit(channelMask.IsValid());

    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kCount, sizeof(count), count));
    VerifyOrExit(count.IsValid());

    SuccessOrExit(MeshCoP::Tlv::GetTlv(aMessage, MeshCoP::Tlv::kPeriod, sizeof(period), period));
    VerifyOrExit(period.IsValid());

    SendAnnounce(channelMask.GetMask(), count.GetCount(), period.GetPeriod());

    if (aHeader.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast())
    {
        SuccessOrExit(GetNetif().GetCoap().SendEmptyAck(aHeader, responseInfo));
        otLogInfoMeshCoP(GetInstance(), "sent announce begin response");
    }

exit:
    return;
}
Пример #12
0
void Joiner::SendJoinerEntrustResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aRequestInfo)
{
    ThreadNetif &    netif = GetNetif();
    otError          error = OT_ERROR_NONE;
    Coap::Message *  message;
    Ip6::MessageInfo responseInfo(aRequestInfo);

    VerifyOrExit((message = NewMeshCoPMessage(netif.GetCoap())) != NULL, error = OT_ERROR_NO_BUFS);
    message->SetDefaultResponseHeader(aRequest);
    message->SetSubType(Message::kSubTypeJoinerEntrust);

    memset(&responseInfo.mSockAddr, 0, sizeof(responseInfo.mSockAddr));
    SuccessOrExit(error = netif.GetCoap().SendMessage(*message, responseInfo));

    mState = OT_JOINER_STATE_JOINED;

    otLogInfoArp("Sent Joiner Entrust response");

    otLogInfoMeshCoP("Sent joiner entrust response length = %d", message->GetLength());
    otLogCertMeshCoP("[THCI] direction=send | type=JOIN_ENT.rsp");

exit:

    if (error != OT_ERROR_NONE && message != NULL)
    {
        message->Free();
    }
}
Пример #13
0
void ChildSupervisor::SendMessage(Child &aChild)
{
    ThreadNetif &netif   = GetNetif();
    Message *    message = NULL;
    uint8_t      childIndex;

    VerifyOrExit(aChild.GetIndirectMessageCount() == 0);

    message = netif.GetInstance().GetMessagePool().New(Message::kTypeSupervision, sizeof(uint8_t));
    VerifyOrExit(message != NULL);

    // Supervision message is an empty payload 15.4 data frame.
    // The child index is stored here in the message content to allow
    // the destination of the message to be later retrieved using
    // `ChildSupervisor::GetDestination(message)`.

    childIndex = netif.GetMle().GetChildIndex(aChild);
    SuccessOrExit(message->Append(&childIndex, sizeof(childIndex)));

    SuccessOrExit(netif.SendMessage(*message));
    message = NULL;

    otLogInfoUtil(GetInstance(), "Sending supervision message to child 0x%04x", aChild.GetRloc16());

exit:

    if (message != NULL)
    {
        message->Free();
    }
}
Пример #14
0
EnergyScanClient::EnergyScanClient(Instance &aInstance)
    : InstanceLocator(aInstance)
    , mEnergyScan(OT_URI_PATH_ENERGY_REPORT, &EnergyScanClient::HandleReport, this)
{
    mContext  = NULL;
    mCallback = NULL;
    GetNetif().GetCoap().AddResource(mEnergyScan);
}
Пример #15
0
PanIdQueryClient::PanIdQueryClient(Instance &aInstance) :
    InstanceLocator(aInstance),
    mCallback(NULL),
    mContext(NULL),
    mPanIdQuery(OT_URI_PATH_PANID_CONFLICT, &PanIdQueryClient::HandleConflict, this)
{
    GetNetif().GetCoap().AddResource(mPanIdQuery);
}
Пример #16
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;
}
Пример #17
0
void EnergyScanServer::HandleStateChanged(otChangedFlags aFlags)
{
    if ((aFlags & OT_CHANGED_THREAD_NETDATA) != 0 && !mActive &&
        GetNetif().GetNetworkDataLeader().GetCommissioningData() == NULL)
    {
        mActive = false;
        mTimer.Stop();
    }
}
Пример #18
0
void Leader::HandleTimer(void)
{
    VerifyOrExit(GetNetif().GetMle().GetRole() == OT_DEVICE_ROLE_LEADER);

    ResignCommissioner();

exit:
    return;
}
Пример #19
0
otError CoapSecure::Connect(const Ip6::MessageInfo &aMessageInfo, ConnectedCallback aCallback, void *aContext)
{
    mPeerAddress       = aMessageInfo;
    mConnectedCallback = aCallback;
    mConnectedContext  = aContext;

    return GetNetif().GetDtls().Start(true, &CoapSecure::HandleDtlsConnected, &CoapSecure::HandleDtlsReceive,
                                      &CoapSecure::HandleDtlsSend, this);
}
Пример #20
0
otError EnergyScanServer::SendReport(void)
{
    otError                  error = OT_ERROR_NONE;
    Coap::Header             header;
    MeshCoP::ChannelMask0Tlv channelMask;
    MeshCoP::EnergyListTlv   energyList;
    Ip6::MessageInfo         messageInfo;
    Message *                message;

    header.Init(OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
    header.SetToken(Coap::Header::kDefaultTokenLength);
    header.AppendUriPathOptions(OT_URI_PATH_ENERGY_REPORT);
    header.SetPayloadMarker();

    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(GetNetif().GetCoap(), header)) != NULL,
                 error = OT_ERROR_NO_BUFS);

    channelMask.Init();
    channelMask.SetMask(mChannelMask);
    SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));

    energyList.Init();
    energyList.SetLength(mScanResultsLength);
    SuccessOrExit(error = message->Append(&energyList, sizeof(energyList)));
    SuccessOrExit(error = message->Append(mScanResults, mScanResultsLength));

    messageInfo.SetSockAddr(GetNetif().GetMle().GetMeshLocal16());
    messageInfo.SetPeerAddr(mCommissioner);
    messageInfo.SetPeerPort(kCoapUdpPort);
    SuccessOrExit(error = GetNetif().GetCoap().SendMessage(*message, messageInfo));

    otLogInfoMeshCoP(GetInstance(), "sent scan results");

exit:

    if (error != OT_ERROR_NONE && message != NULL)
    {
        message->Free();
    }

    mActive = false;

    return error;
}
Пример #21
0
void Leader::SetEmptyCommissionerData(void)
{
    CommissionerSessionIdTlv mCommissionerSessionId;

    mCommissionerSessionId.Init();
    mCommissionerSessionId.SetCommissionerSessionId(++mSessionId);

    GetNetif().GetNetworkDataLeader().SetCommissioningData(reinterpret_cast<uint8_t *>(&mCommissionerSessionId),
                                                           sizeof(Tlv) + mCommissionerSessionId.GetLength());
}
Пример #22
0
otError PanIdQueryClient::SendQuery(uint16_t aPanId, uint32_t aChannelMask, const Ip6::Address &aAddress,
                                    otCommissionerPanIdConflictCallback aCallback, void *aContext)
{
    ThreadNetif &netif = GetNetif();
    otError error = OT_ERROR_NONE;
    Coap::Header header;
    MeshCoP::CommissionerSessionIdTlv sessionId;
    MeshCoP::ChannelMask0Tlv channelMask;
    MeshCoP::PanIdTlv panId;
    Ip6::MessageInfo messageInfo;
    Message *message = NULL;

    VerifyOrExit(netif.GetCommissioner().IsActive(), error = OT_ERROR_INVALID_STATE);

    header.Init(aAddress.IsMulticast() ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE,
                OT_COAP_CODE_POST);
    header.SetToken(Coap::Header::kDefaultTokenLength);
    header.AppendUriPathOptions(OT_URI_PATH_PANID_QUERY);
    header.SetPayloadMarker();

    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(netif.GetCoap(), header)) != NULL,
                 error = OT_ERROR_NO_BUFS);

    sessionId.Init();
    sessionId.SetCommissionerSessionId(netif.GetCommissioner().GetSessionId());
    SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId)));

    channelMask.Init();
    channelMask.SetMask(aChannelMask);
    SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));

    panId.Init();
    panId.SetPanId(aPanId);
    SuccessOrExit(error = message->Append(&panId, sizeof(panId)));

    messageInfo.SetSockAddr(netif.GetMle().GetMeshLocal16());
    messageInfo.SetPeerAddr(aAddress);
    messageInfo.SetPeerPort(kCoapUdpPort);
    messageInfo.SetInterfaceId(netif.GetInterfaceId());
    SuccessOrExit(error = netif.GetCoap().SendMessage(*message, messageInfo));

    otLogInfoMeshCoP(GetInstance(), "sent panid query");

    mCallback = aCallback;
    mContext = aContext;

exit:

    if (error != OT_ERROR_NONE && message != NULL)
    {
        message->Free();
    }

    return error;
}
Пример #23
0
AnnounceBeginServer::AnnounceBeginServer(otInstance &aInstance) :
    InstanceLocator(aInstance),
    mChannelMask(0),
    mPeriod(0),
    mCount(0),
    mChannel(0),
    mTimer(aInstance, &AnnounceBeginServer::HandleTimer, this),
    mAnnounceBegin(OT_URI_PATH_ANNOUNCE_BEGIN, &AnnounceBeginServer::HandleRequest, this)
{
    GetNetif().GetCoap().AddResource(mAnnounceBegin);
}
Пример #24
0
Dhcp6Server::Dhcp6Server(otInstance &aInstance):
    InstanceLocator(aInstance),
    mSocket(GetNetif().GetIp6().GetUdp())
{
    for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
    {
        memset(&(mPrefixAgents[i]), 0, sizeof(PrefixAgent));
        memset(&mAgentsAloc[i], 0, sizeof(mAgentsAloc[i]));
    }

    mPrefixAgentsCount = 0;
    mPrefixAgentsMask = 0;
}
Пример #25
0
JoinerRouter::JoinerRouter(Instance &aInstance)
    : InstanceLocator(aInstance)
    , mSocket(aInstance.GetThreadNetif().GetIp6().GetUdp())
    , mRelayTransmit(OT_URI_PATH_RELAY_TX, &JoinerRouter::HandleRelayTransmit, this)
    , mTimer(aInstance, &JoinerRouter::HandleTimer, this)
    , mNotifierCallback(&JoinerRouter::HandleStateChanged, this)
    , mJoinerUdpPort(0)
    , mIsJoinerPortConfigured(false)
    , mExpectJoinEntRsp(false)
{
    GetNetif().GetCoap().AddResource(mRelayTransmit);
    aInstance.GetNotifier().RegisterCallback(mNotifierCallback);
}
otError AnnounceBeginClient::SendRequest(uint32_t aChannelMask, uint8_t aCount, uint16_t aPeriod,
                                         const Ip6::Address &aAddress)
{
    otError error = OT_ERROR_NONE;
    Coap::Header header;
    MeshCoP::CommissionerSessionIdTlv sessionId;
    MeshCoP::ChannelMask0Tlv channelMask;
    MeshCoP::CountTlv count;
    MeshCoP::PeriodTlv period;

    Ip6::MessageInfo messageInfo;
    Message *message = NULL;

    VerifyOrExit(GetNetif().GetCommissioner().IsActive(), error = OT_ERROR_INVALID_STATE);

    header.Init(aAddress.IsMulticast() ? OT_COAP_TYPE_NON_CONFIRMABLE : OT_COAP_TYPE_CONFIRMABLE,
                OT_COAP_CODE_POST);
    header.SetToken(Coap::Header::kDefaultTokenLength);
    header.AppendUriPathOptions(OT_URI_PATH_ANNOUNCE_BEGIN);
    header.SetPayloadMarker();

    VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(GetNetif().GetCoap(), header)) != NULL,
                 error = OT_ERROR_NO_BUFS);

    sessionId.Init();
    sessionId.SetCommissionerSessionId(GetNetif().GetCommissioner().GetSessionId());
    SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId)));

    channelMask.Init();
    channelMask.SetMask(aChannelMask);
    SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));

    count.Init();
    count.SetCount(aCount);
    SuccessOrExit(error = message->Append(&count, sizeof(count)));

    period.Init();
    period.SetPeriod(aPeriod);
    SuccessOrExit(error = message->Append(&period, sizeof(period)));

    messageInfo.SetSockAddr(GetNetif().GetMle().GetMeshLocal16());
    messageInfo.SetPeerAddr(aAddress);
    messageInfo.SetPeerPort(kCoapUdpPort);
    messageInfo.SetInterfaceId(GetNetif().GetInterfaceId());

    SuccessOrExit(error = GetNetif().GetCoap().SendMessage(*message, messageInfo));

    otLogInfoMeshCoP(GetInstance(), "sent announce begin query");

exit:

    if (error != OT_ERROR_NONE && message != NULL)
    {
        message->Free();
    }

    return error;
}
Пример #27
0
otError Dhcp6Server::AppendServerIdentifier(Message &aMessage)
{
    otError error = OT_ERROR_NONE;
    ServerIdentifier option;

    option.Init();
    option.SetDuidType(kDuidLL);
    option.SetDuidHardwareType(kHardwareTypeEui64);
    option.SetDuidLinkLayerAddress(GetNetif().GetMac().GetExtAddress());
    SuccessOrExit(error = aMessage.Append(&option, sizeof(option)));

exit:
    return error;
}
Пример #28
0
void SupervisionListener::UpdateOnReceive(const Mac::Address &aSourceAddress, bool aIsSecure)
{
    ThreadNetif &netif = GetNetif();

    // If listener is enabled and device is a child and it received a secure frame from its parent, restart the timer.

    VerifyOrExit(mTimer.IsRunning() && aIsSecure && (netif.GetMle().GetRole() == OT_DEVICE_ROLE_CHILD) &&
                 (netif.GetMle().GetNeighbor(aSourceAddress) == netif.GetMle().GetParent()));

    RestartTimer();

exit:
    return;
}
Пример #29
0
void SupervisionListener::RestartTimer(void)
{
    ThreadNetif &netif = GetNetif();

    if ((mTimeout != 0) && (netif.GetMle().GetRole() != OT_DEVICE_ROLE_DISABLED) &&
        (netif.GetMeshForwarder().GetRxOnWhenIdle() == false))
    {
        mTimer.Start(TimerMilli::SecToMsec(mTimeout));
    }
    else
    {
        mTimer.Stop();
    }
}
Пример #30
0
void SupervisionListener::HandleTimer(void)
{
    ThreadNetif &netif = GetNetif();

    VerifyOrExit((netif.GetMle().GetRole() == OT_DEVICE_ROLE_CHILD) &&
                 (netif.GetMeshForwarder().GetRxOnWhenIdle() == false));

    otLogWarnUtil(netif.GetInstance(), "Supervision timeout. No frame from parent in %d sec", mTimeout);

    netif.GetMle().SendChildUpdateRequest();

exit:
    RestartTimer();
}