23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
+
+
-
-
+
+
-
-
-
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
*/
#import <ObjFW/ObjFW.h>
#import "XMPPCallback.h"
#import "XMPPStorage.h"
OF_ASSUME_NONNULL_BEGIN
@class XMPPConnection;
@class XMPPJID;
@class XMPPIQ;
@class XMPPMessage;
@class XMPPPresence;
@class XMPPAuthenticator;
@class SSLSocket;
@class XMPPMulticastDelegate;
/**
* \brief A protocol that should be (partially) implemented
* by delegates of a XMPPConnection
* \brief A protocol that should be (partially) implemented by delegates of a
* @ref XMPPConnection
*/
@protocol XMPPConnectionDelegate
#ifndef XMPP_CONNECTION_M
<OFObject>
#endif
@optional
/**
* \brief This callback is called when the connection received an element.
*
* \param connection The connection that received the element
* \param element The element that was received
*/
- (void)connection: (XMPPConnection*)connection
didReceiveElement: (OFXMLElement*)element;
- (void)connection: (XMPPConnection *)connection
didReceiveElement: (OFXMLElement *)element;
/**
* \brief This callback is called when the connection sent an element.
*
* \param connection The connection that sent the element
* \param element The element that was sent
*/
- (void)connection: (XMPPConnection*)connection
didSendElement: (OFXMLElement*)element;
- (void)connection: (XMPPConnection *)connection
didSendElement: (OFXMLElement *)element;
/**
* \brief This callback is called when the connection sucessfully authenticated.
*
* \param connection The connection that was authenticated
*/
- (void)connectionWasAuthenticated: (XMPPConnection*)connection;
- (void)connectionWasAuthenticated: (XMPPConnection *)connection;
/**
* \brief This callback is called when the connection was bound to a JID.
*
* \param connection The connection that was bound to a JID
* \param JID The JID the conecction was bound to
*/
- (void)connection: (XMPPConnection*)connection
wasBoundToJID: (XMPPJID*)JID;
- (void)connection: (XMPPConnection *)connection
wasBoundToJID: (XMPPJID *)JID;
/**
* \brief This callback is called when the connection received an IQ stanza.
*
* \param connection The connection that received the stanza
* \param iq The IQ stanza that was received
*/
- (bool)connection: (XMPPConnection*)connection
didReceiveIQ: (XMPPIQ*)iq;
- (bool)connection: (XMPPConnection *)connection
didReceiveIQ: (XMPPIQ *)iq;
/**
* \brief This callback is called when the connection received a presence
* stanza.
*
* \param connection The connection that received the stanza
* \param presence The presence stanza that was received
*/
- (void)connection: (XMPPConnection*)connection
didReceivePresence: (XMPPPresence*)presence;
- (void)connection: (XMPPConnection *)connection
didReceivePresence: (XMPPPresence *)presence;
/**
* \brief This callback is called when the connection received a message stanza.
*
* \param connection The connection that received the stanza
* \param message The message stanza that was received
*/
- (void)connection: (XMPPConnection*)connection
didReceiveMessage: (XMPPMessage*)message;
- (void)connection: (XMPPConnection *)connection
didReceiveMessage: (XMPPMessage *)message;
/**
* \brief This callback is called when the connection was closed.
*
* \param connection The connection that was closed
*/
- (void)connectionWasClosed: (XMPPConnection*)connection;
- (void)connectionWasClosed: (XMPPConnection *)connection;
/*!
* @brief This callback is called when the connection threw an exception.
*
* This is only called for connections on which
* @ref XMPPConnection::handleConnection has been called.
*
* @param connection The connection which threw an exception
* @param exception The exception the connection threw
*/
- (void)connection: (XMPPConnection*)connection
didThrowException: (OFException*)exception;
- (void)connection: (XMPPConnection *)connection
didThrowException: (OFException *)exception;
/**
* \brief This callback is called when the connection is about to upgrade to
* TLS.
*
* \param connection The connection that will upgraded to TLS
*/
- (void)connectionWillUpgradeToTLS: (XMPPConnection*)connection;
- (void)connectionWillUpgradeToTLS: (XMPPConnection *)connection;
/**
* \brief This callback is called when the connection was upgraded to use TLS.
*
* \param connection The connection that was upgraded to TLS
*/
- (void)connectionDidUpgradeToTLS: (XMPPConnection*)connection;
- (void)connectionDidUpgradeToTLS: (XMPPConnection *)connection;
@end
/**
* \brief A class which abstracts a connection to an XMPP service.
*/
@interface XMPPConnection: OFObject <OFXMLParserDelegate,
OFXMLElementBuilderDelegate>
{
id _socket;
OFXMLParser *_parser, *_oldParser;
OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder;
OFString *_username, *_password, *_server, *_resource;
OFString *_privateKeyFile, *_certificateFile;
const char *_privateKeyPassphrase;
OFString *_domain, *_domainToASCII;
XMPPJID *_JID;
uint16_t _port;
id <XMPPStorage> _dataStorage;
OFString *_language;
XMPPMulticastDelegate *_delegates;
OFMutableDictionary *_callbacks;
OFMutableDictionary OF_GENERIC(OFString *, XMPPCallback *) *_callbacks;
XMPPAuthenticator *_authModule;
bool _streamOpen;
bool _needsSession;
bool _encryptionRequired, _encrypted;
bool _supportsRosterVersioning;
bool _supportsStreamManagement;
unsigned int _lastID;
}
/// \brief The username to use for authentication
@property (copy) OFString *username;
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *username;
/// \brief The password to use for authentication
@property (copy) OFString *password;
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *password;
/**
* \brief The server to use for the connection
*
* This is useful if the address of the server is different from the domain.
*/
@property (copy) OFString *server;
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *server;
/// \brief The domain to connect to
@property (copy) OFString *domain;
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *domain;
/// \brief The resource to request for the connection
@property (copy) OFString *resource;
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *resource;
/// \brief The language to request for the connection
@property (copy) OFString *language;
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *language;
/// \brief A private key file to use for authentication
@property (copy) OFString *privateKeyFile;
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *privateKeyFile;
/// \brief A certificate file to use for authentication
@property (copy) OFString *certificateFile;
@property OF_NULLABLE_PROPERTY (nonatomic, copy) OFString *certificateFile;
/// \brief The JID the server assigned to the connection after binding
@property (copy, readonly) XMPPJID *JID;
@property (readonly, nonatomic) XMPPJID *JID;
/// \brief The port to connect to
@property uint16_t port;
/// \brief An object for data storage, conforming to the XMPPStorage protocol
@property (assign) id <XMPPStorage> dataStorage;
@property OF_NULLABLE_PROPERTY (assign) id <XMPPStorage> dataStorage;
/// \brief The socket used for the connection
@property (readonly, retain) OFTCPSocket *socket;
@property (readonly, nonatomic) OFTCPSocket *socket;
/// \brief Whether encryption is required
@property bool encryptionRequired;
/// \brief Whether the connection is encrypted
@property (readonly) bool encrypted;
/// \brief Whether roster versioning is supported
@property (readonly) bool supportsRosterVersioning;
/// \brief Whether stream management is supported
|
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
-
+
+
|
* pointer to the reason why the certificate is not valid
*
* \param reason A pointer to an OFString which is set to a reason in case the
* certificate is not valid (otherwise, it does not touch it).
* Passing NULL means the reason is not stored anywhere.
* \return Whether the certificate is valid
*/
- (bool)checkCertificateAndGetReason: (OFString**)reason;
- (bool)checkCertificateAndGetReason:
(OFString *__autoreleasing _Nonnull *_Nullable)reason;
/**
* \brief Adds the connection to the run loop.
*/
- (void)handleConnection;
/**
|
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
|
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
|
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
|
*
* This is useful for handling multiple connections at once.
*
* \param buffer The buffer to parse
* \param length The length of the buffer. If length is 0, it is assumed that
* the connection was closed.
*/
- (void)parseBuffer: (const void*)buffer
- (void)parseBuffer: (const void *)buffer
length: (size_t)length;
/**
* \brief Returns the socket used by the XMPPConnection.
*
* \return The socket used by the XMPPConnection
*/
- (OFTCPSocket*)socket;
/**
* \brief Returns whether encryption is encrypted.
*
* \return Whether encryption is encrypted
*/
- (bool)encryptionRequired;
/**
* \brief Sets whether encryption is required.
*
* \param required Whether encryption is required
*/
- (void)setEncryptionRequired: (bool)required;
/**
* \brief Returns whether the connection is encrypted.
*
* \return Whether the connection is encrypted
*/
- (bool)encrypted;
/**
* \brief Sends an OFXMLElement, usually an XMPPStanza.
*
* \param element The element to send
*/
- (void)sendStanza: (OFXMLElement*)element;
- (void)sendStanza: (OFXMLElement *)element;
/*!
* @brief Sends an XMPPIQ, registering a callback method.
*
* @param IQ The IQ to send
* @param target The object that contains the callback method
* @param selector The selector of the callback method,
* must take exactly one parameter of type XMPPIQ*
* must take exactly one parameter of type `XMPPIQ *`
*/
- (void)sendIQ: (XMPPIQ*)IQ
- (void)sendIQ: (XMPPIQ *)IQ
callbackTarget: (id)target
selector: (SEL)selector;
#ifdef OF_HAVE_BLOCKS
/*!
* @brief Sends an XMPPIQ, registering a callback block.
*
* @param IQ The IQ to send
* @param block The callback block
*/
- (void)sendIQ: (XMPPIQ*)IQ
- (void)sendIQ: (XMPPIQ *)IQ
callbackBlock: (xmpp_callback_block_t)block;
#endif
/**
* \brief Generates a new, unique stanza ID.
*
* \return A new, generated, unique stanza ID.
*/
- (OFString*)generateStanzaID;
- (OFString *)generateStanzaID;
- (void)setUsername: (OFString*)username;
- (OFString*)username;
- (void)setPassword: (OFString*)password;
- (OFString*)password;
- (void)setServer: (OFString*)server;
- (OFString*)server;
- (void)setDomain: (OFString*)domain;
- (OFString*)domain;
- (void)setResource: (OFString*)resource;
- (OFString*)resource;
- (XMPPJID*)JID;
- (void)setPort: (uint16_t)port;
- (uint16_t)port;
- (void)setDataStorage: (id <XMPPStorage>)dataStorage;
- (id <XMPPStorage>)dataStorage;
- (void)setLanguage: (OFString*)language;
- (OFString*)language;
- (bool)supportsRosterVersioning;
- (bool)supportsStreamManagement;
- (void)XMPP_startStream;
- (void)XMPP_handleStream: (OFXMLElement*)element;
- (void)XMPP_handleTLS: (OFXMLElement*)element;
- (void)XMPP_handleSASL: (OFXMLElement*)element;
- (void)XMPP_handleStanza: (OFXMLElement*)element;
- (void)XMPP_sendAuth: (OFString*)authName;
- (void)XMPP_sendResourceBind;
- (void)XMPP_sendStreamError: (OFString*)condition
text: (OFString*)text;
- (void)XMPP_handleIQ: (XMPPIQ*)iq;
- (void)XMPP_handleMessage: (XMPPMessage*)message;
- (void)XMPP_handlePresence: (XMPPPresence*)presence;
- (void)XMPP_handleFeatures: (OFXMLElement*)element;
- (void)XMPP_handleResourceBindForConnection: (XMPPConnection*)connection
IQ: (XMPPIQ*)iq;
- (void)XMPP_sendSession;
- (void)XMPP_handleSessionForConnection: (XMPPConnection*)connection
IQ: (XMPPIQ*)iq;
- (OFString*)XMPP_IDNAToASCII: (OFString*)domain;
- (XMPPMulticastDelegate*)XMPP_delegates;
@end
@interface OFObject (XMPPConnectionDelegate) <XMPPConnectionDelegate>
@end
OF_ASSUME_NONNULL_END
|