X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNetwork%2Fgeneric.cxx;h=423d2be189b28ffec2de641415dc99ab3b1bdcfb;hb=ae50c054a9007b98f1a8dafe6d589d0b4cab8873;hp=4b94eacc1573215ff1fd3ec2e9d0a2cf68858b6e;hpb=a9c47a7b789fee91a8fb96cb7f3afe6e0b8a32f2;p=flightgear.git diff --git a/src/Network/generic.cxx b/src/Network/generic.cxx index 4b94eacc1..423d2be18 100644 --- a/src/Network/generic.cxx +++ b/src/Network/generic.cxx @@ -45,7 +45,7 @@ FGGeneric::FGGeneric(vector tokens) : exitOnError(false) { - int configToken; + size_t configToken; if (tokens[1] == "socket") { configToken = 7; } else if (tokens[1] == "file") { @@ -61,47 +61,33 @@ FGGeneric::FGGeneric(vector tokens) : exitOnError(false) } 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 &e) { - 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() { string generic_sentence; - char tmp[255]; length = 0; double val; @@ -135,7 +121,7 @@ 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; @@ -147,9 +133,11 @@ bool FGGeneric::gen_message_binary() { 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(val); + *((uint32_t*)&buf[length]) = sg_bswap_32(tmpun32.intVal); } - length += sizeof(int32_t); + length += sizeof(uint32_t); break; case FG_DOUBLE: @@ -159,7 +147,9 @@ bool FGGeneric::gen_message_binary() { 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; @@ -196,6 +186,7 @@ bool FGGeneric::gen_message_binary() { break; case FOOTER_MAGIC: + case FOOTER_NONE: break; } @@ -249,8 +240,8 @@ bool FGGeneric::gen_message_ascii() { case FG_DOUBLE: val = _out_message[i].offset + - _out_message[i].prop->getFloatValue() * _out_message[i].factor; - snprintf(tmp, 255, _out_message[i].format.c_str(), (float)val); + _out_message[i].prop->getDoubleValue() * _out_message[i].factor; + snprintf(tmp, 255, _out_message[i].format.c_str(), (double)val); break; default: // SG_STRING @@ -282,7 +273,7 @@ bool FGGeneric::gen_message() { bool FGGeneric::parse_message_binary() { char *p2, *p1 = buf; - int64_t tmp; + int32_t tmp32; double val; int i = -1; @@ -292,12 +283,12 @@ bool FGGeneric::parse_message_binary() { 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); @@ -310,41 +301,43 @@ bool FGGeneric::parse_message_binary() { 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); @@ -384,11 +377,16 @@ bool FGGeneric::parse_message_ascii() { 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); } @@ -447,39 +445,54 @@ bool FGGeneric::process() { goto error_out; } } else if ( get_direction() == SG_IO_IN ) { - if (!binary_mode) { - if ( (length = io->readline( buf, FG_MAX_MSG_SIZE )) > 0 ) { - parse_message(); + if ( io->get_type() == sgFileType ) { + if (!binary_mode) { + length = io->readline( buf, FG_MAX_MSG_SIZE ); + if ( length > 0 ) { + parse_message(); + } else { + SG_LOG( SG_IO, SG_ALERT, "Error reading data." ); + return false; + } } else { - SG_LOG( SG_IO, SG_ALERT, "Error reading data." ); - return false; - } - } else { - if ( (length = io->read( buf, binary_record_length )) > 0 ) { - if (length != binary_record_length) { + length = io->read( buf, binary_record_length ); + if ( length == binary_record_length ) { + parse_message(); + } else { SG_LOG( SG_IO, SG_ALERT, "Generic protocol: Received binary " "record of unexpected size, expected: " - << binary_record_length << "received: " + << binary_record_length << " but received: " << length); - } else { - SG_LOG( SG_IO, SG_DEBUG, - "Generic protocol: received record of " << length << - " bytes."); + } + } + } else { + if (!binary_mode) { + while ((length = io->readline( buf, FG_MAX_MSG_SIZE )) > 0 ) { parse_message(); } } else { - SG_LOG( SG_IO, SG_INFO, - "Generic protocol: Error reading data." ); - return false; + while ((length = io->read( buf, binary_record_length )) + == binary_record_length ) { + parse_message(); + } + + if ( length > 0 ) { + SG_LOG( SG_IO, SG_ALERT, + "Generic protocol: Received binary " + "record of unexpected size, expected: " + << binary_record_length << " but received: " + << length); + } } } } return true; error_out: - if (exitOnError) + if (exitOnError) { fgExit(1); - else + return true; // should not get there, but please the compiler + } else return false; } @@ -505,6 +518,41 @@ bool FGGeneric::close() { } +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) { @@ -618,7 +666,10 @@ 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") { @@ -640,12 +691,14 @@ FGGeneric::read_config(SGPropertyNode *root, vector<_serial_prot> &msg) } - if (binary_record_length == -1) { - binary_record_length = record_length; - } else if (binary_record_length < record_length) { - SG_LOG(SG_IO, SG_ALERT, - "generic protocol: Requested binary record length shorter than " - " requested record representation."); - binary_record_length = record_length; + if( binary_mode ) { + if (binary_record_length == -1) { + binary_record_length = record_length; + } else if (binary_record_length < record_length) { + SG_LOG(SG_IO, SG_ALERT, + "generic protocol: Requested binary record length shorter than " + " requested record representation."); + binary_record_length = record_length; + } } }