src/sync.c
author Edouard Tisserant <edouard@pep-project.org>
Mon, 24 Oct 2016 20:48:00 +0200
changeset 1330 0c55ede4d522
parent 1259 e5bc79871fbb
child 1445 5d233bcdde76
permissions -rw-r--r--
sync : allow non-sync session to deliver handshake results
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
markus@1259
    29
    pEpUUID uuid;
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
edouard@1330
   111
    DeviceState_event event;
edouard@1330
   112
    bool need_partner = false;
edouard@1330
   113
vb@609
   114
    switch (result) {
vb@609
   115
        case SYNC_HANDSHAKE_CANCEL:
edouard@1330
   116
            event = Cancel;
vb@609
   117
            break;
vb@609
   118
        case SYNC_HANDSHAKE_ACCEPTED:
edouard@1330
   119
        {
edouard@1330
   120
            event = HandshakeAccepted;
edouard@1330
   121
            need_partner = true;
vb@609
   122
            break;
edouard@1330
   123
        }
vb@609
   124
        case SYNC_HANDSHAKE_REJECTED:
edouard@1330
   125
        {
edouard@1330
   126
            event = HandshakeRejected;
edouard@1330
   127
            need_partner = true;
vb@609
   128
            break;
edouard@1330
   129
        }
vb@609
   130
        default:
vb@609
   131
            return PEP_ILLEGAL_VALUE;
vb@609
   132
    }
vb@609
   133
edouard@1330
   134
    pEp_identity *_partner = NULL;
edouard@1330
   135
    if(need_partner){
edouard@1330
   136
        _partner = identity_dup(partner);
edouard@1330
   137
        if (_partner == NULL)
edouard@1330
   138
            return PEP_OUT_OF_MEMORY;
edouard@1330
   139
    }
edouard@1330
   140
    status = inject_DeviceState_event(session, event, _partner, NULL);
edouard@1330
   141
vb@1043
   142
    return status;
vb@1043
   143
}
vb@1043
   144
vb@1043
   145
DYNAMIC_API PEP_STATUS do_sync_protocol(
vb@1043
   146
        PEP_SESSION session,
vb@1043
   147
        void *management
vb@1043
   148
    )
vb@1043
   149
{
edouard@1172
   150
    sync_msg_t *msg = NULL;
vb@1043
   151
    PEP_STATUS status = PEP_STATUS_OK;
vb@1043
   152
vb@1043
   153
    assert(session && session->retrieve_next_sync_msg);
vb@1043
   154
    assert(management);
vb@1043
   155
vb@1043
   156
    if (!(session && session->retrieve_next_sync_msg) || !management)
vb@1043
   157
        return PEP_ILLEGAL_VALUE;
vb@1043
   158
vb@1043
   159
    log_event(session, "sync_protocol thread started", "pEp sync protocol", NULL, NULL);
vb@1043
   160
edouard@1172
   161
    while ((msg = (sync_msg_t *) session->retrieve_next_sync_msg(management))) 
vb@1043
   162
    {
vb@1043
   163
        if ((status = receive_sync_msg(session, msg) != PEP_STATUS_OK)) {
vb@1043
   164
            char buffer[MAX_LINELENGTH];
vb@1043
   165
            memset(buffer, 0, MAX_LINELENGTH);
vb@1043
   166
            snprintf(buffer, MAX_LINELENGTH, "problem with msg received: %d\n", (int) status);
vb@1043
   167
            log_event(session, buffer, "pEp sync protocol", NULL, NULL);
vb@1043
   168
        }
vb@1043
   169
    }
vb@1043
   170
vb@1043
   171
    log_event(session, "sync_protocol thread shutdown", "pEp sync protocol", NULL, NULL);
vb@1043
   172
vb@609
   173
    return PEP_STATUS_OK;
vb@609
   174
}
vb@609
   175
vb@1116
   176
DYNAMIC_API PEP_STATUS decode_sync_msg(
vb@1116
   177
        const char *data,
vb@1116
   178
        size_t size,
vb@1116
   179
        char **text
vb@1116
   180
    )
vb@1116
   181
{
vb@1116
   182
    PEP_STATUS status = PEP_STATUS_OK;
vb@1116
   183
vb@1116
   184
    assert(data && text);
vb@1116
   185
    if (!(data && text))
vb@1116
   186
        return PEP_ILLEGAL_VALUE;
vb@1116
   187
vb@1116
   188
    *text = NULL;
vb@1116
   189
vb@1116
   190
    DeviceGroup_Protocol_t *msg = NULL;
vb@1116
   191
    uper_decode_complete(NULL, &asn_DEF_DeviceGroup_Protocol, (void **) &msg,
vb@1116
   192
            data, size);
vb@1116
   193
    if (!msg)
vb@1116
   194
        return PEP_SYNC_ILLEGAL_MESSAGE;
vb@1116
   195
vb@1116
   196
    growing_buf_t *dst = new_growing_buf();
vb@1116
   197
    if (!dst) {
vb@1116
   198
        status = PEP_OUT_OF_MEMORY;
vb@1116
   199
        goto the_end;
vb@1116
   200
    }
vb@1116
   201
vb@1116
   202
    asn_enc_rval_t er = xer_encode(&asn_DEF_DeviceGroup_Protocol, msg,
vb@1117
   203
            XER_F_BASIC, (asn_app_consume_bytes_f *) consume_bytes, (void *) dst);
vb@1116
   204
    if (er.encoded == -1) {
vb@1128
   205
        status = PEP_CANNOT_ENCODE;
vb@1116
   206
        goto the_end;
vb@1116
   207
    }
vb@1116
   208
vb@1116
   209
    *text = dst->data;
vb@1116
   210
    dst->data = NULL;
vb@1116
   211
vb@1116
   212
the_end:
vb@1116
   213
    free_growing_buf(dst);
vb@1116
   214
    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
vb@1116
   215
    return status;
vb@1116
   216
}
vb@1116
   217
vb@1128
   218
DYNAMIC_API PEP_STATUS encode_sync_msg(
vb@1128
   219
        const char *text,
vb@1128
   220
        char **data,
vb@1128
   221
        size_t *size
vb@1128
   222
    )
vb@1128
   223
{
vb@1128
   224
    PEP_STATUS status = PEP_STATUS_OK;
vb@1128
   225
vb@1128
   226
    assert(text && data && size);
vb@1128
   227
    if (!(text && data && size))
vb@1128
   228
        return PEP_ILLEGAL_VALUE;
vb@1128
   229
vb@1129
   230
    *data = NULL;
vb@1129
   231
    *size = 0;
vb@1129
   232
vb@1128
   233
    DeviceGroup_Protocol_t *msg = NULL;
vb@1128
   234
    asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_DeviceGroup_Protocol,
vb@1128
   235
            (void **) &msg, (const void *) text, strlen(text));
vb@1128
   236
    if (dr.code != RC_OK) {
vb@1128
   237
        status = PEP_SYNC_ILLEGAL_MESSAGE;
vb@1128
   238
        goto the_end;
vb@1128
   239
    }
vb@1128
   240
vb@1128
   241
    char *payload = NULL;
vb@1128
   242
    ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_DeviceGroup_Protocol,
vb@1128
   243
            NULL, msg, (void **) &payload);
vb@1128
   244
    if (_size == -1) {
vb@1128
   245
        status = PEP_CANNOT_ENCODE;
vb@1128
   246
        goto the_end;
vb@1128
   247
    }
vb@1128
   248
vb@1128
   249
    *data = payload;
vb@1128
   250
    *size = (size_t) _size;
vb@1128
   251
vb@1128
   252
the_end:
vb@1128
   253
    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
vb@1128
   254
    return status;
vb@1128
   255
}
vb@1128
   256