void PeriodicHeartbeat::event(EventCode code, const char* msg)
{
	const char* const METHOD_NAME = "event";
	if(code == EVENT_SUCCESS)
	{
		SequenceNumber_t firstSeq, lastSeq;
		LocatorList_t locList;
		bool unacked_changes = false;
		{//BEGIN PROTECTION
			boost::lock_guard<boost::recursive_mutex> guardW(*mp_SFW->getMutex());
			std::vector<ChangeForReader_t*> unack;
			for(std::vector<ReaderProxy*>::iterator it = mp_SFW->matchedReadersBegin();
					it!=mp_SFW->matchedReadersEnd();++it)
			{
				unack.clear();
				if(!unacked_changes)
				{
					(*it)->unacked_changes(&unack);
					if(!unack.empty())
					{
						unacked_changes= true;
					}
				}
				locList.push_back((*it)->m_att.endpoint.unicastLocatorList);
				locList.push_back((*it)->m_att.endpoint.multicastLocatorList);
			}
			firstSeq = mp_SFW->get_seq_num_min();
			lastSeq = mp_SFW->get_seq_num_max();
		}
		if(unacked_changes)
		{
			if(firstSeq != c_SequenceNumber_Unknown && lastSeq != c_SequenceNumber_Unknown && lastSeq >= firstSeq)
			{
				mp_SFW->incrementHBCount();
				CDRMessage::initCDRMsg(&m_periodic_hb_msg);
				RTPSMessageCreator::addMessageHeartbeat(&m_periodic_hb_msg,mp_SFW->getGuid().guidPrefix,
						mp_SFW->getHBReaderEntityId(),mp_SFW->getGuid().entityId,
						firstSeq,lastSeq,mp_SFW->getHeartbeatCount(),false,false);
				logInfo(RTPS_WRITER,mp_SFW->getGuid().entityId << " Sending Heartbeat ("<<firstSeq<< " - " << lastSeq<<")" );
				for (std::vector<Locator_t>::iterator lit = locList.begin(); lit != locList.end(); ++lit)
					mp_SFW->getRTPSParticipant()->sendSync(&m_periodic_hb_msg, (*lit));
			}
			//Reset TIMER
			this->restart_timer();
		}

	}
	else if(code == EVENT_ABORT)
	{
		logInfo(RTPS_WRITER,"Aborted");
		this->stopSemaphorePost();
	}
	else
	{
		logInfo(RTPS_WRITER,"Boost message: " <<msg);
	}
}
bool RTPSParticipantImpl::assignEndpoint2LocatorList(Endpoint* endp,LocatorList_t& list,bool isMulti,bool isFixed)
{
	bool valid = true;
	LocatorList_t finalList;
	bool added = false;
	for(auto lit = list.begin();lit != list.end();++lit)
	{
		added = false;
		boost::lock_guard<boost::recursive_mutex> guard(*mp_mutex);
		for(std::vector<ListenResource*>::iterator it = m_listenResourceList.begin();it!=m_listenResourceList.end();++it)
		{
			if((*it)->isListeningTo(*lit))
			{
				(*it)->addAssociatedEndpoint(endp);
				LocatorList_t locList = (*it)->getListenLocators();
				finalList.push_back(locList);
				added = true;
			}
		}
		if(added)
			continue;
		ListenResource* LR = new ListenResource(this,++m_threadID,false);
		if(LR->init_thread(this,*lit,m_att.listenSocketBufferSize,isMulti,isFixed))
		{
			LR->addAssociatedEndpoint(endp);
			LocatorList_t locList = LR->getListenLocators();
			finalList.push_back(locList);
			m_listenResourceList.push_back(LR);
			added = true;
		}
		else
		{
			delete(LR);
			valid &= false;
		}
	}
	if(valid && added)
		list = finalList;
	return valid;
}
bool RTPSParticipantImpl::assignLocatorForBuiltin_unsafe(LocatorList_t& list, bool isMulti, bool isFixed)
{
	bool valid = true;
	LocatorList_t finalList;
	bool added = false;
	for(auto lit = list.begin();lit != list.end();++lit)
	{
		added = false;
		for(std::vector<ListenResource*>::iterator it = m_listenResourceList.begin();it!=m_listenResourceList.end();++it)
		{
			if((*it)->isListeningTo(*lit))
			{
				LocatorList_t locList = (*it)->getListenLocators();
				finalList.push_back(locList);
				added = true;
			}
		}
		if(added)
			continue;
		ListenResource* LR = new ListenResource(this,++m_threadID,false);
		if(LR->init_thread(this,*lit,m_att.listenSocketBufferSize,isMulti,isFixed))
		{
			LocatorList_t locList = LR->getListenLocators();
			finalList.push_back(locList);
			m_listenResourceList.push_back(LR);
			added = true;
		}
		else
		{
			delete(LR);
			valid &= false;
		}
	}
	if(valid && added)
		list = finalList;
	return valid;
}
RTPSParticipantImpl::RTPSParticipantImpl(const RTPSParticipantAttributes& PParam,
		const GuidPrefix_t& guidP,
		RTPSParticipant* par,
		RTPSParticipantListener* plisten):	m_guid(guidP,c_EntityId_RTPSParticipant),
				mp_send_thr(nullptr),
				mp_event_thr(nullptr),
                async_writers_thread_(nullptr),
				mp_builtinProtocols(nullptr),
				mp_ResourceSemaphore(new boost::interprocess::interprocess_semaphore(0)),
				IdCounter(0),
				mp_participantListener(plisten),
				mp_userParticipant(par),
				mp_mutex(new boost::recursive_mutex()),
				m_threadID(0)

{
	const char* const METHOD_NAME = "RTPSParticipantImpl";
	boost::lock_guard<boost::recursive_mutex> guard(*mp_mutex);
	mp_userParticipant->mp_impl = this;
	m_att = PParam;
	Locator_t loc;
	loc.port = PParam.defaultSendPort;
	mp_send_thr = new ResourceSend();
	mp_send_thr->initSend(this,loc,m_att.sendSocketBufferSize,m_att.use_IP4_to_send,m_att.use_IP6_to_send);
	mp_event_thr = new ResourceEvent();
	mp_event_thr->init_thread(this);
    async_writers_thread_ = new AsyncWriterThread();
	bool hasLocatorsDefined = true;
	//If no default locator is defined you define one.
	if(m_att.defaultUnicastLocatorList.empty() && m_att.defaultMulticastLocatorList.empty())
	{
		hasLocatorsDefined = false;
		Locator_t loc2;
		loc2.port=m_att.port.portBase+
				m_att.port.domainIDGain*PParam.builtin.domainId+
				m_att.port.offsetd3+
				m_att.port.participantIDGain*m_att.participantID;
		loc2.kind = LOCATOR_KIND_UDPv4;
		m_att.defaultUnicastLocatorList.push_back(loc2);
	}
	LocatorList_t defcopy = m_att.defaultUnicastLocatorList;
	m_att.defaultUnicastLocatorList.clear();
	for(LocatorListIterator lit = defcopy.begin();lit!=defcopy.end();++lit)
	{
		ListenResource* LR = new ListenResource(this,++m_threadID,true);
		if(LR->init_thread(this,*lit,m_att.listenSocketBufferSize,false,false))
		{
			m_att.defaultUnicastLocatorList.push_back(LR->getListenLocators());
			this->m_listenResourceList.push_back(LR);
		}
		else
		{
			delete(LR);
		}
	}
	if(!hasLocatorsDefined)
		logInfo(RTPS_PARTICIPANT,m_att.getName()<<" Created with NO default Unicast Locator List, adding Locators: "<<m_att.defaultUnicastLocatorList);
	defcopy = m_att.defaultMulticastLocatorList;
	m_att.defaultMulticastLocatorList.clear();
	for(LocatorListIterator lit = defcopy.begin();lit!=defcopy.end();++lit)
	{
		ListenResource* LR = new ListenResource(this,++m_threadID,true);
		if(LR->init_thread(this,*lit,m_att.listenSocketBufferSize,true,false))
		{
			m_att.defaultMulticastLocatorList.push_back(LR->getListenLocators());
			this->m_listenResourceList.push_back(LR);
		}
		else
		{
			delete(LR);
		}
	}


	logInfo(RTPS_PARTICIPANT,"RTPSParticipant \"" <<  m_att.getName() << "\" with guidPrefix: " <<m_guid.guidPrefix);
	//START BUILTIN PROTOCOLS
	mp_builtinProtocols = new BuiltinProtocols();
	if(!mp_builtinProtocols->initBuiltinProtocols(this,m_att.builtin))
	{
		logWarning(RTPS_PARTICIPANT, "The builtin protocols were not corecctly initialized");
	}
	//eClock::my_sleep(300);
}
void PeriodicHeartbeat::event(EventCode code, const char* msg)
{

    // Unused in release mode.
    (void)msg;

	if(code == EVENT_SUCCESS)
	{
		SequenceNumber_t firstSeq, lastSeq;
		Count_t heartbeatCount = 0;
		LocatorList_t locList;
		bool unacked_changes = false;
		{//BEGIN PROTECTION
			boost::lock_guard<boost::recursive_mutex> guardW(*mp_SFW->getMutex());
			for(std::vector<ReaderProxy*>::iterator it = mp_SFW->matchedReadersBegin();
					it != mp_SFW->matchedReadersEnd(); ++it)
			{
				if(!unacked_changes)
				{
                    if((*it)->thereIsUnacknowledged())
					{
						unacked_changes= true;
					}
				}
				locList.push_back((*it)->m_att.endpoint.unicastLocatorList);
				locList.push_back((*it)->m_att.endpoint.multicastLocatorList);
			}

			if (unacked_changes)
			{
				firstSeq = mp_SFW->get_seq_num_min();
				lastSeq = mp_SFW->get_seq_num_max();

				if (firstSeq == c_SequenceNumber_Unknown || lastSeq == c_SequenceNumber_Unknown)
				{
					firstSeq = mp_SFW->next_sequence_number();
					lastSeq = SequenceNumber_t(0, 0);
				}
				else
				{
					(void)firstSeq;
					assert(firstSeq <= lastSeq);
				}

				mp_SFW->incrementHBCount();
				heartbeatCount = mp_SFW->getHeartbeatCount();
			}
		}

		if (unacked_changes)
		{
			CDRMessage::initCDRMsg(&m_periodic_hb_msg);
			// FinalFlag is always false because this class is used only by StatefulWriter in Reliable.
			RTPSMessageCreator::addMessageHeartbeat(&m_periodic_hb_msg, mp_SFW->getGuid().guidPrefix,
				mp_SFW->getHBReaderEntityId(), mp_SFW->getGuid().entityId,
				firstSeq, lastSeq, heartbeatCount, false, false);
			logInfo(RTPS_WRITER,mp_SFW->getGuid().entityId << " Sending Heartbeat ("<<firstSeq<< " - " << lastSeq<<")" );
			for (std::vector<Locator_t>::iterator lit = locList.begin(); lit != locList.end(); ++lit)
				mp_SFW->getRTPSParticipant()->sendSync(&m_periodic_hb_msg,(Endpoint *)mp_SFW , (*lit));
		
			//Reset TIMER
			this->restart_timer();
		}

	}
	else if(code == EVENT_ABORT)
	{
		logInfo(RTPS_WRITER,"Aborted");
	}
	else
	{
		logInfo(RTPS_WRITER,"Boost message: " <<msg);
	}
}
bool BuiltinProtocols::initBuiltinProtocols(RTPSParticipantImpl* p_part, BuiltinAttributes& attributes)
{
    //const char* const METHOD_NAME = "initBuiltinProtocols";
    mp_participantImpl = p_part;
    m_att = attributes;

    m_SPDP_WELL_KNOWN_MULTICAST_PORT = mp_participantImpl->getAttributes().port.getMulticastPort(m_att.domainId);

    m_SPDP_WELL_KNOWN_UNICAST_PORT =
        mp_participantImpl->getAttributes().port.getUnicastPort(m_att.domainId,mp_participantImpl->getAttributes().participantID);

    this->m_mandatoryMulticastLocator.kind = LOCATOR_KIND_UDPv4;
    m_mandatoryMulticastLocator.port = m_SPDP_WELL_KNOWN_MULTICAST_PORT;
    m_mandatoryMulticastLocator.set_IP4_address(239,255,0,1);
    if(m_att.metatrafficMulticastLocatorList.empty())
    {
        m_metatrafficMulticastLocatorList.push_back(m_mandatoryMulticastLocator);
    }
    else
    {
        m_useMandatory = false;
        for(std::vector<Locator_t>::iterator it = m_att.metatrafficMulticastLocatorList.begin();
                it!=m_att.metatrafficMulticastLocatorList.end(); ++it)
        {
            m_metatrafficMulticastLocatorList.push_back(*it);
        }
    }

    p_part->assignLocatorForBuiltin_unsafe(m_metatrafficMulticastLocatorList, true, false);

    if(m_att.metatrafficUnicastLocatorList.empty())
    {
        LocatorList_t locators;
        IPFinder::getIP4Address(&locators);
        for(std::vector<Locator_t>::iterator it=locators.begin(); it!=locators.end(); ++it)
        {
            it->port = m_SPDP_WELL_KNOWN_UNICAST_PORT;
            m_metatrafficUnicastLocatorList.push_back(*it);
        }
    }
    else
    {
        for(std::vector<Locator_t>::iterator it = m_att.metatrafficUnicastLocatorList.begin();
                it!=m_att.metatrafficUnicastLocatorList.end(); ++it)
        {
            m_metatrafficUnicastLocatorList.push_back(*it);
        }
    }

    p_part->assignLocatorForBuiltin_unsafe(m_metatrafficUnicastLocatorList, false, false);

    if(m_att.use_SIMPLE_RTPSParticipantDiscoveryProtocol)
    {
        mp_PDP = new PDPSimple(this);
        mp_PDP->initPDP(mp_participantImpl);
        if(m_att.use_WriterLivelinessProtocol)
        {
            mp_WLP = new WLP(this);
            mp_WLP->initWL(mp_participantImpl);
        }
        mp_PDP->announceParticipantState(true);
        mp_PDP->resetParticipantAnnouncement();
    }

    return true;
}