0eb2042d8f33796096e645db3f44b1e8504bdd18
[debian/gnuradio] / vrt / lib / expanded_header.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2009 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <vrt/expanded_header.h>
26 #include <gruel/inet.h>
27 //#include <stdio.h>
28
29 namespace vrt {
30
31   // lookup tables indexed by packet type
32   unsigned char expanded_header::s_if_data[16] = {
33     1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
34   };
35
36   unsigned char expanded_header::s_ext_data[16] = {
37     0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
38   };
39
40   unsigned char expanded_header::s_data[16] = {
41     1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
42   };
43
44   unsigned char expanded_header::s_context[16] = {
45     0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
46   };
47
48   unsigned char expanded_header::s_stream_id[16] = {
49     0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
50   };
51
52
53   // dispatch codeword bits
54   static const int HAS_STREAM_ID       = 1 << 0;
55   static const int HAS_CLASS_ID        = 1 << 1;
56   static const int HAS_INTEGER_SECS    = 1 << 2;
57   static const int HAS_FRACTIONAL_SECS = 1 << 3;
58   static const int HAS_TRAILER         = 1 << 4;
59
60 #include "expanded_header_cw_tables.h"
61
62   static int
63   compute_codeword(const expanded_header &h)
64   {
65     int cw = 0;
66     if (h.stream_id_p())       cw |= HAS_STREAM_ID;
67     if (h.class_id_p())        cw |= HAS_CLASS_ID;
68     if (h.integer_secs_p())    cw |= HAS_INTEGER_SECS;
69     if (h.fractional_secs_p()) cw |= HAS_FRACTIONAL_SECS;
70     if (h.trailer_p())         cw |= HAS_TRAILER;
71     return cw;
72   }
73
74   bool 
75   expanded_header::parse(const uint32_t *packet,        // in
76                         size_t n32_bit_words_packet,    // in
77                         expanded_header *h,             // out
78                         const uint32_t **payload,       // out
79                         size_t *n32_bit_words_payload)  // out
80   {
81     size_t len = n32_bit_words_packet;
82     const uint32_t *p = packet;
83
84     *payload = 0;
85     *n32_bit_words_payload = 0;
86
87     // printf("parse: n32_bit_words_packet = %zd\n", n32_bit_words_packet);
88
89     if (len < 1){               // must have at least the header word
90       h->header = 0;
91       return false;
92     }
93
94     h->header = ntohl(p[0]);
95
96     if (h->pkt_size() > len)
97       return false;             // VRT header says packet is bigger than what we've got
98
99     len = h->pkt_size();        // valid length of packet
100
101     int cw = compute_codeword(*h);
102     if (cw_header_len(cw) + cw_trailer_len(cw) > len)
103       return false;             // negative payload len
104
105     *payload = p + cw_header_len(cw);
106     *n32_bit_words_payload = len - (cw_header_len(cw) + cw_trailer_len(cw));
107
108     // printf("parse: hdr = 0x%08x, cw = 0x%02x, cw_header_len(cw) = %d, cw_trailer_len(cw) = %d\n",
109     //   h->header, cw, cw_header_len(cw), cw_trailer_len(cw));
110
111     switch (cw & 0x1f){
112 #include "expanded_header_switch_body.h"
113     }
114
115     /* is this a if context packet? */
116     if (h->if_context_p()){
117         *payload = p;
118         *n32_bit_words_payload = n32_bit_words_packet;
119     }
120
121     return true;
122   }
123
124
125 }; // vrt