otError SourceMatchController::AddAddress(const Child &aChild) { otError error = OT_ERROR_NONE; if (aChild.IsIndirectSourceMatchShort()) { error = otPlatRadioAddSrcMatchShortEntry(&GetInstance(), aChild.GetRloc16()); otLogDebgMac(GetInstance(), "SrcAddrMatch - Adding short addr: 0x%04x -- %s (%d)", aChild.GetRloc16(), otThreadErrorToString(error), error); } else { otExtAddress addr; for (uint8_t i = 0; i < sizeof(addr); i++) { addr.m8[i] = aChild.GetExtAddress().m8[sizeof(addr) - 1 - i]; } error = otPlatRadioAddSrcMatchExtEntry(&GetInstance(), &addr); otLogDebgMac(GetInstance(), "SrcAddrMatch - Adding addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x -- %s (%d)", addr.m8[7], addr.m8[6], addr.m8[5], addr.m8[4], addr.m8[3], addr.m8[2], addr.m8[1], addr.m8[0], otThreadErrorToString(error), error); } return error; }
void SourceMatchController::ClearEntry(Child &aChild) { otError error = OT_ERROR_NONE; if (aChild.IsIndirectSourceMatchPending()) { otLogDebgMac(GetInstance(), "SrcAddrMatch - Clearing pending flag for 0x%04x", aChild.GetRloc16()); aChild.SetIndirectSourceMatchPending(false); ExitNow(); } if (aChild.IsIndirectSourceMatchShort()) { error = otPlatRadioClearSrcMatchShortEntry(&GetInstance(), aChild.GetRloc16()); otLogDebgMac(GetInstance(), "SrcAddrMatch - Clearing short address: 0x%04x -- %s (%d)", aChild.GetRloc16(), otThreadErrorToString(error), error); } else { otExtAddress addr; for (uint8_t i = 0; i < sizeof(addr); i++) { addr.m8[i] = aChild.GetExtAddress().m8[sizeof(aChild.GetExtAddress()) - 1 - i]; } error = otPlatRadioClearSrcMatchExtEntry(&GetInstance(), &addr); otLogDebgMac(GetInstance(), "SrcAddrMatch - Clearing addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x -- %s (%d)", addr.m8[7], addr.m8[6], addr.m8[5], addr.m8[4], addr.m8[3], addr.m8[2], addr.m8[1], addr.m8[0], otThreadErrorToString(error), error); } SuccessOrExit(error); if (!IsEnabled()) { SuccessOrExit(AddPendingEntries()); Enable(true); } exit: return; }
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); } }
void Mac::HandleAckTimer(void) { otPlatRadioIdle(); switch (mState) { case kStateActiveScan: do { mScanChannels >>= 1; mScanChannel++; if (mScanChannels == 0 || mScanChannel > kPhyMaxChannel) { mActiveScanHandler(mActiveScanContext, NULL); ScheduleNextTransmission(); ExitNow(); } } while ((mScanChannels & 1) == 0); StartCsmaBackoff(); break; case kStateTransmitData: otLogDebgMac("ack timer fired\n"); SentFrame(false); break; default: assert(false); break; } exit: NextOperation(); }
otError DataPollManager::SendDataPoll(void) { otError error; Message * message; Neighbor *parent; VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE); VerifyOrExit(!Get<Mac::Mac>().GetRxOnWhenIdle(), error = OT_ERROR_INVALID_STATE); parent = Get<Mle::MleRouter>().GetParentCandidate(); VerifyOrExit((parent != NULL) && parent->IsStateValidOrRestoring(), error = OT_ERROR_INVALID_STATE); mTimer.Stop(); for (message = Get<MeshForwarder>().GetSendQueue().GetHead(); message; message = message->GetNext()) { VerifyOrExit(message->GetType() != Message::kTypeMacDataPoll, error = OT_ERROR_ALREADY); } message = Get<MessagePool>().New(Message::kTypeMacDataPoll, 0); VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS); error = Get<MeshForwarder>().SendMessage(*message); if (error != OT_ERROR_NONE) { message->Free(); } exit: switch (error) { case OT_ERROR_NONE: otLogDebgMac("Sending data poll"); if (mNoBufferRetxMode == true) { mNoBufferRetxMode = false; ScheduleNextPoll(kRecalculatePollPeriod); } else { ScheduleNextPoll(kUsePreviousPollPeriod); } break; case OT_ERROR_INVALID_STATE: otLogWarnMac("Data poll tx requested while data polling was not enabled!"); StopPolling(); break; case OT_ERROR_ALREADY: otLogDebgMac("Data poll tx requested when a previous data request still in send queue."); ScheduleNextPoll(kUsePreviousPollPeriod); break; case OT_ERROR_NO_BUFS: default: mNoBufferRetxMode = true; ScheduleNextPoll(kRecalculatePollPeriod); break; } return error; }
void SourceMatchController::Enable(bool aEnable) { mEnabled = aEnable; otPlatRadioEnableSrcMatch(&GetInstance(), mEnabled); otLogDebgMac(GetInstance(), "SrcAddrMatch - %sabling", mEnabled ? "En" : "Dis"); }
void SourceMatchController::ClearTable(void) { otPlatRadioClearSrcMatchShortEntries(&GetInstance()); otPlatRadioClearSrcMatchExtEntries(&GetInstance()); otLogDebgMac(GetInstance(), "SrcAddrMatch - Cleared all entries"); }