src/sync.c
author Edouard Tisserant <edouard@pep-project.org>
Mon, 03 Oct 2016 19:08:15 +0200
branchkeysync
changeset 1236 991afc1aa2a1
parent 1173 5a8002f941e0
child 1259 e5bc79871fbb
permissions -rw-r--r--
sync : attach_sync_session
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
vb@1043
     9
// receive_sync_msg is defined in the sync_actions
vb@1043
    10
vb@1043
    11
PEP_STATUS receive_sync_msg(
vb@1043
    12
        PEP_SESSION session,
edouard@1173
    13
        sync_msg_t *sync_msg
vb@1043
    14
    );
vb@572
    15
vb@572
    16
DYNAMIC_API PEP_STATUS register_sync_callbacks(
vb@599
    17
        PEP_SESSION session,
vb@599
    18
        void *obj,
vb@597
    19
        messageToSend_t messageToSend,
vb@1043
    20
        showHandshake_t showHandshake,
vb@1043
    21
        inject_sync_msg_t inject_sync_msg,
vb@1043
    22
        retrieve_next_sync_msg_t retrieve_next_sync_msg
vb@572
    23
    )
vb@572
    24
{
edouard@1236
    25
    assert(session && obj && messageToSend && showHandshake && inject_sync_msg && retrieve_next_sync_msg);
edouard@1236
    26
    if (!(session && obj && messageToSend && showHandshake && inject_sync_msg && retrieve_next_sync_msg))
edouard@1236
    27
        return PEP_ILLEGAL_VALUE;
edouard@1236
    28
vb@1091
    29
    unsigned char uuid[16];
vb@1091
    30
    uuid_generate_random(uuid);
edouard@1236
    31
    uuid_unparse_upper(uuid, session->sync_uuid);
vb@1091
    32
vb@599
    33
    session->sync_obj = obj;
vb@604
    34
    session->messageToSend = messageToSend;
vb@604
    35
    session->showHandshake = showHandshake;
vb@1043
    36
    session->inject_sync_msg = inject_sync_msg;
vb@1043
    37
    session->retrieve_next_sync_msg = retrieve_next_sync_msg;
vb@572
    38
vb@976
    39
    // start state machine
vb@976
    40
    session->sync_state = InitState;
vb@976
    41
    PEP_STATUS status = fsm_DeviceState_inject(session, Init, NULL, NULL);
vb@987
    42
    if (status != PEP_STATUS_OK)
vb@987
    43
        unregister_sync_callbacks(session);
vb@976
    44
vb@976
    45
    return status;
vb@572
    46
}
vb@572
    47
edouard@1236
    48
DYNAMIC_API PEP_STATUS attach_sync_session(
edouard@1236
    49
        PEP_SESSION session,
edouard@1236
    50
        PEP_SESSION sync_session
edouard@1236
    51
    )
edouard@1236
    52
{
edouard@1236
    53
    assert(session && sync_session && sync_session->sync_obj && sync_session->inject_sync_msg );
edouard@1236
    54
    if (!(session && sync_session && sync_session->sync_obj && sync_session->inject_sync_msg ))
edouard@1236
    55
        return PEP_ILLEGAL_VALUE;
edouard@1236
    56
edouard@1236
    57
    memcpy(session->sync_uuid, sync_session->sync_uuid, 37);
edouard@1236
    58
edouard@1236
    59
    session->sync_obj = sync_session->sync_obj;
edouard@1236
    60
    session->inject_sync_msg = sync_session->inject_sync_msg;
edouard@1236
    61
edouard@1236
    62
    return PEP_STATUS_OK;
edouard@1236
    63
}
edouard@1236
    64
edouard@1236
    65
DYNAMIC_API PEP_STATUS detach_sync_session(PEP_SESSION session)
edouard@1236
    66
{
edouard@1236
    67
    assert(session && session->sync_obj && session->inject_sync_msg );
edouard@1236
    68
    if (!(session && session->sync_obj && session->inject_sync_msg ))
edouard@1236
    69
        return PEP_ILLEGAL_VALUE;
edouard@1236
    70
edouard@1236
    71
    memset(session->sync_uuid, 0, 37);
edouard@1236
    72
edouard@1236
    73
    session->sync_obj = NULL;
edouard@1236
    74
    session->inject_sync_msg = NULL;
edouard@1236
    75
edouard@1236
    76
    return PEP_STATUS_OK;
edouard@1236
    77
}
edouard@1236
    78
edouard@1167
    79
int call_inject_sync_msg(PEP_SESSION session, void *msg)
edouard@1167
    80
{
edouard@1167
    81
    if(session->inject_sync_msg && session->sync_obj)
edouard@1167
    82
        return session->inject_sync_msg(msg, session->sync_obj);
edouard@1167
    83
    else
edouard@1167
    84
       return PEP_SYNC_NO_INJECT_CALLBACK;
edouard@1167
    85
}
edouard@1167
    86
vb@572
    87
DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session) {
vb@986
    88
    // stop state machine
vb@986
    89
    session->sync_state = DeviceState_state_NONE;
vb@986
    90
vb@986
    91
    // unregister
vb@602
    92
    session->sync_obj = NULL;
vb@604
    93
    session->messageToSend = NULL;
vb@604
    94
    session->showHandshake = NULL;
edouard@1167
    95
    session->inject_sync_msg = NULL;
vb@1043
    96
    session->retrieve_next_sync_msg = NULL;
vb@572
    97
}
vb@572
    98
vb@679
    99
DYNAMIC_API PEP_STATUS deliverHandshakeResult(
vb@609
   100
        PEP_SESSION session,
edouard@1160
   101
        Identity partner,
vb@609
   102
        sync_handshake_result result
vb@609
   103
    )
vb@609
   104
{
vb@609
   105
    assert(session);
vb@609
   106
    if (!session)
vb@609
   107
        return PEP_ILLEGAL_VALUE;
vb@609
   108
vb@1043
   109
    PEP_STATUS status = PEP_STATUS_OK;
vb@1043
   110
vb@609
   111
    switch (result) {
vb@609
   112
        case SYNC_HANDSHAKE_CANCEL:
vb@1043
   113
            status = fsm_DeviceState_inject(session, Cancel, NULL, 0);
vb@609
   114
            break;
vb@609
   115
        case SYNC_HANDSHAKE_ACCEPTED:
edouard@1160
   116
            status = fsm_DeviceState_inject(session, HandshakeAccepted, partner, 0);
vb@609
   117
            break;
vb@609
   118
        case SYNC_HANDSHAKE_REJECTED:
edouard@1160
   119
            status = fsm_DeviceState_inject(session, HandshakeRejected, partner, 0);
vb@609
   120
            break;
vb@609
   121
        default:
vb@609
   122
            return PEP_ILLEGAL_VALUE;
vb@609
   123
    }
vb@609
   124
vb@1043
   125
    return status;
vb@1043
   126
}
vb@1043
   127
vb@1043
   128
DYNAMIC_API PEP_STATUS do_sync_protocol(
vb@1043
   129
        PEP_SESSION session,
vb@1043
   130
        void *management
vb@1043
   131
    )
vb@1043
   132
{
edouard@1172
   133
    sync_msg_t *msg = NULL;
vb@1043
   134
    PEP_STATUS status = PEP_STATUS_OK;
vb@1043
   135
vb@1043
   136
    assert(session && session->retrieve_next_sync_msg);
vb@1043
   137
    assert(management);
vb@1043
   138
vb@1043
   139
    if (!(session && session->retrieve_next_sync_msg) || !management)
vb@1043
   140
        return PEP_ILLEGAL_VALUE;
vb@1043
   141
vb@1043
   142
    log_event(session, "sync_protocol thread started", "pEp sync protocol", NULL, NULL);
vb@1043
   143
edouard@1172
   144
    while ((msg = (sync_msg_t *) session->retrieve_next_sync_msg(management))) 
vb@1043
   145
    {
vb@1043
   146
        if ((status = receive_sync_msg(session, msg) != PEP_STATUS_OK)) {
vb@1043
   147
            char buffer[MAX_LINELENGTH];
vb@1043
   148
            memset(buffer, 0, MAX_LINELENGTH);
vb@1043
   149
            snprintf(buffer, MAX_LINELENGTH, "problem with msg received: %d\n", (int) status);
vb@1043
   150
            log_event(session, buffer, "pEp sync protocol", NULL, NULL);
vb@1043
   151
        }
vb@1043
   152
    }
vb@1043
   153
vb@1043
   154
    log_event(session, "sync_protocol thread shutdown", "pEp sync protocol", NULL, NULL);
vb@1043
   155
vb@609
   156
    return PEP_STATUS_OK;
vb@609
   157
}
vb@609
   158
vb@1116
   159
DYNAMIC_API PEP_STATUS decode_sync_msg(
vb@1116
   160
        const char *data,
vb@1116
   161
        size_t size,
vb@1116
   162
        char **text
vb@1116
   163
    )
vb@1116
   164
{
vb@1116
   165
    PEP_STATUS status = PEP_STATUS_OK;
vb@1116
   166
vb@1116
   167
    assert(data && text);
vb@1116
   168
    if (!(data && text))
vb@1116
   169
        return PEP_ILLEGAL_VALUE;
vb@1116
   170
vb@1116
   171
    *text = NULL;
vb@1116
   172
vb@1116
   173
    DeviceGroup_Protocol_t *msg = NULL;
vb@1116
   174
    uper_decode_complete(NULL, &asn_DEF_DeviceGroup_Protocol, (void **) &msg,
vb@1116
   175
            data, size);
vb@1116
   176
    if (!msg)
vb@1116
   177
        return PEP_SYNC_ILLEGAL_MESSAGE;
vb@1116
   178
vb@1116
   179
    growing_buf_t *dst = new_growing_buf();
vb@1116
   180
    if (!dst) {
vb@1116
   181
        status = PEP_OUT_OF_MEMORY;
vb@1116
   182
        goto the_end;
vb@1116
   183
    }
vb@1116
   184
vb@1116
   185
    asn_enc_rval_t er = xer_encode(&asn_DEF_DeviceGroup_Protocol, msg,
vb@1117
   186
            XER_F_BASIC, (asn_app_consume_bytes_f *) consume_bytes, (void *) dst);
vb@1116
   187
    if (er.encoded == -1) {
vb@1128
   188
        status = PEP_CANNOT_ENCODE;
vb@1116
   189
        goto the_end;
vb@1116
   190
    }
vb@1116
   191
vb@1116
   192
    *text = dst->data;
vb@1116
   193
    dst->data = NULL;
vb@1116
   194
vb@1116
   195
the_end:
vb@1116
   196
    free_growing_buf(dst);
vb@1116
   197
    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
vb@1116
   198
    return status;
vb@1116
   199
}
vb@1116
   200
vb@1128
   201
DYNAMIC_API PEP_STATUS encode_sync_msg(
vb@1128
   202
        const char *text,
vb@1128
   203
        char **data,
vb@1128
   204
        size_t *size
vb@1128
   205
    )
vb@1128
   206
{
vb@1128
   207
    PEP_STATUS status = PEP_STATUS_OK;
vb@1128
   208
vb@1128
   209
    assert(text && data && size);
vb@1128
   210
    if (!(text && data && size))
vb@1128
   211
        return PEP_ILLEGAL_VALUE;
vb@1128
   212
vb@1129
   213
    *data = NULL;
vb@1129
   214
    *size = 0;
vb@1129
   215
vb@1128
   216
    DeviceGroup_Protocol_t *msg = NULL;
vb@1128
   217
    asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_DeviceGroup_Protocol,
vb@1128
   218
            (void **) &msg, (const void *) text, strlen(text));
vb@1128
   219
    if (dr.code != RC_OK) {
vb@1128
   220
        status = PEP_SYNC_ILLEGAL_MESSAGE;
vb@1128
   221
        goto the_end;
vb@1128
   222
    }
vb@1128
   223
vb@1128
   224
    char *payload = NULL;
vb@1128
   225
    ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_DeviceGroup_Protocol,
vb@1128
   226
            NULL, msg, (void **) &payload);
vb@1128
   227
    if (_size == -1) {
vb@1128
   228
        status = PEP_CANNOT_ENCODE;
vb@1128
   229
        goto the_end;
vb@1128
   230
    }
vb@1128
   231
vb@1128
   232
    *data = payload;
vb@1128
   233
    *size = (size_t) _size;
vb@1128
   234
vb@1128
   235
the_end:
vb@1128
   236
    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
vb@1128
   237
    return status;
vb@1128
   238
}
vb@1128
   239