FlightGear next
dds_props.cxx
Go to the documentation of this file.
1// dds_props.cxx -- FGFS "DDS" properties protocal class
2//
3// Written by Erik Hofman, started April 2021
4//
5// Copyright (C) 2021 by Erik Hofman <erik@ehofman.com>
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License as
9// published by the Free Software Foundation; either version 2 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful, but
13// WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15// General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20//
21// $Id$
22
23
24#ifdef HAVE_CONFIG_H
25# include <config.h>
26#endif
27
28#include <simgear/structure/exception.hxx>
29#include <simgear/debug/logstream.hxx>
30#include <simgear/io/iochannel.hxx>
31#include <simgear/props/props.hxx>
32
33#include <simgear/io/SGDataDistributionService.hxx>
34
35#include <Main/fg_props.hxx>
36#include <Main/globals.hxx>
37
38#include "dds_props.hxx"
39
40// open hailing frequencies
42 if (is_enabled()) {
43 SG_LOG(SG_IO, SG_ALERT, "This shouldn't happen, but the channel "
44 << "is already in use, ignoring");
45 return false;
46 }
47
48 SGIOChannel *io = get_io_channel();
49
50 SG_DDS_Topic *dds = static_cast<SG_DDS_Topic*>(io);
51 dds->setup(prop, &FG_DDS_prop_desc);
52
53 // always send and recieve.
54 if (!io->open(SG_IO_BI)) {
55 SG_LOG(SG_IO, SG_ALERT, "Error opening channel communication layer.");
56 return false;
57 }
58
59 set_enabled(true);
60
61 return true;
62}
63
64// process work for this port
66 SGIOChannel *io = get_io_channel();
67
68 int length = sizeof(prop);
69 char *buf = reinterpret_cast<char*>(&prop);
70
71 if (get_direction() == SG_IO_IN)
72 {
73 // act as a client: send a request and wait for an answer.
74
75 }
76 else if (get_direction() == SG_IO_OUT || get_direction() == SG_IO_BI)
77 {
78 // act as a server: read requests and send the results.
79 while (io->read(buf, length) &&
80 prop.version == FG_DDS_PROP_VERSION &&
81 prop.mode == FG_DDS_MODE_READ)
82 {
83 // s is used to keep a copy of the string returned by
84 // p->getStringValue() in setProp until it is sent to the DDS layer.
85 std::string s;
86
87 if (prop.id == FG_DDS_PROP_REQUEST)
88 {
89 if (prop.val._d == FG_DDS_STRING)
90 {
91 const char *path = prop.val._u.String;
92 auto it = path_list.find(path);
93 if (it == path_list.end())
94 {
95 SGPropertyNode_ptr props = globals->get_props();
96 SGPropertyNode_ptr p = props->getNode(path);
97 if (p)
98 {
99 prop.id = prop_list.size();
100 try {
101 prop_list.push_back(p);
102 path_list[prop.val._u.String] = prop.id;
103
104 } catch (sg_exception&) {
105 SG_LOG(SG_IO, SG_ALERT, "out of memory");
106 }
107 }
108 setProp(prop, p, s);
109 }
110 else
111 {
112 prop.id = std::distance(path_list.begin(), it);
113 setProp(prop, prop_list[prop.id], s);
114 }
115 }
116 else
117 {
118 SG_LOG(SG_IO, SG_DEBUG, "Recieved a mangled DDS sample.");
119 setProp(prop, nullptr, s);
120 }
121 }
122 else {
123 setProp(prop, prop_list[prop.id], s);
124 }
125
126 // send the response.
127 if (!io->write(buf, length)) {
128 SG_LOG(SG_IO, SG_ALERT, "Error writing data.");
129 }
130 } // while
131 }
132
133 return true;
134}
135
136// close the channel
138 SGIOChannel *io = get_io_channel();
139
140 set_enabled(false);
141
142 if (! io->close()) {
143 return false;
144 }
145
146 return true;
147}
148
149void FGDDSProps::setProp(FG_DDS_prop& prop, SGPropertyNode_ptr p, std::string& s)
150{
151// prop.id = FG_DDS_PROP_REQUEST;
153 prop.mode = FG_DDS_MODE_WRITE;
154 if (p)
155 {
156 simgear::props::Type type = p->getType();
157 if (type == simgear::props::BOOL) {
158 prop.val._d = FG_DDS_BOOL;
159 prop.val._u.Bool = p->getBoolValue();
160 } else if (type == simgear::props::INT) {
161 prop.val._d = FG_DDS_INT;
162 prop.val._u.Int32 = p->getIntValue();
163 } else if (type == simgear::props::LONG) {
164 prop.val._d = FG_DDS_LONG;
165 prop.val._u.Int64 = p->getLongValue();
166 } else if (type == simgear::props::FLOAT) {
167 prop.val._d = FG_DDS_FLOAT;
168 prop.val._u.Float32 = p->getFloatValue();
169 } else if (type == simgear::props::DOUBLE) {
170 prop.val._d = FG_DDS_DOUBLE;
171 prop.val._u.Float64 = p->getDoubleValue();
172 } else if (type == simgear::props::ALIAS) {
173 prop.val._d = FG_DDS_ALIAS;
174 s = p->getStringValue();
175 prop.val._u.String = const_cast<char*>(s.c_str());
176 } else if (type == simgear::props::STRING) {
177 prop.val._d = FG_DDS_STRING;
178 s = p->getStringValue();
179 prop.val._u.String = const_cast<char*>(s.c_str());
180 } else if (type == simgear::props::UNSPECIFIED) {
181 prop.val._d = FG_DDS_UNSPECIFIED;
182 s = p->getStringValue();
183 prop.val._u.String = const_cast<char*>(s.c_str());
184 } else {
185 prop.val._d = FG_DDS_NONE;
186 prop.val._u.Int32 = 0;
187 }
188 }
189}
190
191
#define p(x)
bool open()
Definition dds_props.cxx:41
bool process()
Definition dds_props.cxx:65
bool close()
SGProtocolDir get_direction() const
Definition protocol.hxx:65
SGIOChannel * get_io_channel() const
Definition protocol.hxx:90
void set_enabled(const bool b)
Definition protocol.hxx:88
bool is_enabled() const
Definition protocol.hxx:87
const dds_topic_descriptor_t FG_DDS_prop_desc
Definition dds_props.c:36
#define FG_DDS_MODE_READ
Definition dds_props.h:22
#define FG_DDS_MODE_WRITE
Definition dds_props.h:23
#define FG_DDS_PROP_VERSION
Definition dds_props.h:20
#define FG_DDS_PROP_REQUEST
Definition dds_props.h:21
@ FG_DDS_UNSPECIFIED
Definition dds_props.h:34
@ FG_DDS_LONG
Definition dds_props.h:30
@ FG_DDS_FLOAT
Definition dds_props.h:31
@ FG_DDS_ALIAS
Definition dds_props.h:27
@ FG_DDS_NONE
Definition dds_props.h:26
@ FG_DDS_INT
Definition dds_props.h:29
@ FG_DDS_BOOL
Definition dds_props.h:28
@ FG_DDS_DOUBLE
Definition dds_props.h:32
@ FG_DDS_STRING
Definition dds_props.h:33
FGGlobals * globals
Definition globals.cxx:142
FG_propValue val
Definition dds_props.h:64
uint8_t version
Definition dds_props.h:62
FG_propType _d
Definition dds_props.h:43
union FG_propValue::@155153037146116023270074041102065253170142315045 _u