public void send(final byte[] frame, final boolean blocking)
		throws KNXAckTimeoutException, KNXPortClosedException, InterruptedException
	{
		boolean ack = false;
		try {
			for (int i = 0; i <= REPEAT_LIMIT; ++i) {
				if (logger.isLoggable(LogLevel.TRACE))
					logger.trace("sending FT1.2 frame, " + (blocking ? "" : "non-")
							+ "blocking, attempt " + (i + 1));
				sendData(frame);
				if (!blocking || waitForAck()) {
					ack = true;
					break;
				}
			}
			sendFrameCount ^= FRAMECOUNT_BIT;
			if (state == ACK_PENDING)
				state = OK;
			if (!ack)
				throw new KNXAckTimeoutException("no acknowledge reply received");
		}
		catch (final InterruptedIOException e) {
			throw new InterruptedException(e.getMessage());
		}
		catch (final IOException e) {
			close(false, e.getMessage());
			throw new KNXPortClosedException(e.getMessage(), port, e);
		}
	}