1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
/*
* Copyright (c) 2010, 2011, 2012, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
*
* https://webkeks.org/hg/objxmpp/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
|
︙ | | |
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
|
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
|
-
-
-
-
-
|
@class XMPPConnection;
@class XMPPJID;
@class XMPPIQ;
@class XMPPMessage;
@class XMPPPresence;
@class XMPPAuthenticator;
@class XMPPRoster;
@class XMPPRosterItem;
@class SSLSocket;
@class XMPPMulticastDelegate;
@protocol XMPPConnectionDelegate
#ifndef XMPP_CONNECTION_M
<OFObject>
#endif
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
@optional
#endif
- (void)connection: (XMPPConnection*)connection
didReceiveElement: (OFXMLElement*)element;
- (void)connection: (XMPPConnection*)connection
didSendElement: (OFXMLElement*)element;
- (void)connectionWasAuthenticated: (XMPPConnection*)connection;
- (void)connection: (XMPPConnection*)connection
wasBoundToJID: (XMPPJID*)JID;
- (void)connectionDidReceiveRoster: (XMPPConnection*)connection;
- (BOOL)connection: (XMPPConnection*)connection
didReceiveIQ: (XMPPIQ*)iq;
- (void)connection: (XMPPConnection*)connection
didReceivePresence: (XMPPPresence*)presence;
- (void)connection: (XMPPConnection*)connection
didReceiveMessage: (XMPPMessage*)message;
- (void)connection: (XMPPConnection*)connection
didReceiveRosterItem: (XMPPRosterItem*)rosterItem;
- (void)connectionWasClosed: (XMPPConnection*)connection;
- (void)connectionWillUpgradeToTLS: (XMPPConnection*)connection;
- (void)connectionDidUpgradeToTLS: (XMPPConnection*)connection;
@end
/**
* \brief A class which abstracts a connection to an XMPP service.
|
︙ | | |
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
-
-
|
XMPPMulticastDelegate *delegates;
OFMutableDictionary *callbacks;
XMPPAuthenticator *authModule;
BOOL streamOpen;
BOOL needsSession;
BOOL encryptionRequired, encrypted;
unsigned int lastID;
XMPPRoster *roster;
}
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *username, *password, *server, *domain, *resource;
@property (copy) OFString *privateKeyFile, *certificateFile;
@property (copy, readonly) XMPPJID *JID;
@property (assign) uint16_t port;
@property (readonly, retain) XMPPRoster *roster;
@property (readonly, retain, getter=socket) OFTCPSocket *sock;
@property (assign) BOOL encryptionRequired;
@property (readonly) BOOL encrypted;
@property (readonly) BOOL streamOpen;
#endif
/**
|
︙ | | |
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
-
|
- (void)setDomain: (OFString*)domain;
- (OFString*)domain;
- (void)setResource: (OFString*)resource;
- (OFString*)resource;
- (XMPPJID*)JID;
- (void)setPort: (uint16_t)port;
- (uint16_t)port;
- (XMPPRoster*)roster;
- (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;
|
︙ | | |
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
/*
* Copyright (c) 2010, 2011, 2012, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
*
* https://webkeks.org/hg/objxmpp/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
|
︙ | | |
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
-
-
|
#import "XMPPSCRAMAuth.h"
#import "XMPPPLAINAuth.h"
#import "XMPPStanza.h"
#import "XMPPJID.h"
#import "XMPPIQ.h"
#import "XMPPMessage.h"
#import "XMPPPresence.h"
#import "XMPPRoster.h"
#import "XMPPRosterItem.h"
#import "XMPPMulticastDelegate.h"
#import "XMPPExceptions.h"
#import "namespaces.h"
@implementation XMPPConnection
+ connection
{
|
︙ | | |
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
-
|
[server release];
[domain release];
[resource release];
[JID release];
[delegates release];
[callbacks release];
[authModule release];
[roster release];
[super dealloc];
}
- (void)setUsername: (OFString*)username_
{
OFString *old = username;
|
︙ | | |
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
|
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
|
-
-
-
-
|
/*
* We can't release them now, as we are currently inside them. Release
* them the next time the parser returns.
*/
oldParser = parser;
oldElementBuilder = elementBuilder;
[roster release];
parser = [[OFXMLParser alloc] init];
[parser setDelegate: self];
elementBuilder = [[OFXMLElementBuilder alloc] init];
[elementBuilder setDelegate: self];
roster = [[XMPPRoster alloc] initWithConnection: self];
[sock writeFormat: @"<?xml version='1.0'?>\n"
@"<stream:stream to='%@' "
@"xmlns='" XMPP_NS_CLIENT @"' "
@"xmlns:stream='" XMPP_NS_STREAM @"' "
@"version='1.0'>", domain];
streamOpen = YES;
}
|
︙ | | |
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
|
771
772
773
774
775
776
777
778
779
780
781
782
783
784
|
-
-
-
-
-
|
if ((callback = [callbacks objectForKey: [iq ID]])) {
[callback runWithIQ: iq];
[callbacks removeObjectForKey: [iq ID]];
return;
}
if ([iq elementForName: @"query"
namespace: XMPP_NS_ROSTER])
if ([roster handleIQ: iq])
return;
handled = [delegates broadcastSelector: @selector(
connection:didReceiveIQ:)
forConnection: self
withObject: iq];
if (!handled && ![[iq type] isEqual: @"error"] &&
![[iq type] isEqual: @"result"]) {
|
︙ | | |
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
|
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
|
-
-
-
-
-
|
[delegates removeDelegate: delegate];
}
- (XMPPMulticastDelegate*)XMPP_delegates
{
return delegates;
}
- (XMPPRoster*)roster
{
return [[roster retain] autorelease];
}
@end
@implementation OFObject (XMPPConnectionDelegate)
- (void)connection: (XMPPConnection*)connection
didReceiveElement: (OFXMLElement*)element
{
}
|
︙ | | |
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
|
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
|
-
-
-
-
-
-
-
-
-
|
}
- (void)connection: (XMPPConnection*)connection
wasBoundToJID: (XMPPJID*)JID
{
}
- (void)connectionDidReceiveRoster: (XMPPConnection*)connection
{
}
- (BOOL)connection: (XMPPConnection*)connection
didReceiveIQ: (XMPPIQ*)iq
{
return NO;
}
- (void)connection: (XMPPConnection*)connection
didReceivePresence: (XMPPPresence*)presence
{
}
- (void)connection: (XMPPConnection*)connection
didReceiveMessage: (XMPPMessage*)message
{
}
- (void)connection: (XMPPConnection*)connection
didReceiveRosterItem: (XMPPRosterItem*)rosterItem
{
}
- (void)connectionWasClosed: (XMPPConnection*)connection
{
}
- (void)connectionWillUpgradeToTLS: (XMPPConnection*)connection
|
︙ | | |
1
2
3
4
5
6
7
8
9
|
1
2
3
4
5
6
7
8
9
10
|
+
|
/*
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
*
* https://webkeks.org/hg/objxmpp/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
|
︙ | | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
19
20
21
22
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
|
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#import <ObjFW/ObjFW.h>
@class XMPPConnection;
#import "XMPPConnection.h"
@class XMPPRosterItem;
@class XMPPIQ;
@class XMPPRoster;
@protocol XMPPRosterDelegate
#ifndef XMPP_ROSTER_M
<OFObject>
#endif
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
@optional
#endif
- (void)rosterWasReceived: (XMPPRoster*)roster;
- (void)roster: (XMPPRoster*)roster
didReceiveRosterItem: (XMPPRosterItem*)rosterItem;
@end
@interface XMPPRoster: OFObject
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
<XMPPConnectionDelegate>
#endif
{
XMPPConnection *connection;
OFMutableDictionary *rosterItems;
OFString *rosterID;
id <XMPPRosterDelegate, OFObject> delegate;
}
#ifdef OF_HAVE_PROPERTIES
@property (assign) id <XMPPRosterDelegate> delegate;
#endif
- initWithConnection: (XMPPConnection*)conn;
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem;
- (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem;
- (void)XMPP_deleteRosterItem: (XMPPRosterItem*)rosterItem;
- (OFDictionary*)rosterItems;
- (BOOL)handleIQ: (XMPPIQ*)iq;
- (void)requestRoster;
- (void)addRosterItem: (XMPPRosterItem*)rosterItem;
- (void)updateRosterItem: (XMPPRosterItem*)rosterItem;
- (void)deleteRosterItem: (XMPPRosterItem*)rosterItem;
- (void)setDelegate: (id <XMPPRosterDelegate>)delegate;
- (id <XMPPRosterDelegate>)delegate;
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem;
- (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem;
- (void)XMPP_deleteRosterItem: (XMPPRosterItem*)rosterItem;
- (void)XMPP_handleInitialRoster: (XMPPIQ*)iq;
- (XMPPRosterItem*)XMPP_rosterItemWithXMLElement: (OFXMLElement*)element;
@end
@interface OFObject (XMPPRosterDelegate) <XMPPRosterDelegate>
@end
|
1
2
3
4
5
6
7
8
9
|
1
2
3
4
5
6
7
8
9
10
|
+
|
/*
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
*
* https://webkeks.org/hg/objxmpp/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
|
︙ | | |
20
21
22
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
|
21
22
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
|
+
+
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
-
+
-
+
-
-
-
-
-
-
+
+
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
+
-
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
|
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#define XMPP_ROSTER_M
#include <assert.h>
#import "XMPPRoster.h"
#import "XMPPRosterItem.h"
#import "XMPPConnection.h"
#import "XMPPIQ.h"
#import "XMPPJID.h"
#import "XMPPMulticastDelegate.h"
#import "namespaces.h"
@implementation XMPPRoster
- initWithConnection: (XMPPConnection*)conn
- initWithConnection: (XMPPConnection*)connection_
{
self = [super init];
@try {
rosterItems = [[OFMutableDictionary alloc] init];
connection = connection_;
[connection addDelegate: self];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[rosterItems release];
[rosterID release];
[super dealloc];
}
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem
{
return [self XMPP_updateRosterItem: rosterItem];
}
- (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem
{
[rosterItems setObject: rosterItem
forKey: [[rosterItem JID] bareJID]];
}
- (void)XMPP_deleteRosterItem: (XMPPRosterItem*)rosterItem
{
[rosterItems removeObjectForKey: [[rosterItem JID] bareJID]];
}
- (OFDictionary*)rosterItems
{
return [[rosterItems copy] autorelease];
}
- (void)requestRoster
{
XMPPIQ *iq;
if (rosterID != nil)
assert(0);
rosterID = [[connection generateStanzaID] retain];
iq = [XMPPIQ IQWithType: @"get"
ID: rosterID];
ID: [connection generateStanzaID]];
[iq addChild: [OFXMLElement elementWithName: @"query"
namespace: XMPP_NS_ROSTER]];
[connection sendStanza: iq];
[connection sendIQ: iq
withCallbackObject: self
selector: @selector(XMPP_handleInitialRoster:)];
}
- (BOOL)connection: (XMPPConnection*)connection_
- (BOOL)handleIQ: (XMPPIQ*)iq
didReceiveIQ: (XMPPIQ*)iq
{
OFXMLElement *rosterElement;
OFXMLElement *element;
XMPPRosterItem *rosterItem = nil;
XMPPRosterItem *rosterItem;
OFString *subscription;
OFEnumerator *enumerator;
BOOL isPush = ![[iq ID] isEqual: rosterID];
rosterElement = [iq elementForName: @"query"
namespace: XMPP_NS_ROSTER];
if (rosterElement == nil)
return NO;
if (isPush) {
if (![[iq type] isEqual: @"set"])
return NO;
if (![[iq type] isEqual: @"set"])
return NO;
} else {
if (![[iq type] isEqual: @"result"])
return NO;
}
element = [rosterElement elementForName: @"item"
enumerator = [[rosterElement children] objectEnumerator];
while ((element = [enumerator nextObject]) != nil) {
OFMutableArray *groups = [OFMutableArray array];
OFEnumerator *groupEnumerator;
OFXMLElement *groupElement;
if (![[element name] isEqual: @"item"] ||
![[element namespace] isEqual: XMPP_NS_ROSTER])
continue;
rosterItem = [XMPPRosterItem rosterItem];
[rosterItem setJID: [XMPPJID JIDWithString:
[[element attributeForName: @"jid"] stringValue]]];
[rosterItem setName:
[[element attributeForName: @"name"] stringValue]];
subscription = [[element attributeForName:
@"subscription"] stringValue];
if (![subscription isEqual: @"none"] &&
![subscription isEqual: @"to"] &&
![subscription isEqual: @"from"] &&
![subscription isEqual: @"both"] &&
(![subscription isEqual: @"remove"] || !isPush))
subscription = @"none";
[rosterItem setSubscription: subscription];
groupEnumerator = [[element
elementsForName: @"group"
namespace: XMPP_NS_ROSTER] objectEnumerator];
namespace: XMPP_NS_ROSTER];
while ((groupElement = [groupEnumerator nextObject]) != nil)
[groups addObject: [groupElement stringValue]];
if ([groups count] > 0)
[rosterItem setGroups: groups];
if (element != nil) {
rosterItem = [self XMPP_rosterItemWithXMLElement: element];
if ([subscription isEqual: @"remove"])
if ([[rosterItem subscription] isEqual: @"remove"])
[self XMPP_deleteRosterItem: rosterItem];
else
[self XMPP_addRosterItem: rosterItem];
if (isPush) {
SEL sel = @selector(connection:didReceiveRosterItem:);
if ([delegate respondsToSelector:
@selector(roster:didReceiveRosterItem:)])
[delegate roster: self
[[connection XMPP_delegates]
broadcastSelector: sel
forConnection: connection
withObject: rosterItem];
}
}
didReceiveRosterItem: rosterItem];
}
if (isPush) {
[connection sendStanza: [iq resultIQ]];
[connection_ sendStanza: [iq resultIQ]];
} else {
[[connection XMPP_delegates]
broadcastSelector: @selector(connectionDidReceiveRoster:)
forConnection: connection];
[rosterID release];
rosterID = nil;
}
return YES;
}
- (void)addRosterItem: (XMPPRosterItem*)rosterItem
{
[self updateRosterItem: rosterItem];
|
︙ | | |
231
232
233
234
235
236
237
238
|
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
stringValue: @"remove"];
[query addChild: item];
[iq addChild: query];
[connection sendStanza: iq];
}
- (void)setDelegate: (id <XMPPRosterDelegate>)delegate_
{
delegate = (id <XMPPRosterDelegate, OFObject>)delegate_;
}
- (id <XMPPRosterDelegate>)delegate
{
return delegate;
}
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem
{
return [self XMPP_updateRosterItem: rosterItem];
}
- (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem
{
[rosterItems setObject: rosterItem
forKey: [[rosterItem JID] bareJID]];
}
- (void)XMPP_deleteRosterItem: (XMPPRosterItem*)rosterItem
{
[rosterItems removeObjectForKey: [[rosterItem JID] bareJID]];
}
- (XMPPRosterItem*)XMPP_rosterItemWithXMLElement: (OFXMLElement*)element
{
OFString *subscription;
OFEnumerator *groupEnumerator;
OFXMLElement *groupElement;
OFMutableArray *groups = [OFMutableArray array];
XMPPRosterItem *rosterItem = [XMPPRosterItem rosterItem];
[rosterItem setJID: [XMPPJID JIDWithString:
[[element attributeForName: @"jid"] stringValue]]];
[rosterItem setName:
[[element attributeForName: @"name"] stringValue]];
subscription = [[element attributeForName:
@"subscription"] stringValue];
if (![subscription isEqual: @"none"] &&
![subscription isEqual: @"to"] &&
![subscription isEqual: @"from"] &&
![subscription isEqual: @"both"] &&
![subscription isEqual: @"remove"])
subscription = @"none";
[rosterItem setSubscription: subscription];
groupEnumerator = [[element
elementsForName: @"group"
namespace: XMPP_NS_ROSTER] objectEnumerator];
while ((groupElement = [groupEnumerator nextObject]) != nil)
[groups addObject: [groupElement stringValue]];
if ([groups count] > 0)
[rosterItem setGroups: groups];
return rosterItem;
}
- (void)XMPP_handleInitialRoster: (XMPPIQ*)iq
{
OFXMLElement *rosterElement;
OFEnumerator *enumerator;
OFXMLElement *element;
XMPPRosterItem *rosterItem = nil;
rosterElement = [iq elementForName: @"query"
namespace: XMPP_NS_ROSTER];
enumerator = [[rosterElement children] objectEnumerator];
while ((element = [enumerator nextObject]) != nil) {
if (![[element name] isEqual: @"item"] ||
![[element namespace] isEqual: XMPP_NS_ROSTER])
continue;
rosterItem = [self XMPP_rosterItemWithXMLElement: element];
if ([[rosterItem subscription] isEqual: @"remove"])
[self XMPP_deleteRosterItem: rosterItem];
else
[self XMPP_addRosterItem: rosterItem];
}
if ([delegate respondsToSelector: @selector(rosterWasReceived:)])
[delegate rosterWasReceived: self];
}
@end
@implementation OFObject (XMPPRosterDelegate)
- (void)rosterWasReceived: (XMPPRoster*)roster
{
}
- (void)roster: (XMPPRoster*)roster
didReceiveRosterItem: (XMPPRosterItem*)rosterItem
{
}
@end
|
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
/*
* Copyright (c) 2010, 2011, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
*
* https://webkeks.org/hg/objxmpp/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
|
︙ | | |
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
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
|
-
+
+
+
+
+
-
|
#import "XMPPIQ.h"
#import "XMPPMessage.h"
#import "XMPPPresence.h"
#import "XMPPRoster.h"
@interface AppDelegate: OFObject
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
<OFApplicationDelegate, XMPPConnectionDelegate>
<OFApplicationDelegate, XMPPConnectionDelegate, XMPPRosterDelegate>
#endif
{
XMPPConnection * conn;
XMPPRoster *roster;
}
@end
OF_APPLICATION_DELEGATE(AppDelegate)
@implementation AppDelegate
- (void)applicationDidFinishLaunching
{
XMPPConnection *conn;
OFArray *arguments = [OFApplication arguments];
XMPPPresence *pres = [XMPPPresence presence];
[pres addShow: @"chat"];
[pres addStatus: @"Bored"];
[pres addPriority: 20];
[pres setTo: [XMPPJID JIDWithString: @"alice@example.com"]];
|
︙ | | |
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
+
+
+
|
XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem];
assert([[elem XMLString] isEqual: [stanza XMLString]]);
assert(([[OFString stringWithFormat: @"%@, %@, %@, %@",
[[stanza from] fullJID], [[stanza to] fullJID], [stanza type],
[stanza ID]] isEqual: @"bob@localhost, alice@localhost, get, 42"]));
conn = [[XMPPConnection alloc] init];
roster = [[XMPPRoster alloc] initWithConnection: conn];
[conn addDelegate: self];
[roster setDelegate: self];
if ([arguments count] != 3) {
of_log(@"Invalid count of command line arguments!");
[OFApplication terminateWithStatus: 1];
}
[conn setDomain: [arguments objectAtIndex: 0]];
|
︙ | | |
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
|
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
|
-
+
-
+
-
+
-
+
-
+
-
+
|
}
- (void)connection: (XMPPConnection*)conn
wasBoundToJID: (XMPPJID*)jid
{
of_log(@"Bound to JID: %@", [jid fullJID]);
[[conn roster] requestRoster];
[roster requestRoster];
}
- (void)connectionDidReceiveRoster: (XMPPConnection*)conn
- (void)rosterWasReceived: (XMPPRoster*)roster_
{
XMPPPresence *pres;
of_log(@"Got roster: %@", [[conn roster] rosterItems]);
of_log(@"Got roster: %@", [roster_ rosterItems]);
pres = [XMPPPresence presence];
[pres addPriority: 10];
[pres addStatus: @"ObjXMPP test is working!"];
[conn sendStanza: pres];
#ifdef OF_HAVE_BLOCKS
XMPPIQ *iq = [XMPPIQ IQWithType: @"get"
ID: [conn generateStanzaID]];
[iq addChild: [OFXMLElement elementWithName: @"ping"
namespace: @"urn:xmpp:ping"]];
[conn sendIQ: iq
withCallbackBlock: ^(XMPPIQ* resp) {
of_log(@"Ping response: %@", resp);
}];
#endif
}
- (void)connectionDidUpgradeToTLS: (XMPPConnection*)conn
- (void)connectionDidUpgradeToTLS: (XMPPConnection*)conn_
{
@try {
[conn checkCertificate];
[conn_ checkCertificate];
} @catch (SSLInvalidCertificateException *e) {
OFString *answer;
[of_stdout writeString: @"Couldn't verify certificate: "];
[of_stdout writeFormat: @"%@\n", e];
[of_stdout writeString: @"Do you want to continue [y/N]? "];
answer = [of_stdin readLine];
if (![answer hasPrefix: @"y"])
@throw e;
}
}
- (void)connection: (XMPPConnection*)conn
- (void)roster: (XMPPRoster*)roster_
didReceiveRosterItem: (XMPPRosterItem*)rosterItem
{
of_log(@"Got roster push: %@", rosterItem);
}
- (BOOL)connection: (XMPPConnection*)conn
didReceiveIQ: (XMPPIQ*)iq
|
︙ | | |