8b22fb92549f845ab46d60b9a1cc455492d075ea
[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   static int
61   compute_codeword(const expanded_header &h)
62   {
63     int cw = 0;
64     if (h.stream_id_p())       cw |= HAS_STREAM_ID;
65     if (h.class_id_p())        cw |= HAS_CLASS_ID;
66     if (h.integer_secs_p())    cw |= HAS_INTEGER_SECS;
67     if (h.fractional_secs_p()) cw |= HAS_FRACTIONAL_SECS;
68     if (h.trailer_p())         cw |= HAS_TRAILER;
69     return cw;
70   }
71
72   void expanded_header::unparse(const expanded_header *h,   // in
73                         size_t n32_bit_words_payload,  // in
74                         uint32_t *header,              // out
75                         size_t *n32_bit_words_header,  // out
76                         uint32_t *trailer,             // out
77                         size_t *n32_bit_words_trailer){// out
78     int cw = compute_codeword(*h);
79     //fills in the header (except word0), header length, trailer, trailer length
80     switch (cw & 0x1f){
81 #include "expanded_header_unparse_switch_body.h"
82     }
83     //fill in the header word 0 with the calculated length
84     size_t n32_bit_words_packet = *n32_bit_words_header + n32_bit_words_payload + *n32_bit_words_trailer;
85     header[0] = htonl((h->header & ~VRTH_PKT_SIZE_MASK) | (n32_bit_words_packet & VRTH_PKT_SIZE_MASK));
86   }
87
88   bool 
89   expanded_header::parse(const uint32_t *packet,        // in
90                         size_t n32_bit_words_packet,    // in
91                         expanded_header *h,             // out
92                         const uint32_t **payload,       // out
93                         size_t *n32_bit_words_payload)  // out
94   {
95     size_t n32_bit_words_header = 0;
96     size_t n32_bit_words_trailer = 0;
97     size_t len = n32_bit_words_packet;
98     const uint32_t *p = packet;
99
100     *payload = 0;
101     *n32_bit_words_payload = 0;
102
103     // printf("parse: n32_bit_words_packet = %zd\n", n32_bit_words_packet);
104
105     if (len < 1){               // must have at least the header word
106       h->header = 0;
107       return false;
108     }
109
110     h->header = ntohl(p[0]);
111
112     if (h->pkt_size() > len)
113       return false;             // VRT header says packet is bigger than what we've got
114
115     len = h->pkt_size();        // valid length of packet
116
117     int cw = compute_codeword(*h);
118     switch (cw & 0x1f){
119 #include "expanded_header_parse_switch_body.h"
120     }
121
122     if (n32_bit_words_header + n32_bit_words_trailer > len)
123       return false;             // negative payload len
124
125     *payload = p + n32_bit_words_header;
126     *n32_bit_words_payload = len - (n32_bit_words_header + n32_bit_words_trailer);
127
128     // printf("parse: hdr = 0x%08x, cw = 0x%02x, n32_bit_words_header = %d, n32_bit_words_trailer = %d\n",
129     //   h->header, cw, n32_bit_words_header, n32_bit_words_trailer);
130
131     return true;
132   }
133
134
135 }; // vrt