()
	defer ch.Unlock()
	if err := ch.onClosing(); err!= nil {
		return err
	}
	if err := ch.onClose(); err!= nil {
		return err
	}
	err := ch.onClosed()
	return err
}

// Abort the secure channel.
func (ch *serverSecureChannel) Abort(reason ua.StatusCode, message string) error {
	ch.Lock()
	defer ch.Unlock()
	if err := ch.onClosing(); err!= nil {
		return err
	}
	if err := ch.onAbort(reason, message); err!= nil {
		return err
	}
	err := ch.onClosed()
	return err
}

// Write the service response.
func (ch *serverSecureChannel) Write(res ua.ServiceResponse, id uint32) error {
	if ch.trace {
		b, _ := json.MarshalIndent(res, "", " ")
		log.Printf("%s%s", reflect.TypeOf(res).Elem().Name(), b)
	}
	switch res1 := res.(type) {
	case *ua.OpenSecureChannelResponse:
		err := ch.sendOpenSecureChannelResponse(res1, id)
		if err!= nil {
			log.Printf("Error sending OpenSecureChannelResponse. %s\n", err)
		}
		return err
	default:
		err := ch.sendServiceResponse(res1, id)
		if err!= nil {
			log.Printf("Error sending service response. %s\n", err)
		}
		return err
	}
}

func (ch *serverSecureChannel) onOpening() error {
	// log.Printf("onOpening secure channel.\n")
	return nil
}

func (ch *serverSecureChannel) onOpen() error {
	// log.Printf("onOpen secure channel.\n")
	buf := *(bytesPool.Get().(*[]byte))
	defer bytesPool.Put(&buf)
	_, err := ch.read(buf)
	if err!= nil {
		// log.Printf("Error opening Transport Channel: %s \n", err.Error())
		return ua.BadDecodingError
	}

	var reader = bytes.NewReader(buf)
	var ec = ua.NewEncodingContext()
	var dec = ua.NewBinaryDecoder(reader, ec)

	var msgType uint32
	if err := dec.ReadUInt32(&msgType); err!= nil {
		return ua.BadDecodingError
	}
	var msgLen uint32
	if err := dec.ReadUInt32(&msgLen); err!= nil {
		return ua.BadDecodingError
	}

	var remoteProtocolVersion, remoteReceiveBufferSize, remoteSendBufferSize, remoteMaxMessageSize, remoteMaxChunkCount uint32
	switch msgType {
	case ua.MessageTypeHello:
		if msgLen < 28 {
			return ua.BadDecodingError
		}
		if err!= nil {
			return ua.BadDecodingError
		}
		if err = dec.ReadUInt32(&remoteProtocolVersion); err!= nil || remoteProtocolVersion < protocolVersion {
			return ua.BadProtocolVersionUnsupported
		}
		if err = dec.ReadUInt32(&remoteReceiveBufferSize); err!= nil {
			return ua.BadDecodingError
		}
		if err = dec.ReadUInt32(&remoteSendBufferSize); err!= nil {
			return ua.BadDecodingError
		}
		if err = dec.ReadUInt32(&remoteMaxMessageSize); err!= nil {
			return ua.BadDecodingError
		}
		if err = dec.ReadUInt32(&remoteMaxChunkCount); err!= nil {
			return ua.BadDecodingError
		}
		if err := dec.ReadString(&ch.endpointURL); err!= nil {
			return ua.BadDecodingError
		}
		// log.Printf("-> Hello { ver: %d, rec: %d, snd: %d, msg: %d, chk: %d, ep: %s }\n", remoteProtocolVersion, ch.remoteReceiveBufferSize, ch.remoteSendBufferSize, ch.remoteMaxMessageSize, ch.remoteMaxChunkCount, ch.endpointUrl)

	default:
		return ua.BadDecodingError
	}

	var writer = ua.NewWriter(buf)
	var enc = ua.NewBinaryEncoder(writer, ec)

	// limit the receive buffer to what the sender can send
	if ch.receiveBufferSize > remoteSendBufferSize {
		ch.receiveBufferSize = remoteSendBufferSize
	}
	// limit the send buffer to what the receiver can receive
	if ch.sendBufferSize > remoteReceiveBufferSize {
		ch.sendBufferSize = remoteReceiveBufferSize
	}
	// limit the max message size to what the receiver can receive
	if remoteMaxMessageSize > 0 && ch.maxMessageSize > remoteMaxMessageSize {
		ch.maxMessageSize = remoteMaxMessageSize
	}
	// limit the max chunk count to what the receiver can receive
	if remoteMaxChunkCount > 0 && ch.maxChunkCount > remoteMaxChunkCount {
		ch.maxChunkCount = remoteMaxChunkCount
	}
	enc.WriteUInt32(ua.MessageTypeAck)
	enc.WriteUInt32(uint32(28))
	enc.WriteUInt32(protocolVersion)
	enc.WriteUInt32(ch.receiveBufferSize)
	enc.WriteUInt32(ch.sendBufferSize)
	enc.WriteUInt32(ch.maxMessageSize)
	enc.WriteUInt32(ch.maxChunkCount)
	_, err = ch.write(writer.Bytes())
	if err!= nil {
		// log.Printf("Error opening Transport Channel: %s \n", err.Error())
		return ua.BadEncodingError
	}
	// log.Printf("<- Ack { ver: %d, rec: %d, snd: %d, msg: %d, chk: %d, ep: %s }\n", protocolVersion, ch.receiveBufferSize, ch.sendBufferSize, ch.maxMessageSize, ch.maxChunkCount, ch.conn.RemoteAddr())

	ch.sendBuffer = make([]byte, ch.sendBufferSize)
	ch.receiveBuffer = make([]byte, ch.receiveBufferSize)
	ch.encryptionBuffer = make([]byte, ch.sendBufferSize)
	ch.tokenID = 0
	ch.sendingTokenID = 0
	ch.receivingTokenID = 0
	ch.responseCh = make(chan struct {
		ua.ServiceResponse
		uint32
	}, 32)

	// read first request, which must be an OpenSecureChannelRequest
	req, rid, err := ch.readRequest()
	if err!= nil {
		log.Printf("Error receiving OpenSecureChannelRequest. %s\n", err)
		return err
	}
	oscr, ok := req.(*ua.OpenSecureChannelRequest)
	if!ok {
		return ua.BadDecodingError
	}
	ch.tokenLock.Lock()
	ch.tokenID = ch.getNextTokenID()
	ch.securityMode = oscr.SecurityMode
	if ch.securityMode!= ua.MessageSecurityModeNone {
		ch.localNonce = getNextNonce(ch.securityPolicy.NonceSize())
	} else {
		ch.localNonce = []byte{}
	}
	ch.remoteNonce = []byte(oscr.ClientNonce)
	ch.tokenLock.Unlock()
	for _, ep := range ch.srv.Endpoints() {
		if ep.TransportProfileURI == ua.TransportProfileURIUaTcpTransport && ep.SecurityPolicyURI == ch.securityPolicyURI && ep.SecurityMode == ch.securityMode {
			ch.localEndpoint = ep
			break
		}
	}
	// connecting for discovery only
	if ch.localEndpoint.EndpointURL == "" && ch.securityPolicyURI == ua.SecurityPolicyURINone && ch.securityMode == ua.MessageSecurityModeNone {
		ch.discoveryOnly = true
		ch.localEndpoint = ua.EndpointDescription{
			EndpointURL:       ch.srv.localDescription.DiscoveryURLs[0],
			Server:            ch.srv.localDescription,
			SecurityMode:      ua.MessageSecurityModeNone,
			SecurityPolicyURI: ua.SecurityPolicyURINone,
			UserIdentityTokens: []ua.UserTokenPolicy{
				{
					PolicyID:          "Anonymous",
					