예제 #1
0
OpenDDS::DCPS::ReliableMulticast::detail::NackGenerator::PacketSet::iterator
OpenDDS::DCPS::ReliableMulticast::detail::NackGenerator::join_nacks(
  OpenDDS::DCPS::ReliableMulticast::detail::NackGenerator::PacketSet::iterator first,
  OpenDDS::DCPS::ReliableMulticast::detail::NackGenerator::PacketSet::iterator second
  )
{
  if (second == nacks_.begin())
  {
    return second;
  }
  else if (second == nacks_.end())
  {
    return first;
  }

  if (
    (first->nack_end_ >= second->nack_begin_) ||
    (
      first->nack_begin_ <= second->nack_begin_ &&
      first->nack_begin_ > first->nack_end_
      )
    )
  {
    Packet nack(*first);

    nack.nack_end_ = second->nack_end_;
    nacks_.erase(first);
    nacks_.erase(second);
    return nacks_.insert(nack).first;
  }
  return second;
}
inline lp::Nack
makeNack(const Interest& interest, lp::NackReason reason)
{
  lp::Nack nack(interest);
  nack.setReason(reason);
  return nack;
}
예제 #3
0
파일: client.hpp 프로젝트: C3MA/fullcircle
			void do_on_nack()
			{
				if ( _state != WAIT_FOR_ACK )
				{
					_state = ERROR;
					std::stringstream ss;
					ss << "Unexpected NACK received while in state " << stateNames[_state];
					error(ss.str());
					return;
				}

				_timer.cancel();
				_state = ERROR;
				nack();
			}
예제 #4
0
void
GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt,
                               const EndpointId& endpointId)
{
  BOOST_ASSERT(netPkt.type() == tlv::Interest);
  BOOST_ASSERT(firstPkt.has<lp::NackField>());

  lp::Nack nack((Interest(netPkt)));
  nack.setHeader(firstPkt.get<lp::NackField>());

  if (firstPkt.has<lp::NextHopFaceIdField>()) {
    ++this->nInNetInvalid;
    NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
    return;
  }

  if (firstPkt.has<lp::CachePolicyField>()) {
    ++this->nInNetInvalid;
    NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
    return;
  }

  if (firstPkt.has<lp::IncomingFaceIdField>()) {
    NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
  }

  if (firstPkt.has<lp::CongestionMarkField>()) {
    nack.setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
  }

  if (firstPkt.has<lp::NonDiscoveryField>()) {
    ++this->nInNetInvalid;
    NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP");
    return;
  }

  if (firstPkt.has<lp::PrefixAnnouncementField>()) {
    ++this->nInNetInvalid;
    NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP");
    return;
  }

  this->receiveNack(nack, endpointId);
}
예제 #5
0
void
OpenDDS::DCPS::ReliableMulticast::detail::NackGenerator::nack_range(
  Packet::id_type begin,
  Packet::id_type end
  )
{
  if (begin == end)
  {
    return;
  }
  Packet nack(begin, Packet::NACK, begin, end);
  PacketSet::iterator beg =
    find_nack_containing(nack);

  //if (beg == nacks.end())
  {
    nacks_.insert(nack);
    beg = nacks_.find(begin);
  }

  PacketSet::iterator beg_prev =
    beg;

  if (beg == nacks_.begin())
  {
    beg_prev = nacks_.end();
  }
  --beg_prev;
  beg = join_nacks(beg_prev, beg);

  PacketSet::iterator beg_next =
    beg;

  ++beg_next;
  if (beg_next == nacks_.end())
  {
    beg_next = nacks_.begin();
  }
  join_nacks(beg, beg_next);
}
예제 #6
0
void Datalink::processRxdLpdu()
{
    DnpAddr_t      dest = rxLpdu.getDest();;
    unsigned int   func = rxLpdu.getFunctionCode();
    int            broadcast;

    stats.increment(RX_FRAMES);

    // is it a broadcast?
    if (dest == 0xffff || dest ==0xfffe || dest == 0xfffd)
        broadcast = 1;
    else
        broadcast = 0;
                
    // check to see if it addressed to us or it is a broadcast
    if (dest == addr || broadcast)
    {
        // this LPDU is for us
        if ( rxLpdu.getPrimaryBit() == 0)
        {
            // this is a response - check to see if we are expecting anything
            // it should be one of four vaild response function codes
            if (func == ACK)
            {
                stats.increment( RX_ACKS);
                // check to see if we are expecting an ACK
                if (state == WAITING_FOR_ACK)
                {
                    state = IDLE;
                }
                else if ( state == WAITING_FOR_ACK_TO_LINK_RESET)
                {
                    linkNeedsToBeReset = 0;
                    state = IDLE;
                }
                else
                {
                    stats.increment( RX_UNEXPECTED_ACKS);
                }
            }
            else if (func == NACK)
            {
                stats.increment( RX_NACKS);
                // this is the case no matter what
                linkNeedsToBeReset = 1;
                state = IDLE;
            }
            else if (func == LINK_STATUS)
            {
                stats.increment( RX_LINK_STATUS);
                if ( state == WAITING_FOR_LINK_STATUS)
                {
                    state = IDLE;
                    // timeout = keepAliveInterval_ms;
                }
                else
                {
                    stats.increment( RX_UNEXPECTED_LINK_STATUS);
                }
            }                                
            else if (func == NOT_SUPPORTED)
            {
                // this device can't support what we asked for
                stats.increment( RX_NOT_SUPPORTED);
            }
            else
            {
                // invalid function for a response
                stats.increment( RX_FN_CODE_ERROR);
            }
        }
        else // PRM = 1
        {
            // this is an initiated transaction 
            // it should be one of five vaild function codes
            switch( func)
            {
                case RESET_LINK:

                    stats.increment( RX_RESET_LINK);

                    if (rxLpdu.getFcv() == 0)
                    {
                        rxFcb = 1; // we should expect this next
                        linkReset = 1;
                        if (!broadcast)
                            ack( rxLpdu.getSrc());
                        else
                            stats.increment( RX_FCV_INCORRECT);
                    }
                    break;

                case TEST_LINK:

                    stats.increment( RX_TEST_LINK);

                    if ( linkReset == 1)
                        if ( rxLpdu.getFcv() == 1)
                            if ( rxFcb == rxLpdu.getFcb())
                            {
                                if (!broadcast)
                                {
                                    ack( rxLpdu.getSrc());
                                    rxFcb = rxFcb^1;  // alternate
                                }
                            }
                            else 
                                stats.increment( RX_FCB_INCORRECT);
                        else
                            stats.increment( RX_FCV_INCORRECT);
                    else
                        if (!broadcast)
                            nack( rxLpdu.getSrc());
                    break;

                case CONFIRMED_USER_DATA:

                    stats.increment( RX_USER_DATA_CONFIRM);

                    if ( linkReset == 1)
                        if ( rxLpdu.getFcv() == 1)
                        {
                            // send an ack even if FCB bad
                            if (!broadcast)
                                ack( rxLpdu.getSrc());

                            if ( rxFcb == rxLpdu.getFcb())
                            {
                                rxFcb = rxFcb^1;  // alternate 
                                // fill in user data for application layer use
                                rxLpdu.getUserData(userData);
                            }
                            else
                                stats.increment( RX_FCB_INCORRECT);
                        }
                        else
                            stats.increment( RX_FCB_INCORRECT);
                    else 
                        if (!broadcast)
                            nack( rxLpdu.getSrc());
                    break;
                                
                case UNCONFIRMED_USER_DATA:

                    stats.increment( RX_USER_DATA_NO_CONFIRM);
                    if (rxLpdu.getFcv() == 0)
                        // fill in user data for application layer use
                        rxLpdu.getUserData(userData);
                    else
                        stats.increment( RX_FCV_INCORRECT);

                    break;

                case REQUEST_LINK_STATUS:

                    stats.increment( RX_REQUEST_LINK_STATUS);

                    if ( rxLpdu.getFcv() == 0)
                    {
                        txLpdu.build( isMaster, 0, 0, 0, LINK_STATUS,
                                      rxLpdu.getSrc(), addr);
                        stats.increment( TX_FRAMES);
                        stats.increment( TX_LINK_STATUS);
                        tx_p->transmit( txLpdu);

                    }
                    else
                        stats.increment( RX_FCV_INCORRECT);

                    break;
                        
                default:
                    // invalid function for a response
                    stats.increment( RX_FN_CODE_ERROR);

            } // end switch func

        } // end PRM = 1

    } // end if (addr == dl->addr || broadcast)
    else  
    {
        // this LPDU is not for us
        stats.increment( RX_OTHER_ADDRESSES);
    }
}