src/sync.c
author Edouard Tisserant <edouard@pep-project.org>
Wed, 07 Dec 2016 15:39:06 +0100
branchENGINE-133
changeset 1462 b93663bfc7c6
parent 1460 66ceb5a7f718
child 1494 27ded4922ae2
permissions -rw-r--r--
sync: distinguish management pointer (for queuing sync_messages, i.e. sync job 'management') from obj pointer (for sending email messages, notifying user, alias sync 'object'), thus following original design convention
vb@572
     1
#include "pEp_internal.h"
vb@572
     2
vb@572
     3
#include <memory.h>
vb@572
     4
#include <assert.h>
vb@572
     5
vb@1116
     6
#include "asn1_helper.h"
vb@951
     7
#include "../asn.1/DeviceGroup-Protocol.h"
vb@951
     8
edouard@1460
     9
// receive_sync_msg is defined in the sync_impl
vb@1043
    10
vb@1043
    11
PEP_STATUS receive_sync_msg(
vb@1043
    12
        PEP_SESSION session,
edouard@1445
    13
        sync_msg_t *sync_msg,
edouard@1445
    14
        time_t *timeout
vb@1043
    15
    );
vb@572
    16
vb@572
    17
DYNAMIC_API PEP_STATUS register_sync_callbacks(
vb@599
    18
        PEP_SESSION session,
edouard@1462
    19
        void *management,
vb@597
    20
        messageToSend_t messageToSend,
edouard@1459
    21
        notifyHandshake_t notifyHandshake,
vb@1043
    22
        inject_sync_msg_t inject_sync_msg,
vb@1043
    23
        retrieve_next_sync_msg_t retrieve_next_sync_msg
vb@572
    24
    )
vb@572
    25
{
edouard@1462
    26
    assert(session && management && messageToSend && notifyHandshake && inject_sync_msg && retrieve_next_sync_msg);
edouard@1462
    27
    if (!(session && management && messageToSend && notifyHandshake && inject_sync_msg && retrieve_next_sync_msg))
edouard@1236
    28
        return PEP_ILLEGAL_VALUE;
edouard@1236
    29
markus@1259
    30
    pEpUUID uuid;
vb@1091
    31
    uuid_generate_random(uuid);
edouard@1236
    32
    uuid_unparse_upper(uuid, session->sync_uuid);
vb@1091
    33
edouard@1462
    34
    session->sync_management = management;
vb@604
    35
    session->messageToSend = messageToSend;
edouard@1459
    36
    session->notifyHandshake = notifyHandshake;
vb@1043
    37
    session->inject_sync_msg = inject_sync_msg;
vb@1043
    38
    session->retrieve_next_sync_msg = retrieve_next_sync_msg;
vb@572
    39
vb@976
    40
    // start state machine
vb@976
    41
    session->sync_state = InitState;
edouard@1445
    42
    time_t unused = 0;
edouard@1445
    43
    PEP_STATUS status = fsm_DeviceState_inject(session, Init, NULL, NULL, &unused);
vb@987
    44
    if (status != PEP_STATUS_OK)
vb@987
    45
        unregister_sync_callbacks(session);
vb@976
    46
vb@976
    47
    return status;
vb@572
    48
}
vb@572
    49
edouard@1236
    50
DYNAMIC_API PEP_STATUS attach_sync_session(
edouard@1236
    51
        PEP_SESSION session,
edouard@1236
    52
        PEP_SESSION sync_session
edouard@1236
    53
    )
edouard@1236
    54
{
edouard@1462
    55
    assert(session && sync_session && sync_session->sync_management && sync_session->inject_sync_msg );
edouard@1462
    56
    if (!(session && sync_session && sync_session->sync_management && sync_session->inject_sync_msg ))
edouard@1236
    57
        return PEP_ILLEGAL_VALUE;
edouard@1236
    58
edouard@1236
    59
    memcpy(session->sync_uuid, sync_session->sync_uuid, 37);
edouard@1236
    60
edouard@1462
    61
    session->sync_management = sync_session->sync_management;
edouard@1236
    62
    session->inject_sync_msg = sync_session->inject_sync_msg;
edouard@1236
    63
edouard@1236
    64
    return PEP_STATUS_OK;
edouard@1236
    65
}
edouard@1236
    66
edouard@1236
    67
DYNAMIC_API PEP_STATUS detach_sync_session(PEP_SESSION session)
edouard@1236
    68
{
edouard@1462
    69
    assert(session && session->sync_management && session->inject_sync_msg );
edouard@1462
    70
    if (!(session && session->sync_management && session->inject_sync_msg ))
edouard@1236
    71
        return PEP_ILLEGAL_VALUE;
edouard@1236
    72
edouard@1236
    73
    memset(session->sync_uuid, 0, 37);
edouard@1236
    74
edouard@1462
    75
    session->sync_management = NULL;
edouard@1236
    76
    session->inject_sync_msg = NULL;
edouard@1236
    77
edouard@1236
    78
    return PEP_STATUS_OK;
edouard@1236
    79
}
edouard@1236
    80
edouard@1167
    81
int call_inject_sync_msg(PEP_SESSION session, void *msg)
edouard@1167
    82
{
edouard@1462
    83
    if(session->inject_sync_msg && session->sync_management)
edouard@1462
    84
        return session->inject_sync_msg(msg, session->sync_management);
edouard@1167
    85
    else
edouard@1167
    86
       return PEP_SYNC_NO_INJECT_CALLBACK;
edouard@1167
    87
}
edouard@1167
    88
vb@572
    89
DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session) {
vb@986
    90
    // stop state machine
vb@986
    91
    session->sync_state = DeviceState_state_NONE;
vb@986
    92
vb@986
    93
    // unregister
edouard@1462
    94
    session->sync_management = NULL;
vb@604
    95
    session->messageToSend = NULL;
edouard@1459
    96
    session->notifyHandshake = NULL;
edouard@1167
    97
    session->inject_sync_msg = NULL;
vb@1043
    98
    session->retrieve_next_sync_msg = NULL;
vb@572
    99
}
vb@572
   100
vb@679
   101
DYNAMIC_API PEP_STATUS deliverHandshakeResult(
vb@609
   102
        PEP_SESSION session,
edouard@1160
   103
        Identity partner,
vb@609
   104
        sync_handshake_result result
vb@609
   105
    )
vb@609
   106
{
vb@609
   107
    assert(session);
vb@609
   108
    if (!session)
vb@609
   109
        return PEP_ILLEGAL_VALUE;
vb@609
   110
vb@1043
   111
    PEP_STATUS status = PEP_STATUS_OK;
vb@1043
   112
edouard@1330
   113
    DeviceState_event event;
edouard@1330
   114
    bool need_partner = false;
edouard@1330
   115
vb@609
   116
    switch (result) {
vb@609
   117
        case SYNC_HANDSHAKE_CANCEL:
edouard@1330
   118
            event = Cancel;
vb@609
   119
            break;
vb@609
   120
        case SYNC_HANDSHAKE_ACCEPTED:
edouard@1330
   121
        {
edouard@1330
   122
            event = HandshakeAccepted;
edouard@1330
   123
            need_partner = true;
vb@609
   124
            break;
edouard@1330
   125
        }
vb@609
   126
        case SYNC_HANDSHAKE_REJECTED:
edouard@1330
   127
        {
edouard@1330
   128
            event = HandshakeRejected;
edouard@1330
   129
            need_partner = true;
vb@609
   130
            break;
edouard@1330
   131
        }
vb@609
   132
        default:
vb@609
   133
            return PEP_ILLEGAL_VALUE;
vb@609
   134
    }
vb@609
   135
edouard@1330
   136
    pEp_identity *_partner = NULL;
edouard@1330
   137
    if(need_partner){
edouard@1330
   138
        _partner = identity_dup(partner);
edouard@1330
   139
        if (_partner == NULL)
edouard@1330
   140
            return PEP_OUT_OF_MEMORY;
edouard@1330
   141
    }
edouard@1330
   142
    status = inject_DeviceState_event(session, event, _partner, NULL);
edouard@1330
   143
vb@1043
   144
    return status;
vb@1043
   145
}
vb@1043
   146
vb@1043
   147
DYNAMIC_API PEP_STATUS do_sync_protocol(
vb@1043
   148
        PEP_SESSION session,
edouard@1462
   149
        void *obj
vb@1043
   150
    )
vb@1043
   151
{
edouard@1172
   152
    sync_msg_t *msg = NULL;
vb@1043
   153
    PEP_STATUS status = PEP_STATUS_OK;
edouard@1445
   154
    time_t timeout = 0;
vb@1043
   155
vb@1043
   156
    assert(session && session->retrieve_next_sync_msg);
edouard@1462
   157
    assert(obj);
vb@1043
   158
edouard@1462
   159
    if (!(session && session->retrieve_next_sync_msg) || !obj)
vb@1043
   160
        return PEP_ILLEGAL_VALUE;
vb@1043
   161
vb@1043
   162
    log_event(session, "sync_protocol thread started", "pEp sync protocol", NULL, NULL);
vb@1043
   163
edouard@1462
   164
    session->sync_obj = obj;
edouard@1462
   165
edouard@1446
   166
    while (true) 
vb@1043
   167
    {
edouard@1462
   168
        msg = (sync_msg_t *) session->retrieve_next_sync_msg(session->sync_management, &timeout);
edouard@1446
   169
        if(msg == NULL && timeout == 0)
edouard@1446
   170
            break;
edouard@1447
   171
        else if(msg == NULL && timeout != 0){
edouard@1447
   172
            status = fsm_DeviceState_inject(session, Timeout, NULL, NULL, &timeout);
edouard@1447
   173
            char buffer[MAX_LINELENGTH];
edouard@1447
   174
            memset(buffer, 0, MAX_LINELENGTH);
edouard@1447
   175
            snprintf(buffer, MAX_LINELENGTH, "problem with timeout event : %d\n", (int) status);
edouard@1447
   176
            log_event(session, buffer, "pEp sync protocol", NULL, NULL);
edouard@1446
   177
            continue;
edouard@1447
   178
        }
edouard@1446
   179
        else if ((status = receive_sync_msg(session, msg, &timeout) != PEP_STATUS_OK)) {
vb@1043
   180
            char buffer[MAX_LINELENGTH];
vb@1043
   181
            memset(buffer, 0, MAX_LINELENGTH);
vb@1043
   182
            snprintf(buffer, MAX_LINELENGTH, "problem with msg received: %d\n", (int) status);
vb@1043
   183
            log_event(session, buffer, "pEp sync protocol", NULL, NULL);
vb@1043
   184
        }
vb@1043
   185
    }
vb@1043
   186
vb@1043
   187
    log_event(session, "sync_protocol thread shutdown", "pEp sync protocol", NULL, NULL);
vb@1043
   188
edouard@1462
   189
    session->sync_obj = NULL;
edouard@1462
   190
vb@609
   191
    return PEP_STATUS_OK;
vb@609
   192
}
vb@609
   193
vb@1116
   194
DYNAMIC_API PEP_STATUS decode_sync_msg(
vb@1116
   195
        const char *data,
vb@1116
   196
        size_t size,
vb@1116
   197
        char **text
vb@1116
   198
    )
vb@1116
   199
{
vb@1116
   200
    PEP_STATUS status = PEP_STATUS_OK;
vb@1116
   201
vb@1116
   202
    assert(data && text);
vb@1116
   203
    if (!(data && text))
vb@1116
   204
        return PEP_ILLEGAL_VALUE;
vb@1116
   205
vb@1116
   206
    *text = NULL;
vb@1116
   207
vb@1116
   208
    DeviceGroup_Protocol_t *msg = NULL;
vb@1116
   209
    uper_decode_complete(NULL, &asn_DEF_DeviceGroup_Protocol, (void **) &msg,
vb@1116
   210
            data, size);
vb@1116
   211
    if (!msg)
vb@1116
   212
        return PEP_SYNC_ILLEGAL_MESSAGE;
vb@1116
   213
vb@1116
   214
    growing_buf_t *dst = new_growing_buf();
vb@1116
   215
    if (!dst) {
vb@1116
   216
        status = PEP_OUT_OF_MEMORY;
vb@1116
   217
        goto the_end;
vb@1116
   218
    }
vb@1116
   219
vb@1116
   220
    asn_enc_rval_t er = xer_encode(&asn_DEF_DeviceGroup_Protocol, msg,
vb@1117
   221
            XER_F_BASIC, (asn_app_consume_bytes_f *) consume_bytes, (void *) dst);
vb@1116
   222
    if (er.encoded == -1) {
vb@1128
   223
        status = PEP_CANNOT_ENCODE;
vb@1116
   224
        goto the_end;
vb@1116
   225
    }
vb@1116
   226
vb@1116
   227
    *text = dst->data;
vb@1116
   228
    dst->data = NULL;
vb@1116
   229
vb@1116
   230
the_end:
vb@1116
   231
    free_growing_buf(dst);
vb@1116
   232
    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
vb@1116
   233
    return status;
vb@1116
   234
}
vb@1116
   235
vb@1128
   236
DYNAMIC_API PEP_STATUS encode_sync_msg(
vb@1128
   237
        const char *text,
vb@1128
   238
        char **data,
vb@1128
   239
        size_t *size
vb@1128
   240
    )
vb@1128
   241
{
vb@1128
   242
    PEP_STATUS status = PEP_STATUS_OK;
vb@1128
   243
vb@1128
   244
    assert(text && data && size);
vb@1128
   245
    if (!(text && data && size))
vb@1128
   246
        return PEP_ILLEGAL_VALUE;
vb@1128
   247
vb@1129
   248
    *data = NULL;
vb@1129
   249
    *size = 0;
vb@1129
   250
vb@1128
   251
    DeviceGroup_Protocol_t *msg = NULL;
vb@1128
   252
    asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_DeviceGroup_Protocol,
vb@1128
   253
            (void **) &msg, (const void *) text, strlen(text));
vb@1128
   254
    if (dr.code != RC_OK) {
vb@1128
   255
        status = PEP_SYNC_ILLEGAL_MESSAGE;
vb@1128
   256
        goto the_end;
vb@1128
   257
    }
vb@1128
   258
vb@1128
   259
    char *payload = NULL;
vb@1128
   260
    ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_DeviceGroup_Protocol,
vb@1128
   261
            NULL, msg, (void **) &payload);
vb@1128
   262
    if (_size == -1) {
vb@1128
   263
        status = PEP_CANNOT_ENCODE;
vb@1128
   264
        goto the_end;
vb@1128
   265
    }
vb@1128
   266
vb@1128
   267
    *data = payload;
vb@1128
   268
    *size = (size_t) _size;
vb@1128
   269
vb@1128
   270
the_end:
vb@1128
   271
    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
vb@1128
   272
    return status;
vb@1128
   273
}
vb@1128
   274