Merged eb/usrp-la r6317:6320 into trunk. This deborks the dependency
[debian/gnuradio] / usrp / host / apps-inband / test_usrp_inband_rx.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2007 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
26 #include <mb_mblock.h>
27 #include <mb_runtime.h>
28 #include <mb_runtime_nop.h>             // QA only
29 #include <mb_protocol_class.h>
30 #include <mb_exception.h>
31 #include <mb_msg_queue.h>
32 #include <mb_message.h>
33 #include <mb_mblock_impl.h>
34 #include <mb_msg_accepter.h>
35 #include <mb_class_registry.h>
36 #include <pmt.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <iostream>
40 #include <fstream>
41
42 // Signal set for the USRP server
43 static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
44 static pmt_t s_cmd_close = pmt_intern("cmd-close");
45 static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel");
46 static pmt_t s_cmd_open = pmt_intern("cmd-open");
47 static pmt_t s_cmd_start_recv_raw_samples = pmt_intern("cmd-start-recv-raw-samples");
48 static pmt_t s_cmd_stop_recv_raw_samples = pmt_intern("cmd-stop-recv-raw-samples");
49 static pmt_t s_cmd_to_control_channel = pmt_intern("cmd-to-control-channel");
50 static pmt_t s_cmd_xmit_raw_frame  = pmt_intern("cmd-xmit-raw-frame");
51 static pmt_t s_cmd_max_capacity  = pmt_intern("cmd-max-capacity");
52 static pmt_t s_cmd_ntx_chan  = pmt_intern("cmd-ntx-chan");
53 static pmt_t s_cmd_nrx_chan  = pmt_intern("cmd-nrx-chan");
54 static pmt_t s_cmd_current_capacity_allocation  = pmt_intern("cmd-current-capacity-allocation");
55 static pmt_t s_response_allocate_channel = pmt_intern("response-allocate-channel");
56 static pmt_t s_response_close = pmt_intern("response-close");
57 static pmt_t s_response_deallocate_channel = pmt_intern("response-deallocate-channel");
58 static pmt_t s_response_from_control_channel = pmt_intern("response-from-control-channel");
59 static pmt_t s_response_open = pmt_intern("response-open");
60 static pmt_t s_response_recv_raw_samples = pmt_intern("response-recv-raw-samples");
61 static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
62 static pmt_t s_response_max_capacity = pmt_intern("response-max-capacity");
63 static pmt_t s_response_ntx_chan = pmt_intern("response-ntx-chan");
64 static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan");
65 static pmt_t s_response_current_capacity_allocation  = pmt_intern("response-current-capacity-allocation");
66
67 static bool verbose = false;
68
69 class test_usrp_rx : public mb_mblock
70 {
71   mb_port_sptr  d_rx;
72   mb_port_sptr  d_cs;
73   pmt_t         d_rx_chan;      // returned tx channel handle
74
75   bool d_disk_write;
76
77   enum state_t {
78     INIT,
79     OPENING_USRP,
80     ALLOCATING_CHANNEL,
81     RECEIVING,
82     CLOSING_CHANNEL,
83     CLOSING_USRP,
84   };
85
86   state_t       d_state;
87
88   std::ofstream d_ofile;
89
90  public:
91   test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
92   ~test_usrp_rx();
93   void initial_transition();
94   void handle_message(mb_message_sptr msg);
95
96  protected:
97   void open_usrp();
98   void close_usrp();
99   void allocate_channel();
100   void send_packets();
101   void enter_receiving();
102   void build_and_send_next_frame();
103   void handle_response_recv_raw_samples(pmt_t invocation_handle);
104   void enter_closing_channel();
105 };
106
107 test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
108   : mb_mblock(runtime, instance_name, user_arg),
109   d_disk_write(false)
110
111   
112   d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
113   d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
114   
115   //bool fake_usrp_p = true;
116   bool fake_usrp_p = false;
117   
118   d_disk_write = true;
119
120   // Test the TX side
121
122   // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP
123   pmt_t usrp_dict = pmt_make_dict();
124
125   if(fake_usrp_p)
126     pmt_dict_set(usrp_dict, 
127                  pmt_intern("fake-usrp"),
128                              PMT_T);
129   
130   // Specify the RBF to use
131   pmt_dict_set(usrp_dict,
132                pmt_intern("rbf"),
133                pmt_intern("tmac6.rbf"));
134
135   // Set TX and RX interpolations
136   pmt_dict_set(usrp_dict,
137                pmt_intern("interp-tx"),
138                pmt_from_long(128));
139
140   pmt_dict_set(usrp_dict,
141                pmt_intern("interp-rx"),
142                pmt_from_long(16));
143
144   define_component("server", "usrp_server", usrp_dict);
145
146   connect("self", "rx0", "server", "rx0");
147   connect("self", "cs", "server", "cs");
148
149   if(d_disk_write)
150     d_ofile.open("pdump_rx.dat",std::ios::binary|std::ios::out);
151 }
152
153 test_usrp_rx::~test_usrp_rx()
154 {
155   if(d_disk_write)
156     d_ofile.close();
157 }
158
159 void
160 test_usrp_rx::initial_transition()
161 {
162   open_usrp();
163 }
164
165 void
166 test_usrp_rx::handle_message(mb_message_sptr msg)
167 {
168   pmt_t event = msg->signal();
169   pmt_t data = msg->data();
170
171   pmt_t handle = PMT_F;
172   pmt_t status = PMT_F;
173   std::string error_msg;
174   
175   switch(d_state){
176   case OPENING_USRP:
177     if (pmt_eq(event, s_response_open)){
178       status = pmt_nth(1, data);
179       if (pmt_eq(status, PMT_T)){
180         allocate_channel();
181         return;
182       }
183       else {
184         error_msg = "failed to open usrp:";
185         goto bail;
186       }
187     }
188     goto unhandled;
189     
190   case ALLOCATING_CHANNEL:
191     if (pmt_eq(event, s_response_allocate_channel)){
192       status = pmt_nth(1, data);
193       d_rx_chan = pmt_nth(2, data);
194
195       if (pmt_eq(status, PMT_T)){
196         enter_receiving();
197         return;
198       }
199       else {
200         error_msg = "failed to allocate channel:";
201         goto bail;
202       }
203     }
204     goto unhandled;
205
206   case RECEIVING:
207     if (pmt_eq(event, s_response_recv_raw_samples)){
208       status = pmt_nth(1, data);
209
210       if (pmt_eq(status, PMT_T)){
211         handle_response_recv_raw_samples(data);
212         return;
213       }
214       else {
215         error_msg = "bad response-xmit-raw-frame:";
216         goto bail;
217       }
218     }
219     goto unhandled;
220
221   case CLOSING_CHANNEL:
222     if (pmt_eq(event, s_response_deallocate_channel)){
223       status = pmt_nth(1, data);
224
225       if (pmt_eq(status, PMT_T)){
226         close_usrp();
227         return;
228       }
229       else {
230         error_msg = "failed to deallocate channel:";
231         goto bail;
232       }
233     }
234     goto unhandled;
235
236   case CLOSING_USRP:
237     if (pmt_eq(event, s_response_close)){
238       status = pmt_nth(1, data);
239
240       if (pmt_eq(status, PMT_T)){
241         shutdown_all(PMT_T);
242         return;
243       }
244       else {
245         error_msg = "failed to close USRP:";
246         goto bail;
247       }
248     }
249     goto unhandled;
250
251   default:
252     goto unhandled;
253   }
254   return;
255
256  bail:
257   std::cerr << error_msg << data
258             << "status = " << status << std::endl;
259   shutdown_all(PMT_F);
260   return;
261
262  unhandled:
263   std::cout << "test_usrp_inband_rx: unhandled msg: " << msg
264             << "in state "<< d_state << std::endl;
265 }
266
267
268 void
269 test_usrp_rx::open_usrp()
270 {
271   pmt_t which_usrp = pmt_from_long(0);
272
273   d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
274   d_state = OPENING_USRP;
275 }
276
277 void
278 test_usrp_rx::close_usrp()
279 {
280   d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
281   d_state = CLOSING_USRP;
282 }
283
284 void
285 test_usrp_rx::allocate_channel()
286 {
287   long capacity = (long) 16e6;
288   d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
289   d_state = ALLOCATING_CHANNEL;
290 }
291
292 void
293 test_usrp_rx::enter_receiving()
294 {
295   d_state = RECEIVING;
296
297   d_rx->send(s_cmd_start_recv_raw_samples,
298              pmt_list2(PMT_F,
299                        d_rx_chan));
300 }
301
302 void
303 test_usrp_rx::handle_response_recv_raw_samples(pmt_t data)
304 {
305   pmt_t invocation_handle = pmt_nth(0, data);
306   pmt_t status = pmt_nth(1, data);
307   pmt_t v_samples = pmt_nth(2, data);
308   pmt_t timestamp = pmt_nth(3, data);
309   pmt_t properties = pmt_nth(4, data);
310
311   size_t n_bytes;
312   
313   const char *samples = (const char *) pmt_uniform_vector_elements(v_samples, n_bytes);
314
315   if(d_disk_write)
316     d_ofile.write(samples, n_bytes);
317
318   if(verbose)
319     std::cout << ".";
320
321   if (pmt_is_dict(properties)) {
322     // Read the RSSI
323     if(pmt_t rssi = pmt_dict_ref(properties, 
324                                  pmt_intern("rssi"), 
325                                  PMT_NIL)) {
326       if(!pmt_eqv(rssi, PMT_NIL)) 
327         std::cout << "RSSI: " << rssi << std::endl;
328     }
329   }
330   
331
332 }
333
334 void
335 test_usrp_rx::enter_closing_channel()
336 {
337   d_state = CLOSING_CHANNEL;
338   
339   d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
340 }
341
342 REGISTER_MBLOCK_CLASS(test_usrp_rx);
343
344
345 // ----------------------------------------------------------------
346
347 int
348 main (int argc, char **argv)
349 {
350   // handle any command line args here
351
352   mb_runtime_sptr rt = mb_make_runtime();
353   pmt_t result = PMT_NIL;
354
355   rt->run("top", "test_usrp_rx", PMT_F, &result);
356 }