Request and handle roster.
This commit is contained in:
parent
456cc295bc
commit
e71c601cbe
5 changed files with 111 additions and 15 deletions
|
@ -1,5 +1,5 @@
|
||||||
all:
|
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
|
`pkg-config --cflags --libs libidn` -lobjgnutls
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
- (void)connectionWasAuthenticated: (XMPPConnection*)conn;
|
- (void)connectionWasAuthenticated: (XMPPConnection*)conn;
|
||||||
- (void)connection: (XMPPConnection*)conn
|
- (void)connection: (XMPPConnection*)conn
|
||||||
wasBoundToJID: (XMPPJID*)jid;
|
wasBoundToJID: (XMPPJID*)jid;
|
||||||
|
- (void)connectionDidReceiveRoster: (XMPPConnection*)conn;
|
||||||
- (void)connection: (XMPPConnection*)conn
|
- (void)connection: (XMPPConnection*)conn
|
||||||
didReceiveIQ: (XMPPIQ*)iq;
|
didReceiveIQ: (XMPPIQ*)iq;
|
||||||
- (void)connection: (XMPPConnection*)conn
|
- (void)connection: (XMPPConnection*)conn
|
||||||
|
@ -62,7 +63,8 @@
|
||||||
XMPPAuthenticator *authModule;
|
XMPPAuthenticator *authModule;
|
||||||
BOOL needsSession;
|
BOOL needsSession;
|
||||||
unsigned int lastID;
|
unsigned int lastID;
|
||||||
OFString *bindID, *sessionID;
|
OFString *bindID, *sessionID, *rosterID;
|
||||||
|
OFMutableDictionary *roster;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property (copy) OFString *username, *password, *server, *resource;
|
@property (copy) OFString *username, *password, *server, *resource;
|
||||||
|
@ -70,6 +72,7 @@
|
||||||
@property (assign) uint16_t port;
|
@property (assign) uint16_t port;
|
||||||
@property (assign) BOOL useTLS;
|
@property (assign) BOOL useTLS;
|
||||||
@property (retain) id <XMPPConnectionDelegate> delegate;
|
@property (retain) id <XMPPConnectionDelegate> delegate;
|
||||||
|
@property (copy, readonly) OFDictionary *roster;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects to the XMPP service.
|
* Connects to the XMPP service.
|
||||||
|
@ -94,4 +97,9 @@
|
||||||
* \return A new, generated, unique stanza ID.
|
* \return A new, generated, unique stanza ID.
|
||||||
*/
|
*/
|
||||||
- (OFString*)generateStanzaID;
|
- (OFString*)generateStanzaID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests the roster.
|
||||||
|
*/
|
||||||
|
- (void)requestRoster;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
#define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind"
|
#define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind"
|
||||||
#define NS_CLIENT @"jabber:client"
|
#define NS_CLIENT @"jabber:client"
|
||||||
|
#define NS_ROSTER @"jabber:iq:roster"
|
||||||
#define NS_SASL @"urn:ietf:params:xml:ns:xmpp-sasl"
|
#define NS_SASL @"urn:ietf:params:xml:ns:xmpp-sasl"
|
||||||
#define NS_STARTTLS @"urn:ietf:params:xml:ns:xmpp-tls"
|
#define NS_STARTTLS @"urn:ietf:params:xml:ns:xmpp-tls"
|
||||||
#define NS_SESSION @"urn:ietf:params:xml:ns:xmpp-session"
|
#define NS_SESSION @"urn:ietf:params:xml:ns:xmpp-session"
|
||||||
|
@ -56,24 +57,32 @@
|
||||||
- (void)XMPP_handleResourceBind: (XMPPIQ*)iq;
|
- (void)XMPP_handleResourceBind: (XMPPIQ*)iq;
|
||||||
- (void)XMPP_sendSession;
|
- (void)XMPP_sendSession;
|
||||||
- (void)XMPP_handleSession: (XMPPIQ*)iq;
|
- (void)XMPP_handleSession: (XMPPIQ*)iq;
|
||||||
|
- (void)XMPP_handleRoster: (XMPPIQ*)iq;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation XMPPConnection
|
@implementation XMPPConnection
|
||||||
@synthesize JID, port, useTLS, delegate;
|
@synthesize JID, port, useTLS, delegate, roster;
|
||||||
|
|
||||||
- init
|
- init
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
sock = [[OFTCPSocket alloc] init];
|
@try {
|
||||||
parser = [[OFXMLParser alloc] init];
|
sock = [[OFTCPSocket alloc] init];
|
||||||
elementBuilder = [[OFXMLElementBuilder alloc] init];
|
parser = [[OFXMLParser alloc] init];
|
||||||
|
elementBuilder = [[OFXMLElementBuilder alloc] init];
|
||||||
|
|
||||||
port = 5222;
|
port = 5222;
|
||||||
useTLS = YES;
|
useTLS = YES;
|
||||||
|
|
||||||
parser.delegate = self;
|
parser.delegate = self;
|
||||||
elementBuilder.delegate = self;
|
elementBuilder.delegate = self;
|
||||||
|
|
||||||
|
roster = [[OFMutableDictionary alloc] init];
|
||||||
|
} @catch (id e) {
|
||||||
|
[self release];
|
||||||
|
@throw e;
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -92,6 +101,8 @@
|
||||||
[authModule release];
|
[authModule release];
|
||||||
[bindID release];
|
[bindID release];
|
||||||
[sessionID release];
|
[sessionID release];
|
||||||
|
[rosterID release];
|
||||||
|
[roster release];
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
@ -385,16 +396,21 @@
|
||||||
|
|
||||||
- (void)XMPP_handleIQ: (XMPPIQ*)iq
|
- (void)XMPP_handleIQ: (XMPPIQ*)iq
|
||||||
{
|
{
|
||||||
if ([iq.ID isEqual: bindID] && [iq.type isEqual: @"result"]) {
|
if ([iq.ID isEqual: bindID]) {
|
||||||
[self XMPP_handleResourceBind: iq];
|
[self XMPP_handleResourceBind: iq];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([iq.ID isEqual: sessionID] && [iq.type isEqual: @"result"]) {
|
if ([iq.ID isEqual: sessionID]) {
|
||||||
[self XMPP_handleSession: iq];
|
[self XMPP_handleSession: iq];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ([iq.ID isEqual: rosterID]) {
|
||||||
|
[self XMPP_handleRoster: iq];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ([delegate respondsToSelector: @selector(connection:didReceiveIQ:)])
|
if ([delegate respondsToSelector: @selector(connection:didReceiveIQ:)])
|
||||||
[delegate connection: self
|
[delegate connection: self
|
||||||
didReceiveIQ: iq];
|
didReceiveIQ: iq];
|
||||||
|
@ -508,9 +524,14 @@
|
||||||
|
|
||||||
- (void)XMPP_handleResourceBind: (XMPPIQ*)iq
|
- (void)XMPP_handleResourceBind: (XMPPIQ*)iq
|
||||||
{
|
{
|
||||||
OFXMLElement *bindElem = iq.children.firstObject;
|
OFXMLElement *bindElem;
|
||||||
OFXMLElement *jidElem;
|
OFXMLElement *jidElem;
|
||||||
|
|
||||||
|
if (![iq.type isEqual: @"result"])
|
||||||
|
assert(0);
|
||||||
|
|
||||||
|
bindElem = iq.children.firstObject;
|
||||||
|
|
||||||
if (![bindElem.name isEqual: @"bind"] ||
|
if (![bindElem.name isEqual: @"bind"] ||
|
||||||
![bindElem.namespace isEqual: NS_BIND])
|
![bindElem.namespace isEqual: NS_BIND])
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -556,4 +577,64 @@
|
||||||
[sessionID release];
|
[sessionID release];
|
||||||
sessionID = nil;
|
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
|
@end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
all:
|
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:
|
clean:
|
||||||
rm -f tests *.o
|
rm -f tests *.o
|
||||||
|
|
|
@ -110,10 +110,17 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
||||||
|
|
||||||
- (void)connection: (XMPPConnection*)conn
|
- (void)connection: (XMPPConnection*)conn
|
||||||
wasBoundToJID: (XMPPJID*)jid
|
wasBoundToJID: (XMPPJID*)jid
|
||||||
|
{
|
||||||
|
of_log(@"Bound to JID: %@", [jid fullJID]);
|
||||||
|
|
||||||
|
[conn requestRoster];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connectionDidReceiveRoster :(XMPPConnection*)conn
|
||||||
{
|
{
|
||||||
XMPPPresence *pres;
|
XMPPPresence *pres;
|
||||||
|
|
||||||
of_log(@"Bound to JID: %@", [jid fullJID]);
|
of_log(@"Got roster");
|
||||||
|
|
||||||
pres = [XMPPPresence presence];
|
pres = [XMPPPresence presence];
|
||||||
[pres addPriority: 10];
|
[pres addPriority: 10];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue