<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def check_connection_state(self):
 """Check the state of the connection using connection state request. This sends a CONNECTION_STATE_REQUEST. This method will only return True, if the connection is established and no error code is returned from the KNX/IP gateway """

        if not self.connected:
            self.connection_state = -1
            return False

        frame = KNXIPFrame(KNXIPFrame.CONNECTIONSTATE_REQUEST)
        frame.body = self.hpai_body()

        # Send maximum 3 connection state requests with a 10 second timeout
        res = False
        self.connection_state = 0

        maximum_retry = 3
        for retry_counter in range(0, maximum_retry):
            logging.debug("Heartbeat: Send connection state request")

            # Suggestion:
            # Carve the Control Socket out of the KNXIPTunnel
            # Class and Public only the Send and Receive
            # function and Implement in there the Heartbeat so we
            # can block when other Functions want to send
            self.control_socket.settimeout(10)  # Kind of a quirks
            self.control_socket.sendto(bytes(frame.to_frame()),
                                       (self.remote_ip, self.remote_port))

            try:
                self.control_socket.sendto(bytes(frame.to_frame()),
                                           (self.remote_ip, self.remote_port))
                receive = self.control_socket.recv(1024)

            except socket.timeout:
                logging.info("Heartbeat: No response, Retry Counter %d/%d",
                             retry_counter, maximum_retry)
                break

            frame = KNXIPFrame.from_frame(receive)
            if frame.service_type_id == KNXIPFrame.CONNECTIONSTATE_RESPONSE:
                if frame.body[1] == KNXIPFrame.E_NO_ERROR:
                    logging.debug("Heartbeat: Successful")
                    res = True
                    break
                if frame.body[1] == KNXIPFrame.E_CONNECTION_ID:
                    logging.error(
                        "Heartbeat: Response No active "
                        "connection found for Channel:%d ", self.channel
                    )
                if frame.body[1] == KNXIPFrame.E_DATA_CONNECTION:
                    logging.error(
                        "Heartbeat: Response Data Connection Error Response "
                        "for  Channel:%d ", self.channel
                    )
                if frame.body[1] == KNXIPFrame.E_DATA_CONNECTION:
                    logging.error(
                        "Heartbeat: Response KNX Sub Network Error Response "
                        "for  Channel:%d ", self.channel
                    )
            else:
                logging.error("Heartbeat: Invalid Response!")

        if self.connection_state != 0:
            logging.info("Heartbeat: Connection state was %s",
                         self.connection_state)
            res = False

        if not res:
            if self.connection_state == 0:
                self.connection_state = -1
            self.disconnect()
            return False

        return True