src/sync.c
author Edouard Tisserant <edouard@pep-project.org>
Fri, 16 Dec 2016 19:13:00 +0100
changeset 1494 27ded4922ae2
parent 1462 b93663bfc7c6
child 1513 e7f7e42385b5
permissions -rw-r--r--
sync: more debug information when NDEBUG is not defined
     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_impl
    10 
    11 PEP_STATUS receive_sync_msg(
    12         PEP_SESSION session,
    13         sync_msg_t *sync_msg,
    14         time_t *timeout
    15     );
    16 
    17 DYNAMIC_API PEP_STATUS register_sync_callbacks(
    18         PEP_SESSION session,
    19         void *management,
    20         messageToSend_t messageToSend,
    21         notifyHandshake_t notifyHandshake,
    22         inject_sync_msg_t inject_sync_msg,
    23         retrieve_next_sync_msg_t retrieve_next_sync_msg
    24     )
    25 {
    26     assert(session && management && messageToSend && notifyHandshake && inject_sync_msg && retrieve_next_sync_msg);
    27     if (!(session && management && messageToSend && notifyHandshake && inject_sync_msg && retrieve_next_sync_msg))
    28         return PEP_ILLEGAL_VALUE;
    29 
    30     pEpUUID uuid;
    31     uuid_generate_random(uuid);
    32     uuid_unparse_upper(uuid, session->sync_uuid);
    33 
    34     session->sync_management = management;
    35     session->messageToSend = messageToSend;
    36     session->notifyHandshake = notifyHandshake;
    37     session->inject_sync_msg = inject_sync_msg;
    38     session->retrieve_next_sync_msg = retrieve_next_sync_msg;
    39 
    40     // start state machine
    41     session->sync_state = InitState;
    42     time_t unused = 0;
    43     PEP_STATUS status = fsm_DeviceState_inject(session, Init, NULL, NULL, &unused);
    44     if (status != PEP_STATUS_OK)
    45         unregister_sync_callbacks(session);
    46 
    47     return status;
    48 }
    49 
    50 DYNAMIC_API PEP_STATUS attach_sync_session(
    51         PEP_SESSION session,
    52         PEP_SESSION sync_session
    53     )
    54 {
    55     assert(session && sync_session && sync_session->sync_management && sync_session->inject_sync_msg );
    56     if (!(session && sync_session && sync_session->sync_management && sync_session->inject_sync_msg ))
    57         return PEP_ILLEGAL_VALUE;
    58 
    59     memcpy(session->sync_uuid, sync_session->sync_uuid, 37);
    60 
    61     session->sync_management = sync_session->sync_management;
    62     session->inject_sync_msg = sync_session->inject_sync_msg;
    63 
    64     return PEP_STATUS_OK;
    65 }
    66 
    67 DYNAMIC_API PEP_STATUS detach_sync_session(PEP_SESSION session)
    68 {
    69     assert(session && session->sync_management && session->inject_sync_msg );
    70     if (!(session && session->sync_management && session->inject_sync_msg ))
    71         return PEP_ILLEGAL_VALUE;
    72 
    73     memset(session->sync_uuid, 0, 37);
    74 
    75     session->sync_management = NULL;
    76     session->inject_sync_msg = NULL;
    77 
    78     return PEP_STATUS_OK;
    79 }
    80 
    81 int call_inject_sync_msg(PEP_SESSION session, void *msg)
    82 {
    83     if(session->inject_sync_msg && session->sync_management)
    84         return session->inject_sync_msg(msg, session->sync_management);
    85     else
    86        return PEP_SYNC_NO_INJECT_CALLBACK;
    87 }
    88 
    89 DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session) {
    90     // stop state machine
    91     session->sync_state = DeviceState_state_NONE;
    92 
    93     // unregister
    94     session->sync_management = NULL;
    95     session->messageToSend = NULL;
    96     session->notifyHandshake = NULL;
    97     session->inject_sync_msg = NULL;
    98     session->retrieve_next_sync_msg = NULL;
    99 }
   100 
   101 DYNAMIC_API PEP_STATUS deliverHandshakeResult(
   102         PEP_SESSION session,
   103         Identity partner,
   104         sync_handshake_result result
   105     )
   106 {
   107     assert(session);
   108     if (!session)
   109         return PEP_ILLEGAL_VALUE;
   110 
   111     PEP_STATUS status = PEP_STATUS_OK;
   112 
   113     DeviceState_event event;
   114     bool need_partner = false;
   115 
   116     switch (result) {
   117         case SYNC_HANDSHAKE_CANCEL:
   118             event = Cancel;
   119             break;
   120         case SYNC_HANDSHAKE_ACCEPTED:
   121         {
   122             event = HandshakeAccepted;
   123             need_partner = true;
   124             break;
   125         }
   126         case SYNC_HANDSHAKE_REJECTED:
   127         {
   128             event = HandshakeRejected;
   129             need_partner = true;
   130             break;
   131         }
   132         default:
   133             return PEP_ILLEGAL_VALUE;
   134     }
   135 
   136     pEp_identity *_partner = NULL;
   137     if(need_partner){
   138         _partner = identity_dup(partner);
   139         if (_partner == NULL)
   140             return PEP_OUT_OF_MEMORY;
   141     }
   142     status = inject_DeviceState_event(session, event, _partner, NULL);
   143 
   144     return status;
   145 }
   146 
   147 DYNAMIC_API PEP_STATUS do_sync_protocol(
   148         PEP_SESSION session,
   149         void *obj
   150     )
   151 {
   152     sync_msg_t *msg = NULL;
   153     PEP_STATUS status = PEP_STATUS_OK;
   154     time_t timeout = 0;
   155 
   156     assert(session && session->retrieve_next_sync_msg);
   157     assert(obj);
   158 
   159     if (!(session && session->retrieve_next_sync_msg) || !obj)
   160         return PEP_ILLEGAL_VALUE;
   161 
   162     log_event(session, "sync_protocol thread started", "pEp sync protocol", NULL, NULL);
   163 
   164     session->sync_obj = obj;
   165 
   166     while (true) 
   167     {
   168         msg = (sync_msg_t *) session->retrieve_next_sync_msg(session->sync_management, &timeout);
   169         if(msg == NULL && timeout == 0)
   170             break;
   171         else if(msg == NULL && timeout != 0){
   172             status = fsm_DeviceState_inject(session, Timeout, NULL, NULL, &timeout);
   173 #ifndef NDEBUG
   174             char buffer[MAX_LINELENGTH];
   175             memset(buffer, 0, MAX_LINELENGTH);
   176             snprintf(buffer, MAX_LINELENGTH, "problem with timeout event : %d\n", (int) status);
   177             log_event(session, buffer, "pEp sync protocol", NULL, NULL);
   178             continue;
   179 #endif
   180         }
   181         else if ((status = receive_sync_msg(session, msg, &timeout) != PEP_STATUS_OK)) {
   182 #ifndef NDEBUG
   183             char buffer[MAX_LINELENGTH];
   184             memset(buffer, 0, MAX_LINELENGTH);
   185             snprintf(buffer, MAX_LINELENGTH, "problem with msg received: %d\n", (int) status);
   186             log_event(session, buffer, "pEp sync protocol", NULL, NULL);
   187 #endif
   188         }
   189     }
   190 
   191     log_event(session, "sync_protocol thread shutdown", "pEp sync protocol", NULL, NULL);
   192 
   193     session->sync_obj = NULL;
   194 
   195     return PEP_STATUS_OK;
   196 }
   197 
   198 DYNAMIC_API PEP_STATUS decode_sync_msg(
   199         const char *data,
   200         size_t size,
   201         char **text
   202     )
   203 {
   204     PEP_STATUS status = PEP_STATUS_OK;
   205 
   206     assert(data && text);
   207     if (!(data && text))
   208         return PEP_ILLEGAL_VALUE;
   209 
   210     *text = NULL;
   211 
   212     DeviceGroup_Protocol_t *msg = NULL;
   213     uper_decode_complete(NULL, &asn_DEF_DeviceGroup_Protocol, (void **) &msg,
   214             data, size);
   215     if (!msg)
   216         return PEP_SYNC_ILLEGAL_MESSAGE;
   217 
   218     growing_buf_t *dst = new_growing_buf();
   219     if (!dst) {
   220         status = PEP_OUT_OF_MEMORY;
   221         goto the_end;
   222     }
   223 
   224     asn_enc_rval_t er = xer_encode(&asn_DEF_DeviceGroup_Protocol, msg,
   225             XER_F_BASIC, (asn_app_consume_bytes_f *) consume_bytes, (void *) dst);
   226     if (er.encoded == -1) {
   227         status = PEP_CANNOT_ENCODE;
   228         goto the_end;
   229     }
   230 
   231     *text = dst->data;
   232     dst->data = NULL;
   233 
   234 the_end:
   235     free_growing_buf(dst);
   236     ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   237     return status;
   238 }
   239 
   240 DYNAMIC_API PEP_STATUS encode_sync_msg(
   241         const char *text,
   242         char **data,
   243         size_t *size
   244     )
   245 {
   246     PEP_STATUS status = PEP_STATUS_OK;
   247 
   248     assert(text && data && size);
   249     if (!(text && data && size))
   250         return PEP_ILLEGAL_VALUE;
   251 
   252     *data = NULL;
   253     *size = 0;
   254 
   255     DeviceGroup_Protocol_t *msg = NULL;
   256     asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_DeviceGroup_Protocol,
   257             (void **) &msg, (const void *) text, strlen(text));
   258     if (dr.code != RC_OK) {
   259         status = PEP_SYNC_ILLEGAL_MESSAGE;
   260         goto the_end;
   261     }
   262 
   263     char *payload = NULL;
   264     ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_DeviceGroup_Protocol,
   265             NULL, msg, (void **) &payload);
   266     if (_size == -1) {
   267         status = PEP_CANNOT_ENCODE;
   268         goto the_end;
   269     }
   270 
   271     *data = payload;
   272     *size = (size_t) _size;
   273 
   274 the_end:
   275     ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   276     return status;
   277 }
   278