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