docs: async def start(self, remoteParameters):
          """
          Start DTLS transport negotiation with the parameters of the remote
          DTLS transport.
  
          :param: remoteParameters: An :class:`RTCDtlsParameters`.
          """
          assert self._state == State.NEW
          assert len(remoteParameters.fingerprints)
  
          if self.transport.role == 'controlling':
              self._role = 'server'
              lib.SSL_set_accept_state(self.ssl)
          else:
              self._role = 'client'
              lib.SSL_set_connect_state(self.ssl)
  
          self._set_state(State.CONNECTING)
          try:
              while not self.encrypted:
                  result = lib.SSL_do_handshake(self.ssl)
                  await self._write_ssl()
  
                  if result > 0:
                      self.encrypted = True
                      break
  
                  error = lib.SSL_get_error(self.ssl, result)
                  if error == lib.SSL_ERROR_WANT_READ:
                      await self._recv_next()
                  else:
                      self.__log_debug('x DTLS handshake failed (error %d)', error)
                      for info in get_error_queue():
                          self.__log_debug('x %s', ':'.join(info))
                      self._set_state(State.FAILED)
                      return
          except ConnectionError:
              self.__log_debug('x DTLS handshake failed (connection error)')
              self._set_state(State.FAILED)
              return
  
          # check remote fingerprint
          x509 = lib.SSL_get_peer_certificate(self.ssl)
          remote_fingerprint = certificate_digest(x509)
          fingerprint_is_valid = False
          for f in remoteParameters.fingerprints:
              if f.algorithm.lower() == 'sha-256' and f.value.lower() == remote_fingerprint.lower():
                  fingerprint_is_valid = True
                  break
          if not fingerprint_is_valid:
              self.__log_debug('x DTLS handshake failed (fingerprint mismatch)')
              self._set_state(State.FAILED)
              return
  
          # generate keying material
          buf = ffi.new('unsigned char[]', 2 * (SRTP_KEY_LEN + SRTP_SALT_LEN))
          extractor = b'EXTRACTOR-dtls_srtp'
          _openssl_assert(lib.SSL_export_keying_material(
              self.ssl, buf, len(buf), extractor, len(extractor), ffi.NULL, 0, 0) == 1)
  
          view = ffi.buffer(buf)
          if self._role == 'server':
              srtp_tx_key = get_srtp_key_salt(view, 1)
              srtp_rx_key = get_srtp_key_salt(view, 0)
          else:
              srtp_tx_key = get_srtp_key_salt(view, 0)
              srtp_rx_key = get_srtp_key_salt(view, 1)
  
          rx_policy = Policy(key=srtp_rx_key, ssrc_type=Policy.SSRC_ANY_INBOUND)
          rx_policy.allow_repeat_tx = True
          rx_policy.window_size = 1024
          self._rx_srtp = Session(rx_policy)
  
          tx_policy = Policy(key=srtp_tx_key, ssrc_type=Policy.SSRC_ANY_OUTBOUND)
          tx_policy.allow_repeat_tx = True
          tx_policy.window_size = 1024
          self._tx_srtp = Session(tx_policy)
  
          # start data pump
          self.__log_debug('- DTLS handshake complete')
          self._set_state(State.CONNECTED)
          self._task = asyncio.ensure_future(self.__run())