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 MethodCall (Message message) { this.message = message; Path = (ObjectPath)message.Header.Fields[FieldCode.Path]; if (message.Header.Fields.ContainsKey (FieldCode.Interface)) Interface = (string)message.Header.Fields[FieldCode.Interface]; Member = (string)message.Header.Fields[FieldCode.Member]; Destination = (string)message.Header.Fields[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.Fields[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.Fields[FieldCode.ReplySignature]; else ReplySignature = Signature.Empty; #endif //Signature = (Signature)message.Header.Fields[FieldCode.Signature]; //use the wrapper in Message because it checks for emptiness 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 == NDesk.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 != NDesk.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 == NDesk.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 object[] GetDynamicValues (Message msg, Type[] types) { //TODO: this validation check should provide better information, eg. message dump or a stack trace if (Protocol.Verbose) { if (Signature.GetSig (types) != msg.Signature) Console.Error.WriteLine ("Warning: The signature of the message does not match that of the handler"); } object[] vals = new object[types.Length]; if (msg.Body != null) { MessageReader reader = new MessageReader (msg); for (int i = 0 ; i != types.Length ; i++) { object arg; reader.GetValue (types[i], out arg); vals[i] = arg; } } return vals; }
//GetDynamicValues() should probably use yield eventually public static object[] GetDynamicValues (Message msg, ParameterInfo[] parms) { //TODO: consider out parameters Type[] types = new Type[parms.Length]; for (int i = 0 ; i != parms.Length ; i++) types[i] = parms[i].ParameterType; return MessageHelper.GetDynamicValues (msg, types); }
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 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]; }
//this is useful as a Predicate<Message> delegate public bool Matches (Message msg) { if (MessageType != null) if (msg.Header.MessageType != MessageType) return false; object value; if (Interface != null) if (msg.Header.Fields.TryGetValue (FieldCode.Interface, out value)) if ((string)value != Interface) return false; if (Member != null) if (msg.Header.Fields.TryGetValue (FieldCode.Member, out value)) if ((string)value != Member) return false; if (Path != null) if (msg.Header.Fields.TryGetValue (FieldCode.Path, out value)) //if ((ObjectPath)value != Path) if (((ObjectPath)value).Value != Path.Value) return false; if (Sender != null) if (msg.Header.Fields.TryGetValue (FieldCode.Sender, out value)) if ((string)value != Sender) return false; if (Destination != null) if (msg.Header.Fields.TryGetValue (FieldCode.Destination, out value)) if ((string)value != Destination) return false; //FIXME: do args return true; }
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 Signal (Message message) { this.message = message; Path = (ObjectPath)message.Header.Fields[FieldCode.Path]; Interface = (string)message.Header.Fields[FieldCode.Interface]; Member = (string)message.Header.Fields[FieldCode.Member]; if (message.Header.Fields.ContainsKey (FieldCode.Sender)) Sender = (string)message.Header.Fields[FieldCode.Sender]; }
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 MethodReturn (Message message) { this.message = message; ReplySerial = (uint)message.Header.Fields[FieldCode.ReplySerial]; }
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; }