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