1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright (c) 2003-2012 by AG-Software 											 *
3  * All Rights Reserved.																 *
4  * Contact information for AG-Software is available at http://www.ag-software.de	 *
5  *																					 *
6  * Licence:																			 *
7  * The agsXMPP SDK is released under a dual licence									 *
8  * agsXMPP can be used under either of two licences									 *
9  * 																					 *
10  * A commercial licence which is probably the most appropriate for commercial 		 *
11  * corporate use and closed source projects. 										 *
12  *																					 *
13  * The GNU Public License (GPL) is probably most appropriate for inclusion in		 *
14  * other open source projects.														 *
15  *																					 *
16  * See README.html for details.														 *
17  *																					 *
18  * For general enquiries visit our website at:										 *
19  * http://www.ag-software.de														 *
20  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21 
22 using System;
23 using System.Collections;
24 using System.Threading;
25 
26 using agsXMPP.protocol.client;
27 
28 //using agsXMPP.protocol.component;
29 
30 using agsXMPP.Xml;
31 
32 namespace agsXMPP
33 {
34 	public class IqGrabber : PacketGrabber
35 	{
36 		/// <summary>
37 		///
38 		/// </summary>
39 		/// <param name="conn"></param>
IqGrabber(XmppClientConnection conn)40 		public IqGrabber(XmppClientConnection conn)
41 		{
42             m_connection = conn;
43             conn.OnIq += OnIq;
44 		}
45 
IqGrabber(XmppComponentConnection conn)46         public IqGrabber(XmppComponentConnection conn)
47         {
48             m_connection = conn;
49             conn.OnIq += OnIq;
50         }
51 
52 #if !CF
53         private IQ  synchronousResponse     = null;
54 
55         private int m_SynchronousTimeout    = 5000;
56 
57         /// <summary>
58         /// Timeout for synchronous requests, default value is 5000 (5 seconds)
59         /// </summary>
60         public int SynchronousTimeout
61         {
62             get { return m_SynchronousTimeout; }
63             set { m_SynchronousTimeout = value; }
64         }
65 #endif
66 
67 		/// <summary>
68 		/// An IQ Element is received. Now check if its one we are looking for and
69 		/// raise the event in this case.
70 		/// </summary>
71 		/// <param name="sender"></param>
72 		/// <param name="e"></param>
OnIq(object sender, IQEventArgs e)73 		public void OnIq(object sender, IQEventArgs e)
74 		{
75             // the tracker handles on iq responses, which are either result or error
76             if (e.IQ.Type != IqType.error && e.IQ.Type != IqType.result)
77                 return;
78 
79             string id = e.IQ.Id;
80 			if(id == null)
81 				return;
82 
83             IqHandler td;
84 
85 			lock (m_grabbing)
86 			{
87 				td = (IqHandler) m_grabbing[id];
88 
89 				if (td == null)
90 				{
91 					return;
92 				}
93 				m_grabbing.Remove(id);
94 			}
95 
96             td(this, e);
97 		}
98 
99         /// <summary>
100         /// Send an IQ Request and store the object with callback in the Hashtable
101         /// </summary>
102         /// <param name="iq">The iq to send</param>
103         /// <param name="cb">the callback function which gets raised for the response</param>
SendIq(IQ iq, IqHandler cb)104         public void SendIq(IQ iq, IqHandler cb)
105         {
106             // check if the callback is null, in case of wrong usage of this class
107             if (cb == null) {
108                 throw new ArgumentNullException("cb");
109             }
110 
111             if (iq == null) {
112                 throw new ArgumentNullException("cb");
113             }
114 
115             m_grabbing[iq.Id] = cb;
116 
117 			m_connection.Send(iq);
118 		}
119 
120 #if !CF
121         /// <summary>
122         /// Sends an Iq synchronous and return the response or null on timeout
123         /// </summary>
124         /// <param name="iq">The IQ to send</param>
125         /// <param name="timeout"></param>
126         /// <returns>The response IQ or null on timeout</returns>
SendIq(agsXMPP.protocol.client.IQ iq, int timeout)127         public IQ SendIq(agsXMPP.protocol.client.IQ iq, int timeout)
128         {
129             synchronousResponse = null;
130             AutoResetEvent are = new AutoResetEvent(false);
131 
132             SendIq(iq,
133                    delegate (object sender, IQEventArgs e)
134                     {
135                         e.Handled = true;
136                         are.Set();
137                     }
138             );
139 
140             if (!are.WaitOne(timeout, true))
141             {
142                 // Timed out
143                 lock (m_grabbing)
144                 {
145                     if (m_grabbing.ContainsKey(iq.Id))
146                         m_grabbing.Remove(iq.Id);
147                 }
148                 return null;
149             }
150 
151             return synchronousResponse;
152 		}
153 
154         /// <summary>
155         /// Sends an Iq synchronous and return the response or null on timeout.
156         /// Timeout time used is <see cref="SynchronousTimeout"/>
157         /// </summary>
158         /// <param name="iq">The IQ to send</param>
159         /// <returns>The response IQ or null on timeout</returns>
SendIq(IQ iq)160         public IQ SendIq(IQ iq)
161         {
162             return SendIq(iq, m_SynchronousTimeout);
163         }
164 
165 #endif
166 	}
167 }