Merged r11377:11390 from jcorgan/usrp-headers in to trunk.
[debian/gnuradio] / usrp / limbo / inband / usb_packet.py
1 #
2 # Copyright 2007 Free Software Foundation, Inc.
3
4 # This file is part of GNU Radio
5
6 # GNU Radio is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3, or (at your option)
9 # any later version.
10
11 # GNU Radio is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License along
17 # with this program; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #
20
21 import struct
22
23
24 FL_OVERRUN        = 0x80000000
25 FL_UNDERRUN       = 0x40000000
26 FL_DROPPED        = 0x20000000
27 FL_END_OF_BURST   = 0x10000000
28 FL_START_OF_BURST = 0x08000000
29
30 FL_ALL_FLAGS      = 0xf8000000
31
32 FL_OVERRUN_SHIFT = 31
33 FL_UNDERRUN_SHIFT = 30
34 FL_DROPPED_SHIFT = 29
35 FL_END_OF_BURST_SHIFT = 28
36 FL_START_OF_BURST_SHIFT = 27
37   
38 RSSI_MASK = 0x3f
39 RSSI_SHIFT = 21
40
41 CHAN_MASK = 0x1f
42 CHAN_SHIFT = 16
43
44 TAG_MASK = 0xf
45 TAG_SHIFT = 9
46
47 PAYLOAD_LEN_MASK = 0x1ff
48 PAYLOAD_LEN_SHIFT = 0
49
50 def make_header(flags, chan, payload_len, timestamp, rssi=0, tag=0):
51     word0 =  ((flags & FL_ALL_FLAGS)
52               | ((rssi & RSSI_MASK) << RSSI_SHIFT)
53               | ((chan & CHAN_MASK) << CHAN_SHIFT)
54               | ((tag & TAG_MASK) << TAG_SHIFT)
55               | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT))
56     word1 = timestamp
57     return struct.pack('<2I', word0, word1)
58
59
60 def _decode(pred, indicator):
61     if pred:
62         return indicator
63     else:
64         return '-'
65
66
67 class usb_packet(object):
68     def __init__(self, raw_pkt):
69         assert isinstance(raw_pkt, str) and len(raw_pkt) == 512
70         self._raw_pkt = raw_pkt;
71         (self._word0, self._word1) = struct.unpack('<2I', self._raw_pkt[0:8])
72
73     def timestamp(self):
74         return self._word1
75
76     def rssi(self):
77         return (self._word0 >> RSSI_SHIFT) & RSSI_MASK
78
79     def chan(self):
80         return (self._word0 >> CHAN_SHIFT) & CHAN_MASK
81
82     def tag(self):
83         return (self._word0 >> TAG_SHIFT) & TAG_MASK
84
85     def payload_len(self):
86         return (self._word0 >> PAYLOAD_LEN_SHIFT) & PAYLOAD_LEN_MASK
87
88     def flags(self):
89         return self._word0 & FL_ALL_FLAGS
90
91     def overrun(self):
92         return (self._word0 >> FL_OVERRUN_SHIFT) & 0x1
93
94     def underrun(self):
95         return (self._word0 >> FL_UNDERRUN_SHIFT) & 0x1
96
97     def start_of_burst(self):
98         return (self._word0 >> FL_START_OF_BURST_SHIFT) & 0x1
99
100     def end_of_burst(self):
101         return (self._word0 >> FL_END_OF_BURST_SHIFT) & 0x1
102
103     def dropped(self):
104         return (self._word0 >> FL_DROPPED_SHIFT) & 0x1
105
106     def payload(self):
107         return self._raw_pkt[8:8+self.payload_len()]
108
109     def decoded_flags(self):
110         s = (_decode(self.overrun(), 'O')
111              + _decode(self.underrun(), 'U')
112              + _decode(self.dropped(), 'D')
113              + _decode(self.end_of_burst(), 'E')
114              + _decode(self.start_of_burst(), 'S'))
115         return s