DESERT 3.5.1
Loading...
Searching...
No Matches
packer.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
38#include "packer.h"
39
40#include <cmath>
41#include <iomanip>
42#include <iostream>
43#include <limits.h>
44
45typedef unsigned char BARR_ELTYPE;
46
47#define DEFAULT_DUMMY_CONTENT_LENGTH 256
48
53#define BARR_ELBITS (CHAR_BIT * sizeof(BARR_ELTYPE))
60#define BARR_ARRAYSIZE(N) (((N) + BARR_ELBITS - 1) / BARR_ELBITS)
67#define BARR_ELNUM(N) ((N) / BARR_ELBITS)
74#define BARR_BITNUM(N) ((N) % BARR_ELBITS)
81#define BARR_SET(barr, N) \
82 (((BARR_ELTYPE *) (barr))[BARR_ELNUM(N)] |= (BARR_ELTYPE) 1 \
83 << BARR_BITNUM(N))
90#define BARR_CLEAR(barr, N) \
91 (((BARR_ELTYPE *) (barr))[BARR_ELNUM(N)] &= \
92 ~((BARR_ELTYPE) 1 << BARR_BITNUM(N)))
99#define BARR_TEST(barr, N) \
100 (((BARR_ELTYPE *) (barr))[BARR_ELNUM(N)] & \
101 ((BARR_ELTYPE) 1 << BARR_BITNUM(N)))
102
106static class PackerClass : public TclClass
107{
108public:
110 : TclClass("UW/AL/Packer")
111 {
112 }
113
114 TclObject *
115 create(int, const char *const *)
116 {
117 return (new packer(true));
118 }
120
121packer::packer(bool init_)
122 : n_bits(0)
123 , activePackers(0)
124 , payload_length(0)
125{
126 debug_ = 0;
127 bind("debug_", &debug_);
128 printAllFields = false;
129
130 if (init_) {
131 SRC_ID_Bits = 8 * sizeof(uint8_t);
132 PKT_ID_Bits = 8 * sizeof(unsigned int);
133 FRAME_OFFSET_Bits = 8 * sizeof(uint16_t);
134 M_BIT_Bits = 1;
136
137 bind("SRC_ID_Bits", (int *) &SRC_ID_Bits);
138 bind("PKT_ID_Bits", (int *) &PKT_ID_Bits);
139 bind("FRAME_OFFSET_Bits", (int *) &FRAME_OFFSET_Bits);
140 bind("M_BIT_Bits", (int *) &M_BIT_Bits);
141 bind("DUMMY_CONTENT_Bits", (int *) &DUMMY_CONTENT_Bits);
142
143 if (debug_) {
144 std::cout << "Initialization (from constructor) of n_bits for the "
145 "UWAL packer "
146 << std::endl;
147 }
148
149 n_bits.clear();
150 n_bits.push_back(SRC_ID_Bits);
151 n_bits.push_back(PKT_ID_Bits);
152 n_bits.push_back(FRAME_OFFSET_Bits);
153 n_bits.push_back(M_BIT_Bits);
154 n_bits.push_back(DUMMY_CONTENT_Bits);
155 }
157}
158
160{
161}
162
163void
165{
166 if (debug_) {
167 std::cout << "Re-initialization of n_bits for the UWAL packer "
168 << std::endl;
169 }
170
171 n_bits.clear();
172 n_bits.push_back(SRC_ID_Bits);
173 n_bits.push_back(PKT_ID_Bits);
174 n_bits.push_back(FRAME_OFFSET_Bits);
175 n_bits.push_back(M_BIT_Bits);
176 n_bits.push_back(DUMMY_CONTENT_Bits);
177}
178
179int
180packer::command(int argc, const char *const *argv)
181{
182
183 if (argc == 2) {
184 if (strcmp(argv[1], "packerInit") == 0) {
185 init();
187 return TCL_OK;
188 }
189 if (strcmp(argv[1], "printMap") == 0) {
190 printMap();
191 return TCL_OK;
192 }
193 if (strcmp(argv[1], "printAllFields") == 0) {
194 printAllFields = true;
195 return TCL_OK;
196 }
197 }
198
199 if (argc == 3) {
200 if (strcmp(argv[1], "addPacker") == 0) {
201 activePackers.push_back((packer *) TclObject::lookup(argv[2]));
203 if (debug_) {
204 std::cout << "Packer added, current payload length: "
206 << " [Bytes]. Corresponding MAP: " << std::endl;
207 activePackers.back()->printMyHdrMap();
208 }
209 return TCL_OK;
210 }
211 }
212 return TclObject::command(argc, argv);
213}
214
215size_t
217{
218 size_t PayloadBinLength = 0;
219 for (std::vector<packer *>::iterator it = activePackers.begin();
220 it != activePackers.end();
221 ++it) {
222 PayloadBinLength += (*it)->getMyHdrBinLength();
223 }
224 return PayloadBinLength;
225}
226
227size_t
232
233std::string
235{
236 unsigned char *buf = new unsigned char[hdr_length];
237 memset(buf, '\0', hdr_length);
238
239 size_t offset = 0;
240 packMyHdr(p, buf, offset);
241 hdr_uwal *hal = HDR_UWAL(p);
242 memset(hal->binPkt(), '\0', hdr_length);
243 hal->binHdrLength() = 0;
244
246
247 memcpy(hal->binPkt(), buf, hdr_length);
248 hal->binHdrLength() = hdr_length;
249 hal->binPktLength() += hdr_length;
250
251 if (hal->binPktLength() != hdr_length &&
253 std::cout << "\033[0;0;31m"
254 << " ERROR"
255 << "\033[0m" << std::endl;
256 ;
257 cout << "in packer::packHdr -> pkt size set to: "
258 << hal->binPktLength()
259 << ", whilst header length is: " << hdr_length
260 << " and DEFAULT payload length is: " << payload_length
261 << endl;
262 exit(-1);
263 }
264
265 } else {
266 std::cout << "\033[0;0;31m"
267 << " ERROR"
268 << "\033[0m" << std::endl;
269 ;
270 cout << "in packer::packHdr -> hdr size returned by packer is "
271 << hdr_length << ", higher than MAX_BIN_PKT_ARRAY_LENGTH: "
272 << MAX_BIN_PKT_ARRAY_LENGTH << ". Hdr is not serialized." << endl;
273 }
274
275 std::string res;
276 res.assign((const char *) buf, hdr_length);
277 delete[] buf;
278
279 if (debug_) {
280 std::cout << "\033[0;47;30m"
281 << " TX"
282 << "\033[0m" << std::endl;
283 cout << "--> Bin data header generated by packer:"
284 << hexdump(hal->binPkt(), hdr_length) << endl;
285 cout << "--> Header length (unsigned char):" << hdr_length << endl;
286 }
287
288 return res;
289}
290
291std::string
293{
294 std::string res;
295 hdr_uwal *hal = HDR_UWAL(p);
296 memset(hal->binPkt() + hdr_length,
297 '\0',
299 size_t offset;
300 if (!activePackers.empty()) {
301 // unsigned char *buf = new unsigned char[payload_length];
302 // memset(buf, '\0', payload_length);
303 unsigned char *buf =
304 new unsigned char[MAX_BIN_PKT_ARRAY_LENGTH - hdr_length];
305 memset(buf, '\0', MAX_BIN_PKT_ARRAY_LENGTH - hdr_length);
306
307 offset = 0;
308 for (std::vector<packer *>::iterator it = activePackers.begin();
309 it != activePackers.end();
310 ++it) {
311 offset = (*it)->packMyHdr(p, buf, offset);
312 }
313
315 memcpy(hal->binPkt() + hdr_length, buf, std::ceil(offset / 8.0));
316 hal->binPktLength() += BARR_ARRAYSIZE(offset);
317 if (hal->binPktLength() != hdr_length + payload_length) {
318 if (debug_ > 1) {
319 std::cout << "\033[0;0;31m"
320 << " WARNING - REDUCED PACKET"
321 << "\033[0m" << std::endl;
322 ;
323 std::cout << "in packer::packPayload -> pkt size set to: "
324 << hal->binPktLength()
325 << ", header length is: " << hdr_length
326 << " and payload length is: "
327 << BARR_ARRAYSIZE(offset)
328 << " , DEFAULT payload length is "
329 << payload_length << std::endl;
330 }
331 }
332 } else {
333 std::cout << "\033[0;0;31m"
334 << " ERROR"
335 << "\033[0m" << std::endl;
336 ;
337 std::cout << "in packer::packPayload -> payload size returned by "
338 "packer is: "
339 << offset << ", higher than: "
341 << " Which is the max pkt length: "
343 << " minus the header length: " << hdr_length
344 << ". Payload is not serialized." << std::endl;
345 }
346
347 /* if (!(payload_length > MAX_BIN_PKT_ARRAY_LENGTH - hdr_length)) {
348 memcpy(hal->binPkt() + hdr_length, buf, payload_length);
349 hal->binPktLength() += payload_length;
350 if (hal->binPktLength() != payload_length &&
351 hal->binPktLength() != hdr_length + payload_length) {
352 std::cout << "\033[0;0;31m" << " ERROR" << "\033[0m" <<
353 std::endl;;
354 cout << "in packer::packHdr -> pkt size set to: " <<
355 hal->binPktLength() << ", whilst header length is: " << hdr_length <<
356 " and payload length is: " << payload_length << endl;
357 exit(-1);
358 }
359 } else {
360 std::cout << "\033[0;0;31m" << " ERROR" << "\033[0m" <<
361 std::endl;;
362 std::cout << "in packer::packPayload -> payload size
363 returned by packer is: " << payload_length << ", higher than: " <<
364 (MAX_BIN_PKT_ARRAY_LENGTH - hdr_length) << " Which is the max pkt
365 length: " << MAX_BIN_PKT_ARRAY_LENGTH << " minus the header length: "
366 << hdr_length << ". Payload is not serialized." << std::endl;
367 }
368 // conversion from const char* to string
369 res.assign((const char *) buf, payload_length);
370 delete[] buf;
371 */
372 // conversion from const char* to string
373 res.assign((const char *) buf, BARR_ARRAYSIZE(offset));
374 delete[] buf;
375 } else {
376 if (payload_length != 0) {
377 std::cout << "\033[0;0;31m"
378 << " WARNING"
379 << "\033[0m" << std::endl;
380 std::cout << "in packer::packPayload -> payload activePackers "
381 "empty but payload_length: "
382 << payload_length << ". Empty string is returned"
383 << std::endl;
384 }
385 res.assign("");
386 }
387
388 if (debug_) {
389 std::cout << "\033[0;47;30m"
390 << " TX"
391 << "\033[0m" << std::endl;
392 std::cout << "--> Bin data payload generated by packer:"
393 << hexdump(hal->binPkt() + hdr_length, BARR_ARRAYSIZE(offset))
394 << std::endl;
395 std::cout << "--> Payload length (unsigned char):"
396 << BARR_ARRAYSIZE(offset) << std::endl;
397 }
398
399 /* if (debug_) {
400
401 std::cout << "\033[0;47;30m" << " TX" << "\033[0m" << std::endl;
402 std::cout << "--> Bin data payload generated by packer:" <<
403 hexdump(hal->binPkt() + hdr_length, payload_length) << std::endl;
404 std::cout << "--> Payload length (unsigned char):" << payload_length
405 << std::endl;
406 }
407 */
408 return res;
409}
410
411Packet *
413{
414 hdr_uwal *hal = HDR_UWAL(p);
415 hal->binHdrLength() = hdr_length;
416
417 if (debug_) {
418 std::cout << "\033[0;47;30m"
419 << " RX"
420 << "\033[0m" << std::endl;
421 std::cout << "<-- Bin data header received by packer:"
422 << hexdump(hal->binPkt(), hdr_length) << std::endl;
423 }
424
425 size_t offset = 0;
426
427 unpackMyHdr((unsigned char *) hal->binPkt(), offset, p);
428
429 return p;
430}
431
432Packet *
434{
435 hdr_uwal *hal = HDR_UWAL(p);
436
437 if (debug_) {
438 std::cout << "\033[0;47;30m"
439 << " RX"
440 << "\033[0m" << std::endl;
441 // std::cout << "<-- Bin data payload received by packer:" <<
442 // hexdump(hal->binPkt() + hal->binHdrLength(), payload_length) <<
443 // std::endl;
444 hdr_cmn *ch = HDR_CMN(p);
445 std::cout << "<-- Bin data payload received by packer:"
446 << hexdump(hal->binPkt() + hal->binHdrLength(), ch->size())
447 << std::endl;
448 }
449
450 if (activePackers.empty()) {
451 if (hal->binPktLength() - hal->binHdrLength() != 0) {
452 std::cout << "\033[0;0;31m"
453 << " WARNING"
454 << "\033[0m" << std::endl;
455 std::cout << "in packer::unpackPayload -> payload activePackers "
456 "empty but binary payload: "
457 << hexdump(hal->binPkt() + hal->binHdrLength(),
458 hal->binPktLength() - hal->binHdrLength())
459 << ". Packet in ERROR is returned" << std::endl;
460 hdr_cmn *ch = HDR_CMN(p);
461 ch->error() = 1;
462 return p;
463 }
464 }
465
466 if (hal->binPktLength() - hal->binHdrLength() < payload_length) {
467 if (debug_ > 1) {
468 std::cout << "\033[0;0;31m"
469 << " WARNING"
470 << "\033[0m" << std::endl;
471 std::cout << "in packer::unpackPayload -> the payload size "
472 "computed from the HDR_UWAL corresponding fields is: "
473 << hal->binPktLength() - hal->binHdrLength()
474 << " which is not the DEFAULT expected size: "
475 << payload_length << ". Is it a REDUCED packet?"
476 << std::endl;
477 }
478
479 // hdr_cmn *ch = HDR_CMN(p);
480 // ch->error() = 1;
481 // return p;
482 }
483
484 size_t offset = 0;
485 for (std::vector<packer *>::iterator it = activePackers.begin();
486 it != activePackers.end();
487 ++it) {
488 offset = (*it)->unpackMyHdr(
489 (unsigned char *) (hal->binPkt() + hal->binHdrLength()),
490 offset,
491 p);
492 }
493
494 // Now we have unpacked the whole packet, set the size according to the
495 // total received bits
496 HDR_CMN(p)->size() = offset / (sizeof(char) * 8);
497 if (debug_) {
498 std::cout << "ch->size() after unpack is: " << HDR_CMN(p)->size()
499 << std::endl;
500 }
501
502 return p;
503}
504
505void
507{
508 std::cout << "\n\033[0;47;30m"
509 << " MAP in USE"
510 << "\033[0m" << std::endl;
511 std::cout << "Header length: " << hdr_length << " [Bytes]" << std::endl;
513 std::cout << "Payload length: " << payload_length << " [Bytes]"
514 << std::endl;
515 for (std::vector<packer *>::iterator it = activePackers.begin();
516 it != activePackers.end();
517 ++it) {
518 (*it)->printMyHdrMap();
519 }
520}
521
522size_t
523packer::packMyHdr(Packet *p, unsigned char *buf, size_t offset)
524{
525 // Pointer to the AL packer header
526 hdr_uwal *alh = HDR_UWAL(p);
527
528 int field_idx = 0;
529
530 offset += put(buf, offset, &(alh->srcID_), n_bits[field_idx++]);
531 offset += put(buf, offset, &(alh->pktID_), n_bits[field_idx++]);
532 offset +=
533 put(buf, offset, &(alh->framePayloadOffset_), n_bits[field_idx++]);
534 offset += put(buf, offset, &(alh->Mbit_), n_bits[field_idx++]);
535 offset += put(buf, offset, &(alh->dummyStr_), n_bits[field_idx++]);
536
537 if (debug_) {
538 std::cout << "\033[0;47;30m"
539 << " TX AL packer hdr"
540 << "\033[0m" << std::endl;
542 }
543
544 return offset;
545}
546
547size_t
548packer::unpackMyHdr(unsigned char *buf, size_t offset, Packet *p)
549{
550 // Pointer to the AL packer header
551 hdr_uwal *alh = HDR_UWAL(p);
552
553 int field_idx = 0;
554
555 memset(&(alh->srcID_), 0, sizeof(alh->srcID_));
556 offset += get(buf, offset, &(alh->srcID_), n_bits[field_idx++]);
557
558 memset(&(alh->pktID_), 0, sizeof(alh->pktID_));
559 offset += get(buf, offset, &(alh->pktID_), n_bits[field_idx++]);
560
561 memset(&(alh->framePayloadOffset_), 0, sizeof(alh->framePayloadOffset_));
562 offset +=
563 get(buf, offset, &(alh->framePayloadOffset_), n_bits[field_idx++]);
564
565 memset(&(alh->Mbit_), 0, sizeof(alh->Mbit_));
566 offset += get(buf, offset, &(alh->Mbit_), n_bits[field_idx++]);
567
568 memset(&(alh->dummyStr_), '\0', MAX_DUMMY_STRING_LENGTH);
569 offset += get(buf, offset, &(alh->dummyStr_), n_bits[field_idx++]);
570
571 if (debug_) {
572 std::cout << "\033[0;47;30m"
573 << " RX AL packer hdr"
574 << "\033[0m" << std::endl;
576 }
577
578 return offset;
579}
580
581void
583{
584 std::cout << "\033[0;47;30m"
585 << " Packer Name "
586 << "\033[0m"
587 << " UWAL" << std::endl;
588 std::cout << "\033[0;47;30m 1st field "
589 << "\033[0m"
590 << " src ID: " << SRC_ID_Bits << " bits" << std::endl;
591 std::cout << "\033[0;47;30m 2st field "
592 << "\033[0m"
593 << " pkt IkD: " << PKT_ID_Bits << " bits" << std::endl;
594 std::cout << "\033[0;47;30m 3st field "
595 << "\033[0m"
596 << " frame offset: " << FRAME_OFFSET_Bits << " bits" << std::endl;
597 std::cout << "\033[0;47;30m 4st field "
598 << "\033[0m"
599 << " M bit: " << M_BIT_Bits << " bits" << std::endl;
600 std::cout << "\033[0;47;30m 5st field "
601 << "\033[0m"
602 << " dummy content: " << DUMMY_CONTENT_Bits << " bits"
603 << std::endl;
604 return;
605}
606
607void
609{
610 for (int i = 0, l = n_bits.size(); i < l; i++) {
611 if (printAllFields || n_bits[i] != 0)
612 printMyHdrField(p, i);
613 }
614}
615
616void
617packer::printMyHdrField(Packet *p, int field)
618{
619 hdr_uwal *alh = HDR_UWAL(p);
620
621 // size_t printedFieldLength = 2048;
622 // char printedField[printedFieldLength];
623 // memset(printedField, '\0', printedFieldLength);
624
625 switch (field) {
626 case 0:
627 std::cout << "\033[0;47;30m src ID:\033[0m "
628 << static_cast<uint32_t>(alh->srcID()) << " "
629 << hex_bytes(alh->srcID(), n_bits[0]) << std::endl;
630 break;
631 case 1:
632 std::cout << "\033[0;47;30m pkt ID:\033[0m "
633 << static_cast<uint32_t>(alh->pktID()) << " "
634 << hex_bytes(alh->pktID(), n_bits[1]) << std::endl;
635 break;
636 case 2:
637 std::cout << "\033[0;47;30m frame offset:\033[0m "
638 << static_cast<uint32_t>(alh->framePayloadOffset()) << " "
639 << hex_bytes(alh->framePayloadOffset(), n_bits[2])
640 << std::endl;
641 break;
642 case 3:
643 std::cout << "\033[0;47;30m M bit:\033[0m "
644 << static_cast<uint32_t>(alh->Mbit()) << " "
645 << hex_bytes(alh->Mbit(), n_bits[3]) << std::endl;
646 break;
647 case 4:
648 std::cout << "\033[0;47;30m dummy content:\033[0m "
649 << hexdump(alh->dummyStr()) << std::endl;
650 break;
651 default:
652 std::cout << "\033[0;41;30m WARNING \033[0m, Field number "
653 << (field + 1)
654 << " does not exist or its printing is not implemented"
655 << std::endl;
656 }
657 // return printedField;
658}
659
660size_t
662{
663
664 size_t total_bits = 0;
665
666 for (int i = 0, l = n_bits.size(); i < l; i++)
667 total_bits += n_bits[i];
668
669 return total_bits;
670}
671
672size_t
673packer::get(unsigned char *buffer, size_t offset, void *val, size_t h)
674{
675 for (size_t j = 0; j < h; j++)
676 if (BARR_TEST(buffer, (offset + j)))
677 BARR_SET(val, j);
678 else
679 BARR_CLEAR(val, j);
680
681 return h;
682}
683
684size_t
685packer::put(unsigned char *buffer, size_t offset, void *val, size_t h)
686{
687 for (size_t j = 0; j < h; j++)
688 if (BARR_TEST(val, j))
689 BARR_SET(buffer, (offset + j));
690 else
691 BARR_CLEAR(buffer, (offset + j));
692
693 return h;
694}
695
696std::string
697packer::hexdump_nice(std::string str)
698{
699 const char *data = str.c_str();
700 size_t len = str.size();
701
702 return hexdump_nice(data, len);
703}
704
705std::string
706packer::hexdump_nice(const char *data, size_t len)
707{
708 std::string str_out = "";
709
710 for (size_t i = 0; i < len; i++) {
711 if (std::isalnum(data[i]) || std::ispunct(data[i]))
712 str_out += data[i];
713 else {
714 std::stringstream sstr("");
715 sstr << "[";
716 sstr.fill('0');
717 sstr.width(2);
718 sstr << std::hex << (unsigned int) (unsigned char) data[i]
719 << std::dec << "]";
720 str_out += sstr.str();
721 }
722 }
723 return str_out;
724}
725
726std::string
727packer::hexdump(std::string str)
728{
729 const char *data = str.c_str();
730 size_t len = str.size();
731 return hexdump(data, len);
732}
733
734std::string
735packer::hexdump(const char *data, size_t len)
736{
737 std::string str_out = "";
738
739 for (size_t i = 0; i < len; i++) {
740 std::stringstream sstr("");
741 sstr << "[";
742 sstr.fill('0');
743 sstr.width(2);
744 sstr << std::hex << (unsigned int) (unsigned char) data[i] << std::dec
745 << "]";
746 str_out += sstr.str();
747 }
748 return str_out;
749}
750
751std::string
753{
754 unsigned char *p = (unsigned char *) &value;
755 std::stringstream sstr("");
756 // cout << "packer::hex_bytes:Value to print:" << value << std::endl;
757 sstr << "[";
758 for (int i = 0; i < sizeof(value); i++) {
759 sstr.fill('0');
760 sstr.width(2);
761 sstr << std::hex << static_cast<uint32_t>(p[i]);
762 }
763 sstr << std::dec << "]";
764
765 return sstr.str();
766}
767
768std::string
769packer::hex_bytes(double value)
770{
771 unsigned char *p = (unsigned char *) &value;
772 std::stringstream sstr("");
773 // cout << "packer::hex_bytes:Value to print:" << value << std::endl;
774 sstr << "[";
775 for (int i = 0; i < sizeof(value); i++) {
776 sstr.fill('0');
777 sstr.width(2);
778 sstr << std::hex << static_cast<uint32_t>(p[i]);
779 }
780 sstr << std::dec << "]";
781
782 return sstr.str();
783}
784
785std::string
786packer::hex_bytes(const char &value, const uint32_t &len_bits)
787{
788 assert(len_bits <= sizeof(value) * 8);
789 const int BINARY_MASK = 0xff;
790 const int num_bytes = ceil(len_bits / 8.0);
791 std::stringstream sstr("");
792 // cout << "packer::hex_bytes:Value to print:" << value << ", num bits: "
793 // << len_bits << ", num bytes: " << num_bytes << std::endl;
794 sstr << "[";
795 ;
796 switch (num_bytes) {
797 case 1:
798 sstr.fill('0');
799 sstr.width(2);
800 sstr << std::hex << (value & BINARY_MASK);
801 break;
802 default:
803 sstr << std::dec << std::endl;
804 // sstr << std::dec << "Number of bytes to print higher
805 // than " << sizeof (value) << ", not supported." <<
806 // std::endl;
807 }
808 sstr << "]";
809 return sstr.str();
810}
811
812std::string
813packer::hex_bytes(const int8_t &value, const uint32_t &len_bits)
814{
815 assert(len_bits <= sizeof(value) * 8);
816 const int8_t BINARY_MASK = 0xff;
817 const uint32_t num_bytes = ceil(len_bits / 8.0);
818 std::stringstream sstr("");
819 // cout << "packer::hex_bytes:Value to print:" <<
820 // static_cast<int32_t>(value) << ", num bits: " << len_bits << ", num
821 // bytes: " << num_bytes << std::endl;
822 sstr << "[";
823 switch (num_bytes) {
824 case 1:
825 sstr.fill('0');
826 sstr.width(2);
827 sstr << std::hex << (value & BINARY_MASK);
828 break;
829 default:
830 sstr << std::dec << std::endl;
831 // sstr << std::dec << "Number of bytes to print higher
832 // than " << sizeof (value) << ", not supported." <<
833 // std::endl;
834 }
835 sstr << "]";
836 return sstr.str();
837}
838
839std::string
840packer::hex_bytes(const int16_t &value, const uint32_t &len_bits)
841{
842 assert(len_bits <= sizeof(value) * 8);
843 const int16_t BINARY_MASK = 0x00ff;
844 const uint32_t num_bytes = ceil(len_bits / 8.0);
845 std::stringstream sstr("");
846 // cout << "packer::hex_bytes:Value to print:" <<
847 // static_cast<int32_t>(value) << ", num bits: " << len_bits << ", num
848 // bytes: " << num_bytes << std::endl;
849 sstr << "[";
850 switch (num_bytes) {
851 case 2:
852 sstr.fill('0');
853 sstr.width(2);
854 sstr << std::hex << ((value >> 8) & BINARY_MASK);
855 case 1:
856 sstr.fill('0');
857 sstr.width(2);
858 sstr << std::hex << (value & BINARY_MASK);
859 break;
860 default:
861 sstr << std::dec << std::endl;
862 // sstr << std::dec << "Number of bytes to print higher
863 // than " << sizeof (value) << ", not supported." <<
864 // std::endl;
865 }
866 sstr << "]";
867 return sstr.str();
868}
869
870std::string
871packer::hex_bytes(const int32_t &value, const uint32_t &len_bits)
872{
873 assert(len_bits <= sizeof(value) * 8);
874 const int32_t BINARY_MASK = 0x000000ff;
875 const uint32_t num_bytes = ceil(len_bits / 8.0);
876 std::stringstream sstr("");
877 // cout << "packer::hex_bytes:Value to print:" << value << ", num bits: "
878 // << len_bits << ", num bytes: " << num_bytes << std::endl;
879 sstr << "[";
880 switch (num_bytes) {
881 case 4:
882 sstr.fill('0');
883 sstr.width(2);
884 sstr << std::hex << ((value >> 24) & BINARY_MASK);
885 case 3:
886 sstr.fill('0');
887 sstr.width(2);
888 sstr << std::hex << ((value >> 16) & BINARY_MASK);
889 case 2:
890 sstr.fill('0');
891 sstr.width(2);
892 sstr << std::hex << ((value >> 8) & BINARY_MASK);
893 case 1:
894 sstr.fill('0');
895 sstr.width(2);
896 sstr << std::hex << (value & BINARY_MASK);
897 break;
898 default:
899 sstr << std::dec << std::endl;
900 // sstr << std::dec << "Number of bytes to print higher
901 // than " << sizeof (value) << ", not supported." <<
902 // std::endl;
903 }
904 sstr << "]";
905 return sstr.str();
906}
907
908std::string
909packer::hex_bytes(const int64_t &value, const uint32_t &len_bits)
910{
911 assert(len_bits <= sizeof(value) * 8);
912 const int64_t BINARY_MASK = 0x00000000000000ff;
913 const uint32_t num_bytes = ceil(len_bits / 8.0);
914 std::stringstream sstr("");
915 // cout << "packer::hex_bytes:Value to print:" << value << ", num bits: "
916 // << len_bits << ", num bytes: " << num_bytes << std::endl;
917 sstr << "[";
918 switch (num_bytes) {
919 case 8:
920 sstr.fill('0');
921 sstr.width(2);
922 sstr << std::hex << ((value >> 56) & BINARY_MASK);
923 case 7:
924 sstr.fill('0');
925 sstr.width(2);
926 sstr << std::hex << ((value >> 48) & BINARY_MASK);
927 case 6:
928 sstr.fill('0');
929 sstr.width(2);
930 sstr << std::hex << ((value >> 40) & BINARY_MASK);
931 case 5:
932 sstr.fill('0');
933 sstr.width(2);
934 sstr << std::hex << ((value >> 32) & BINARY_MASK);
935 case 4:
936 sstr.fill('0');
937 sstr.width(2);
938 sstr << std::hex << ((value >> 24) & BINARY_MASK);
939 case 3:
940 sstr.fill('0');
941 sstr.width(2);
942 sstr << std::hex << ((value >> 16) & BINARY_MASK);
943 case 2:
944 sstr.fill('0');
945 sstr.width(2);
946 sstr << std::hex << ((value >> 8) & BINARY_MASK);
947 case 1:
948 sstr.fill('0');
949 sstr.width(2);
950 sstr << std::hex << (value & BINARY_MASK);
951 break;
952 default:
953 sstr << std::dec << std::endl;
954 // sstr << std::dec << "Number of bytes to print higher
955 // than " << sizeof (value) << ", not supported." <<
956 // std::endl;
957 }
958 sstr << "]";
959 return sstr.str();
960}
961
962std::string
963packer::hex_bytes(const uint8_t &value, const uint32_t &len_bits)
964{
965 assert(len_bits <= sizeof(value) * 8);
966 const uint8_t BINARY_MASK = 0xff;
967 const uint32_t num_bytes = ceil(len_bits / 8.0);
968 std::stringstream sstr("");
969 // cout << "packer::hex_bytes:Value to print:" <<
970 // static_cast<uint32_t>(value) << ", num bits: " << len_bits << ", num
971 // bytes: " << num_bytes << std::endl;
972 sstr << "[";
973 switch (num_bytes) {
974 case 1:
975 sstr.fill('0');
976 sstr.width(2);
977 sstr << std::hex << (value & BINARY_MASK);
978 break;
979 default:
980 sstr << std::dec << std::endl;
981 // sstr << std::dec << "Number of bytes to print higher
982 // than " << sizeof (value) << ", not supported." <<
983 // std::endl;
984 }
985 sstr << "]";
986 return sstr.str();
987}
988
989std::string
990packer::hex_bytes(const uint16_t &value, const uint32_t &len_bits)
991{
992 assert(len_bits <= sizeof(value) * 8);
993 const uint16_t BINARY_MASK = 0x00ff;
994 const uint32_t num_bytes = ceil(len_bits / 8.0);
995 std::stringstream sstr("");
996 // cout << "packer::hex_bytes:Value to print:" <<
997 // static_cast<uint32_t>(value) << ", num bits: " << len_bits << ", num
998 // bytes: " << num_bytes << std::endl;
999 sstr << "[";
1000 switch (num_bytes) {
1001 case 2:
1002 sstr.fill('0');
1003 sstr.width(2);
1004 sstr << std::hex << ((value >> 8) & BINARY_MASK);
1005 case 1:
1006 sstr.fill('0');
1007 sstr.width(2);
1008 sstr << std::hex << (value & BINARY_MASK);
1009 break;
1010 default:
1011 sstr << std::dec << std::endl;
1012 // sstr << std::dec << "Number of bytes to print higher
1013 // than " << sizeof (value) << ", not supported." <<
1014 // std::endl;
1015 }
1016 sstr << "]";
1017 return sstr.str();
1018}
1019
1020std::string
1021packer::hex_bytes(const uint32_t &value, const uint32_t &len_bits)
1022{
1023 assert(len_bits <= sizeof(value) * 8);
1024 const uint32_t BINARY_MASK = 0x000000ff;
1025 const uint32_t num_bytes = ceil(len_bits / 8.0);
1026 std::stringstream sstr("");
1027 // cout << "packer::hex_bytes:Value to print:" << value << ", num bits: "
1028 // << len_bits << ", num bytes: " << num_bytes << std::endl;
1029 sstr << "[";
1030 switch (num_bytes) {
1031 case 4:
1032 sstr.fill('0');
1033 sstr.width(2);
1034 sstr << std::hex << ((value >> 24) & BINARY_MASK);
1035 case 3:
1036 sstr.fill('0');
1037 sstr.width(2);
1038 sstr << std::hex << ((value >> 16) & BINARY_MASK);
1039 case 2:
1040 sstr.fill('0');
1041 sstr.width(2);
1042 sstr << std::hex << ((value >> 8) & BINARY_MASK);
1043 case 1:
1044 sstr.fill('0');
1045 sstr.width(2);
1046 sstr << std::hex << (value & BINARY_MASK);
1047 break;
1048 default:
1049 sstr << std::dec << std::endl;
1050 // sstr << std::dec << "Number of bytes to print higher
1051 // than " << sizeof (value) << ", not supported." <<
1052 // std::endl;
1053 }
1054 sstr << "]";
1055 return sstr.str();
1056}
1057
1058std::string
1059packer::hex_bytes(const uint64_t &value, const uint32_t &len_bits)
1060{
1061 assert(len_bits <= sizeof(value) * 8);
1062 const uint64_t BINARY_MASK = 0x00000000000000ff;
1063 const uint32_t num_bytes = ceil(len_bits / 8.0);
1064 std::stringstream sstr("");
1065 // cout << "packer::hex_bytes:Value to print:" << value << ", num bits: "
1066 // << len_bits << ", num bytes: " << num_bytes << std::endl;
1067 sstr << "[";
1068 switch (num_bytes) {
1069 case 8:
1070 sstr.fill('0');
1071 sstr.width(2);
1072 sstr << std::hex << ((value >> 56) & BINARY_MASK);
1073 case 7:
1074 sstr.fill('0');
1075 sstr.width(2);
1076 sstr << std::hex << ((value >> 48) & BINARY_MASK);
1077 case 6:
1078 sstr.fill('0');
1079 sstr.width(2);
1080 sstr << std::hex << ((value >> 40) & BINARY_MASK);
1081 case 5:
1082 sstr.fill('0');
1083 sstr.width(2);
1084 sstr << std::hex << ((value >> 32) & BINARY_MASK);
1085 case 4:
1086 sstr.fill('0');
1087 sstr.width(2);
1088 sstr << std::hex << ((value >> 24) & BINARY_MASK);
1089 case 3:
1090 sstr.fill('0');
1091 sstr.width(2);
1092 sstr << std::hex << ((value >> 16) & BINARY_MASK);
1093 case 2:
1094 sstr.fill('0');
1095 sstr.width(2);
1096 sstr << std::hex << ((value >> 8) & BINARY_MASK);
1097 case 1:
1098 sstr.fill('0');
1099 sstr.width(2);
1100 sstr << std::hex << (value & BINARY_MASK);
1101 break;
1102 default:
1103 sstr << std::dec << std::endl;
1104 // sstr << std::dec << "Number of bytes to print higher
1105 // than " << sizeof (value) << ", not supported." <<
1106 // std::endl;
1107 }
1108 sstr << "]";
1109 return sstr.str();
1110}
1111
1112std::string
1113packer::bindump(std::string str)
1114{
1115 size_t len = str.size();
1116 const char *data = str.c_str();
1117
1118 return bindump(data, len);
1119}
1120
1121std::string
1122packer::bindump(const char *data, size_t len)
1123{
1124 std::string str_out = "";
1125 std::string str_tmp;
1126
1127 for (size_t i = 0; i < len; i++) {
1128 str_tmp = "";
1129 for (int j = 0; j < CHAR_BIT; j++) {
1130 if BARR_TEST (data, i * CHAR_BIT + j)
1131 str_tmp += '1';
1132 else
1133 str_tmp += '0';
1134 }
1135 str_out += ("[" + str_tmp + "]");
1136 }
1137
1138 return str_out;
1139}
Class to create the Otcl shadow object for an object of the class packer.
Definition packer.cpp:107
TclObject * create(int, const char *const *)
Definition packer.cpp:115
Class exploited by the Uwal module to map an NS-Miracle packet into a bit stream, and vice-versa.
Definition packer.h:57
std::vector< size_t > n_bits
Vector of elements containing the indication of the number of bits to consider for each header field.
Definition packer.h:224
virtual size_t packMyHdr(Packet *, unsigned char *, size_t)
Definition packer.cpp:523
static std::string hexdump_nice(std::string)
Function used for log and debug purposes (in order to print binary strings, even if they contain spec...
Definition packer.cpp:697
virtual void printMyHdrMap()
Definition packer.cpp:582
virtual void printMyHdrFields(Packet *)
Definition packer.cpp:608
Packet * unpackHdr(Packet *)
Definition packer.cpp:412
void printMap()
Definition packer.cpp:506
int command(int, const char *const *)
Method to map tcl commands into c++ methods.
Definition packer.cpp:180
size_t PKT_ID_Bits
Bit length of the srcID_ field to be put in the header stream of bits.
Definition packer.h:290
size_t put(unsigned char *buffer, size_t offset, void *val, size_t h)
Method used to map in a certain number of bits, contained in a buffer of chars, a given variable.
Definition packer.cpp:685
std::vector< packer * > activePackers
Vector of elements containing the pointers to the active packers (i.e., the derived classed of packer...
Definition packer.h:271
bool printAllFields
Definition packer.h:286
size_t DUMMY_CONTENT_Bits
Bit length of the Mbit_ field to be put in the header stream of bits.
Definition packer.h:296
~packer()
Class destructor.
Definition packer.cpp:159
static std::string bindump(std::string)
Definition packer.cpp:1113
size_t M_BIT_Bits
Bit length of the frameID_ field to be put in the header stream of bits.
Definition packer.h:294
std::string packPayload(Packet *)
Method to map an NS-Miracle packet into a legal modem payload (i.e., a string of binary characters) w...
Definition packer.cpp:292
virtual void init()
Definition packer.cpp:164
packer(bool)
Class constructor.
Definition packer.cpp:121
size_t FRAME_OFFSET_Bits
Bit length of the pktID_ field to be put in the header stream of bits.
Definition packer.h:292
static std::string hex_bytes(float)
Definition packer.cpp:752
size_t get(unsigned char *buffer, size_t offset, void *val, size_t h)
Method used to retrieve a given variable from a certain number of bits contained in a buffer of chars...
Definition packer.cpp:673
size_t getMyHdrBinLength()
Definition packer.cpp:661
size_t getHdrBinLength()
Definition packer.cpp:228
size_t hdr_length
The minimum number of elements that a buffer of char must have in order to store the header fields of...
Definition packer.h:282
static std::string hexdump(std::string)
Definition packer.cpp:727
int debug_
Flag to enable debug messages.
Definition packer.h:227
size_t payload_length
The minimum number of elements that a buffer of char must have in order to store the fields to be cod...
Definition packer.h:277
Packet * unpackPayload(Packet *)
Method to de-map a legal modem payload (i.e., a string of binary characters) into an NS-Miracle packe...
Definition packer.cpp:433
virtual void printMyHdrField(Packet *, int)
Definition packer.cpp:617
size_t getPayloadBinLength()
Definition packer.cpp:216
std::string packHdr(Packet *)
Definition packer.cpp:234
virtual size_t unpackMyHdr(unsigned char *, size_t, Packet *)
Definition packer.cpp:548
size_t SRC_ID_Bits
Definition packer.h:288
#define BARR_SET(barr, N)
Definition frame-set.cpp:55
#define BARR_TEST(barr, N)
Definition frame-set.cpp:59
#define MAX_BIN_PKT_ARRAY_LENGTH
Definition hdr-uwal.h:44
#define MAX_DUMMY_STRING_LENGTH
Definition hdr-uwal.h:45
#define HDR_UWAL(p)
Definition hdr-uwal.h:43
#define BARR_ARRAYSIZE(N)
MACRO to compute the minimum number of elements that a buffer of BARR_ELTYPEs must have in order to s...
Definition packer.cpp:60
unsigned char BARR_ELTYPE
Definition packer.cpp:45
#define BARR_CLEAR(barr, N)
MACRO to set to 0 the bit N of a buffer of BARR_ELTYPEs.
Definition packer.cpp:90
PackerClass class_module_packer
#define DEFAULT_DUMMY_CONTENT_LENGTH
Definition packer.cpp:47
Header of the class responsible to map an NS-Miracle packet into a bit stream, and vice-versa.
hdr_uwal describes the packet header used by Uwal objects.
Definition hdr-uwal.h:52
char * dummyStr()
Return the pointer to the dummyStr_ array.
Definition hdr-uwal.h:132
uint8_t & Mbit()
Reference to the Mbit_ variable.
Definition hdr-uwal.h:123
uint32_t & binHdrLength()
Reference to the binHdrLength_ variable.
Definition hdr-uwal.h:159
uint16_t & framePayloadOffset()
Reference to the frameOffset_ variable.
Definition hdr-uwal.h:114
char dummyStr_[MAX_DUMMY_STRING_LENGTH]
array containing a dummy string.
Definition hdr-uwal.h:75
unsigned int & pktID()
Reference to the pktID_ variable.
Definition hdr-uwal.h:105
char * binPkt()
Return to the binPkt_ array pointer.
Definition hdr-uwal.h:141
uint8_t srcID_
ID of the packet's source node.
Definition hdr-uwal.h:69
unsigned int pktID_
ID of the packet.
Definition hdr-uwal.h:70
uint16_t framePayloadOffset_
Offset of the frame payload.
Definition hdr-uwal.h:71
uint8_t & srcID()
Reference to the srcID_ variable.
Definition hdr-uwal.h:96
uint32_t & binPktLength()
Reference to the binPktLength_ variable.
Definition hdr-uwal.h:150
uint8_t Mbit_
M bit: if set to 0 the current frame is the last or the only one; if set to 1 the current frame is no...
Definition hdr-uwal.h:72