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