00001
00002
00004 #define __NQ_INTERNAL_SW__
00005
00006 #include "PlatformSW.h"
00007 #include <assert.h>
00008 #include "NQDeclarations.h"
00009 #include "NQLogging.h"
00010 #include "NQMessage.h"
00011
00012 #include <stdio.h>
00013
00015
00017
00018 CNQMessage::CNQMessage()
00019 {
00020 clear();
00021 }
00022
00023
00024 CNQMessage::~CNQMessage()
00025 {
00026
00027 clear();
00028 }
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 bool CNQMessage::isRequest() const
00041 {
00042 if (mandatoryPhysicalPacketType == NQ_PT_REQUEST) return true;
00043
00044 return false;
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 bool CNQMessage::isResponse() const
00058 {
00059 if (mandatoryPhysicalPacketType == NQ_PT_RESPONSE) return true;
00060
00061 return false;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 bool CNQMessage::isTelegram() const
00075 {
00076 if (mandatoryPhysicalPacketType == NQ_PT_TELEGRAM) return true;
00077
00078 return false;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 void CNQMessage::setType( UINT8 aPhysicalType, UINT8 aLogicalType)
00090 {
00091 mandatoryLogicalPacketType = aLogicalType;
00092 mandatoryPhysicalPacketType = aPhysicalType;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101 UINT8 CNQMessage::getLogicalType()
00102 {
00103 return mandatoryLogicalPacketType;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112 UINT8 CNQMessage::getPhysicalType()
00113 {
00114 return mandatoryPhysicalPacketType;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 bool CNQMessage::getSenderIPandPort( UINT32 &ip_peer_hostorder, UINT16 &port_peer_hostorder )
00131 {
00132 if (message_came_from_set == false) return false;
00133
00134 ip_peer_hostorder = message_came_from_ip;
00135 port_peer_hostorder = message_came_from_port;
00136
00137 return true;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 void CNQMessage::clear()
00149 {
00150 message_came_from_set = false;
00151
00152 internalPacketMagic = NQ_PACKET_MAGIC_TOP;
00153 internalPacketVersion = 0x1;
00154 internalPacketSpecialBits = NQ_PACKET_SPECIAL_BITS_DEFAULT_VALUE;
00155 internalPacketTail = NQ_PACKET_MAGIC_TAIL;
00156 mandatoryPhysicalPacketType = NQ_PT_NONE;
00157 mandatoryLogicalPacketType = NQ_LT_NONE;
00158 notifySemaphoreOnReceiveAnswer = NQ_NO_SEMAPHORE;
00159 notifySemaphoreOnReceiveAck = NQ_NO_SEMAPHORE;
00160
00161 payload_maxlength_net = NQ_MAX_PACKET_SIZE - (NQ_SIZE_MESSAGE_FILL_STUFF+NQ_SIZE_PACKET_FILL_STUFF);
00162
00163 payload_curlength_net = 0;
00164 payload_num_elements = 0;
00165 payload_buffer_left = (NQ_MAX_NUM_ENTRIES*NQ_MIN_SIZE_DATA)+NQ_SIZE_ADD_LINKEDLIST;
00166
00167 payload_first_offset = -1;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 INT32 CNQMessage::check_int() const
00189 {
00190 if (internalPacketMagic != NQ_PACKET_MAGIC_TOP) return -1;
00191 if (internalPacketTail != NQ_PACKET_MAGIC_TAIL) return -2;
00192 if ((internalPacketVersion&NQ_PACKET_VERSIONS_SUPPORTED) == 0) return -3;
00193
00194
00195 if ((internalPacketSpecialBits&NQ_PACKET_SPECIAL_BITS_VALID_MASK) != 0) return -4;
00196
00197 if ((mandatoryPhysicalPacketType != NQ_PT_REQUEST) &&
00198 (mandatoryPhysicalPacketType != NQ_PT_RESPONSE) &&
00199 (mandatoryPhysicalPacketType != NQ_PT_TELEGRAM)) return -5;
00200
00201 if ((mandatoryPhysicalPacketType == NQ_PT_REQUEST) || (mandatoryPhysicalPacketType == NQ_PT_RESPONSE))
00202 {
00203 if ((mandatoryLogicalPacketType != NQ_LT_GET) &&
00204 (mandatoryLogicalPacketType != NQ_LT_PUT) &&
00205 (mandatoryLogicalPacketType != NQ_LT_CALL)) return -6;
00206 }
00207
00208 if (mandatoryPhysicalPacketType == NQ_PT_TELEGRAM)
00209 {
00210 if ((mandatoryLogicalPacketType != NQ_LT_TRAP) &&
00211 (mandatoryLogicalPacketType != NQ_LT_UPDATE)) return -7;
00212 }
00213
00214 if (payload_curlength_net > payload_maxlength_net) return -8;
00215
00216 return 0;
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226 bool CNQMessage::check_bool() const
00227 {
00228 if (check_int() == 0) return true;
00229 else
00230 return false;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 bool CNQMessage::isAckPacket() const
00244 {
00245 if ((internalPacketSpecialBits&NQ_PACKET_BIT_IS_ACKPACKET) == 0) return false;
00246
00247 return true;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 bool CNQMessage::wantAckPacket() const
00261 {
00262 if ((internalPacketSpecialBits&NQ_PACKET_BIT_WANT_ACK) == 0) return false;
00263
00264 return true;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 bool CNQMessage::matchAckPacket(const CNQMessage &ack_packet)
00287 {
00288 bool is_ack = true;
00289
00290 if ((internalPacketSpecialBits&NQ_PACKET_BIT_WANT_ACK) == 0) { is_ack = false; goto end; }
00291 if ((ack_packet.internalPacketSpecialBits&NQ_PACKET_BIT_IS_ACKPACKET) == 0) { is_ack = false; goto end; }
00292
00293 if (ack_packet.internalPacketMagic != internalPacketMagic) { is_ack = false; goto end; }
00294 if (ack_packet.internalPacketVersion != internalPacketVersion) { is_ack = false; goto end; }
00295 if (ack_packet.optAuthorisationID != optAuthorisationID) { is_ack = false; goto end; }
00296
00297 if (ack_packet.internalRequestID != internalRequestID) { is_ack = false; goto end; }
00298 if (ack_packet.optSubsystemDeviceID != optSubsystemDeviceID) { is_ack = false; goto end; }
00299 if (ack_packet.mandatoryPhysicalPacketType != mandatoryPhysicalPacketType) { is_ack = false; goto end; }
00300 if (ack_packet.optPacketTypeParam != optPacketTypeParam) { is_ack = false; goto end; }
00301 if (ack_packet.mandatoryLogicalPacketType != mandatoryLogicalPacketType) { is_ack = false; goto end; }
00302 if (ack_packet.optPacketTypeParam != optPacketTypeParam) { is_ack = false; goto end; }
00303 if (ack_packet.internalPacketTail != internalPacketTail) { is_ack = false; goto end; }
00304
00305 end:
00306 return is_ack;
00307
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 void CNQMessage::constructAckPacket(const CNQMessage &template_packet)
00322 {
00323 clear();
00324
00325 internalPacketSpecialBits = 0;
00326 internalPacketSpecialBits |= NQ_PACKET_BIT_IS_ACKPACKET;
00327
00328 internalPacketMagic = template_packet.internalPacketMagic;
00329 internalPacketVersion = template_packet.internalPacketVersion;
00330 optAuthorisationID = template_packet.optAuthorisationID;
00331
00332 internalRequestID = template_packet.internalRequestID;
00333 optSubsystemDeviceID = template_packet.optSubsystemDeviceID;
00334 mandatoryPhysicalPacketType = template_packet.mandatoryPhysicalPacketType;
00335 mandatoryLogicalPacketType = template_packet.mandatoryLogicalPacketType;
00336 optPacketTypeParam = template_packet.optPacketTypeParam;
00337 internalPacketTail = template_packet.internalPacketTail;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 bool CNQMessage::ExportMessageToPacketBuffer(UINT8 *buffer, INT32 &buffer_length)
00360 {
00361 const UINT8 *buffer8orig = (UINT8 *) buffer;
00362 UINT8 *buffer8 = (UINT8 *) buffer;
00363
00364 if (buffer == NULL) return false;
00365
00366 internalPacketSize = NQ_SIZE_MESSAGE_FILL_STUFF+NQ_SIZE_PACKET_FILL_STUFF+payload_curlength_net;
00367
00368 if (buffer_length < internalPacketSize ) return false;
00369
00370 platform_put_uint16_at( buffer8, internalPacketMagic);
00371 platform_put_uint16_at( buffer8+2, internalPacketSize);
00372 platform_put_uint16_at( buffer8+4, internalPacketVersion);
00373 platform_put_uint16_at( buffer8+6, internalPacketSpecialBits);
00374
00375 platform_put_uint32_at( buffer8+8, optAuthorisationID);
00376
00377 platform_put_uint16_at( buffer8+12, internalPacketIndex);
00378 platform_put_uint16_at( buffer8+14, internalRequestID);
00379 platform_put_uint16_at( buffer8+16, optSubsystemDeviceID);
00380 platform_put_uint16_at( buffer8+18, payload_num_elements);
00381
00382 platform_put_uint8_at( buffer8+20, mandatoryPhysicalPacketType);
00383 platform_put_uint8_at( buffer8+21, mandatoryLogicalPacketType);
00384
00385 platform_put_uint16_at( buffer8+22, optPacketTypeParam);
00386
00387 buffer8 += 24;
00388
00389 if (payload_num_elements > 0)
00390 {
00391 UINT8 *pdp;
00392 UINT32 payload_next = payload_first_offset;
00393
00394 for (int i=0;i<payload_num_elements;i++)
00395 {
00396 pdp = &payload_buffer[payload_next];
00397
00398 if (i>0)
00399 assert(payload_next>0);
00400
00401 UINT16 gross_size;
00402
00403
00404 payload_next = platform_get_uint32_at(pdp);
00405 gross_size = platform_get_uint16_at(pdp+4);
00406
00407 memcpy(buffer8, pdp+4, gross_size);
00408 buffer8+=gross_size;
00409
00410 pdp = &payload_buffer[payload_next];
00411 }
00412 }
00413
00414 platform_put_uint16_at(buffer8, internalPacketTail);
00415
00416 buffer_length = (UINT32) (buffer8+2 - buffer8orig);
00417
00418
00419 if (buffer_length != internalPacketSize)
00420 {
00421 NQ_DBG(("Buffer length(%d) != packet_size(%d)\n", buffer_length, internalPacketSize));
00422 NQ_DBG(("payload_curlength_net(%d) payload_num_elements(%d)\n", payload_curlength_net, payload_num_elements));
00423 }
00424
00425 assert( buffer_length == internalPacketSize);
00426
00427 return true;
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 bool CNQMessage::ImportMessageFromPacketBuffer(const UINT8 *buffer, INT32 buffer_length, UINT32 ip_hostorder, UINT16 port_hostorder)
00449 {
00450 INT32 pdl=0;
00451 UINT8 *buffer8 = (UINT8 *) buffer;
00452 UINT8 *l_packet_data;
00453
00454
00455 pdl = buffer_length - (NQ_SIZE_MESSAGE_FILL_STUFF+NQ_SIZE_PACKET_FILL_STUFF);
00456
00457 if (pdl < 0 || pdl > payload_maxlength_net)
00458 {
00459 return false;
00460 }
00461
00462 internalPacketMagic = platform_get_uint16_at(buffer8);
00463 internalPacketSize = platform_get_uint16_at(buffer8+2);
00464
00465 if (internalPacketSize != buffer_length) return false;
00466
00467 internalPacketVersion = platform_get_uint16_at(buffer8+4);
00468 internalPacketSpecialBits = platform_get_uint16_at(buffer8+6);
00469
00470 optAuthorisationID = platform_get_uint32_at(buffer8+8);
00471
00472 internalPacketIndex = platform_get_uint16_at(buffer8+12);
00473 internalRequestID = platform_get_uint16_at(buffer8+14);
00474 optSubsystemDeviceID = platform_get_uint16_at(buffer8+16);
00475 payload_num_elements = platform_get_uint16_at(buffer8+18);
00476
00477 mandatoryPhysicalPacketType = platform_get_uint8_at(buffer8+20);
00478 mandatoryLogicalPacketType = platform_get_uint8_at(buffer8+21);
00479
00480 optPacketTypeParam = platform_get_uint16_at(buffer8+22);
00481
00482 buffer8 += 24;
00483 l_packet_data = buffer8;
00484 buffer8 += pdl;
00485 payload_curlength_net = pdl;
00486
00487 internalPacketTail = platform_get_uint16_at(buffer8);
00488
00489
00490 if (check_bool() == false ) return false;
00491
00492 payload_first_offset = -1;
00493 UINT8 *pdp = &payload_buffer[0];
00494 const UINT8 *pdp_end = (&payload_buffer[(NQ_MAX_NUM_ENTRIES*NQ_MIN_SIZE_DATA)+NQ_SIZE_ADD_LINKEDLIST-1]);
00495
00496 UINT8 *source_buffer = l_packet_data;
00497
00498 UINT8 *source_buffer_end = l_packet_data+buffer_length-(NQ_SIZE_MESSAGE_FILL_STUFF+NQ_SIZE_PACKET_FILL_STUFF);
00499
00500
00501
00502
00503
00504 if (payload_num_elements > 0)
00505 {
00506 for (int i=0;i<payload_num_elements;i++)
00507 {
00508 UINT32 payload_next;
00509 UINT16 blocksize;
00510 UINT16 vartype;
00511 UINT16 varid;
00512 UINT16 net_size;
00513
00514 if (payload_first_offset == -1)
00515 {
00516 payload_first_offset = 0;
00517 }
00518
00519 blocksize = platform_get_uint16_at(source_buffer);
00520
00521
00522
00523 assert( blocksize <= pdl );
00524 if (blocksize > pdl) return false;
00525
00526
00527 varid = platform_get_uint16_at(source_buffer+2);
00528
00529
00530 vartype = platform_get_uint16_at(source_buffer+4);
00531 assert( (vartype >= NQ_MIN_VARTYPE) && (vartype <= NQ_MAX_VARTYPE));
00532 if ((vartype < NQ_MIN_VARTYPE) || (vartype > NQ_MAX_VARTYPE)) return false;
00533
00534 net_size = sizeof_per_element(vartype)*(platform_get_uint16_at(source_buffer+6));
00535
00536 payload_next = pdp + blocksize + 4 - payload_buffer;
00537
00538 if (i == (payload_num_elements-1)) payload_next = 0;
00539
00540 assert( (pdp+blocksize+4) <= pdp_end );
00541 if ((pdp+blocksize+4) > pdp_end) return false;
00542
00543 platform_put_uint32_at(pdp, payload_next);
00544 platform_put_uint16_at(pdp+4, blocksize);
00545
00546
00547
00548 memcpy(pdp+6, source_buffer+2, net_size+6);
00549
00550 source_buffer+=blocksize;
00551
00552 assert( source_buffer <= source_buffer_end );
00553 if (source_buffer > source_buffer_end) return false;
00554
00555 pdp = &payload_buffer[payload_next];
00556
00557
00558 assert( payload_next <= ((NQ_MAX_NUM_ENTRIES*NQ_MIN_SIZE_DATA)+NQ_SIZE_ADD_LINKEDLIST) );
00559 if (payload_next > ((NQ_MAX_NUM_ENTRIES*NQ_MIN_SIZE_DATA)+NQ_SIZE_ADD_LINKEDLIST)) return false;
00560 }
00561 }
00562
00563 notifySemaphoreOnReceiveAnswer = NQ_NO_SEMAPHORE;
00564 notifySemaphoreOnReceiveAck = NQ_NO_SEMAPHORE;
00565
00566 message_came_from_set = true;
00567 message_came_from_ip = ip_hostorder;
00568 message_came_from_port = port_hostorder;
00569
00570 return true;
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 bool CNQMessage::check_buffer_against_vartype( UINT16 vartype, const VOIDP buffer, UINT32 buflength)
00591 {
00592
00593
00594 if (buffer == NULL) return false;
00595 if (buflength == 0) return false;
00596
00597 switch( vartype )
00598 {
00599 case NQ_VARTYPE_BINARY:
00600 case NQ_VARTYPE_FLOAT:
00601 case NQ_VARTYPE_DOUBLE:
00602 case NQ_VARTYPE_INT8:
00603 case NQ_VARTYPE_UINT8:
00604 case NQ_VARTYPE_INT16:
00605 case NQ_VARTYPE_UINT16:
00606 case NQ_VARTYPE_INT32:
00607 case NQ_VARTYPE_UINT32:
00608 return true;
00609 break;
00610
00611 case NQ_VARTYPE_TEXT:
00612 {
00613 UINT8 *bui8 = (UINT8 *) buffer;
00614 UINT16 local_length = 0;
00615
00616
00617 while (local_length < buflength)
00618 {
00619 if (bui8[local_length]==0) break;
00620 local_length++;
00621 }
00622
00623
00624
00625 if (local_length > 0 && local_length<buflength) return true;
00626 }
00627 break;
00628
00629
00630 default:
00631 break;
00632 }
00633
00634 return false;
00635 }
00636
00637
00638
00639
00640
00641 bool CNQMessage::read_BINARY( UINT16 varid, UINT8 *target_buffer, UINT32 &target_buffer_size_bytes)
00642 {
00643 return read( varid, NQ_VARTYPE_BINARY, target_buffer, target_buffer_size_bytes);
00644 }
00645
00646 bool CNQMessage::read_FLOAT( UINT16 varid, FLOAT &target_buffer)
00647 {
00648 FLOAT fltbuf;
00649 UINT32 num_elements = 1;
00650
00651 if (read( varid, NQ_VARTYPE_FLOAT, &fltbuf, num_elements) == true)
00652 {
00653 target_buffer=fltbuf;
00654 return true;
00655 }
00656
00657 return false;
00658 }
00659
00660 bool CNQMessage::read_DOUBLE( UINT16 varid, DOUBLE &target_buffer)
00661 {
00662 DOUBLE dblbuf;
00663 UINT32 num_elements = 1;
00664
00665 if (read( varid, NQ_VARTYPE_DOUBLE, &dblbuf, num_elements) == true)
00666 {
00667 target_buffer=dblbuf;
00668 return true;
00669 }
00670
00671 return false;
00672 }
00673
00674 bool CNQMessage::read_INT8( UINT16 varid, INT8 &target_buffer)
00675 {
00676 INT32 i8buf;
00677 UINT32 num_elements = 1;
00678
00679 if (read( varid, NQ_VARTYPE_INT8, &i8buf, num_elements) == true)
00680 {
00681 target_buffer= i8buf;
00682 return true;
00683 }
00684
00685 return false;
00686 }
00687
00688 bool CNQMessage::read_UINT8( UINT16 varid, UINT8 &target_buffer)
00689 {
00690 UINT8 ui8buf;
00691 UINT32 num_elements = 1;
00692
00693 if (read( varid, NQ_VARTYPE_UINT8, &ui8buf, num_elements) == true)
00694 {
00695 target_buffer= ui8buf;
00696 return true;
00697 }
00698
00699 return false;
00700 }
00701
00702 bool CNQMessage::read_INT16( UINT16 varid, INT16 &target_buffer)
00703 {
00704 INT16 i16buf;
00705 UINT32 num_elements = 1;
00706
00707 if (read( varid, NQ_VARTYPE_INT16, &i16buf, num_elements) == true)
00708 {
00709 target_buffer=i16buf;
00710 return true;
00711 }
00712
00713 return false;
00714 }
00715
00716 bool CNQMessage::read_UINT16( UINT16 varid, UINT16 &target_buffer)
00717 {
00718 UINT16 ui16buf;
00719 UINT32 num_elements = 1;
00720
00721 if (read( varid, NQ_VARTYPE_UINT16, &ui16buf, num_elements) == true)
00722 {
00723 target_buffer=ui16buf;
00724 return true;
00725 }
00726
00727 return false;
00728 }
00729
00730 bool CNQMessage::read_INT32( UINT16 varid, INT32 &target_buffer)
00731 {
00732 INT32 i32buf;
00733 UINT32 num_elements = 1;
00734
00735 if (read( varid, NQ_VARTYPE_INT32, &i32buf, num_elements) == true)
00736 {
00737 target_buffer=i32buf;
00738 return true;
00739 }
00740
00741 return false;
00742 }
00743
00744 bool CNQMessage::read_UINT32( UINT16 varid, UINT32 &target_buffer)
00745 {
00746 UINT32 ui32buf;
00747 UINT32 num_elements = 1;
00748
00749 if (read( varid, NQ_VARTYPE_UINT32, &ui32buf, num_elements) == true)
00750 {
00751 target_buffer=ui32buf;
00752 return true;
00753 }
00754
00755 return false;
00756 }
00757
00758 bool CNQMessage::read_TEXT( UINT16 varid, UINT8 *target_buffer, UINT32 &target_buffer_size_bytes)
00759 {
00760 return read( varid, NQ_VARTYPE_TEXT, target_buffer, target_buffer_size_bytes );
00761 }
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 bool CNQMessage::read( UINT16 varid, UINT16 vartype, VOIDP target_buffer, UINT32 &target_buffer_num_elements)
00797 {
00798
00799 if (payload_first_offset == -1) return false;
00800
00801
00802 if (target_buffer == NULL) return false;
00803
00804 UINT8 *pdp = &payload_buffer[payload_first_offset];
00805
00806 UINT32 payload_next;
00807 UINT16 cur_varid;
00808 UINT16 cur_vartype;
00809 UINT16 cur_num_elements;
00810
00811 do
00812 {
00813 payload_next = platform_get_uint32_at(pdp);
00814 cur_varid = platform_get_uint16_at(pdp+6);
00815 cur_vartype = platform_get_uint16_at(pdp+8);
00816 cur_num_elements = platform_get_uint16_at(pdp+10);
00817
00818 if (varid == cur_varid)
00819 {
00820
00821 if (cur_vartype != vartype) return false;
00822
00823 if (target_buffer_num_elements >= cur_num_elements)
00824 {
00825 copy_data_depending_on_vartype( (UINT32 *) target_buffer, (const UINT32 *) (pdp+12), cur_num_elements, vartype);
00826 target_buffer_num_elements = cur_num_elements;
00827 return true;
00828 }
00829 else
00830 {
00831 target_buffer_num_elements = cur_num_elements;
00832 return false;
00833 }
00834 }
00835
00836 pdp = &payload_buffer[payload_next];
00837
00838 }
00839 while (payload_next != 0);
00840
00841 return false;
00842 }
00843
00844
00845
00846
00847
00848 bool CNQMessage::write_BINARY( UINT16 varid, const UINT8 *source_buffer, UINT32 source_buffer_size_bytes)
00849 {
00850 return write( varid, NQ_VARTYPE_BINARY, (const VOIDP) source_buffer, source_buffer_size_bytes );
00851 }
00852
00853 bool CNQMessage::write_FLOAT( UINT16 varid, FLOAT source_buffer)
00854 {
00855 return write( varid, NQ_VARTYPE_FLOAT, &source_buffer, 1 );
00856 }
00857
00858 bool CNQMessage::write_DOUBLE( UINT16 varid, DOUBLE source_buffer)
00859 {
00860 return write( varid, NQ_VARTYPE_DOUBLE, &source_buffer, 1 );
00861 }
00862
00863 bool CNQMessage::write_INT8( UINT16 varid, INT8 source_buffer)
00864 {
00865 return write( varid, NQ_VARTYPE_INT8, &source_buffer, 1 );
00866 }
00867
00868 bool CNQMessage::write_UINT8( UINT16 varid, UINT8 source_buffer)
00869 {
00870 return write( varid, NQ_VARTYPE_UINT8, &source_buffer, 1 );
00871 }
00872
00873 bool CNQMessage::write_INT16( UINT16 varid, INT16 source_buffer)
00874 {
00875 return write( varid, NQ_VARTYPE_INT16, &source_buffer, 1 );
00876 }
00877
00878 bool CNQMessage::write_UINT16( UINT16 varid, UINT16 source_buffer)
00879 {
00880 return write( varid, NQ_VARTYPE_UINT16, &source_buffer, 1 );
00881 }
00882
00883 bool CNQMessage::write_INT32( UINT16 varid, INT32 source_buffer)
00884 {
00885 return write( varid, NQ_VARTYPE_INT32, &source_buffer, 1 );
00886 }
00887
00888 bool CNQMessage::write_UINT32( UINT16 varid, UINT32 source_buffer)
00889 {
00890 return write( varid, NQ_VARTYPE_UINT32, &source_buffer, 1 );
00891 }
00892
00893 bool CNQMessage::write_TEXT( UINT16 varid, const UINT8 *source_buffer, UINT32 source_buffer_size_bytes)
00894 {
00895 return write( varid, NQ_VARTYPE_TEXT, (const VOIDP) source_buffer, source_buffer_size_bytes );
00896 }
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926 bool CNQMessage::write( UINT16 varid, UINT16 vartype, const VOIDP buffer, const UINT32 elements_in_buffer)
00927 {
00928 UINT32 buffer_size = sizeof_per_element(vartype)*elements_in_buffer;
00929
00930 if (check_buffer_against_vartype(vartype, buffer, buffer_size) == false) return false;
00931
00932
00933 UINT32 new_gross_size = buffer_size;
00934 if (buffer_size&3) new_gross_size += 4-(buffer_size&3);
00935 new_gross_size += NQ_MIN_SIZE_DATA_NET-4;
00936
00937 INT32 payload_first_offset_local = payload_first_offset;
00938 UINT8 *pdp = &payload_buffer[payload_first_offset_local];
00939 UINT8 *prev_pdp = NULL;
00940
00941 if (payload_num_elements > 0)
00942 {
00943 bool new_first;
00944 UINT32 payload_next;
00945 UINT16 cur_varid;
00946 UINT16 cur_net_size;
00947 UINT16 cur_gross_size;
00948
00949 do
00950 {
00951 payload_next = platform_get_uint32_at(pdp);
00952 cur_gross_size = platform_get_uint16_at(pdp+4);
00953 cur_varid = platform_get_uint16_at(pdp+6);
00954 cur_net_size = platform_get_uint16_at(pdp+10);
00955 new_first=false;
00956
00957 if (varid == cur_varid)
00958 {
00959 if (cur_net_size == elements_in_buffer)
00960 {
00961 platform_put_uint16_at(pdp+8, vartype);
00962 copy_data_depending_on_vartype((UINT32 *) (pdp+12), (const UINT32 *) buffer, elements_in_buffer, vartype);
00963
00964 return true;
00965 }
00966 else
00967 {
00968
00969 if (prev_pdp == NULL)
00970 {
00971
00972
00973 if (payload_buffer_left < (new_gross_size+4)) return false;
00974
00975
00976 INT32 size = payload_curlength_net;
00977
00978 size -= (cur_gross_size);
00979 size += (new_gross_size);
00980
00981 if (size > payload_maxlength_net) return false;
00982
00983
00984 payload_first_offset_local = payload_next;
00985 payload_curlength_net -= (cur_gross_size);
00986 payload_num_elements--;
00987
00988
00989
00990 new_first=true;
00991 }
00992 }
00993 }
00994
00995 if (new_first)
00996 {
00997 prev_pdp = NULL;
00998 pdp = &payload_buffer[payload_first_offset_local];
00999 }
01000 else
01001 {
01002 prev_pdp = pdp;
01003 if (payload_next != 0) pdp = &payload_buffer[payload_next];
01004 }
01005
01006 }
01007 while (payload_next != 0);
01008
01009
01010
01011
01012
01013 if (payload_buffer_left < (new_gross_size+4))
01014 {
01015 assert(payload_buffer_left >= (new_gross_size+4));
01016 return false;
01017 }
01018 if ((payload_curlength_net+new_gross_size) > payload_maxlength_net)
01019 {
01020 assert((payload_curlength_net+new_gross_size) <= payload_maxlength_net);
01021 return false;
01022 }
01023
01024 payload_next = pdp+(cur_gross_size+4)-payload_buffer;
01025 platform_put_uint32_at(pdp, payload_next);
01026 pdp = &payload_buffer[payload_next];
01027
01028 platform_put_uint32_at(pdp, 0);
01029 platform_put_uint16_at(pdp+4, new_gross_size );
01030 platform_put_uint16_at(pdp+6, varid);
01031 platform_put_uint16_at(pdp+8, vartype);
01032 platform_put_uint16_at(pdp+10, elements_in_buffer);
01033
01034 copy_data_depending_on_vartype((UINT32 *) (pdp+12), (const UINT32 *) buffer, elements_in_buffer, vartype);
01035
01036 payload_buffer_left -= (new_gross_size+4);
01037 payload_curlength_net += new_gross_size;
01038 payload_num_elements++;
01039
01040 payload_first_offset = payload_first_offset_local;
01041 }
01042 else
01043 {
01044
01045 payload_first_offset_local = 0;
01046 pdp = &payload_buffer[payload_first_offset_local];
01047
01048 if (payload_buffer_left < (new_gross_size+4)) return false;
01049 if ((payload_curlength_net+new_gross_size) > payload_maxlength_net) return false;
01050
01051 platform_put_uint32_at(pdp, 0);
01052 platform_put_uint16_at(pdp+4, new_gross_size );
01053 platform_put_uint16_at(pdp+6, varid);
01054 platform_put_uint16_at(pdp+8, vartype);
01055 platform_put_uint16_at(pdp+10, elements_in_buffer);
01056
01057 copy_data_depending_on_vartype((UINT32 *) (pdp+12), (const UINT32 *) buffer, elements_in_buffer, vartype);
01058
01059 payload_buffer_left -= (new_gross_size+4);
01060 payload_curlength_net += new_gross_size;
01061 payload_num_elements++;
01062
01063 payload_first_offset = payload_first_offset_local;
01064
01065 }
01066
01067 return true;
01068 }
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 void CNQMessage::copy_data_depending_on_vartype( UINT32 *tgtbufpos, const UINT32* srcbufpos, UINT32 num_elements, UINT16 vartype)
01089 {
01090
01091 assert(tgtbufpos != NULL);
01092 assert(srcbufpos != NULL);
01093 assert(num_elements != 0);
01094
01095 switch( vartype )
01096 {
01097 case NQ_VARTYPE_TEXT:
01098 case NQ_VARTYPE_BINARY:
01099 case NQ_VARTYPE_INT8:
01100 case NQ_VARTYPE_UINT8:
01101 memcpy(tgtbufpos, srcbufpos, num_elements*sizeof_per_element(vartype));
01102 break;
01103
01104 case NQ_VARTYPE_FLOAT:
01105 {
01106 FLOAT* srcbufpos_float = (FLOAT *) srcbufpos;
01107 FLOAT* tgtbufpos_float = (FLOAT *) tgtbufpos;
01108
01109 while( num_elements > 0)
01110 {
01111 platform_put_float_at((UINT8 *) (tgtbufpos_float++), *srcbufpos_float++ );
01112 num_elements--;
01113 }
01114 }
01115 break;
01116
01117
01118 case NQ_VARTYPE_DOUBLE:
01119 {
01120 DOUBLE* srcbufpos_double = (DOUBLE *) srcbufpos;
01121 DOUBLE* tgtbufpos_double = (DOUBLE *) tgtbufpos;
01122
01123 while( num_elements > 0)
01124 {
01125 platform_put_double_at((UINT8 *) (tgtbufpos_double++), *srcbufpos_double++ );
01126 num_elements--;
01127 }
01128 }
01129 break;
01130
01131
01132 case NQ_VARTYPE_INT16:
01133 {
01134 INT16* srcbufpos_int16 = (INT16 *) srcbufpos;
01135 INT16* tgtbufpos_int16 = (INT16 *) tgtbufpos;
01136
01137 while( num_elements > 0)
01138 {
01139 platform_put_int16_at((UINT8 *) (tgtbufpos_int16++), *srcbufpos_int16++ );
01140 num_elements--;
01141 }
01142 }
01143 break;
01144
01145 case NQ_VARTYPE_UINT16:
01146 {
01147 UINT16* srcbufpos_uint16 = (UINT16 *) srcbufpos;
01148 UINT16* tgtbufpos_uint16 = (UINT16 *) tgtbufpos;
01149
01150 while( num_elements > 0)
01151 {
01152 platform_put_uint16_at((UINT8 *)(tgtbufpos_uint16++), *srcbufpos_uint16++ );
01153 num_elements--;
01154 }
01155 }
01156 break;
01157
01158 case NQ_VARTYPE_INT32:
01159 {
01160 INT32* srcbufpos_int32 = (INT32 *) srcbufpos;
01161 INT32* tgtbufpos_int32 = (INT32 *) tgtbufpos;
01162
01163 while( num_elements > 0)
01164 {
01165 platform_put_int32_at((UINT8 *) (tgtbufpos_int32++), *srcbufpos_int32++ );
01166 num_elements--;
01167 }
01168 }
01169 break;
01170
01171 case NQ_VARTYPE_UINT32:
01172 {
01173 UINT32* srcbufpos_uint32 = (UINT32 *) srcbufpos;
01174 UINT32* tgtbufpos_uint32 = (UINT32 *) tgtbufpos;
01175
01176 while( num_elements > 0)
01177 {
01178 platform_put_uint32_at((UINT8 *) (tgtbufpos_uint32++), *srcbufpos_uint32++ );
01179 num_elements--;
01180 }
01181 }
01182 break;
01183
01184 default: assert(1==2);
01185 break;
01186 }
01187
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 UINT32 CNQMessage::sizeof_per_element( const UINT16 vartype )
01209 {
01210 switch( vartype )
01211 {
01212
01213 case NQ_VARTYPE_TEXT:
01214 case NQ_VARTYPE_BINARY:
01215 case NQ_VARTYPE_INT8:
01216 case NQ_VARTYPE_UINT8:
01217 return 1;
01218 break;
01219
01220 case NQ_VARTYPE_INT16:
01221 case NQ_VARTYPE_UINT16:
01222 return 2;
01223 break;
01224
01225 case NQ_VARTYPE_FLOAT:
01226 case NQ_VARTYPE_INT32:
01227 case NQ_VARTYPE_UINT32:
01228 return 4;
01229 break;
01230
01231 case NQ_VARTYPE_DOUBLE:
01232 return 8;
01233 break;
01234
01235 default:
01236 break;
01237 }
01238
01239 assert(1==2);
01240 return 1;
01241 }
01242