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