294 lines
7.2 KiB
Objective-C
294 lines
7.2 KiB
Objective-C
#import "XMPPMessageCarbons.h"
|
|
#import "XMPP.h"
|
|
#import "XMPPFramework.h"
|
|
#import "XMPPLogging.h"
|
|
#import "XMPPIDTracker.h"
|
|
#import "NSXMLElement+XEP_0297.h"
|
|
#import "XMPPMessage+XEP_0280.h"
|
|
#import "XMPPInternal.h"
|
|
|
|
#if ! __has_feature(objc_arc)
|
|
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
|
#endif
|
|
|
|
// Log levels: off, error, warn, info, verbose
|
|
// Log flags: trace
|
|
#if DEBUG
|
|
static const int xmppLogLevel = XMPP_LOG_LEVEL_VERBOSE; // | XMPP_LOG_FLAG_TRACE;
|
|
#else
|
|
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
|
|
#endif
|
|
|
|
|
|
#define XMLNS_XMPP_MESSAGE_CARBONS @"urn:xmpp:carbons:2"
|
|
|
|
@implementation XMPPMessageCarbons
|
|
|
|
- (id)initWithDispatchQueue:(dispatch_queue_t)queue
|
|
{
|
|
if((self = [super initWithDispatchQueue:queue]))
|
|
{
|
|
autoEnableMessageCarbons = YES;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (BOOL)activate:(XMPPStream *)aXmppStream
|
|
{
|
|
XMPPLogTrace();
|
|
|
|
if ([super activate:aXmppStream])
|
|
{
|
|
XMPPLogVerbose(@"%@: Activated", THIS_FILE);
|
|
|
|
xmppIDTracker = [[XMPPIDTracker alloc] initWithDispatchQueue:moduleQueue];
|
|
|
|
return YES;
|
|
}
|
|
|
|
return NO;
|
|
}
|
|
|
|
- (void)deactivate
|
|
{
|
|
XMPPLogTrace();
|
|
|
|
dispatch_block_t block = ^{ @autoreleasepool {
|
|
|
|
[xmppIDTracker removeAllIDs];
|
|
xmppIDTracker = nil;
|
|
|
|
}};
|
|
|
|
if (dispatch_get_specific(moduleQueueTag))
|
|
block();
|
|
else
|
|
dispatch_sync(moduleQueue, block);
|
|
|
|
[super deactivate];
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark Properties
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
- (BOOL)autoEnableMessageCarbons
|
|
{
|
|
__block BOOL result = NO;
|
|
|
|
dispatch_block_t block = ^{
|
|
result = autoEnableMessageCarbons;
|
|
};
|
|
|
|
if (dispatch_get_specific(moduleQueueTag))
|
|
block();
|
|
else
|
|
dispatch_sync(moduleQueue, block);
|
|
|
|
return result;
|
|
}
|
|
|
|
- (void)setAutoEnableMessageCarbons:(BOOL)flag
|
|
{
|
|
dispatch_block_t block = ^{
|
|
autoEnableMessageCarbons = flag;
|
|
};
|
|
|
|
if (dispatch_get_specific(moduleQueueTag))
|
|
block();
|
|
else
|
|
dispatch_async(moduleQueue, block);
|
|
}
|
|
|
|
- (BOOL)isMessageCarbonsEnabled
|
|
{
|
|
__block BOOL result = NO;
|
|
|
|
dispatch_block_t block = ^{
|
|
result = messageCarbonsEnabled;
|
|
};
|
|
|
|
if (dispatch_get_specific(moduleQueueTag))
|
|
block();
|
|
else
|
|
dispatch_sync(moduleQueue, block);
|
|
|
|
return result;
|
|
}
|
|
|
|
- (BOOL)allowsUntrustedMessageCarbons
|
|
{
|
|
__block BOOL result = NO;
|
|
|
|
dispatch_block_t block = ^{
|
|
result = allowsUntrustedMessageCarbons;
|
|
};
|
|
|
|
if (dispatch_get_specific(moduleQueueTag))
|
|
block();
|
|
else
|
|
dispatch_sync(moduleQueue, block);
|
|
|
|
return result;
|
|
}
|
|
|
|
- (void)setAllowsUntrustedMessageCarbons:(BOOL)flag
|
|
{
|
|
dispatch_block_t block = ^{
|
|
allowsUntrustedMessageCarbons = flag;
|
|
};
|
|
|
|
if (dispatch_get_specific(moduleQueueTag))
|
|
block();
|
|
else
|
|
dispatch_async(moduleQueue, block);
|
|
}
|
|
|
|
- (void)enableMessageCarbons
|
|
{
|
|
dispatch_block_t block = ^{
|
|
|
|
if(!messageCarbonsEnabled && [xmppIDTracker numberOfIDs] == 0)
|
|
{
|
|
NSString *elementID = [XMPPStream generateUUID];
|
|
XMPPIQ *iq = [XMPPIQ iqWithType:@"set" elementID:elementID];
|
|
[iq setXmlns:@"jabber:client"];
|
|
|
|
NSXMLElement *enable = [NSXMLElement elementWithName:@"enable" xmlns:XMLNS_XMPP_MESSAGE_CARBONS];
|
|
[iq addChild:enable];
|
|
|
|
[xmppIDTracker addElement:iq
|
|
target:self
|
|
selector:@selector(enableMessageCarbonsIQ:withInfo:)
|
|
timeout:XMPPIDTrackerTimeoutNone];
|
|
|
|
[xmppStream sendElement:iq];
|
|
}
|
|
};
|
|
|
|
if (dispatch_get_specific(moduleQueueTag))
|
|
block();
|
|
else
|
|
dispatch_sync(moduleQueue, block);
|
|
}
|
|
|
|
- (void)disableMessageCarbons
|
|
{
|
|
dispatch_block_t block = ^{
|
|
|
|
if(messageCarbonsEnabled && [xmppIDTracker numberOfIDs] == 0)
|
|
{
|
|
NSString *elementID = [XMPPStream generateUUID];
|
|
|
|
XMPPIQ *iq = [XMPPIQ iqWithType:@"set" elementID:elementID];
|
|
[iq setXmlns:@"jabber:client"];
|
|
|
|
NSXMLElement *enable = [NSXMLElement elementWithName:@"disable" xmlns:XMLNS_XMPP_MESSAGE_CARBONS];
|
|
[iq addChild:enable];
|
|
|
|
[xmppIDTracker addElement:iq
|
|
target:self
|
|
selector:@selector(disableMessageCarbonsIQ:withInfo:)
|
|
timeout:XMPPIDTrackerTimeoutNone];
|
|
|
|
[xmppStream sendElement:iq];
|
|
}
|
|
};
|
|
|
|
if (dispatch_get_specific(moduleQueueTag))
|
|
block();
|
|
else
|
|
dispatch_sync(moduleQueue, block);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark XMPPStream Delegate
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
|
|
{
|
|
XMPPLogTrace();
|
|
|
|
messageCarbonsEnabled = NO;
|
|
|
|
if(self.autoEnableMessageCarbons)
|
|
{
|
|
[self enableMessageCarbons];
|
|
}
|
|
}
|
|
|
|
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
|
|
{
|
|
messageCarbonsEnabled = NO;
|
|
}
|
|
|
|
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
|
|
{
|
|
[xmppIDTracker invokeForID:[iq elementID] withObject:iq];
|
|
|
|
return NO;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#pragma mark XMPPStream Delegate
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
- (void)enableMessageCarbonsIQ:(XMPPIQ *)iq withInfo:(XMPPBasicTrackingInfo *)trackerInfo
|
|
{
|
|
XMPPLogTrace();
|
|
|
|
if([iq isResultIQ])
|
|
{
|
|
messageCarbonsEnabled = YES;
|
|
}
|
|
}
|
|
|
|
- (void)disableMessageCarbonsIQ:(XMPPIQ *)iq withInfo:(XMPPBasicTrackingInfo *)trackerInfo
|
|
{
|
|
XMPPLogTrace();
|
|
|
|
if([iq isResultIQ])
|
|
{
|
|
messageCarbonsEnabled = NO;
|
|
}
|
|
}
|
|
|
|
- (XMPPMessage *)xmppStream:(XMPPStream *)sender willReceiveMessage:(XMPPMessage *)message
|
|
{
|
|
XMPPLogTrace();
|
|
|
|
if([message isTrustedMessageCarbonForMyJID:sender.myJID] ||
|
|
([message isMessageCarbon] && allowsUntrustedMessageCarbons))
|
|
{
|
|
BOOL outgoing = [message isSentMessageCarbon];
|
|
|
|
XMPPMessage *messageCarbonForwardedMessage = [message messageCarbonForwardedMessage];
|
|
|
|
[multicastDelegate xmppMessageCarbons:self
|
|
willReceiveMessage:messageCarbonForwardedMessage
|
|
outgoing:outgoing];
|
|
}
|
|
|
|
return message;
|
|
}
|
|
|
|
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
|
|
{
|
|
XMPPLogTrace();
|
|
|
|
if([message isTrustedMessageCarbonForMyJID:sender.myJID] ||
|
|
([message isMessageCarbon] && allowsUntrustedMessageCarbons))
|
|
{
|
|
BOOL outgoing = [message isSentMessageCarbon];
|
|
|
|
XMPPMessage *messageCarbonForwardedMessage = [message messageCarbonForwardedMessage];
|
|
|
|
[multicastDelegate xmppMessageCarbons:self
|
|
didReceiveMessage:messageCarbonForwardedMessage
|
|
outgoing:outgoing];
|
|
}
|
|
}
|
|
|
|
|
|
@end
|