Index: src/XMPPContactManager.h ================================================================== --- src/XMPPContactManager.h +++ src/XMPPContactManager.h @@ -55,10 +55,19 @@ * \param contact The contact that was removed */ - (void)contactManager: (XMPPContactManager*)manager didRemoveContact: (XMPPContact*)contact; +/** + * \brief This callback is called when a subscription request is received + * + * \param manager The contact manager that received the request + * \param presence The type=subscribe presence + */ +- (void)contactManager: (XMPPContactManager*)manager + didReceiveSubscriptionRequest: (XMPPPresence*)presence; + /** * \brief This callback is called whenever a contact is about to change its * roster item * * \param contact The contact about to updated its roster item @@ -116,10 +125,13 @@ * @return An initialized XMPPContactManager */ - initWithConnection: (XMPPConnection*)connection roster: (XMPPRoster*)roster; +- (void)sendSubscribedToJID: (XMPPJID*)subscriber; +- (void)sendUnsubscribedToJID: (XMPPJID*)subscriber; + /** * \brief Adds the specified delegate. * * \param delegate The delegate to add */ Index: src/XMPPContactManager.m ================================================================== --- src/XMPPContactManager.m +++ src/XMPPContactManager.m @@ -56,10 +56,26 @@ [_contacts release]; [super dealloc]; } + +- (void)sendSubscribedToJID: (XMPPJID*)subscriber +{ + XMPPPresence *presence = [XMPPPresence presenceWithType: @"subscribed"]; + [presence setTo: subscriber]; + [_connection sendStanza: presence]; +} + +- (void)sendUnsubscribedToJID: (XMPPJID*)subscriber +{ + XMPPPresence *presence = + [XMPPPresence presenceWithType: @"unsubscribed"]; + [presence setTo: subscriber]; + [_connection sendStanza: presence]; +} + - (void)addDelegate: (id )delegate { [_delegates addDelegate: delegate]; } @@ -143,30 +159,47 @@ } - (void)connection: (XMPPConnection*)connection didReceivePresence: (XMPPPresence*)presence { + XMPPContact *contact; XMPPJID *JID = [presence from]; - XMPPContact *contact = [_contacts objectForKey: [JID bareJID]]; + OFString *type = [presence type]; + + /* Subscription request */ + if ([type isEqual: @"subscribe"]) { + of_log(@"ObjXMPP: received subscription request"); + [_delegates broadcastSelector: @selector(contactManager: + didReceiveSubscriptionRequest:) + withObject: self + withObject: presence]; + return; + } + contact = [_contacts objectForKey: [JID bareJID]]; if (contact == nil) return; - // We only care for available and unavailable here, not subscriptions - if ([[presence type] isEqual: @"available"]) { + /* Available presence */ + if ([type isEqual: @"available"]) { [contact XMPP_setPresence: presence resource: [JID resource]]; [_delegates broadcastSelector: @selector(contact: didSendPresence:) withObject: contact withObject: presence]; - } else if ([[presence type] isEqual: @"unavailable"]) { + return; + } + + /* Unavailable presence */ + if ([type isEqual: @"unavailable"]) { [contact XMPP_removePresenceForResource: [JID resource]]; [_delegates broadcastSelector: @selector(contact: didSendPresence:) withObject: contact withObject: presence]; + return; } } - (void)connection: (XMPPConnection*)connection didReceiveMessage: (XMPPMessage*)message