Request and handle roster.

This commit is contained in:
Jonathan Schleifer 2011-03-21 20:51:17 +01:00
parent 456cc295bc
commit e71c601cbe
5 changed files with 111 additions and 15 deletions

View file

@ -1,5 +1,5 @@
all:
objfw-compile -Wall --lib 0.0 -o objxmpp *.m \
objfw-compile -Wall -g --lib 0.0 -o objxmpp *.m \
`pkg-config --cflags --libs libidn` -lobjgnutls
clean:

View file

@ -35,6 +35,7 @@
- (void)connectionWasAuthenticated: (XMPPConnection*)conn;
- (void)connection: (XMPPConnection*)conn
wasBoundToJID: (XMPPJID*)jid;
- (void)connectionDidReceiveRoster: (XMPPConnection*)conn;
- (void)connection: (XMPPConnection*)conn
didReceiveIQ: (XMPPIQ*)iq;
- (void)connection: (XMPPConnection*)conn
@ -62,7 +63,8 @@
XMPPAuthenticator *authModule;
BOOL needsSession;
unsigned int lastID;
OFString *bindID, *sessionID;
OFString *bindID, *sessionID, *rosterID;
OFMutableDictionary *roster;
}
@property (copy) OFString *username, *password, *server, *resource;
@ -70,6 +72,7 @@
@property (assign) uint16_t port;
@property (assign) BOOL useTLS;
@property (retain) id <XMPPConnectionDelegate> delegate;
@property (copy, readonly) OFDictionary *roster;
/**
* Connects to the XMPP service.
@ -94,4 +97,9 @@
* \return A new, generated, unique stanza ID.
*/
- (OFString*)generateStanzaID;
/**
* Requests the roster.
*/
- (void)requestRoster;
@end

View file

@ -40,6 +40,7 @@
#define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind"
#define NS_CLIENT @"jabber:client"
#define NS_ROSTER @"jabber:iq:roster"
#define NS_SASL @"urn:ietf:params:xml:ns:xmpp-sasl"
#define NS_STARTTLS @"urn:ietf:params:xml:ns:xmpp-tls"
#define NS_SESSION @"urn:ietf:params:xml:ns:xmpp-session"
@ -56,24 +57,32 @@
- (void)XMPP_handleResourceBind: (XMPPIQ*)iq;
- (void)XMPP_sendSession;
- (void)XMPP_handleSession: (XMPPIQ*)iq;
- (void)XMPP_handleRoster: (XMPPIQ*)iq;
@end
@implementation XMPPConnection
@synthesize JID, port, useTLS, delegate;
@synthesize JID, port, useTLS, delegate, roster;
- init
{
self = [super init];
sock = [[OFTCPSocket alloc] init];
parser = [[OFXMLParser alloc] init];
elementBuilder = [[OFXMLElementBuilder alloc] init];
@try {
sock = [[OFTCPSocket alloc] init];
parser = [[OFXMLParser alloc] init];
elementBuilder = [[OFXMLElementBuilder alloc] init];
port = 5222;
useTLS = YES;
port = 5222;
useTLS = YES;
parser.delegate = self;
elementBuilder.delegate = self;
parser.delegate = self;
elementBuilder.delegate = self;
roster = [[OFMutableDictionary alloc] init];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
@ -92,6 +101,8 @@
[authModule release];
[bindID release];
[sessionID release];
[rosterID release];
[roster release];
[super dealloc];
}
@ -385,16 +396,21 @@
- (void)XMPP_handleIQ: (XMPPIQ*)iq
{
if ([iq.ID isEqual: bindID] && [iq.type isEqual: @"result"]) {
if ([iq.ID isEqual: bindID]) {
[self XMPP_handleResourceBind: iq];
return;
}
if ([iq.ID isEqual: sessionID] && [iq.type isEqual: @"result"]) {
if ([iq.ID isEqual: sessionID]) {
[self XMPP_handleSession: iq];
return;
}
if ([iq.ID isEqual: rosterID]) {
[self XMPP_handleRoster: iq];
return;
}
if ([delegate respondsToSelector: @selector(connection:didReceiveIQ:)])
[delegate connection: self
didReceiveIQ: iq];
@ -508,9 +524,14 @@
- (void)XMPP_handleResourceBind: (XMPPIQ*)iq
{
OFXMLElement *bindElem = iq.children.firstObject;
OFXMLElement *bindElem;
OFXMLElement *jidElem;
if (![iq.type isEqual: @"result"])
assert(0);
bindElem = iq.children.firstObject;
if (![bindElem.name isEqual: @"bind"] ||
![bindElem.namespace isEqual: NS_BIND])
assert(0);
@ -556,4 +577,64 @@
[sessionID release];
sessionID = nil;
}
- (void)requestRoster
{
XMPPIQ *iq;
if (rosterID != nil)
assert(0);
rosterID = [[self generateStanzaID] retain];
iq = [XMPPIQ IQWithType: @"get"
ID: rosterID];
[iq addChild: [OFXMLElement elementWithName: @"query"
namespace: NS_ROSTER]];
[self sendStanza: iq];
}
- (void)XMPP_handleRoster: (XMPPIQ*)iq
{
OFXMLElement *rosterElem;
if (![iq.type isEqual: @"result"])
assert(0);
rosterElem = iq.children.firstObject;
if (![rosterElem.name isEqual: @"query"] ||
![rosterElem.namespace isEqual: NS_ROSTER])
assert(0);
for (OFXMLElement *elem in rosterElem.children) {
OFString *group;
OFMutableArray *rosterGroup;
if (![elem.name isEqual: @"item"] ||
![elem.ns isEqual: NS_ROSTER])
continue;
group = [[elem
elementsForName: @"group"
namespace: NS_ROSTER].firstObject stringValue];
if (group == nil)
group = @"";
if ((rosterGroup = [roster objectForKey: group]) == nil) {
rosterGroup = [OFMutableArray array];
[roster setObject: rosterGroup
forKey: group];
}
[rosterGroup addObject: elem];
}
if ([delegate respondsToSelector:
@selector(connectionDidReceiveRoster:)])
[delegate connectionDidReceiveRoster: self];
[rosterID release];
rosterID = nil;
}
@end

View file

@ -1,5 +1,5 @@
all:
objfw-compile -Wall -o tests *.m -I../src -L../src -lobjxmpp
objfw-compile -Wall -g -o tests *.m -I../src -L../src -lobjxmpp
clean:
rm -f tests *.o

View file

@ -110,10 +110,17 @@ OF_APPLICATION_DELEGATE(AppDelegate)
- (void)connection: (XMPPConnection*)conn
wasBoundToJID: (XMPPJID*)jid
{
of_log(@"Bound to JID: %@", [jid fullJID]);
[conn requestRoster];
}
- (void)connectionDidReceiveRoster :(XMPPConnection*)conn
{
XMPPPresence *pres;
of_log(@"Bound to JID: %@", [jid fullJID]);
of_log(@"Got roster");
pres = [XMPPPresence presence];
[pres addPriority: 10];