2 using System
.Collections
.Generic
;
5 public static class VxDbus
{
6 static WvLog log
= new WvLog("VxDbus", WvLog
.L
.Debug1
);
7 static WvLog smalldump
= log
.split(WvLog
.L
.Debug4
);
8 static WvLog fulldump
= log
.split(WvLog
.L
.Debug5
);
10 public static Message
CreateError(string type
, string msg
, Message cause
)
12 Message error
= new Message();
13 error
.Header
.MessageType
= MessageType
.Error
;
15 HeaderFlag
.NoReplyExpected
| HeaderFlag
.NoAutoStart
;
16 error
.Header
.Fields
[FieldCode
.ErrorName
] = type
;
17 error
.Header
.Fields
[FieldCode
.ReplySerial
] = cause
.Header
.Serial
;
20 if (cause
.Header
.Fields
.TryGetValue(FieldCode
.Sender
, out sender
))
21 error
.Header
.Fields
[FieldCode
.Destination
] = sender
;
24 error
.Signature
= new Signature("s");
25 MessageWriter writer
=
26 new MessageWriter(Connection
.NativeEndianness
);
28 error
.Body
= writer
.ToArray();
34 public static Message
CreateReply(Message call
)
36 return CreateReply(call
, null, null);
39 public static Message
CreateReply(Message call
, string signature
,
42 Message reply
= new Message();
43 reply
.Header
.MessageType
= MessageType
.MethodReturn
;
45 HeaderFlag
.NoReplyExpected
| HeaderFlag
.NoAutoStart
;
46 reply
.Header
.Fields
[FieldCode
.ReplySerial
] = call
.Header
.Serial
;
49 if (call
.Header
.Fields
.TryGetValue(FieldCode
.Sender
, out sender
))
50 reply
.Header
.Fields
[FieldCode
.Destination
] = sender
;
52 if (signature
!= null && signature
!= "") {
53 reply
.Signature
= new Signature(signature
);
54 reply
.Body
= body
.ToArray();
60 public static Message
CreateSignal(object destination
, string signalname
,
61 string signature
, MessageWriter body
)
63 // Idea shamelessly stolen from CreateReply method above
64 Message signal
= new Message();
65 signal
.Header
.MessageType
= MessageType
.Signal
;
67 HeaderFlag
.NoReplyExpected
| HeaderFlag
.NoAutoStart
;
68 // The ObjectPath is required by signals, and is the "source of the
69 // signal." OK then; seems useless to me.
70 signal
.Header
.Fields
[FieldCode
.Path
] = new ObjectPath("/db");
71 signal
.Header
.Fields
[FieldCode
.Interface
] = "vx.db";
72 signal
.Header
.Fields
[FieldCode
.Member
] = signalname
;
74 if (destination
!= null)
75 signal
.Header
.Fields
[FieldCode
.Destination
] = destination
;
77 if (signature
!= null && signature
!= "")
79 signal
.Signature
= new Signature(signature
);
80 signal
.Body
= body
.ToArray();
86 public static void MessageDump(string prefix
, Message msg
)
88 Header hdr
= msg
.Header
;
90 if (hdr
.Fields
.ContainsKey(FieldCode
.ReplySerial
))
91 log
.print("MD {0} REPLY#{1}\n",
93 hdr
.Fields
[FieldCode
.ReplySerial
]);
94 else if (hdr
.MessageType
!= MessageType
.Signal
)
95 log
.print("MD {0} #{1} {2}.{3}\n",
98 hdr
.Fields
[FieldCode
.Interface
],
99 hdr
.Fields
[FieldCode
.Member
]);
101 log
.print("MD {0} {1}\n", prefix
, hdr
.Fields
[FieldCode
.Interface
]);
103 smalldump
.print("Message dump:\n");
104 smalldump
.print(" endianness={0} ", hdr
.Endianness
);
105 smalldump
.print(" t={0} ", hdr
.MessageType
);
106 smalldump
.print(" ver={0} ", hdr
.MajorVersion
);
107 smalldump
.print(" blen={0} ", hdr
.Length
);
108 smalldump
.print(" ser={0}\n", hdr
.Serial
);
109 smalldump
.print(" flags={0}\n", hdr
.Flags
);
111 smalldump
.print(" Fields\n");
112 foreach (KeyValuePair
<FieldCode
,object> kvp
in hdr
.Fields
) {
113 smalldump
.print(" - {0}: {1}\n", kvp
.Key
, kvp
.Value
);
117 byte[] header
= msg
.GetHeaderData();
118 if (header
!= null) {
119 smalldump
.print("Header data:\n");
120 smalldump
.print(wv
.hexdump(header
));
121 hdrlen
= header
.Length
;
123 smalldump
.print("No header data encoded\n");
126 if (msg
.Body
!= null) {
127 fulldump
.print("Body data:\n");
128 fulldump
.print(wv
.hexdump(msg
.Body
, hdrlen
, msg
.Body
.Length
));
130 smalldump
.print("No body data encoded\n");
135 public class VxMethodCallRouter
{
136 WvLog log
= new WvLog("VxMethodCallRouter", WvLog
.L
.Debug3
);
138 private IDictionary
<string,VxInterfaceRouter
> interfaces
139 = new Dictionary
<string,VxInterfaceRouter
>();
141 public void AddInterface(VxInterfaceRouter ir
)
143 log
.print("Adding interface {0}\n", ir
.Interface
);
144 interfaces
.Add(ir
.Interface
, ir
);
147 public void RemoveInterface(VxInterfaceRouter ir
)
149 RemoveInterface(ir
.Interface
);
152 public void RemoveInterface(string iface
)
154 interfaces
.Remove(iface
);
157 public bool RouteMessage(Message call
, out Message reply
)
159 if (call
.Header
.MessageType
!= MessageType
.MethodCall
)
160 throw new ArgumentException("Not a method call message");
164 // FIXME: Dbus spec says that interface should be optional so it
165 // should search all of the interfaces for a matching method...
167 if (!call
.Header
.Fields
.TryGetValue(FieldCode
.Interface
, out iface
))
168 return false; // No interface; ignore it
170 log
.print("Router interface {0}\n", iface
);
172 VxInterfaceRouter ir
;
173 if (!interfaces
.TryGetValue((string)iface
, out ir
))
174 return false; // Interface not found
176 log
.print("Passing to interface router\n");
178 return ir
.RouteMessage(call
, out reply
);
182 public abstract class VxInterfaceRouter
{
183 public readonly string Interface
;
185 protected VxInterfaceRouter(string iface
)
190 // Return value is the response
192 void MethodCallProcessor(Message call
, out Message reply
);
194 protected IDictionary
<string,MethodCallProcessor
> methods
195 = new Dictionary
<string,MethodCallProcessor
>();
197 public bool RouteMessage(Message call
, out Message reply
)
199 if (call
.Header
.MessageType
!= MessageType
.MethodCall
)
200 throw new ArgumentException("Not a method call message");
205 if (!call
.Header
.Fields
.TryGetValue(FieldCode
.Member
, out method
))
206 return false; // No method
208 MethodCallProcessor processor
;
209 if (!methods
.TryGetValue((string)method
, out processor
)) {
210 reply
= VxDbus
.CreateError(
211 "org.freedesktop.DBus.Error.UnknownMethod",
213 "Method name {0} not found on interface {1}",
214 method
, Interface
), call
);
219 ExecuteCall(processor
, call
, out reply
);
224 protected virtual void ExecuteCall(MethodCallProcessor processor
,
225 Message call
, out Message reply
)
228 processor(call
, out reply
);
229 } catch (Exception e
) {
230 reply
= VxDbus
.CreateError(