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; }
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; }
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; }
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; }
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; }
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(); } }
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; }
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(); } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); } }
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; }
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; }
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; }
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; }
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; }
// 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); } }
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; }
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; }
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; }
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; }