four_multi
Multi-Antenna,Multi-Node,Multi-Band,Multi-Cell
core/four_multi.cpp
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
 All Classes Functions Variables