... sync
authorVolker Birk <vb@pep.foundation>
Thu, 09 Aug 2018 12:15:44 +0200
branchsync
changeset 2830d6f044e43e1a
parent 2829 e444c3c960bb
child 2831 be6623599adb
...
Makefile
asn.1/Makefile
src/keymanagement.c
src/map_asn1.c
src/message_api.c
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
src/platform_unix.h
src/platform_windows.h
src/sync.c
src/sync.h
src/sync_actions.c
src/sync_app.h
sync/Makefile
sync/fsm.yml2
sync/gen_actions.ysl2
sync/gen_statemachine.ysl2
     1.1 --- a/Makefile	Tue Aug 07 17:16:03 2018 +0200
     1.2 +++ b/Makefile	Thu Aug 09 12:15:44 2018 +0200
     1.3 @@ -22,7 +22,6 @@
     1.4  .PHONY: all
     1.5  all:
     1.6  	$(MAKE) -C sync
     1.7 -	$(MAKE) -C asn.1 generate
     1.8  	$(MAKE) -C asn.1
     1.9  	$(MAKE) -C src all
    1.10  
     2.1 --- a/asn.1/Makefile	Tue Aug 07 17:16:03 2018 +0200
     2.2 +++ b/asn.1/Makefile	Thu Aug 09 12:15:44 2018 +0200
     2.3 @@ -24,7 +24,12 @@
     2.4  sync.asn1 keysync.asn1 pEp.asn1:
     2.5  	cp -f ../sync/generated/*.asn1 ../asn.1
     2.6  
     2.7 -.PHONY: clean
     2.8 +.PHONY: clean install uninstall
     2.9  
    2.10  clean:
    2.11  	rm -f *.a *.o *.c *.h *.sample sync.asn1 keysync.asn1
    2.12 +
    2.13 +install:
    2.14 +
    2.15 +uninstall:
    2.16 +
     3.1 --- a/src/keymanagement.c	Tue Aug 07 17:16:03 2018 +0200
     3.2 +++ b/src/keymanagement.c	Thu Aug 09 12:15:44 2018 +0200
     3.3 @@ -12,7 +12,6 @@
     3.4  #include "pEp_internal.h"
     3.5  #include "keymanagement.h"
     3.6  
     3.7 -#include "sync_fsm.h"
     3.8  #include "blacklist.h"
     3.9  
    3.10  static bool key_matches_address(PEP_SESSION session, const char* address,
     4.1 --- a/src/map_asn1.c	Tue Aug 07 17:16:03 2018 +0200
     4.2 +++ b/src/map_asn1.c	Thu Aug 09 12:15:44 2018 +0200
     4.3 @@ -23,9 +23,8 @@
     4.4          return NULL;
     4.5  
     4.6      if (ident->address) {
     4.7 -        result->address = OCTET_STRING_new_fromBuf(&asn_DEF_UTF8String,
     4.8 -                ident->address, -1);
     4.9 -        if (ident->address && !result->address)
    4.10 +        int r = OCTET_STRING_fromBuf(&result->address, ident->address, -1);
    4.11 +        if (r)
    4.12              goto enomem;
    4.13      }
    4.14  
    4.15 @@ -35,25 +34,19 @@
    4.16      }
    4.17  
    4.18      if (ident->user_id) {
    4.19 -        result->user_id = OCTET_STRING_new_fromBuf(&asn_DEF_UTF8String,
    4.20 -                ident->user_id, -1);
    4.21 -        if (ident->user_id && !result->user_id)
    4.22 +        int r = OCTET_STRING_fromBuf(&result->user_id, ident->user_id, -1);
    4.23 +        if (r)
    4.24              goto enomem;
    4.25      }
    4.26  
    4.27      if (ident->username) {
    4.28 -        result->username = OCTET_STRING_new_fromBuf(&asn_DEF_UTF8String,
    4.29 -                ident->username, -1);
    4.30 -        if (ident->username && !result->username)
    4.31 +        int r = OCTET_STRING_fromBuf(&result->username, ident->username, -1);
    4.32 +        if (r)
    4.33              goto enomem;
    4.34      }
    4.35  
    4.36      if (ident->comm_type != PEP_ct_unknown) {
    4.37 -        result->comm_type = malloc(sizeof(long));
    4.38 -        assert(result->comm_type);
    4.39 -        if (!result->comm_type)
    4.40 -            goto enomem;
    4.41 -        *result->comm_type = ident->comm_type;
    4.42 +        result->comm_type = ident->comm_type;
    4.43      }
    4.44  
    4.45      if (ident->lang[0]) {
    4.46 @@ -91,37 +84,30 @@
    4.47      if (!result)
    4.48          return NULL;
    4.49  
    4.50 -    if (ident->address) {
    4.51 -        result->address = strndup((char *) ident->address->buf,
    4.52 -                ident->address->size);
    4.53 -        assert(result->address);
    4.54 -        if (!result->address)
    4.55 -            goto enomem;
    4.56 -    }
    4.57 +    result->address = strndup((char *) ident->address.buf,
    4.58 +            ident->address.size);
    4.59 +    assert(result->address);
    4.60 +    if (!result->address)
    4.61 +        goto enomem;
    4.62  
    4.63      result->fpr = strndup((char *) ident->fpr.buf, ident->fpr.size);
    4.64      assert(result->fpr);
    4.65      if (!result->fpr)
    4.66          goto enomem;
    4.67  
    4.68 -    if (ident->user_id) {
    4.69 -        result->user_id = strndup((char *) ident->user_id->buf,
    4.70 -                ident->user_id->size);
    4.71 -        assert(result->user_id);
    4.72 -        if (!result->user_id)
    4.73 -            goto enomem;
    4.74 -    }
    4.75 +    result->user_id = strndup((char *) ident->user_id.buf,
    4.76 +            ident->user_id.size);
    4.77 +    assert(result->user_id);
    4.78 +    if (!result->user_id)
    4.79 +        goto enomem;
    4.80  
    4.81 -    if (ident->username) {
    4.82 -        result->username = strndup((char *) ident->username->buf,
    4.83 -                ident->username->size);
    4.84 -        assert(result->username);
    4.85 -        if (!result->username)
    4.86 -            goto enomem;
    4.87 -    }
    4.88 +    result->username = strndup((char *) ident->username.buf,
    4.89 +            ident->username.size);
    4.90 +    assert(result->username);
    4.91 +    if (!result->username)
    4.92 +        goto enomem;
    4.93  
    4.94 -    if (ident->comm_type)
    4.95 -        result->comm_type = (PEP_comm_type) *ident->comm_type;
    4.96 +    result->comm_type = (PEP_comm_type) ident->comm_type;
    4.97  
    4.98      if (ident->lang.size == 2) {
    4.99          result->lang[0] = ident->lang.buf[0];
     5.1 --- a/src/message_api.c	Tue Aug 07 17:16:03 2018 +0200
     5.2 +++ b/src/message_api.c	Thu Aug 09 12:15:44 2018 +0200
     5.3 @@ -14,13 +14,6 @@
     5.4  #include <math.h>
     5.5  
     5.6  
     5.7 -#ifndef _MIN
     5.8 -#define _MIN(A, B) ((B) > (A) ? (A) : (B))
     5.9 -#endif
    5.10 -#ifndef _MAX
    5.11 -#define _MAX(A, B) ((B) > (A) ? (B) : (A))
    5.12 -#endif
    5.13 -
    5.14  // These are globals used in generating message IDs and should only be
    5.15  // computed once, as they're either really constants or OS-dependent
    5.16  
    5.17 @@ -463,7 +456,7 @@
    5.18          
    5.19      const int DESIRED_BITS = 64;
    5.20  
    5.21 -    num_bits = _MIN(num_bits, DESIRED_BITS);
    5.22 +    num_bits = MIN(num_bits, DESIRED_BITS);
    5.23      
    5.24      int i;
    5.25      
    5.26 @@ -482,9 +475,9 @@
    5.27  
    5.28          output_value |= temp_val;
    5.29  
    5.30 -        i -= _MIN(num_bits, i); 
    5.31 +        i -= MIN(num_bits, i); 
    5.32          
    5.33 -        bitshift = _MIN(num_bits, i);
    5.34 +        bitshift = MIN(num_bits, i);
    5.35          output_value <<= bitshift;        
    5.36          bitmask = get_bitmask(bitshift);
    5.37      }
    5.38 @@ -1322,7 +1315,7 @@
    5.39          else if (ident->comm_type == PEP_ct_mistrusted)
    5.40              return PEP_ct_mistrusted;
    5.41          else
    5.42 -            return _MIN(max_comm_type, ident->comm_type);
    5.43 +            return MIN(max_comm_type, ident->comm_type);
    5.44      }
    5.45      else {
    5.46          return PEP_ct_unknown;
    5.47 @@ -3217,7 +3210,7 @@
    5.48                      case PEP_DECRYPTED:
    5.49                      case PEP_DECRYPTED_AND_VERIFIED:
    5.50                          if (decrypt_status <= PEP_DECRYPTED_AND_VERIFIED)
    5.51 -                            decrypt_status = _MIN(decrypt_status, _decrypt_in_pieces_status);
    5.52 +                            decrypt_status = MIN(decrypt_status, _decrypt_in_pieces_status);
    5.53                          break;
    5.54                      case PEP_STATUS_OK:
    5.55                          break;    
    5.56 @@ -3605,7 +3598,7 @@
    5.57          *rating = PEP_rating_undefined;
    5.58      }
    5.59      else
    5.60 -        *rating = _MAX(_rating(max_comm_type, PEP_rating_undefined),
    5.61 +        *rating = MAX(_rating(max_comm_type, PEP_rating_undefined),
    5.62                                 PEP_rating_unencrypted);
    5.63  
    5.64      return PEP_STATUS_OK;
     6.1 --- a/src/pEpEngine.c	Tue Aug 07 17:16:03 2018 +0200
     6.2 +++ b/src/pEpEngine.c	Thu Aug 09 12:15:44 2018 +0200
     6.3 @@ -379,23 +379,14 @@
     6.4  
     6.5  // Sequence
     6.6  static const char *sql_sequence_value1 = 
     6.7 -    "insert or replace into sequences (name, value, own) "
     6.8 +    "insert or replace into sequences (name, value) "
     6.9      "values (?1, "
    6.10      "       (select coalesce((select value + 1 from sequences "
    6.11 -    "           where name = ?1), 1 )), "
    6.12 -    "       (select coalesce((select own or ?2 from sequences "
    6.13 -    "           where name = ?1), ?2))) ; ";
    6.14 +    "           where name = ?1), 1 ))); ";
    6.15  
    6.16  static const char *sql_sequence_value2 = 
    6.17      "select value, own from sequences where name = ?1 ;";
    6.18  
    6.19 -static const char *sql_sequence_value3 = 
    6.20 -    "insert or replace into sequences (name, value, own) "
    6.21 -    "values (?1, "
    6.22 -    "        ?2, "
    6.23 -    "       (select coalesce((select own or ?3 from sequences "
    6.24 -    "           where name = ?1), ?3))) ; ";
    6.25 -        
    6.26  // Revocation tracking
    6.27  static const char *sql_set_revoked =
    6.28      "insert or replace into revoked_keys ("
    6.29 @@ -698,8 +689,7 @@
    6.30                  // sequences
    6.31                  "create table if not exists sequences(\n"
    6.32                  "   name text primary key,\n"
    6.33 -                "   value integer default 0,\n"
    6.34 -                "   own integer default 0\n"
    6.35 +                "   value integer default 0\n"
    6.36                  ");\n"
    6.37                  "create table if not exists revoked_keys (\n"
    6.38                  "   revoked_fpr text primary key,\n"
    6.39 @@ -774,9 +764,6 @@
    6.40              else if (table_contains_column(_session, "identity", "is_own") > 0) {
    6.41                  version = 6;
    6.42              }
    6.43 -            else if (table_contains_column(_session, "sequences", "own") > 0) {
    6.44 -                version = 3;
    6.45 -            }
    6.46              else if (table_contains_column(_session, "pgp_keypair", "flags") > 0) {
    6.47                  version = 2;
    6.48              }
    6.49 @@ -842,18 +829,6 @@
    6.50                  assert(int_result == SQLITE_OK);
    6.51              }
    6.52  
    6.53 -            if (version < 3) {
    6.54 -                int_result = sqlite3_exec(
    6.55 -                    _session->db,
    6.56 -                    "alter table sequences\n"
    6.57 -                    "   add column own integer default 0;\n",
    6.58 -                    NULL,
    6.59 -                    NULL,
    6.60 -                    NULL
    6.61 -                );
    6.62 -                assert(int_result == SQLITE_OK);
    6.63 -            }
    6.64 -
    6.65              if (version < 5) {
    6.66                  int_result = sqlite3_exec(
    6.67                      _session->db,
    6.68 @@ -1267,11 +1242,6 @@
    6.69              NULL);
    6.70      assert(int_result == SQLITE_OK);
    6.71  
    6.72 -    int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value3,
    6.73 -            (int)strlen(sql_sequence_value3), &_session->sequence_value3,
    6.74 -            NULL);
    6.75 -    assert(int_result == SQLITE_OK);
    6.76 -
    6.77      // Revocation tracking
    6.78      
    6.79      int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
    6.80 @@ -1464,8 +1434,6 @@
    6.81                  sqlite3_finalize(session->sequence_value1);
    6.82              if (session->sequence_value2)
    6.83                  sqlite3_finalize(session->sequence_value2);
    6.84 -            if (session->sequence_value3)
    6.85 -                sqlite3_finalize(session->sequence_value3);
    6.86              if (session->set_revoked)
    6.87                  sqlite3_finalize(session->set_revoked);
    6.88              if (session->get_revoked)
    6.89 @@ -3637,7 +3605,7 @@
    6.90  }
    6.91  
    6.92  static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
    6.93 -        const char *name, int own)
    6.94 +        const char *name)
    6.95  {
    6.96      assert(session && name);
    6.97      if (!(session && name))
    6.98 @@ -3645,7 +3613,6 @@
    6.99  
   6.100      sqlite3_reset(session->sequence_value1);
   6.101      sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
   6.102 -    sqlite3_bind_int(session->sequence_value1, 2, own);
   6.103      int result = sqlite3_step(session->sequence_value1);
   6.104      assert(result == SQLITE_DONE);
   6.105      sqlite3_reset(session->sequence_value1);
   6.106 @@ -3655,26 +3622,6 @@
   6.107          return PEP_CANNOT_INCREASE_SEQUENCE;
   6.108  }
   6.109  
   6.110 -static PEP_STATUS _set_sequence_value(PEP_SESSION session,
   6.111 -        const char *name, int32_t value, int own)
   6.112 -{
   6.113 -    assert(session && name && value > 0);
   6.114 -    if (!(session && name && value > 0))
   6.115 -        return PEP_ILLEGAL_VALUE;
   6.116 -
   6.117 -    sqlite3_reset(session->sequence_value3);
   6.118 -    sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
   6.119 -    sqlite3_bind_int(session->sequence_value3, 2, value);
   6.120 -    sqlite3_bind_int(session->sequence_value3, 3, own);
   6.121 -    int result = sqlite3_step(session->sequence_value3);
   6.122 -    assert(result == SQLITE_DONE);
   6.123 -    sqlite3_reset(session->sequence_value3);
   6.124 -    if (result == SQLITE_DONE)
   6.125 -        return PEP_STATUS_OK;
   6.126 -    else
   6.127 -        return PEP_CANNOT_SET_SEQUENCE_VALUE;
   6.128 -}
   6.129 -
   6.130  DYNAMIC_API PEP_STATUS sequence_value(
   6.131          PEP_SESSION session,
   6.132          char *name,
   6.133 @@ -3685,56 +3632,14 @@
   6.134      int result;
   6.135  
   6.136      assert(session);
   6.137 -    assert(name && value && *value >= 0);
   6.138 -
   6.139 -    if (!(session && name && value && *value >= 0))
   6.140 +    assert(name && value);
   6.141 +
   6.142 +    if (!(session && name && name[0] && value))
   6.143          return PEP_ILLEGAL_VALUE;
   6.144  
   6.145 -    int own = 0;
   6.146 -    if (!name[0]) {
   6.147 -        pEpUUID uuid;
   6.148 -        uuid_generate_random(uuid);
   6.149 -        uuid_unparse_upper(uuid, name);
   6.150 -        own = 1;
   6.151 -    }
   6.152 -    else {
   6.153 -        if (name == session->sync_session->sync_uuid || 
   6.154 -            strcmp(name, session->sync_session->sync_uuid) == 0)
   6.155 -            own = 1;
   6.156 -    }
   6.157 -
   6.158 -    if (*value) {
   6.159 -        sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
   6.160 -        int32_t old_value = 0;
   6.161 -        status = _get_sequence_value(session, name, &old_value);
   6.162 -        if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
   6.163 -        {
   6.164 -            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   6.165 -            return status;
   6.166 -        }
   6.167 -
   6.168 -        if (old_value >= *value) {
   6.169 -            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   6.170 -            return PEP_SEQUENCE_VIOLATED;
   6.171 -        }
   6.172 -        else {
   6.173 -            status = _set_sequence_value(session, name, *value, own);
   6.174 -            if (status == PEP_STATUS_OK) {
   6.175 -                result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
   6.176 -                if (result == SQLITE_OK)
   6.177 -                    return PEP_STATUS_OK;
   6.178 -                else
   6.179 -                    return PEP_COMMIT_FAILED;
   6.180 -            } else {
   6.181 -                sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   6.182 -                return status;
   6.183 -            }
   6.184 -        }
   6.185 -    }
   6.186 -
   6.187 -    assert(*value == 0);
   6.188 +    *value = 0;
   6.189      sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
   6.190 -    status = _increment_sequence_value(session, name, own);
   6.191 +    status = _increment_sequence_value(session, name);
   6.192      if (status == PEP_STATUS_OK) {
   6.193          status = _get_sequence_value(session, name, value);
   6.194      }
     7.1 --- a/src/pEpEngine.h	Tue Aug 07 17:16:03 2018 +0200
     7.2 +++ b/src/pEpEngine.h	Thu Aug 09 12:15:44 2018 +0200
     7.3 @@ -97,8 +97,8 @@
     7.4      PEP_CANNOT_SET_SEQUENCE_VALUE                   = 0x0972,
     7.5      PEP_OWN_SEQUENCE                                = 0x097f,
     7.6  
     7.7 -    PEP_SYNC_STATEMACHINE_ERROR                     = 0x0980,
     7.8 -    PEP_SYNC_NO_TRUST                               = 0x0981,
     7.9 +    PEP_STATEMACHINE_ERROR                          = 0x0980,
    7.10 +    PEP_NO_TRUST                                    = 0x0981,
    7.11      PEP_STATEMACHINE_INVALID_STATE                  = 0x0982,
    7.12      PEP_STATEMACHINE_INVALID_EVENT                  = 0x0983,
    7.13      PEP_STATEMACHINE_INVALID_CONDITION              = 0x0984,
     8.1 --- a/src/pEp_internal.h	Tue Aug 07 17:16:03 2018 +0200
     8.2 +++ b/src/pEp_internal.h	Thu Aug 09 12:15:44 2018 +0200
     8.3 @@ -107,6 +107,7 @@
     8.4  #include "cryptotech.h"
     8.5  #include "transport.h"
     8.6  #include "sync.h"
     8.7 +#include "Sync_func.h"
     8.8  
     8.9  #define NOT_IMPLEMENTED assert(0); return PEP_UNKNOWN_ERROR;
    8.10  
    8.11 @@ -182,7 +183,6 @@
    8.12      // sequence value
    8.13      sqlite3_stmt *sequence_value1;
    8.14      sqlite3_stmt *sequence_value2;
    8.15 -    sqlite3_stmt *sequence_value3;
    8.16  
    8.17      // revoked keys
    8.18      sqlite3_stmt *set_revoked;
    8.19 @@ -207,13 +207,15 @@
    8.20      inject_sync_msg_t inject_sync_msg;
    8.21      retrieve_next_sync_msg_t retrieve_next_sync_msg;
    8.22  
    8.23 -    // key sync
    8.24 +    // pEp Sync
    8.25      pEpSession* sync_session;
    8.26 -    DeviceState_state sync_state;
    8.27 -    void* sync_state_payload;
    8.28 -    char sync_uuid[37];
    8.29 -    time_t LastCannotDecrypt;
    8.30 -    time_t LastUpdateRequest;
    8.31 +    struct Sync_state_s sync_state;
    8.32 +    struct own_Sync_state_s own_sync_state;
    8.33 +
    8.34 +//     void* sync_state_payload;
    8.35 +//     char sync_uuid[37];
    8.36 +//     time_t LastCannotDecrypt;
    8.37 +//     time_t LastUpdateRequest;
    8.38  
    8.39      // runtime config
    8.40  
     9.1 --- a/src/platform_unix.h	Tue Aug 07 17:16:03 2018 +0200
     9.2 +++ b/src/platform_unix.h	Thu Aug 09 12:15:44 2018 +0200
     9.3 @@ -9,6 +9,7 @@
     9.4  #include <unistd.h>
     9.5  #include <strings.h>
     9.6  #include <sys/select.h>
     9.7 +#include <sys/param.h>
     9.8  #include <regex.h>
     9.9  
    9.10  #ifndef ANDROID
    10.1 --- a/src/platform_windows.h	Tue Aug 07 17:16:03 2018 +0200
    10.2 +++ b/src/platform_windows.h	Thu Aug 09 12:15:44 2018 +0200
    10.3 @@ -30,6 +30,11 @@
    10.4  #define RTLD_LAZY 1
    10.5  #define mode_t int
    10.6  
    10.7 +#ifndef MIN
    10.8 +#define MIN(A, B) ((A)>(B) ? (B) : (A))
    10.9 +#define MAX(A, B) ((A)>(B) ? (A) : (B))
   10.10 +#endif
   10.11 +
   10.12  void *dlopen(const char *filename, int flag);
   10.13  int dlclose(void *handle);
   10.14  void *dlsym(void *handle, const char *symbol);
    11.1 --- a/src/sync.c	Tue Aug 07 17:16:03 2018 +0200
    11.2 +++ b/src/sync.c	Thu Aug 09 12:15:44 2018 +0200
    11.3 @@ -7,7 +7,7 @@
    11.4  #include <assert.h>
    11.5  
    11.6  #include "asn1_helper.h"
    11.7 -#include "../asn.1/DeviceGroup-Protocol.h"
    11.8 +#include "KeySync_fsm.h"
    11.9  
   11.10  // receive_sync_msg is defined in the sync_impl
   11.11  
   11.12 @@ -30,10 +30,6 @@
   11.13      if (!(session && management && messageToSend && notifyHandshake && inject_sync_msg && retrieve_next_sync_msg))
   11.14          return PEP_ILLEGAL_VALUE;
   11.15  
   11.16 -    pEpUUID uuid;
   11.17 -    uuid_generate_random(uuid);
   11.18 -    uuid_unparse_upper(uuid, session->sync_uuid);
   11.19 -
   11.20      session->sync_management = management;
   11.21      session->messageToSend = messageToSend;
   11.22      session->notifyHandshake = notifyHandshake;
   11.23 @@ -41,9 +37,7 @@
   11.24      session->retrieve_next_sync_msg = retrieve_next_sync_msg;
   11.25  
   11.26      // start state machine
   11.27 -    session->sync_state = InitState;
   11.28 -    time_t unused = 0;
   11.29 -    PEP_STATUS status = fsm_DeviceState_inject(session, Init, NULL, NULL, &unused);
   11.30 +    PEP_STATUS status = inject_Sync_event(session, Sync_PR_keysync, Init);
   11.31      if (status != PEP_STATUS_OK)
   11.32          unregister_sync_callbacks(session);
   11.33  
   11.34 @@ -95,7 +89,7 @@
   11.35  
   11.36  DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session) {
   11.37      // stop state machine
   11.38 -    session->sync_state = DeviceState_state_NONE;
   11.39 +    memset(&session->sync_state, 0, sizeof(session->sync_state));
   11.40  
   11.41      // unregister
   11.42      session->sync_management = NULL;
   11.43 @@ -107,7 +101,7 @@
   11.44  
   11.45  DYNAMIC_API PEP_STATUS deliverHandshakeResult(
   11.46          PEP_SESSION session,
   11.47 -        Identity partner,
   11.48 +        pEp_identity *partner,
   11.49          sync_handshake_result result
   11.50      )
   11.51  {
   11.52 @@ -117,7 +111,7 @@
   11.53  
   11.54      PEP_STATUS status = PEP_STATUS_OK;
   11.55  
   11.56 -    DeviceState_event event;
   11.57 +    int event;
   11.58      bool need_partner = false;
   11.59  
   11.60      switch (result) {
   11.61 @@ -126,14 +120,12 @@
   11.62              break;
   11.63          case SYNC_HANDSHAKE_ACCEPTED:
   11.64          {
   11.65 -            event = HandshakeAccepted;
   11.66 -            need_partner = true;
   11.67 +            event = Accept;
   11.68              break;
   11.69          }
   11.70          case SYNC_HANDSHAKE_REJECTED:
   11.71          {
   11.72 -            event = HandshakeRejected;
   11.73 -            need_partner = true;
   11.74 +            event = Reject;
   11.75              break;
   11.76          }
   11.77          default:
    12.1 --- a/src/sync.h	Tue Aug 07 17:16:03 2018 +0200
    12.2 +++ b/src/sync.h	Thu Aug 09 12:15:44 2018 +0200
    12.3 @@ -1,218 +1,38 @@
    12.4  // This file is under GNU General Public License 3.0
    12.5  // see LICENSE.txt
    12.6  
    12.7 -/*
    12.8 -====================================
    12.9 -Engine/adapter/app KeySync interface 
   12.10 -====================================
   12.11 -
   12.12 -
   12.13 -         Engine         |          Adapter            |          App
   12.14 -                        |                             |
   12.15 - . . . . . . . . . . . .|. . . . . . . . . . . . . . .|. . Attached session .  
   12.16 -     ,---------,        |                             |
   12.17 -   ,-| decrypt |<--------------------------------------- Incomming message 
   12.18 -   | | message |        |                             |
   12.19 -   | '---------'        |                             |
   12.20 -   | ,----------,       |                             |
   12.21 -   |-| myself   |<-------------------------------------- Create new account
   12.22 -   | | (keygen) |       |                             |
   12.23 -   | '----------'       |                             |
   12.24 -   | ,-----------,      |                             |
   12.25 -   |-| deliver   |<------------------------------------------- Accept/reject
   12.26 -   | | handshake |      |                     KeySync |            handshake
   12.27 -   | | result    |      |                     Message |
   12.28 -   | '-----------'      |                      Queue  |
   12.29 -   |                    |                      ,---,  |
   12.30 -   '-----------------------inject_sync_msg---->|   |  |
   12.31 - . . . . . . . . . . . .|. . . . . . . . . . . |---| .|. . . . Sync session .  
   12.32 - *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *|   |* | 
   12.33 -                        |                      |---|  | 
   12.34 - *   ,------------------retrieve_next_sync_msg-|   |* | 
   12.35 -   ,-v--------,         |                      '---'  | 
   12.36 - * | Driver   |         |                           * |
   12.37 -   '----------'         |                             |
   12.38 - *  ||'-event-----,     |                           * |
   12.39 -    |'--partner--,|     |                             |
   12.40 - *  '---extra---,||     |           SYNC THREAD     *<-------------- Start Sync
   12.41 -            ,---vvv---, |                             |
   12.42 - *     ,----|   FSM   | |                           * |
   12.43 -       |    '---------' |                             |
   12.44 - *     |  ,-------,     |                           * |
   12.45 -       '->|actions|---------messageToSend-------------------> Send mail to self
   12.46 - *        '-------'     |                           * |
   12.47 -              '-------------notifyHandshake-----------------> Ask for handshake
   12.48 - *                      |                           * |    display group status
   12.49 -                        |                             |
   12.50 - *  *  *  *  *  *  *  * |*  *  *  *  *  *  *  *  *  * |
   12.51 -                        |                             |
   12.52 -
   12.53 -Emails to self
   12.54 ---------------
   12.55 -
   12.56 -With e-mail as a transport KeySync message handling is done when an incoming 
   12.57 -email to self is passed to decrypt_message(), assuming that all incoming email
   12.58 -messages are passed to decrypt_massage(). 
   12.59 -
   12.60 -In case of an email containing a KeySync paload, KeySync may consume or ignore
   12.61 -the message. decrypt_message() signals this to the app with decrypt flags
   12.62 -PEP_decrypt_flag_consume and PEP_decrypt_flag_ignore.
   12.63 -
   12.64 -In case of PEP_decrypt_flag_consume, app should delete the message.
   12.65 -In case of PEP_decrypt_flag_ignore, app should ignore message.
   12.66 -In both cases, message should be hidden.
   12.67 -
   12.68 -States, events, actions
   12.69 ------------------------
   12.70 -
   12.71 -In the engine, KeySync is implemented through a finite state machine (FSM) [1].
   12.72 -KeySync state machine is driven [2] by events, triggering actions [3] and
   12.73 -transitions to new states.
   12.74 -
   12.75 -Events happen on :
   12.76 -
   12.77 - - decryption of email messages
   12.78 -
   12.79 - - key generation
   12.80 -
   12.81 - - user interaction through the app 
   12.82 -
   12.83 - - timeout when staying too long in some particular states.
   12.84 -
   12.85 -[1] sync/devicegroup.fsm , src/sync_fsm.c (generated)
   12.86 -[2] src/sync_driver.c (generated)
   12.87 -[3] src/sync_actions.c , src/sync_send_actions.c (generated)
   12.88 -
   12.89 -Sync session, attached sessions
   12.90 --------------------------------
   12.91 -
   12.92 -To use KeySync, the adapter has to create a session dedicated to handle the
   12.93 -protocol, register some callbacks [4] to the engine, and then call protocol's
   12.94 -event consumer loop [5] in a dedicated thread. KeySync actions are executed as
   12.95 -callback invoked from that thread.
   12.96 -
   12.97 -When a session is attached [6] to a KeySync session, decryption of pEp email
   12.98 -messages in the attached session may trigger operations in KeySync session. In
   12.99 -case of an adapter capable to serve multiple apps, each app is associated to a
  12.100 -different KeySync session, and sessions created for use in that app are
  12.101 -attached to that session.
  12.102 -
  12.103 -Adapters present different approaches regarding session and client abstraction,
  12.104 -and may not propose to explicitely create or attach session or sync session.
  12.105 -
  12.106 -[4] register_sync_callbacks()
  12.107 -[5] do_sync_protocol()
  12.108 -[6] attach_sync_session()
  12.109 -
  12.110 -KeySync Messages and queue
  12.111 ---------------------------
  12.112 -
  12.113 -KeySync messages [7], not to be confused with pEp (email) messages, are either
  12.114 -directly events to be processed by the state machine, or KeySync payloads
  12.115 -collected from decrypted messages. 
  12.116 -
  12.117 -KeySync messages can be emitted by different sessions, and could naturally come
  12.118 -from different threads. They must be serialized in a locked queue. 
  12.119 -KeySync messages queue is implemented by adapter, along with thread handling
  12.120 -KeySync protocol. 
  12.121 -
  12.122 -Attached sessions inject [8] KeySync messages in the queue. Protocol loop
  12.123 -retrieves [9] them from the queue. KeySync message is received [10] by the
  12.124 -state machine, where event, partner and extra parameters are eventually deduced
  12.125 -from payload.
  12.126 -
  12.127 -A state timeout event is a particular case. It doesn't traverse the queue, and
  12.128 -isn't emitted by a session. It is triggered by a timeout on the retrieve
  12.129 -operation. Value of the timeout is determined when entering a new state, and is
  12.130 -passed as a parameter of the call to the blocking queue retrieve operation on 
  12.131 -next protocol loop iteraton.
  12.132 -
  12.133 -[7] type sync_msg_t
  12.134 -[8] callback inject_sync_msg
  12.135 -[9] callback retrieve_next_sync_msg
  12.136 -[10] receive_sync_msg() (src/sync_impl.c)
  12.137 -
  12.138 -Application callbacks
  12.139 ----------------------
  12.140 -
  12.141 -Some Keysync actions require the application to act, through callbacks :
  12.142 -
  12.143 - - messageToSend : send pEp messages through app's transport. 
  12.144 -   Messages are already encrypted and just need to be passed as-is to
  12.145 -   transport for transmission, as for messages returned by encrypt_message().
  12.146 -
  12.147 - - notifyHandshake : display KeySync status and handshake to the user.
  12.148 -   notifyHandshake callback receives 2 identities, 'me' and 'partner', together
  12.149 -   with a sync_handshake_signal enum :
  12.150 -
  12.151 -    SYNC_NOTIFY_INIT_ADD_OUR_DEVICE :
  12.152 -        Device (me) is sole, about to enter a group (partner).
  12.153 -        App displays trustwords, and requests user accept or reject
  12.154 -        App calls deliverHandshakeResult with user's answer
  12.155 -
  12.156 -    SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE :
  12.157 -        Device (me) is grouped, another device (partner) wants to join group.
  12.158 -        App displays trustwords, and requests user accept or reject
  12.159 -        App calls deliverHandshakeResult with user's answer
  12.160 -
  12.161 -    SYNC_NOTIFY_INIT_FORM_GROUP :
  12.162 -        Device (me) is forming a group, including another device (partner)
  12.163 -        App displays trustwords, and requests user accept or reject
  12.164 -        App calls deliverHandshakeResult with user's answer
  12.165 -
  12.166 -    SYNC_NOTIFY_INIT_MOVE_OUR_DEVICE
  12.167 -        Device (me) is grouped and will leave current group to join another
  12.168 -        device's (partner) group.
  12.169 -        App displays trustwords, and requests user accept or reject
  12.170 -        App calls deliverHandshakeResult with user's answer
  12.171 -
  12.172 -
  12.173 -    SYNC_NOTIFY_TIMEOUT :
  12.174 -        KeySync operation timed out.
  12.175 -        Identities are set reflecting peers involved in aborted operation.
  12.176 -        App displays error message. No feedback to engine.
  12.177 -
  12.178 -    SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED,
  12.179 -        New device was added to group.
  12.180 -        App displays message. No feedback to engine.
  12.181 -
  12.182 -    SYNC_NOTIFY_ACCEPTED_GROUP_CREATED
  12.183 -        New group created.
  12.184 -        App displays message. No feedback to engine.
  12.185 -
  12.186 -    SYNC_NOTIFY_ACCEPTED_DEVICE_MOVED
  12.187 -        New device was moved from one group to another.
  12.188 -        App displays message. No feedback to engine.
  12.189 -
  12.190 -   To deliver handshake result back to engine once user reacted,
  12.191 -   deliver_handshake_result is used. Result can be :
  12.192 -
  12.193 -    SYNC_HANDSHAKE_CANCEL
  12.194 -        Gives no answer. User doesn't know id TrustWord are good or bad.
  12.195 -        For example in case peering device is away.
  12.196 -        Handshake will re-appear later.
  12.197 -
  12.198 -    SYNC_HANDSHAKE_ACCEPTED
  12.199 -        Trustwords match with other device and user accepts handshake.
  12.200 -
  12.201 -    SYNC_HANDSHAKE_REJECTED
  12.202 -        Trustwords do not match with any device and user rejects handshake.
  12.203 -*/
  12.204 +// this module is for being used WITHOUT the Transport API in transport.h
  12.205 +// DO NOT USE IT WHEN USING Transport API!
  12.206  
  12.207  #pragma once
  12.208  
  12.209  #include "message.h"
  12.210 -#include "sync_fsm.h"
  12.211 -#include "sync_app.h"
  12.212 -
  12.213 -// this module is for being used WITHOUT the Transport API in transport.h
  12.214 -// DO NOT USE IT WHEN USING Transport API!
  12.215 -
  12.216  
  12.217  #ifdef __cplusplus
  12.218  extern "C" {
  12.219  #endif
  12.220  
  12.221 +typedef enum _sync_handshake_signal {
  12.222 +    SYNC_NOTIFY_UNDEFINED = 0,
  12.223 +
  12.224 +    // request show handshake dialog
  12.225 +    SYNC_NOTIFY_INIT_ADD_OUR_DEVICE,
  12.226 +    SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE,
  12.227 +    SYNC_NOTIFY_INIT_FORM_GROUP,
  12.228 +    SYNC_NOTIFY_INIT_MOVE_OUR_DEVICE,
  12.229 +
  12.230 +    // handshake process timed out
  12.231 +    SYNC_NOTIFY_TIMEOUT,
  12.232 +
  12.233 +    // handshake accepted by user
  12.234 +    SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED,
  12.235 +    SYNC_NOTIFY_ACCEPTED_GROUP_CREATED,
  12.236 +    SYNC_NOTIFY_ACCEPTED_DEVICE_MOVED,
  12.237 +
  12.238 +    // handshake dialog must be closed
  12.239 +    SYNC_NOTIFY_OVERTAKEN
  12.240 +} sync_handshake_signal;
  12.241 +
  12.242  // messageToSend() - send a message
  12.243  //
  12.244  //  parameters:
  12.245 @@ -262,7 +82,7 @@
  12.246  
  12.247  DYNAMIC_API PEP_STATUS deliverHandshakeResult(
  12.248          PEP_SESSION session,
  12.249 -        Identity partner,
  12.250 +        pEp_identity *partner,
  12.251          sync_handshake_result result
  12.252      );
  12.253  
    13.1 --- a/src/sync_actions.c	Tue Aug 07 17:16:03 2018 +0200
    13.2 +++ b/src/sync_actions.c	Thu Aug 09 12:15:44 2018 +0200
    13.3 @@ -1,6 +1,9 @@
    13.4  // This file is under GNU General Public License 3.0
    13.5  // see LICENSE.txt
    13.6  
    13.7 +#include "pEp_internal.h"
    13.8 +#include "map_asn1.h"
    13.9 +
   13.10  #include "Sync_impl.h"
   13.11  #include "KeySync_fsm.h"
   13.12  
   13.13 @@ -11,7 +14,7 @@
   13.14          return PEP_ILLEGAL_VALUE;
   13.15  
   13.16      static const char *sql = "select count(*) from identity where user_id = '"PEP_OWN_USERID"' and (flags & 4) = 4;";
   13.17 -    static const size_t len = strlen(sql);
   13.18 +    static const size_t len = sizeof("select count(*) from identity where user_id = '"PEP_OWN_USERID"' and (flags & 4) = 4;");
   13.19      sqlite3_stmt *_sql;
   13.20      int int_result = sqlite3_prepare_v2(session->db, sql, (int) len, &_sql, NULL);
   13.21      assert(int_result == SQLITE_OK);
   13.22 @@ -115,7 +118,7 @@
   13.23      pEpUUID c;
   13.24      uuid_generate_random(c);
   13.25  
   13.26 -    OCTET_STRING_fromBuf(&session->own_sync_state.challenge, c, 16);
   13.27 +    OCTET_STRING_fromBuf(&session->own_sync_state.challenge, (char *) c, 16);
   13.28  
   13.29      return PEP_STATUS_OK;
   13.30  }
   13.31 @@ -147,7 +150,7 @@
   13.32      pEpUUID c;
   13.33      uuid_generate_random(c);
   13.34  
   13.35 -    OCTET_STRING_fromBuf(&session->own_sync_state.transaction, c, 16);
   13.36 +    OCTET_STRING_fromBuf(&session->own_sync_state.transaction, (char *) c, 16);
   13.37  
   13.38      return PEP_STATUS_OK;
   13.39  }
   13.40 @@ -184,6 +187,7 @@
   13.41      if (!session->sync_state.basic.from)
   13.42          return PEP_ILLEGAL_VALUE;
   13.43  
   13.44 +    pEp_identity *from = session->sync_state.basic.from;
   13.45      pEp_identity *me = NULL;
   13.46      PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
   13.47      assert(status == PEP_STATUS_OK);
   13.48 @@ -196,14 +200,14 @@
   13.49          return PEP_ILLEGAL_VALUE;
   13.50      }
   13.51  
   13.52 -    pEp_identity *partner = identity_dup(session->sync_state.basic.from);
   13.53 +    pEp_identity *partner = identity_dup(from);
   13.54      if (!partner) {
   13.55          free_identity(me);
   13.56          return PEP_OUT_OF_MEMORY;
   13.57      }
   13.58  
   13.59 -    PEP_STATUS status = session->notifyHandshake(
   13.60 -            session->sync_management, me, partner, SYNC_NOTIFY_INIT_FORM_GROUP);
   13.61 +    status = session->notifyHandshake(session->sync_management, me,
   13.62 +            partner, SYNC_NOTIFY_INIT_FORM_GROUP);
   13.63      if (status)
   13.64          return status;
   13.65  
   13.66 @@ -258,7 +262,14 @@
   13.67          "   join trust on id = trust.user_id"
   13.68          "       and pgp_keypair_fpr = identity.main_key_id"
   13.69          "   where identity.user_id = '" PEP_OWN_USERID "';";
   13.70 -    static const size_t len = strlen(sql);
   13.71 +    static const size_t len = sizeof("select fpr, username, comm_type, lang,"
   13.72 +        "   identity.flags | pgp_keypair.flags"
   13.73 +        "   from identity"
   13.74 +        "   join person on id = identity.user_id"
   13.75 +        "   join pgp_keypair on fpr = identity.main_key_id"
   13.76 +        "   join trust on id = trust.user_id"
   13.77 +        "       and pgp_keypair_fpr = identity.main_key_id"
   13.78 +        "   where identity.user_id = '" PEP_OWN_USERID "';");
   13.79      sqlite3_stmt *_sql;
   13.80      int int_result = sqlite3_prepare_v2(session->db, sql, (int) len, &_sql, NULL);
   13.81      assert(int_result == SQLITE_OK);
   13.82 @@ -269,6 +280,7 @@
   13.83      if (!il)
   13.84          return PEP_OUT_OF_MEMORY;
   13.85  
   13.86 +    pEp_identity *from = session->sync_state.basic.from;
   13.87      identity_list *_il = il;
   13.88  
   13.89      int result;
   13.90 @@ -278,9 +290,9 @@
   13.91          switch (result) {
   13.92          case SQLITE_ROW:
   13.93              _identity = new_identity(
   13.94 -                    address,
   13.95 +                    from->address,
   13.96                      (const char *) sqlite3_column_text(_sql, 0),
   13.97 -                    user_id,
   13.98 +                    from->user_id,
   13.99                      (const char *) sqlite3_column_text(_sql, 1)
  13.100                      );
  13.101              assert(_identity);
  13.102 @@ -315,7 +327,7 @@
  13.103  
  13.104          default:
  13.105              free_identity_list(il);
  13.106 -            return PEP_UNKOWN_ERROR;
  13.107 +            return PEP_UNKNOWN_ERROR;
  13.108          }
  13.109      } while (result != SQLITE_DONE);
  13.110  
  13.111 @@ -341,6 +353,7 @@
  13.112      if (!session->sync_state.basic.from)
  13.113          return PEP_ILLEGAL_VALUE;
  13.114  
  13.115 +    pEp_identity *from = session->sync_state.basic.from;
  13.116      pEp_identity *me = NULL;
  13.117      PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
  13.118      assert(status == PEP_STATUS_OK);
  13.119 @@ -353,14 +366,14 @@
  13.120          return PEP_ILLEGAL_VALUE;
  13.121      }
  13.122  
  13.123 -    pEp_identity *partner = identity_dup(session->sync_state.basic.from);
  13.124 +    pEp_identity *partner = identity_dup(from);
  13.125      if (!partner) {
  13.126          free_identity(me);
  13.127          return PEP_OUT_OF_MEMORY;
  13.128      }
  13.129  
  13.130 -    PEP_STATUS status = session->notifyHandshake(
  13.131 -            session->sync_management, me, partner, SYNC_NOTIFY_INIT_ADD_OUR_DEVICE);
  13.132 +    status = session->notifyHandshake(session->sync_management, me,
  13.133 +            partner, SYNC_NOTIFY_INIT_ADD_OUR_DEVICE);
  13.134      if (status)
  13.135          return status;
  13.136  
  13.137 @@ -381,6 +394,7 @@
  13.138      if (!session->sync_state.basic.from)
  13.139          return PEP_ILLEGAL_VALUE;
  13.140  
  13.141 +    pEp_identity *from = session->sync_state.basic.from;
  13.142      pEp_identity *me = NULL;
  13.143      PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
  13.144      assert(status == PEP_STATUS_OK);
  13.145 @@ -393,14 +407,14 @@
  13.146          return PEP_ILLEGAL_VALUE;
  13.147      }
  13.148  
  13.149 -    pEp_identity *partner = identity_dup(session->sync_state.basic.from);
  13.150 +    pEp_identity *partner = identity_dup(from);
  13.151      if (!partner) {
  13.152          free_identity(me);
  13.153          return PEP_OUT_OF_MEMORY;
  13.154      }
  13.155  
  13.156 -    PEP_STATUS status = session->notifyHandshake(
  13.157 -            session->sync_management, me, partner, SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE);
  13.158 +    status = session->notifyHandshake(session->sync_management, me,
  13.159 +            partner, SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE);
  13.160      if (status)
  13.161          return status;
  13.162  
    14.1 --- a/src/sync_app.h	Tue Aug 07 17:16:03 2018 +0200
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,34 +0,0 @@
    14.4 -//
    14.5 -//  sync_app.h
    14.6 -//  pEpEngine
    14.7 -//
    14.8 -//  Created by Dirk Zimmermann on 16.05.17.
    14.9 -//  Copyright © 2017 Edouard Tisserant. All rights reserved.
   14.10 -//
   14.11 -
   14.12 -#ifndef sync_app_h
   14.13 -#define sync_app_h
   14.14 -
   14.15 -// TODO add this to generated code.
   14.16 -typedef enum _sync_handshake_signal {
   14.17 -    SYNC_NOTIFY_UNDEFINED = 0,
   14.18 -
   14.19 -    // request show handshake dialog
   14.20 -    SYNC_NOTIFY_INIT_ADD_OUR_DEVICE,
   14.21 -    SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE,
   14.22 -    SYNC_NOTIFY_INIT_FORM_GROUP,
   14.23 -    SYNC_NOTIFY_INIT_MOVE_OUR_DEVICE,
   14.24 -
   14.25 -    // handshake process timed out
   14.26 -    SYNC_NOTIFY_TIMEOUT,
   14.27 -
   14.28 -    // handshake accepted by user
   14.29 -    SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED,
   14.30 -    SYNC_NOTIFY_ACCEPTED_GROUP_CREATED,
   14.31 -    SYNC_NOTIFY_ACCEPTED_DEVICE_MOVED,
   14.32 -
   14.33 -    // handshake dialog must be closed
   14.34 -    SYNC_NOTIFY_OVERTAKEN
   14.35 -} sync_handshake_signal;
   14.36 -
   14.37 -#endif /* sync_app_h */
    15.1 --- a/sync/Makefile	Tue Aug 07 17:16:03 2018 +0200
    15.2 +++ b/sync/Makefile	Thu Aug 09 12:15:44 2018 +0200
    15.3 @@ -6,8 +6,8 @@
    15.4  all: .codegen
    15.5  
    15.6  .codegen: .statemachines .actions .codecs .messages
    15.7 -	cp -f generated/*.c generated/*.h ../src
    15.8  	touch .codegen
    15.9 +	make copy
   15.10  
   15.11  .actions: sync.fsm gen_actions.ysl2 fsm.yml2 functions.ysl2 cond_act.yml2
   15.12  	$(YML2_PROC) -y gen_actions.ysl2 $< -o $@
   15.13 @@ -21,13 +21,16 @@
   15.14  .messages: sync.fsm gen_messages.ysl2 fsm.yml2 functions.ysl2
   15.15  	$(YML2_PROC) -y gen_messages.ysl2 $< -o $@
   15.16  
   15.17 -.PHONY: clean
   15.18 +.PHONY: clean copy
   15.19  
   15.20  clean:
   15.21  	rm -f *.xml *.xsl \
   15.22      $(pathsub generated/%, ../src/% $(wildcard generated/*.*)) \
   15.23      ../generated/* .statemachines .actions .codecs .messages *.dot *.svg
   15.24  
   15.25 +copy:
   15.26 +	cp -f generated/*.c generated/*.h ../src
   15.27 +
   15.28  %.xml: %.fsm
   15.29  	yml2c $< -o $@
   15.30  
    16.1 --- a/sync/fsm.yml2	Tue Aug 07 17:16:03 2018 +0200
    16.2 +++ b/sync/fsm.yml2	Thu Aug 09 12:15:44 2018 +0200
    16.3 @@ -26,6 +26,10 @@
    16.4  
    16.5  decl event @name, on is event;
    16.6  
    16.7 +// external events can have IDs
    16.8 +
    16.9 +decl external @name (id);
   16.10 +
   16.11  // a transistion moves the statemachine to another state
   16.12  
   16.13  decl transition @target, go is transition;
    17.1 --- a/sync/gen_actions.ysl2	Tue Aug 07 17:16:03 2018 +0200
    17.2 +++ b/sync/gen_actions.ysl2	Thu Aug 09 12:15:44 2018 +0200
    17.3 @@ -29,6 +29,9 @@
    17.4              // This file is under GNU General Public License 3.0
    17.5              // see LICENSE.txt
    17.6  
    17.7 +            #include "pEp_internal.h"
    17.8 +            #include "map_asn1.h"
    17.9 +
   17.10              #include "«@name»_impl.h"
   17.11              `` for "fsm" | #include "«@name»_fsm.h"
   17.12  
    18.1 --- a/sync/gen_statemachine.ysl2	Tue Aug 07 17:16:03 2018 +0200
    18.2 +++ b/sync/gen_statemachine.ysl2	Thu Aug 09 12:15:44 2018 +0200
    18.3 @@ -326,8 +326,12 @@
    18.4              const "name", "@name";
    18.5              |> «$name» = «/protocol/fsm/message[@name=$name]/@id»,
    18.6          }
    18.7 +        for "func:distinctName(state/event[not(not(../../external/@name=@name))])" {
    18.8 +            const "name", "@name";
    18.9 +            |> «$name» = «/protocol/fsm/external[@name=$name]/@id»,
   18.10 +        }
   18.11          |> «@name»_event_Extra = Extra,
   18.12 -        for "func:distinctName(state/event[not(../../message/@name=@name)])" {
   18.13 +        for "func:distinctName(state/event[not(../../message/@name=@name or ../../external/@name=@name)])" {
   18.14              if "@name!='Init'"
   18.15                  |> «@name»`if "position()!=last()" > , `
   18.16          }