sync/gen_actions.ysl2
author Krista Bennett <krista@pep-project.org>
Thu, 18 Jan 2018 00:46:19 +0100
changeset 2410 721952accdee
parent 2287 026ab4dae779
child 2829 e444c3c960bb
permissions -rw-r--r--
DANGER! MERGED IN ENGINE-289! SOME DOC BUGS STILL EXIST - USE WITH CARE!!!
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 // generate actions skeleton
     5 
     6 // Copyleft (c) 2016, p≡p foundation
     7 
     8 // Written by Volker Birk
     9 
    10 include yslt.yml2
    11 
    12 tstylesheet {
    13     include standardlib.ysl2
    14     include ./functions.ysl2
    15 
    16     template "/protocol" {
    17         apply "fsm", mode=send, 0;
    18         apply "fsm", mode=other, 0;
    19     }
    20 
    21     template "fsm", mode=send document "generated/{@filename}_send_actions.c", "text" {
    22         const "name", "@name";
    23         const "filename", "@filename";
    24         ||
    25         // Send Actions for «@name» state machine
    26 
    27         #include <assert.h>
    28         #include "pEp_internal.h"
    29         #include "keymanagement.h"
    30         #include "message.h"
    31         #include "«@filename»_fsm.h"
    32         #include "baseprotocol.h"
    33         #include "map_asn1.h"
    34         #include "../asn.1/DeviceGroup-Protocol.h"
    35         #include "sync_impl.h"
    36         ||
    37         for "func:distinctName(//action)"
    38             if "substring(@name, 1, 4) = 'send'"
    39                 | #include "../asn.1/«substring(@name, 5, 255)».h"
    40         |
    41         for "func:distinctName(//action)"
    42             if "substring(@name, 1, 4) = 'send'"
    43                 call "send_action"
    44                     with "action", ".",
    45                     with "fsm", "$name",
    46                     with "filename", "$filename";
    47 
    48         ||
    49 
    50         PEP_STATUS _notifyHandshake(
    51                 PEP_SESSION session,
    52                 Identity partner,
    53                 sync_handshake_signal signal
    54             );
    55         ||
    56 
    57         for "func:distinctName(//action)"
    58             if "substring(@name, 1, 6) = 'notify'"
    59                 call "notify_action"
    60                     with "action", ".",
    61                     with "fsm", "$name",
    62                     with "filename", "$filename";
    63     }
    64 
    65     template "fsm", mode=other document "skeletons/{@filename}_actions.c", "text" {
    66         const "name", "@name";
    67         const "filename", "@filename";
    68         ||
    69         // Actions for «@name» state machine
    70 
    71         #include <assert.h>
    72         #include "pEp_internal.h"
    73         #include "keymanagement.h"
    74         #include "message.h"
    75         #include "«@filename»_fsm.h"
    76         #include "../asn.1/DeviceGroup-Protocol.h"
    77 
    78         ||
    79         for "func:distinctName(//action)"
    80             if "substring(@name, 1, 4) != 'send'"
    81                 call "other_action"
    82                     with "action", ".",
    83                     with "fsm", "$name",
    84                     with "filename", "$filename";
    85     }
    86 
    87     function "paramcheck" {
    88         param "partner";
    89         |> assert(session);
    90         choose {
    91             when "$partner"
    92             ||
    93                 assert(partner);
    94                 if (!(session && partner))
    95                     return PEP_ILLEGAL_VALUE;
    96             ||
    97             otherwise
    98             ||
    99                 assert(!partner);
   100                 if (!(session && !partner))
   101                     return PEP_ILLEGAL_VALUE;
   102             ||
   103         }
   104     }
   105 
   106     function "other_action" {
   107         param "action";
   108         param "fsm";
   109         param "filename", "'###'";
   110 
   111         ||
   112 
   113         // «$action/@name»() - 
   114         //
   115         //  params:
   116         //      session (in)        session handle
   117         //      state (in)          state the state machine is in
   118         `` if "parm"        | //      partner (in)        partner to communicate with
   119         `` if "not(parm)"   | //      partner (in)        (must be NULL)
   120         //
   121         //  returns:
   122         //      PEP_STATUS_OK or any other value on error
   123 
   124         PEP_STATUS «$action/@name»(
   125                 PEP_SESSION session,
   126                 «$fsm»_state state,
   127                 Identity partner,
   128                 void *extra
   129             )
   130         {
   131             PEP_STATUS status = PEP_STATUS_OK;
   132 
   133             `` call "paramcheck" with "partner", "parm/partner";
   134 
   135             // working code
   136 
   137             // free extra
   138             return status;
   139 
   140         enomem:
   141             status = PEP_OUT_OF_MEMORY;
   142         error:
   143             // free extra
   144             return status;
   145         }
   146 
   147         ||
   148     }
   149 
   150     function "send_action" {
   151         param "action";
   152         param "fsm";
   153         param "filename", "'###'";
   154         const "name", "substring($action/@name, 5, 255)";
   155         const "lname", "concat(yml:lcase(substring($name, 1, 1)), substring($name, 2))";
   156 
   157         ||
   158 
   159         // «$action/@name»() - send «$name» message
   160         //
   161         //  params:
   162         //      session (in)        session handle
   163         //      state (in)          state the state machine is in
   164         `` if "parm"        | //      partner (in)        partner to communicate with
   165         `` if "not(parm)"   | //      partner (in)        (must be NULL)
   166         //
   167         //  returns:
   168         //      PEP_STATUS_OK or any other value on error
   169 
   170         PEP_STATUS «$action/@name»(
   171                 PEP_SESSION session,
   172                 «$fsm»_state state,
   173                 Identity partner,
   174                 void *extra
   175             )
   176         {
   177             assert(session && state);
   178             if (!(session && state))
   179                 return PEP_ILLEGAL_VALUE;
   180 
   181             PEP_STATUS status = PEP_STATUS_OK;
   182             `` if "$name='GroupKeys' or $name='GroupUpdate'" |> identity_list *kl = new_identity_list(NULL);
   183 
   184             DeviceGroup_Protocol_t *msg = new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR_«$lname»);
   185             if (!msg)
   186                 goto enomem;
   187         ||
   188         choose {
   189             when "$name='GroupKeys' or $name='GroupUpdate'" {
   190                 |
   191                 |> status = _own_identities_retrieve(session, &kl, PEP_idf_not_for_sync);
   192                 |> if (status != PEP_STATUS_OK)
   193                 |>> goto error;
   194                 |> if (IdentityList_from_identity_list(kl, &msg->payload.choice.«$lname».ownIdentities) == NULL)
   195                 |>> goto enomem;
   196             }
   197         }
   198         choose {
   199             when "$name='GroupKeys' or $name='HandshakeRequest'" {
   200                 |
   201                 |> msg->payload.choice.«$lname».partner_id = 
   202                 |>     OCTET_STRING_new_fromBuf(&asn_DEF_UTF8String,
   203                 |>                              partner->user_id, -1);
   204                 |> if (partner->user_id && !msg->payload.choice.«$lname».partner_id)
   205                 |>    goto enomem;
   206                 |
   207                 |> char *devgrp = NULL;
   208                 |> status = get_device_group(session, &devgrp);
   209                 |> if (status == PEP_STATUS_OK && devgrp && devgrp[0])
   210                 |> msg->payload.choice.«$lname».group_id = 
   211                 |>     OCTET_STRING_new_fromBuf(&asn_DEF_UTF8String,
   212                 |>                              devgrp, -1);
   213                 |> free(devgrp);
   214                 |> if (devgrp && !msg->payload.choice.«$lname».partner_id)
   215                 |>    goto enomem;
   216             }
   217         }
   218         ||
   219 
   220         ||
   221         choose {
   222             when "count(/protocol/unencrypted/*[name()=$action/@name]) = 0"
   223                 |> bool encrypted = true;
   224             otherwise
   225                 |> bool encrypted = false;
   226         }
   227         choose {
   228             when "count(/protocol/broadcast/*[name()=$action/@name]) = 0"
   229                 |> status = unicast_msg(session, partner, state, msg, encrypted);
   230             otherwise
   231                 |> status = multicast_self_msg(session, state, msg, encrypted);
   232         }
   233         ||
   234             if (status != PEP_STATUS_OK)
   235                 goto error;
   236 
   237             `` if "$name='GroupKeys' or $name='GroupUpdate'" |> free_identity_list(kl);
   238             free_DeviceGroup_Protocol_msg(msg);
   239             return PEP_STATUS_OK;
   240 
   241         enomem:
   242             status = PEP_OUT_OF_MEMORY;
   243         error:
   244             free_DeviceGroup_Protocol_msg(msg);
   245             `` if "$name='GroupKeys'" |> free_identity_list(kl);
   246             return status;
   247         }
   248 
   249         ||
   250     }
   251 
   252     function "UnCamelUp" {
   253         param "text";
   254         const "tokens", "str:tokenize($text, '')";
   255 
   256         for "$tokens" {
   257             choose {
   258                 when "contains('ABCDEFGHIJKLMNOPQRSTUVWXYZ',.)" > _«.»
   259                 otherwise value "yml:ucase(.)";
   260             }
   261         }
   262     }
   263 
   264     function "notify_action" {
   265         param "action";
   266         param "fsm";
   267         param "filename", "'###'";
   268         const "name", "substring($action/@name, 7, 255)";
   269         const "uname" call "UnCamelUp" with "text", "$name";
   270         ||
   271 
   272         // «$action/@name»() - notify «$name» to app
   273         //
   274         //  params:
   275         //      session (in)        session handle
   276         //      state (in)          state the state machine is in
   277         //      partner (in)        partner to communicate with
   278         //
   279         //  returns:
   280         //      PEP_STATUS_OK or any other value on error
   281 
   282         PEP_STATUS «$action/@name»(
   283                 PEP_SESSION session,
   284                 «$fsm»_state state,
   285                 Identity partner,
   286                 void *extra
   287             )
   288         {
   289             assert(session && state);
   290             assert(extra == NULL);
   291             if (!(session && state && extra == NULL))
   292                 return PEP_ILLEGAL_VALUE;
   293 
   294             return _notifyHandshake(session, partner, SYNC_NOTIFY«$uname»);
   295         }
   296 
   297         ||
   298     }
   299 }
   300