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