... sync
authorVolker Birk <vb@pep.foundation>
Sat, 11 Aug 2018 00:46:58 +0200
branchsync
changeset 28387eef15a2c61e
parent 2837 f3f3e42f5358
child 2839 d9f7cb22f1d1
...
.hgignore
src/sync.c
src/sync_actions.c
src/sync_impl.c
src/sync_impl.h
sync/cond_act.yml2
sync/gen_message_func.ysl2
sync/gen_statemachine.ysl2
     1.1 --- a/.hgignore	Fri Aug 10 11:16:26 2018 +0200
     1.2 +++ b/.hgignore	Sat Aug 11 00:46:58 2018 +0200
     1.3 @@ -67,6 +67,8 @@
     1.4  src/KeySync_fsm.h
     1.5  src/Sync_func.c
     1.6  src/Sync_func.h
     1.7 +src/Sync_event.c
     1.8 +src/Sync_event.h
     1.9  asn.1/keysync.asn1
    1.10  asn.1/sync.asn1
    1.11  sync/.codecs
    1.12 @@ -74,3 +76,4 @@
    1.13  sync/.actions
    1.14  sync/.codegen
    1.15  sync/.statemachines
    1.16 +
     2.1 --- a/src/sync.c	Fri Aug 10 11:16:26 2018 +0200
     2.2 +++ b/src/sync.c	Sat Aug 11 00:46:58 2018 +0200
     2.3 @@ -29,11 +29,6 @@
     2.4      session->inject_sync_msg = inject_sync_msg;
     2.5      session->retrieve_next_sync_msg = retrieve_next_sync_msg;
     2.6  
     2.7 -    // start state machine
     2.8 -    PEP_STATUS status = inject_Sync_event(session, Sync_PR_keysync, Init);
     2.9 -    if (status != PEP_STATUS_OK)
    2.10 -        unregister_sync_callbacks(session);
    2.11 -
    2.12      return status;
    2.13  }
    2.14  
     3.1 --- a/src/sync_actions.c	Fri Aug 10 11:16:26 2018 +0200
     3.2 +++ b/src/sync_actions.c	Sat Aug 11 00:46:58 2018 +0200
     3.3 @@ -66,7 +66,7 @@
     3.4      if (!(session && result))
     3.5          return PEP_ILLEGAL_VALUE;
     3.6  
     3.7 -    pEp_identity *from = session->sync_state.basic.from;
     3.8 +    pEp_identity *from = session->sync_state.common.from;
     3.9  
    3.10      assert(from && from->fpr && from->fpr[0] && from->address && from->address[0]);
    3.11      if (!(from && from->fpr && from->fpr[0] && from->address && from->address[0]))
    3.12 @@ -183,11 +183,11 @@
    3.13      if (!session->notifyHandshake)
    3.14          return PEP_SYNC_NO_NOTIFY_CALLBACK;
    3.15   
    3.16 -    assert(session->sync_state.basic.from);
    3.17 -    if (!session->sync_state.basic.from)
    3.18 +    assert(session->sync_state.common.from);
    3.19 +    if (!session->sync_state.common.from)
    3.20          return PEP_ILLEGAL_VALUE;
    3.21  
    3.22 -    pEp_identity *from = session->sync_state.basic.from;
    3.23 +    pEp_identity *from = session->sync_state.common.from;
    3.24      pEp_identity *me = NULL;
    3.25      PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
    3.26      assert(status == PEP_STATUS_OK);
    3.27 @@ -280,7 +280,7 @@
    3.28      if (!il)
    3.29          return PEP_OUT_OF_MEMORY;
    3.30  
    3.31 -    pEp_identity *from = session->sync_state.basic.from;
    3.32 +    pEp_identity *from = session->sync_state.common.from;
    3.33      identity_list *_il = il;
    3.34  
    3.35      int result;
    3.36 @@ -349,11 +349,11 @@
    3.37      if (!session->notifyHandshake)
    3.38          return PEP_SYNC_NO_NOTIFY_CALLBACK;
    3.39   
    3.40 -    assert(session->sync_state.basic.from);
    3.41 -    if (!session->sync_state.basic.from)
    3.42 +    assert(session->sync_state.common.from);
    3.43 +    if (!session->sync_state.common.from)
    3.44          return PEP_ILLEGAL_VALUE;
    3.45  
    3.46 -    pEp_identity *from = session->sync_state.basic.from;
    3.47 +    pEp_identity *from = session->sync_state.common.from;
    3.48      pEp_identity *me = NULL;
    3.49      PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
    3.50      assert(status == PEP_STATUS_OK);
    3.51 @@ -390,11 +390,11 @@
    3.52      if (!session->notifyHandshake)
    3.53          return PEP_SYNC_NO_NOTIFY_CALLBACK;
    3.54   
    3.55 -    assert(session->sync_state.basic.from);
    3.56 -    if (!session->sync_state.basic.from)
    3.57 +    assert(session->sync_state.common.from);
    3.58 +    if (!session->sync_state.common.from)
    3.59          return PEP_ILLEGAL_VALUE;
    3.60  
    3.61 -    pEp_identity *from = session->sync_state.basic.from;
    3.62 +    pEp_identity *from = session->sync_state.common.from;
    3.63      pEp_identity *me = NULL;
    3.64      PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
    3.65      assert(status == PEP_STATUS_OK);
     4.1 --- a/src/sync_impl.c	Fri Aug 10 11:16:26 2018 +0200
     4.2 +++ b/src/sync_impl.c	Sat Aug 11 00:46:58 2018 +0200
     4.3 @@ -15,20 +15,25 @@
     4.4      if (!(session && fsm))
     4.5          return PEP_ILLEGAL_VALUE;
     4.6  
     4.7 -    switch (fsm) {
     4.8 -        case Sync_PR_keysync: {
     4.9 -            int state = session->sync_state.keysync.state;
    4.10 -            state = fsm_KeySync(session, state, event);
    4.11 -            if (state > 0)
    4.12 -                session->sync_state.keysync.state = state;
    4.13 -            else if (state < 0)
    4.14 -                return PEP_STATEMACHINE_ERROR - state;
    4.15 -            break;
    4.16 +    int next_state = None;
    4.17 +    do {
    4.18 +        switch (fsm) {
    4.19 +            case Sync_PR_keysync: {
    4.20 +                next_state = fsm_KeySync(session, session->sync_state.keysync.state, event);
    4.21 +                if (next_state > None) {
    4.22 +                    session->sync_state.keysync.state = next_state;
    4.23 +                    event = Init;
    4.24 +                }
    4.25 +                else if (next_state < None) {
    4.26 +                    return PEP_STATEMACHINE_ERROR - state;
    4.27 +                }
    4.28 +                break;
    4.29 +            }
    4.30 +            
    4.31 +            default:
    4.32 +                return PEP_ILLEGAL_VALUE;
    4.33          }
    4.34 -        
    4.35 -        default:
    4.36 -            return PEP_ILLEGAL_VALUE;
    4.37 -    }
    4.38 +    }  while (next_state);
    4.39  
    4.40      return PEP_STATUS_OK;
    4.41  }
     5.1 --- a/src/sync_impl.h	Fri Aug 10 11:16:26 2018 +0200
     5.2 +++ b/src/sync_impl.h	Sat Aug 11 00:46:58 2018 +0200
     5.3 @@ -11,14 +11,6 @@
     5.4  extern "C" {
     5.5  #endif
     5.6  
     5.7 -// event struct
     5.8 -
     5.9 -typedef struct _Sync_event {
    5.10 -    Sync_PR fsm;
    5.11 -    int event;
    5.12 -    Sync_t *msg;
    5.13 -} Sync_event_t;
    5.14 -
    5.15  // conditions
    5.16  
    5.17  PEP_STATUS deviceGrouped(PEP_SESSION session, bool *result);
    5.18 @@ -57,11 +49,11 @@
    5.19          int event
    5.20      );
    5.21  
    5.22 -// receive event and store it in state
    5.23 +// receive message and store it in state
    5.24  
    5.25 -PEP_STATUS recv_Sync_event(
    5.26 +PEP_STATUS recv_Sync_message(
    5.27          PEP_SESSION session,
    5.28 -        Sync_event_t *ev
    5.29 +        Sync_t *msg
    5.30      );
    5.31  
    5.32  // state machine driver
     6.1 --- a/sync/cond_act.yml2	Fri Aug 10 11:16:26 2018 +0200
     6.2 +++ b/sync/cond_act.yml2	Sat Aug 11 00:46:58 2018 +0200
     6.3 @@ -63,7 +63,7 @@
     6.4  
     6.5  condition keyElectionWon
     6.6  ||
     6.7 -    pEp_identity *from = session->sync_state.basic.from;
     6.8 +    pEp_identity *from = session->sync_state.common.from;
     6.9  
    6.10      assert(from && from->fpr && from->fpr[0] && from->address && from->address[0]);
    6.11      if (!(from && from->fpr && from->fpr[0] && from->address && from->address[0]))
    6.12 @@ -147,11 +147,11 @@
    6.13          if (!session->notifyHandshake)
    6.14              return PEP_SYNC_NO_NOTIFY_CALLBACK;
    6.15       
    6.16 -        assert(session->sync_state.basic.from);
    6.17 -        if (!session->sync_state.basic.from)
    6.18 +        assert(session->sync_state.common.from);
    6.19 +        if (!session->sync_state.common.from)
    6.20              return PEP_ILLEGAL_VALUE;
    6.21  
    6.22 -        pEp_identity *from = session->sync_state.basic.from;
    6.23 +        pEp_identity *from = session->sync_state.common.from;
    6.24          pEp_identity *me = NULL;
    6.25          PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
    6.26          assert(status == PEP_STATUS_OK);
    6.27 @@ -223,7 +223,7 @@
    6.28          if (!il)
    6.29              return PEP_OUT_OF_MEMORY;
    6.30  
    6.31 -        pEp_identity *from = session->sync_state.basic.from;
    6.32 +        pEp_identity *from = session->sync_state.common.from;
    6.33          identity_list *_il = il;
    6.34  
    6.35          int result;
     7.1 --- a/sync/gen_message_func.ysl2	Fri Aug 10 11:16:26 2018 +0200
     7.2 +++ b/sync/gen_message_func.ysl2	Sat Aug 11 00:46:58 2018 +0200
     7.3 @@ -39,9 +39,9 @@
     7.4  // state
     7.5  
     7.6  struct «@name»_state_s {
     7.7 -    struct basic_state_s {
     7.8 +    struct common_state_s {
     7.9          pEp_identity *from;
    7.10 -    } basic;
    7.11 +    } common;
    7.12  
    7.13      `` apply "fsm", mode=state
    7.14  };
    7.15 @@ -95,17 +95,17 @@
    7.16      if (!session)
    7.17          return;
    7.18  
    7.19 -    free_identity(session->«yml:lcase(@name)»_state.basic.from);
    7.20 -    session->«yml:lcase(@name)»_state.basic.from = NULL;
    7.21 +    free_identity(session->«yml:lcase(@name)»_state.common.from);
    7.22  
    7.23  ||
    7.24  for "fsm"
    7.25      for "func:distinctName(message/field[not(func:basicType())])"
    7.26          |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
    7.27 -|
    7.28  for "func:distinctName(fsm/message/field[@type='TID'])"
    7.29      |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->own_«yml:lcase(../../../@name)»_state.«@name»);
    7.30  ||
    7.31 +
    7.32 +    memset(&session->sync_state, 0, sizeof(session->sync_state));
    7.33  }
    7.34  
    7.35  «@name»_t *new_«@name»_message(«@name»_PR fsm, int message_type)
     8.1 --- a/sync/gen_statemachine.ysl2	Fri Aug 10 11:16:26 2018 +0200
     8.2 +++ b/sync/gen_statemachine.ysl2	Sat Aug 11 00:46:58 2018 +0200
     8.3 @@ -14,6 +14,107 @@
     8.4      include ./functions.ysl2
     8.5  
     8.6      template "/protocol" {
     8.7 +        document "generated/{@name}_event.h", "text"
     8.8 +        ||
     8.9 +        // This file is under GNU General Public License 3.0
    8.10 +        // see LICENSE.txt
    8.11 +
    8.12 +        #pragma once
    8.13 +
    8.14 +        #include "dynamic_api.h"
    8.15 +
    8.16 +        #ifdef __cplusplus
    8.17 +        extern "C" {
    8.18 +        #endif
    8.19 +
    8.20 +        #include "../asn.1/«@name».h"
    8.21 +
    8.22 +
    8.23 +        typedef struct _«@name»_event {
    8.24 +            «@name»_PR fsm;
    8.25 +            int event;
    8.26 +            «@name»_t *msg;
    8.27 +        } «@name»_event_t;
    8.28 +
    8.29 + 
    8.30 +        // new_«@name»_event() - allocate a new «@name»_event
    8.31 +        //
    8.32 +        //  parameters:
    8.33 +        //      fsm (in)        finite state machine the event is for
    8.34 +        //      event (in)      event or None
    8.35 +        //      msg (in)        message to compute event from
    8.36 +        //
    8.37 +        //  return value:
    8.38 +        //      pointer to new event or NULL in case of failure
    8.39 +        //
    8.40 +        //  caveat:
    8.41 +        //      event must be valid for fsm or None
    8.42 +        //      in case msg is given event will be calculated out of message
    8.43 +
    8.44 +        DYNAMIC_API «@name»_event_t *new_«@name»_event(«@name»_PR fsm, int event, «@name»_t *msg);
    8.45 +
    8.46 +
    8.47 +        // free_«@name»_event() - free memory occupied by event
    8.48 +        //
    8.49 +        //  parameters:
    8.50 +        //      ev (in)         event to free
    8.51 +
    8.52 +        DYNAMIC_API void free_«@name»_event(«@name»_event_t *ev);
    8.53 +
    8.54 +
    8.55 +        #ifdef __cplusplus
    8.56 +        }
    8.57 +        #endif
    8.58 +
    8.59 +        ||
    8.60 +
    8.61 +        document "generated/{@name}_event.c", "text"
    8.62 +        ||
    8.63 +        // This file is under GNU General Public License 3.0
    8.64 +        // see LICENSE.txt
    8.65 +
    8.66 +        #include "pEp_internal.h"
    8.67 +        #include "«@name»_event.h"
    8.68 +        #include "«@name»_func.h"
    8.69 +
    8.70 +        DYNAMIC_API «@name»_event_t *new_«@name»_event(«@name»_PR fsm, int event, «@name»_t *msg)
    8.71 +        {
    8.72 +            assert(fsm > 0 && (event >= 0 |`> |` msg));
    8.73 +            if (!(fsm > 0 && (event >= 0 |`> |` msg)))
    8.74 +                return NULL;
    8.75 +
    8.76 +            «@name»_event_t *ev = («@name»_event_t *) calloc(1, sizeof(«@name»_event_t));
    8.77 +            assert(ev);
    8.78 +            if (!ev)
    8.79 +                return NULL;
    8.80 +
    8.81 +            ev->fsm = fsm;
    8.82 +            ev->event = event;
    8.83 +            ev->msg = msg;
    8.84 +
    8.85 +            if (msg) {
    8.86 +                switch (fsm) {
    8.87 +                    `` apply "fsm", 3, mode=event
    8.88 +                    default:
    8.89 +                        // unknown protocol
    8.90 +                        free(ev);
    8.91 +                        return NULL;
    8.92 +                }
    8.93 +            }
    8.94 +
    8.95 +            return ev;
    8.96 +        }
    8.97 +
    8.98 +        DYNAMIC_API void free_«@name»_event(«@name»_event_t *ev)
    8.99 +        {
   8.100 +            if (ev) {
   8.101 +                free_«@name»_message(ev->msg);
   8.102 +                free(ev);
   8.103 +            }
   8.104 +        }
   8.105 +
   8.106 +        ||
   8.107 +
   8.108          document "generated/{@name}_impl.h", "text" {
   8.109          ||
   8.110          // This file is under GNU General Public License 3.0
   8.111 @@ -29,14 +130,6 @@
   8.112          extern "C" {
   8.113          #endif
   8.114  
   8.115 -        // event struct
   8.116 -
   8.117 -        typedef struct _«@name»_event {
   8.118 -            «@name»_PR fsm;
   8.119 -            int event;
   8.120 -            «@name»_t *msg;
   8.121 -        } «@name»_event_t;
   8.122 -
   8.123          // conditions
   8.124  
   8.125          ||
   8.126 @@ -69,11 +162,11 @@
   8.127                  int event
   8.128              );
   8.129  
   8.130 -        // receive event and store it in state
   8.131 +        // receive message and store it in state
   8.132  
   8.133 -        PEP_STATUS recv_«@name»_event(
   8.134 +        PEP_STATUS recv_«@name»_message(
   8.135                  PEP_SESSION session,
   8.136 -                «@name»_event_t *ev
   8.137 +                «@name»_t *msg
   8.138              );
   8.139      
   8.140          // state machine driver
   8.141 @@ -118,11 +211,14 @@
   8.142              if (!(session && fsm))
   8.143                  return PEP_ILLEGAL_VALUE;
   8.144  
   8.145 -            switch (fsm) {
   8.146 -                `` apply "fsm", 2, mode=driver               
   8.147 -                default:
   8.148 -                    return PEP_ILLEGAL_VALUE;
   8.149 -            }
   8.150 +            int next_state = None;
   8.151 +            do {
   8.152 +                switch (fsm) {
   8.153 +                    `` apply "fsm", 3, mode=driver               
   8.154 +                    default:
   8.155 +                        return PEP_ILLEGAL_VALUE;
   8.156 +                }
   8.157 +            }  while (next_state);
   8.158  
   8.159              return PEP_STATUS_OK;
   8.160          }
   8.161 @@ -271,15 +367,41 @@
   8.162          apply "fsm", 0, mode=gen;
   8.163      }
   8.164  
   8.165 +    template "fsm", mode=event
   8.166 +    {
   8.167 +    ||
   8.168 +    case Sync_PR_«yml:lcase(@name)»: {
   8.169 +        switch (msg->choice.keysync.choice.present) {
   8.170 +    ||
   8.171 +    for "message"
   8.172 +    ||
   8.173 +            case «../@name»__payload_PR_«yml:mixedCase(@name)»:
   8.174 +                ev->event = «@name»;
   8.175 +                break;
   8.176 +    ||
   8.177 +    ||
   8.178 +            default:
   8.179 +                // unknown message type
   8.180 +                free(ev);
   8.181 +                return NULL;
   8.182 +        }
   8.183 +        break;
   8.184 +    }
   8.185 +
   8.186 +    ||
   8.187 +    }
   8.188 +
   8.189      template "fsm", mode=driver
   8.190      ||
   8.191      case Sync_PR_«yml:lcase(@name)»: {
   8.192 -        int state = session->sync_state.«yml:lcase(@name)».state;
   8.193 -        state = fsm_«@name»(session, state, event);
   8.194 -        if (state > 0)
   8.195 -            session->sync_state.«yml:lcase(@name)».state = state;
   8.196 -        else if (state < 0)
   8.197 +        next_state = fsm_«@name»(session, session->«yml:lcase(../@name)»_state.«yml:lcase(@name)».state, event);
   8.198 +        if (next_state > None) {
   8.199 +            session->«yml:lcase(../@name)»_state.«yml:lcase(@name)».state = next_state;
   8.200 +            event = Init;
   8.201 +        }
   8.202 +        else if (next_state < None) {
   8.203              return PEP_STATEMACHINE_ERROR - state;
   8.204 +        }
   8.205          break;
   8.206      }
   8.207  
   8.208 @@ -338,6 +460,9 @@
   8.209  
   8.210          const char *«@name»_state_name(int state);
   8.211  
   8.212 +        // the state machine function is returning the next state in case of a
   8.213 +        // transition or None for staying
   8.214 +
   8.215          «@name»_state fsm_«@name»(
   8.216                  PEP_SESSION session,
   8.217                  «@name»_state state,
   8.218 @@ -427,16 +552,15 @@
   8.219  
   8.220              switch (state) {
   8.221                  case None:
   8.222 -                    «@name»_SERVICE_LOG("transition to state Init", "None is not a valid state");
   8.223 -                    return Init;
   8.224 +                    return «@name»_state_Init;
   8.225                  
   8.226                  `` apply "state", 2, mode=fsm
   8.227                  default:
   8.228 -                    «@name»_ERR_LOG_INT("«@name»_fsm() called with invalid state", state);
   8.229 +                    «@name»_ERR_LOG_INT("invalid state", state);
   8.230                      return invalid_state;
   8.231              }
   8.232              
   8.233 -            return state;
   8.234 +            return None;
   8.235          }
   8.236  
   8.237          ||
   8.238 @@ -454,11 +578,20 @@
   8.239              switch (event) {
   8.240                  case None:
   8.241                      «../@name»_SERVICE_LOG("received None event", "ignoring");
   8.242 -                    return state;
   8.243 +                    break;
   8.244       
   8.245 +        ||
   8.246 +        if "not(event[@name='Init'])"
   8.247 +        ||
   8.248 +                case Init:
   8.249 +                    // nothing to do
   8.250 +                    break;
   8.251 +
   8.252 +        ||
   8.253 +        ||
   8.254                  `` apply "event", 2, mode=fsm
   8.255                  default:
   8.256 -                    «../@name»_ERR_LOG_INT("«../@name»_fsm() called with invalid event", event);
   8.257 +                    «../@name»_ERR_LOG_INT("invalid event", event);
   8.258                      return invalid_event;
   8.259              }
   8.260              break;
   8.261 @@ -491,8 +624,7 @@
   8.262          ||
   8.263  
   8.264          «$fsm/@name»_SERVICE_LOG("transition to state", "«@target»");
   8.265 -        state = «@target»;
   8.266 -        break;
   8.267 +        return «@target»;
   8.268          ||
   8.269      }
   8.270