code: func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
  	var call *Call
  
  	msg.serial = conn.getSerial()
  	if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
  		if ch == nil {
  			ch = make(chan *Call, 5)
  		} else if cap(ch) == 0 {
  			panic("dbus: unbuffered channel passed to (*Conn).Send")
  		}
  		call = new(Call)
  		call.Destination, _ = msg.Headers[FieldDestination].value.(string)
  		call.Path, _ = msg.Headers[FieldPath].value.(ObjectPath)
  		iface, _ := msg.Headers[FieldInterface].value.(string)
  		member, _ := msg.Headers[FieldMember].value.(string)
  		call.Method = iface + "." + member
  		call.Args = msg.Body
  		call.Done = ch
  		conn.callsLck.Lock()
  		conn.calls[msg.serial] = call
  		conn.callsLck.Unlock()
  		conn.outLck.RLock()
  		if conn.closed {
  			call.Err = ErrClosed
  			call.Done <- call
  		} else {
  			conn.out <- msg
  		}
  		conn.outLck.RUnlock()
  	} else {
  		conn.outLck.RLock()
  		if conn.closed {
  			call = &Call{Err: ErrClosed}
  		} else {
  			conn.out <- msg
  			call = &Call{Err: nil}
  		}
  		conn.outLck.RUnlock()
  	}
  	return call
  }
docs: // Send sends the given message to the message bus. You usually don't need to
  // use this; use the higher-level equivalents (Call / Go, Emit and Export)
  // instead. If msg is a method call and NoReplyExpected is not set, a non-nil
  // call is returned and the same value is sent to ch (which must be buffered)
  // once the call is complete. Otherwise, ch is ignored and a Call structure is
  // returned of which only the Err member is valid.