void CXReflectorDPlusHandler::process(CConnectData& connect)
{
    CD_TYPE    type = connect.getType();
    in_addr address = connect.getYourAddress();

    for (unsigned int i = 0U; i < m_maxReflectors; i++) {
        CXReflectorDPlusHandler* reflector = m_reflectors[i];
        if (reflector != NULL) {
            if (reflector->m_address.s_addr == address.s_addr) {
                bool res = m_reflectors[i]->processInt(connect, type);
                if (res) {
                    delete m_reflectors[i];
                    m_reflectors[i] = NULL;
                }
            }
        }
    }

    unsigned int port = connect.getYourPort();

    // Check that it isn't a duplicate
    for (unsigned int i = 0U; i < m_maxReflectors; i++) {
        if (m_reflectors[i] != NULL) {
            if (m_reflectors[i]->m_address.s_addr == address.s_addr)
                return;
        }
    }

    if (type == CT_UNLINK)
        return;

    if (type != CT_LINK1) {
        wxLogMessage(wxT("Incoming D-Plus message from unknown source"));
        return;
    }

    CXReflectorDPlusHandler* dplus = new CXReflectorDPlusHandler(address, port);

    bool found = false;

    for (unsigned int i = 0U; i < m_maxReflectors; i++) {
        if (m_reflectors[i] == NULL) {
            m_reflectors[i] = dplus;
            found = true;
            break;
        }
    }

    if (found) {
        CConnectData connect(CT_LINK1, address, port, 0U);
        m_handler->writeConnect(connect);
    } else {
        wxLogError(wxT("No space to add new D-Plus dongle, ignoring"));
        delete dplus;
    }
}
bool CCCSProtocolHandler::writeConnect(const CConnectData& connect)
{
	unsigned char buffer[40U];
	unsigned int length = connect.getCCSData(buffer, 40U);

#if defined(DUMP_TX)
	CUtils::dump(wxT("Sending Connect"), buffer, length);
#endif

	return m_socket.write(buffer, length, connect.getYourAddress(), connect.getYourPort());
}
bool CDPlusHandler::processInt(CConnectData& connect, CD_TYPE type)
{
	switch (m_direction) {
		case DIR_OUTGOING:
			switch (type) {
				case CT_ACK:
					if (m_linkState == DPLUS_LINKING) {
						wxLogMessage(wxT("D-Plus ACK message received from %s"), m_reflector.c_str());
						m_destination->linkUp(DP_DPLUS, m_reflector);
						m_stateChange = true;
						m_linkState   = DPLUS_LINKED;
						m_tryTimer.stop();
						m_pollTimer.start();
						m_pollInactivityTimer.start();
					}
					return false;

				case CT_NAK:
					if (m_linkState == DPLUS_LINKING) {
						wxLogMessage(wxT("D-Plus NAK message received from %s"), m_reflector.c_str());
						m_destination->linkDown(DP_DPLUS, m_reflector, false);
						CConnectData reply(CT_UNLINK, connect.getYourAddress(), connect.getYourPort());
						m_handler->writeConnect(reply);
						m_tryTimer.stop();
					}
					return true;

				case CT_UNLINK:
					if (m_linkState == DPLUS_UNLINKING) {
						wxLogMessage(wxT("D-Plus disconnect acknowledgement received from %s"), m_reflector.c_str());
						m_destination->linkDown(DP_DPLUS, m_reflector, false);
						m_stateChange = true;
						m_tryTimer.stop();
					}
					return true;

				case CT_LINK1: {
						CConnectData reply(m_dplusLogin, CT_LINK2, connect.getYourAddress(), connect.getYourPort());
						m_handler->writeConnect(reply);
						m_tryTimer.stop();
					}
					return false;

				default:
					return false;
			}
			break;

		case DIR_INCOMING:
			switch (type) {
				case CT_LINK2: {
						m_reflector = connect.getRepeater();
						wxLogMessage(wxT("D-Plus dongle link to %s has started"), m_reflector.c_str());
						CConnectData reply(CT_ACK, m_yourAddress, m_yourPort);
						m_handler->writeConnect(reply);
						m_linkState   = DPLUS_LINKED;
						m_stateChange = true;
					}
					return false;

				case CT_UNLINK:
					if (m_linkState == DPLUS_LINKED) {
						wxLogMessage(wxT("D-Plus dongle link to %s has ended (unlinked)"), m_reflector.c_str());
						m_stateChange = true;
						m_handler->writeConnect(connect);
					}
					return true;

				default:
					return false;
			}
			break;
	}

	return false;
}
void CDPlusHandler::process(CConnectData& connect)
{
	CD_TYPE          type = connect.getType();
	in_addr   yourAddress = connect.getYourAddress();
	unsigned int yourPort = connect.getYourPort();
	unsigned int   myPort = connect.getMyPort();

	for (unsigned int i = 0U; i < m_maxReflectors; i++) {
		CDPlusHandler* reflector = m_reflectors[i];

		if (reflector != NULL) {
			if (reflector->m_yourAddress.s_addr == yourAddress.s_addr &&
				reflector->m_yourPort           == yourPort &&
				reflector->m_myPort             == myPort) {
				bool res = m_reflectors[i]->processInt(connect, type);
				if (res) {
					delete m_reflectors[i];
					m_reflectors[i] = NULL;
				}
			}
		}
	}

	// Check that it isn't a duplicate
	for (unsigned int i = 0U; i < m_maxReflectors; i++) {
		CDPlusHandler* reflector = m_reflectors[i];

		if (reflector != NULL) {
			if (reflector->m_yourAddress.s_addr == yourAddress.s_addr &&
				reflector->m_yourPort           == yourPort &&
				reflector->m_myPort             == myPort)
				return;
		}
	}

	if (type == CT_UNLINK)
		return;

	if (type != CT_LINK1) {
		wxLogMessage(wxT("Incoming D-Plus message from unknown source"));
		return;
	}

	// Check to see if we are allowed to accept it
	unsigned int count = 0U;
	for (unsigned int i = 0U; i < m_maxReflectors; i++) {
		if (m_reflectors[i] != NULL &&
			m_reflectors[i]->m_direction == DIR_INCOMING)
			count++;
	}

	if (count >= m_maxDongles)
		return;

	CDPlusHandler* dplus = new CDPlusHandler(m_incoming, yourAddress, yourPort);

	bool found = false;

	for (unsigned int i = 0U; i < m_maxReflectors; i++) {
		if (m_reflectors[i] == NULL) {
			m_reflectors[i] = dplus;
			found = true;
			break;
		}
	}

	if (found) {
		CConnectData connect(CT_LINK1, yourAddress, yourPort);
		m_incoming->writeConnect(connect);
	} else {
		wxLogError(wxT("No space to add new D-Plus dongle, ignoring"));
		delete dplus;
	}
}