3 * Copyright 2007,2008 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
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)
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.
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.
26 #include <usrp_inband_usb_packet.h>
27 #include <qa_inband_usrp_server.h>
28 #include <cppunit/TestAssert.h>
30 #include <usrp_server.h>
31 #include <mblock/mblock.h>
32 #include <mblock/runtime.h>
33 #include <mblock/protocol_class.h>
34 #include <mblock/class_registry.h>
39 #include <symbols_usrp_server_cs.h>
40 #include <symbols_usrp_tx.h>
41 #include <symbols_usrp_rx.h>
42 #include <symbols_usrp_channel.h>
43 #include <symbols_usrp_low_level_cs.h>
45 typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit easy
47 static bool verbose = false;
49 static pmt_t s_timeout = pmt_intern("%timeout");
51 // ----------------------------------------------------------------------------------------------
53 class qa_alloc_top : public mb_mblock
63 long d_ntx_chan, d_nrx_chan;
66 long d_nstatus_to_recv;
69 qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
71 void initial_transition();
72 void handle_message(mb_message_sptr msg);
75 void check_message(mb_message_sptr msg);
79 qa_alloc_top::qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
80 : mb_mblock(runtime, instance_name, user_arg)
85 d_nstatus_to_recv = 50;
87 d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
88 d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
89 d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
91 // Use the stub with the usrp_server
92 pmt_t usrp_server_dict = pmt_make_dict();
93 pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
96 define_component("server", "usrp_server", usrp_server_dict);
97 connect("self", "tx0", "server", "tx0");
98 connect("self", "rx0", "server", "rx0");
99 connect("self", "cs", "server", "cs");
103 qa_alloc_top::~qa_alloc_top(){}
106 qa_alloc_top::initial_transition()
108 // Allocations should fail before open
109 d_tx->send(s_cmd_allocate_channel,
110 pmt_list2(pmt_list2(s_response_allocate_channel,
111 s_err_usrp_not_opened),
114 d_rx->send(s_cmd_allocate_channel,
115 pmt_list2(pmt_list2(s_response_allocate_channel,
116 s_err_usrp_not_opened),
119 // Retrieve information about the USRP, then run tests
120 d_cs->send(s_cmd_open,
121 pmt_list2(pmt_list2(s_response_open, PMT_T),
124 d_cs->send(s_cmd_max_capacity,
125 pmt_list1(pmt_list2(s_response_max_capacity, PMT_T)));
127 d_cs->send(s_cmd_ntx_chan,
128 pmt_list1(pmt_list2(s_response_ntx_chan, PMT_T)));
130 d_cs->send(s_cmd_nrx_chan,
131 pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T)));
135 qa_alloc_top::run_tests()
138 std::cout << "[qa_alloc_top] Starting tests...\n";
140 // should be able to allocate 1 byte
141 d_tx->send(s_cmd_allocate_channel,
142 pmt_list2(PMT_T, pmt_from_long(1)));
144 // should not be able to allocate max capacity after 100 bytes were allocated
145 d_tx->send(s_cmd_allocate_channel,
146 pmt_list2(s_err_requested_capacity_unavailable,
147 pmt_from_long(d_max_capacity)));
149 // keep allocating a little more until all of the channels are used and test
150 // the error response we start at 1 since we've already allocated 1 channel
151 for(int i=1; i < d_ntx_chan; i++) {
154 std::cout << "[qa_alloc_top] Sent allocation request...\n";
156 d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
161 // No more channels after allocating all of them is expected
162 d_tx->send(s_cmd_allocate_channel,
163 pmt_list2(s_err_channel_unavailable,
166 // test out the same on the RX side
167 d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
169 d_rx->send(s_cmd_allocate_channel,
170 pmt_list2(s_err_requested_capacity_unavailable,
171 pmt_from_long(d_max_capacity)));
173 for(int i=1; i < d_nrx_chan; i++) {
175 d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
180 d_rx->send(s_cmd_allocate_channel,
181 pmt_list2(s_err_channel_unavailable,
184 // when all is said and done, there should be d_ntx_chan+d_ntx_chan bytes
186 d_cs->send(s_cmd_current_capacity_allocation,
187 pmt_list1(pmt_from_long(d_ntx_chan+d_nrx_chan)));
191 qa_alloc_top::handle_message(mb_message_sptr msg)
193 pmt_t data = msg->data();
195 if ((pmt_eq(msg->port_id(), d_tx->port_symbol())
196 || pmt_eq(msg->port_id(), d_rx->port_symbol()))
197 && pmt_eq(msg->signal(), s_response_allocate_channel))
200 if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
202 if(pmt_eq(msg->signal(), s_response_max_capacity)) {
203 d_max_capacity = pmt_to_long(pmt_nth(2, data));
205 std::cout << "[qa_alloc_top] USRP has max capacity of "
206 << d_max_capacity << "\n";
208 else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
209 d_ntx_chan = pmt_to_long(pmt_nth(2, data));
211 std::cout << "[qa_alloc_top] USRP tx channels: "
212 << d_ntx_chan << "\n";
214 else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
215 d_nrx_chan = pmt_to_long(pmt_nth(2, data));
217 std::cout << "[qa_alloc_top] USRP rx channels: "
218 << d_nrx_chan << "\n";
220 else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
228 if(d_nstatus==d_nstatus_to_recv)
234 qa_alloc_top::check_message(mb_message_sptr msg)
236 pmt_t data = msg->data();
237 pmt_t event = msg->signal();
239 pmt_t expected = pmt_nth(0, data);
240 pmt_t status = pmt_nth(1, data);
242 pmt_t e_event = pmt_nth(0, expected);
243 pmt_t e_status = pmt_nth(1, expected);
248 if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
250 std::cout << "Got: " << status << " Expected: " << e_status << "\n";
255 std::cout << "[qa_alloc_top] Received expected response for message "
256 << d_nrecvd << " (" << event << ")\n";
259 if(d_nrecvd == d_nmsgs_to_recv)
263 REGISTER_MBLOCK_CLASS(qa_alloc_top);
265 // ----------------------------------------------------------------------------------------------
267 class qa_dealloc_top : public mb_mblock
274 long d_ntx_chan, d_nrx_chan;
277 long d_nstatus_to_recv;
279 long d_nalloc_to_recv;
282 long d_ndealloc_to_recv;
283 long d_ndealloc_recvd;
285 std::vector<long> d_tx_chans;
286 std::vector<long> d_rx_chans;
289 qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
291 void initial_transition();
292 void handle_message(mb_message_sptr msg);
295 void check_allocation(mb_message_sptr msg);
296 void check_deallocation(mb_message_sptr msg);
298 void deallocate_all();
301 qa_dealloc_top::qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
302 : mb_mblock(runtime, instance_name, user_arg)
305 d_ndealloc_to_recv = 0;
307 d_nalloc_to_recv = 0; // auto-set
309 d_nstatus_to_recv = 4;
311 d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
312 d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
313 d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
315 // Use the stub with the usrp_server
316 pmt_t usrp_server_dict = pmt_make_dict();
317 pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
320 define_component("server", "usrp_server", usrp_server_dict);
321 connect("self", "tx0", "server", "tx0");
322 connect("self", "rx0", "server", "rx0");
323 connect("self", "cs", "server", "cs");
326 qa_dealloc_top::~qa_dealloc_top(){}
329 qa_dealloc_top::initial_transition()
333 std::cout << "[qa_dealloc_top] Initializing...\n";
335 // Retrieve information about the USRP, then run tests
336 d_cs->send(s_cmd_open,
337 pmt_list2(pmt_list2(s_response_open,PMT_T),
340 d_cs->send(s_cmd_max_capacity,
341 pmt_list1(pmt_list2(s_response_max_capacity,PMT_T)));
343 d_cs->send(s_cmd_ntx_chan,
344 pmt_list1(pmt_list2(s_response_ntx_chan,PMT_T)));
346 d_cs->send(s_cmd_nrx_chan,
347 pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T)));
351 qa_dealloc_top::allocate_max()
354 // Keep allocating until we hit the maximum number of channels
355 for(int i=0; i < d_ntx_chan; i++) {
356 d_tx->send(s_cmd_allocate_channel,
357 pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T),
358 pmt_from_long(1))); // 1 byte is good enough
363 for(int i=0; i < d_nrx_chan; i++) {
364 d_rx->send(s_cmd_allocate_channel,
365 pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T),
374 qa_dealloc_top::deallocate_all() {
376 // Deallocate all of the channels that were allocated from allocate_max()
377 for(int i=0; i < (int)d_tx_chans.size(); i++) {
380 std::cout << "[qa_dealloc_top] Trying to dealloc TX "
381 << d_tx_chans[i] << std::endl;
383 d_tx->send(s_cmd_deallocate_channel,
384 pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T),
385 pmt_from_long(d_tx_chans[i])));
387 d_ndealloc_to_recv++;
390 // Deallocate the RX side now
391 for(int i=0; i < (int)d_rx_chans.size(); i++) {
394 std::cout << "[qa_dealloc_top] Trying to dealloc RX "
395 << d_tx_chans[i] << std::endl;
397 d_rx->send(s_cmd_deallocate_channel,
398 pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T),
399 pmt_from_long(d_rx_chans[i])));
401 d_ndealloc_to_recv++;
404 // Should get permission denied errors trying to re-dealloc the channels, as
405 // we no longer have permission to them after deallocating
406 for(int i=0; i < (int)d_tx_chans.size(); i++) {
408 d_tx->send(s_cmd_deallocate_channel,
409 pmt_list2(pmt_list2(s_response_deallocate_channel,
410 s_err_channel_permission_denied),
411 pmt_from_long(d_tx_chans[i])));
413 d_ndealloc_to_recv++;
417 for(int i=0; i < (int)d_rx_chans.size(); i++) {
419 d_rx->send(s_cmd_deallocate_channel,
420 pmt_list2(pmt_list2(s_response_deallocate_channel,
421 s_err_channel_permission_denied),
422 pmt_from_long(d_rx_chans[i])));
424 d_ndealloc_to_recv++;
427 // Try to deallocate a channel that doesn't exist on both sides, the last
428 // element in the vectors is the highest channel number, so we take that plus
430 d_ndealloc_to_recv+=2;
431 d_tx->send(s_cmd_deallocate_channel,
432 pmt_list2(pmt_list2(s_response_deallocate_channel,
433 s_err_channel_invalid),
434 pmt_from_long(d_rx_chans.back()+1)));
436 d_rx->send(s_cmd_deallocate_channel,
437 pmt_list2(pmt_list2(s_response_deallocate_channel,
438 s_err_channel_invalid),
439 pmt_from_long(d_rx_chans.back()+1)));
442 // The used capacity should be back to 0 now that we've deallocated everything
443 d_cs->send(s_cmd_current_capacity_allocation,
444 pmt_list1(pmt_list2(s_response_current_capacity_allocation,
449 qa_dealloc_top::handle_message(mb_message_sptr msg)
451 pmt_t data = msg->data();
452 pmt_t event = msg->signal();
454 if(pmt_eq(event, pmt_intern("%shutdown")))
457 pmt_t expected = pmt_nth(0, data);
458 pmt_t status = pmt_nth(1, data);
460 pmt_t e_event = pmt_nth(0, expected);
461 pmt_t e_status = pmt_nth(1, expected);
463 if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
465 std::cout << "Got: " << status << " Expected: " << e_status << "\n";
470 std::cout << "[qa_alloc_top] Received expected response for message "
472 << " (" << event << ")\n";
475 if (pmt_eq(msg->port_id(), d_tx->port_symbol())
476 || pmt_eq(msg->port_id(), d_rx->port_symbol())) {
478 if(pmt_eq(msg->signal(), s_response_allocate_channel)) {
479 check_allocation(msg);
484 if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
486 if(pmt_eq(msg->signal(), s_response_max_capacity)) {
487 d_max_capacity = pmt_to_long(pmt_nth(2, data));
489 else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
490 d_ntx_chan = pmt_to_long(pmt_nth(2, data));
492 else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
493 d_nrx_chan = pmt_to_long(pmt_nth(2, data));
495 else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
496 // the final command is a capacity check which should be 0, then we
498 pmt_t expected_result = pmt_from_long(0);
499 pmt_t result = pmt_nth(2, data);
501 if(pmt_eqv(expected_result, result)) {
512 if(d_nstatus==d_nstatus_to_recv)
519 qa_dealloc_top::check_allocation(mb_message_sptr msg)
521 pmt_t data = msg->data();
522 pmt_t event = msg->signal();
524 pmt_t expected = pmt_nth(0, data);
525 pmt_t status = pmt_nth(1, data);
526 pmt_t channel = pmt_nth(2, data);
530 if(!pmt_eqv(status, PMT_T)) {
534 // store all of the allocate channel numbers
535 if(pmt_eq(msg->port_id(), d_tx->port_symbol()))
536 d_tx_chans.push_back(pmt_to_long(channel));
537 if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
538 d_rx_chans.push_back(pmt_to_long(channel));
541 if(d_nalloc_recvd == d_nalloc_to_recv) {
544 std::cout << "[qa_dealloc_top] Allocated TX channels: ";
545 for(int i=0; i < (int)d_tx_chans.size(); i++)
546 std::cout << d_tx_chans[i] << " ";
548 std::cout << "\n[qa_dealloc_top] Allocated RX channels: ";
549 for(int i=0; i < (int)d_rx_chans.size(); i++)
550 std::cout << d_rx_chans[i] << " ";
554 deallocate_all(); // once we've allocated all of our channels, try to
559 REGISTER_MBLOCK_CLASS(qa_dealloc_top);
561 // ----------------------------------------------------------------------------------------------
563 class qa_open_close_top : public mb_mblock
573 qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
574 ~qa_open_close_top();
575 void initial_transition();
576 void handle_message(mb_message_sptr msg);
579 void check_cs(mb_message_sptr msg);
583 qa_open_close_top::qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
584 : mb_mblock(runtime, instance_name, user_arg)
590 d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
592 // Use the stub with the usrp_server
593 pmt_t usrp_server_dict = pmt_make_dict();
594 pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
597 define_component("server", "usrp_server", usrp_server_dict);
598 connect("self", "cs", "server", "cs");
601 qa_open_close_top::~qa_open_close_top(){}
604 qa_open_close_top::initial_transition()
610 qa_open_close_top::run_tests()
612 // std::cout << "[qa_open_close_top] Starting tests\n";
614 // A close before an open should fail
615 d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,
616 s_err_usrp_already_closed)));
618 // Perform an open, and a second open which should fail
619 d_cs->send(s_cmd_open,
620 pmt_list2(pmt_list2(s_response_open,PMT_T),
623 d_cs->send(s_cmd_open,
624 pmt_list2(pmt_list2(s_response_open,
625 s_err_usrp_already_opened),
628 // A close should now be successful since the interface is open
629 d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
631 // But, a second close should fail
632 d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,
633 s_err_usrp_already_closed)));
635 // Just to be thorough, try an open and close again
636 d_cs->send(s_cmd_open,
637 pmt_list2(pmt_list2(s_response_open,PMT_T),
640 d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
646 qa_open_close_top::handle_message(mb_message_sptr msg)
648 pmt_t data = msg->data();
650 if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
656 if(d_nmsg_to_recv == d_nmsg_recvd)
661 qa_open_close_top::check_cs(mb_message_sptr msg)
663 pmt_t data = msg->data();
664 pmt_t event = msg->signal();
666 pmt_t expected = pmt_nth(0, data);
667 pmt_t status = pmt_nth(1, data);
669 pmt_t e_event = pmt_nth(0, expected);
670 pmt_t e_status = pmt_nth(1, expected);
672 if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
675 std::cout << "[qa_open_close_top] FAILED check_cs... Got: " << status
676 << " Expected: " << e_status
677 << " for event " << event << "\n";
682 std::cout << "[qa_open_close_top] Received expected CS response ("
688 REGISTER_MBLOCK_CLASS(qa_open_close_top);
690 // ----------------------------------------------------------------------------------------------
692 class qa_tx_top : public mb_mblock
699 long d_ntx_chan, d_nrx_chan;
708 qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
710 void initial_transition();
711 void handle_message(mb_message_sptr msg);
714 void check_allocation(mb_message_sptr msg);
715 void check_deallocation(mb_message_sptr msg);
716 void check_xmit(mb_message_sptr msg);
717 void check_cs(mb_message_sptr msg);
721 qa_tx_top::qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
722 : mb_mblock(runtime, instance_name, user_arg)
728 d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
729 d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
730 d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
732 // Use the stub with the usrp_server
733 pmt_t usrp_server_dict = pmt_make_dict();
734 pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
737 define_component("server", "usrp_server", usrp_server_dict);
738 connect("self", "tx0", "server", "tx0");
739 connect("self", "rx0", "server", "rx0");
740 connect("self", "cs", "server", "cs");
743 qa_tx_top::~qa_tx_top(){}
746 qa_tx_top::initial_transition()
752 qa_tx_top::run_tests()
755 std::cout << "[qa_tx_top] Starting tests\n";
757 // A transmit before an open should fail
758 d_tx->send(s_cmd_xmit_raw_frame,
759 pmt_list4(pmt_list2(s_response_xmit_raw_frame,
760 s_err_usrp_not_opened),
762 pmt_make_u32vector(transport_pkt::max_payload()/4, 0),
766 d_cs->send(s_cmd_open,
767 pmt_list2(pmt_list2(s_response_open,PMT_T),
770 // Try to transmit on a channel that we have no allocation for
771 d_tx->send(s_cmd_xmit_raw_frame,
772 pmt_list4(pmt_list2(s_response_xmit_raw_frame,
773 s_err_channel_permission_denied),
775 pmt_make_u32vector(transport_pkt::max_payload()/4, 0),
778 // Get a channel allocation and send on it, we assume 0 (FIXME) until 'defer'
779 // is implemented for simplicity
780 d_tx->send(s_cmd_allocate_channel,
781 pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T),
784 d_tx->send(s_cmd_xmit_raw_frame,
785 pmt_list4(pmt_list2(s_response_xmit_raw_frame, PMT_T),
787 pmt_make_u32vector(transport_pkt::max_payload()/4, 0),
790 // Close should be successful
791 d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
793 // After closing, a new transmit raw frame should fail again
794 d_tx->send(s_cmd_xmit_raw_frame,
795 pmt_list4(pmt_list2(s_response_xmit_raw_frame,
796 s_err_usrp_not_opened),
798 pmt_make_u32vector(transport_pkt::max_payload()/4, 0),
801 // Reopen and retry before getting an allocation, the first xmit should fail,
802 // after we allocate it should work again
803 d_cs->send(s_cmd_open,
804 pmt_list2(pmt_list2(s_response_open, PMT_T),
807 d_tx->send(s_cmd_xmit_raw_frame,
808 pmt_list4(pmt_list2(s_response_xmit_raw_frame,
809 s_err_channel_permission_denied),
811 pmt_make_u32vector(transport_pkt::max_payload()/4, 0),
814 d_tx->send(s_cmd_allocate_channel,
815 pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T),
818 d_tx->send(s_cmd_xmit_raw_frame,
819 pmt_list4(pmt_list2(s_response_xmit_raw_frame,PMT_T),
821 pmt_make_u32vector(transport_pkt::max_payload()/4, 0),
824 // A final close which should be successful
825 d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
831 qa_tx_top::handle_message(mb_message_sptr msg)
833 pmt_t data = msg->data();
834 pmt_t event = msg->signal();
836 if(pmt_eq(event, pmt_intern("%shutdown")))
839 pmt_t expected = pmt_nth(0, data);
840 pmt_t status = pmt_nth(1, data);
842 pmt_t e_event = pmt_nth(0, expected);
843 pmt_t e_status = pmt_nth(1, expected);
845 if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
847 std::cout << "[qa_xmit_top] Got: " << status
848 << " Expected: " << e_status
849 << "For signal: " << event << "\n";
854 std::cout << "[qa_xmit_top] Received expected response for message "
856 << " (" << event << ")\n";
859 if (pmt_eq(msg->port_id(), d_tx->port_symbol())
860 || pmt_eq(msg->port_id(), d_rx->port_symbol())) {
862 if(pmt_eq(msg->signal(), s_response_allocate_channel))
863 check_allocation(msg);
869 if(d_nmsg_to_recv == d_nmsg_recvd){
876 qa_tx_top::check_allocation(mb_message_sptr msg)
878 pmt_t data = msg->data();
879 pmt_t event = msg->signal();
881 pmt_t expected = pmt_nth(0, data);
882 pmt_t status = pmt_nth(1, data);
883 pmt_t channel = pmt_nth(2, data);
885 if(pmt_eqv(status, PMT_T)) {
886 // store all of the allocate channel numbers
887 if(pmt_eq(msg->port_id(), d_tx->port_symbol()))
888 d_tx_chan = pmt_to_long(channel);
889 if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
890 d_rx_chan = pmt_to_long(channel);
894 REGISTER_MBLOCK_CLASS(qa_tx_top);
896 // ----------------------------------------------------------------------------------------------
898 class qa_rx_top : public mb_mblock
904 long d_ntx_chan, d_nrx_chan;
908 bool d_got_response_recv;
914 qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
916 void initial_transition();
917 void handle_message(mb_message_sptr msg);
920 void check_allocation(mb_message_sptr msg);
921 void check_deallocation(mb_message_sptr msg);
922 void check_xmit(mb_message_sptr msg);
923 void check_cs(mb_message_sptr msg);
927 qa_rx_top::qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
928 : mb_mblock(runtime, instance_name, user_arg),
929 d_got_response_recv(false)
932 d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
933 d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
935 // Use the stub with the usrp_server
936 pmt_t usrp_dict = pmt_make_dict();
937 // Set TX and RX interpolations
938 pmt_dict_set(usrp_dict,
939 pmt_intern("decim-rx"),
941 pmt_dict_set(usrp_dict, pmt_intern("fake-usrp"), PMT_T);
944 define_component("server", "usrp_server", usrp_dict);
945 connect("self", "rx0", "server", "rx0");
946 connect("self", "cs", "server", "cs");
949 qa_rx_top::~qa_rx_top(){}
952 qa_rx_top::initial_transition()
958 qa_rx_top::run_tests()
961 std::cout << "[qa_rx_top] Starting tests\n";
963 d_cs->send(s_cmd_open, pmt_list2(pmt_list2(s_response_open,PMT_T), pmt_from_long(0)));
965 d_rx->send(s_cmd_allocate_channel,
966 pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T),
969 d_rx->send(s_cmd_start_recv_raw_samples,
973 // Schedule a small timeout in which we expect to have received at least one
974 // packet worth of samples from the stub
975 d_t0 = mb_time::time();
976 schedule_one_shot_timeout(d_t0 + 0.01, PMT_NIL);
981 qa_rx_top::handle_message(mb_message_sptr msg)
983 pmt_t data = msg->data();
984 pmt_t event = msg->signal();
986 if(pmt_eq(event, pmt_intern("%shutdown")))
989 pmt_t expected = pmt_nth(0, data);
990 pmt_t status = pmt_nth(1, data);
992 // If we get a timeout we shutdown
993 if(pmt_eq(event, s_timeout)) {
995 std::cout << "[qa_rx_top] Got timeout\n";
996 d_rx->send(s_cmd_stop_recv_raw_samples,
1000 d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
1004 // For testing RX, an invocation handle is not generated by the stub,
1005 // therefore the same approach for testing is not used. We simply
1006 // expect all responses to be true.
1007 if(pmt_eq(event, s_response_recv_raw_samples)) {
1008 if(pmt_eqv(status, PMT_T)) {
1011 std::cout << "[qa_rx_top] Received expected response for message "
1012 << " (" << event << ")\n";
1014 // All we want is 1 response receive! Can't guarantee exact numbers
1015 d_got_response_recv = true;
1019 std::cout << "Got: " << status << " Expected: " << PMT_T << "\n";
1020 shutdown_all(PMT_F);
1025 pmt_t e_event = pmt_nth(0, expected);
1026 pmt_t e_status = pmt_nth(1, expected);
1028 if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
1030 std::cout << "Got: " << status << " Expected: " << e_status << "\n";
1031 shutdown_all(PMT_F);
1035 std::cout << "[qa_rx_top] Received expected response for message "
1036 << " (" << event << ")\n";
1039 if (pmt_eq(msg->port_id(), d_rx->port_symbol())) {
1041 if(pmt_eq(msg->signal(), s_response_allocate_channel))
1042 check_allocation(msg);
1046 // We stop when we get a close, we are successful if we
1047 // got a response from recv, fail if we never got a recv response
1048 if(pmt_eq(msg->signal(), s_response_close)) {
1050 if(d_got_response_recv) {
1051 shutdown_all(PMT_T);
1055 shutdown_all(PMT_F);
1057 std::cout << "[qa_rx_top] No response message before close\n";
1065 qa_rx_top::check_allocation(mb_message_sptr msg)
1067 pmt_t data = msg->data();
1068 pmt_t event = msg->signal();
1070 pmt_t expected = pmt_nth(0, data);
1071 pmt_t status = pmt_nth(1, data);
1072 pmt_t channel = pmt_nth(2, data);
1074 if(pmt_eqv(status, PMT_T)) {
1075 // store all of the allocate channel numbers
1076 if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
1077 d_rx_chan = pmt_to_long(channel);
1081 REGISTER_MBLOCK_CLASS(qa_rx_top);
1083 // ----------------------------------------------------------------------------------------------
1085 class qa_rid_top : public mb_mblock
1100 qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
1102 void initial_transition();
1103 void handle_message(mb_message_sptr msg);
1107 void send_max_pings();
1110 qa_rid_top::qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
1111 : mb_mblock(runtime, instance_name, user_arg)
1115 d_cycles = d_tcycles;
1116 d_max_rid = usrp_server::D_MAX_RID;
1120 d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
1121 d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
1122 d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
1124 // Use the stub with the usrp_server
1125 pmt_t usrp_server_dict = pmt_make_dict();
1126 pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
1129 define_component("server", "usrp_server", usrp_server_dict);
1130 connect("self", "tx0", "server", "tx0");
1131 connect("self", "rx0", "server", "rx0");
1132 connect("self", "cs", "server", "cs");
1136 qa_rid_top::~qa_rid_top(){}
1139 qa_rid_top::initial_transition()
1145 qa_rid_top::run_tests()
1148 std::cout << "[qa_rid_top] Starting tests...\n";
1150 // Retrieve information about the USRP, then run tests
1151 d_cs->send(s_cmd_open,
1152 pmt_list2(pmt_list2(s_response_open, PMT_T),
1155 // should be able to allocate 1 byte
1156 d_tx->send(s_cmd_allocate_channel,
1157 pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T),
1160 d_rx->send(s_cmd_allocate_channel,
1161 pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T),
1164 // Need to start receiving to read from the USRP to get C/S responses
1165 d_rx->send(s_cmd_start_recv_raw_samples,
1169 // Build a subpacket of MAX_RID pings and wait a small amount for all of the
1170 // responses and fire off another MAX_RID. If MAX_RID*2 responses are
1171 // received, the RID recycling is working correctly.
1172 // Schedule a timer in which we expect to have received all of the responses,
1173 // which will send off another MAX_RID worth.
1175 d_t0 = mb_time::time();
1176 schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
1180 qa_rid_top::send_max_pings()
1182 pmt_t ping = pmt_list2(s_op_ping_fixed,
1183 pmt_list2(pmt_from_long(0),
1186 pmt_t sub_packets = PMT_NIL;
1188 for(int i=0; i<d_max_rid; i++)
1189 sub_packets = pmt_list_add(sub_packets, ping);
1191 d_tx->send(s_cmd_to_control_channel,
1192 pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
1197 qa_rid_top::handle_message(mb_message_sptr msg)
1199 pmt_t data = msg->data();
1200 pmt_t event = msg->signal();
1202 // If we get a timeout we ensure we got a maximum RID number of responses.
1203 if(pmt_eq(event, s_timeout)) {
1205 std::cout << "[qa_rid_top] Got timeout, received so far: "
1206 << d_npongs << "\n";
1210 if(d_cycles==0 && d_npongs == d_max_rid*d_tcycles) {
1211 shutdown_all(PMT_T);
1213 else if(d_cycles==0) {
1215 std::cout << "[qa_rid_top] d_npongs: " << d_npongs
1216 << " expected: " << d_max_rid*d_tcycles
1219 shutdown_all(PMT_F);
1223 d_t0 = mb_time::time();
1224 schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
1228 else if(pmt_eq(event, s_response_from_control_channel))
1235 REGISTER_MBLOCK_CLASS(qa_rid_top);
1238 // ----------------------------------------------------------------------------------------------
1240 class qa_cs_top : public mb_mblock
1246 long d_nmsgs_to_recv;
1249 long d_max_capacity;
1250 long d_ntx_chan, d_nrx_chan;
1253 long d_nstatus_to_recv;
1256 qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
1258 void initial_transition();
1259 void handle_message(mb_message_sptr msg);
1262 void check_message(mb_message_sptr msg);
1266 qa_cs_top::qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
1267 : mb_mblock(runtime, instance_name, user_arg)
1270 d_nmsgs_to_recv = 8;
1272 d_nstatus_to_recv = 50;
1274 d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
1275 d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
1276 d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
1278 // Use the stub with the usrp_server
1279 pmt_t usrp_server_dict = pmt_make_dict();
1280 pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
1283 define_component("server", "usrp_server", usrp_server_dict);
1284 connect("self", "tx0", "server", "tx0");
1285 connect("self", "rx0", "server", "rx0");
1286 connect("self", "cs", "server", "cs");
1290 qa_cs_top::~qa_cs_top(){}
1293 qa_cs_top::initial_transition()
1299 qa_cs_top::run_tests()
1302 std::cout << "[qa_cs_top] Starting tests...\n";
1304 // Retrieve information about the USRP, then run tests
1305 d_cs->send(s_cmd_open,
1306 pmt_list2(pmt_list2(s_response_open, PMT_T),
1309 // should be able to allocate 1 byte
1310 d_tx->send(s_cmd_allocate_channel,
1311 pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T),
1314 d_rx->send(s_cmd_allocate_channel,
1315 pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T),
1318 // Need to start receiving to read from the USRP to get C/S responses
1319 d_rx->send(s_cmd_start_recv_raw_samples,
1323 d_tx->send(s_cmd_to_control_channel,
1324 pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
1326 pmt_list2(s_op_ping_fixed,
1327 pmt_list2(pmt_from_long(3),
1328 pmt_from_long(0))))));
1330 d_tx->send(s_cmd_to_control_channel,
1331 pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
1333 pmt_list2(s_op_write_reg,
1336 pmt_from_long(0x4))))));
1338 d_tx->send(s_cmd_to_control_channel,
1339 pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
1341 pmt_list2(s_op_write_reg_masked,
1345 pmt_from_long(0x5))))));
1347 d_tx->send(s_cmd_to_control_channel,
1348 pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
1350 pmt_list2(s_op_read_reg,
1351 pmt_list2(pmt_from_long(0),
1352 pmt_from_long(0x6))))));
1354 d_tx->send(s_cmd_to_control_channel,
1355 pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
1357 pmt_list2(s_op_delay,
1358 pmt_list1(pmt_from_long(0x7))))));
1360 pmt_t subpackets = pmt_list5(
1361 pmt_list2(s_op_ping_fixed, pmt_list2(pmt_from_long(0), pmt_from_long(0))),
1362 pmt_list2(s_op_delay, pmt_list1(pmt_from_long(0x7))),
1363 pmt_list2(s_op_write_reg_masked, pmt_list3(pmt_from_long(3),
1366 pmt_list2(s_op_write_reg, pmt_list2(pmt_from_long(3),
1368 pmt_list2(s_op_read_reg, pmt_list2(pmt_from_long(0),
1372 d_tx->send(s_cmd_to_control_channel,
1373 pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
1376 pmt_t i2c_data = pmt_make_u8vector(8, 0xff);
1378 subpackets = pmt_list2(
1379 pmt_list2(s_op_i2c_write,
1380 pmt_list2(pmt_from_long(8), i2c_data)),
1381 pmt_list2(s_op_i2c_read,
1382 pmt_list3(pmt_from_long(0), pmt_from_long(9), pmt_from_long(1)))
1386 d_tx->send(s_cmd_to_control_channel,
1387 pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
1393 qa_cs_top::handle_message(mb_message_sptr msg)
1395 pmt_t data = msg->data();
1397 if ((pmt_eq(msg->port_id(), d_tx->port_symbol())
1398 || pmt_eq(msg->port_id(), d_rx->port_symbol()))
1399 && pmt_eq(msg->signal(), s_response_allocate_channel))
1402 if (pmt_eq(msg->port_id(), d_tx->port_symbol())
1403 && pmt_eq(msg->signal(), s_response_from_control_channel))
1406 if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
1408 if(pmt_eq(msg->signal(), s_response_max_capacity)) {
1409 d_max_capacity = pmt_to_long(pmt_nth(2, data));
1411 std::cout << "[qa_cs_top] USRP has max capacity of "
1412 << d_max_capacity << "\n";
1414 else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
1415 d_ntx_chan = pmt_to_long(pmt_nth(2, data));
1417 std::cout << "[qa_cs_top] USRP tx channels: "
1418 << d_ntx_chan << "\n";
1420 else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
1421 d_nrx_chan = pmt_to_long(pmt_nth(2, data));
1423 std::cout << "[qa_cs_top] USRP rx channels: "
1424 << d_nrx_chan << "\n";
1426 else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
1434 if(d_nstatus==d_nstatus_to_recv)
1440 qa_cs_top::check_message(mb_message_sptr msg)
1442 pmt_t data = msg->data();
1443 pmt_t event = msg->signal();
1445 pmt_t expected = pmt_nth(0, data);
1446 pmt_t status = pmt_nth(1, data);
1448 pmt_t e_event = pmt_nth(0, expected);
1449 pmt_t e_status = pmt_nth(1, expected);
1454 if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
1456 std::cout << "[qa_cs_top] Got: " << status << " Expected: " << e_status << "\n";
1457 shutdown_all(PMT_F);
1461 std::cout << "[qa_cs_top] Received expected response for message "
1462 << d_nrecvd << " (" << event << ")\n";
1465 if(d_nrecvd == d_nmsgs_to_recv)
1466 shutdown_all(PMT_T);
1469 REGISTER_MBLOCK_CLASS(qa_cs_top);
1471 // ----------------------------------------------------------------------------------------------
1474 qa_inband_usrp_server::test_open_close()
1476 mb_runtime_sptr rt = mb_make_runtime();
1477 pmt_t result = PMT_T;
1479 // std::cout << "\n\n----------------------------\n";
1480 // std::cout << " RUNNING OPEN/CLOSE TESTS \n";
1482 rt->run("top", "qa_open_close_top", PMT_F, &result);
1484 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
1488 qa_inband_usrp_server::test_chan_allocation()
1490 mb_runtime_sptr rt = mb_make_runtime();
1491 pmt_t result = PMT_T;
1493 // std::cout << "\n\n----------------------------\n";
1494 // std::cout << " RUNNING ALLOCATION TESTS \n";
1496 rt->run("qa_alloc_top", "qa_alloc_top", PMT_F, &result);
1498 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
1502 qa_inband_usrp_server::test_chan_deallocation()
1504 mb_runtime_sptr rt = mb_make_runtime();
1505 pmt_t result = PMT_T;
1507 // std::cout << "\n\n----------------------------\n";
1508 // std::cout << " RUNNING DEALLOCATION TESTS \n";
1510 rt->run("qa_dealloc_top", "qa_dealloc_top", PMT_F, &result);
1512 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
1516 qa_inband_usrp_server::test_tx()
1518 mb_runtime_sptr rt = mb_make_runtime();
1519 pmt_t result = PMT_T;
1521 // std::cout << "\n\n-----------------\n";
1522 // std::cout << " RUNNING TX TESTS \n";
1524 rt->run("top", "qa_tx_top", PMT_F, &result);
1526 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
1530 qa_inband_usrp_server::test_rx()
1532 mb_runtime_sptr rt = mb_make_runtime();
1533 pmt_t result = PMT_T;
1535 // std::cout << "\n\n-----------------\n";
1536 // std::cout << " RUNNING RX TESTS \n";
1538 rt->run("top", "qa_rx_top", PMT_F, &result);
1540 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
1544 qa_inband_usrp_server::test_cs()
1546 // FIXME This test is disabled because it hangs with the change to use usrp_standard_*_sptr's
1549 mb_runtime_sptr rt = mb_make_runtime();
1550 pmt_t result = PMT_T;
1552 // std::cout << "\n\n-----------------\n";
1553 // std::cout << " RUNNING CS TESTS \n";
1555 rt->run("top", "qa_cs_top", PMT_F, &result);
1557 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
1561 qa_inband_usrp_server::test_rid()
1563 // FIXME This test is disabled because it hangs with the change to use usrp_standard_*_sptr's
1566 mb_runtime_sptr rt = mb_make_runtime();
1567 pmt_t result = PMT_T;
1569 // std::cout << "\n\n-----------------\n";
1570 // std::cout << " RUNNING RID TESTS \n";
1572 rt->run("top", "qa_rid_top", PMT_F, &result);
1574 CPPUNIT_ASSERT(pmt_equal(PMT_T, result));