From f196c8418d11846ac7b5e3a24e80d615d64a2cf0 Mon Sep 17 00:00:00 2001 From: Erik Hofman <erik@ehofman.com> Date: Thu, 15 Apr 2021 10:11:42 +0200 Subject: [PATCH] Update the props sample description: remove an unnecessary type specifier (the union already holds it), add a sample version number and a mode to indicate reading from, or writing to, a property. The option to set a property value is reserved for future use and not yet implemented. --- src/Network/DDS/dds_props.c | 9 ++-- src/Network/DDS/dds_props.h | 8 ++- src/Network/DDS/dds_props.idl | 41 ++++++++------- src/Network/DDS/fg_dds_log.cpp | 8 ++- src/Network/DDS/fg_dds_prop.cpp | 91 ++++++++++++++++++--------------- src/Network/dds_props.cxx | 20 ++++---- 6 files changed, 99 insertions(+), 78 deletions(-) diff --git a/src/Network/DDS/dds_props.c b/src/Network/DDS/dds_props.c index 413c5f67e..7d4297763 100644 --- a/src/Network/DDS/dds_props.c +++ b/src/Network/DDS/dds_props.c @@ -17,8 +17,8 @@ static const dds_key_descriptor_t FG_DDS_PROP_keys[1] = static const uint32_t FG_DDS_PROP_ops [] = { DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_SGN | DDS_OP_FLAG_KEY, offsetof (FG_DDS_PROP, id), - DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (FG_DDS_PROP, guid), 16, - DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_SGN, offsetof (FG_DDS_PROP, type), + DDS_OP_ADR | DDS_OP_TYPE_1BY, offsetof (FG_DDS_PROP, version), + DDS_OP_ADR | DDS_OP_TYPE_BOO, offsetof (FG_DDS_PROP, mode), DDS_OP_ADR | DDS_OP_TYPE_UNI | DDS_OP_SUBTYPE_4BY | DDS_OP_FLAG_SGN, offsetof (FG_DDS_PROP, val._d), 9u, (31u << 16) + 4u, DDS_OP_JEQ | DDS_OP_TYPE_BOO | 0, FG_DDS_BOOL, offsetof (FG_DDS_PROP, val._u.Bool), DDS_OP_JEQ | DDS_OP_TYPE_4BY | DDS_OP_FLAG_SGN | 0, FG_DDS_NONE, offsetof (FG_DDS_PROP, val._u.Int32), @@ -29,6 +29,7 @@ static const uint32_t FG_DDS_PROP_ops [] = DDS_OP_JEQ | DDS_OP_TYPE_STR | 0, FG_DDS_ALIAS, offsetof (FG_DDS_PROP, val._u.String), DDS_OP_JEQ | DDS_OP_TYPE_STR | 0, FG_DDS_STRING, offsetof (FG_DDS_PROP, val._u.String), DDS_OP_JEQ | DDS_OP_TYPE_STR | 0, FG_DDS_UNSPECIFIED, offsetof (FG_DDS_PROP, val._u.String), + DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_1BY, offsetof (FG_DDS_PROP, guid), 16, DDS_OP_RTS }; @@ -40,7 +41,7 @@ const dds_topic_descriptor_t FG_DDS_PROP_desc = 1u, "FG::DDS_PROP", FG_DDS_PROP_keys, - 14, + 15, FG_DDS_PROP_ops, - "<MetaData version=\"1.0.0\"><Module name=\"FG\"><Enum name=\"propType\"><Element name=\"DDS_NONE\" value=\"0\"/><Element name=\"DDS_ALIAS\" value=\"1\"/><Element name=\"DDS_BOOL\" value=\"2\"/><Element name=\"DDS_INT\" value=\"3\"/><Element name=\"DDS_LONG\" value=\"4\"/><Element name=\"DDS_FLOAT\" value=\"5\"/><Element name=\"DDS_DOUBLE\" value=\"6\"/><Element name=\"DDS_STRING\" value=\"7\"/><Element name=\"DDS_UNSPECIFIED\" value=\"8\"/></Enum><Union name=\"propValue\"><SwitchType><Type name=\"propType\"/></SwitchType><Case name=\"Bool\"><Boolean/><Label value=\"DDS_BOOL\"/></Case><Case name=\"Int32\"><Long/><Label value=\"DDS_NONE\"/><Label value=\"DDS_INT\"/></Case><Case name=\"Int64\"><LongLong/><Label value=\"DDS_LONG\"/></Case><Case name=\"Float32\"><Float/><Label value=\"DDS_FLOAT\"/></Case><Case name=\"Float64\"><Double/><Label value=\"DDS_DOUBLE\"/></Case><Case name=\"String\"><String/><Label value=\"DDS_ALIAS\"/><Label value=\"DDS_STRING\"/><Label value=\"DDS_UNSPECIFIED\"/></Case></Union><Struct name=\"DDS_PROP\"><Member name=\"id\"><Long/></Member><Member name=\"guid\"><Array size=\"16\"><Octet/></Array></Member><Member name=\"type\"><Type name=\"propType\"/></Member><Member name=\"val\"><Type name=\"propValue\"/></Member></Struct></Module></MetaData>" + "<MetaData version=\"1.0.0\"><Module name=\"FG\"><Enum name=\"propType\"><Element name=\"DDS_NONE\" value=\"0\"/><Element name=\"DDS_ALIAS\" value=\"1\"/><Element name=\"DDS_BOOL\" value=\"2\"/><Element name=\"DDS_INT\" value=\"3\"/><Element name=\"DDS_LONG\" value=\"4\"/><Element name=\"DDS_FLOAT\" value=\"5\"/><Element name=\"DDS_DOUBLE\" value=\"6\"/><Element name=\"DDS_STRING\" value=\"7\"/><Element name=\"DDS_UNSPECIFIED\" value=\"8\"/></Enum><Union name=\"propValue\"><SwitchType><Type name=\"propType\"/></SwitchType><Case name=\"Bool\"><Boolean/><Label value=\"DDS_BOOL\"/></Case><Case name=\"Int32\"><Long/><Label value=\"DDS_NONE\"/><Label value=\"DDS_INT\"/></Case><Case name=\"Int64\"><LongLong/><Label value=\"DDS_LONG\"/></Case><Case name=\"Float32\"><Float/><Label value=\"DDS_FLOAT\"/></Case><Case name=\"Float64\"><Double/><Label value=\"DDS_DOUBLE\"/></Case><Case name=\"String\"><String/><Label value=\"DDS_ALIAS\"/><Label value=\"DDS_STRING\"/><Label value=\"DDS_UNSPECIFIED\"/></Case></Union><Struct name=\"DDS_PROP\"><Member name=\"id\"><Long/></Member><Member name=\"version\"><Octet/></Member><Member name=\"mode\"><Boolean/></Member><Member name=\"val\"><Type name=\"propValue\"/></Member><Member name=\"guid\"><Array size=\"16\"><Octet/></Array></Member></Struct></Module></MetaData>" }; diff --git a/src/Network/DDS/dds_props.h b/src/Network/DDS/dds_props.h index 5985daf1f..38a240299 100644 --- a/src/Network/DDS/dds_props.h +++ b/src/Network/DDS/dds_props.h @@ -17,7 +17,10 @@ extern "C" { #endif +#define FG_DDS_PROP_VERSION 0 #define FG_DDS_PROP_REQUEST -1 +#define FG_DDS_MODE_READ (0) +#define FG_DDS_MODE_WRITE (1) typedef enum FG_propType { FG_DDS_NONE, @@ -56,9 +59,10 @@ typedef struct FG_propValue typedef struct FG_DDS_PROP { int32_t id; - uint8_t guid[16]; - FG_propType type; + uint8_t version; + bool mode; FG_propValue val; + uint8_t guid[16]; } FG_DDS_PROP; extern const dds_topic_descriptor_t FG_DDS_PROP_desc; diff --git a/src/Network/DDS/dds_props.idl b/src/Network/DDS/dds_props.idl index dd59a3e18..0b8ac6bf8 100644 --- a/src/Network/DDS/dds_props.idl +++ b/src/Network/DDS/dds_props.idl @@ -5,7 +5,10 @@ module FG { // defining it this way also generates accompanying #defines in the header file. +const octet DDS_PROP_VERSION = 0; const short DDS_PROP_REQUEST = -1; +const boolean DDS_MODE_READ = 0; +const boolean DDS_MODE_WRITE = 1; enum propType { @@ -47,38 +50,40 @@ union propValue switch ( propType ) // Initial property request sequence // for properties where the id is not yet known: // 1. Set id to FG_DDS_PROP_REQUEST -// 2. set guid to the 16-byte participants GUID -// 3. Set type to STRING -// 4. Set val.String to the propery path -// 5. Send the package. +// 2. Set version to FG_DDS_PROP_VERSION +// 3. Set mode to FG_DDS_MODE_READ +// 4. set guid to the 16-byte participants GUID +// 5. Set val type to STRING +// 6. Set val String to the propery path +// 7. Send the package. // -// 6. wait for an answer +// 8. Wait for an answer // * Check whether guid matches the participants GUID. // * The index of the requested propery path is stored in the id variable // which should be used by successive request as the id for that property. -// * The type variable indicates the type of the value of the property. // * The val union holds the value of the propery. // // Successive property request sequence: -// 1. Set id to the id of the requested property -// 2. Send the package. +// 1. Make sure id is to the id of the requested property +// 2. Make sure version is to FG_DDS_PROP_VERSION +// 3. Set mode to FG_DDS_MODE_READ or FG_DDS_MODE_WRITE +// 3a. Optionally set the val union to match the property to overwrite. +// 4. Send the package. // -// 3. wait for an answer +// 5. Wait for an answer // * Check whether id matches the requested property id. -// * The type variable indicates the type of the value of the property. // * The val union holds the value of the propery. -// -// guid is not defined as an array of 16 unsigned characters to keep the -// sample small for successive requests. This way only a FG_DDS_PROP_REQUEST -// sample will reserve the full 16-bytes. struct DDS_PROP { - long id; // property index and DDS id + long id; // 32-bit property index and DDS id. + octet version; // 8-bit sample-type version number. + boolean mode; // FG_DDS_MODE_READ or FG_DDS_MODE_WRITE + propValue val; // property value or path. + + // A sequence could be used here but unfortunatelly it's initializer + // already is 10-bytes in size. octet guid[16]; - - propType type; - propValue val; }; #pragma keylist DDS_PROP id diff --git a/src/Network/DDS/fg_dds_log.cpp b/src/Network/DDS/fg_dds_log.cpp index 0102a05a8..8fe28e17a 100644 --- a/src/Network/DDS/fg_dds_log.cpp +++ b/src/Network/DDS/fg_dds_log.cpp @@ -111,11 +111,15 @@ int main() printf(" rudder: %lf\n", ctrls.rudder); } - if (topics["prop"]->read()) { + if (topics["prop"]->read() && + prop.version == FG_DDS_PROP_VERSION ) + { printf("=== [fg_dds_log] Received : "); printf("Prop Message:\n"); + printf(" version: %i\n", prop.version); + printf(" mode: %s\n", prop.mode ? "write" : "read"); if (prop.id == FG_DDS_PROP_REQUEST) { - printf(" request: %s\n", prop.val._u.String); + printf(" path: %s\n", prop.val._u.String); printf("GUID: "); for(int i=0; i<16; ++i) printf("%X ", prop.guid[i]); diff --git a/src/Network/DDS/fg_dds_prop.cpp b/src/Network/DDS/fg_dds_prop.cpp index 947b3e328..5720463ac 100644 --- a/src/Network/DDS/fg_dds_prop.cpp +++ b/src/Network/DDS/fg_dds_prop.cpp @@ -16,7 +16,7 @@ int main() FG_DDS_PROP prop; SG_DDS_Topic *topic = new SG_DDS_Topic(prop, &FG_DDS_PROP_desc); - participant.add(topic, SG_IO_OUT); + participant.add(topic, SG_IO_BI); dds_guid_t guid = topic->get_guid(); memcpy(prop.guid, guid.v, 16); @@ -25,6 +25,9 @@ int main() printf("%X ", prop.guid[i]); printf("\n"); + prop.version = FG_DDS_PROP_VERSION; + prop.mode = FG_DDS_MODE_READ; + char path[256]; printf("\nType 'q' to quit\n"); do @@ -33,7 +36,7 @@ int main() int len = scanf("%255s", path); if (len == EOF) continue; - if (*path == 'q') break; + if (*path == 'q') break; prop.id = FG_DDS_PROP_REQUEST; prop.val._d = FG_DDS_STRING; @@ -42,47 +45,51 @@ int main() topic->write(); participant.wait(); - - topic->read(); - switch(prop.val._d) + if (topic->read() && + prop.version == FG_DDS_PROP_VERSION && + prop.id != FG_DDS_PROP_REQUEST) { - case FG_DDS_NONE: - printf(" type: none"); - break; - case FG_DDS_ALIAS: - printf(" type: alias"); - printf(" value: %s\n", prop.val._u.String); - break; - case FG_DDS_BOOL: - printf(" type: bool"); - printf(" value: %i\n", prop.val._u.Bool); - break; - case FG_DDS_INT: - printf(" type: int"); - printf(" value: %i\n", prop.val._u.Int32); - break; - case FG_DDS_LONG: - printf(" type: long"); - printf(" value: %li\n", prop.val._u.Int64); - break; - case FG_DDS_FLOAT: - printf(" type: float"); - printf(" value: %f\n", prop.val._u.Float32); - break; - case FG_DDS_DOUBLE: - printf(" type: double"); - printf(" value: %lf\n", prop.val._u.Float64); - break; - case FG_DDS_STRING: - printf(" type: string"); - printf(" value: %s\n", prop.val._u.String); - break; - case FG_DDS_UNSPECIFIED: - printf(" type: unspecified"); - printf(" value: %s\n", prop.val._u.String); - break; - default: - break; + printf("\nReceived:\n"); + switch(prop.val._d) + { + case FG_DDS_NONE: + printf(" type: none"); + break; + case FG_DDS_ALIAS: + printf(" type: alias"); + printf(" value: %s\n", prop.val._u.String); + break; + case FG_DDS_BOOL: + printf(" type: bool"); + printf(" value: %i\n", prop.val._u.Bool); + break; + case FG_DDS_INT: + printf(" type: int"); + printf(" value: %i\n", prop.val._u.Int32); + break; + case FG_DDS_LONG: + printf(" type: long"); + printf(" value: %li\n", prop.val._u.Int64); + break; + case FG_DDS_FLOAT: + printf(" type: float"); + printf(" value: %f\n", prop.val._u.Float32); + break; + case FG_DDS_DOUBLE: + printf(" type: double"); + printf(" value: %lf\n", prop.val._u.Float64); + break; + case FG_DDS_STRING: + printf(" type: string"); + printf(" value: %s\n", prop.val._u.String); + break; + case FG_DDS_UNSPECIFIED: + printf(" type: unspecified"); + printf(" value: %s\n", prop.val._u.String); + break; + default: + break; + } } } while(true); diff --git a/src/Network/dds_props.cxx b/src/Network/dds_props.cxx index 72513f825..aacb2ba7b 100644 --- a/src/Network/dds_props.cxx +++ b/src/Network/dds_props.cxx @@ -81,7 +81,7 @@ bool FGDDSProps::process() { { if (prop.id == FG_DDS_PROP_REQUEST) { - if (prop.type == FG_DDS_STRING) + if (prop.val._d == FG_DDS_STRING) { const char *path = prop.val._u.String; auto it = path_list.find(path); @@ -148,31 +148,31 @@ void FGDDSProps::setProp(FG_DDS_PROP& prop, SGPropertyNode_ptr p) { simgear::props::Type type = p->getType(); if (type == simgear::props::BOOL) { - prop.type = FG_DDS_BOOL; + prop.val._d = FG_DDS_BOOL; prop.val._u.Bool = p->getBoolValue(); } else if (type == simgear::props::INT) { - prop.type = FG_DDS_INT; + prop.val._d = FG_DDS_INT; prop.val._u.Int32 = p->getIntValue(); } else if (type == simgear::props::LONG) { - prop.type = FG_DDS_LONG; + prop.val._d = FG_DDS_LONG; prop.val._u.Int64 = p->getLongValue(); } else if (type == simgear::props::FLOAT) { - prop.type = FG_DDS_FLOAT; + prop.val._d = FG_DDS_FLOAT; prop.val._u.Float32 = p->getFloatValue(); } else if (type == simgear::props::DOUBLE) { - prop.type = FG_DDS_DOUBLE; + prop.val._d = FG_DDS_DOUBLE; prop.val._u.Float64 = p->getDoubleValue(); } else if (type == simgear::props::ALIAS) { - prop.type = FG_DDS_ALIAS; + prop.val._d = FG_DDS_ALIAS; prop.val._u.String = const_cast<char*>(p->getStringValue()); } else if (type == simgear::props::STRING) { - prop.type = FG_DDS_STRING; + prop.val._d = FG_DDS_STRING; prop.val._u.String = const_cast<char*>(p->getStringValue()); } else if (type == simgear::props::UNSPECIFIED) { - prop.type = FG_DDS_UNSPECIFIED; + prop.val._d = FG_DDS_UNSPECIFIED; prop.val._u.String = const_cast<char*>(p->getStringValue()); } else { - prop.type = FG_DDS_NONE; + prop.val._d = FG_DDS_NONE; prop.val._u.Int32 = 0; } }