Exchange data with an activated target (*send_data* is a command
        frame) or as an activated target (*send_data* is a response
        frame). Returns a target response frame (if data is send to an
        activated target) or a next command frame (if data is send
        from an activated target). Returns None if the communication
        link broke during exchange (if data is sent as a target). The
        timeout is the number of seconds to wait for data to return,
        if the timeout expires an nfc.clf.TimeoutException is
        raised. Other nfc.clf.CommunicationError exceptions may be raised if
        an error is detected during communication.

def exchange(self, send_data, timeout):
        """Exchange data with an activated target (*send_data* is a command
        frame) or as an activated target (*send_data* is a response
        frame). Returns a target response frame (if data is send to an
        activated target) or a next command frame (if data is send
        from an activated target). Returns None if the communication
        link broke during exchange (if data is sent as a target). The
        timeout is the number of seconds to wait for data to return,
        if the timeout expires an nfc.clf.TimeoutException is
        raised. Other nfc.clf.CommunicationError exceptions may be raised if
        an error is detected during communication.

        """
        with self.lock:
            if self.device is None:
                raise IOError(errno.ENODEV, os.strerror(errno.ENODEV))

            log.debug(">>> %s timeout=%s", print_data(send_data), str(timeout))

            if isinstance(self.target, RemoteTarget):
                exchange = self.device.send_cmd_recv_rsp
            elif isinstance(self.target, LocalTarget):
                exchange = self.device.send_rsp_recv_cmd
            else:
                log.error("no target for data exchange")
                return None

            send_time = time.time()
            rcvd_data = exchange(self.target, send_data, timeout)
            recv_time = time.time() - send_time

            log.debug("<<< %s %.3fs", print_data(rcvd_data), recv_time)
            return rcvd_data