예제 #1
0
template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS>(void)
{
    otError             error = OT_ERROR_NONE;
    const otExtAddress *eui64;
    uint32_t            timeout;
    const char *        psk;

    SuccessOrExit(error = mDecoder.OpenStruct());

    if (!mDecoder.IsAllReadInStruct())
    {
        SuccessOrExit(error = mDecoder.ReadEui64(eui64));
    }
    else
    {
        // Empty struct indicates any Joiner (no EUI64 is given so NULL is used.).
        eui64 = NULL;
    }

    SuccessOrExit(error = mDecoder.CloseStruct());

    SuccessOrExit(error = mDecoder.ReadUint32(timeout));
    SuccessOrExit(error = mDecoder.ReadUtf8(psk));

    error = otCommissionerAddJoiner(mInstance, eui64, psk, timeout);

exit:
    return error;
}
예제 #2
0
void Leader::HandleKeepAlive(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
    StateTlv state;
    CommissionerSessionIdTlv sessionId;
    StateTlv::State responseState;

    otLogInfoMeshCoP(GetInstance(), "received keep alive");

    SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kState, sizeof(state), state));
    VerifyOrExit(state.IsValid());

    SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kCommissionerSessionId, sizeof(sessionId), sessionId));
    VerifyOrExit(sessionId.IsValid());

    if (sessionId.GetCommissionerSessionId() != mSessionId)
    {
        responseState = StateTlv::kReject;
    }
    else if (state.GetState() != StateTlv::kAccept)
    {
        responseState = StateTlv::kReject;
        ResignCommissioner();
    }
    else
    {
        responseState = StateTlv::kAccept;
        mTimer.Start(TimerMilli::SecToMsec(kTimeoutLeaderPetition));
    }

    SendKeepAliveResponse(aHeader, aMessageInfo, responseState);

exit:
    return;
}
예제 #3
0
otError Dhcp6Server::AppendIaAddress(Message &aMessage, ClientIdentifier &aClient)
{
    otError error = OT_ERROR_NONE;
    otIp6Prefix *prefix = NULL;

    // if specified, only apply specified prefixes
    if (mPrefixAgentsMask)
    {
        for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
        {
            if (mPrefixAgentsMask & (1 << i))
            {
                prefix = mPrefixAgents[i].GetPrefix();
                SuccessOrExit(error = AddIaAddress(aMessage, *prefix, aClient));
            }
        }
    }
    else  // if not specified, apply all configured prefixes
    {
        for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
        {
            prefix = mPrefixAgents[i].GetPrefix();

            if (prefix->mLength == 0)
            {
                continue;
            }

            SuccessOrExit(error = AddIaAddress(aMessage, *prefix, aClient));
        }
    }

exit:
    return error;
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
0
void ChildSupervisor::SendMessage(Child &aChild)
{
    ThreadNetif &netif = GetNetif();
    Message *message = NULL;
    otError error = OT_ERROR_NONE;
    uint8_t childIndex;

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

    message = netif.GetInstance().mMessagePool.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(error = message->Append(&childIndex, sizeof(childIndex)));

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

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

exit:

    if (message != NULL)
    {
        message->Free();
    }
}
예제 #7
0
otError Dtls::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
{
    otError      error   = OT_ERROR_NONE;
    ot::Message *message = NULL;

    VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
    message->SetSubType(aMessageSubType);
    message->SetLinkSecurityEnabled(mLayerTwoSecurity);

    SuccessOrExit(error = message->Append(aBuf, aLength));

    // Set message sub type in case Joiner Finalize Response is appended to the message.
    if (aMessageSubType != Message::kSubTypeNone)
    {
        message->SetSubType(aMessageSubType);
    }

    if (mTransportCallback)
    {
        SuccessOrExit(error = mTransportCallback(mTransportContext, *message, mPeerAddress));
    }
    else
    {
        SuccessOrExit(error = mSocket.SendTo(*message, mPeerAddress));
    }

exit:

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

    return error;
}
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;
}
예제 #9
0
void ChildSupervisor::SendMessage(Child &aChild)
{
    Message *message = NULL;
    uint8_t  childIndex;

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

    message = Get<MessagePool>().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 = Get<ChildTable>().GetChildIndex(aChild);
    SuccessOrExit(message->Append(&childIndex, sizeof(childIndex)));

    SuccessOrExit(Get<ThreadNetif>().SendMessage(*message));
    message = NULL;

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

exit:

    if (message != NULL)
    {
        message->Free();
    }
}
예제 #10
0
void Dhcp6Server::ProcessSolicit(Message &aMessage, otIp6Address &aDst, uint8_t *aTransactionId)
{
    IaNa iana;
    ClientIdentifier clientIdentifier;
    uint16_t optionOffset;
    uint16_t offset = aMessage.GetOffset();
    uint16_t length = aMessage.GetLength() - aMessage.GetOffset();

    // Client Identifier (discard if not present)
    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionClientIdentifier)) > 0);
    SuccessOrExit(ProcessClientIdentifier(aMessage, optionOffset, clientIdentifier));

    // Server Identifier (assuming Rapid Commit, discard if present)
    VerifyOrExit(FindOption(aMessage, offset, length, kOptionServerIdentifier) == 0);

    // Rapid Commit (assuming Rapid Commit, discard if not present)
    VerifyOrExit(FindOption(aMessage, offset, length, kOptionRapidCommit) > 0);

    // Elapsed Time if present
    if ((optionOffset = FindOption(aMessage, offset, length, kOptionElapsedTime)) > 0)
    {
        SuccessOrExit(ProcessElapsedTime(aMessage, optionOffset));
    }

    // IA_NA (discard if not present)
    VerifyOrExit((optionOffset = FindOption(aMessage, offset, length, kOptionIaNa)) > 0);
    SuccessOrExit(ProcessIaNa(aMessage, optionOffset, iana));

    SuccessOrExit(SendReply(aDst, aTransactionId, clientIdentifier, iana));

exit:
    return;
}
예제 #11
0
void EnergyScanClient::HandleReport(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
    uint32_t mask;

    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");

    VerifyOrExit((mask = MeshCoP::ChannelMaskTlv::GetChannelMask(aMessage)) != 0);

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

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

    SuccessOrExit(Get<Coap::Coap>().SendEmptyAck(aMessage, aMessageInfo));

    otLogInfoMeshCoP("sent energy scan report response");

exit:
    return;
}
예제 #12
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;
}
예제 #13
0
파일: joiner.cpp 프로젝트: turon/openthread
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;
}
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;
}
예제 #15
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;
}
예제 #16
0
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID>(void)
{
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadUint8(mPreferredRouteId));

    SuccessOrExit(error = otThreadSetPreferredRouterId(mInstance, mPreferredRouteId));

exit:
    return error;
}
예제 #17
0
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_STEERING_DATA>(void)
{
    otError error = OT_ERROR_NONE;

    SuccessOrExit(error = mDecoder.ReadEui64(mSteeringDataAddress));

    SuccessOrExit(error = otThreadSetSteeringData(mInstance, &mSteeringDataAddress));

exit:
    return error;
}
예제 #18
0
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD>(void)
{
    otError  error = OT_ERROR_NONE;
    uint16_t xtalThreshold;

    SuccessOrExit(error = mDecoder.ReadUint16(xtalThreshold));

    SuccessOrExit(error = otNetworkTimeSetXtalThreshold(mInstance, xtalThreshold));

exit:
    return error;
}
예제 #19
0
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_TIME_SYNC_PERIOD>(void)
{
    otError  error = OT_ERROR_NONE;
    uint16_t timeSyncPeriod;

    SuccessOrExit(error = mDecoder.ReadUint16(timeSyncPeriod));

    SuccessOrExit(error = otNetworkTimeSetSyncPeriod(mInstance, timeSyncPeriod));

exit:
    return error;
}
예제 #20
0
void Mac::HandleBeginTransmit(void)
{
    ThreadError error = kThreadError_None;

    if (otPlatRadioIdle() != kThreadError_None)
    {
        mBeginTransmit.Post();
        ExitNow();
    }

    switch (mState)
    {
    case kStateActiveScan:
        mSendFrame.SetChannel(mScanChannel);
        SendBeaconRequest(mSendFrame);
        mSendFrame.SetSequence(0);
        break;

    case kStateTransmitBeacon:
        mSendFrame.SetChannel(mChannel);
        SendBeacon(mSendFrame);
        mSendFrame.SetSequence(mBeaconSequence++);
        break;

    case kStateTransmitData:
        mSendFrame.SetChannel(mChannel);
        SuccessOrExit(error = mSendHead->HandleFrameRequest(mSendFrame));
        mSendFrame.SetSequence(mDataSequence);
        break;

    default:
        assert(false);
        break;
    }

    // Security Processing
    ProcessTransmitSecurity();

    SuccessOrExit(error = otPlatRadioTransmit(&mSendFrame));

    if (mSendFrame.GetAckRequest() && !(otPlatRadioGetCaps() & kRadioCapsAckTimeout))
    {
        mAckTimer.Start(kAckTimeout);
        otLogDebgMac("ack timer start\n");
    }

exit:

    if (error != kThreadError_None)
    {
        assert(false);
    }
}
예제 #21
0
otError SpinelDecoder::ReadDataWithLen(const uint8_t *&aData, uint16_t &aDataLen)
{
    otError  error = OT_ERROR_NONE;
    uint16_t len;

    SuccessOrExit(error = ReadUint16(len));
    SuccessOrExit(error = ReadItem(&aData, len));
    aDataLen = len;

exit:
    return error;
}
예제 #22
0
otError CoapSecure::Start(uint16_t aPort)
{
    otError error = OT_ERROR_NONE;

    mConnectedCallback = NULL;
    mConnectedContext  = NULL;

    SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
    SuccessOrExit(error = mDtls.Bind(aPort));

exit:
    return error;
}
예제 #23
0
otError CoapSecure::Start(MeshCoP::Dtls::TransportCallback aCallback, void *aContext)
{
    otError error = OT_ERROR_NONE;

    mConnectedCallback = NULL;
    mConnectedContext  = NULL;

    SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
    SuccessOrExit(error = mDtls.Bind(aCallback, aContext));

exit:
    return error;
}
예제 #24
0
otError Dhcp6Server::SendReply(otIp6Address &aDst, uint8_t *aTransactionId, ClientIdentifier &aClient, IaNa &aIaNa)
{
    otError error = OT_ERROR_NONE;
    Ip6::MessageInfo messageInfo;
    Message *message;

    VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
    SuccessOrExit(error = AppendHeader(*message, aTransactionId));
    SuccessOrExit(error = AppendServerIdentifier(*message));
    SuccessOrExit(error = AppendClientIdentifier(*message, aClient));
    SuccessOrExit(error = AppendIaNa(*message, aIaNa));
    SuccessOrExit(error = AppendStatusCode(*message, kStatusSuccess));
    SuccessOrExit(error = AppendIaAddress(*message, aClient));
    SuccessOrExit(error = AppendRapidCommit(*message));

    memset(&messageInfo, 0, sizeof(messageInfo));
    memcpy(&messageInfo.GetPeerAddr().mFields.m8, &aDst, sizeof(otIp6Address));
    messageInfo.mPeerPort = kDhcpClientPort;
    SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));

exit:

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

    return error;
}
예제 #25
0
otError Udp::Start(void)
{
    otError error;

    otSockAddr sockaddr;
    memset(&sockaddr, 0, sizeof(otSockAddr));
    sockaddr.mPort = 7335;

    SuccessOrExit(error = otUdpOpen(mInstance, &mSocket, &Udp::HandleUdpReceive, this));
    SuccessOrExit(error = otUdpBind(&mSocket, &sockaddr));

exit:
    return error;
}
예제 #26
0
// This method encodes a frame from the tx frame buffer (mTxFrameBuffer) into the uart buffer and sends it over uart.
// If the uart buffer gets full, it sends the current encoded portion. This method remembers current state, so on
// sub-sequent calls, it restarts encoding the bytes from where it left of in the frame .
void NcpUart::EncodeAndSendToUart(void)
{
    uint16_t len;

    while (!mTxFrameBuffer.IsEmpty())
    {
        switch (mState)
        {
        case kStartingFrame:

            SuccessOrExit(mFrameEncoder.Init(mUartBuffer));

            mTxFrameBuffer.OutFrameBegin();

            mState = kEncodingFrame;

            while (!mTxFrameBuffer.OutFrameHasEnded())
            {
                mByte = mTxFrameBuffer.OutFrameReadByte();

            case kEncodingFrame:

                SuccessOrExit(mFrameEncoder.Encode(mByte, mUartBuffer));
            }

            mTxFrameBuffer.OutFrameRemove();

            // Notify the super/base class that there is space available in tx frame buffer for a new frame.
            super_t::HandleSpaceAvailableInTxBuffer();

            mState = kFinalizingFrame;

            // fall through

        case kFinalizingFrame:

            SuccessOrExit(mFrameEncoder.Finalize(mUartBuffer));

            mState = kStartingFrame;
        }
    }

exit:
    len = mUartBuffer.GetLength();

    if (len > 0)
    {
        otPlatUartSend(mUartBuffer.GetBuffer(), len);
    }
}
예제 #27
0
otError Dataset::AppendMleDatasetTlv(Message &aMessage) const
{
    otError        error = OT_ERROR_NONE;
    Mle::Tlv       tlv;
    Mle::Tlv::Type type;
    const Tlv *    cur = reinterpret_cast<const Tlv *>(mTlvs);
    const Tlv *    end = reinterpret_cast<const Tlv *>(mTlvs + mLength);

    VerifyOrExit(mLength > 0);

    type = (mType == Tlv::kActiveTimestamp ? Mle::Tlv::kActiveDataset : Mle::Tlv::kPendingDataset);

    tlv.SetType(type);
    tlv.SetLength(static_cast<uint8_t>(mLength) - sizeof(Tlv) - sizeof(Timestamp));
    SuccessOrExit(error = aMessage.Append(&tlv, sizeof(Tlv)));

    while (cur < end)
    {
        if (cur->GetType() == mType)
        {
            ; // skip Active or Pending Timestamp TLV
        }
        else if (cur->GetType() == Tlv::kDelayTimer)
        {
            uint32_t      elapsed = TimerMilli::GetNow() - mUpdateTime;
            DelayTimerTlv delayTimer(static_cast<const DelayTimerTlv &>(*cur));

            if (delayTimer.GetDelayTimer() > elapsed)
            {
                delayTimer.SetDelayTimer(delayTimer.GetDelayTimer() - elapsed);
            }
            else
            {
                delayTimer.SetDelayTimer(0);
            }

            SuccessOrExit(error = aMessage.Append(&delayTimer, sizeof(delayTimer)));
        }
        else
        {
            SuccessOrExit(error = aMessage.Append(cur, sizeof(Tlv) + cur->GetLength()));
        }

        cur = cur->GetNext();
    }

exit:
    return error;
}
예제 #28
0
otError Dhcp6Server::AppendIaNa(Message &aMessage, IaNa &aIaNa)
{
    otError error = OT_ERROR_NONE;
    uint16_t length = 0;

    if (mPrefixAgentsMask)
    {
        for (uint8_t i = 0; i < OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES; i++)
        {
            if ((mPrefixAgentsMask & (1 << i)))
            {
                length += sizeof(IaAddress);
            }
        }
    }
    else
    {
        length += sizeof(IaAddress) * mPrefixAgentsCount;
    }

    length += sizeof(IaNa) + sizeof(StatusCode) - sizeof(Dhcp6Option);

    aIaNa.SetLength(length);
    aIaNa.SetT1(OT_DHCP6_DEFAULT_IA_NA_T1);
    aIaNa.SetT2(OT_DHCP6_DEFAULT_IA_NA_T2);
    SuccessOrExit(error = aMessage.Append(&aIaNa, sizeof(IaNa)));

exit:
    return error;
}
예제 #29
0
otError Dhcp6Server::ProcessIaNa(Message &aMessage, uint16_t aOffset, IaNa &aIaNa)
{
    otError error = OT_ERROR_NONE;
    uint16_t optionOffset;
    uint16_t length;

    VerifyOrExit((aMessage.Read(aOffset, sizeof(aIaNa), &aIaNa) == sizeof(aIaNa)), error = OT_ERROR_PARSE);

    aOffset += sizeof(aIaNa);
    length = aIaNa.GetLength() + sizeof(Dhcp6Option) - sizeof(IaNa);

    VerifyOrExit(length <= aMessage.GetLength() - aOffset, error = OT_ERROR_PARSE);

    mPrefixAgentsMask = 0;

    while (length > 0)
    {
        VerifyOrExit((optionOffset = FindOption(aMessage, aOffset, length, kOptionIaAddress)) > 0);
        SuccessOrExit(error = ProcessIaAddress(aMessage, optionOffset));

        length -= ((optionOffset - aOffset) + sizeof(IaAddress));
        aOffset = optionOffset + sizeof(IaAddress);
    }

exit:
    return error;
}
예제 #30
0
otError CoapSecure::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
{
    otError error = OT_ERROR_NONE;

    if (mTransmitMessage == NULL)
    {
        VerifyOrExit((mTransmitMessage = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
        mTransmitMessage->SetSubType(aMessageSubType);
        mTransmitMessage->SetLinkSecurityEnabled(false);
    }

    SuccessOrExit(error = mTransmitMessage->Append(aBuf, aLength));

    // Set message sub type in case Joiner Finalize Response is appended to the message.
    if (aMessageSubType != Message::kSubTypeNone)
    {
        mTransmitMessage->SetSubType(aMessageSubType);
    }

    mTransmitTask.Post();

exit:

    if (error != OT_ERROR_NONE && mTransmitMessage != NULL && mTransmitMessage->GetLength() == 0)
    {
        mTransmitMessage->Free();
        mTransmitMessage = NULL;
    }

    return error;
}