code: func (c *Client) ExchangeMTU(clientRxMTU int) (serverRxMTU int, err error) {
  	if clientRxMTU < ble.DefaultMTU || clientRxMTU > ble.MaxMTU {
  		return 0, ErrInvalidArgument
  	}
  
  	// Acquire and reuse the txBuf, and release it after usage.
  	// The same txBuf, or a newly allocate one, if the txMTU is changed,
  	// will be released back to the channel.
  	txBuf := <-c.chTxBuf
  	defer func() { c.chTxBuf <- txBuf }()
  
  	// Let L2CAP know the MTU we can handle.
  	c.l2c.SetRxMTU(clientRxMTU)
  
  	req := ExchangeMTURequest(txBuf[:3])
  	req.SetAttributeOpcode()
  	req.SetClientRxMTU(uint16(clientRxMTU))
  
  	b, err := c.sendReq(req)
  	if err != nil {
  		return 0, err
  	}
  
  	// Convert and validate the response.
  	rsp := ExchangeMTUResponse(b)
  	switch {
  	case rsp[0] == ErrorResponseCode && len(rsp) == 5:
  		return 0, ble.ATTError(rsp[4])
  	case rsp[0] == ErrorResponseCode && len(rsp) != 5:
  		fallthrough
  	case rsp[0] != rsp.AttributeOpcode():
  		fallthrough
  	case len(rsp) != 3:
  		return 0, ErrInvalidResponse
  	}
  
  	txMTU := int(rsp.ServerRxMTU())
  	if len(txBuf) != txMTU {
  		// Let L2CAP know the MTU that the remote device can handle.
  		c.l2c.SetTxMTU(txMTU)
  		// Put a re-allocated txBuf back to the channel.
  		// The txBuf has been captured in deferred function.
  		txBuf = make([]byte, txMTU, txMTU)
  	}
  
  	return txMTU, nil
  }
docs: // ExchangeMTU informs the server of the client’s maximum receive MTU size and
  // request the server to respond with its maximum receive MTU size. [Vol 3, Part F, 3.4.2.1]