pEpObjCAdapter/PEPSync.m
author Dirk Zimmermann <dirk@pep-project.org>
Tue, 30 Oct 2018 14:50:53 +0100
branchIOSAD-103
changeset 732 defc14d75ec9
parent 730 831b6ad3e204
child 733 41104554955f
permissions -rw-r--r--
IOSAD-103 rename
dirk@681
     1
//
dirk@681
     2
//  PEPSync.m
dirk@681
     3
//  pEpObjCAdapter
dirk@681
     4
//
dirk@681
     5
//  Created by Dirk Zimmermann on 04.10.18.
dirk@681
     6
//  Copyright © 2018 p≡p. All rights reserved.
dirk@681
     7
//
dirk@681
     8
dirk@681
     9
#import "PEPSync.h"
dirk@681
    10
dirk@732
    11
#import "PEPSendMessageDelegate.h"
dirk@704
    12
#import "PEPNotifyHandshakeDelegate.h"
dirk@688
    13
#import "PEPMessageUtil.h"
dirk@688
    14
#import "PEPMessage.h"
dirk@700
    15
#import "PEPQueue.h"
dirk@725
    16
#import "PEPLock.h"
dirk@725
    17
#import "PEPObjCAdapter.h"
dirk@725
    18
#import "NSError+PEP.h"
dirk@686
    19
dirk@693
    20
// MARK: - Declare internals
dirk@693
    21
dirk@726
    22
typedef PEP_STATUS (* t_messageToSendCallback)(struct _message *msg);
dirk@726
    23
typedef int (* t_injectSyncCallback)(SYNC_EVENT ev, void *management);
dirk@726
    24
dirk@691
    25
@interface PEPSync ()
dirk@691
    26
dirk@699
    27
+ (PEPSync * _Nullable)instance;
dirk@691
    28
dirk@732
    29
@property (nonatomic, nullable, weak) id<PEPSendMessageDelegate> sendMessageDelegate;
dirk@704
    30
@property (nonatomic, nullable, weak) id<PEPNotifyHandshakeDelegate> notifyHandshakeDelegate;
dirk@700
    31
@property (nonatomic, nonnull) PEPQueue *queue;
dirk@720
    32
@property (nonatomic, nullable) NSThread *syncThread;
dirk@700
    33
dirk@726
    34
/**
dirk@726
    35
 @Return: The callback for message sending that should be used on every session init.
dirk@726
    36
 */
dirk@726
    37
+ (t_messageToSendCallback)messageToSendCallback;
dirk@726
    38
dirk@726
    39
/**
dirk@726
    40
 @Return: The callback for injectiong sync messages that should be used on every session init.
dirk@726
    41
 */
dirk@726
    42
+ (t_injectSyncCallback)injectSyncCallback;
dirk@726
    43
dirk@700
    44
- (int)injectSyncEvent:(SYNC_EVENT)event;
dirk@730
    45
dirk@730
    46
- (PEP_STATUS)notifyHandshake:(pEp_identity *)me
dirk@730
    47
                      partner:(pEp_identity *)partner
dirk@730
    48
                       signal:(sync_handshake_signal)signal;
dirk@730
    49
dirk@724
    50
- (SYNC_EVENT)retrieveNextSyncEvent:(time_t)threshold;
dirk@692
    51
dirk@691
    52
@end
dirk@691
    53
dirk@728
    54
// MARK: - Callbacks called by the engine, used in session init
dirk@693
    55
dirk@722
    56
static PEP_STATUS messageToSendObjc(struct _message *msg)
dirk@682
    57
{
dirk@732
    58
    id<PEPSendMessageDelegate> delegate = [[PEPSync instance] sendMessageDelegate];
dirk@688
    59
    if (delegate) {
dirk@688
    60
        PEPMessage *theMessage = pEpMessageFromStruct(msg);
dirk@688
    61
        return [delegate sendMessage:theMessage];
dirk@689
    62
    } else {
dirk@689
    63
        return PEP_SYNC_NO_MESSAGE_SEND_CALLBACK;
dirk@688
    64
    }
dirk@682
    65
}
dirk@682
    66
dirk@722
    67
static int inject_sync_eventObjc(SYNC_EVENT ev, void *management)
dirk@682
    68
{
dirk@700
    69
    PEPSync *pEpSync = [PEPSync instance];
dirk@700
    70
dirk@700
    71
    if (!pEpSync) {
dirk@700
    72
        pEpSync = (PEPSync *) CFBridgingRelease(management);
dirk@698
    73
    }
dirk@700
    74
dirk@700
    75
    if (pEpSync) {
dirk@700
    76
        return [pEpSync injectSyncEvent:ev];
dirk@700
    77
    } else {
dirk@700
    78
        return 1;
dirk@700
    79
    }
dirk@682
    80
}
dirk@682
    81
dirk@728
    82
// MARK: - Callbacks called by the engine, used in register_sync_callbacks
dirk@728
    83
dirk@729
    84
static PEP_STATUS notifyHandshake(pEp_identity *me,
dirk@729
    85
                                  pEp_identity *partner,
dirk@729
    86
                                  sync_handshake_signal signal)
dirk@729
    87
{
dirk@730
    88
    PEPSync *sync = [PEPSync instance];
dirk@730
    89
    return [sync notifyHandshake:me partner:partner signal:signal];
dirk@729
    90
}
dirk@729
    91
dirk@724
    92
static SYNC_EVENT retrieve_next_sync_event(void *management, time_t threshold)
dirk@724
    93
{
dirk@724
    94
    PEPSync *sync = (PEPSync *) CFBridgingRelease(management);
dirk@724
    95
    return [sync retrieveNextSyncEvent:threshold];
dirk@724
    96
}
dirk@724
    97
dirk@693
    98
// MARK: - Internal globals
dirk@693
    99
dirk@699
   100
static __weak PEPSync *s_pEpSync;
dirk@686
   101
dirk@720
   102
// MARK: - Public PEPSync class
dirk@693
   103
dirk@681
   104
@implementation PEPSync
dirk@681
   105
dirk@722
   106
+ (t_messageToSendCallback)messageToSendCallback
dirk@722
   107
{
dirk@722
   108
    return messageToSendObjc;
dirk@722
   109
}
dirk@722
   110
dirk@722
   111
+ (t_injectSyncCallback)injectSyncCallback
dirk@722
   112
{
dirk@722
   113
    return inject_sync_eventObjc;
dirk@722
   114
}
dirk@722
   115
dirk@725
   116
+ (PEP_SESSION)createSession:(NSError **)error
dirk@725
   117
{
dirk@725
   118
    [PEPSync setupTrustWordsDB];
dirk@725
   119
dirk@725
   120
    PEP_SESSION session = NULL;
dirk@725
   121
dirk@725
   122
    [PEPLock lockWrite];
dirk@725
   123
    PEP_STATUS status = init(&session,
dirk@725
   124
                             [PEPSync messageToSendCallback],
dirk@725
   125
                             [PEPSync injectSyncCallback]);
dirk@725
   126
    [PEPLock unlockWrite];
dirk@725
   127
dirk@725
   128
    if (status != PEP_STATUS_OK) {
dirk@725
   129
        if (error) {
dirk@725
   130
            *error = [NSError errorWithPEPStatus:status];
dirk@725
   131
        }
dirk@725
   132
        return nil;
dirk@725
   133
    }
dirk@725
   134
dirk@725
   135
    return session;
dirk@725
   136
}
dirk@725
   137
dirk@725
   138
+ (void)releaseSession:(PEP_SESSION)session
dirk@725
   139
{
dirk@725
   140
    [PEPLock lockWrite];
dirk@725
   141
    release(session);
dirk@725
   142
    [PEPLock unlockWrite];
dirk@725
   143
}
dirk@725
   144
dirk@732
   145
- (instancetype)initWithSendMessageDelegate:(id<PEPSendMessageDelegate>
dirk@732
   146
                                             _Nonnull)sendMessageDelegate
dirk@732
   147
                    notifyHandshakeDelegate:(id<PEPNotifyHandshakeDelegate>
dirk@732
   148
                                             _Nonnull)notifyHandshakeDelegate
dirk@695
   149
{
dirk@695
   150
    if (self = [super init]) {
dirk@732
   151
        _sendMessageDelegate = sendMessageDelegate;
dirk@699
   152
        _notifyHandshakeDelegate = notifyHandshakeDelegate;
dirk@700
   153
        _queue = [PEPQueue new];
dirk@699
   154
        s_pEpSync = self;
dirk@695
   155
    }
dirk@695
   156
    return self;
dirk@695
   157
}
dirk@695
   158
dirk@720
   159
- (void)startup
dirk@720
   160
{
dirk@720
   161
    NSThread *theSyncThread = [[NSThread alloc] initWithTarget:self
dirk@720
   162
                                                      selector:@selector(syncThreadLoop:)
dirk@720
   163
                                                        object:nil];
dirk@720
   164
    self.syncThread = theSyncThread;
dirk@720
   165
}
dirk@720
   166
dirk@701
   167
- (void)shutdown
dirk@701
   168
{
dirk@701
   169
}
dirk@701
   170
dirk@720
   171
// MARK: - Private
dirk@720
   172
dirk@723
   173
+ (PEPSync * _Nullable)instance
dirk@723
   174
{
dirk@723
   175
    return s_pEpSync;
dirk@723
   176
}
dirk@723
   177
dirk@725
   178
+ (void)setupTrustWordsDB
dirk@725
   179
{
dirk@725
   180
    static dispatch_once_t once;
dirk@725
   181
    dispatch_once(&once, ^{
dirk@725
   182
        [PEPObjCAdapter setupTrustWordsDB:[NSBundle bundleForClass:[self class]]];
dirk@725
   183
    });
dirk@725
   184
}
dirk@725
   185
dirk@720
   186
- (void)syncThreadLoop:(id)object {
dirk@727
   187
    NSError *error = nil;
dirk@727
   188
    PEP_SESSION session = [PEPSync createSession:&error];
dirk@727
   189
dirk@727
   190
    if (session) {
dirk@727
   191
    } else {
dirk@727
   192
    }
dirk@727
   193
dirk@727
   194
    [PEPSync releaseSession:session];
dirk@720
   195
}
dirk@720
   196
dirk@700
   197
- (int)injectSyncEvent:(SYNC_EVENT)event
dirk@700
   198
{
dirk@700
   199
    [self.queue enqueue:[NSValue valueWithBytes:&event objCType:@encode(SYNC_EVENT)]];
dirk@700
   200
    return 0;
dirk@700
   201
}
dirk@700
   202
dirk@730
   203
- (PEP_STATUS)notifyHandshake:(pEp_identity *)me
dirk@730
   204
                      partner:(pEp_identity *)partner
dirk@730
   205
                       signal:(sync_handshake_signal)signal
dirk@730
   206
{
dirk@730
   207
    if (self.notifyHandshakeDelegate) {
dirk@730
   208
        PEPIdentity *meIdentity = PEP_identityFromStruct(me);
dirk@730
   209
        PEPIdentity *partnerIdentity = PEP_identityFromStruct(partner);
dirk@732
   210
        return [self.notifyHandshakeDelegate notifyHandshake:NULL
dirk@730
   211
                                                          me:meIdentity
dirk@730
   212
                                                     partner:partnerIdentity
dirk@730
   213
                                                      signal:signal];
dirk@730
   214
    } else {
dirk@730
   215
        return PEP_SYNC_NO_NOTIFY_CALLBACK;
dirk@730
   216
    }
dirk@730
   217
}
dirk@730
   218
dirk@724
   219
- (SYNC_EVENT)retrieveNextSyncEvent:(time_t)threshold
dirk@724
   220
{
dirk@724
   221
    NSValue *value = [self.queue timedDequeue:&threshold];
dirk@724
   222
    if (value) {
dirk@724
   223
        SYNC_EVENT event;
dirk@724
   224
        [value getValue:&event];
dirk@724
   225
        return event;
dirk@724
   226
    } else {
dirk@724
   227
        return new_sync_timeout_event();
dirk@724
   228
    }
dirk@724
   229
}
dirk@724
   230
dirk@681
   231
@end