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