41#include "FGInputSocket.h"
43#include "models/FGAircraft.h"
44#include "FGXMLElement.h"
45#include "string_utilities.h"
73 log <<
"No port assigned in input element\n";
78 if (to_upper(action) ==
"BLOCKING_INPUT")
92 return CreateSocket();
99bool FGInputSocket::CreateSocket()
101 socket = std::make_unique<FGfdmSocket>(SockPort, SockProtocol);
103 if (!socket)
return false;
104 if (!socket->GetConnectStatus())
return false;
136 return enabled_status;
144 if (!socket->GetConnectStatus())
return;
147 socket->WaitUntilReadable();
149 string raw_data = socket->Receive();
151 if (!raw_data.empty()) {
158 size_t string_start = data.find_first_not_of(
"\r\n", start);
159 if (string_start == string::npos)
break;
160 size_t string_end = data.find_first_of(
"\r\n", string_start);
161 if (string_end == string::npos)
break;
162 string line = data.substr(string_start, string_end-string_start);
163 if (line.empty())
break;
166 vector <string> tokens = split(line,
' ');
168 string command, argument, str_value;
169 if (!tokens.empty()) {
170 command = to_lower(tokens[0]);
171 if (tokens.size() > 1) {
172 argument = trim(tokens[1]);
173 if (tokens.size() > 2) {
174 str_value = trim(tokens[2]);
179 if (command ==
"set") {
182 if (argument.empty()) {
183 socket->Reply(
"No property argument supplied.\r\n");
187 node = PropertyManager->GetNode(argument);
189 socket->Reply(
"Badly formed property query\r\n");
194 socket->Reply(
"Unknown property\r\n");
197 socket->Reply(
"Not a leaf property\r\n");
201 double value = atof_locale_c(str_value);
204 string msg(e.what());
210 socket->Reply(
"set successful\r\n");
212 }
else if (command ==
"get") {
215 if (argument.empty()) {
216 socket->Reply(
"No property argument supplied.\r\n");
220 node = PropertyManager->GetNode(argument);
222 socket->Reply(
"Badly formed property query\r\n");
227 socket->Reply(
"Unknown property\r\n");
232 socket->Reply(query);
234 socket->Reply(
"Must be in HOLD to search properties\r\n");
238 buf << argument <<
" = " << setw(12) << setprecision(6) << node->
getDoubleValue() <<
'\r' << endl;
239 socket->Reply(buf.str());
242 }
else if (command ==
"hold") {
245 socket->Reply(
"Holding\r\n");
247 }
else if (command ==
"resume") {
250 socket->Reply(
"Resuming\r\n");
252 }
else if (command ==
"iterate") {
255 istringstream (argument) >> argumentInt;
256 if (argument.empty()) {
257 socket->Reply(
"No argument supplied for number of iterations.\r\n");
260 if ( !(argumentInt > 0) ){
261 socket->Reply(
"Required argument must be a positive Integer.\r\n");
266 socket->Reply(
"Iterations performed\r\n");
268 }
else if (command ==
"quit") {
271 socket->Send(
"Closing connection\r\n");
274 }
else if (command ==
"info") {
278 info <<
"JSBSim version: " << JSBSim_version <<
"\r\n";
279 info <<
"Config File version: " << needed_cfg_version <<
"\r\n";
280 info <<
"Aircraft simulated: " << FDMExec->
GetAircraft()->GetAircraftName() <<
"\r\n";
281 info <<
"Simulation time: " << setw(8) << setprecision(3) << FDMExec->
GetSimTime() <<
'\r' << endl;
282 socket->Reply(info.str());
284 }
else if (command ==
"help") {
287 " JSBSim Server commands:\r\n\r\n"
288 " get {property name}\r\n"
289 " set {property name} {value}\r\n"
292 " iterate {value}\r\n"
298 socket->Reply(
string(
"Unknown command: ") + command +
"\r\n");
305 size_t last_crlf = data.find_last_of(
"\r\n");
306 if (last_crlf != string::npos) {
307 if (last_crlf < data.length()-1)
308 data = data.substr(last_crlf+1);
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
Encapsulates the JSBSim simulation executive.
std::shared_ptr< FGAircraft > GetAircraft(void) const
Returns the FGAircraft pointer.
std::string QueryPropertyCatalog(const std::string &check, const std::string &end_of_line="\n")
Retrieves property or properties matching the supplied string.
void EnableIncrementThenHold(int Timesteps)
Turn on hold after increment.
void Resume(void)
Resumes execution from a "Hold".
double GetSimTime(void) const
Returns the cumulative simulation time in seconds.
void Hold(void)
Pauses execution by preventing time from incrementing.
The FGfdmSocket class enables JSBSim to communicate via sockets.
A node in a property tree.
double getDoubleValue() const
Get a double value for this node.
bool setDoubleValue(double value)
Set a double value for this node.
bool hasValue() const
Test whether this node contains a primitive leaf value.
Main namespace for the JSBSim Flight Dynamics Model.