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