示例#1
0
        //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);
            }
        }