public Error(Message message) { this.message = message; ErrorName = (string)message.Header[FieldCode.ErrorName]; ReplySerial = (uint)message.Header[FieldCode.ReplySerial]; //Signature = (Signature)message.Header[FieldCode.Signature]; }
public MessageReader(Message message) : this(message.Header.Endianness, message.Body) { if (message == null) throw new ArgumentNullException ("message"); this.message = message; }
public Signal(Message message) { this.message = message; Path = (ObjectPath)message.Header[FieldCode.Path]; Interface = (string)message.Header[FieldCode.Interface]; Member = (string)message.Header[FieldCode.Member]; Sender = (string)message.Header[FieldCode.Sender]; }
public MethodCall(Message message) { this.message = message; Path = (ObjectPath)message.Header[FieldCode.Path]; Interface = (string)message.Header[FieldCode.Interface]; Member = (string)message.Header[FieldCode.Member]; Destination = (string)message.Header[FieldCode.Destination]; //TODO: filled by the bus so reliable, but not the case for p2p //so we make it optional here, but this needs some more thought //if (message.Header.Fields.ContainsKey (FieldCode.Sender)) Sender = (string)message.Header[FieldCode.Sender]; #if PROTO_REPLY_SIGNATURE //TODO: note that an empty ReplySignature should really be treated differently to the field not existing! if (message.Header.Fields.ContainsKey (FieldCode.ReplySignature)) ReplySignature = (Signature)message.Header[FieldCode.ReplySignature]; else ReplySignature = Signature.Empty; #endif Signature = message.Signature; }
internal uint SendReal(Message msg) { if (!isConnected) return 0; try { return base.Send(msg); } catch { //} catch (System.IO.IOException) { isConnected = false; Server.SBus.RemoveConnection(this); } return 0; }
internal override uint Send(Message msg) { if (!isConnected) return 0; /* if (msg.Header.MessageType == DBus.MessageType.Signal) { Signal signal = new Signal (msg); if (signal.Member == "NameAcquired" || signal.Member == "NameLost") { string dest = (string)msg.Header[FieldCode.Destination]; if (dest != UniqueName) return 0; } } */ if (msg.Header.MessageType != DBus.MessageType.MethodReturn) { msg.Header[FieldCode.Sender] = ServerBus.DBusBusName; } if (UniqueName != null) msg.Header[FieldCode.Destination] = UniqueName; if (shouldDump) { MessageDumper.WriteComment("Sending:", Console.Out); MessageDumper.WriteMessage(msg, Console.Out); } //return base.Send (msg); return SendReal(msg); }
internal override void HandleMessage(Message msg) { if (!isConnected) return; if (msg == null) { Console.Error.WriteLine("Disconnected!"); isConnected = false; //Server.Bus.RemoveConnection (this); //ServerBus sbus = Unregister (new ObjectPath ("/org/freedesktop/DBus")) as ServerBus; /* ServerBus sbus = Unregister (new ObjectPath ("/org/freedesktop/DBus")) as ServerBus; Register (new ObjectPath ("/org/freedesktop/DBus"), sbus); sbus.RemoveConnection (this); */ Server.SBus.RemoveConnection(this); //Server.ConnectionLost (this); return; } Server.CurrentMessageConnection = this; Server.CurrentMessage = msg; try { if (shouldDump) { MessageDumper.WriteComment("Handling:", Console.Out); MessageDumper.WriteMessage(msg, Console.Out); } if (UniqueName != null) msg.Header[FieldCode.Sender] = UniqueName; object fieldValue = msg.Header[FieldCode.Destination]; if (fieldValue != null) { if ((string)fieldValue == ServerBus.DBusBusName) { // Workaround for our daemon only listening on a single path if (msg.Header.MessageType == DBus.MessageType.MethodCall) msg.Header[FieldCode.Path] = ServerBus.Path; base.HandleMessage(msg); //return; } } //base.HandleMessage (msg); Server.SBus.HandleMessage(msg); } finally { Server.CurrentMessageConnection = null; Server.CurrentMessage = null; } }
internal void HandleMessage(Message msg) { if (msg == null) return; //List<Connection> recipients = new List<Connection> (); HashSet<Connection> recipients = new HashSet<Connection>(); //HashSet<Connection> recipientsAll = new HashSet<Connection> (Connections); object fieldValue = msg.Header[FieldCode.Destination]; if (fieldValue != null) { string destination = (string)fieldValue; Connection destConn; if (Names.TryGetValue(destination, out destConn)) recipients.Add(destConn); else if (destination != DBusBusName && !destination.StartsWith(":") && (msg.Header.Flags & HeaderFlag.NoAutoStart) != HeaderFlag.NoAutoStart) { // Attempt activation StartProcessNamed(destination); //Thread.Sleep (5000); // TODO: Route the message to the newly activated service! activationMessages[destination] = msg; //if (Names.TryGetValue (destination, out destConn)) // recipients.Add (destConn); //else // Console.Error.WriteLine ("Couldn't route message to activated service"); } else if (destination != DBusBusName) { // Send an error when there's no hope of getting the requested reply if (msg.ReplyExpected) { // Error org.freedesktop.DBus.Error.ServiceUnknown: The name {0} was not provided by any .service files Message rmsg = MessageHelper.CreateUnknownMethodError(new MethodCall(msg)); if (rmsg != null) { //Caller.Send (rmsg); Caller.SendReal(rmsg); return; } } } } HashSet<Connection> recipientsMatchingHeader = new HashSet<Connection>(); HashSet<ArgMatchTest> a = new HashSet<ArgMatchTest>(); foreach (KeyValuePair<MatchRule, List<Connection>> pair in Rules) { if (recipients.IsSupersetOf(pair.Value)) continue; if (pair.Key.MatchesHeader(msg)) { a.UnionWith(pair.Key.Args); recipientsMatchingHeader.UnionWith(pair.Value); } } MatchRule.Test(a, msg); foreach (KeyValuePair<MatchRule, List<Connection>> pair in Rules) { if (recipients.IsSupersetOf(pair.Value)) continue; if (!recipientsMatchingHeader.IsSupersetOf(pair.Value)) continue; if (a.IsSupersetOf(pair.Key.Args)) recipients.UnionWith(pair.Value); } foreach (Connection conn in recipients) { // TODO: rewrite/don't header fields //conn.Send (msg); // TODO: Zero the Serial or not? //msg.Header.Serial = 0; ((ServerConnection)conn).SendReal(msg); } }
public static void WriteMessage(Message msg, TextWriter w) { w.WriteLine ("# Message"); w.WriteLine ("# Header"); MessageDumper.WriteBlock (msg.GetHeaderData (), w); w.WriteLine ("# Body"); MessageDumper.WriteBlock (msg.Body, w); w.WriteLine (); w.Flush (); }
public static Message ReadMessage(TextReader r) { byte[] header = MessageDumper.ReadBlock (r); if (header == null) return null; byte[] body = MessageDumper.ReadBlock (r); Message msg = new Message (); msg.SetHeaderData (header); msg.Body = body; return msg; }
public static object[] GetDynamicValues(Message msg) { Type[] types = msg.Signature.ToTypes (); return GetDynamicValues (msg, types); }
public static object[] GetDynamicValues(Message msg, Type[] types) { //TODO: this validation check should provide better information, eg. message dump or a stack trace, or at least the interface/member if (Protocol.Verbose) { Signature expected = Signature.GetSig (types); Signature actual = msg.Signature; if (actual != expected) Console.Error.WriteLine ("Warning: The signature of the message does not match that of the handler: " + "Expected '" + expected + "', got '" + actual + "'"); } object[] vals = new object[types.Length]; if (msg.Body != null) { MessageReader reader = new MessageReader (msg); for (int i = 0 ; i != types.Length ; i++) vals[i] = reader.ReadValue (types[i]); } return vals; }
public static object[] GetDynamicValues(Message msg, ParameterInfo[] parms) { //TODO: this validation check should provide better information, eg. message dump or a stack trace, or at least the interface/member /* if (Protocol.Verbose) { Signature expected = Signature.GetSig (types); Signature actual = msg.Signature; if (actual != expected) Console.Error.WriteLine ("Warning: The signature of the message does not match that of the handler: " + "Expected '" + expected + "', got '" + actual + "'"); } */ object[] vals = new object[parms.Length]; if (msg.Body != null) { MessageReader reader = new MessageReader (msg); foreach (ParameterInfo parm in parms) { if (parm.IsOut) continue; vals[parm.Position] = reader.ReadValue (parm.ParameterType); } } return vals; }
public bool MatchesHeader(Message msg) { if (MessageType != null) if (msg.Header.MessageType != MessageType) return false; foreach (KeyValuePair<FieldCode,MatchTest> pair in Fields) { object value; if (!msg.Header.Fields.TryGetValue ((byte)pair.Key, out value)) return false; if (!pair.Value.Value.Equals (value)) return false; } return true; }
public static void Test(HashSet<ArgMatchTest> a, Message msg) { List<Signature> sigs = new List<Signature> (); sigs.AddRange (msg.Signature.GetParts ()); if (sigs.Count == 0) { a.Clear (); return; } a.RemoveWhere ( delegate (ArgMatchTest t) { return t.ArgNum >= sigs.Count || t.Signature != sigs[t.ArgNum]; } ); // Sorting the list here is not ideal List<ArgMatchTest> tests = new List<ArgMatchTest> (a); tests.Sort ( delegate (ArgMatchTest aa, ArgMatchTest bb) { return aa.ArgNum - bb.ArgNum; } ); if (tests.Count == 0) { a.Clear (); return; } MessageReader reader = new MessageReader (msg); int argNum = 0; foreach (ArgMatchTest test in tests) { if (argNum > test.ArgNum) { // This test cannot pass because a previous test already did. // So we already know it will fail without even trying. // This logic will need to be changed to support wildcards. a.Remove (test); continue; } while (argNum != test.ArgNum) { Signature sig = sigs[argNum]; if (!reader.StepOver (sig)) throw new Exception (); argNum++; } // TODO: Avoid re-reading values int savedPos = reader.pos; if (!reader.ReadValue (test.Signature[0]).Equals (test.Value)) { a.Remove (test); reader.pos = savedPos; continue; } argNum++; } }
public MessageReader SendMethodCall(string iface, string member, string inSigStr, MessageWriter writer, Type retType, DisposableList disposableList, out Exception exception) { if (string.IsNullOrEmpty(bus_name)) { throw new ArgumentNullException("bus_name"); } if (object_path == null) { throw new ArgumentNullException("object_path"); } exception = null; Signature inSig = String.IsNullOrEmpty(inSigStr) ? Signature.Empty : new Signature(inSigStr); MessageContainer method_call = new MessageContainer { Path = object_path, Interface = iface, Member = member, Destination = bus_name, Signature = inSig }; Message callMsg = method_call.Message; callMsg.AttachBodyTo(writer); bool needsReply = true; callMsg.ReplyExpected = needsReply; callMsg.Signature = inSig; if (!needsReply) { conn.Send(callMsg); return(null); } #if PROTO_REPLY_SIGNATURE if (needsReply) { Signature outSig = Signature.GetSig(retType); callMsg.Header[FieldCode.ReplySignature] = outSig; } #endif Message retMsg = conn.SendWithReplyAndBlock(callMsg, disposableList != null); if (disposableList != null && retMsg.UnixFDArray != null) { foreach (var fd in retMsg.UnixFDArray.FDs) { disposableList.Add(fd); } } MessageReader retVal = null; //handle the reply message switch (retMsg.Header.MessageType) { case MessageType.MethodReturn: retVal = new MessageReader(retMsg); break; case MessageType.Error: MessageContainer error = MessageContainer.FromMessage(retMsg); string errMsg = String.Empty; if (retMsg.Signature.Value.StartsWith("s")) { MessageReader reader = new MessageReader(retMsg); errMsg = reader.ReadString(); } exception = new Exception(error.ErrorName + ": " + errMsg); break; default: throw new Exception("Got unexpected message of type " + retMsg.Header.MessageType + " while waiting for a MethodReturn or Error"); } return(retVal); }