void NFCReaderUnit::writeChipUid(std::shared_ptr<Chip> c,
                                     const std::vector<uint8_t> &new_uid)
	{
        WriteUIDConfigGuard config_guard(*this);
        assert(new_uid.size() == 4);
        LOG(DEBUGS) << "Attempting to change the UID of a card. "
                "This will work only on some non-original \"backup card\"";

        std::vector<uint8_t> abtHalt = {0x50, 0x00, 0x00, 0x00};
        uint8_t wakeUp[1] = {0x52};

        // special unlock command
        uint8_t abtUnlock1[1] = {0x40};
        std::vector<uint8_t> abtUnlock2 = {0x43};
        std::vector<uint8_t> abtWrite = {0xa0, 0x00, 0x5f, 0xb1};
        std::vector<uint8_t> abtData = {0x01, 0x23, 0x45, 0x67, 0x00, 0x08, 0x04, 0x00, 0x46, 0x59, 0x25, 0x58, 0x49, 0x10, 0x23, 0x02, 0x23, 0xeb};

        iso14443a_crc_append(&abtHalt[0], 2);
        getDefaultNFCReaderCardAdapter()->sendCommand(abtHalt);

        // write user-provided UID and compute the checksum
        std::copy(new_uid.begin(), new_uid.end(), abtData.begin());
        abtData[4] = abtData[0] ^ abtData[1] ^ abtData[2] ^ abtData[3];
        iso14443a_crc_append(&abtData[0], 16);

        transmitBits(abtUnlock1, 7);
        getDefaultNFCReaderCardAdapter()->sendCommand(abtUnlock2);
        getDefaultNFCReaderCardAdapter()->sendCommand(abtWrite);
        getDefaultNFCReaderCardAdapter()->sendCommand(abtData);

        getDefaultNFCReaderCardAdapter()->sendCommand(abtHalt);
        transmitBits(wakeUp, 7);

        // if we reach this point, the UID was changed. However since error are
        // disabled, we a are very likely to reach this point...
        // We need to fix up our internals to match the new UID.
        nfc_target nfct = d_chips[c];
        for (int i = 0; i < 4; ++i)
            nfct.nti.nai.abtUid[i] = new_uid[i];
        d_chips[c] = nfct;
        c->setChipIdentifier(new_uid);
    }
void CSoundCardRepeaterTXThread::transmitNetwork()
{
	if (m_networkBuffer.isEmpty() && m_outBuffer.isEmpty()) {
#if defined(TX_TO_WAV_FILE)
		if (m_writer != NULL) {
			wxLogMessage(wxT("Closing the output WAV file"));
			m_writer->close();
			delete m_writer;
			m_writer = NULL;
		}
#endif
		m_networkStarted = false;
		m_networkRun = 0U;

		// Switch off the transmitter?
		if (m_tx) {
			// If no hang time, switch off the TX immediately
			if (m_hangTimer.getTimeout() == 0U) {
				m_tx = false;
			} else {
				// Start the hang timer if not already running
				if (!m_hangTimer.isRunning())
					m_hangTimer.start();

				if (m_hangTimer.isRunning() && m_hangTimer.hasExpired()) {
					m_hangTimer.stop();
					m_tx = false;
				}
			}
		}
	} else if (!m_networkBuffer.isEmpty() && m_outBuffer.isEmpty()) {
		// Switch on the transmitter
		m_networkStarted = true;
		m_tx = true;

#if defined(TX_TO_WAV_FILE)
		wxDateTime time;
		time.SetToCurrent();

		// This is for logging the output audio to a WAV file
		wxString fileName = time.Format(wxT("%Y%m%d-%H%M%S.wav"));
		CWAVFileWriter* writer = new CWAVFileWriter(fileName, DSTAR_RADIO_SAMPLE_RATE, 1U, 16U, DSTAR_RADIO_BLOCK_SIZE);

		bool res = writer->open();
		if (!res) {
			wxLogError(wxT("Cannot open the output WAV file - %s"), fileName.c_str());
			delete writer;
		} else {
			wxLogMessage(wxT("Opened the output WAV file - %s"), fileName.c_str());
			m_writer = writer;
		}
#endif
		// Put quite a lot of data into the buffer to allow for slow downs
		bool bits[DV_FRAME_LENGTH_BITS * 3U];
		unsigned int length = m_networkBuffer.getData(bits, DV_FRAME_LENGTH_BITS * 3U);

		transmitBits(bits, length);
	} else if (!m_networkBuffer.isEmpty() && !m_outBuffer.isEmpty()) {
		m_networkStarted = true;
		m_tx = true;

		bool bits[DV_FRAME_LENGTH_BITS];
		unsigned int length = m_networkBuffer.getData(bits, DV_FRAME_LENGTH_BITS);

		transmitBits(bits, length);
	} else {	// m_networkBuffer.isEmpty() && !m_outBuffer.isEmpty()
		m_networkStarted = true;
		m_tx = true;
	}

	if (m_pttDelay != NULL)
		m_controller->setRadioTransmit(m_pttDelay->delay(m_tx));
	else
		m_controller->setRadioTransmit(m_tx);
}