sync/gen_message_func.ysl2
author Volker Birk <vb@pep-project.org>
Wed, 29 May 2019 23:29:43 +0200
branchsync
changeset 3780 e4d673d3038e
parent 3779 c6898c703a27
child 3935 578eeb202e26
permissions -rw-r--r--
always use output buffer
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@3512
     6
// Copyleft (c) 2017-2019, 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@3772
    42
    // own state
vb@3772
    43
vb@3772
    44
    struct own_«@name»_state_s {
vb@3772
    45
        stringlist_t *keys;
vb@3772
    46
        identity_list *identities;
vb@3772
    47
vb@3773
    48
        // TIDs we're using ourselves
vb@3772
    49
        `` for "func:distinctName(fsm/message/field[@type='TID'])" |>> «func:ctype()» «@name»;
vb@3772
    50
    } own;
vb@3772
    51
vb@3772
    52
    // state we learned about our communication partner
vb@3594
    53
vb@3767
    54
    struct comm_partner_state_s {
vb@3772
    55
        // transport data we expect
vb@3779
    56
        char *sender_fpr;
vb@3772
    57
vb@3772
    58
        // TIDs our comm partner wants to have
vb@3773
    59
        `` for "func:distinctName(fsm/message/field[@type='TID'])" |>> «func:ctype()» «@name»;
vb@3767
    60
    } comm_partner;
vb@3768
    61
vb@3775
    62
    // input buffer for actual transport data coming in
vb@3768
    63
vb@3772
    64
    struct transport_data_s {
vb@3772
    65
        // transport data we got
vb@3772
    66
        pEp_identity *from;
vb@3779
    67
        char *sender_fpr;
vb@3773
    68
    } transport;
vb@2831
    69
    `` apply "fsm", mode=state
vb@2831
    70
};
vb@2831
    71
vb@2831
    72
void free_«@name»_state(PEP_SESSION session);
vb@2831
    73
vb@2831
    74
// functions for protocol «@name»
vb@2831
    75
vb@2831
    76
«@name»_t *new_«@name»_message(«@name»_PR fsm, int message_type);
vb@2831
    77
void free_«@name»_message(«@name»_t *msg);
vb@2831
    78
vb@2831
    79
PEP_STATUS update_«@name»_state(PEP_SESSION session, «@name»_t *msg,
vb@2831
    80
        «@name»_PR *fsm, int *message_type);
vb@2831
    81
vb@2854
    82
PEP_STATUS update_«@name»_message(PEP_SESSION session, «@name»_t *msg);
vb@2831
    83
vb@2831
    84
#ifdef __cplusplus
vb@2831
    85
}
vb@2831
    86
#endif
vb@2831
    87
vb@2831
    88
||
vb@2831
    89
vb@2831
    90
template "fsm", mode=state
vb@2831
    91
||
vb@3594
    92
vb@3775
    93
// input/output buffer for «@name» messages
vb@3594
    94
vb@2831
    95
struct _«@name»_state_s {
vb@2831
    96
    int state;
vb@2831
    97
vb@2831
    98
    `` for "func:distinctName(message/field)" |> «func:ctype()» «@name»;
vb@3773
    99
} «yml:lcase(@name)»;
vb@2831
   100
||
vb@2831
   101
vb@2831
   102
template "protocol", mode=impl
vb@2831
   103
    document "generated/{@name}_func.c", "text" {
vb@2831
   104
||
vb@2831
   105
// This file is under GNU General Public License 3.0
vb@2831
   106
// see LICENSE.txt
vb@2831
   107
vb@2831
   108
#include <assert.h>
vb@2831
   109
#include <stdlib.h>
vb@2831
   110
#include "pEp_internal.h"
vb@2831
   111
#include "map_asn1.h"
vb@2831
   112
#include "«@name»_func.h"
vb@3123
   113
`` for "fsm" | #include "«@name»_fsm.h"
vb@2831
   114
vb@2831
   115
void free_«@name»_state(PEP_SESSION session)
vb@2831
   116
{
vb@2831
   117
    if (!session)
vb@2831
   118
        return;
vb@2831
   119
vb@3773
   120
    // own state
vb@3773
   121
vb@3773
   122
    free_stringlist(session->«yml:lcase(@name)»_state.own.keys);
vb@3773
   123
    session->«yml:lcase(@name)»_state.own.keys = NULL;
vb@3773
   124
    free_identity_list(session->«yml:lcase(@name)»_state.own.identities);
vb@3773
   125
    session->«yml:lcase(@name)»_state.own.identities = NULL;
vb@3773
   126
vb@3773
   127
    // TIDs we're using ourselves
vb@3773
   128
||
vb@3773
   129
    for "func:distinctName(fsm/message/field[@type='TID'])"
vb@3773
   130
        |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.own.«@name»);
vb@3773
   131
||
vb@3773
   132
vb@3773
   133
    // state we learned about our communication partner
vb@3773
   134
vb@3779
   135
    free(session->«yml:lcase(@name)»_state.comm_partner.sender_fpr);
vb@3779
   136
    session->«yml:lcase(@name)»_state.comm_partner.sender_fpr = NULL;
vb@3773
   137
vb@3773
   138
    // TIDs our comm partner wants to have
vb@3773
   139
||
vb@3773
   140
    for "func:distinctName(fsm/message/field[@type='TID'])"
vb@3773
   141
        |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.comm_partner.«@name»);
vb@3773
   142
||
vb@3773
   143
vb@3773
   144
    // buffer for transport data
vb@3773
   145
vb@3773
   146
    free_identity(session->«yml:lcase(@name)»_state.transport.from);
vb@3773
   147
    session->«yml:lcase(@name)»_state.transport.from = NULL;
vb@3779
   148
    free(session->«yml:lcase(@name)»_state.transport.sender_fpr);
vb@3779
   149
    session->«yml:lcase(@name)»_state.transport.sender_fpr = NULL;
vb@3773
   150
vb@3773
   151
    // message buffers
vb@2831
   152
vb@2831
   153
||
vb@3773
   154
    for "fsm" {
vb@3773
   155
        for "func:distinctName(message/field[not(substring(@type,1,1)=yml:lcase(substring(@type,1,1)))])"
vb@3773
   156
            |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
vb@3773
   157
        |
vb@3773
   158
    }
vb@2831
   159
||
vb@2844
   160
    memset(&session->«yml:lcase(@name)»_state, 0, sizeof(session->«yml:lcase(@name)»_state));
vb@2831
   161
}
vb@2831
   162
vb@2831
   163
«@name»_t *new_«@name»_message(«@name»_PR fsm, int message_type)
vb@2831
   164
{
vb@2831
   165
    «@name»_t *msg = calloc(sizeof(«@name»_t), 1);
vb@2831
   166
    assert(msg);
vb@2831
   167
    if (!msg)
vb@2831
   168
        return NULL;
vb@2831
   169
vb@2841
   170
    if (fsm) {
vb@2841
   171
        msg->present = fsm;
vb@2841
   172
        if (message_type) {
vb@2841
   173
            switch (fsm) {
vb@2841
   174
                `` apply "fsm", 4, mode=impl
vb@2841
   175
                default:
vb@2841
   176
                    free(msg);
vb@2841
   177
                    return NULL;
vb@2841
   178
            }
vb@2841
   179
        }
vb@2831
   180
    }
vb@2831
   181
vb@2831
   182
    return msg;
vb@2831
   183
}
vb@2831
   184
vb@2831
   185
void free_«@name»_message(«@name»_t *msg)
vb@2831
   186
{
vb@2831
   187
    ASN_STRUCT_FREE(asn_DEF_«@name», msg);
vb@2831
   188
}
vb@2831
   189
vb@2831
   190
PEP_STATUS update_«@name»_state(PEP_SESSION session, «@name»_t *msg,
vb@2831
   191
        «@name»_PR *fsm, int *message_type)
vb@2831
   192
{
vb@2831
   193
    int result = 0;
vb@2831
   194
vb@2831
   195
    assert(session && msg && fsm && message_type);
vb@2831
   196
    if (!(session && msg && fsm && message_type))
vb@2831
   197
        return PEP_ILLEGAL_VALUE;
vb@2831
   198
vb@2831
   199
    *fsm = 0;
vb@3123
   200
    *message_type = None;
vb@2831
   201
vb@2831
   202
    switch (msg->present) {
vb@2831
   203
        case «@name»_PR_NOTHING:
vb@2831
   204
            return PEP_ILLEGAL_VALUE;
vb@2831
   205
vb@2831
   206
        `` apply "fsm", 2, mode=update_state
vb@2831
   207
        default:
vb@2831
   208
            return PEP_ILLEGAL_VALUE;
vb@2831
   209
    }
vb@2831
   210
vb@2831
   211
    *fsm = msg->present;
vb@2831
   212
    return PEP_STATUS_OK;
vb@2831
   213
}
vb@2831
   214
vb@2854
   215
PEP_STATUS update_«@name»_message(PEP_SESSION session, «@name»_t *msg)
vb@2831
   216
{
vb@2831
   217
    assert(session && msg);
vb@2831
   218
    if (!(session && msg))
vb@2831
   219
        return PEP_ILLEGAL_VALUE;
vb@2831
   220
vb@2854
   221
    int fsm = msg->present;
vb@2831
   222
    switch (fsm) {
vb@2831
   223
        case «@name»_PR_NOTHING:
vb@2831
   224
            return PEP_ILLEGAL_VALUE;
vb@2831
   225
vb@2831
   226
        `` apply "fsm", 2, mode=update_message
vb@2831
   227
        default:
vb@2831
   228
            return PEP_ILLEGAL_VALUE;
vb@2831
   229
    }
vb@2831
   230
vb@2831
   231
    return PEP_STATUS_OK;
vb@2831
   232
}
vb@2831
   233
vb@2831
   234
||
vb@2831
   235
}
vb@2831
   236
vb@2831
   237
template "fsm", mode=update_message
vb@2831
   238
||
vb@2831
   239
case «../@name»_PR_«yml:lcase(@name)»:
vb@2854
   240
    {
vb@3509
   241
        int message_type = msg->choice.«yml:lcase(@name)».present;
vb@2854
   242
        switch (message_type) {
vb@3509
   243
            case «@name»_PR_NOTHING:
vb@2854
   244
                return PEP_ILLEGAL_VALUE;
vb@2831
   245
vb@2854
   246
            `` apply "message", 2, mode=update_message
vb@2854
   247
            default:
vb@2854
   248
                return PEP_ILLEGAL_VALUE;
vb@2854
   249
        }
vb@2854
   250
        break;
vb@2831
   251
    }
vb@2831
   252
||
vb@2831
   253
vb@2831
   254
template "message", mode=update_message {
vb@2831
   255
    ||
vb@3509
   256
    case «../@name»_PR_«yml:mixedCase(@name)»:
vb@2855
   257
        `` apply "auto"
vb@2856
   258
        `` apply "field", mode=update_message
vb@2831
   259
        break;
vb@2831
   260
vb@2831
   261
    ||
vb@2831
   262
}
vb@2831
   263
vb@2855
   264
template "auto" choose {
vb@2856
   265
    when "@type = 'Version'" {
vb@2856
   266
        const "fsm", "ancestor::fsm";
vb@2855
   267
        ||
vb@2855
   268
        {
vb@2855
   269
            long *major = (long *) malloc(sizeof(long));
vb@2855
   270
            long *minor = (long *) malloc(sizeof(long));
vb@2855
   271
            assert(major && minor);
vb@2855
   272
            if (!(major && minor))
vb@2855
   273
                return PEP_OUT_OF_MEMORY;
vb@2855
   274
vb@2856
   275
            *major = «$fsm/version/@major»;
vb@2856
   276
            *minor = «$fsm/version/@minor»;
vb@2855
   277
vb@3509
   278
            msg->choice.«yml:lcase($fsm/@name)».choice.«yml:mixedCase(../@name)».«@name».major = major;
vb@3509
   279
            msg->choice.«yml:lcase($fsm/@name)».choice.«yml:mixedCase(../@name)».«@name».minor = minor;
vb@2855
   280
        }
vb@2855
   281
vb@2855
   282
        ||
vb@2856
   283
    }
vb@2855
   284
vb@2855
   285
    otherwise
vb@2855
   286
        error "unkown type for auto in message: {@type}; allowed types: Version";
vb@2855
   287
}
vb@2855
   288
vb@2831
   289
template "field", mode=update_message {
vb@2856
   290
    const "message_name", "yml:mixedCase(../@name)";
vb@3780
   291
    const "state" > «yml:lcase(ancestor::protocol/@name)»_state.«yml:lcase(ancestor::fsm/@name)»
vb@2856
   292
vb@2831
   293
    choose {
vb@2831
   294
        when "func:basicType()" // copyable
vb@2831
   295
        ||
vb@3509
   296
        msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name»
vb@2856
   297
                 = session->«$state».«@name»;
vb@2831
   298
vb@2831
   299
        ||
vb@2831
   300
        when "@type='IdentityList'"
vb@2831
   301
        ||
vb@2831
   302
        {
vb@2831
   303
            identity_list *il = IdentityList_to_identity_list(
vb@2856
   304
                    &session->«$state».«@name», NULL);
vb@2831
   305
            if (!il)
vb@2831
   306
                return PEP_OUT_OF_MEMORY;
vb@2831
   307
            IdentityList_t *_il = IdentityList_from_identity_list(il,
vb@3509
   308
                    &msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name»);
vb@2831
   309
            free_identity_list(il);
vb@2831
   310
            if (!_il)
vb@2831
   311
                return PEP_OUT_OF_MEMORY;
vb@2831
   312
        }
vb@2831
   313
vb@2831
   314
        ||
vb@2831
   315
        otherwise // string based
vb@2831
   316
        ||
vb@2856
   317
        {
vb@2856
   318
            int result = OCTET_STRING_fromBuf(
vb@3509
   319
                    &msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name»,
vb@2856
   320
                    (char *) session->«$state».«@name».buf,
vb@2856
   321
                    session->«$state».«@name».size
vb@2856
   322
                );
vb@2856
   323
            if (result)
vb@2856
   324
                return PEP_OUT_OF_MEMORY;
vb@2856
   325
        }
vb@2831
   326
        ||
vb@2831
   327
    }
vb@2831
   328
}
vb@2831
   329
vb@2831
   330
template "fsm", mode=update_state
vb@2831
   331
||
vb@2831
   332
case «../@name»_PR_«yml:lcase(@name)»:
vb@3509
   333
    switch (msg->choice.«yml:lcase(@name)».present) {
vb@3509
   334
        case «@name»_PR_NOTHING:
vb@2831
   335
            return PEP_ILLEGAL_VALUE;
vb@2831
   336
vb@2831
   337
        `` apply "message", 2, mode=update_state
vb@2831
   338
        default:
vb@2831
   339
            return PEP_ILLEGAL_VALUE;
vb@2831
   340
    }
vb@2831
   341
    break;
vb@2831
   342
vb@2831
   343
||
vb@2831
   344
vb@2831
   345
template "message", mode=update_state {
vb@2831
   346
    const "message_name", "concat(yml:lcase(substring(@name,1,1)), substring(@name,2))";
vb@2831
   347
    ||
vb@3509
   348
    case «../@name»_PR_«$message_name»:
vb@2831
   349
        `` apply "field", mode=update_state with "message_name", "$message_name"
vb@3123
   350
        *message_type = «yml:capit($message_name)»;
vb@2831
   351
        break;
vb@2831
   352
vb@2831
   353
    ||
vb@2831
   354
}
vb@2831
   355
vb@2831
   356
template "field", mode=update_state {
vb@2831
   357
    param "message_name";
vb@2831
   358
    choose {
vb@2831
   359
        when "func:basicType()" // copyable
vb@2831
   360
        ||
vb@2831
   361
        session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name» = msg->choice.«yml:lcase(../../@name)»
vb@3509
   362
                .choice.«$message_name».«@name»;
vb@2831
   363
vb@2831
   364
        ||
vb@2831
   365
        when "@type='IdentityList'"
vb@2831
   366
        ||
vb@2831
   367
        {
vb@2831
   368
            identity_list *il = IdentityList_to_identity_list(
vb@3509
   369
                    &msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name», NULL);
vb@2831
   370
            if (!il)
vb@2831
   371
                return PEP_OUT_OF_MEMORY;
vb@2831
   372
            IdentityList_t *_il = IdentityList_from_identity_list(il,
vb@2831
   373
                    &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
vb@2831
   374
            free_identity_list(il);
vb@2831
   375
            if (!_il)
vb@2831
   376
                return PEP_OUT_OF_MEMORY;
vb@2831
   377
        }
vb@2831
   378
vb@2831
   379
        ||
vb@2831
   380
        otherwise // string based
vb@2831
   381
        ||
vb@2831
   382
        result = OCTET_STRING_fromBuf(&session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»,
vb@3509
   383
                (char *) msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name».buf,
vb@3509
   384
                msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name».size);
vb@2831
   385
        if (result)
vb@2831
   386
            return PEP_OUT_OF_MEMORY;
vb@2831
   387
vb@2831
   388
        ||
vb@2831
   389
    }
vb@2831
   390
}
vb@2831
   391
vb@2831
   392
template "fsm", mode=impl
vb@2831
   393
||
vb@2831
   394
case «../@name»_PR_«yml:lcase(@name)»:
vb@3509
   395
    msg->choice.«yml:lcase(@name)».present = message_type;
vb@2831
   396
        break;
vb@2831
   397
vb@2831
   398
||
vb@2831
   399
vb@2831
   400
}
vb@2831
   401