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