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