PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/External/Quickblox.framework/Versions/A/Headers/Core/External/XMPP/Core/QBXMPPStream.h

https://gitlab.com/intelij/ChattAR-ios
C Header | 834 lines | 175 code | 99 blank | 560 comment | 0 complexity | d416416b67da64488b49363cd75f4303 MD5 | raw file
  1. #import <Foundation/Foundation.h>
  2. #import "QBGCDAsyncSocket.h"
  3. #import "QBGCDMulticastDelegate.h"
  4. #if TARGET_OS_IPHONE
  5. #import "QBDDXML.h"
  6. #endif
  7. @class QBXMPPSRVResolver;
  8. @class QBDDList;
  9. @class QBXMPPParser;
  10. @class QBXMPPJID;
  11. @class QBXMPPIQ;
  12. @class QBXMPPMessage;
  13. @class QBXMPPPresence;
  14. @class QBXMPPModule;
  15. @class QBXMPPElementReceipt;
  16. @protocol QBXMPPStreamDelegate;
  17. #if TARGET_OS_IPHONE
  18. #define MIN_KEEPALIVE_INTERVAL 20.0 // 20 Seconds
  19. #define DEFAULT_KEEPALIVE_INTERVAL 120.0 // 2 Minutes
  20. #else
  21. #define MIN_KEEPALIVE_INTERVAL 10.0 // 10 Seconds
  22. #define DEFAULT_KEEPALIVE_INTERVAL 300.0 // 5 Minutes
  23. #endif
  24. extern NSString *const QBXMPPStreamErrorDomain;
  25. enum QBXMPPStreamErrorCode
  26. {
  27. XMPPStreamInvalidType, // Attempting to access P2P methods in a non-P2P stream, or vice-versa
  28. XMPPStreamInvalidState, // Invalid state for requested action, such as connect when already connected
  29. XMPPStreamInvalidProperty, // Missing a required property, such as hostName or myJID
  30. XMPPStreamInvalidParameter, // Invalid parameter, such as a nil JID
  31. XMPPStreamUnsupportedAction, // The server doesn't support the requested action
  32. };
  33. typedef enum QBXMPPStreamErrorCode XMPPStreamErrorCode;
  34. @interface QBXMPPStream : NSObject <QBGCDAsyncSocketDelegate>
  35. {
  36. dispatch_queue_t xmppQueue;
  37. dispatch_queue_t parserQueue;
  38. QBGCDMulticastDelegate <QBXMPPStreamDelegate> *multicastDelegate;
  39. int state;
  40. QBGCDAsyncSocket *asyncSocket;
  41. NSMutableData *socketBuffer;
  42. UInt64 numberOfBytesSent;
  43. UInt64 numberOfBytesReceived;
  44. QBXMPPParser *parser;
  45. NSError *parserError;
  46. Byte flags;
  47. Byte config;
  48. NSString *hostName;
  49. UInt16 hostPort;
  50. NSString *tempPassword;
  51. BOOL isAccessToken;
  52. NSString *appId;
  53. QBXMPPJID *myJID;
  54. QBXMPPJID *remoteJID;
  55. QBXMPPPresence *myPresence;
  56. NSXMLElement *rootElement;
  57. NSTimeInterval keepAliveInterval;
  58. dispatch_source_t keepAliveTimer;
  59. NSTimeInterval lastSendReceiveTime;
  60. QBDDList *registeredModules;
  61. NSMutableDictionary *autoDelegateDict;
  62. QBXMPPSRVResolver *srvResolver;
  63. NSArray *srvResults;
  64. NSUInteger srvResultsIndex;
  65. NSMutableArray *receipts;
  66. NSThread *xmppUtilityThread;
  67. NSRunLoop *xmppUtilityRunLoop;
  68. id userTag;
  69. }
  70. /**
  71. * Standard XMPP initialization.
  72. * The stream is a standard client to server connection.
  73. *
  74. * P2P streams using XEP-0174 are also supported.
  75. * See the P2P section below.
  76. **/
  77. - (id)init;
  78. /**
  79. * Peer to Peer XMPP initialization.
  80. * The stream is a direct client to client connection as outlined in XEP-0174.
  81. **/
  82. - (id)initP2PFrom:(QBXMPPJID *)myJID;
  83. /**
  84. * Facebook Chat X-FACEBOOK-PLATFORM SASL authentication initialization.
  85. * This is a convienence init method to help configure Facebook Chat.
  86. **/
  87. - (id)initWithFacebookAppId:(NSString *)fbAppId;
  88. /**
  89. * XMPPStream uses a multicast delegate.
  90. * This allows one to add multiple delegates to a single XMPPStream instance,
  91. * which makes it easier to separate various components and extensions.
  92. *
  93. * For example, if you were implementing two different custom extensions on top of XMPP,
  94. * you could put them in separate classes, and simply add each as a delegate.
  95. **/
  96. - (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
  97. - (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
  98. - (void)removeDelegate:(id)delegate;
  99. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  100. #pragma mark Properties
  101. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  102. /**
  103. * The appId can be passed to custom authentication classes.
  104. * For example, the appId is used for Facebook Chat X-FACEBOOK-PLATFORM SASL authentication.
  105. **/
  106. @property (readwrite,copy) NSString *appId;
  107. /**
  108. * The server's hostname that should be used to make the TCP connection.
  109. * This may be a domain name (e.g. "deusty.com") or an IP address (e.g. "70.85.193.226").
  110. *
  111. * Note that this may be different from the virtual xmpp hostname.
  112. * Just as HTTP servers can support mulitple virtual hosts from a single server, so too can xmpp servers.
  113. * A prime example is google via google apps.
  114. *
  115. * For example, say you own the domain "mydomain.com".
  116. * If you go to mydomain.com in a web browser,
  117. * you are directed to your apache server running on your webserver somewhere in the cloud.
  118. * But you use google apps for your email and xmpp needs.
  119. * So if somebody sends you an email, it actually goes to google's servers, where you later access it from.
  120. * Similarly, you connect to google's servers to sign into xmpp.
  121. *
  122. * In the example above, your hostname is "talk.google.com" and your JID is "me@mydomain.com".
  123. *
  124. * This hostName property is optional.
  125. * If you do not set the hostName, then the framework will follow the xmpp specification using jid's domain.
  126. * That is, it first do an SRV lookup (as specified in the xmpp RFC).
  127. * If that fails, it will fall back to simply attempting to connect to the jid's domain.
  128. **/
  129. @property (readwrite, copy) NSString *hostName;
  130. /**
  131. * The port the xmpp server is running on.
  132. * If you do not explicitly set the port, the default port will be used.
  133. * If you set the port to zero, the default port will be used.
  134. *
  135. * The default port is 5222.
  136. **/
  137. @property (readwrite, assign) UInt16 hostPort;
  138. /**
  139. * The JID of the user.
  140. *
  141. * This value is required, and is used in many parts of the underlying implementation.
  142. * When connecting, the domain of the JID is used to properly specify the correct xmpp virtual host.
  143. * It is used during registration to supply the username of the user to create an account for.
  144. * It is used during authentication to supply the username of the user to authenticate with.
  145. * And the resource may be used post-authentication during the required xmpp resource binding step.
  146. *
  147. * A proper JID is of the form user@domain/resource.
  148. * For example: robbiehanson@deusty.com/work
  149. *
  150. * The resource is optional, in the sense that if one is not supplied,
  151. * one will be automatically generated for you (either by us or by the server).
  152. *
  153. * Please note:
  154. * Resource collisions are handled in different ways depending on server configuration.
  155. *
  156. * For example:
  157. * You are signed in with user1@domain.com/home on your desktop.
  158. * Then you attempt to sign in with user1@domain.com/home on your laptop.
  159. *
  160. * The server could possibly:
  161. * - Reject the resource request for the laptop.
  162. * - Accept the resource request for the laptop, and immediately disconnect the desktop.
  163. * - Automatically assign the laptop another resource without a conflict.
  164. *
  165. * For this reason, you may wish to check the myJID variable after the stream has been connected,
  166. * just in case the resource was changed by the server.
  167. **/
  168. @property (readwrite, copy) QBXMPPJID *myJID;
  169. /**
  170. * Only used in P2P streams.
  171. **/
  172. @property (readonly) QBXMPPJID *remoteJID;
  173. /**
  174. * Many routers will teardown a socket mapping if there is no activity on the socket.
  175. * For this reason, the xmpp stream supports sending keep-alive data.
  176. * This is simply whitespace, which is ignored by the xmpp protocol.
  177. *
  178. * Keep-alive data is only sent in the absence of any other data being sent/received.
  179. *
  180. * The default value is defined in DEFAULT_KEEPALIVE_INTERVAL.
  181. * The minimum value is defined in MIN_KEEPALIVE_INTERVAL.
  182. *
  183. * To disable keep-alive, set the interval to zero.
  184. *
  185. * The keep-alive timer (if enabled) fires every (keepAliveInterval / 4) seconds.
  186. * Upon firing it checks when data was last sent/received,
  187. * and sends keep-alive data if the elapsed time has exceeded the keepAliveInterval.
  188. * Thus the effective resolution of the keepalive timer is based on the interval.
  189. **/
  190. @property (readwrite, assign) NSTimeInterval keepAliveInterval;
  191. /**
  192. * Represents the last sent presence element concerning the presence of myJID on the server.
  193. * In other words, it represents the presence as others see us.
  194. *
  195. * This excludes presence elements sent concerning subscriptions, MUC rooms, etc.
  196. **/
  197. @property (readonly) QBXMPPPresence *myPresence;
  198. /**
  199. * Returns the total number of bytes bytes sent/received by the xmpp stream.
  200. *
  201. * By default this is the byte count since the xmpp stream object has been created.
  202. * If the stream has connected/disconnected/reconnected multiple times,
  203. * the count will be the summation of all connections.
  204. *
  205. * The functionality may optionaly be changed to count only the current socket connection.
  206. * See the resetByteCountPerConnection property.
  207. **/
  208. @property (readonly) UInt64 numberOfBytesSent;
  209. @property (readonly) UInt64 numberOfBytesReceived;
  210. /**
  211. * Affects the funtionality of the byte counter.
  212. *
  213. * The default value is NO.
  214. *
  215. * If set to YES, the byte count will be reset just prior to a new connection (in the connect methods).
  216. **/
  217. @property (readwrite, assign) BOOL resetByteCountPerConnection;
  218. /**
  219. * The tag property allows you to associate user defined information with the stream.
  220. * Tag values are not used internally, and should not be used by xmpp modules.
  221. **/
  222. @property (readwrite, retain) id tag;
  223. #if TARGET_OS_IPHONE
  224. /**
  225. * If set, the kCFStreamNetworkServiceTypeVoIP flags will be set on the underlying CFRead/Write streams.
  226. *
  227. * The default value is NO.
  228. **/
  229. @property (readwrite, assign) BOOL enableBackgroundingOnSocket;
  230. #endif
  231. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  232. #pragma mark State
  233. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  234. /**
  235. * Returns YES if the connection is closed, and thus no stream is open.
  236. * If the stream is neither disconnected, nor connected, then a connection is currently being established.
  237. **/
  238. - (BOOL)isDisconnected;
  239. /**
  240. * Returns YES if the connection is open, and the stream has been properly established.
  241. * If the stream is neither disconnected, nor connected, then a connection is currently being established.
  242. *
  243. * If this method returns YES, then it is ready for you to start sending and receiving elements.
  244. **/
  245. - (BOOL)isConnected;
  246. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  247. #pragma mark Connect & Disconnect
  248. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  249. /**
  250. * Connects to the configured hostName on the configured hostPort.
  251. * If the hostName or myJID are not set, this method will return NO and set the error parameter.
  252. **/
  253. - (BOOL)connect:(NSError **)errPtr;
  254. /**
  255. * THIS IS DEPRECATED BY THE XMPP SPECIFICATION.
  256. *
  257. * The xmpp specification outlines the proper use of SSL/TLS by negotiating
  258. * the startTLS upgrade within the stream negotiation.
  259. * This method exists for those ancient servers that still require the connection to be secured prematurely.
  260. *
  261. * Note: Such servers generally use port 5223 for this, which you will need to set.
  262. **/
  263. - (BOOL)oldSchoolSecureConnect:(NSError **)errPtr;
  264. /**
  265. * Starts a P2P connection to the given user and given address.
  266. * This method only works with XMPPStream objects created using the initP2P method.
  267. *
  268. * The given address is specified as a sockaddr structure wrapped in a NSData object.
  269. * For example, a NSData object returned from NSNetservice's addresses method.
  270. **/
  271. - (BOOL)connectTo:(QBXMPPJID *)remoteJID withAddress:(NSData *)remoteAddr error:(NSError **)errPtr;
  272. /**
  273. * Starts a P2P connection with the given accepted socket.
  274. * This method only works with XMPPStream objects created using the initP2P method.
  275. *
  276. * The given socket should be a socket that has already been accepted.
  277. * The remoteJID will be extracted from the opening stream negotiation.
  278. **/
  279. - (BOOL)connectP2PWithSocket:(QBGCDAsyncSocket *)acceptedSocket error:(NSError **)errPtr;
  280. /**
  281. * Disconnects from the remote host by closing the underlying TCP socket connection.
  282. *
  283. * The disconnect method is synchronous.
  284. * Meaning that the disconnect will happen immediately, even if there are pending elements yet to be sent.
  285. * The xmppStreamDidDisconnect:withError: method will be invoked before the disconnect method returns.
  286. *
  287. * The disconnectAfterSending method is asynchronous.
  288. * The disconnect will happen after all pending elements have been sent.
  289. * Attempting to send elements after this method is called will not result in the elements getting sent.
  290. * The disconnectAfterSending method will return immediately,
  291. * and the xmppStreamDidDisconnect:withError: delegate method will be invoked at a later time.
  292. **/
  293. - (void)disconnect;
  294. - (void)disconnectAfterSending;
  295. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  296. #pragma mark Security
  297. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  298. /**
  299. * Returns YES if SSL/TLS was used to establish a connection to the server.
  300. *
  301. * Some servers may require an "upgrade to TLS" in order to start communication,
  302. * so even if the connection was not explicitly secured, an ugrade to TLS may have occured.
  303. *
  304. * See also the xmppStream:willSecureWithSettings: delegate method.
  305. **/
  306. - (BOOL)isSecure;
  307. /**
  308. * Returns whether or not the server supports securing the connection via SSL/TLS.
  309. *
  310. * Some servers will actually require a secure connection,
  311. * in which case the stream will attempt to secure the connection during the opening process.
  312. *
  313. * If the connection has already been secured, this method may return NO.
  314. **/
  315. - (BOOL)supportsStartTLS;
  316. /**
  317. * Attempts to secure the connection via SSL/TLS.
  318. *
  319. * This method is asynchronous.
  320. * The SSL/TLS handshake will occur in the background, and
  321. * the xmppStreamDidSecure: delegate method will be called after the TLS process has completed.
  322. *
  323. * This method returns immediately.
  324. * If the secure process was started, it will return YES.
  325. * If there was an issue while starting the security process,
  326. * this method will return NO and set the error parameter.
  327. *
  328. * The errPtr parameter is optional - you may pass nil.
  329. *
  330. * You may wish to configure the security settings via the xmppStream:willSecureWithSettings: delegate method.
  331. *
  332. * If the SSL/TLS handshake fails, the connection will be closed.
  333. * The reason for the error will be reported via the xmppStreamDidDisconnect:withError: delegate method.
  334. * The error parameter will be an NSError object, and may have an error domain of kCFStreamErrorDomainSSL.
  335. * The corresponding error code is documented in Apple's Security framework, in SecureTransport.h
  336. **/
  337. - (BOOL)secureConnection:(NSError **)errPtr;
  338. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  339. #pragma mark Registration
  340. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  341. /**
  342. * In Band Registration.
  343. * Creating a user account on the xmpp server within the xmpp protocol.
  344. *
  345. * The registerWithPassword:error: method is asynchronous.
  346. * It will return immediately, and the delegate methods are used to determine success.
  347. * See the xmppStreamDidRegister: and xmppStream:didNotRegister: methods.
  348. *
  349. * If there is something immediately wrong, such as the stream is not connected,
  350. * this method will return NO and set the error.
  351. *
  352. * The errPtr parameter is optional - you may pass nil.
  353. *
  354. * Security Note:
  355. * The password will be sent in the clear unless the stream has been secured.
  356. **/
  357. - (BOOL)supportsInBandRegistration;
  358. - (BOOL)registerWithPassword:(NSString *)password error:(NSError **)errPtr;
  359. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  360. #pragma mark Authentication
  361. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  362. /**
  363. * Authentication.
  364. *
  365. * The authenticateWithPassword:error: and authenticateWithFacebookAccessToken:error: methods are asynchronous.
  366. * Each will return immediately, and the delegate methods are used to determine success.
  367. * See the xmppStreamDidAuthenticate: and xmppStream:didNotAuthenticate: methods.
  368. *
  369. * If there is something immediately wrong, such as the stream is not connected,
  370. * the method will return NO and set the error.
  371. *
  372. * The errPtr parameter is optional - you may pass nil.
  373. *
  374. * The authenticateWithPassword:error: method will choose the most secure protocol to send the password.
  375. *
  376. * Security Note:
  377. * Care should be taken if sending passwords in the clear is not acceptable.
  378. * You may use the supportsXAuthentication methods below to determine
  379. * if an acceptable authentication protocol is supported.
  380. **/
  381. - (BOOL)isAuthenticated;
  382. - (BOOL)supportsAnonymousAuthentication;
  383. - (BOOL)supportsPlainAuthentication;
  384. - (BOOL)supportsDigestMD5Authentication;
  385. - (BOOL)supportsXFacebookPlatformAuthentication;
  386. - (BOOL)supportsDeprecatedPlainAuthentication;
  387. - (BOOL)supportsDeprecatedDigestAuthentication;
  388. - (BOOL)authenticateWithFacebookAccessToken:(NSString *)accessToken error:(NSError **)errPtr;
  389. - (BOOL)authenticateWithPassword:(NSString *)password error:(NSError **)errPtr;
  390. - (BOOL)authenticateAnonymously:(NSError **)errPtr;
  391. - (void)handleAuth1:(NSXMLElement *)response;
  392. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  393. #pragma mark Server Info
  394. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  395. /**
  396. * This method will return the root element of the document.
  397. * This element contains the opening <stream:stream/> and <stream:features/> tags received from the server.
  398. *
  399. * If multiple <stream:features/> have been received during the course of stream negotiation,
  400. * the root element contains only the most recent (current) version.
  401. *
  402. * Note: The rootElement is "empty", in so much as it does not contain all the XML elements the stream has
  403. * received during it's connection. This is done for performance reasons and for the obvious benefit
  404. * of being more memory efficient.
  405. **/
  406. - (NSXMLElement *)rootElement;
  407. /**
  408. * Returns the version attribute from the servers's <stream:stream/> element.
  409. * This should be at least 1.0 to be RFC 3920 compliant.
  410. * If no version number was set, the server is not RFC compliant, and 0 is returned.
  411. **/
  412. - (float)serverXmppStreamVersionNumber;
  413. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  414. #pragma mark Sending
  415. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  416. /**
  417. * Sends the given XML element.
  418. * If the stream is not yet connected, this method does nothing.
  419. **/
  420. - (void)sendElement:(NSXMLElement *)element;
  421. /**
  422. * Just like the sendElement: method above,
  423. * but allows you to receive a receipt that can later be used to verify the element has been sent.
  424. *
  425. * If you later want to check to see if the element has been sent:
  426. *
  427. * if ([receipt wait:0]) {
  428. * // Element has been sent
  429. * }
  430. *
  431. * If you later want to wait until the element has been sent:
  432. *
  433. * if ([receipt wait:-1]) {
  434. * // Element was sent
  435. * } else {
  436. * // Element failed to send due to disconnection
  437. * }
  438. *
  439. * It is important to understand what it means when [receipt wait:timeout] returns YES.
  440. * It does NOT mean the server has received the element.
  441. * It only means the data has been queued for sending in the underlying OS socket buffer.
  442. *
  443. * So at this point the OS will do everything in its capacity to send the data to the server,
  444. * which generally means the server will eventually receive the data.
  445. * Unless, of course, something horrible happens such as a network failure,
  446. * or a system crash, or the server crashes, etc.
  447. *
  448. * Even if you close the xmpp stream after this point, the OS will still do everything it can to send the data.
  449. **/
  450. - (void)sendElement:(NSXMLElement *)element andGetReceipt:(QBXMPPElementReceipt **)receiptPtr;
  451. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  452. #pragma mark Module Plug-In System
  453. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  454. /**
  455. * The XMPPModule class automatically invokes these methods when it is activated/deactivated.
  456. *
  457. * The registerModule method registers the module with the xmppStream.
  458. * If there are any other modules that have requested to be automatically added as delegates to modules of this type,
  459. * then those modules are automatically added as delegates during the asynchronous execution of this method.
  460. *
  461. * The registerModule method is asynchronous.
  462. *
  463. * The unregisterModule method unregisters the module with the xmppStream,
  464. * and automatically removes it as a delegate of any other module.
  465. *
  466. * The unregisterModule method is fully synchronous.
  467. * That is, after this method returns, the module will not be scheduled in any more delegate calls from other modules.
  468. * However, if the module was already scheduled in an existing asynchronous delegate call from another module,
  469. * the scheduled delegate invocation remains queued and will fire in the near future.
  470. * Since the delegate invocation is already queued,
  471. * the module's retainCount has been incremented,
  472. * and the module will not be deallocated until after the delegate invocation has fired.
  473. **/
  474. - (void)registerModule:(QBXMPPModule *)module;
  475. - (void)unregisterModule:(QBXMPPModule *)module;
  476. /**
  477. * Automatically registers the given delegate with all current and future registered modules of the given class.
  478. *
  479. * That is, the given delegate will be added to the delegate list ([module addDelegate:delegate delegateQueue:dq]) to
  480. * all current and future registered modules that respond YES to [module isKindOfClass:aClass].
  481. *
  482. * This method is used by modules to automatically integrate with other modules.
  483. * For example, a module may auto-add itself as a delegate to XMPPCapabilities
  484. * so that it can broadcast its implemented features.
  485. *
  486. * This may also be useful to clients, for example, to add a delegate to instances of something like XMPPChatRoom,
  487. * where there may be multiple instances of the module that get created during the course of an xmpp session.
  488. *
  489. * If you auto register on multiple queues, you can remove all registrations with a single
  490. * call to removeAutoDelegate::: by passing NULL as the 'dq' parameter.
  491. *
  492. * If you auto register for multiple classes, you can remove all registrations with a single
  493. * call to removeAutoDelegate::: by passing nil as the 'aClass' parameter.
  494. **/
  495. - (void)autoAddDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue toModulesOfClass:(Class)aClass;
  496. - (void)removeAutoDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue fromModulesOfClass:(Class)aClass;
  497. /**
  498. * Allows for enumeration of the currently registered modules.
  499. *
  500. * This may be useful if the stream needs to be queried for modules of a particular type.
  501. **/
  502. - (void)enumerateModulesWithBlock:(void (^)(QBXMPPModule *module, NSUInteger idx, BOOL *stop))block;
  503. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  504. #pragma mark Utilities
  505. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  506. /**
  507. * Generates and returns a new autoreleased UUID.
  508. * UUIDs (Universally Unique Identifiers) may also be known as GUIDs (Globally Unique Identifiers).
  509. *
  510. * The UUID is generated using the CFUUID library, which generates a unique 128 bit value.
  511. * The uuid is then translated into a string using the standard format for UUIDs:
  512. * "68753A44-4D6F-1226-9C60-0050E4C00067"
  513. *
  514. * This method is most commonly used to generate a unique id value for an xmpp element.
  515. **/
  516. + (NSString *)generateUUID;
  517. - (NSString *)generateUUID;
  518. /**
  519. * The XMPP Framework is designed to be entirely GCD based.
  520. * However, there are various utility classes provided by Apple that are still dependent upon a thread/runloop model.
  521. * For example, monitoring a network for changes related to connectivity requires we register a runloop-based delegate.
  522. * Thus XMPPStream creates a dedicated thread/runloop for any xmpp classes that may need it.
  523. * This provides multiple benefits:
  524. *
  525. * - Development is simplified for those transitioning from previous thread/runloop versions.
  526. * - Development is simplified for those who rely on utility classes that don't yet support pure GCD,
  527. * as they don't have to setup and maintain a thread/runloop on their own.
  528. * - It prevents multiple xmpp classes from creating multiple internal threads (which would be resource costly).
  529. *
  530. * Please note:
  531. * This thread is designed to be used only if absolutely necessary.
  532. * That is, if you MUST use a class that doesn't yet support pure GCD.
  533. * If there is a GCD alternative, you should be using it instead.
  534. * For example, do NOT use NSTimer. Instead setup a GCD timer using a dispatch_source.
  535. **/
  536. - (NSThread *)xmppUtilityThread;
  537. - (NSRunLoop *)xmppUtilityRunLoop;
  538. @end
  539. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  540. #pragma mark -
  541. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  542. @interface QBXMPPElementReceipt : NSObject
  543. {
  544. uint32_t atomicFlags;
  545. dispatch_semaphore_t semaphore;
  546. }
  547. /**
  548. * Element receipts allow you to check to see if the element has been sent.
  549. * The timeout parameter allows you to do any of the following:
  550. *
  551. * - Do an instantaneous check (pass timeout == 0)
  552. * - Wait until the element has been sent (pass timeout < 0)
  553. * - Wait up to a certain amount of time (pass timeout > 0)
  554. *
  555. * It is important to understand what it means when [receipt wait:timeout] returns YES.
  556. * It does NOT mean the server has received the element.
  557. * It only means the data has been queued for sending in the underlying OS socket buffer.
  558. *
  559. * So at this point the OS will do everything in its capacity to send the data to the server,
  560. * which generally means the server will eventually receive the data.
  561. * Unless, of course, something horrible happens such as a network failure,
  562. * or a system crash, or the server crashes, etc.
  563. *
  564. * Even if you close the xmpp stream after this point, the OS will still do everything it can to send the data.
  565. **/
  566. - (BOOL)wait:(NSTimeInterval)timeout;
  567. @end
  568. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  569. #pragma mark -
  570. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  571. @protocol QBXMPPStreamDelegate
  572. @optional
  573. /**
  574. * This method is called before the stream begins the connection process.
  575. *
  576. * If developing an iOS app that runs in the background, this may be a good place to indicate
  577. * that this is a task that needs to continue running in the background.
  578. **/
  579. - (void)xmppStreamWillConnect:(QBXMPPStream *)sender;
  580. /**
  581. * This method is called after the tcp socket has connected to the remote host.
  582. * It may be used as a hook for various things, such as updating the UI or extracting the server's IP address.
  583. *
  584. * If developing an iOS app that runs in the background,
  585. * please use XMPPStream's enableBackgroundingOnSocket property as opposed to doing it directly on the socket here.
  586. **/
  587. - (void)xmppStream:(QBXMPPStream *)sender socketDidConnect:(QBGCDAsyncSocket *)socket;
  588. /**
  589. * This method is called after a TCP connection has been established with the server,
  590. * and the opening XML stream negotiation has started.
  591. **/
  592. - (void)xmppStreamDidStartNegotiation:(QBXMPPStream *)sender;
  593. /**
  594. * This method is called immediately prior to the stream being secured via TLS/SSL.
  595. * Note that this delegate may be called even if you do not explicitly invoke the startTLS method.
  596. * Servers have the option of requiring connections to be secured during the opening process.
  597. * If this is the case, the XMPPStream will automatically attempt to properly secure the connection.
  598. *
  599. * The possible keys and values for the security settings are well documented.
  600. * Some possible keys are:
  601. * - kCFStreamSSLLevel
  602. * - kCFStreamSSLAllowsExpiredCertificates
  603. * - kCFStreamSSLAllowsExpiredRoots
  604. * - kCFStreamSSLAllowsAnyRoot
  605. * - kCFStreamSSLValidatesCertificateChain
  606. * - kCFStreamSSLPeerName
  607. * - kCFStreamSSLCertificates
  608. *
  609. * Please refer to Apple's documentation for associated values, as well as other possible keys.
  610. *
  611. * The dictionary of settings is what will be passed to the startTLS method of ther underlying AsyncSocket.
  612. * The AsyncSocket header file also contains a discussion of the security consequences of various options.
  613. * It is recommended reading if you are planning on implementing this method.
  614. *
  615. * The dictionary of settings that are initially passed will be an empty dictionary.
  616. * If you choose not to implement this method, or simply do not edit the dictionary,
  617. * then the default settings will be used.
  618. * That is, the kCFStreamSSLPeerName will be set to the configured host name,
  619. * and the default security validation checks will be performed.
  620. *
  621. * This means that authentication will fail if the name on the X509 certificate of
  622. * the server does not match the value of the hostname for the xmpp stream.
  623. * It will also fail if the certificate is self-signed, or if it is expired, etc.
  624. *
  625. * These settings are most likely the right fit for most production environments,
  626. * but may need to be tweaked for development or testing,
  627. * where the development server may be using a self-signed certificate.
  628. **/
  629. - (void)xmppStream:(QBXMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings;
  630. /**
  631. * This method is called after the stream has been secured via SSL/TLS.
  632. * This method may be called if the server required a secure connection during the opening process,
  633. * or if the secureConnection: method was manually invoked.
  634. **/
  635. - (void)xmppStreamDidSecure:(QBXMPPStream *)sender;
  636. /**
  637. * This method is called after the XML stream has been fully opened.
  638. * More precisely, this method is called after an opening <xml/> and <stream:stream/> tag have been sent and received,
  639. * and after the stream features have been received, and any required features have been fullfilled.
  640. * At this point it's safe to begin communication with the server.
  641. **/
  642. - (void)xmppStreamDidConnect:(QBXMPPStream *)sender;
  643. /**
  644. * This method is called after registration of a new user has successfully finished.
  645. * If registration fails for some reason, the xmppStream:didNotRegister: method will be called instead.
  646. **/
  647. - (void)xmppStreamDidRegister:(QBXMPPStream *)sender;
  648. /**
  649. * This method is called if registration fails.
  650. **/
  651. - (void)xmppStream:(QBXMPPStream *)sender didNotRegister:(NSXMLElement *)error;
  652. /**
  653. * This method is called after authentication has successfully finished.
  654. * If authentication fails for some reason, the xmppStream:didNotAuthenticate: method will be called instead.
  655. **/
  656. - (void)xmppStreamDidAuthenticate:(QBXMPPStream *)sender;
  657. /**
  658. * This method is called if authentication fails.
  659. **/
  660. - (void)xmppStream:(QBXMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error;
  661. /**
  662. * These methods are called after their respective XML elements are received on the stream.
  663. *
  664. * In the case of an IQ, the delegate method should return YES if it has or will respond to the given IQ.
  665. * If the IQ is of type 'get' or 'set', and no delegates respond to the IQ,
  666. * then xmpp stream will automatically send an error response.
  667. **/
  668. - (BOOL)xmppStream:(QBXMPPStream *)sender didReceiveIQ:(QBXMPPIQ *)iq;
  669. - (void)xmppStream:(QBXMPPStream *)sender didReceiveMessage:(QBXMPPMessage *)message;
  670. - (void)xmppStream:(QBXMPPStream *)sender didReceivePresence:(QBXMPPPresence *)presence;
  671. /**
  672. * This method is called if an XMPP error is received.
  673. * In other words, a <stream:error/>.
  674. *
  675. * However, this method may also be called for any unrecognized xml stanzas.
  676. *
  677. * Note that standard errors (<iq type='error'/> for example) are delivered normally,
  678. * via the other didReceive...: methods.
  679. **/
  680. - (void)xmppStream:(QBXMPPStream *)sender didReceiveError:(NSXMLElement *)error;
  681. /**
  682. * These methods are called before their respective XML elements are sent over the stream.
  683. * These methods can be used to customize elements on the fly.
  684. * (E.g. add standard information for custom protocols.)
  685. **/
  686. - (void)xmppStream:(QBXMPPStream *)sender willSendIQ:(QBXMPPIQ *)iq;
  687. - (void)xmppStream:(QBXMPPStream *)sender willSendMessage:(QBXMPPMessage *)message;
  688. - (void)xmppStream:(QBXMPPStream *)sender willSendPresence:(QBXMPPPresence *)presence;
  689. /**
  690. * These methods are called after their respective XML elements are sent over the stream.
  691. * These methods may be used to listen for certain events (such as an unavailable presence having been sent),
  692. * or for general logging purposes. (E.g. a central history logging mechanism).
  693. **/
  694. - (void)xmppStream:(QBXMPPStream *)sender didSendIQ:(QBXMPPIQ *)iq;
  695. - (void)xmppStream:(QBXMPPStream *)sender didSendMessage:(QBXMPPMessage *)message;
  696. - (void)xmppStream:(QBXMPPStream *)sender didSendPresence:(QBXMPPPresence *)presence;
  697. /**
  698. * This method is called if the disconnect method is called.
  699. * It may be used to determine if a disconnection was purposeful, or due to an error.
  700. **/
  701. - (void)xmppStreamWasToldToDisconnect:(QBXMPPStream *)sender;
  702. /**
  703. * This method is called after the stream is closed.
  704. *
  705. * The given error parameter will be non-nil if the error was due to something outside the general xmpp realm.
  706. * Some examples:
  707. * - The TCP socket was unexpectedly disconnected.
  708. * - The SRV resolution of the domain failed.
  709. * - Error parsing xml sent from server.
  710. **/
  711. - (void)xmppStreamDidDisconnect:(QBXMPPStream *)sender withError:(NSError *)error;
  712. /**
  713. * This method is only used in P2P mode when the connectTo:withAddress: method was used.
  714. *
  715. * It allows the delegate to read the <stream:features/> element if/when they arrive.
  716. * Recall that the XEP specifies that <stream:features/> SHOULD be sent.
  717. **/
  718. - (void)xmppStream:(QBXMPPStream *)sender didReceiveP2PFeatures:(NSXMLElement *)streamFeatures;
  719. /**
  720. * This method is only used in P2P mode when the connectTo:withSocket: method was used.
  721. *
  722. * It allows the delegate to customize the <stream:features/> element,
  723. * adding any specific featues the delegate might support.
  724. **/
  725. - (void)xmppStream:(QBXMPPStream *)sender willSendP2PFeatures:(NSXMLElement *)streamFeatures;
  726. /**
  727. * These methods are called as xmpp modules are registered and unregistered with the stream.
  728. * This generally corresponds to xmpp modules being initailzed and deallocated.
  729. *
  730. * The methods may be useful, for example, if a more precise auto delegation mechanism is needed
  731. * than what is available with the autoAddDelegate:toModulesOfClass: method.
  732. **/
  733. - (void)xmppStream:(QBXMPPStream *)sender didRegisterModule:(id)module;
  734. - (void)xmppStream:(QBXMPPStream *)sender willUnregisterModule:(id)module;
  735. @end