Browse Source

...

sync_and_key_reset
Volker Birk 4 years ago
parent
commit
89b78fd5c4
8 changed files with 204 additions and 77 deletions
  1. +3
    -0
      .hgignore
  2. +0
    -5
      src/sync.c
  3. +11
    -11
      src/sync_actions.c
  4. +18
    -13
      src/sync_impl.c
  5. +3
    -11
      src/sync_impl.h
  6. +5
    -5
      sync/cond_act.yml2
  7. +5
    -5
      sync/gen_message_func.ysl2
  8. +159
    -27
      sync/gen_statemachine.ysl2

+ 3
- 0
.hgignore View File

@ -67,6 +67,8 @@ src/KeySync_fsm.c
src/KeySync_fsm.h
src/Sync_func.c
src/Sync_func.h
src/Sync_event.c
src/Sync_event.h
asn.1/keysync.asn1
asn.1/sync.asn1
sync/.codecs
@ -74,3 +76,4 @@ sync/.messages
sync/.actions
sync/.codegen
sync/.statemachines

+ 0
- 5
src/sync.c View File

@ -29,11 +29,6 @@ DYNAMIC_API PEP_STATUS register_sync_callbacks(
session->inject_sync_msg = inject_sync_msg;
session->retrieve_next_sync_msg = retrieve_next_sync_msg;
// start state machine
PEP_STATUS status = inject_Sync_event(session, Sync_PR_keysync, Init);
if (status != PEP_STATUS_OK)
unregister_sync_callbacks(session);
return status;
}


+ 11
- 11
src/sync_actions.c View File

@ -66,7 +66,7 @@ PEP_STATUS keyElectionWon(PEP_SESSION session, bool *result)
if (!(session && result))
return PEP_ILLEGAL_VALUE;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *from = session->sync_state.common.from;
assert(from && from->fpr && from->fpr[0] && from->address && from->address[0]);
if (!(from && from->fpr && from->fpr[0] && from->address && from->address[0]))
@ -183,11 +183,11 @@ PEP_STATUS showSoleHandshake(PEP_SESSION session)
if (!session->notifyHandshake)
return PEP_SYNC_NO_NOTIFY_CALLBACK;
assert(session->sync_state.basic.from);
if (!session->sync_state.basic.from)
assert(session->sync_state.common.from);
if (!session->sync_state.common.from)
return PEP_ILLEGAL_VALUE;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *from = session->sync_state.common.from;
pEp_identity *me = NULL;
PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
assert(status == PEP_STATUS_OK);
@ -280,7 +280,7 @@ PEP_STATUS ownKeysAreGroupKeys(PEP_SESSION session)
if (!il)
return PEP_OUT_OF_MEMORY;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *from = session->sync_state.common.from;
identity_list *_il = il;
int result;
@ -349,11 +349,11 @@ PEP_STATUS showJoinGroupHandshake(PEP_SESSION session)
if (!session->notifyHandshake)
return PEP_SYNC_NO_NOTIFY_CALLBACK;
assert(session->sync_state.basic.from);
if (!session->sync_state.basic.from)
assert(session->sync_state.common.from);
if (!session->sync_state.common.from)
return PEP_ILLEGAL_VALUE;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *from = session->sync_state.common.from;
pEp_identity *me = NULL;
PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
assert(status == PEP_STATUS_OK);
@ -390,11 +390,11 @@ PEP_STATUS showGroupedHandshake(PEP_SESSION session)
if (!session->notifyHandshake)
return PEP_SYNC_NO_NOTIFY_CALLBACK;
assert(session->sync_state.basic.from);
if (!session->sync_state.basic.from)
assert(session->sync_state.common.from);
if (!session->sync_state.common.from)
return PEP_ILLEGAL_VALUE;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *from = session->sync_state.common.from;
pEp_identity *me = NULL;
PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
assert(status == PEP_STATUS_OK);


+ 18
- 13
src/sync_impl.c View File

@ -15,20 +15,25 @@ PEP_STATUS Sync_driver(
if (!(session && fsm))
return PEP_ILLEGAL_VALUE;
switch (fsm) {
case Sync_PR_keysync: {
int state = session->sync_state.keysync.state;
state = fsm_KeySync(session, state, event);
if (state > 0)
session->sync_state.keysync.state = state;
else if (state < 0)
return PEP_STATEMACHINE_ERROR - state;
break;
int next_state = None;
do {
switch (fsm) {
case Sync_PR_keysync: {
next_state = fsm_KeySync(session, session->sync_state.keysync.state, event);
if (next_state > None) {
session->sync_state.keysync.state = next_state;
event = Init;
}
else if (next_state < None) {
return PEP_STATEMACHINE_ERROR - state;
}
break;
}
default:
return PEP_ILLEGAL_VALUE;
}
default:
return PEP_ILLEGAL_VALUE;
}
} while (next_state);
return PEP_STATUS_OK;
}


+ 3
- 11
src/sync_impl.h View File

@ -11,14 +11,6 @@
extern "C" {
#endif
// event struct
typedef struct _Sync_event {
Sync_PR fsm;
int event;
Sync_t *msg;
} Sync_event_t;
// conditions
PEP_STATUS deviceGrouped(PEP_SESSION session, bool *result);
@ -57,11 +49,11 @@ PEP_STATUS send_Sync_message(
int event
);
// receive event and store it in state
// receive message and store it in state
PEP_STATUS recv_Sync_event(
PEP_STATUS recv_Sync_message(
PEP_SESSION session,
Sync_event_t *ev
Sync_t *msg
);
// state machine driver


+ 5
- 5
sync/cond_act.yml2 View File

@ -63,7 +63,7 @@ condition challengeAccepted
condition keyElectionWon
||
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *from = session->sync_state.common.from;
assert(from && from->fpr && from->fpr[0] && from->address && from->address[0]);
if (!(from && from->fpr && from->fpr[0] && from->address && from->address[0]))
@ -147,11 +147,11 @@ function "show_handshake" {
if (!session->notifyHandshake)
return PEP_SYNC_NO_NOTIFY_CALLBACK;
assert(session->sync_state.basic.from);
if (!session->sync_state.basic.from)
assert(session->sync_state.common.from);
if (!session->sync_state.common.from)
return PEP_ILLEGAL_VALUE;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *from = session->sync_state.common.from;
pEp_identity *me = NULL;
PEP_STATUS status = get_identity(session, from->address, PEP_OWN_USERID, &me);
assert(status == PEP_STATUS_OK);
@ -223,7 +223,7 @@ action ownKeysAreGroupKeys {
if (!il)
return PEP_OUT_OF_MEMORY;
pEp_identity *from = session->sync_state.basic.from;
pEp_identity *from = session->sync_state.common.from;
identity_list *_il = il;
int result;


+ 5
- 5
sync/gen_message_func.ysl2 View File

@ -39,9 +39,9 @@ extern "C" {
// state
struct «@name»_state_s {
struct basic_state_s {
struct common_state_s {
pEp_identity *from;
} basic;
} common;
`` apply "fsm", mode=state
};
@ -95,17 +95,17 @@ void free_«@name»_state(PEP_SESSION session)
if (!session)
return;
free_identity(session->«yml:lcase(@name)»_state.basic.from);
session->«yml:lcase(@name)»_state.basic.from = NULL;
free_identity(session->«yml:lcase(@name)»_state.common.from);
||
for "fsm"
for "func:distinctName(message/field[not(func:basicType())])"
|> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
|
for "func:distinctName(fsm/message/field[@type='TID'])"
|> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->own_«yml:lcase(../../../@name)»_state.«@name»);
||
memset(&session->sync_state, 0, sizeof(session->sync_state));
}
«@name»_t *new_«@name»_message(«@name»_PR fsm, int message_type)


+ 159
- 27
sync/gen_statemachine.ysl2 View File

@ -14,22 +14,21 @@ tstylesheet {
include ./functions.ysl2
template "/protocol" {
document "generated/{@name}_impl.h", "text" {
document "generated/{@name}_event.h", "text"
||
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#pragma once
#include "fsm_common.h"
#include "message_api.h"
#include "../asn.1/Sync.h"
#include "dynamic_api.h"
#ifdef __cplusplus
extern "C" {
#endif
// event struct
#include "../asn.1/«@name».h"
typedef struct _«@name»_event {
«@name»_PR fsm;
@ -37,6 +36,100 @@ tstylesheet {
«@name»_t *msg;
} «@name»_event_t;
// new_«@name»_event() - allocate a new «@name»_event
//
// parameters:
// fsm (in) finite state machine the event is for
// event (in) event or None
// msg (in) message to compute event from
//
// return value:
// pointer to new event or NULL in case of failure
//
// caveat:
// event must be valid for fsm or None
// in case msg is given event will be calculated out of message
DYNAMIC_API «@name»_event_t *new_«@name»_event(«@name»_PR fsm, int event, «@name»_t *msg);
// free_«@name»_event() - free memory occupied by event
//
// parameters:
// ev (in) event to free
DYNAMIC_API void free_«@name»_event(«@name»_event_t *ev);
#ifdef __cplusplus
}
#endif
||
document "generated/{@name}_event.c", "text"
||
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include "pEp_internal.h"
#include "«@name»_event.h"
#include "«@name»_func.h"
DYNAMIC_API «@name»_event_t *new_«@name»_event(«@name»_PR fsm, int event, «@name»_t *msg)
{
assert(fsm > 0 && (event >= 0 |`> |` msg));
if (!(fsm > 0 && (event >= 0 |`> |` msg)))
return NULL;
«@name»_event_t *ev = («@name»_event_t *) calloc(1, sizeof(«@name»_event_t));
assert(ev);
if (!ev)
return NULL;
ev->fsm = fsm;
ev->event = event;
ev->msg = msg;
if (msg) {
switch (fsm) {
`` apply "fsm", 3, mode=event
default:
// unknown protocol
free(ev);
return NULL;
}
}
return ev;
}
DYNAMIC_API void free_«@name»_event(«@name»_event_t *ev)
{
if (ev) {
free_«@name»_message(ev->msg);
free(ev);
}
}
||
document "generated/{@name}_impl.h", "text" {
||
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#pragma once
#include "fsm_common.h"
#include "message_api.h"
#include "../asn.1/Sync.h"
#ifdef __cplusplus
extern "C" {
#endif
// conditions
||
@ -69,11 +162,11 @@ tstylesheet {
int event
);
// receive event and store it in state
// receive message and store it in state
PEP_STATUS recv_«@name»_event(
PEP_STATUS recv_«@name»_message(
PEP_SESSION session,
«@name»_event_t *ev
«@name»_t *msg
);
// state machine driver
@ -118,11 +211,14 @@ tstylesheet {
if (!(session && fsm))
return PEP_ILLEGAL_VALUE;
switch (fsm) {
`` apply "fsm", 2, mode=driver
default:
return PEP_ILLEGAL_VALUE;
}
int next_state = None;
do {
switch (fsm) {
`` apply "fsm", 3, mode=driver
default:
return PEP_ILLEGAL_VALUE;
}
} while (next_state);
return PEP_STATUS_OK;
}
@ -271,15 +367,41 @@ tstylesheet {
apply "fsm", 0, mode=gen;
}
template "fsm", mode=event
{
||
case Sync_PR_«yml:lcase(@name)»: {
switch (msg->choice.keysync.choice.present) {
||
for "message"
||
case «../@name»__payload_PR_«yml:mixedCase(@name)»:
ev->event = «@name»;
break;
||
||
default:
// unknown message type
free(ev);
return NULL;
}
break;
}
||
}
template "fsm", mode=driver
||
case Sync_PR_«yml:lcase(@name)»: {
int state = session->sync_state.«yml:lcase(@name)».state;
state = fsm_«@name»(session, state, event);
if (state > 0)
session->sync_state.«yml:lcase(@name)».state = state;
else if (state < 0)
next_state = fsm_«@name»(session, session->«yml:lcase(../@name)»_state.«yml:lcase(@name)».state, event);
if (next_state > None) {
session->«yml:lcase(../@name)»_state.«yml:lcase(@name)».state = next_state;
event = Init;
}
else if (next_state < None) {
return PEP_STATEMACHINE_ERROR - state;
}
break;
}
@ -338,6 +460,9 @@ tstylesheet {
const char *«@name»_state_name(int state);
// the state machine function is returning the next state in case of a
// transition or None for staying
«@name»_state fsm_«@name»(
PEP_SESSION session,
«@name»_state state,
@ -427,16 +552,15 @@ tstylesheet {
switch (state) {
case None:
«@name»_SERVICE_LOG("transition to state Init", "None is not a valid state");
return Init;
return «@name»_state_Init;
`` apply "state", 2, mode=fsm
default:
«@name»_ERR_LOG_INT("«@name»_fsm() called with invalid state", state);
«@name»_ERR_LOG_INT("invalid state", state);
return invalid_state;
}
return state;
return None;
}
||
@ -454,11 +578,20 @@ tstylesheet {
switch (event) {
case None:
«../@name»_SERVICE_LOG("received None event", "ignoring");
return state;
break;
||
if "not(event[@name='Init'])"
||
case Init:
// nothing to do
break;
||
||
`` apply "event", 2, mode=fsm
default:
«../@name»_ERR_LOG_INT("«../@name»_fsm() called with invalid event", event);
«../@name»_ERR_LOG_INT("invalid event", event);
return invalid_event;
}
break;
@ -491,8 +624,7 @@ tstylesheet {
||
«$fsm/@name»_SERVICE_LOG("transition to state", "«@target»");
state = «@target»;
break;
return «@target»;
||
}


Loading…
Cancel
Save