//not particularly efficient and needs to be generalized internal void HandleMethodCall(MethodCall method_call) { //TODO: Ping and Introspect need to be abstracted and moved somewhere more appropriate once message filter infrastructure is complete //FIXME: these special cases are slightly broken for the case where the member but not the interface is specified in the message if (method_call.Interface == "org.freedesktop.DBus.Peer" && method_call.Member == "Ping") { object[] pingRet = new object[0]; Message reply = MessageHelper.ConstructReplyFor(method_call, pingRet); Send(reply); return; } if (method_call.Interface == "org.freedesktop.DBus.Introspectable" && method_call.Member == "Introspect") { Introspector intro = new Introspector(); intro.root_path = method_call.Path; intro.WriteStart(); //FIXME: do this properly //this is messy and inefficient List <string> linkNodes = new List <string> (); int depth = method_call.Path.Decomposed.Length; foreach (ObjectPath pth in RegisteredObjects.Keys) { if (pth.Value == (method_call.Path.Value)) { ExportObject exo = (ExportObject)RegisteredObjects[pth]; intro.WriteType(exo.obj.GetType()); } else { for (ObjectPath cur = pth; cur != null; cur = cur.Parent) { if (cur.Value == method_call.Path.Value) { string linkNode = pth.Decomposed[depth]; if (!linkNodes.Contains(linkNode)) { intro.WriteNode(linkNode); linkNodes.Add(linkNode); } } } } } intro.WriteEnd(); object[] introRet = new object[1]; introRet[0] = intro.xml; Message reply = MessageHelper.ConstructReplyFor(method_call, introRet); Send(reply); return; } BusObject bo; if (RegisteredObjects.TryGetValue(method_call.Path, out bo)) { ExportObject eo = (ExportObject)bo; eo.HandleMethodCall(method_call); } else { MaybeSendUnknownMethodError(method_call); } }
public void HandleMethodCall(MethodCall method_call) { Type type = obj.GetType(); //object retObj = type.InvokeMember (msg.Member, BindingFlags.InvokeMethod, null, obj, MessageHelper.GetDynamicValues (msg)); //TODO: there is no member name mapping for properties etc. yet MethodInfo mi = Mapper.GetMethod(type, method_call); if (mi == null) { conn.MaybeSendUnknownMethodError(method_call); return; } object retObj = null; try { object[] inArgs = MessageHelper.GetDynamicValues(method_call.message, mi.GetParameters()); retObj = mi.Invoke(obj, inArgs); } catch (TargetInvocationException e) { if (!method_call.message.ReplyExpected) { return; } Exception ie = e.InnerException; //TODO: complete exception sending support Error error = new Error(Mapper.GetInterfaceName(ie.GetType()), method_call.message.Header.Serial); error.message.Signature = new Signature(DType.String); MessageWriter writer = new MessageWriter(Connection.NativeEndianness); writer.connection = conn; writer.Write(ie.Message); error.message.Body = writer.ToArray(); //TODO: we should be more strict here, but this fallback was added as a quick fix for p2p if (method_call.Sender != null) { error.message.Header.Fields[FieldCode.Destination] = method_call.Sender; } conn.Send(error.message); return; } if (method_call.message.ReplyExpected) { /* * object[] retObjs; * * if (retObj == null) { * retObjs = new object[0]; * } else { * retObjs = new object[1]; * retObjs[0] = retObj; * } * * Message reply = ConstructReplyFor (method_call, retObjs); */ Message reply = MessageHelper.ConstructReplyFor(method_call, mi.ReturnType, retObj); conn.Send(reply); } }