}
string config = tokens[ configToken ];
- string file = config+".xml";
+ file_name = config+".xml";
+ direction = tokens[2];
- SGPath path( globals->get_fg_root() );
- path.append("Protocol");
- path.append(file.c_str());
- SG_LOG(SG_GENERAL, SG_INFO, "Reading communication protocol from "
- << path.str());
-
- SGPropertyNode root;
- try {
- readProperties(path.str(), &root);
- } catch (const sg_exception &) {
- SG_LOG(SG_GENERAL, SG_ALERT,
- "Unable to load the protocol configuration file");
- return;
- }
-
- if (tokens[2] == "out") {
- SGPropertyNode *output = root.getNode("generic/output");
- if (output) {
- read_config(output, _out_message);
- }
- } else if (tokens[2] == "in") {
- SGPropertyNode *input = root.getNode("generic/input");
- if (input) {
- read_config(input, _in_message);
- }
- } else {
+ if (direction != "in" && direction != "out") {
SG_LOG(SG_GENERAL, SG_ALERT, "Unsuported protocol direction: "
- << tokens[2]);
+ << direction);
}
+
+ reinit();
}
FGGeneric::~FGGeneric() {
}
+union u32 {
+ uint32_t intVal;
+ float floatVal;
+};
+
+union u64 {
+ uint64_t longVal;
+ double doubleVal;
+};
// generate the message
bool FGGeneric::gen_message_binary() {
if (binary_byte_order == BYTE_ORDER_MATCHES_NETWORK_ORDER) {
*((int32_t*)&buf[length]) = (int32_t)fixed;
} else {
- *((uint32_t*)&buf[length]) = sg_bswap_32((uint32_t)val);
+ *((uint32_t*)&buf[length]) = sg_bswap_32((uint32_t)fixed);
}
length += sizeof(int32_t);
break;
if (binary_byte_order == BYTE_ORDER_MATCHES_NETWORK_ORDER) {
*((float*)&buf[length]) = val;
} else {
- *((float*)&buf[length]) = sg_bswap_32(*(uint32_t*)&val);
+ u32 tmpun32;
+ tmpun32.floatVal = static_cast<float>(val);
+ *((uint32_t*)&buf[length]) = sg_bswap_32(tmpun32.intVal);
}
- length += sizeof(int32_t);
+ length += sizeof(uint32_t);
break;
case FG_DOUBLE:
if (binary_byte_order == BYTE_ORDER_MATCHES_NETWORK_ORDER) {
*((double*)&buf[length]) = val;
} else {
- *((double*)&buf[length]) = sg_bswap_64(*(uint64_t*)&val);
+ u64 tmpun64;
+ tmpun64.doubleVal = val;
+ *((uint64_t*)&buf[length]) = sg_bswap_64(tmpun64.longVal);
}
length += sizeof(int64_t);
break;
break;
case FOOTER_MAGIC:
+ case FOOTER_NONE:
break;
}
bool FGGeneric::parse_message_binary() {
char *p2, *p1 = buf;
- int64_t tmp;
+ int32_t tmp32;
double val;
int i = -1;
switch (_in_message[i].type) {
case FG_INT:
if (binary_byte_order == BYTE_ORDER_NEEDS_CONVERSION) {
- tmp = sg_bswap_32(*(int32_t *)p1);
+ tmp32 = sg_bswap_32(*(int32_t *)p1);
} else {
- tmp = *(int32_t *)p1;
+ tmp32 = *(int32_t *)p1;
}
- val = _in_message[i].offset + (double)tmp * _in_message[i].factor;
+ val = _in_message[i].offset + (double)tmp32 * _in_message[i].factor;
_in_message[i].prop->setIntValue((int)val);
p1 += sizeof(int32_t);
case FG_FIXED:
if (binary_byte_order == BYTE_ORDER_NEEDS_CONVERSION) {
- tmp = sg_bswap_32(*(int32_t *)p1);
+ tmp32 = sg_bswap_32(*(int32_t *)p1);
} else {
- tmp = *(int32_t *)p1;
+ tmp32 = *(int32_t *)p1;
}
val = _in_message[i].offset +
- ((double)tmp / 65536.0f) * _in_message[i].factor;
+ ((double)tmp32 / 65536.0f) * _in_message[i].factor;
_in_message[i].prop->setFloatValue(val);
p1 += sizeof(int32_t);
break;
case FG_FLOAT:
+ u32 tmpun32;
if (binary_byte_order == BYTE_ORDER_NEEDS_CONVERSION) {
- tmp = sg_bswap_32(*(int32_t *)p1);
+ tmpun32.intVal = sg_bswap_32(*(uint32_t *)p1);
} else {
- tmp = *(int32_t *)p1;
+ tmpun32.floatVal = *(float *)p1;
}
val = _in_message[i].offset +
- *(float *)&tmp * _in_message[i].factor;
+ tmpun32.floatVal * _in_message[i].factor;
_in_message[i].prop->setFloatValue(val);
p1 += sizeof(int32_t);
break;
case FG_DOUBLE:
+ u64 tmpun64;
if (binary_byte_order == BYTE_ORDER_NEEDS_CONVERSION) {
- tmp = sg_bswap_64(*(int64_t *)p1);
+ tmpun64.longVal = sg_bswap_64(*(uint64_t *)p1);
} else {
- tmp = *(int64_t *)p1;
+ tmpun64.doubleVal = *(double *)p1;
}
val = _in_message[i].offset +
- *(double *)&tmp * _in_message[i].factor;
+ tmpun64.doubleVal * _in_message[i].factor;
_in_message[i].prop->setDoubleValue(val);
p1 += sizeof(int64_t);
break;
case FG_FIXED:
- case FG_DOUBLE:
+ case FG_FLOAT:
val = _in_message[i].offset + strtod(p1, 0) * _in_message[i].factor;
_in_message[i].prop->setFloatValue((float)val);
break;
+ case FG_DOUBLE:
+ val = _in_message[i].offset + strtod(p1, 0) * _in_message[i].factor;
+ _in_message[i].prop->setDoubleValue(val);
+ break;
+
default: // SG_STRING
_in_message[i].prop->setStringValue(p1);
}
length = io->read( buf, binary_record_length );
if ( length == binary_record_length ) {
parse_message();
+ } else if ( length > 0 ) {
+ SG_LOG( SG_IO, SG_ALERT,
+ "Generic protocol: Received binary "
+ "record of unexpected size, expected: "
+ << binary_record_length << " but received: "
+ << length);
}
}
} while ( length == binary_record_length );
}
+void
+FGGeneric::reinit()
+{
+ SGPath path( globals->get_fg_root() );
+ path.append("Protocol");
+ path.append(file_name.c_str());
+
+ SG_LOG(SG_GENERAL, SG_INFO, "Reading communication protocol from "
+ << path.str());
+
+ SGPropertyNode root;
+ try {
+ readProperties(path.str(), &root);
+ } catch (const sg_exception &) {
+ SG_LOG(SG_GENERAL, SG_ALERT,
+ "Unable to load the protocol configuration file");
+ return;
+ }
+
+ if (direction == "out") {
+ SGPropertyNode *output = root.getNode("generic/output");
+ if (output) {
+ _out_message.clear();
+ read_config(output, _out_message);
+ }
+ } else if (direction == "in") {
+ SGPropertyNode *input = root.getNode("generic/input");
+ if (input) {
+ _in_message.clear();
+ read_config(input, _in_message);
+ }
+ }
+}
+
+
void
FGGeneric::read_config(SGPropertyNode *root, vector<_serial_prot> &msg)
{
chunk.prop = fgGetNode(node.c_str(), true);
string type = chunks[i]->getStringValue("type");
- if (type == "bool") {
+
+ // Note: officially the type is called 'bool' but for backward
+ // compatibility 'boolean' will also be supported.
+ if (type == "bool" || type == "boolean") {
chunk.type = FG_BOOL;
record_length += 1;
} else if (type == "float") {