src/sync.c
author Volker Birk <vb@pep.foundation>
Fri, 02 Sep 2016 16:54:55 +0200
branchkeysync
changeset 1129 d928a7221b96
parent 1128 51ea505b60e6
child 1160 a176739cd3c3
permissions -rw-r--r--
adding safeguards
     1 #include "pEp_internal.h"
     2 
     3 #include <memory.h>
     4 #include <assert.h>
     5 
     6 #include "asn1_helper.h"
     7 #include "../asn.1/DeviceGroup-Protocol.h"
     8 
     9 // receive_sync_msg is defined in the sync_actions
    10 
    11 PEP_STATUS receive_sync_msg(
    12         PEP_SESSION session,
    13         DeviceGroup_Protocol_t *msg
    14     );
    15 
    16 DYNAMIC_API PEP_STATUS register_sync_callbacks(
    17         PEP_SESSION session,
    18         void *obj,
    19         messageToSend_t messageToSend,
    20         showHandshake_t showHandshake,
    21         inject_sync_msg_t inject_sync_msg,
    22         retrieve_next_sync_msg_t retrieve_next_sync_msg
    23     )
    24 {
    25     unsigned char uuid[16];
    26     uuid_generate_random(uuid);
    27     uuid_unparse_upper(uuid, sync_uuid);
    28 
    29     session->sync_obj = obj;
    30     session->messageToSend = messageToSend;
    31     session->showHandshake = showHandshake;
    32     session->inject_sync_msg = inject_sync_msg;
    33     session->retrieve_next_sync_msg = retrieve_next_sync_msg;
    34 
    35     // start state machine
    36     session->sync_state = InitState;
    37     PEP_STATUS status = fsm_DeviceState_inject(session, Init, NULL, NULL);
    38     if (status != PEP_STATUS_OK)
    39         unregister_sync_callbacks(session);
    40 
    41     return status;
    42 }
    43 
    44 DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session) {
    45     // stop state machine
    46     session->sync_state = DeviceState_state_NONE;
    47 
    48     // unregister
    49     session->sync_obj = NULL;
    50     session->messageToSend = NULL;
    51     session->showHandshake = NULL;
    52     session->retrieve_next_sync_msg = NULL;
    53 }
    54 
    55 DYNAMIC_API PEP_STATUS deliverHandshakeResult(
    56         PEP_SESSION session,
    57         sync_handshake_result result
    58     )
    59 {
    60     assert(session);
    61     if (!session)
    62         return PEP_ILLEGAL_VALUE;
    63 
    64     PEP_STATUS status = PEP_STATUS_OK;
    65 
    66     switch (result) {
    67         case SYNC_HANDSHAKE_CANCEL:
    68             status = fsm_DeviceState_inject(session, Cancel, NULL, 0);
    69             break;
    70         case SYNC_HANDSHAKE_ACCEPTED:
    71             status = fsm_DeviceState_inject(session, HandshakeAccepted, NULL, 0);
    72             break;
    73         case SYNC_HANDSHAKE_REJECTED:
    74             status = fsm_DeviceState_inject(session, HandshakeRejected, NULL, 0);
    75             break;
    76         default:
    77             return PEP_ILLEGAL_VALUE;
    78     }
    79 
    80     return status;
    81 }
    82 
    83 DYNAMIC_API PEP_STATUS do_sync_protocol(
    84         PEP_SESSION session,
    85         void *management
    86     )
    87 {
    88     DeviceGroup_Protocol_t *msg = NULL;
    89     PEP_STATUS status = PEP_STATUS_OK;
    90 
    91     assert(session && session->retrieve_next_sync_msg);
    92     assert(management);
    93 
    94     if (!(session && session->retrieve_next_sync_msg) || !management)
    95         return PEP_ILLEGAL_VALUE;
    96 
    97     log_event(session, "sync_protocol thread started", "pEp sync protocol", NULL, NULL);
    98 
    99     while ((msg = (DeviceGroup_Protocol_t *) session->retrieve_next_sync_msg(management))) 
   100     {
   101         if ((status = receive_sync_msg(session, msg) != PEP_STATUS_OK)) {
   102             char buffer[MAX_LINELENGTH];
   103             memset(buffer, 0, MAX_LINELENGTH);
   104             snprintf(buffer, MAX_LINELENGTH, "problem with msg received: %d\n", (int) status);
   105             log_event(session, buffer, "pEp sync protocol", NULL, NULL);
   106         }
   107     }
   108 
   109     log_event(session, "sync_protocol thread shutdown", "pEp sync protocol", NULL, NULL);
   110 
   111     return PEP_STATUS_OK;
   112 }
   113 
   114 DYNAMIC_API PEP_STATUS decode_sync_msg(
   115         const char *data,
   116         size_t size,
   117         char **text
   118     )
   119 {
   120     PEP_STATUS status = PEP_STATUS_OK;
   121 
   122     assert(data && text);
   123     if (!(data && text))
   124         return PEP_ILLEGAL_VALUE;
   125 
   126     *text = NULL;
   127 
   128     DeviceGroup_Protocol_t *msg = NULL;
   129     uper_decode_complete(NULL, &asn_DEF_DeviceGroup_Protocol, (void **) &msg,
   130             data, size);
   131     if (!msg)
   132         return PEP_SYNC_ILLEGAL_MESSAGE;
   133 
   134     growing_buf_t *dst = new_growing_buf();
   135     if (!dst) {
   136         status = PEP_OUT_OF_MEMORY;
   137         goto the_end;
   138     }
   139 
   140     asn_enc_rval_t er = xer_encode(&asn_DEF_DeviceGroup_Protocol, msg,
   141             XER_F_BASIC, (asn_app_consume_bytes_f *) consume_bytes, (void *) dst);
   142     if (er.encoded == -1) {
   143         status = PEP_CANNOT_ENCODE;
   144         goto the_end;
   145     }
   146 
   147     *text = dst->data;
   148     dst->data = NULL;
   149 
   150 the_end:
   151     free_growing_buf(dst);
   152     ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   153     return status;
   154 }
   155 
   156 DYNAMIC_API PEP_STATUS encode_sync_msg(
   157         const char *text,
   158         char **data,
   159         size_t *size
   160     )
   161 {
   162     PEP_STATUS status = PEP_STATUS_OK;
   163 
   164     assert(text && data && size);
   165     if (!(text && data && size))
   166         return PEP_ILLEGAL_VALUE;
   167 
   168     *data = NULL;
   169     *size = 0;
   170 
   171     DeviceGroup_Protocol_t *msg = NULL;
   172     asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_DeviceGroup_Protocol,
   173             (void **) &msg, (const void *) text, strlen(text));
   174     if (dr.code != RC_OK) {
   175         status = PEP_SYNC_ILLEGAL_MESSAGE;
   176         goto the_end;
   177     }
   178 
   179     char *payload = NULL;
   180     ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_DeviceGroup_Protocol,
   181             NULL, msg, (void **) &payload);
   182     if (_size == -1) {
   183         status = PEP_CANNOT_ENCODE;
   184         goto the_end;
   185     }
   186 
   187     *data = payload;
   188     *size = (size_t) _size;
   189 
   190 the_end:
   191     ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   192     return status;
   193 }
   194