sync/gen_actions_skeleton.ysl2
author Volker Birk <vb@pep.foundation>
Mon, 08 Aug 2016 17:32:51 +0200
branchkeysync
changeset 985 087d5d60c082
parent 955 060272dfaaeb
child 991 b230b6418b52
permissions -rw-r--r--
moving #include and installing headers
     1 // generate actions skeleton
     2 
     3 // Copyleft (c) 2016, p≡p foundation
     4 
     5 // Written by Volker Birk
     6 
     7 include yslt.yml2
     8 
     9 tstylesheet {
    10     include ./functions.ysl2
    11 
    12     template "/protocol" {
    13         apply "fsm", mode=send, 0;
    14         apply "fsm", mode=other, 0;
    15     }
    16 
    17     template "fsm", mode=send document "../src/{@filename}_send_actions.c", "text" {
    18         const "name", "@name";
    19         const "filename", "@filename";
    20         ||
    21         // Send Actions for «@name» state machine
    22 
    23         #include <assert.h>
    24         #include "pEp_internal.h"
    25         #include "keymanagement.h"
    26         #include "message.h"
    27         #include "«@filename»_fsm.h"
    28         #include "baseprotocol.h"
    29         #include "map_asn1.h"
    30         #include "../asn.1/DeviceGroup-Protocol.h"
    31         ||
    32         for "func:distinctName(//action)"
    33             if "substring(@name, 1, 4) = 'send'"
    34                 | #include "../asn.1/«substring(@name, 5, 255)».h"
    35         |
    36         for "func:distinctName(//action)"
    37             if "substring(@name, 1, 4) = 'send'"
    38                 call "send_action"
    39                     with "action", ".",
    40                     with "fsm", "$name",
    41                     with "filename", "$filename";
    42     }
    43 
    44     template "fsm", mode=other document "../src/{@filename}_actions.c.skeleton", "text" {
    45         const "name", "@name";
    46         const "filename", "@filename";
    47         ||
    48         // Actions for «@name» state machine
    49 
    50         #include <assert.h>
    51         #include "pEp_internal.h"
    52         #include "keymanagement.h"
    53         #include "message.h"
    54         #include "«@filename»_fsm.h"
    55         #include "../asn.1/DeviceGroup-Protocol.h"
    56 
    57         ||
    58         for "func:distinctName(//action)"
    59             if "substring(@name, 1, 4) != 'send'"
    60                 call "other_action"
    61                     with "action", ".",
    62                     with "fsm", "$name",
    63                     with "filename", "$filename";
    64     }
    65 
    66     function "paramcheck" {
    67         param "partner";
    68         |> assert(session);
    69         choose {
    70             when "$partner"
    71             ||
    72                 assert(partner);
    73                 if (!(session && partner))
    74                     return PEP_ILLEGAL_VALUE;
    75             ||
    76             otherwise
    77             ||
    78                 assert(!partner);
    79                 if (!(session && !partner))
    80                     return PEP_ILLEGAL_VALUE;
    81             ||
    82         }
    83     }
    84 
    85     function "other_action" {
    86         param "action";
    87         param "fsm";
    88         param "filename", "'###'";
    89 
    90         ||
    91 
    92         // «$action/@name»() - 
    93         //
    94         //  params:
    95         //      session (in)        session handle
    96         //      state (in)          state the state machine is in
    97         `` if "parm"        | //      partner (in)        partner to communicate with
    98         `` if "not(parm)"   | //      partner (in)        (must be NULL)
    99         //
   100         //  returns:
   101         //      PEP_STATUS_OK or any other value on error
   102 
   103         PEP_STATUS «$action/@name»(
   104                 PEP_SESSION session,
   105                 «$fsm»_state state,
   106                 Identity partner,
   107                 void *extra
   108             )
   109         {
   110             PEP_STATUS status = PEP_STATUS_OK;
   111 
   112             `` call "paramcheck" with "partner", "parm/partner";
   113 
   114             // working code
   115 
   116             free_identity(partner);
   117             // free extra
   118             return status;
   119 
   120         enomem:
   121             status = PEP_OUT_OF_MEMORY;
   122         error:
   123             free_identity(partner);
   124             // free extra
   125             return status;
   126         }
   127 
   128         ||
   129     }
   130 
   131     function "send_action" {
   132         param "action";
   133         param "fsm";
   134         param "filename", "'###'";
   135         const "name", "substring($action/@name, 5, 255)";
   136 
   137         ||
   138 
   139         // «$action/@name»() - send «$name» message
   140         //
   141         //  params:
   142         //      session (in)        session handle
   143         //      state (in)          state the state machine is in
   144         `` if "parm"        | //      partner (in)        partner to communicate with
   145         `` if "not(parm)"   | //      partner (in)        (must be NULL)
   146         //
   147         //  returns:
   148         //      PEP_STATUS_OK or any other value on error
   149 
   150         PEP_STATUS «$action/@name»(
   151                 PEP_SESSION session,
   152                 «$fsm»_state state,
   153                 Identity partner,
   154                 void *extra
   155             )
   156         {
   157             PEP_STATUS status = PEP_STATUS_OK;
   158             «$name»_t *msg = NULL;
   159             char *payload = NULL;
   160             message *_message = NULL;
   161             pEp_identity *me = NULL;
   162             `` if "$name='GroupKeys'" |> identity_list *kl = NULL;
   163 
   164             `` call "paramcheck" with "partner", "parm/partner";
   165 
   166             assert(session->messageToSend);
   167             if (!session->messageToSend) {
   168                 status = PEP_SEND_FUNCTION_NOT_REGISTERED;
   169                 goto error;
   170             }
   171 
   172             msg = («$name»_t *) calloc(1, sizeof(«$name»_t));
   173             assert(msg);
   174             if (!msg)
   175                 goto enomem;
   176 
   177             int32_t seq;
   178             status = sequence_value(session, "DeviceGroup", &seq);
   179             if (status != PEP_STATUS_OK)
   180                 goto error;
   181             msg->header.sequence = (long) seq;
   182 
   183             bool devicegroup = storedGroupKeys(session);
   184             if (devicegroup) { // default is FALSE
   185                 BOOLEAN_t *dg = malloc(sizeof(BOOLEAN_t));
   186                 assert(dg);
   187                 if (!dg)
   188                     goto enomem;
   189 
   190                 *dg = 1;
   191                 msg->header.devicegroup = dg;
   192             }
   193 
   194             msg->header.state = (long) state;
   195 
   196             me = new_identity(NULL, NULL, NULL, NULL);
   197             if (!me)
   198                 goto enomem;
   199             status = myself(session, me);
   200             if (status != PEP_STATUS_OK)
   201                 goto error;
   202             if (Identity_from_Struct(me, &msg->header.me) == NULL)
   203                 goto enomem;
   204         ||
   205         if "$name='GroupKeys'" {
   206             |
   207             |> status = own_identities_retrieve(session, &kl);
   208             |> if (status != PEP_STATUS_OK)
   209             |>> goto error;
   210             |> if (IdentityList_from_identity_list(kl, &msg->ownIdentities) == NULL)
   211             |>> goto enomem;
   212         }
   213         ||
   214 
   215             if (asn_check_constraints(&asn_DEF_«$name», msg, NULL, NULL)) {
   216                 status = PEP_CONTRAINTS_VIOLATED;
   217                 goto error;
   218             }
   219 
   220             ssize_t size = uper_encode_to_new_buffer(&asn_DEF_«$name»,
   221                     NULL, msg, (void **) &payload);
   222             if (size == -1) {
   223                 status = PEP_CANNOT_ENCODE;
   224                 goto error;
   225             }
   226 
   227             status = prepare_message(me, partner, payload, size, &_message);
   228             if (status != PEP_STATUS_OK)
   229                 goto error;
   230             payload = NULL;
   231 
   232             free_identity(me);
   233             me = NULL;
   234 
   235             status = session->messageToSend(session->«$filename»_obj, _message);
   236 
   237             free_message(_message);
   238             ASN_STRUCT_FREE(asn_DEF_«$name», msg);
   239             free_identity(partner);
   240             `` if "$name='GroupKeys'" |> free_identity_list(kl);
   241             return status;
   242 
   243         enomem:
   244             status = PEP_OUT_OF_MEMORY;
   245         error:
   246             ASN_STRUCT_FREE(asn_DEF_«$name», msg);
   247             free(payload);
   248             free_message(_message);
   249             free_identity(me);
   250             free_identity(partner);
   251             `` if "$name='GroupKeys'" |> free_identity_list(kl);
   252             return status;
   253         }
   254 
   255         ||
   256     }
   257 }
   258