![]() |
four_multi
Multi-Antenna,Multi-Node,Multi-Band,Multi-Cell
|
00001 // Copyright 2011-2013, Per Zetterberg, KTH Royal Institute of Technology 00002 // 00003 // This program is free software: you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation, either version 3 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // This program is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00015 // 00016 00017 00018 00019 #include <fstream> 00020 #include <uhd/device.hpp> 00021 #include <uhd/utils/thread_priority.hpp> 00022 #include <uhd/utils/safe_main.hpp> 00023 #include <uhd/usrp/multi_usrp.hpp> 00024 #include <boost/format.hpp> 00025 #include <iostream> 00026 #include <complex> 00027 #include <uhd/types/clock_config.hpp> 00028 #include "gps.hpp" 00029 #include <uhd/usrp/subdev_spec.hpp> 00030 #include "four_multi.hpp" 00031 #include <uhd/types/ranges.hpp> 00032 #include "get_usrp2_ip_addr.hpp" 00033 #include <boost/thread/thread.hpp> 00034 #include <iostream> 00035 #include <boost/asio.hpp> 00036 #include <boost/asio/io_service.hpp> 00037 #include <boost/asio/serial_port.hpp> 00038 #include <boost/thread/thread.hpp> 00039 #include <boost/asio/socket_base.hpp> 00040 #include <boost/asio/ip/address.hpp> 00041 #include <boost/asio/ip/tcp.hpp> 00042 #include <boost/asio/write.hpp> 00043 #include <boost/asio/buffer.hpp> 00044 00045 00046 using namespace boost::asio::ip; 00047 using boost::asio::ip::tcp; 00048 00049 namespace po = boost::program_options; 00050 using namespace boost; 00051 00053 class four_multi_node::udp_function_thread_class{ 00054 public: 00055 00056 uint32_t this_node_ix; 00057 uint32_t other_node_ix; 00058 void *pointer_to_data; 00059 uint32_t num_bytes; 00060 00061 00062 void operator()(void){ 00063 00064 try 00065 { 00066 00067 boost::asio::io_service io_service; 00068 udp::socket socket(io_service, udp::endpoint(udp::v4(), 00069 2000+other_node_ix*100+this_node_ix)); 00070 00071 00072 udp::endpoint remote_endpoint; 00073 boost::system::error_code error; 00074 size_t len=socket.receive_from(boost::asio::buffer(pointer_to_data,num_bytes), 00075 remote_endpoint, 0, error); 00076 00077 00078 while (len<num_bytes) { 00079 void *p; 00080 p=pointer_to_data; 00081 p=(void* ) (((char*) p)+len/sizeof(char)); 00082 size_t len1=socket.receive_from(boost::asio::buffer(pointer_to_data,num_bytes), 00083 remote_endpoint, 0, error); 00084 len=len+len1; 00085 }; 00086 } 00087 catch (std::exception& e) 00088 { 00089 std::cerr << e.what() << std::endl; 00090 } 00091 00092 00093 }; 00094 }; 00095 00097 class four_multi_node::usrp_thread_function_class { 00098 public: 00099 00100 uhd::usrp::multi_usrp::sptr d_mdev; 00101 uhd::device::sptr d_dev; 00102 00103 std::vector<const void *> d_tx_buffers; 00104 std::vector<void *> d_rx_buffers; 00105 00106 uint32_t d_buffer_length; 00107 uint32_t d_no_ant; 00108 bool do_tx; 00109 uint32_t tx_repeats; 00110 00111 00112 uhd::time_spec_t stream_time; 00113 00114 uhd::tx_metadata_t md_tx; 00115 uhd::rx_metadata_t md_rx; 00116 00117 00118 void operator()(void){ 00119 00120 if (do_tx) { 00121 00122 if (tx_repeats<2) { 00123 d_dev->send( 00124 d_tx_buffers, d_buffer_length, md_tx, 00125 uhd::io_type_t::COMPLEX_INT16, 00126 uhd::device::SEND_MODE_FULL_BUFF); 00127 } else { 00128 00129 for (int i1=0;i1<(int) tx_repeats;i1++) { 00130 d_dev->send( 00131 d_tx_buffers, d_buffer_length, md_tx, 00132 uhd::io_type_t::COMPLEX_INT16, 00133 uhd::device::SEND_MODE_FULL_BUFF); 00134 md_tx.time_spec += 5.2e-4; 00135 00136 }; 00137 00138 #if 0 00139 uhd::tx_metadata_t md_tx_temp=md_tx; 00140 md_tx_temp.end_of_burst = false; 00141 md_tx.has_time_spec = true; 00142 00143 d_dev->send( 00144 d_tx_buffers, d_buffer_length, md_tx_temp, 00145 uhd::io_type_t::COMPLEX_INT16, 00146 uhd::device::SEND_MODE_FULL_BUFF); 00147 00148 md_tx_temp.start_of_burst = false; 00149 md_tx_temp.has_time_spec = false; 00150 00151 for (int i1=0;i1<((int) tx_repeats)-2;i1++) { 00152 d_dev->send( 00153 d_tx_buffers, d_buffer_length, md_tx_temp, 00154 uhd::io_type_t::COMPLEX_INT16, 00155 uhd::device::SEND_MODE_FULL_BUFF); 00156 }; 00157 00158 md_tx.end_of_burst = true; 00159 d_dev->send(d_tx_buffers, d_buffer_length, md_tx_temp, 00160 uhd::io_type_t::COMPLEX_INT16, 00161 uhd::device::SEND_MODE_FULL_BUFF); 00162 00163 #endif 00164 00165 }; 00166 00167 00168 } else { 00169 00170 00171 uint32_t num_rx_samps=0; 00172 uhd::stream_cmd_t 00173 stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); 00174 00175 stream_cmd.stream_now=false; 00176 stream_cmd.num_samps = d_buffer_length; 00177 stream_cmd.time_spec = stream_time; 00178 d_mdev->issue_stream_cmd(stream_cmd); 00179 00180 while (num_rx_samps==0) { 00181 00182 num_rx_samps=d_dev->recv( 00183 d_rx_buffers, 00184 d_buffer_length, 00185 md_rx, 00186 uhd::io_type_t::COMPLEX_INT16, 00187 uhd::device::RECV_MODE_FULL_BUFF 00188 ); 00189 00190 00191 if (!((md_rx.error_code==0) || (md_rx.error_code==1))) { 00192 std::cout << "!!!!!!!!!!!!!!!!!!!!!! md_rx.error_code=" << md_rx.error_code << std::endl; 00193 00194 std::complex<int16_t> *p1; 00195 for (uint32_t i3=0;i3<d_no_ant;i3++) { 00196 p1=(std::complex<int16_t> *) d_rx_buffers[i3]; 00197 p1[0]=10000; 00198 }; 00199 break; 00200 }; 00201 00202 00203 }; // while 00204 00205 00206 }; // if-else 00207 00208 00209 }; // operator() 00210 00211 }; // class 00212 00213 00214 00215 four_multi_node::four_multi_node(uint32_t buffer_length, uint32_t no_ant1, uint32_t no_ant2, bool use_external_10MHz,bool same_antenna, 00216 uint32_t node_ix, 00217 std::vector<std::string> IP_addresses,bool simulate,uint32_t skip_ant) 00218 { 00219 d_rate=25e6; 00220 d_skip_ant=skip_ant; 00221 save_input_on_file=false; 00222 no_rx_buffer_stored_so_far=0; 00223 wait_time_for_transmissions_to_finish=1.0; 00224 set_time_on_pps=true; 00225 skip_hw_set_during_init=false; 00226 use_udp=false; 00227 00228 00229 00230 d_node_ix=node_ix; 00231 d_IP_addresses=IP_addresses; 00232 d_simulate=simulate; 00233 00234 d_buffer_length=buffer_length; 00235 d_no_ant=no_ant1; 00236 d_no_ant1=no_ant1; 00237 d_no_ant2=no_ant2; 00238 d_no_ant=d_no_ant1+d_no_ant2; 00239 d_use_external_10MHz=use_external_10MHz; 00240 d_use_same_antenna=same_antenna; 00241 00242 00243 init(buffer_length); 00244 00245 00246 }; 00247 00248 four_multi_node::four_multi_node(uint32_t no_ant1, uint32_t no_ant2, bool use_external_10MHz,bool same_antenna, 00249 uint32_t node_ix, 00250 std::vector<std::string> IP_addresses,bool simulate,uint32_t skip_ant) 00251 { 00252 d_rate=25e6; 00253 d_skip_ant=skip_ant; 00254 save_input_on_file=false; 00255 no_rx_buffer_stored_so_far=0; 00256 wait_time_for_transmissions_to_finish=1.0; 00257 set_time_on_pps=true; 00258 skip_hw_set_during_init=false; 00259 use_udp=false; 00260 00261 00262 d_node_ix=node_ix; 00263 d_IP_addresses=IP_addresses; 00264 d_simulate=simulate; 00265 00266 d_no_ant=no_ant1; 00267 d_no_ant1=no_ant1; 00268 d_no_ant2=no_ant2; 00269 d_no_ant=d_no_ant1+d_no_ant2; 00270 d_use_external_10MHz=use_external_10MHz; 00271 d_use_same_antenna=same_antenna; 00272 00273 00274 }; 00275 00276 00277 00278 00279 void four_multi_node::save_raw_input_on_file(uint32_t max_no_frames_to_save,std::string directory_name) { 00280 00281 save_input_on_file=true; 00282 raw_data_dir=directory_name; 00283 std::complex<int16_t> *temp_buffer; 00284 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00285 if (d_rx_storage_buffers[i1]==NULL) { 00286 temp_buffer=new std::complex<int16_t>[d_buffer_length*max_no_frames_to_save]; 00287 d_rx_storage_buffers[i1]=temp_buffer; 00288 }; 00289 }; 00290 d_max_no_frames_to_save=max_no_frames_to_save; 00291 00292 } 00293 00294 00295 void four_multi_node::dont_save_raw_input_on_file(void) { 00296 save_input_on_file=false; 00297 std::complex<int16_t> *temp_buffer; 00298 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00299 temp_buffer= (std::complex<int16_t> *) d_rx_storage_buffers[i1]; 00300 delete[] temp_buffer; 00301 }; 00302 } 00303 00304 void four_multi_node::init(uint32_t buffer_length){ 00305 00306 m1= new usrp_thread_function_class[1]; 00307 m2= new usrp_thread_function_class[1]; 00308 00309 00310 m1->d_no_ant=d_no_ant1; 00311 m2->d_no_ant=d_no_ant2; 00312 d_old_frame_settings.what=START; 00313 d_buffer_length=buffer_length; 00314 m1->tx_repeats=0; 00315 m2->tx_repeats=0; 00316 00317 // Internal variables 00318 uhd::clock_config_t my_clock_config; 00319 00320 00321 00322 m1->d_buffer_length=buffer_length; 00323 m2->d_buffer_length=buffer_length; 00324 00325 00326 00327 std::string IP_addresses1, IP_addresses2, IP_addresses; 00328 std::stringstream temp_ss; 00329 uhd::device_addr_t dev_addr1; 00330 uhd::device_addr_t dev_addr2; 00331 00332 00333 IP_addresses=get_usrp2_ip_addr(d_no_ant+d_skip_ant); // Get all IP addresses needed 00334 00335 // Split them into two subsets 00336 std::istringstream iss(IP_addresses); 00337 00338 // Skip skip_ant addresses: 00339 for (uint32_t i1=0;i1<d_skip_ant;i1++) { 00340 std::string subs; 00341 iss >> subs; 00342 }; 00343 00344 //std::cout << "IP_addresses=" << IP_addresses << std::endl; 00345 00346 for (uint32_t i1=0;i1<d_no_ant1;i1++) { 00347 std::string subs; 00348 std::string numb; 00349 std::stringstream ss; 00350 00351 ss << i1; 00352 ss >> numb; 00353 numb="addr"+numb; 00354 iss >> subs; 00355 dev_addr1[numb]=subs; 00356 IP_addresses1+=subs; 00357 if (i1<(d_no_ant1-1)){ 00358 IP_addresses1+=" "; 00359 } 00360 }; 00361 00362 for (uint32_t i2=0;i2<d_no_ant2;i2++) { 00363 std::string subs; 00364 std::string numb; 00365 std::stringstream ss; 00366 00367 ss << i2; 00368 ss >> numb; 00369 numb="addr"+numb; 00370 iss >> subs; 00371 dev_addr2[numb]=subs; 00372 IP_addresses2+=subs; 00373 if (i2<(d_no_ant2-1)) 00374 IP_addresses2+=" "; 00375 }; 00376 00377 00378 00379 temp_ss << buffer_length*4*4; 00380 dev_addr1["recv_buff_size"]=temp_ss.str(); 00381 dev_addr1["send_buff_size"]=temp_ss.str(); 00382 dev_addr2["recv_buff_size"]=temp_ss.str(); 00383 dev_addr2["send_buff_size"]=temp_ss.str(); 00384 00385 00386 if (!d_simulate) { 00387 00388 00389 if (d_no_ant1>0) 00390 m1->d_mdev=uhd::usrp::multi_usrp::make(dev_addr1); 00391 if (d_no_ant2>0) 00392 m2->d_mdev=uhd::usrp::multi_usrp::make(dev_addr2); 00393 00394 #if 0 00395 uhd::usrp::subdev_spec_t e(""); 00396 00397 if (d_no_ant1>0) { 00398 for (uint32_t i1=0;i1<d_no_ant1;i1++) { 00399 m1->d_mdev->set_rx_subdev_spec(e, i1); 00400 m1->d_mdev->set_tx_subdev_spec(e, i1); 00401 }; 00402 m1->d_dev=m1->d_mdev->get_device(); 00403 }; 00404 if (d_no_ant2>0) { 00405 for (uint32_t i1=0;i1<d_no_ant2;i1++) { 00406 m2->d_mdev->set_rx_subdev_spec(e, i1); 00407 m2->d_mdev->set_tx_subdev_spec(e, i1); 00408 }; 00409 m2->d_dev=m2->d_mdev->get_device(); 00410 }; 00411 #endif 00412 00413 //XCVR2450-LNA 00414 //XCVR2450-VGA 00415 //0,15,30.5 00416 //0,2,62 00417 //XCVR2450-VGA 00418 //XCVR2450-BB 00419 //0,0.5,30 00420 //0,1.5,5 00421 00422 }; 00423 00424 00425 std::complex<int16_t> *temp_buffer; 00426 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00427 temp_buffer=new std::complex<int16_t>[d_buffer_length]; 00428 d_tx_buffers.push_back(temp_buffer); 00429 }; 00430 00431 00432 00433 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00434 temp_buffer=new std::complex<int16_t>[d_buffer_length]; 00435 d_rx_buffers.push_back(temp_buffer); 00436 }; 00437 00438 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00439 temp_buffer=NULL; 00440 d_rx_storage_buffers.push_back(temp_buffer); 00441 }; 00442 00443 00444 00445 for (uint32_t i1=0;i1<d_no_ant1;i1++) { 00446 temp_buffer=(std::complex<short int>*) d_tx_buffers[i1]; 00447 m1->d_tx_buffers.push_back(temp_buffer); 00448 temp_buffer=(std::complex<short int>*) d_rx_buffers[i1]; 00449 m1->d_rx_buffers.push_back(temp_buffer); 00450 }; 00451 00452 for (uint32_t i1=0;i1<d_no_ant2;i1++) { 00453 temp_buffer=(std::complex<short int>*) d_tx_buffers[i1+d_no_ant1]; 00454 m2->d_tx_buffers.push_back(temp_buffer); 00455 temp_buffer=(std::complex<short int>*) d_rx_buffers[i1+d_no_ant1]; 00456 m2->d_rx_buffers.push_back(temp_buffer); 00457 }; 00458 00459 00460 if (!d_simulate) { 00461 00462 std::string config; 00463 uint32_t temp; 00464 bool is_basic_1=false, is_xcvr2450_1=false, 00465 is_basic_2=false, is_xcvr2450_2=false; 00466 00467 00468 00469 if (d_no_ant1>0) { 00470 m1->d_mdev->set_rx_rate(d_rate); 00471 m1->d_mdev->set_tx_rate(d_rate); 00472 00473 00474 config = m1->d_mdev->get_pp_string(); 00475 00476 00477 temp=config.find("Basic"); 00478 if (temp<config.length()) 00479 is_basic_1=true; 00480 else 00481 is_basic_1=false; 00482 00483 temp=config.find("XCVR2450"); 00484 if (temp<config.length()) 00485 is_xcvr2450_1=true; 00486 else 00487 is_xcvr2450_1=false; 00488 00489 }; 00490 00491 if (d_no_ant2>0) { 00492 m2->d_mdev->set_rx_rate(d_rate); 00493 m2->d_mdev->set_tx_rate(d_rate); 00494 00495 config = m2->d_mdev->get_pp_string(); 00496 temp=config.find("Basic"); 00497 if (temp<config.length()) 00498 is_basic_2=true; 00499 else 00500 is_basic_2=false; 00501 00502 temp=config.find("XCVR2450"); 00503 if (temp<config.length()) 00504 is_xcvr2450_2=true; 00505 else 00506 is_xcvr2450_2=false; 00507 00508 }; 00509 00510 bool is_basic , is_xcvr2450; 00511 00512 is_basic=is_basic_1 | is_basic_2; 00513 is_xcvr2450=is_xcvr2450_1 | is_xcvr2450_2; 00514 00515 if (is_basic & is_xcvr2450) { 00516 std::cout << "Either basic db or xcvr2450 must be used, not both. \n"; 00517 exit(1); 00518 }; 00519 if (!(is_basic | is_xcvr2450)) { 00520 std::cout << "Either basic db or xcvr2450 must be used \n"; 00521 exit(1); 00522 }; 00523 00524 if (is_xcvr2450) { 00525 if (d_use_same_antenna) { 00526 for (uint32_t i1=0;i1<d_no_ant1;i1++) { 00527 m1->d_mdev->set_tx_antenna("J1",i1); 00528 m1->d_mdev->set_rx_antenna("J1",i1); 00529 } 00530 for (uint32_t i1=0;i1<d_no_ant2;i1++) { 00531 m2->d_mdev->set_tx_antenna("J1",i1); 00532 m2->d_mdev->set_rx_antenna("J1",i1); 00533 } 00534 } else { 00535 for (uint32_t i1=0;i1<d_no_ant1;i1++) { 00536 m1->d_mdev->set_tx_antenna("J2",i1); 00537 m1->d_mdev->set_rx_antenna("J1",i1); 00538 }; 00539 for (uint32_t i1=0;i1<d_no_ant2;i1++) { 00540 m2->d_mdev->set_tx_antenna("J2",i1); 00541 m2->d_mdev->set_rx_antenna("J1",i1); 00542 }; 00543 }; 00544 }; 00545 00546 if (is_basic) { 00547 uhd::usrp::subdev_spec_t spec("A:A"); 00548 for (uint32_t i1=0;i1<d_no_ant1;i1++) { 00549 m1->d_mdev->set_rx_subdev_spec(spec, i1); 00550 m1->d_mdev->set_tx_subdev_spec(spec, i1); 00551 }; 00552 for (uint32_t i1=0;i1<d_no_ant2;i1++) { 00553 m2->d_mdev->set_rx_subdev_spec(spec, i1); 00554 m2->d_mdev->set_tx_subdev_spec(spec, i1); 00555 }; 00556 00557 }; 00558 00559 if (d_no_ant1>0) 00560 m1->d_dev=m1->d_mdev->get_device(); 00561 if (d_no_ant2>0) 00562 m2->d_dev=m2->d_mdev->get_device(); 00563 00564 my_clock_config.pps_source=uhd::clock_config_t::PPS_SMA; 00565 my_clock_config.pps_polarity=uhd::clock_config_t::PPS_POS; 00566 00567 // Lock to 10MHz 00568 if (d_use_external_10MHz) 00569 my_clock_config.ref_source=uhd::clock_config_t::REF_SMA; 00570 else 00571 my_clock_config.ref_source=uhd::clock_config_t::REF_INT; 00572 }; 00573 00574 if (!d_simulate) { 00575 for (uint32_t i1=0;i1<d_no_ant1;i1++) 00576 m1->d_mdev->set_clock_config(my_clock_config, i1); 00577 00578 for (uint32_t i1=0;i1<d_no_ant2;i1++) 00579 m2->d_mdev->set_clock_config(my_clock_config, i1); 00580 }; 00581 00582 00583 usleep(1e5); 00584 00585 00586 } 00587 00588 00589 00590 00591 void four_multi_node::run(void) { 00592 run("",0); 00593 }; 00594 00595 00596 void four_multi_node::run(const char* device_name, uint32_t gps_time_combined){ 00597 00598 00599 frame_settings new_frame_settings; 00600 //uhd::tune_result_t tr; 00601 00602 00603 uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); // For reception 00604 uhd::rx_metadata_t md_rx; 00605 uhd::tx_metadata_t md_tx; 00606 00607 00608 md_tx.start_of_burst = true; 00609 md_tx.end_of_burst = true; 00610 md_tx.has_time_spec = true; 00611 00612 m1->md_tx=md_tx; 00613 m2->md_tx=md_tx; 00614 00615 00616 no_rx_buffer_stored_so_far=0; 00617 new_frame_settings=node_init(); 00618 00619 00620 if (!skip_hw_set_during_init) { 00621 set_trx_params(new_frame_settings); 00622 }; 00623 00624 00625 if (gps_time_combined>0) 00626 gps_wait_until(device_name,gps_time_combined); 00627 00628 00629 00630 const uhd::time_spec_t t0=time_available_for_trigger+headroom_after_trigger; // Seconds 00631 00632 if (set_time_on_pps) { 00633 // Sync the node to pps 00634 if (d_no_ant1>0) 00635 m1->d_mdev->set_time_next_pps(uhd::time_spec_t(0.0)); 00636 if (d_no_ant2>0) 00637 m2->d_mdev->set_time_next_pps(uhd::time_spec_t(0.0)); 00638 std::cout << "Wait for pps trigger!" << std::endl; 00639 usleep(1e6*time_available_for_trigger); 00640 std::cout << "Sync hopefully done" << std::endl; 00641 }; 00642 00643 00644 while (!(new_frame_settings.what==END)) { 00645 00646 std::cout << "time=" << new_frame_settings.time.get_real_secs() << std::endl; 00647 00648 switch (new_frame_settings.what) { 00649 00650 case TX: 00651 case CALIB_TXTX: 00652 m1->do_tx=true; 00653 m2->do_tx=true; 00654 break; 00655 case CALIB_TXRX: 00656 m1->do_tx=true; 00657 m2->do_tx=false; 00658 break; 00659 case CALIB_RXTX: 00660 m1->do_tx=false; 00661 m2->do_tx=true; 00662 break; 00663 case RX: 00664 case CALIB_RXRX: 00665 m1->do_tx=false; 00666 m2->do_tx=false; 00667 break; 00668 case START: 00669 /* Just to keep the compiler happy */ 00670 break; 00671 case END: 00672 std::cout << "END !! \n"; 00673 /* Just to keep the compiler happy */ 00674 break; 00675 }; 00676 00677 00678 m1->md_tx.time_spec = uhd::time_spec_t(t0+new_frame_settings.time); 00679 m1->stream_time=uhd::time_spec_t(t0+new_frame_settings.time); 00680 m2->md_tx.time_spec = uhd::time_spec_t(t0+new_frame_settings.time); 00681 m2->stream_time=uhd::time_spec_t(t0+new_frame_settings.time); 00682 00683 std::cout << "new_frame_settings.tx_repeats=" << 00684 new_frame_settings.tx_repeats << std::endl; 00685 00686 if (new_frame_settings.small_buffer_length!=0) { 00687 m1->d_buffer_length=new_frame_settings.small_buffer_length; 00688 m2->d_buffer_length=new_frame_settings.small_buffer_length; 00689 } ; 00690 if (new_frame_settings.tx_repeats!=0) { 00691 m1->tx_repeats=new_frame_settings.tx_repeats; 00692 m2->tx_repeats=new_frame_settings.tx_repeats; 00693 } ; 00694 00695 00696 if ((d_no_ant1>0) && (d_no_ant2>0)) { 00697 boost::thread m2t(*m2); 00698 (*m1)(); 00699 m2t.join(); 00700 }; 00701 if ((d_no_ant1>0) && (d_no_ant2==0)) { 00702 (*m1)(); 00703 }; 00704 if ((d_no_ant2>0) && (d_no_ant1==0)) { 00705 (*m2)(); 00706 }; 00707 00708 00709 if (new_frame_settings.small_buffer_length!=0) { 00710 m1->d_buffer_length=d_buffer_length; 00711 m2->d_buffer_length=d_buffer_length; 00712 }; 00713 if (new_frame_settings.tx_repeats!=0) { 00714 m1->tx_repeats=0; 00715 m2->tx_repeats=0; 00716 } ; 00717 00718 00719 00720 if (save_input_on_file) { 00721 if (new_frame_settings.what==RX) { 00722 if (new_frame_settings.small_buffer_length!=0) { 00723 log_raw_buffer(new_frame_settings.small_buffer_length); 00724 } else { 00725 log_raw_buffer(d_buffer_length); 00726 }; 00727 }; 00728 }; 00729 00730 00731 d_old_frame_settings=new_frame_settings; 00732 new_frame_settings=node_process(); 00733 00734 00735 //double new_freq, old_freq, new_gain_rx, old_gain_rx; 00736 //double new_gain_tx, old_gain_tx; 00737 00738 00739 if (!(new_frame_settings.what==END)) { 00740 set_trx_params(new_frame_settings,d_old_frame_settings); 00741 } ; 00742 00743 00744 00745 }; 00746 if (save_input_on_file) { 00747 save_logged_raw_data(); 00748 }; 00749 usleep(1e6*wait_time_for_transmissions_to_finish); 00750 // Just so that all outgoing frames have left. 00751 end_of_run(); 00752 std::cout << "Done !\n"; 00753 00754 }; 00755 00756 void four_multi_node::log_raw_buffer(uint32_t number_of_samples) { 00757 std::complex<int16_t> *p1; 00758 void *p2; 00759 00760 00761 //std::cout << "no_samples=" << number_of_samples << std::endl; 00762 if (no_rx_buffer_stored_so_far<d_max_no_frames_to_save) { 00763 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00764 p1=(std::complex<int16_t> *) d_rx_storage_buffers[i1]; 00765 p1=&p1[no_rx_buffer_stored_so_far*d_buffer_length]; 00766 p2=d_rx_buffers[i1]; 00767 memcpy (p1, p2 , number_of_samples*4 ); 00768 }; 00769 no_rx_buffer_stored_so_far++; 00770 }; 00771 }; 00772 00773 00774 void four_multi_node::save_logged_raw_data(void){ 00775 00776 std::string filename; 00777 std::stringstream temp_ss; 00778 00779 00780 if (no_rx_buffer_stored_so_far>0) { 00781 for (uint32_t i1=0;i1<no_rx_buffer_stored_so_far;i1++) { 00782 temp_ss << d_node_ix; 00783 filename=raw_data_dir+"node="+temp_ss.str()+"_"; 00784 temp_ss.str(""); 00785 temp_ss << i1; 00786 filename+="frame="+temp_ss.str()+".dat"; 00787 temp_ss.str(""); 00788 //std::cout << "d_buffer_length=" << d_buffer_length << std::endl; 00789 //std::cout << " filename=" << filename << std::endl; 00790 00791 std::ofstream s1(filename.c_str(), std::ios::binary); 00792 for (uint32_t i2=0;i2<d_no_ant;i2++) { 00793 //std::cout << "save_logged_raw_data i2=" << i2 << std::endl; 00794 s1.write(((char *) d_rx_storage_buffers[i2]) + 00795 4*i1*d_buffer_length, 00796 d_buffer_length*4); 00797 }; 00798 00799 s1.flush(); 00800 s1.close(); 00801 00802 } 00803 }; 00804 00805 00806 } 00807 00808 00809 void four_multi_node::x2_tx_udp(uint32_t other_node_ix ,const void * pointer_to_data, 00810 uint32_t size) { 00811 00812 00813 00814 00815 try { 00816 std::stringstream temp_ss; 00817 boost::asio::io_service io_service; 00818 udp::socket socket(io_service, udp::endpoint(udp::v4(),0)); 00819 udp::resolver resolver(io_service); 00820 temp_ss << 2000+d_node_ix*100+other_node_ix; 00821 udp::resolver::query query(udp::v4(), d_IP_addresses[other_node_ix], temp_ss.str()); 00822 udp::endpoint receiver_endpoint = *resolver.resolve(query); 00823 00824 00825 socket.send_to(boost::asio::buffer(pointer_to_data,size), receiver_endpoint); 00826 socket.close(); 00827 00828 00829 } 00830 catch (std::exception& e) 00831 { 00832 std::cout << "exception in x2_tx_udp \n"; 00833 std::cerr << e.what() << std::endl; 00834 } 00835 00836 } 00837 00838 void four_multi_node::x2_tx(uint32_t other_node_ix ,const void * pointer_to_data, 00839 uint32_t size) { 00840 00841 if (use_udp && (!d_simulate)) 00842 x2_tx_udp(other_node_ix,pointer_to_data,size); 00843 else 00844 x2_tx_tcp(other_node_ix,pointer_to_data,size); 00845 00846 } 00847 00848 00849 void four_multi_node::x2_tx_tcp(uint32_t other_node_ix ,const void * pointer_to_data, 00850 uint32_t size) 00851 { 00852 00853 00854 if (d_simulate) { 00855 bool empty; 00856 00857 00858 empty=(feedback_buffers_empty)[other_node_ix+num_nodes*d_node_ix]; 00859 if (!empty) { 00860 std::cerr << "Feedback buffer not empty! \n"; 00861 exit(1); 00862 }; 00863 00864 // Create room and copy the data 00865 void *p; 00866 p=malloc(size); 00867 memcpy (p,pointer_to_data,size); 00868 feedback_buffers[other_node_ix+num_nodes*d_node_ix]=p; 00869 (feedback_buffers_empty)[other_node_ix+num_nodes*d_node_ix]=false; 00870 00871 00872 } else { 00873 00874 00875 00876 try { 00877 00878 00879 boost::asio::io_service io_service; 00880 tcp::resolver resolver(io_service); 00881 std::stringstream temp_ss; 00882 00883 temp_ss << 2000+d_node_ix*100+other_node_ix; 00884 tcp::resolver::query query(d_IP_addresses[other_node_ix], temp_ss.str()); 00885 tcp::resolver::iterator endpoint_iterator; 00886 endpoint_iterator = resolver.resolve(query); 00887 resolver.resolve(query); 00888 00889 tcp::resolver::iterator end; 00890 tcp::socket socket(io_service); 00891 boost::system::error_code error = boost::asio::error::host_not_found; 00892 00893 while (error && endpoint_iterator != end) 00894 { 00895 socket.close(); 00896 socket.connect(*endpoint_iterator, error); 00897 while (error==boost::system::errc::connection_refused) { 00898 socket.connect(*endpoint_iterator, error); 00899 usleep(100); 00900 }; 00901 endpoint_iterator++; 00902 } 00903 00904 if (error) { 00905 std::cout << "error=" << error << "\n"; 00906 throw boost::system::system_error(error); 00907 }; 00908 00909 boost::system::error_code ignored_error; 00910 boost::asio::write(socket, 00911 boost::asio::buffer(pointer_to_data,size), 00912 boost::asio::transfer_all(), ignored_error); 00913 00914 } 00915 catch (std::exception& e) 00916 { 00917 std::cerr << e.what() << std::endl; 00918 } 00919 00920 }; 00921 00922 return; 00923 00924 00925 00926 }; 00927 00928 00929 void four_multi_node::x2_rx(uint32_t other_node_ix ,void *pointer_to_data, 00930 uint32_t size) { 00931 00932 if (use_udp && (!d_simulate)) 00933 x2_rx_udp(other_node_ix,pointer_to_data,size); 00934 else 00935 x2_rx_tcp(other_node_ix,pointer_to_data,size); 00936 00937 } 00938 void four_multi_node::x2_rx_tcp(uint32_t other_node_ix ,void *pointer_to_data, 00939 uint32_t size) { 00940 00941 00942 if (d_simulate) { 00943 bool empty; 00944 empty=(feedback_buffers_empty)[d_node_ix+other_node_ix*num_nodes]; 00945 if (empty) { 00946 std::cerr << "Feedback buffer is empty! \n"; 00947 exit(1); 00948 }; 00949 00950 // Copy the data 00951 void *p; 00952 p=feedback_buffers[d_node_ix+num_nodes*other_node_ix]; 00953 memcpy(pointer_to_data,p,size); 00954 (feedback_buffers_empty)[d_node_ix+num_nodes*other_node_ix]=true; 00955 00956 // Free the memory 00957 free(p); 00958 00959 } 00960 else 00961 { 00962 00963 00964 00965 00966 try 00967 { 00968 boost::system::error_code error; 00969 boost::asio::io_service io_service; 00970 tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 2000+other_node_ix*100+d_node_ix)); 00971 00972 00973 { 00974 tcp::socket socket(io_service); 00975 acceptor.accept(socket); 00976 00977 boost::asio::ip::tcp::endpoint remote_ep = socket.remote_endpoint(); 00978 address remote_ad = remote_ep.address(); 00979 std::string new_ip_address = remote_ad.to_string(); 00980 std::cout << "received call from: " << new_ip_address << std::endl; 00981 00982 size_t len=socket.read_some(boost::asio::buffer(pointer_to_data,size), error); 00983 00984 while (len<size) { 00985 std::cout << "Extra read_some \n"; 00986 void *p; 00987 p=pointer_to_data; 00988 p=(void* ) (((char*) p)+len/sizeof(char)); 00989 size_t len1=socket.read_some(boost::asio::buffer(p,size-len), error); 00990 len=len+len1; 00991 }; 00992 00993 00994 //boost::system::error_code ignored_error; 00995 //boost::asio::write(socket, boost::asio::buffer(response_ip_address), 00996 //boost::asio::transfer_all(), ignored_error); 00997 00998 socket.close(); 00999 } 01000 } 01001 catch (std::exception& e) 01002 { 01003 std::cerr << e.what() << std::endl; 01004 } 01005 01006 }; 01007 01008 01009 }; 01010 01011 void four_multi_node::x2_rx_udp(uint32_t other_node_ix ,void * const 01012 pointer_to_data, uint32_t size) { 01013 01014 udp_function_thread_class n0p; 01015 n0p.this_node_ix=d_node_ix; 01016 n0p.other_node_ix=other_node_ix; 01017 n0p.pointer_to_data=pointer_to_data; 01018 n0p.num_bytes=size; 01019 boost::thread n0t(n0p); 01020 n0t.join(); 01021 01022 01023 } 01024 01025 void four_multi_node::x2_rx(std::vector<uint32_t> other_node_ixs ,std::vector<void *> const pointers_to_data, std::vector<uint32_t> num_bytess) { 01026 01027 if (use_udp && (!d_simulate)) 01028 x2_rx_udp(other_node_ixs,pointers_to_data,num_bytess); 01029 else 01030 x2_rx_tcp(other_node_ixs,pointers_to_data,num_bytess); 01031 } 01032 01033 01034 void four_multi_node::x2_rx_tcp(std::vector<uint32_t> other_node_ixs ,std::vector<void *> const pointers_to_data, std::vector<uint32_t> num_bytess) { 01035 01036 for (uint32_t i1=0;i1< other_node_ixs.size();i1++) { 01037 x2_rx_tcp(other_node_ixs[i1],pointers_to_data[i1],num_bytess[i1]); 01038 }; 01039 01040 } 01041 01042 01043 void four_multi_node::x2_rx_udp(std::vector<uint32_t> other_node_ixs ,std::vector<void *> pointers_to_data, std::vector<uint32_t> num_bytess) { 01044 01045 01046 udp_function_thread_class n0p; 01047 n0p.this_node_ix=d_node_ix; 01048 n0p.other_node_ix=other_node_ixs[0]; 01049 n0p.pointer_to_data=pointers_to_data[0]; 01050 n0p.num_bytes=num_bytess[0]; 01051 boost::thread n0t(n0p); 01052 if (other_node_ixs.size()>1) { 01053 udp_function_thread_class n1p; 01054 n1p.this_node_ix=d_node_ix; 01055 n1p.other_node_ix=other_node_ixs[1]; 01056 n1p.pointer_to_data=pointers_to_data[1]; 01057 n1p.num_bytes=num_bytess[1]; 01058 boost::thread n1t(n1p); 01059 if (other_node_ixs.size()>2) { 01060 udp_function_thread_class n2p; 01061 n2p.this_node_ix=d_node_ix; 01062 n2p.other_node_ix=other_node_ixs[2]; 01063 n2p.pointer_to_data=pointers_to_data[2]; 01064 n2p.num_bytes=num_bytess[2]; 01065 boost::thread n2t(n2p); 01066 if (other_node_ixs.size()>3) { 01067 std::cerr << "x2_rx_udp can currently only take max 3 subnodes \n"; 01068 }; 01069 n2t.join(); 01070 }; 01071 n1t.join(); 01072 }; 01073 n0t.join(); 01074 01075 } 01076 01077 01078 void four_multi_node::set_trx_params(frame_settings fs_new, frame_settings fs_old) { 01079 01080 uhd::tune_result_t tr; 01081 double old_freq, new_freq, new_gain_tx, old_gain_tx, new_gain_rx, old_gain_rx; 01082 01083 for (uint32_t i1=0;i1<d_no_ant1;i1++) { 01084 if (i1<fs_old.frequency.size()) 01085 old_freq=fs_old.frequency[i1]; 01086 else { 01087 old_freq=fs_old.frequency.back(); 01088 }; 01089 01090 if (i1<fs_new.frequency.size()) 01091 new_freq=fs_new.frequency[i1]; 01092 else 01093 new_freq=fs_new.frequency.back(); 01094 01095 if (!(old_freq==new_freq)) { 01096 std::cout << "NEW FREQUENCY !!! \n"; 01097 tr=m1->d_mdev->set_rx_freq(new_freq,i1); 01098 }; 01099 01100 01101 if (i1<fs_old.gain_rx.size()) 01102 old_gain_rx=fs_old.gain_rx[i1]; 01103 else 01104 old_gain_rx=fs_old.gain_rx.back(); 01105 01106 if (i1<fs_new.gain_rx.size()) 01107 new_gain_rx=fs_new.gain_rx[i1]; 01108 else 01109 new_gain_rx=fs_new.gain_rx.back(); 01110 01111 if (!(old_gain_rx==new_gain_rx)) { 01112 std::cout << "NEW RX GAIN !!! \n"; 01113 m1->d_mdev->set_rx_gain(new_gain_rx,i1); 01114 } 01115 01116 if (i1<fs_old.gain_tx.size()) 01117 old_gain_tx=fs_old.gain_tx[i1]; 01118 else 01119 old_gain_tx=fs_old.gain_tx.back(); 01120 01121 if (i1<fs_new.gain_tx.size()) 01122 new_gain_tx=fs_new.gain_tx[i1]; 01123 else 01124 new_gain_tx=fs_new.gain_tx.back(); 01125 01126 if (!(old_gain_tx==new_gain_tx)) { 01127 std::cout << "NEW TX GAIN !!! \n"; 01128 m1->d_mdev->set_tx_gain(new_gain_tx,i1); 01129 std::cout << "new_gain_tx=" << new_gain_tx << std::endl; 01130 } 01131 01132 01133 }; 01134 for (uint32_t i2=0;i2<d_no_ant2;i2++) { 01135 01136 01137 uint32_t i1; 01138 i1=i2+d_no_ant1; 01139 01140 if (i1<fs_old.frequency.size()) 01141 old_freq=fs_old.frequency[i1]; 01142 else { 01143 old_freq=fs_old.frequency.back(); 01144 }; 01145 if (i1<fs_new.frequency.size()) 01146 new_freq=fs_new.frequency[i1]; 01147 else 01148 new_freq=fs_new.frequency.back(); 01149 01150 01151 if (!(old_freq==new_freq)) { 01152 tr=m2->d_mdev->set_rx_freq(i2,new_freq); 01153 }; 01154 01155 if (i1<fs_old.gain_rx.size()) 01156 old_gain_rx=fs_old.gain_rx[i1]; 01157 else 01158 old_gain_rx=fs_old.gain_rx.back(); 01159 01160 if (i1<fs_new.gain_rx.size()) 01161 new_gain_rx=fs_new.gain_rx[i1]; 01162 else 01163 new_gain_rx=fs_new.gain_rx.back(); 01164 01165 if (!(old_gain_rx==new_gain_rx)) { 01166 m2->d_mdev->set_rx_gain(new_gain_rx,i2); 01167 } 01168 if (i1<fs_old.gain_tx.size()) 01169 old_gain_tx=fs_old.gain_tx[i1]; 01170 else 01171 old_gain_tx=fs_old.gain_tx.back(); 01172 01173 if (i1<fs_new.gain_tx.size()) 01174 new_gain_tx=fs_new.gain_tx[i1]; 01175 else 01176 new_gain_tx=fs_new.gain_tx.back(); 01177 01178 if (!(old_gain_tx==new_gain_tx)) { 01179 m2->d_mdev->set_tx_gain(new_gain_tx,i2); 01180 }; 01181 01182 01183 }; 01184 01185 }; 01186 01187 01188 void four_multi_node::set_trx_params(frame_settings fs) { 01189 uhd::tune_result_t tr; 01190 01191 for (uint32_t i1=0;i1<d_no_ant1;i1++) { 01192 if (i1<fs.frequency.size()) { 01193 tr=m1->d_mdev->set_rx_freq(fs.frequency[i1],i1); 01194 tr=m1->d_mdev->set_tx_freq(fs.frequency[i1],i1); 01195 } else { 01196 tr=m1->d_mdev->set_rx_freq(fs.frequency.back(),i1); 01197 tr=m1->d_mdev->set_tx_freq(fs.frequency.back(),i1); 01198 }; 01199 if (i1<fs.gain_rx.size()) { 01200 m1->d_mdev->set_rx_gain(fs.gain_rx[i1],i1); 01201 } else 01202 m1->d_mdev->set_rx_gain(fs.gain_rx.back(),i1); 01203 01204 if (i1<fs.gain_tx.size()) { 01205 m1->d_mdev->set_tx_gain(fs.gain_tx[i1],i1); 01206 } else { 01207 m1->d_mdev->set_tx_gain(fs.gain_tx.back(),i1); 01208 }; 01209 }; 01210 for (uint32_t i2=0;i2<d_no_ant2;i2++) { 01211 uint32_t i1; 01212 i1=i2+d_no_ant1; 01213 01214 if (i1<fs.frequency.size()) { 01215 tr=m2->d_mdev->set_rx_freq(fs.frequency[i1],i2); 01216 tr=m2->d_mdev->set_tx_freq(fs.frequency[i1],i2); 01217 } 01218 else { 01219 tr=m2->d_mdev->set_rx_freq(fs.frequency.back(),i2); 01220 tr=m2->d_mdev->set_tx_freq(fs.frequency.back(),i2); 01221 }; 01222 01223 if (i1<fs.gain_rx.size()) { 01224 m2->d_mdev->set_rx_gain(fs.gain_rx[i1],i2); 01225 } 01226 else 01227 m2->d_mdev->set_rx_gain(fs.gain_rx.back(),i2); 01228 01229 if (i1<fs.gain_tx.size()) 01230 m2->d_mdev->set_tx_gain(fs.gain_tx[i1],i2); 01231 else 01232 m2->d_mdev->set_tx_gain(fs.gain_tx.back(),i2); 01233 01234 }; 01235 01236 } 01237 01238 #if 0 01239 void four_multi_node::change_buffer_length(uint32_t new_buffer_length){ 01240 01241 std::complex<int16_t> *temp_buffer; 01242 for (uint32_t i1=0;i1<d_no_ant;i1++) { 01243 temp_buffer=(std::complex<int16_t> *) d_tx_buffers[i1]; 01244 delete[] temp_buffer; 01245 temp_buffer=new std::complex<int16_t>[new_buffer_length]; 01246 d_tx_buffers[i1]=temp_buffer; 01247 }; 01248 01249 for (uint32_t i1=0;i1<d_no_ant;i1++) { 01250 temp_buffer=(std::complex<int16_t> *) d_rx_buffers[i1]; 01251 delete[] temp_buffer; 01252 temp_buffer=new std::complex<int16_t>[new_buffer_length]; 01253 d_rx_buffers[i1]=temp_buffer; 01254 }; 01255 01256 d_buffer_length=new_buffer_length; 01257 01258 }; 01259 #endif