LTKCPP-- LLRP Toolkit C Plus Plus Library
ltkcpp_framedecode.cpp
1 
2 /*
3  *****************************************************************************
4  * *
5  * IMPINJ CONFIDENTIAL AND PROPRIETARY *
6  * *
7  * This source code is the sole property of Impinj, Inc. Reproduction or *
8  * utilization of this source code in whole or in part is forbidden without *
9  * the prior written consent of Impinj, Inc. *
10  * *
11  * (c) Copyright Impinj, Inc. 2007,2008. All rights reserved. *
12  * *
13  *****************************************************************************/
14 
15 
16 
17 #include <assert.h>
18 
19 #include "ltkcpp_platform.h"
20 #include "ltkcpp_base.h"
21 #include "ltkcpp_frame.h"
22 
23 
24 namespace LLRP
25 {
26 
27 CFrameDecoder::CFrameDecoder (
28  const CTypeRegistry * pTypeRegistry,
29  unsigned char * pBuffer,
30  unsigned int nBuffer)
31  : CDecoder(pTypeRegistry)
32 {
33  m_pBuffer = pBuffer;
34  m_nBuffer = nBuffer;
35 
36  m_iNext = 0;
37  m_BitFieldBuffer = 0;
38  m_nBitFieldResid = 0;
39 }
40 
41 CFrameDecoder::~CFrameDecoder (void)
42 {
43 }
44 
45 CMessage *
46 CFrameDecoder::decodeMessage (void)
47 {
48  CFrameDecoderStream DecoderStream(this);
49  CMessage * pMessage;
50 
51  pMessage = DecoderStream.getMessage();
52 
53  return pMessage;
54 }
55 
56 llrp_u8_t
57 CFrameDecoder::next_u8 (void)
58 {
59  llrp_u8_t Value;
60 
61  assert(m_iNext + 1u <= m_nBuffer);
62 
63  Value = m_pBuffer[m_iNext++];
64 
65  return Value;
66 }
67 
68 llrp_u16_t
69 CFrameDecoder::next_u16 (void)
70 {
71  llrp_u16_t Value;
72 
73  assert(m_iNext + 2u <= m_nBuffer);
74 
75  Value = m_pBuffer[m_iNext++];
76  Value <<= 8u;
77  Value |= m_pBuffer[m_iNext++];
78 
79  return Value;
80 }
81 
82 llrp_u32_t
83 CFrameDecoder::next_u32 (void)
84 {
85  llrp_u32_t Value;
86 
87  assert(m_iNext + 4u <= m_nBuffer);
88 
89  Value = m_pBuffer[m_iNext++];
90  Value <<= 8u;
91  Value |= m_pBuffer[m_iNext++];
92  Value <<= 8u;
93  Value |= m_pBuffer[m_iNext++];
94  Value <<= 8u;
95  Value |= m_pBuffer[m_iNext++];
96 
97  return Value;
98 }
99 
100 llrp_u64_t
101 CFrameDecoder::next_u64 (void)
102 {
103  llrp_u64_t Value;
104 
105  assert(m_iNext + 8u <= m_nBuffer);
106 
107  Value = m_pBuffer[m_iNext++];
108  Value <<= 8u;
109  Value |= m_pBuffer[m_iNext++];
110  Value <<= 8u;
111  Value |= m_pBuffer[m_iNext++];
112  Value <<= 8u;
113  Value |= m_pBuffer[m_iNext++];
114  Value <<= 8u;
115  Value |= m_pBuffer[m_iNext++];
116  Value <<= 8u;
117  Value |= m_pBuffer[m_iNext++];
118  Value <<= 8u;
119  Value |= m_pBuffer[m_iNext++];
120  Value <<= 8u;
121  Value |= m_pBuffer[m_iNext++];
122 
123  return Value;
124 }
125 
126 llrp_u8_t
127 CFrameDecoderStream::get_u8 (
128  const CFieldDescriptor * pFieldDescriptor)
129 {
130  llrp_u8_t Value;
131 
132  if(checkAvailable(1u, pFieldDescriptor))
133  {
134  Value = m_pDecoder->next_u8();
135  }
136  else
137  {
138  Value = 0;
139  }
140 
141  return Value;
142 }
143 
144 llrp_s8_t
145 CFrameDecoderStream::get_s8 (
146  const CFieldDescriptor * pFieldDescriptor)
147 {
148  llrp_s8_t Value;
149 
150  if(checkAvailable(1u, pFieldDescriptor))
151  {
152  Value = m_pDecoder->next_u8();
153  }
154  else
155  {
156  Value = 0;
157  }
158 
159  return Value;
160 }
161 
162 llrp_u8v_t
163 CFrameDecoderStream::get_u8v (
164  const CFieldDescriptor * pFieldDescriptor)
165 {
166  llrp_u16_t nValue;
167  llrp_u8v_t Value;
168 
169  nValue = getVarlenCount(pFieldDescriptor);
170 
171  if(0 < nValue)
172  {
173  if(checkAvailable(1u * nValue, pFieldDescriptor))
174  {
175  Value = llrp_u8v_t(nValue);
176  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
177  {
178  for(unsigned int Ix = 0; Ix < nValue; Ix++)
179  {
180  Value.m_pValue[Ix] = m_pDecoder->next_u8();
181  }
182  }
183  }
184  }
185 
186  return Value;
187 }
188 
189 llrp_s8v_t
190 CFrameDecoderStream::get_s8v (
191  const CFieldDescriptor * pFieldDescriptor)
192 {
193  llrp_u16_t nValue;
194  llrp_s8v_t Value;
195 
196  nValue = getVarlenCount(pFieldDescriptor);
197 
198  if(0 < nValue)
199  {
200  if(checkAvailable(1u * nValue, pFieldDescriptor))
201  {
202  Value = llrp_s8v_t(nValue);
203  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
204  {
205  for(unsigned int Ix = 0; Ix < nValue; Ix++)
206  {
207  Value.m_pValue[Ix] = m_pDecoder->next_u8();
208  }
209  }
210  }
211  }
212 
213  return Value;
214 }
215 
216 llrp_u16_t
217 CFrameDecoderStream::get_u16 (
218  const CFieldDescriptor * pFieldDescriptor)
219 {
220  llrp_u16_t Value;
221 
222  if(checkAvailable(2u, pFieldDescriptor))
223  {
224  Value = m_pDecoder->next_u16();
225  }
226  else
227  {
228  Value = 0;
229  }
230 
231  return Value;
232 }
233 
234 llrp_s16_t
235 CFrameDecoderStream::get_s16 (
236  const CFieldDescriptor * pFieldDescriptor)
237 {
238  llrp_u16_t Value;
239 
240  if(checkAvailable(2u, pFieldDescriptor))
241  {
242  Value = m_pDecoder->next_u16();
243  }
244  else
245  {
246  Value = 0;
247  }
248 
249  return Value;
250 }
251 
252 llrp_u16v_t
253 CFrameDecoderStream::get_u16v (
254  const CFieldDescriptor * pFieldDescriptor)
255 {
256  llrp_u16_t nValue;
257  llrp_u16v_t Value;
258 
259  nValue = getVarlenCount(pFieldDescriptor);
260 
261  if(0 < nValue)
262  {
263  if(checkAvailable(2u * nValue, pFieldDescriptor))
264  {
265  Value = llrp_u16v_t(nValue);
266  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
267  {
268  for(unsigned int Ix = 0; Ix < nValue; Ix++)
269  {
270  Value.m_pValue[Ix] = m_pDecoder->next_u16();
271  }
272  }
273  }
274  }
275 
276  return Value;
277 }
278 
279 llrp_s16v_t
280 CFrameDecoderStream::get_s16v (
281  const CFieldDescriptor * pFieldDescriptor)
282 {
283  llrp_u16_t nValue;
284  llrp_s16v_t Value;
285 
286  nValue = getVarlenCount(pFieldDescriptor);
287 
288  if(0 < nValue)
289  {
290  if(checkAvailable(2u * nValue, pFieldDescriptor))
291  {
292  Value = llrp_s16v_t(nValue);
293  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
294  {
295  for(unsigned int Ix = 0; Ix < nValue; Ix++)
296  {
297  Value.m_pValue[Ix] = m_pDecoder->next_u16();
298  }
299  }
300  }
301  }
302 
303  return Value;
304 }
305 
306 
307 
308 llrp_u32_t
309 CFrameDecoderStream::get_u32 (
310  const CFieldDescriptor * pFieldDescriptor)
311 {
312  llrp_u32_t Value;
313 
314  if(checkAvailable(4u, pFieldDescriptor))
315  {
316  Value = m_pDecoder->next_u32();
317  }
318  else
319  {
320  Value = 0;
321  }
322 
323  return Value;
324 }
325 
326 llrp_s32_t
327 CFrameDecoderStream::get_s32 (
328  const CFieldDescriptor * pFieldDescriptor)
329 {
330  llrp_s32_t Value;
331 
332  if(checkAvailable(4u, pFieldDescriptor))
333  {
334  Value = m_pDecoder->next_u32();
335  }
336  else
337  {
338  Value = 0;
339  }
340 
341  return Value;
342 }
343 
344 llrp_u32v_t
345 CFrameDecoderStream::get_u32v (
346  const CFieldDescriptor * pFieldDescriptor)
347 {
348  llrp_u16_t nValue;
349  llrp_u32v_t Value;
350 
351  nValue = getVarlenCount(pFieldDescriptor);
352 
353  if(0 < nValue)
354  {
355  if(checkAvailable(4u * nValue, pFieldDescriptor))
356  {
357  Value = llrp_u32v_t(nValue);
358  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
359  {
360  for(unsigned int Ix = 0; Ix < nValue; Ix++)
361  {
362  Value.m_pValue[Ix] = m_pDecoder->next_u32();
363  }
364  }
365  }
366  }
367 
368  return Value;
369 }
370 
371 llrp_s32v_t
372 CFrameDecoderStream::get_s32v (
373  const CFieldDescriptor * pFieldDescriptor)
374 {
375  llrp_u16_t nValue;
376  llrp_s32v_t Value;
377 
378  nValue = getVarlenCount(pFieldDescriptor);
379 
380  if(0 < nValue)
381  {
382  if(checkAvailable(4u * nValue, pFieldDescriptor))
383  {
384  Value = llrp_s32v_t(nValue);
385  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
386  {
387  for(unsigned int Ix = 0; Ix < nValue; Ix++)
388  {
389  Value.m_pValue[Ix] = m_pDecoder->next_u32();
390  }
391  }
392  }
393  }
394 
395  return Value;
396 }
397 
398 
399 llrp_u64_t
400 CFrameDecoderStream::get_u64 (
401  const CFieldDescriptor * pFieldDescriptor)
402 {
403  llrp_u64_t Value;
404 
405  if(checkAvailable(8u, pFieldDescriptor))
406  {
407  Value = m_pDecoder->next_u64();
408  }
409  else
410  {
411  Value = 0;
412  }
413 
414  return Value;
415 }
416 
417 llrp_s64_t
418 CFrameDecoderStream::get_s64 (
419  const CFieldDescriptor * pFieldDescriptor)
420 {
421  llrp_s64_t Value;
422 
423  if(checkAvailable(8u, pFieldDescriptor))
424  {
425  Value = m_pDecoder->next_u64();
426  }
427  else
428  {
429  Value = 0;
430  }
431 
432  return Value;
433 }
434 
435 llrp_u64v_t
436 CFrameDecoderStream::get_u64v (
437  const CFieldDescriptor * pFieldDescriptor)
438 {
439  llrp_u16_t nValue;
440  llrp_u64v_t Value;
441 
442  nValue = getVarlenCount(pFieldDescriptor);
443 
444  if(0 < nValue)
445  {
446  if(checkAvailable(8u * nValue, pFieldDescriptor))
447  {
448  Value = llrp_u64v_t(nValue);
449  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
450  {
451  for(unsigned int Ix = 0; Ix < nValue; Ix++)
452  {
453  Value.m_pValue[Ix] = m_pDecoder->next_u64();
454  }
455  }
456  }
457  }
458 
459  return Value;
460 }
461 
462 llrp_s64v_t
463 CFrameDecoderStream::get_s64v (
464  const CFieldDescriptor * pFieldDescriptor)
465 {
466  llrp_u16_t nValue;
467  llrp_s64v_t Value;
468 
469  nValue = getVarlenCount(pFieldDescriptor);
470 
471  if(0 < nValue)
472  {
473  if(checkAvailable(8u * nValue, pFieldDescriptor))
474  {
475  Value = llrp_s64v_t(nValue);
476  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
477  {
478  for(unsigned int Ix = 0; Ix < nValue; Ix++)
479  {
480  Value.m_pValue[Ix] = m_pDecoder->next_u64();
481  }
482  }
483  }
484  }
485 
486  return Value;
487 }
488 
489 llrp_u1_t
490 CFrameDecoderStream::get_u1 (
491  const CFieldDescriptor * pFieldDescriptor)
492 {
493  llrp_u1_t Value;
494 
495  Value = getBitField(1, pFieldDescriptor);
496 
497  return Value;
498 }
499 
500 llrp_u1v_t
501 CFrameDecoderStream::get_u1v (
502  const CFieldDescriptor * pFieldDescriptor)
503 {
504  llrp_u16_t nBit;
505  llrp_u1v_t Value;
506 
507  nBit = getVarlenCount(pFieldDescriptor);
508 
509  if(0 < nBit)
510  {
511  unsigned int nByte = (nBit + 7u) / 8u;
512 
513  if(checkAvailable(nByte, pFieldDescriptor))
514  {
515  Value = llrp_u1v_t(nBit);
516  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
517  {
518  for(unsigned int Ix = 0; Ix < nByte; Ix++)
519  {
520  Value.m_pValue[Ix] = m_pDecoder->next_u8();
521  }
522  }
523  }
524  }
525 
526  return Value;
527 }
528 
529 llrp_u2_t
530 CFrameDecoderStream::get_u2 (
531  const CFieldDescriptor * pFieldDescriptor)
532 {
533  llrp_u2_t Value;
534 
535  Value = getBitField(2, pFieldDescriptor);
536 
537  return Value;
538 }
539 
540 llrp_u96_t
541 CFrameDecoderStream::get_u96 (
542  const CFieldDescriptor * pFieldDescriptor)
543 {
544  llrp_u96_t Value;
545 
546  if(checkAvailable(12u, pFieldDescriptor))
547  {
548  for(unsigned int Ix = 0; Ix < 12u; Ix++)
549  {
550  Value.m_aValue[Ix] = m_pDecoder->next_u8();
551  }
552  }
553 
554  return Value;
555 }
556 
557 llrp_utf8v_t
558 CFrameDecoderStream::get_utf8v (
559  const CFieldDescriptor * pFieldDescriptor)
560 {
561  llrp_u16_t nValue;
562  llrp_utf8v_t Value;
563 
564  nValue = getVarlenCount(pFieldDescriptor);
565 
566  if(0 < nValue)
567  {
568  if(checkAvailable(1u * nValue, pFieldDescriptor))
569  {
570  Value = llrp_utf8v_t(nValue);
571  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
572  {
573  for(unsigned int Ix = 0; Ix < nValue; Ix++)
574  {
575  Value.m_pValue[Ix] = m_pDecoder->next_u8();
576  }
577  }
578  }
579  }
580 
581  return Value;
582 }
583 
584 llrp_bytesToEnd_t
585 CFrameDecoderStream::get_bytesToEnd (
586  const CFieldDescriptor * pFieldDescriptor)
587 {
588  llrp_u16_t nValue;
589  llrp_bytesToEnd_t Value;
590 
591  nValue = getRemainingByteCount();
592 
593  if(0 < nValue)
594  {
595  if(checkAvailable(1u * nValue, pFieldDescriptor))
596  {
597  Value = llrp_bytesToEnd_t(nValue);
598  if(verifyVectorAllocation(Value.m_pValue, pFieldDescriptor))
599  {
600  for(unsigned int Ix = 0; Ix < nValue; Ix++)
601  {
602  Value.m_pValue[Ix] = m_pDecoder->next_u8();
603  }
604  }
605  }
606  }
607 
608  return Value;
609 }
610 
611 int
612 CFrameDecoderStream::get_e1 (
613  const CFieldDescriptor * pFieldDescriptor)
614 {
615  int eValue;
616 
617  eValue = (int)get_u1(pFieldDescriptor);
618 
619  return eValue;
620 }
621 
622 int
623 CFrameDecoderStream::get_e2 (
624  const CFieldDescriptor * pFieldDescriptor)
625 {
626  int eValue;
627 
628  eValue = (int)get_u2(pFieldDescriptor);
629 
630  return eValue;
631 }
632 
633 int
634 CFrameDecoderStream::get_e8 (
635  const CFieldDescriptor * pFieldDescriptor)
636 {
637  int eValue;
638 
639  eValue = (int)get_u8(pFieldDescriptor);
640 
641  return eValue;
642 }
643 
644 int
645 CFrameDecoderStream::get_e16 (
646  const CFieldDescriptor * pFieldDescriptor)
647 {
648  int eValue;
649 
650  eValue = (int)get_u16(pFieldDescriptor);
651 
652  return eValue;
653 }
654 
655 int
656 CFrameDecoderStream::get_e32 (
657  const CFieldDescriptor * pFieldDescriptor)
658 {
659  int eValue;
660 
661  eValue = (int)get_u32(pFieldDescriptor);
662 
663  return eValue;
664 }
665 
666 llrp_u8v_t
667 CFrameDecoderStream::get_e8v (
668  const CFieldDescriptor * pFieldDescriptor)
669 {
670  return get_u8v(pFieldDescriptor);
671 }
672 
673 void
674 CFrameDecoderStream::get_reserved (
675  unsigned int nBit)
676 {
677  CErrorDetails * pError = &m_pDecoder->m_ErrorDetails;
678 
679  if(RC_OK != pError->m_eResultCode)
680  {
681  return;
682  }
683 
684  while(0 < nBit)
685  {
686  unsigned int Step = 7u & nBit;
687 
688  if(0 != m_pDecoder->m_nBitFieldResid)
689  {
690  if(Step != m_pDecoder->m_nBitFieldResid)
691  {
692  pError->m_eResultCode = RC_UnalignedReservedBits;
693  pError->m_pWhatStr = "unaligned reserved bits";
694  pError->m_pRefType = m_pRefType;
695  pError->m_pRefField = NULL;
696  pError->m_OtherDetail = m_pDecoder->m_iNext;
697  return;
698  }
699 
700  nBit -= Step;
701  m_pDecoder->m_nBitFieldResid = 0;
702  }
703  else
704  {
705  if(0 != Step)
706  {
707  pError->m_eResultCode = RC_UnalignedReservedBits;
708  pError->m_pWhatStr = "unaligned reserved bits";
709  pError->m_pRefType = m_pRefType;
710  pError->m_pRefField = NULL;
711  pError->m_OtherDetail = m_pDecoder->m_iNext;
712  return;
713  }
714 
715  if(m_pDecoder->m_iNext >= m_iLimit)
716  {
717  pError->m_eResultCode = RC_ReservedBitsUnderrun;
718  pError->m_pWhatStr = "underrun at reserved bits";
719  pError->m_pRefType = m_pRefType;
720  pError->m_pRefField = NULL;
721  pError->m_OtherDetail = m_pDecoder->m_iNext;
722  return;
723  }
724 
725  m_pDecoder->next_u8();
726  nBit -= 8;
727  }
728  }
729 }
730 
731 CFrameDecoderStream::CFrameDecoderStream (
732  CFrameDecoder * pDecoder)
733 {
734  m_pDecoder = pDecoder;
735  m_pEnclosingDecoderStream = NULL;
736  m_iBegin = pDecoder->m_iNext;
737  m_iLimit = pDecoder->m_nBuffer;
738  m_pRefType = NULL;
739 }
740 
741 CFrameDecoderStream::CFrameDecoderStream (
742  CFrameDecoderStream * pEnclosingDecoderStream)
743 {
744  m_pDecoder = pEnclosingDecoderStream->m_pDecoder;
745  m_pEnclosingDecoderStream = pEnclosingDecoderStream;
746  m_iBegin = m_pDecoder->m_iNext;
747  m_iLimit = pEnclosingDecoderStream->m_iLimit;
748  m_pRefType = NULL;
749 }
750 
751 CMessage *
752 CFrameDecoderStream::getMessage (void)
753 {
754  CErrorDetails * pError = &m_pDecoder->m_ErrorDetails;
755  const CTypeRegistry * pRegistry = m_pDecoder->m_pRegistry;
756  const CTypeDescriptor * pTypeDescriptor = NULL;
757  llrp_u16_t Type;
758  llrp_u16_t Vers;
759  llrp_u32_t nLength;
760  unsigned int iLimit;
761  llrp_u32_t MessageID;
762 
763  if(RC_OK != pError->m_eResultCode)
764  {
765  return NULL;
766  }
767 
768  Type = get_u16(&g_fdMessageHeader_Type);
769  Vers = (Type >> 10) & 3;
770  Type &= 0x3FF;
771 
772  if(RC_OK != pError->m_eResultCode)
773  {
774  return NULL;
775  }
776 
777  if(1u != Vers)
778  {
779  pError->m_eResultCode = RC_BadVersion;
780  pError->m_pWhatStr = "unsupported version";
781  pError->m_pRefType = NULL;
782  pError->m_pRefField = &g_fdMessageHeader_Type;
783  pError->m_OtherDetail = m_pDecoder->m_iNext;
784  return NULL;
785  }
786 
787  nLength = get_u32(&g_fdMessageHeader_Length);
788 
789  if(RC_OK != pError->m_eResultCode)
790  {
791  return NULL;
792  }
793 
794  if(10u > nLength)
795  {
796  pError->m_eResultCode = RC_InvalidLength;
797  pError->m_pWhatStr = "message length too small";
798  pError->m_pRefType = NULL;
799  pError->m_pRefField = &g_fdMessageHeader_Length;
800  pError->m_OtherDetail = m_pDecoder->m_iNext;
801  return NULL;
802  }
803 
804  iLimit = m_iBegin + nLength;
805 
806  if(iLimit > m_iLimit)
807  {
808  pError->m_eResultCode = RC_ExcessiveLength;
809  pError->m_pWhatStr = "message length exceeds enclosing length";
810  pError->m_pRefType = NULL;
811  pError->m_pRefField = &g_fdMessageHeader_Length;
812  pError->m_OtherDetail = m_pDecoder->m_iNext;
813  return NULL;
814  }
815 
816  m_iLimit = iLimit;
817 
818  MessageID = get_u32(&g_fdMessageHeader_MessageID);
819 
820  if(RC_OK != pError->m_eResultCode)
821  {
822  return NULL;
823  }
824 
825  /* Custom? */
826  if(1023u == Type)
827  {
828  llrp_u32_t VendorPEN;
829  llrp_u8_t Subtype;
830 
831  VendorPEN = get_u32(&g_fdMessageHeader_VendorPEN);
832  Subtype = get_u8(&g_fdMessageHeader_Subtype);
833 
834  if(RC_OK != pError->m_eResultCode)
835  {
836  return NULL;
837  }
838 
839  pTypeDescriptor = pRegistry->lookupCustomMessage(VendorPEN, Subtype);
840  if(NULL == pTypeDescriptor)
841  {
842  /*
843  * If we don't have a definition for a particular
844  * CUSTOM message, just use the generic one.
845  */
846  m_pDecoder->m_iNext -= 5; /* back up to VendorPEN and SubType */
847  pTypeDescriptor = pRegistry->lookupMessage(1023u);
848  }
849  }
850  else
851  {
852  pTypeDescriptor = pRegistry->lookupMessage(Type);
853  }
854 
855  if(NULL == pTypeDescriptor)
856  {
857  pError->m_eResultCode = RC_UnknownMessageType;
858  pError->m_pWhatStr = "unknown message type";
859  pError->m_pRefType = NULL;
860  pError->m_pRefField = &g_fdMessageHeader_Type;
861  pError->m_OtherDetail = 0;
862  return NULL;
863  }
864 
865  m_pRefType = pTypeDescriptor;
866 
867  CMessage * pMessage;
868 
869  pMessage = (CMessage *) pTypeDescriptor->constructElement();
870 
871  if(NULL == pMessage)
872  {
873  pError->m_eResultCode = RC_MessageAllocationFailed;
874  pError->m_pWhatStr = "message allocation failed";
875  pError->m_pRefType = pTypeDescriptor;
876  pError->m_pRefField = NULL;
877  pError->m_OtherDetail = m_pDecoder->m_iNext;
878  return NULL;
879  }
880 
881  pMessage->setMessageID(MessageID);
882 
883  pMessage->decodeFields(this);
884 
885  if(RC_OK != pError->m_eResultCode)
886  {
887  delete pMessage;
888  return NULL;
889  }
890 
891  /*
892  * Subparameters
893  */
894  while(0 < getRemainingByteCount() &&
895  RC_OK == pError->m_eResultCode)
896  {
897  CFrameDecoderStream NestStream(this);
898  CParameter * pParameter;
899 
900  pParameter = NestStream.getParameter();
901 
902  if(NULL == pParameter)
903  {
904  if(RC_OK == pError->m_eResultCode)
905  {
906  pError->m_eResultCode = RC_Botch;
907  pError->m_pWhatStr = "botch -- no param and no error";
908  pError->m_pRefType = pTypeDescriptor;
909  pError->m_pRefField = NULL;
910  pError->m_OtherDetail = m_pDecoder->m_iNext;
911  }
912  break;
913  }
914 
915  pParameter->m_pParent = pMessage;
916  pMessage->addSubParameterToAllList(pParameter);
917 
918  }
919 
920  if(RC_OK == pError->m_eResultCode)
921  {
922  if(m_pDecoder->m_iNext != m_iLimit)
923  {
924  pError->m_eResultCode = RC_ExtraBytes;
925  pError->m_pWhatStr = "extra bytes at end of message";
926  pError->m_pRefType = pTypeDescriptor;
927  pError->m_pRefField = NULL;
928  pError->m_OtherDetail = m_pDecoder->m_iNext;
929  }
930  }
931 
932  if(RC_OK != pError->m_eResultCode)
933  {
934  delete pMessage;
935  return NULL;
936  }
937 
938  pMessage->assimilateSubParameters(pError);
939 
940  if(RC_OK != pError->m_eResultCode)
941  {
942  delete pMessage;
943  return NULL;
944  }
945 
946  return pMessage;
947 }
948 
949 CParameter *
950 CFrameDecoderStream::getParameter (void)
951 {
952  CErrorDetails * pError = &m_pDecoder->m_ErrorDetails;
953  const CTypeRegistry * pRegistry = m_pDecoder->m_pRegistry;
954  const CTypeDescriptor * pTypeDescriptor = NULL;
955  llrp_u16_t Type;
956  bool bIsTV;
957 
958  if(RC_OK != pError->m_eResultCode)
959  {
960  return NULL;
961  }
962 
963  Type = get_u8(&g_fdParameterHeader_TVType);
964 
965  if(RC_OK != pError->m_eResultCode)
966  {
967  return NULL;
968  }
969 
970  if(0 != (Type&0x80))
971  {
972  /*
973  * Type-Value (TV).
974  * All we can do is inherit the length from
975  * the enclosing element.
976  */
977  Type &= 0x7F;
978  bIsTV = TRUE;
979  }
980  else
981  {
982  /*
983  * Type-Length-Value (TLV).
984  * Back up and get the real type number,
985  * then get the length.
986  */
987  m_pDecoder->m_iNext--;
988  Type = get_u16(&g_fdParameterHeader_TLVType);
989  Type &= 0x3FF;
990 
991  if(RC_OK != pError->m_eResultCode)
992  {
993  return NULL;
994  }
995 
996  llrp_u16_t nLength;
997 
998  nLength = get_u16(&g_fdParameterHeader_TLVLength);
999 
1000  if(RC_OK != pError->m_eResultCode)
1001  {
1002  return NULL;
1003  }
1004 
1005  if(4u > nLength)
1006  {
1007  pError->m_eResultCode = RC_InvalidLength;
1008  pError->m_pWhatStr = "TLV parameter length too small";
1009  pError->m_pRefType = NULL;
1010  pError->m_pRefField = &g_fdParameterHeader_TLVLength;
1011  pError->m_OtherDetail = m_pDecoder->m_iNext;
1012  return NULL;
1013  }
1014 
1015  unsigned int iLimit;
1016 
1017  iLimit = m_iBegin + nLength;
1018 
1019  if(iLimit > m_iLimit)
1020  {
1021  pError->m_eResultCode = RC_ExcessiveLength;
1022  pError->m_pWhatStr =
1023  "TLV parameter length exceeds enclosing length";
1024  pError->m_pRefType = NULL;
1025  pError->m_pRefField = &g_fdParameterHeader_TLVLength;
1026  pError->m_OtherDetail = m_pDecoder->m_iNext;
1027  return NULL;
1028  }
1029 
1030  m_iLimit = iLimit;
1031 
1032  bIsTV = FALSE;
1033  }
1034 
1035  /* Custom? */
1036  if(1023u == Type)
1037  {
1038  llrp_u32_t VendorPEN;
1039  llrp_u32_t Subtype;
1040 
1041  VendorPEN = get_u32(&g_fdParameterHeader_VendorPEN);
1042  Subtype = get_u32(&g_fdParameterHeader_Subtype);
1043 
1044  if(RC_OK != pError->m_eResultCode)
1045  {
1046  return NULL;
1047  }
1048 
1049  pTypeDescriptor = pRegistry->lookupCustomParameter(VendorPEN, Subtype);
1050  if(NULL == pTypeDescriptor)
1051  {
1052  /*
1053  * If we don't have a definition for a particular
1054  * CUSTOM message, just use the generic one.
1055  */
1056  m_pDecoder->m_iNext -= 8; /* back up to VendorPEN and SubType */
1057  pTypeDescriptor = pRegistry->lookupParameter(1023u);
1058  }
1059  }
1060  else
1061  {
1062  pTypeDescriptor = pRegistry->lookupParameter(Type);
1063  }
1064 
1065  if(NULL == pTypeDescriptor)
1066  {
1067  pError->m_eResultCode = RC_UnknownParameterType;
1068  pError->m_pWhatStr = "unknown parameter type";
1069  pError->m_pRefType = NULL;
1070  if(bIsTV)
1071  {
1072  pError->m_pRefField = &g_fdParameterHeader_TVType;
1073  }
1074  else
1075  {
1076  pError->m_pRefField = &g_fdParameterHeader_TLVType;
1077  }
1078  pError->m_OtherDetail = m_pDecoder->m_iNext;
1079  return NULL;
1080  }
1081 
1082  m_pRefType = pTypeDescriptor;
1083 
1084  CParameter * pParameter;
1085 
1086  pParameter = (CParameter *) pTypeDescriptor->constructElement();
1087 
1088  if(NULL == pParameter)
1089  {
1090  pError->m_eResultCode = RC_ParameterAllocationFailed;
1091  pError->m_pWhatStr = "parameter allocation failed";
1092  pError->m_pRefType = pTypeDescriptor;
1093  pError->m_pRefField = NULL;
1094  pError->m_OtherDetail = m_pDecoder->m_iNext;
1095  return NULL;
1096  }
1097 
1098  pParameter->decodeFields(this);
1099 
1100  if(RC_OK != pError->m_eResultCode)
1101  {
1102  delete pParameter;
1103  return NULL;
1104  }
1105 
1106  if(!bIsTV)
1107  {
1108  /*
1109  * Subparameters
1110  */
1111  while(0 < getRemainingByteCount() &&
1112  RC_OK == pError->m_eResultCode)
1113  {
1114  CFrameDecoderStream NestStream(this);
1115  CParameter * pSubParameter;
1116 
1117  pSubParameter = NestStream.getParameter();
1118 
1119  if(NULL == pSubParameter)
1120  {
1121  if(RC_OK == pError->m_eResultCode)
1122  {
1123  pError->m_eResultCode = RC_Botch;
1124  pError->m_pWhatStr = "botch -- no param and no error";
1125  pError->m_pRefType = pTypeDescriptor;
1126  pError->m_pRefField = NULL;
1127  pError->m_OtherDetail = m_pDecoder->m_iNext;
1128  }
1129  break;
1130  }
1131 
1132  pSubParameter->m_pParent = pParameter;
1133  pParameter->addSubParameterToAllList(pSubParameter);
1134  }
1135 
1136  if(RC_OK == pError->m_eResultCode)
1137  {
1138  if(m_pDecoder->m_iNext != m_iLimit)
1139  {
1140  pError->m_eResultCode = RC_ExtraBytes;
1141  pError->m_pWhatStr = "extra bytes at end of TLV parameter";
1142  pError->m_pRefType = pTypeDescriptor;
1143  pError->m_pRefField = NULL;
1144  pError->m_OtherDetail = m_pDecoder->m_iNext;
1145  }
1146  }
1147 
1148  if(RC_OK != pError->m_eResultCode)
1149  {
1150  delete pParameter;
1151  return NULL;
1152  }
1153 
1154  pParameter->assimilateSubParameters(pError);
1155 
1156  if(RC_OK != pError->m_eResultCode)
1157  {
1158  delete pParameter;
1159  return NULL;
1160  }
1161  }
1162 
1163  return pParameter;
1164 }
1165 
1166 unsigned int
1167 CFrameDecoderStream::getRemainingByteCount (void)
1168 {
1169  if(m_pDecoder->m_iNext < m_iLimit)
1170  {
1171  return m_iLimit - m_pDecoder->m_iNext;
1172  }
1173  else
1174  {
1175  return 0;
1176  }
1177 }
1178 
1179 llrp_bool_t
1180 CFrameDecoderStream::checkAvailable (
1181  unsigned int nByte,
1182  const CFieldDescriptor * pFieldDescriptor)
1183 {
1184  CErrorDetails * pError = &m_pDecoder->m_ErrorDetails;
1185 
1186  if(RC_OK != pError->m_eResultCode)
1187  {
1188  return FALSE;
1189  }
1190 
1191  if(m_pDecoder->m_iNext + nByte > m_iLimit)
1192  {
1193  pError->m_eResultCode = RC_FieldUnderrun;
1194  pError->m_pWhatStr = "underrun at field";
1195  pError->m_pRefType = m_pRefType;
1196  pError->m_pRefField = pFieldDescriptor;
1197  pError->m_OtherDetail = m_pDecoder->m_iNext;
1198  return FALSE;
1199  }
1200 
1201  if(0 != m_pDecoder->m_nBitFieldResid)
1202  {
1203  pError->m_eResultCode = RC_UnalignedBitField;
1204  pError->m_pWhatStr = "unaligned/incomplete bit field";
1205  pError->m_pRefType = m_pRefType;
1206  pError->m_pRefField = pFieldDescriptor;
1207  pError->m_OtherDetail = m_pDecoder->m_iNext;
1208  return FALSE;
1209  }
1210 
1211  return TRUE;
1212 }
1213 
1214 unsigned int
1215 CFrameDecoderStream::getBitField (
1216  unsigned int nBit,
1217  const CFieldDescriptor * pFieldDescriptor)
1218 {
1219  CErrorDetails * pError = &m_pDecoder->m_ErrorDetails;
1220  unsigned int Value;
1221 
1222  if(0 == m_pDecoder->m_nBitFieldResid)
1223  {
1224  if(checkAvailable(1u, pFieldDescriptor))
1225  {
1226  m_pDecoder->m_BitFieldBuffer = m_pDecoder->next_u8();
1227  m_pDecoder->m_nBitFieldResid = 8u;
1228  }
1229  else
1230  {
1231  return 0;
1232  }
1233  }
1234 
1235  if(m_pDecoder->m_nBitFieldResid < nBit)
1236  {
1237  pError->m_eResultCode = RC_UnalignedBitField;
1238  pError->m_pWhatStr = "unaligned/incomplete bit field";
1239  pError->m_pRefType = m_pRefType;
1240  pError->m_pRefField = pFieldDescriptor;
1241  pError->m_OtherDetail = m_pDecoder->m_iNext;
1242  return 0;
1243  }
1244 
1245  m_pDecoder->m_nBitFieldResid -= nBit;
1246 
1247  Value = m_pDecoder->m_BitFieldBuffer >> m_pDecoder->m_nBitFieldResid;
1248  Value &= (1u << nBit) - 1u;
1249 
1250  return Value;
1251 }
1252 
1253 llrp_u16_t
1254 CFrameDecoderStream::getVarlenCount (
1255  const CFieldDescriptor * pFieldDescriptor)
1256 {
1257  llrp_u16_t nValue;
1258 
1259  if(checkAvailable(2u, pFieldDescriptor))
1260  {
1261  nValue = m_pDecoder->next_u16();
1262  }
1263  else
1264  {
1265  nValue = 0;
1266  }
1267 
1268  return nValue;
1269 }
1270 
1271 llrp_bool_t
1272 CFrameDecoderStream::verifyVectorAllocation (
1273  const void * pValue,
1274  const CFieldDescriptor * pFieldDescriptor)
1275 {
1276  if(NULL == pValue)
1277  {
1278  CErrorDetails * pError = &m_pDecoder->m_ErrorDetails;
1279 
1280  pError->m_eResultCode = RC_FieldAllocationFailed;
1281  pError->m_pWhatStr = "field allocation failed";
1282  pError->m_pRefType = m_pRefType;
1283  pError->m_pRefField = pFieldDescriptor;
1284  pError->m_OtherDetail = m_pDecoder->m_iNext;
1285 
1286  return FALSE;
1287  }
1288  else
1289  {
1290  return TRUE;
1291  }
1292 }
1293 
1294 }; /* namespace LLRP */
CElement * constructElement(void) const
Convenience function.
Definition: ltkcpp_base.h:794
const CTypeDescriptor * m_pRefType
If non-NULL this is the type descriptors for the errored type.
Definition: ltkcpp_base.h:639
Based type descriptions for the LTKCPP library.
Classes to encode and decod LLRP binary frames.
Based types for the LKTCPP library.
CErrorDetails(void)
Default Constructor.
Definition: ltkcpp.h:45