sync/gen_message_func.ysl2
author Volker Birk <vb@pep.foundation>
Wed, 29 Aug 2018 21:49:28 +0200
branchsync
changeset 2903 33549a7c7191
parent 2864 dcbed0d35466
child 3123 2475e49c3154
permissions -rw-r--r--
safeguards
vb@2831
     1
// This file is under GNU General Public License 3.0
vb@2831
     2
// see LICENSE.txt
vb@2831
     3
vb@2831
     4
// generate message functions
vb@2831
     5
vb@2864
     6
// Copyleft (c) 2017, 2018, p≡p foundation
vb@2831
     7
vb@2831
     8
// Written by Volker Birk
vb@2831
     9
vb@2831
    10
include yslt.yml2
vb@2831
    11
vb@2831
    12
tstylesheet {
vb@2831
    13
vb@2831
    14
include standardlib.ysl2
vb@2831
    15
include ./functions.ysl2
vb@2831
    16
vb@2831
    17
template "/" {
vb@2831
    18
    apply "protocol", 0, mode=header;
vb@2831
    19
    apply "protocol", 0, mode=impl;
vb@2831
    20
}
vb@2831
    21
vb@2831
    22
template "protocol", mode=header
vb@2831
    23
    document "generated/{@name}_func.h", "text"
vb@2831
    24
||
vb@2831
    25
// This file is under GNU General Public License 3.0
vb@2831
    26
// see LICENSE.txt
vb@2831
    27
vb@2831
    28
#pragma once
vb@2831
    29
vb@2831
    30
#ifdef __cplusplus
vb@2831
    31
extern "C" {
vb@2831
    32
#endif
vb@2831
    33
vb@2831
    34
#include <stdbool.h>
vb@2831
    35
vb@2831
    36
#include "../asn.1/«@name».h"
vb@2831
    37
`` for "func:distinctType(fsm/message/field[not(func:basicType())])" | #include "../asn.1/«@type».h"
vb@2831
    38
vb@2831
    39
// state
vb@2831
    40
vb@2831
    41
struct «@name»_state_s {
vb@2838
    42
    struct common_state_s {
vb@2831
    43
        pEp_identity *from;
vb@2838
    44
    } common;
vb@2831
    45
vb@2831
    46
    `` apply "fsm", mode=state
vb@2831
    47
};
vb@2831
    48
vb@2831
    49
struct own_«@name»_state_s {
vb@2831
    50
    `` for "func:distinctName(fsm/message/field[@type='TID'])" |> «func:ctype()» «@name»;
vb@2831
    51
};
vb@2831
    52
vb@2831
    53
void free_«@name»_state(PEP_SESSION session);
vb@2831
    54
vb@2831
    55
// functions for protocol «@name»
vb@2831
    56
vb@2831
    57
«@name»_t *new_«@name»_message(«@name»_PR fsm, int message_type);
vb@2831
    58
void free_«@name»_message(«@name»_t *msg);
vb@2831
    59
vb@2831
    60
PEP_STATUS update_«@name»_state(PEP_SESSION session, «@name»_t *msg,
vb@2831
    61
        «@name»_PR *fsm, int *message_type);
vb@2831
    62
vb@2854
    63
PEP_STATUS update_«@name»_message(PEP_SESSION session, «@name»_t *msg);
vb@2831
    64
vb@2831
    65
#ifdef __cplusplus
vb@2831
    66
}
vb@2831
    67
#endif
vb@2831
    68
vb@2831
    69
||
vb@2831
    70
vb@2831
    71
template "fsm", mode=state
vb@2831
    72
||
vb@2831
    73
struct _«@name»_state_s {
vb@2831
    74
    int state;
vb@2831
    75
vb@2831
    76
    `` for "func:distinctName(message/field)" |> «func:ctype()» «@name»;
vb@2831
    77
} «yml:lcase(@name)»;
vb@2831
    78
||
vb@2831
    79
vb@2831
    80
template "protocol", mode=impl
vb@2831
    81
    document "generated/{@name}_func.c", "text" {
vb@2831
    82
||
vb@2831
    83
// This file is under GNU General Public License 3.0
vb@2831
    84
// see LICENSE.txt
vb@2831
    85
vb@2831
    86
#include <assert.h>
vb@2831
    87
#include <stdlib.h>
vb@2831
    88
#include "pEp_internal.h"
vb@2831
    89
#include "map_asn1.h"
vb@2831
    90
#include "«@name»_func.h"
vb@2831
    91
vb@2831
    92
void free_«@name»_state(PEP_SESSION session)
vb@2831
    93
{
vb@2831
    94
    if (!session)
vb@2831
    95
        return;
vb@2831
    96
vb@2838
    97
    free_identity(session->«yml:lcase(@name)»_state.common.from);
vb@2831
    98
vb@2831
    99
||
vb@2831
   100
for "fsm"
vb@2831
   101
    for "func:distinctName(message/field[not(func:basicType())])"
vb@2831
   102
        |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
vb@2831
   103
for "func:distinctName(fsm/message/field[@type='TID'])"
vb@2831
   104
    |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->own_«yml:lcase(../../../@name)»_state.«@name»);
vb@2831
   105
||
vb@2838
   106
vb@2844
   107
    memset(&session->«yml:lcase(@name)»_state, 0, sizeof(session->«yml:lcase(@name)»_state));
vb@2831
   108
}
vb@2831
   109
vb@2831
   110
«@name»_t *new_«@name»_message(«@name»_PR fsm, int message_type)
vb@2831
   111
{
vb@2831
   112
    «@name»_t *msg = calloc(sizeof(«@name»_t), 1);
vb@2831
   113
    assert(msg);
vb@2831
   114
    if (!msg)
vb@2831
   115
        return NULL;
vb@2831
   116
vb@2841
   117
    if (fsm) {
vb@2841
   118
        msg->present = fsm;
vb@2841
   119
        if (message_type) {
vb@2841
   120
            switch (fsm) {
vb@2841
   121
                `` apply "fsm", 4, mode=impl
vb@2841
   122
                default:
vb@2841
   123
                    free(msg);
vb@2841
   124
                    return NULL;
vb@2841
   125
            }
vb@2841
   126
        }
vb@2831
   127
    }
vb@2831
   128
vb@2831
   129
    return msg;
vb@2831
   130
}
vb@2831
   131
vb@2831
   132
void free_«@name»_message(«@name»_t *msg)
vb@2831
   133
{
vb@2831
   134
    ASN_STRUCT_FREE(asn_DEF_«@name», msg);
vb@2831
   135
}
vb@2831
   136
vb@2831
   137
PEP_STATUS update_«@name»_state(PEP_SESSION session, «@name»_t *msg,
vb@2831
   138
        «@name»_PR *fsm, int *message_type)
vb@2831
   139
{
vb@2831
   140
    int result = 0;
vb@2831
   141
vb@2831
   142
    assert(session && msg && fsm && message_type);
vb@2831
   143
    if (!(session && msg && fsm && message_type))
vb@2831
   144
        return PEP_ILLEGAL_VALUE;
vb@2831
   145
vb@2831
   146
    *fsm = 0;
vb@2831
   147
    *message_type = 0;
vb@2831
   148
vb@2831
   149
    switch (msg->present) {
vb@2831
   150
        case «@name»_PR_NOTHING:
vb@2831
   151
            return PEP_ILLEGAL_VALUE;
vb@2831
   152
vb@2831
   153
        `` apply "fsm", 2, mode=update_state
vb@2831
   154
        default:
vb@2831
   155
            return PEP_ILLEGAL_VALUE;
vb@2831
   156
    }
vb@2831
   157
vb@2831
   158
    *fsm = msg->present;
vb@2831
   159
    return PEP_STATUS_OK;
vb@2831
   160
}
vb@2831
   161
vb@2854
   162
PEP_STATUS update_«@name»_message(PEP_SESSION session, «@name»_t *msg)
vb@2831
   163
{
vb@2831
   164
    assert(session && msg);
vb@2831
   165
    if (!(session && msg))
vb@2831
   166
        return PEP_ILLEGAL_VALUE;
vb@2831
   167
vb@2854
   168
    int fsm = msg->present;
vb@2831
   169
    switch (fsm) {
vb@2831
   170
        case «@name»_PR_NOTHING:
vb@2831
   171
            return PEP_ILLEGAL_VALUE;
vb@2831
   172
vb@2831
   173
        `` apply "fsm", 2, mode=update_message
vb@2831
   174
        default:
vb@2831
   175
            return PEP_ILLEGAL_VALUE;
vb@2831
   176
    }
vb@2831
   177
vb@2831
   178
    return PEP_STATUS_OK;
vb@2831
   179
}
vb@2831
   180
vb@2831
   181
||
vb@2831
   182
}
vb@2831
   183
vb@2831
   184
template "fsm", mode=update_message
vb@2831
   185
||
vb@2831
   186
case «../@name»_PR_«yml:lcase(@name)»:
vb@2854
   187
    {
vb@2855
   188
        static long sequence = 0;
vb@2855
   189
        msg->choice.«yml:lcase(@name)».header.sequence = ++sequence;
vb@2854
   190
        int message_type = msg->choice.«yml:lcase(@name)».payload.present;
vb@2854
   191
        switch (message_type) {
vb@2854
   192
            case «@name»__payload_PR_NOTHING:
vb@2854
   193
                return PEP_ILLEGAL_VALUE;
vb@2831
   194
vb@2854
   195
            `` apply "message", 2, mode=update_message
vb@2854
   196
            default:
vb@2854
   197
                return PEP_ILLEGAL_VALUE;
vb@2854
   198
        }
vb@2854
   199
        break;
vb@2831
   200
    }
vb@2831
   201
||
vb@2831
   202
vb@2831
   203
template "message", mode=update_message {
vb@2831
   204
    ||
vb@2856
   205
    case «../@name»__payload_PR_«yml:mixedCase(@name)»:
vb@2855
   206
        `` apply "auto"
vb@2856
   207
        `` apply "field", mode=update_message
vb@2831
   208
        break;
vb@2831
   209
vb@2831
   210
    ||
vb@2831
   211
}
vb@2831
   212
vb@2855
   213
template "auto" choose {
vb@2856
   214
    when "@type = 'Version'" {
vb@2856
   215
        const "fsm", "ancestor::fsm";
vb@2855
   216
        ||
vb@2855
   217
        {
vb@2855
   218
            long *major = (long *) malloc(sizeof(long));
vb@2855
   219
            long *minor = (long *) malloc(sizeof(long));
vb@2855
   220
            assert(major && minor);
vb@2855
   221
            if (!(major && minor))
vb@2855
   222
                return PEP_OUT_OF_MEMORY;
vb@2855
   223
vb@2856
   224
            *major = «$fsm/version/@major»;
vb@2856
   225
            *minor = «$fsm/version/@minor»;
vb@2855
   226
vb@2856
   227
            msg->choice.«yml:lcase($fsm/@name)».payload.choice.«yml:mixedCase(../@name)».«@name».major = major;
vb@2856
   228
            msg->choice.«yml:lcase($fsm/@name)».payload.choice.«yml:mixedCase(../@name)».«@name».minor = minor;
vb@2855
   229
        }
vb@2855
   230
vb@2855
   231
        ||
vb@2856
   232
    }
vb@2855
   233
vb@2855
   234
    otherwise
vb@2855
   235
        error "unkown type for auto in message: {@type}; allowed types: Version";
vb@2855
   236
}
vb@2855
   237
vb@2831
   238
template "field", mode=update_message {
vb@2856
   239
    const "message_name", "yml:mixedCase(../@name)";
vb@2856
   240
    const "state" choose {
vb@2856
   241
        when "@type='TID'"
vb@2856
   242
            > own_«yml:lcase(ancestor::protocol/@name)»_state
vb@2856
   243
        otherwise
vb@2856
   244
            > «yml:lcase(ancestor::protocol/@name)»_state.«yml:lcase(ancestor::fsm/@name)»
vb@2856
   245
    }
vb@2856
   246
vb@2831
   247
    choose {
vb@2831
   248
        when "func:basicType()" // copyable
vb@2831
   249
        ||
vb@2831
   250
        msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name»
vb@2856
   251
                 = session->«$state».«@name»;
vb@2831
   252
vb@2831
   253
        ||
vb@2831
   254
        when "@type='IdentityList'"
vb@2831
   255
        ||
vb@2831
   256
        {
vb@2831
   257
            identity_list *il = IdentityList_to_identity_list(
vb@2856
   258
                    &session->«$state».«@name», NULL);
vb@2831
   259
            if (!il)
vb@2831
   260
                return PEP_OUT_OF_MEMORY;
vb@2831
   261
            IdentityList_t *_il = IdentityList_from_identity_list(il,
vb@2831
   262
                    &msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name»);
vb@2831
   263
            free_identity_list(il);
vb@2831
   264
            if (!_il)
vb@2831
   265
                return PEP_OUT_OF_MEMORY;
vb@2831
   266
        }
vb@2831
   267
vb@2831
   268
        ||
vb@2831
   269
        otherwise // string based
vb@2831
   270
        ||
vb@2856
   271
        {
vb@2856
   272
            int result = OCTET_STRING_fromBuf(
vb@2856
   273
                    &msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name»,
vb@2856
   274
                    (char *) session->«$state».«@name».buf,
vb@2856
   275
                    session->«$state».«@name».size
vb@2856
   276
                );
vb@2856
   277
            if (result)
vb@2856
   278
                return PEP_OUT_OF_MEMORY;
vb@2856
   279
        }
vb@2831
   280
        ||
vb@2831
   281
    }
vb@2831
   282
}
vb@2831
   283
vb@2831
   284
template "fsm", mode=update_state
vb@2831
   285
||
vb@2831
   286
case «../@name»_PR_«yml:lcase(@name)»:
vb@2831
   287
    switch (msg->choice.«yml:lcase(@name)».payload.present) {
vb@2831
   288
        case «@name»__payload_PR_NOTHING:
vb@2831
   289
            return PEP_ILLEGAL_VALUE;
vb@2831
   290
vb@2831
   291
        `` apply "message", 2, mode=update_state
vb@2831
   292
        default:
vb@2831
   293
            return PEP_ILLEGAL_VALUE;
vb@2831
   294
    }
vb@2831
   295
    *message_type = msg->choice.«yml:lcase(@name)».payload.present;
vb@2831
   296
    break;
vb@2831
   297
vb@2831
   298
||
vb@2831
   299
vb@2831
   300
template "message", mode=update_state {
vb@2831
   301
    const "message_name", "concat(yml:lcase(substring(@name,1,1)), substring(@name,2))";
vb@2831
   302
    ||
vb@2831
   303
    case «../@name»__payload_PR_«$message_name»:
vb@2831
   304
        `` apply "field", mode=update_state with "message_name", "$message_name"
vb@2831
   305
        break;
vb@2831
   306
vb@2831
   307
    ||
vb@2831
   308
}
vb@2831
   309
vb@2831
   310
template "field", mode=update_state {
vb@2831
   311
    param "message_name";
vb@2831
   312
    choose {
vb@2831
   313
        when "func:basicType()" // copyable
vb@2831
   314
        ||
vb@2831
   315
        session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name» = msg->choice.«yml:lcase(../../@name)»
vb@2831
   316
                .payload.choice.«$message_name».«@name»;
vb@2831
   317
vb@2831
   318
        ||
vb@2831
   319
        when "@type='IdentityList'"
vb@2831
   320
        ||
vb@2831
   321
        {
vb@2831
   322
            identity_list *il = IdentityList_to_identity_list(
vb@2831
   323
                    &msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name», NULL);
vb@2831
   324
            if (!il)
vb@2831
   325
                return PEP_OUT_OF_MEMORY;
vb@2831
   326
            IdentityList_t *_il = IdentityList_from_identity_list(il,
vb@2831
   327
                    &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
vb@2831
   328
            free_identity_list(il);
vb@2831
   329
            if (!_il)
vb@2831
   330
                return PEP_OUT_OF_MEMORY;
vb@2831
   331
        }
vb@2831
   332
vb@2831
   333
        ||
vb@2831
   334
        otherwise // string based
vb@2831
   335
        ||
vb@2831
   336
        result = OCTET_STRING_fromBuf(&session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»,
vb@2831
   337
                (char *) msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name».buf,
vb@2831
   338
                msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name».size);
vb@2831
   339
        if (result)
vb@2831
   340
            return PEP_OUT_OF_MEMORY;
vb@2831
   341
vb@2831
   342
        ||
vb@2831
   343
    }
vb@2831
   344
}
vb@2831
   345
vb@2831
   346
template "fsm", mode=impl
vb@2831
   347
||
vb@2831
   348
case «../@name»_PR_«yml:lcase(@name)»:
vb@2831
   349
    msg->choice.«yml:lcase(@name)».payload.present = message_type;
vb@2831
   350
        break;
vb@2831
   351
vb@2831
   352
||
vb@2831
   353
vb@2831
   354
}
vb@2831
   355