1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4 namespace System.ServiceModel.Channels
5 {
6     using System.Collections.Generic;
7     using System.ServiceModel;
8     using System.Diagnostics;
9     using System.Runtime.Serialization;
10     using System.ServiceModel.Diagnostics;
11 
12 
13     [MessageContract(IsWrapped = false)]
14     class ConnectInfo
15     {
16         [DataContract(Name = "ConnectInfo", Namespace = PeerStrings.Namespace)]
17         class ConnectInfoDC
18         {
19             [DataMember(Name = "NodeId")]
20             public ulong nodeId;
21 
22             [DataMember(Name = "Address")]
23             public PeerNodeAddress address;
24 
ConnectInfoDC()25             public ConnectInfoDC() { }
ConnectInfoDC(ulong nodeId, PeerNodeAddress address)26             public ConnectInfoDC(ulong nodeId, PeerNodeAddress address)
27             {
28                 this.nodeId = nodeId;
29                 this.address = address;
30             }
31         }
32 
33         [MessageBodyMember(Name = "Connect", Namespace = PeerStrings.Namespace)]
34         ConnectInfoDC body;
35 
ConnectInfo()36         public ConnectInfo()
37         {
38             this.body = new ConnectInfoDC();
39         }
40 
ConnectInfo(ulong nodeId, PeerNodeAddress address)41         public ConnectInfo(ulong nodeId, PeerNodeAddress address)
42         {
43             this.body = new ConnectInfoDC(nodeId, address);
44         }
45 
46         public PeerNodeAddress Address
47         {
48             get { return this.body.address; }
49         }
50 
51         public ulong NodeId
52         {
53             get { return this.body.nodeId; }
54         }
55 
HasBody()56         public bool HasBody()
57         {
58             return body != null;
59         }
60     }
61 
62     [MessageContract(IsWrapped = false)]
63     class DisconnectInfo
64     {
65         [DataContract(Name = "DisconnectInfo", Namespace = PeerStrings.Namespace)]
66         class DisconnectInfoDC
67         {
68             [DataMember(Name = "Reason")]
69             public DisconnectReason reason;
70 
71             [DataMember(Name = "Referrals")]
72             public Referral[] referrals;
73 
DisconnectInfoDC()74             public DisconnectInfoDC() { }
75 
DisconnectInfoDC(DisconnectReason reason, Referral[] referrals)76             public DisconnectInfoDC(DisconnectReason reason, Referral[] referrals)
77             {
78                 this.reason = reason;
79                 this.referrals = referrals;
80             }
81         }
82 
83         [MessageBodyMember(Name = "Disconnect", Namespace = PeerStrings.Namespace)]
84         DisconnectInfoDC body;
85 
DisconnectInfo()86         public DisconnectInfo()
87         {
88             body = new DisconnectInfoDC();
89         }
90 
DisconnectInfo(DisconnectReason reason, Referral[] referrals)91         public DisconnectInfo(DisconnectReason reason, Referral[] referrals)
92         {
93             this.body = new DisconnectInfoDC(reason, referrals);
94         }
95 
96         public DisconnectReason Reason
97         {
98             get { return this.body.reason; }
99         }
100 
101         public IList<Referral> Referrals
102         {
103             get
104             {
105                 return this.body.referrals != null ? Array.AsReadOnly<Referral>(this.body.referrals) : null;
106             }
107         }
108 
HasBody()109         public bool HasBody()
110         {
111             return body != null;
112         }
113     }
114 
115     // Reasons for sending a Disconnect message
116     enum DisconnectReason
117     {
118         LeavingMesh = PeerCloseReason.LeavingMesh,
119         NotUsefulNeighbor = PeerCloseReason.NotUsefulNeighbor,
120         DuplicateNeighbor = PeerCloseReason.DuplicateNeighbor,
121         DuplicateNodeId = PeerCloseReason.DuplicateNodeId,
122         NodeBusy = PeerCloseReason.NodeBusy,
123         InternalFailure = PeerCloseReason.InternalFailure,
124     }
125 
126 
127     //
128     // Service contract used for neighbor-to-neighbor communication
129     // Sending messages is asynchronous and processing incoming messages is synchronous.
130     // Used for Service implementation
131     //
132     [ServiceContract(Name = PeerStrings.ServiceContractName,
133                  Namespace = PeerStrings.Namespace,
134                  SessionMode = SessionMode.Required,
135                  CallbackContract = typeof(IPeerServiceContract))]
136     interface IPeerServiceContract
137     {
138         [OperationContract(IsOneWay = true, Action = PeerStrings.ConnectAction)]
Connect(ConnectInfo connectInfo)139         void Connect(ConnectInfo connectInfo);
140 
141         [OperationContract(IsOneWay = true, Action = PeerStrings.DisconnectAction)]
Disconnect(DisconnectInfo disconnectInfo)142         void Disconnect(DisconnectInfo disconnectInfo);
143 
144         [OperationContract(IsOneWay = true, Action = PeerStrings.RefuseAction)]
Refuse(RefuseInfo refuseInfo)145         void Refuse(RefuseInfo refuseInfo);
146 
147         [OperationContract(IsOneWay = true, Action = PeerStrings.WelcomeAction)]
Welcome(WelcomeInfo welcomeInfo)148         void Welcome(WelcomeInfo welcomeInfo);
149 
150         [OperationContract(IsOneWay = true, Action = PeerStrings.FloodAction, AsyncPattern = true)]
BeginFloodMessage(Message floodedInfo, AsyncCallback callback, object state)151         IAsyncResult BeginFloodMessage(Message floodedInfo, AsyncCallback callback, object state);
EndFloodMessage(IAsyncResult result)152         void EndFloodMessage(IAsyncResult result);
153 
154         [OperationContract(IsOneWay = true, Action = PeerStrings.LinkUtilityAction)]
LinkUtility(UtilityInfo utilityInfo)155         void LinkUtility(UtilityInfo utilityInfo);
156 
157         [OperationContract(
158             Action = TrustFeb2005Strings.RequestSecurityToken,
159             ReplyAction = TrustFeb2005Strings.RequestSecurityTokenResponse)]
ProcessRequestSecurityToken(Message message)160         Message ProcessRequestSecurityToken(Message message);
161 
162         [OperationContract(IsOneWay = true, Action = PeerStrings.PingAction)]
Ping(Message message)163         void Ping(Message message);
164 
165         [OperationContract(IsOneWay = true, Action = Addressing10Strings.FaultAction)]
Fault(Message message)166         void Fault(Message message);
167 
168     }
169 
170     [ServiceContract(Name = PeerStrings.ServiceContractName,
171                  Namespace = PeerStrings.Namespace,
172                  SessionMode = SessionMode.Required,
173                  CallbackContract = typeof(IPeerService))]
174     interface IPeerProxy : IPeerServiceContract, IOutputChannel
175     {
176     }
177 
178     [ServiceContract(Name = PeerStrings.ServiceContractName,
179                      Namespace = PeerStrings.Namespace,
180                      SessionMode = SessionMode.Required,
181                      CallbackContract = typeof(IPeerProxy))]
182     interface IPeerService : IPeerServiceContract
183     {
184     }
185 
186     static class PeerConnectorHelper
187     {
IsDefined(DisconnectReason value)188         public static bool IsDefined(DisconnectReason value)
189         {
190             return ((value == DisconnectReason.LeavingMesh) ||
191                     (value == DisconnectReason.NotUsefulNeighbor) ||
192                     (value == DisconnectReason.DuplicateNeighbor) ||
193                     (value == DisconnectReason.DuplicateNodeId) ||
194                     (value == DisconnectReason.NodeBusy) ||
195                     (value == DisconnectReason.InternalFailure));
196         }
197 
IsDefined(RefuseReason value)198         public static bool IsDefined(RefuseReason value)
199         {
200             return ((value == RefuseReason.DuplicateNodeId) ||
201                     (value == RefuseReason.DuplicateNeighbor) ||
202                     (value == RefuseReason.NodeBusy));
203         }
204     }
205 
206     [DataContract(Name = "Referral", Namespace = PeerStrings.Namespace)]
207     class Referral
208     {
209         [DataMember(Name = "NodeId")]
210         ulong nodeId;               // Referral NodeId
211 
212         [DataMember(Name = "Address")]
213         PeerNodeAddress address;    // Referral address
214 
Referral(ulong nodeId, PeerNodeAddress address)215         public Referral(ulong nodeId, PeerNodeAddress address)
216         {
217             this.nodeId = nodeId;
218             this.address = address;
219         }
220 
221         public PeerNodeAddress Address
222         {
223             get { return this.address; }
224             set { this.address = value; }
225         }
226 
227         public ulong NodeId
228         {
229             get { return this.nodeId; }
230             set { this.nodeId = value; }
231         }
232     }
233 
234     [MessageContract(IsWrapped = false)]
235     class RefuseInfo
236     {
237         [DataContract(Name = "RefuseInfo", Namespace = PeerStrings.Namespace)]
238         class RefuseInfoDC
239         {
240             [DataMember(Name = "Reason")]
241             public RefuseReason reason;
242 
243             [DataMember(Name = "Referrals")]
244             public Referral[] referrals;
245 
RefuseInfoDC()246             public RefuseInfoDC() { }
RefuseInfoDC(RefuseReason reason, Referral[] referrals)247             public RefuseInfoDC(RefuseReason reason, Referral[] referrals)
248             {
249                 this.reason = reason;
250                 this.referrals = referrals;
251             }
252         }
253 
RefuseInfo()254         public RefuseInfo()
255         {
256             this.body = new RefuseInfoDC();
257         }
258 
RefuseInfo(RefuseReason reason, Referral[] referrals)259         public RefuseInfo(RefuseReason reason, Referral[] referrals)
260         {
261             this.body = new RefuseInfoDC(reason, referrals);
262         }
263 
264         [MessageBodyMember(Name = "Refuse", Namespace = PeerStrings.Namespace)]
265         RefuseInfoDC body;
266 
267         public RefuseReason Reason
268         {
269             get { return this.body.reason; }
270         }
271 
272         public IList<Referral> Referrals
273         {
274             get { return this.body.referrals != null ? Array.AsReadOnly<Referral>(this.body.referrals) : null; }
275         }
276 
HasBody()277         public bool HasBody()
278         {
279             return body != null;
280         }
281     }
282 
283     // Reasons for sending a Refuse message
284     enum RefuseReason
285     {
286         DuplicateNeighbor = PeerCloseReason.DuplicateNeighbor,
287         DuplicateNodeId = PeerCloseReason.DuplicateNodeId,
288         NodeBusy = PeerCloseReason.NodeBusy,
289     }
290 
291     [MessageContract(IsWrapped = false)]
292     class UtilityInfo
293     {
294         [DataContract(Name = "LinkUtilityInfo", Namespace = PeerStrings.Namespace)]
295         class UtilityInfoDC
296         {
297             [DataMember(Name = "Useful")]
298             public uint useful;
299 
300             [DataMember(Name = "Total")]
301             public uint total;
302 
UtilityInfoDC()303             public UtilityInfoDC() { }
304 
UtilityInfoDC(uint useful, uint total)305             public UtilityInfoDC(uint useful, uint total)
306             {
307                 this.useful = useful;
308                 this.total = total;
309             }
310         }
311 
UtilityInfo()312         public UtilityInfo()
313         {
314             this.body = new UtilityInfoDC();
315         }
316 
UtilityInfo(uint useful, uint total)317         public UtilityInfo(uint useful, uint total)
318         {
319             this.body = new UtilityInfoDC(useful, total);
320         }
321 
322         [MessageBodyMember(Name = "LinkUtility", Namespace = PeerStrings.Namespace)]
323         UtilityInfoDC body;
324 
325         public uint Useful
326         {
327             get { return body.useful; }
328         }
329 
330         public uint Total
331         {
332             get { return body.total; }
333         }
334 
HasBody()335         public bool HasBody()
336         {
337             return body != null;
338         }
339     }
340 
341     [MessageContract(IsWrapped = false)]
342     class WelcomeInfo
343     {
344         [DataContract(Name = "WelcomeInfo", Namespace = PeerStrings.Namespace)]
345         class WelcomeInfoDC
346         {
347             [DataMember(Name = "NodeId")]
348             public ulong nodeId;
349 
350             [DataMember(Name = "Referrals")]
351             public Referral[] referrals;
352 
WelcomeInfoDC()353             public WelcomeInfoDC() { }
WelcomeInfoDC(ulong nodeId, Referral[] referrals)354             public WelcomeInfoDC(ulong nodeId, Referral[] referrals)
355             {
356                 this.nodeId = nodeId;
357                 this.referrals = referrals;
358             }
359         }
360 
WelcomeInfo()361         public WelcomeInfo()
362         {
363             this.body = new WelcomeInfoDC();
364         }
WelcomeInfo(ulong nodeId, Referral[] referrals)365         public WelcomeInfo(ulong nodeId, Referral[] referrals)
366         {
367             this.body = new WelcomeInfoDC(nodeId, referrals);
368         }
369 
370         [MessageBodyMember(Name = "Welcome", Namespace = PeerStrings.Namespace)]
371         WelcomeInfoDC body;
372 
373         public ulong NodeId
374         {
375             get { return this.body.nodeId; }
376         }
377 
378         public IList<Referral> Referrals
379         {
380             get { return this.body.referrals != null ? Array.AsReadOnly<Referral>(this.body.referrals) : null; }
381         }
382 
HasBody()383         public bool HasBody()
384         {
385             return body != null;
386         }
387     }
388 }
389 
390