some encoding sync
authorVolker Birk <vb@pep.foundation>
Mon, 13 Aug 2018 15:33:42 +0200
branchsync
changeset 2840b881c48c9e9d
parent 2839 d9f7cb22f1d1
child 2841 3b56e21206cd
some encoding
.hgignore
src/Sync_helper.c
src/Sync_helper.h
src/growing_buf.c
src/growing_buf.h
src/sync.c
src/sync.h
src/sync_impl.c
sync/Makefile
sync/gen_codec.ysl2
sync/gen_statemachine.ysl2
sync/sync.fsm
     1.1 --- a/.hgignore	Sat Aug 11 21:45:50 2018 +0200
     1.2 +++ b/.hgignore	Mon Aug 13 15:33:42 2018 +0200
     1.3 @@ -69,6 +69,8 @@
     1.4  src/Sync_func.h
     1.5  src/Sync_event.c
     1.6  src/Sync_event.h
     1.7 +src/Sync_codec.c
     1.8 +src/Sync_codec.h
     1.9  asn.1/keysync.asn1
    1.10  asn.1/sync.asn1
    1.11  sync/.codecs
    1.12 @@ -76,4 +78,3 @@
    1.13  sync/.actions
    1.14  sync/.codegen
    1.15  sync/.statemachines
    1.16 -
     2.1 --- a/src/Sync_helper.c	Sat Aug 11 21:45:50 2018 +0200
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,124 +0,0 @@
     2.4 -// This file is under GNU General Public License 3.0
     2.5 -// see LICENSE.txt
     2.6 -
     2.7 -#include "Sync_helper.h"
     2.8 -#include "pEp_internal.h"
     2.9 -
    2.10 -typedef struct growing_buf {
    2.11 -    char *data;
    2.12 -    size_t size;
    2.13 -} growing_buf_t;
    2.14 -
    2.15 -growing_buf_t *new_growing_buf(void)
    2.16 -{
    2.17 -    growing_buf_t *result = calloc(1, sizeof(growing_buf_t));
    2.18 -    assert(result);
    2.19 -    return result;
    2.20 -}
    2.21 -
    2.22 -void free_growing_buf(growing_buf_t *buf)
    2.23 -{
    2.24 -    if (buf) {
    2.25 -        free(buf->data);
    2.26 -        free(buf);
    2.27 -    }
    2.28 -}
    2.29 -
    2.30 -int consume_bytes(const void *src, size_t size, growing_buf_t *dst)
    2.31 -{
    2.32 -    assert(src && dst);
    2.33 -    if (!(src && dst))
    2.34 -        return -1;
    2.35 -
    2.36 -    char *new_data = realloc(dst->data, dst->size + size + 1);
    2.37 -    assert(new_data);
    2.38 -    if (!new_data)
    2.39 -        return -1;
    2.40 -    dst->data = new_data;
    2.41 -    memcpy(dst->data + dst->size, src, size);
    2.42 -    dst->size += size;
    2.43 -    dst->data[dst->size] = 0; // safeguard
    2.44 -
    2.45 -    return 1;
    2.46 -}
    2.47 -
    2.48 -DYNAMIC_API PEP_STATUS decode_sync_msg(
    2.49 -        const char *data,
    2.50 -        size_t size,
    2.51 -        char **text
    2.52 -    )
    2.53 -{
    2.54 -    PEP_STATUS status = PEP_STATUS_OK;
    2.55 -
    2.56 -    assert(data && text);
    2.57 -    if (!(data && text))
    2.58 -        return PEP_ILLEGAL_VALUE;
    2.59 -
    2.60 -    *text = NULL;
    2.61 -
    2.62 -    Sync_t *msg = NULL;
    2.63 -    uper_decode_complete(NULL, &asn_DEF_Sync, (void **) &msg, data, size);
    2.64 -    if (!msg)
    2.65 -        return PEP_SYNC_ILLEGAL_MESSAGE;
    2.66 -
    2.67 -    growing_buf_t *dst = new_growing_buf();
    2.68 -    if (!dst) {
    2.69 -        status = PEP_OUT_OF_MEMORY;
    2.70 -        goto the_end;
    2.71 -    }
    2.72 -
    2.73 -    asn_enc_rval_t er = xer_encode(&asn_DEF_Sync, msg, XER_F_BASIC,
    2.74 -            (asn_app_consume_bytes_f *) consume_bytes, (void *) dst);
    2.75 -    if (er.encoded == -1) {
    2.76 -        status = PEP_CANNOT_ENCODE;
    2.77 -        goto the_end;
    2.78 -    }
    2.79 -
    2.80 -    *text = dst->data;
    2.81 -    dst->data = NULL;
    2.82 -
    2.83 -the_end:
    2.84 -    free_growing_buf(dst);
    2.85 -    ASN_STRUCT_FREE(asn_DEF_Sync, msg);
    2.86 -    return status;
    2.87 -}
    2.88 -
    2.89 -DYNAMIC_API PEP_STATUS encode_sync_msg(
    2.90 -        const char *text,
    2.91 -        char **data,
    2.92 -        size_t *size
    2.93 -    )
    2.94 -{
    2.95 -    PEP_STATUS status = PEP_STATUS_OK;
    2.96 -
    2.97 -    assert(text && data && size);
    2.98 -    if (!(text && data && size))
    2.99 -        return PEP_ILLEGAL_VALUE;
   2.100 -
   2.101 -    *data = NULL;
   2.102 -    *size = 0;
   2.103 -
   2.104 -    Sync_t *msg = NULL;
   2.105 -    asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_Sync, (void **) &msg,
   2.106 -            (const void *) text, strlen(text));
   2.107 -    if (dr.code != RC_OK) {
   2.108 -        status = PEP_SYNC_ILLEGAL_MESSAGE;
   2.109 -        goto the_end;
   2.110 -    }
   2.111 -
   2.112 -    char *payload = NULL;
   2.113 -    ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_Sync, NULL, msg,
   2.114 -            (void **) &payload);
   2.115 -    if (_size == -1) {
   2.116 -        status = PEP_CANNOT_ENCODE;
   2.117 -        goto the_end;
   2.118 -    }
   2.119 -
   2.120 -    *data = payload;
   2.121 -    *size = (size_t) _size;
   2.122 -
   2.123 -the_end:
   2.124 -    ASN_STRUCT_FREE(asn_DEF_Sync, msg);
   2.125 -    return status;
   2.126 -}
   2.127 -
     3.1 --- a/src/Sync_helper.h	Sat Aug 11 21:45:50 2018 +0200
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,45 +0,0 @@
     3.4 -// This file is under GNU General Public License 3.0
     3.5 -// see LICENSE.txt
     3.6 -
     3.7 -#pragma once
     3.8 -
     3.9 -
    3.10 -#include "pEpEngine.h"
    3.11 -
    3.12 -
    3.13 -#ifdef __cplusplus
    3.14 -extern "C" {
    3.15 -#endif
    3.16 -
    3.17 -// decode_sync_msg() - decode sync message from PER into XER
    3.18 -//
    3.19 -//  parameters:
    3.20 -//      data (in)               PER encoded data
    3.21 -//      size (in)               size of PER encoded data
    3.22 -//      text (out)              XER text of the same sync message
    3.23 -
    3.24 -DYNAMIC_API PEP_STATUS decode_sync_msg(
    3.25 -        const char *data,
    3.26 -        size_t size,
    3.27 -        char **text
    3.28 -    );
    3.29 -
    3.30 -
    3.31 -// encode_sync_msg() - encode sync message from XER into PER
    3.32 -//
    3.33 -//  parameters:
    3.34 -//      text (in)               string with XER text of the sync message
    3.35 -//      data (out)              PER encoded data
    3.36 -//      size (out)              size of PER encoded data
    3.37 -
    3.38 -DYNAMIC_API PEP_STATUS encode_sync_msg(
    3.39 -        const char *text,
    3.40 -        char **data,
    3.41 -        size_t *size
    3.42 -    );
    3.43 -
    3.44 -
    3.45 -#ifdef __cplusplus
    3.46 -}
    3.47 -#endif
    3.48 -
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/growing_buf.c	Mon Aug 13 15:33:42 2018 +0200
     4.3 @@ -0,0 +1,39 @@
     4.4 +// This file is under GNU General Public License 3.0
     4.5 +// see LICENSE.txt
     4.6 +
     4.7 +#include "pEp_internal.h"
     4.8 +#include "growing_buf.h"
     4.9 +
    4.10 +growing_buf_t *new_growing_buf(void)
    4.11 +{
    4.12 +    growing_buf_t *result = calloc(1, sizeof(growing_buf_t));
    4.13 +    assert(result);
    4.14 +    return result;
    4.15 +}
    4.16 +
    4.17 +void free_growing_buf(growing_buf_t *buf)
    4.18 +{
    4.19 +    if (buf) {
    4.20 +        free(buf->data);
    4.21 +        free(buf);
    4.22 +    }
    4.23 +}
    4.24 +
    4.25 +int growing_buf_consume(const void *src, size_t size, growing_buf_t *dst)
    4.26 +{
    4.27 +    assert(src && dst);
    4.28 +    if (!(src && dst))
    4.29 +        return -1;
    4.30 +
    4.31 +    char *new_data = realloc(dst->data, dst->size + size + 1);
    4.32 +    assert(new_data);
    4.33 +    if (!new_data)
    4.34 +        return -1;
    4.35 +    dst->data = new_data;
    4.36 +    memcpy(dst->data + dst->size, src, size);
    4.37 +    dst->size += size;
    4.38 +    dst->data[dst->size] = 0; // safeguard
    4.39 +
    4.40 +    return 1;
    4.41 +}
    4.42 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/growing_buf.h	Mon Aug 13 15:33:42 2018 +0200
     5.3 @@ -0,0 +1,56 @@
     5.4 +// This file is under GNU General Public License 3.0
     5.5 +// see LICENSE.txt
     5.6 +
     5.7 +#pragma once
     5.8 +
     5.9 +
    5.10 +#include "pEpEngine.h"
    5.11 +
    5.12 +
    5.13 +#ifdef __cplusplus
    5.14 +extern "C" {
    5.15 +#endif
    5.16 +
    5.17 +
    5.18 +// this is a growing buffer, which is needed by the ASN.1 implementation
    5.19 +// i.e. for encoding to XER
    5.20 +
    5.21 +typedef struct growing_buf {
    5.22 +    char *data;
    5.23 +    size_t size;
    5.24 +} growing_buf_t;
    5.25 +
    5.26 +
    5.27 +// new_growing_buf() - allocate a new growing buffer
    5.28 +//
    5.29 +//  return value:
    5.30 +//      new buffer or NULL if out of memory
    5.31 +
    5.32 +growing_buf_t *new_growing_buf(void);
    5.33 +
    5.34 +
    5.35 +// free_growing_buf() - free growing buffer
    5.36 +//
    5.37 +//  parameters:
    5.38 +//      buf (in)            buffer to free
    5.39 +
    5.40 +void free_growing_buf(growing_buf_t *buf);
    5.41 +
    5.42 +
    5.43 +// growing_buf_consume() - append new data to growing buffer
    5.44 +//
    5.45 +//  parameters:
    5.46 +//      src (in)            new data
    5.47 +//      size (in)           size of new data
    5.48 +//      dst (in)            growing buffer where new data will be appended
    5.49 +//
    5.50 +//  return value:
    5.51 +//      1 on succes, -1 on failure
    5.52 +
    5.53 +int growing_buf_consume(const void *src, size_t size, growing_buf_t *dst);
    5.54 +
    5.55 +
    5.56 +#ifdef __cplusplus
    5.57 +}
    5.58 +#endif
    5.59 +
     6.1 --- a/src/sync.c	Sat Aug 11 21:45:50 2018 +0200
     6.2 +++ b/src/sync.c	Mon Aug 13 15:33:42 2018 +0200
     6.3 @@ -88,7 +88,7 @@
     6.4          void *obj
     6.5      )
     6.6  {
     6.7 -    Sync_t *msg = NULL;
     6.8 +    Sync_event_t *event= NULL;
     6.9      PEP_STATUS status = PEP_STATUS_OK;
    6.10  
    6.11      assert(session && session->retrieve_next_sync_event);
    6.12 @@ -101,10 +101,10 @@
    6.13      while (true) 
    6.14      {
    6.15          event = session->retrieve_next_sync_event(session->sync_management);
    6.16 -        if (msg == NULL)
    6.17 +        if (!event)
    6.18              break;
    6.19  
    6.20 -        status = recv_Sync_event(session, msg);
    6.21 +        status = recv_Sync_event(session, event);
    6.22          if (status != PEP_STATUS_OK && status != PEP_MESSAGE_IGNORE) {
    6.23              char buffer[MAX_LINELENGTH];
    6.24              memset(buffer, 0, MAX_LINELENGTH);
     7.1 --- a/src/sync.h	Sat Aug 11 21:45:50 2018 +0200
     7.2 +++ b/src/sync.h	Mon Aug 13 15:33:42 2018 +0200
     7.3 @@ -95,7 +95,7 @@
     7.4  //  return value:
     7.5  //      next event
     7.6  
     7.7 -typedef struct Sync_event_t *(*retrieve_next_sync_event_t)(void *management);
     7.8 +typedef Sync_event_t *(*retrieve_next_sync_event_t)(void *management);
     7.9  
    7.10  
    7.11  // register_sync_callbacks() - register adapter's callbacks
     8.1 --- a/src/sync_impl.c	Sat Aug 11 21:45:50 2018 +0200
     8.2 +++ b/src/sync_impl.c	Mon Aug 13 15:33:42 2018 +0200
     8.3 @@ -131,6 +131,22 @@
     8.4      return status;
     8.5  }
     8.6  
     8.7 +PEP_STATUS send_Sync_message(
     8.8 +        PEP_SESSION session, 
     8.9 +        Sync_PR fsm,
    8.10 +        int event
    8.11 +    )
    8.12 +{
    8.13 +    PEP_STATUS status = PEP_STATUS_OK;
    8.14 +
    8.15 +    assert(session && fsm > None && event > None);
    8.16 +    if (!(session && fsm > None && event > None))
    8.17 +        return PEP_ILLEGAL_VALUE;
    8.18 +    
    8.19 +
    8.20 +    return status;
    8.21 +}
    8.22 +
    8.23  PEP_STATUS recv_Sync_event(
    8.24          PEP_SESSION session,
    8.25          Sync_event_t *ev
     9.1 --- a/sync/Makefile	Sat Aug 11 21:45:50 2018 +0200
     9.2 +++ b/sync/Makefile	Mon Aug 13 15:33:42 2018 +0200
     9.3 @@ -15,12 +15,13 @@
     9.4  .statemachines: sync.fsm gen_statemachine.ysl2 fsm.yml2 functions.ysl2
     9.5  	$(YML2_PROC) -y gen_statemachine.ysl2 $< -o $@
     9.6  
     9.7 -.codecs: sync.fsm gen_message_func.ysl2 fsm.yml2 functions.ysl2
     9.8 +.codecs: sync.fsm gen_codec.ysl2 fsm.yml2 functions.ysl2
     9.9 +	$(YML2_PROC) -y gen_codec.ysl2 $< -o $@
    9.10 +
    9.11 +.messages: sync.fsm gen_messages.ysl2 gen_message_func.ysl2 fsm.yml2 functions.ysl2
    9.12 +	$(YML2_PROC) -y gen_messages.ysl2 $< -o $@
    9.13  	$(YML2_PROC) -y gen_message_func.ysl2 $< -o $@
    9.14  
    9.15 -.messages: sync.fsm gen_messages.ysl2 fsm.yml2 functions.ysl2
    9.16 -	$(YML2_PROC) -y gen_messages.ysl2 $< -o $@
    9.17 -
    9.18  .PHONY: clean copy
    9.19  
    9.20  clean:
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/sync/gen_codec.ysl2	Mon Aug 13 15:33:42 2018 +0200
    10.3 @@ -0,0 +1,234 @@
    10.4 +// This file is under GNU General Public License 3.0
    10.5 +// see LICENSE.txt
    10.6 +
    10.7 +// generate conditions and actions
    10.8 +
    10.9 +// Copyleft (c) 2018, p≡p foundation
   10.10 +
   10.11 +// Written by Volker Birk
   10.12 +
   10.13 +include yslt.yml2
   10.14 +
   10.15 +tstylesheet {
   10.16 +    include standardlib.ysl2
   10.17 +
   10.18 +    template "/protocol" {
   10.19 +        document "generated/{@name}_codec.h", "text"
   10.20 +        ||
   10.21 +        // This file is under GNU General Public License 3.0
   10.22 +        // see LICENSE.txt
   10.23 +
   10.24 +        #pragma once
   10.25 +
   10.26 +
   10.27 +        #include "pEpEngine.h"
   10.28 +        #include "../asn.1/«@name».h"
   10.29 +
   10.30 +
   10.31 +        #ifdef __cplusplus
   10.32 +        extern "C" {
   10.33 +        #endif
   10.34 +
   10.35 +
   10.36 +        // decode_«@name»_msg() - decode PER encoded «@name» message
   10.37 +        //
   10.38 +        //  parameters:
   10.39 +        //      data (in)               PER encoded data
   10.40 +        //      size (in)               size of PER encoded data
   10.41 +        //      msg (out)               «@name» message
   10.42 +        //
   10.43 +        //  caveat:
   10.44 +        //      msg goes into the ownership of the caller
   10.45 +
   10.46 +        DYNAMIC_API PEP_STATUS decode_«@name»_msg(
   10.47 +                const char *data,
   10.48 +                size_t size,
   10.49 +                «@name»_t **msg
   10.50 +            );
   10.51 +
   10.52 +
   10.53 +        // encode_«@name»_msg() - encode «@name» message into PER encoded data
   10.54 +        //
   10.55 +        //  parameters:
   10.56 +        //      msg (in)                «@name» message
   10.57 +        //      data (out)              PER encoded data
   10.58 +        //      size (out)              size of PER encoded data
   10.59 +        //
   10.60 +        //  caveat:
   10.61 +        //      data goes to the ownership of the caller
   10.62 +
   10.63 +        DYNAMIC_API PEP_STATUS encode_«@name»_msg(
   10.64 +                «@name»_t *msg,
   10.65 +                char **data,
   10.66 +                size_t *size
   10.67 +            );
   10.68 +
   10.69 +
   10.70 +        // PER_to_XER_«@name»_msg() - decode «@name» message from PER into XER
   10.71 +        //
   10.72 +        //  parameters:
   10.73 +        //      data (in)               PER encoded data
   10.74 +        //      size (in)               size of PER encoded data
   10.75 +        //      text (out)              XER text of the same «@name» message
   10.76 +
   10.77 +        DYNAMIC_API PEP_STATUS PER_to_XER_«@name»_msg(
   10.78 +                const char *data,
   10.79 +                size_t size,
   10.80 +                char **text
   10.81 +            );
   10.82 +
   10.83 +
   10.84 +        // XER_to_PER_«@name»_msg() - encode «@name» message from XER into PER
   10.85 +        //
   10.86 +        //  parameters:
   10.87 +        //      text (in)               string with XER text of the «@name» message
   10.88 +        //      data (out)              PER encoded data
   10.89 +        //      size (out)              size of PER encoded data
   10.90 +
   10.91 +        DYNAMIC_API PEP_STATUS XER_to_PER_«@name»_msg(
   10.92 +                const char *text,
   10.93 +                char **data,
   10.94 +                size_t *size
   10.95 +            );
   10.96 +
   10.97 +
   10.98 +        #ifdef __cplusplus
   10.99 +        }
  10.100 +        #endif
  10.101 +
  10.102 +        ||
  10.103 +        document "generated/{@name}_codec.c", "text"
  10.104 +        ||
  10.105 +        // This file is under GNU General Public License 3.0
  10.106 +        // see LICENSE.txt
  10.107 +
  10.108 +        #include "«@name»_codec.h"
  10.109 +        #include "pEp_internal.h"
  10.110 +        #include "growing_buf.h"
  10.111 +
  10.112 +        DYNAMIC_API PEP_STATUS decode_«@name»_msg(
  10.113 +                const char *data,
  10.114 +                size_t size,
  10.115 +                «@name»_t **msg
  10.116 +            )
  10.117 +        {
  10.118 +            assert(data && msg);
  10.119 +            if (!(data && msg))
  10.120 +                return PEP_ILLEGAL_VALUE;
  10.121 +
  10.122 +            *msg = NULL;
  10.123 +            uper_decode_complete(NULL, &asn_DEF_«@name», (void **) &msg, data, size);
  10.124 +            if (!msg)
  10.125 +                return PEP_SYNC_ILLEGAL_MESSAGE;
  10.126 +
  10.127 +            return PEP_STATUS_OK;
  10.128 +        }
  10.129 +
  10.130 +        DYNAMIC_API PEP_STATUS encode_«@name»_msg(
  10.131 +                «@name»_t *msg,
  10.132 +                char **data,
  10.133 +                size_t *size
  10.134 +            )
  10.135 +        {
  10.136 +            assert(data && msg);
  10.137 +            if (!(data && msg))
  10.138 +                return PEP_ILLEGAL_VALUE;
  10.139 +
  10.140 +            *data = NULL;
  10.141 +            *size = 0;
  10.142 +
  10.143 +            char *_data = NULL;
  10.144 +            ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_«@name», NULL, msg,
  10.145 +                    (void **) &_data);
  10.146 +            if (_size == -1)
  10.147 +                return PEP_CANNOT_ENCODE;
  10.148 +
  10.149 +            *data = _data;
  10.150 +            *size = (size_t) _size;
  10.151 +
  10.152 +            return PEP_STATUS_OK;
  10.153 +        }
  10.154 +
  10.155 +        DYNAMIC_API PEP_STATUS PER_to_XER_«@name»_msg(
  10.156 +                const char *data,
  10.157 +                size_t size,
  10.158 +                char **text
  10.159 +            )
  10.160 +        {
  10.161 +            PEP_STATUS status = PEP_STATUS_OK;
  10.162 +            growing_buf_t *dst = NULL;
  10.163 +
  10.164 +            assert(data && text);
  10.165 +            if (!(data && text))
  10.166 +                return PEP_ILLEGAL_VALUE;
  10.167 +
  10.168 +            *text = NULL;
  10.169 +
  10.170 +            «@name»_t *msg = NULL;
  10.171 +            status = decode_«@name»_msg(data, size, &msg);
  10.172 +            if (status)
  10.173 +                goto the_end;
  10.174 +
  10.175 +            dst = new_growing_buf();
  10.176 +            if (!dst) {
  10.177 +                status = PEP_OUT_OF_MEMORY;
  10.178 +                goto the_end;
  10.179 +            }
  10.180 +
  10.181 +            asn_enc_rval_t er = xer_encode(&asn_DEF_«@name», msg, XER_F_BASIC,
  10.182 +                    (asn_app_consume_bytes_f *) growing_buf_consume, (void *) dst);
  10.183 +            if (er.encoded == -1) {
  10.184 +                status = PEP_CANNOT_ENCODE;
  10.185 +                goto the_end;
  10.186 +            }
  10.187 +
  10.188 +            *text = dst->data;
  10.189 +            dst->data = NULL;
  10.190 +
  10.191 +        the_end:
  10.192 +            free_growing_buf(dst);
  10.193 +            ASN_STRUCT_FREE(asn_DEF_«@name», msg);
  10.194 +            return status;
  10.195 +        }
  10.196 +
  10.197 +        DYNAMIC_API PEP_STATUS XER_to_PER_«@name»_msg(
  10.198 +                const char *text,
  10.199 +                char **data,
  10.200 +                size_t *size
  10.201 +            )
  10.202 +        {
  10.203 +            PEP_STATUS status = PEP_STATUS_OK;
  10.204 +
  10.205 +            assert(text && data && size);
  10.206 +            if (!(text && data && size))
  10.207 +                return PEP_ILLEGAL_VALUE;
  10.208 +
  10.209 +            *data = NULL;
  10.210 +            *size = 0;
  10.211 +
  10.212 +            «@name»_t *msg = NULL;
  10.213 +            asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_«@name», (void **) &msg,
  10.214 +                    (const void *) text, strlen(text));
  10.215 +            if (dr.code != RC_OK) {
  10.216 +                status = PEP_SYNC_ILLEGAL_MESSAGE;
  10.217 +                goto the_end;
  10.218 +            }
  10.219 +
  10.220 +            char *_data = NULL;
  10.221 +            size_t _size = 0;
  10.222 +            status = encode_«@name»_msg(msg, &_data, &_size);
  10.223 +            if (status)
  10.224 +                goto the_end;
  10.225 +
  10.226 +            *data = _data;
  10.227 +            *size = (size_t) _size;
  10.228 +
  10.229 +        the_end:
  10.230 +            ASN_STRUCT_FREE(asn_DEF_«@name», msg);
  10.231 +            return status;
  10.232 +        }
  10.233 +
  10.234 +        ||
  10.235 +    }
  10.236 +}
  10.237 +
    11.1 --- a/sync/gen_statemachine.ysl2	Sat Aug 11 21:45:50 2018 +0200
    11.2 +++ b/sync/gen_statemachine.ysl2	Mon Aug 13 15:33:42 2018 +0200
    11.3 @@ -3,7 +3,7 @@
    11.4  
    11.5  // generate state machine code
    11.6  
    11.7 -// Copyleft (c) 2016, 2017, p≡p foundation
    11.8 +// Copyleft (c) 2016 - 2018, p≡p foundation
    11.9  
   11.10  // Written by Volker Birk
   11.11  
   11.12 @@ -316,6 +316,22 @@
   11.13              return status;
   11.14          }
   11.15  
   11.16 +        PEP_STATUS send_«@name»_message(
   11.17 +                PEP_SESSION session, 
   11.18 +                «@name»_PR fsm,
   11.19 +                int event
   11.20 +            )
   11.21 +        {
   11.22 +            PEP_STATUS status = PEP_STATUS_OK;
   11.23 +
   11.24 +            assert(session && fsm > None && event > None);
   11.25 +            if (!(session && fsm > None && event > None))
   11.26 +                return PEP_ILLEGAL_VALUE;
   11.27 +            
   11.28 +
   11.29 +            return status;
   11.30 +        }
   11.31 +
   11.32          PEP_STATUS recv_«@name»_event(
   11.33                  PEP_SESSION session,
   11.34                  «@name»_event_t *ev
    12.1 --- a/sync/sync.fsm	Sat Aug 11 21:45:50 2018 +0200
    12.2 +++ b/sync/sync.fsm	Mon Aug 13 15:33:42 2018 +0200
    12.3 @@ -1,7 +1,7 @@
    12.4  // This file is under BSD License 2.0
    12.5  
    12.6  // Sync protocol for p≡p
    12.7 -// Copyright (c) 2016, 2017 p≡p foundation
    12.8 +// Copyright (c) 2016 - 2018, p≡p foundation
    12.9  
   12.10  // Written by Volker Birk
   12.11