Fixed spelling error: s/writeable/writable/g
[debian/gnuradio] / gr-msdd6000 / src / lib / msdd_source_base.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2008 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 //#define MSDD_DEBUG_TRUE
24 //#define MSDD_DEBUG2_TRUE
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <msdd_source_base.h>
31 #include <gr_io_signature.h>
32 #include <assert.h>
33 #include <netdb.h>
34 #include <omnithread.h>
35 #include <stdexcept>
36 #include <sys/socket.h>
37 #include <arpa/inet.h>
38
39 #ifdef MSDD_DEBUG_TRUE
40 #include <iostream>
41 #define MSDD_DEBUG(x) std::cout << x << std::endl;
42 #else
43 #define MSDD_DEBUG(x)
44 #endif
45
46
47 #ifdef MSDD_DEBUG2_TRUE
48 #include <iostream>
49 #define MSDD_DEBUG2(x) std::cout << x << std::endl;
50 #else
51 #define MSDD_DEBUG2(x)
52 #endif
53
54 #include <iostream>
55
56 namespace {
57   const int OUTPUT_MAX((1 << 15)*8);
58   const double PGA_MAX(75);
59   const double PGA_MIN(10);
60   const double PGA_STEP(.5);
61   const double DEFAULT_RX_FREQ(2.417e6);
62   const double DEFAULT_GAIN(32);
63   const msdd_source_base::msdd_fft_mode_t DEFAULT_FFT_MODE(msdd_source_base::MODE_MAG);
64   const msdd_source_base::msdd_fft_points_t DEFAULT_FFT_POINTS(msdd_source_base::S8192);
65   const msdd_source_base::msdd_decimation_t DEFAULT_DECIMATION_RATE(msdd_source_base::D2);
66 }
67
68 class msdd_source_base::Impl {
69   
70 public:
71   Impl(int opp_mode) :
72     d_noverruns (0),
73     d_deci_rate (DEFAULT_DECIMATION_RATE),
74     d_rx_freq ((unsigned long) DEFAULT_RX_FREQ),
75     d_gain(DEFAULT_GAIN),
76     d_verbose (false),
77     d_updated(false),
78     d_msdd_command_type((msdd_command_type_t) opp_mode),
79     d_msdd_fft_mode(DEFAULT_FFT_MODE),
80     d_desired_sample_size(2^15),
81     d_fft_points (DEFAULT_FFT_POINTS)
82   {
83   }
84
85   int            d_noverruns;
86   msdd_decimation_t   d_deci_rate;
87   unsigned long  d_rx_freq;
88   double         d_gain;
89   bool           d_verbose;
90   bool           d_updated;  
91   msdd_command_type_t d_msdd_command_type;
92   msdd_fft_mode_t d_msdd_fft_mode;
93   unsigned long  d_desired_sample_size;
94   
95   int            d_socket;        // handle to socket
96   int            d_socket_rcv;    // handle to socket retuned in the accept call
97   struct in_addr d_ip_src;        // store the source IP address to use
98   unsigned short d_port_src;      // the port number to open for connections to this service
99   sockaddr_in    d_sockaddr_src;  // store the source sockaddr data (formatted IP address and port number) 
100   std::auto_ptr<unsigned char> d_temp_buff;     // hold buffer between calls
101   
102   omni_mutex    d_mutex;
103   msdd_fft_points_t   d_fft_points; 
104   
105   struct msdd_request_fft_packet {
106     msdd_command_type_t command_type;
107     int foo_x20;
108     unsigned int center_freq_mhz;
109     int offset_freq_hz;
110     int gain;
111     msdd_fft_window_type_t window_type;
112     msdd_fft_points_t fft_points;
113     msdd_decimation_t decimation;
114     msdd_fft_mode_t fft_mode;
115     int number_sets;
116   } __attribute__((__packed__));
117   
118   struct msdd_request_iq_packet {
119     msdd_command_type_t command_type;
120     int foo0x18;
121     unsigned int center_freq_mhz;
122     int offset_freq_hz;
123     int gain;
124     int number;
125     msdd_decimation_t decimation;
126     int number_sets;
127   } __attribute__((__packed__));
128
129   void make_request_fft_packet(msdd_request_fft_packet& packet);
130   
131   void make_request_iq_packet(msdd_request_iq_packet& packet, unsigned int number_samples);
132   
133   msdd_request_fft_packet   d_fft_request_packet; // fft request packet
134   msdd_request_iq_packet    d_iq_request_packet; // fft request packet
135 };
136
137
138 msdd_source_base::msdd_source_base (const std::string &name,
139                                     gr_io_signature_sptr output_signature,
140                                     int which_board,
141                                     int opp_mode,
142                                     const char *src, 
143                                     unsigned short port_src
144                                     ) throw (std::runtime_error)
145   : gr_sync_block (name,
146                    gr_make_io_signature (0, 0, 0),
147                    output_signature),
148     pimpl(new Impl(opp_mode))
149 {
150   int ret (0);
151     
152   // Set up the address stucture for the source address and port numbers
153   // Get the source IP address from the host name
154   struct hostent *hsrc (gethostbyname(src));
155     
156   if(hsrc) {   // if the source was provided as a host namex
157     pimpl->d_ip_src = *(struct in_addr*)hsrc->h_addr_list[0];    
158   }
159   else { // assume it was specified as an IP address
160     if((ret=inet_aton(src, &pimpl->d_ip_src)) == 0) {            // format IP address
161       perror("Not a valid source IP address or host name");
162       throw std::runtime_error("can't initialize source socket");
163     }
164   }
165     
166   pimpl->d_port_src = htons(port_src);     // format port number
167   
168   pimpl->d_sockaddr_src.sin_family = AF_INET;
169   pimpl->d_sockaddr_src.sin_addr   = pimpl->d_ip_src;
170   pimpl->d_sockaddr_src.sin_port   = pimpl->d_port_src;
171   
172   pimpl->d_temp_buff.reset(new unsigned char[OUTPUT_MAX + 
173                                              std::max(sizeof(Impl::msdd_request_iq_packet),
174                                                       sizeof(Impl::msdd_request_fft_packet))]);   // allow it to hold up to payload_size bytes
175   
176   set_output_multiple (OUTPUT_MAX / output_signature->sizeof_stream_item (0));
177 }
178                                       
179
180 bool
181 msdd_source_base::open()
182 {
183   omni_mutex_lock l(pimpl->d_mutex);   // hold mutex for duration of this function
184   // create socket
185   MSDD_DEBUG2("MSDD: Before socket ")
186   pimpl->d_socket = socket(PF_INET, SOCK_DGRAM, 0);
187   if(pimpl->d_socket == -1) {
188     perror("socket open");
189     throw std::runtime_error("can't open socket");
190   }
191
192   // Turn on reuse address
193   int opt_val (1);
194   if(setsockopt(pimpl->d_socket, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(int)) == -1) {
195     perror("SO_REUSEADDR");
196     throw std::runtime_error("can't set socket option SO_REUSEADDR");
197   }
198
199   // Don't wait when shutting down
200   linger lngr;
201   lngr.l_onoff  = 1;
202   lngr.l_linger = 0;
203   if(setsockopt(pimpl->d_socket, SOL_SOCKET, SO_LINGER, (void*)&lngr, sizeof(linger)) == -1) {
204     perror("SO_LINGER");
205     throw std::runtime_error("can't set socket option SO_LINGER");
206   }
207
208   // Set a timeout on the receive function to not block indefinitely
209   // This value can (and probably should) be changed
210   //  timeval timeout;
211   //  timeout.tv_sec = 1;
212   //  timeout.tv_usec = 0;
213   //  if(setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, sizeof(timeout)) == -1) {
214   //    perror("SO_RCVTIMEO");
215   //    throw std::runtime_error("can't set socket option SO_RCVTIMEO");
216   //  }
217
218   // bind socket to an address and port number to listen on
219   MSDD_DEBUG2("MSDD: Before socket bind to " << pimpl->d_sockaddr_src.sin_port)
220   if(::connect(pimpl->d_socket, (struct sockaddr*)&pimpl->d_sockaddr_src, sizeof(pimpl->d_sockaddr_src)) == -1) {
221     perror("socket bind");
222     throw std::runtime_error("can't bind socket");
223   }
224   MSDD_DEBUG2("MSDD: Socket open")
225
226   // Turn streaming service on
227   write_request_packet(pimpl->d_desired_sample_size);
228   
229   pimpl->d_updated = true;
230   return pimpl->d_socket != 0;
231 }
232
233 /* read n bytes from a socket descriptor */
234 int 
235 msdd_source_base::readsock(int sockfd, unsigned char* buf, int nbytes) {
236   int nleft (nbytes);
237   int nread (0);
238     
239   while (nleft > 0) {
240     MSDD_DEBUG2("MSDD: Before socket read: " << nleft)
241     if ((nread = ::read(sockfd, buf, nleft)) < 0) {
242       return(nread); /* error, nread < 0 */
243     } else if (nread == 0) {
244       break;
245     }
246             
247     nleft -= nread;
248     buf += nread;
249   }
250   return(nbytes - nleft);
251 }
252
253 bool
254 msdd_source_base::close()
255 {
256   omni_mutex_lock l(pimpl->d_mutex);   // hold mutex for duration of this function
257
258   //This should turn off UDP streaming but does not yet work
259   //write_request_packet(0);
260   
261   if (pimpl->d_socket){
262     shutdown(pimpl->d_socket, SHUT_RDWR);
263     pimpl->d_socket = 0;
264   }
265   pimpl->d_updated = true;
266   
267   return true;
268 }
269
270 msdd_source_base::~msdd_source_base ()
271 {
272   msdd_source_base::close();
273 }
274
275 unsigned int
276 msdd_source_base::sizeof_basic_sample() const
277 {
278   switch (pimpl->d_msdd_command_type) {
279   case SAMPLES_REALTIME:
280     return 4;
281   case SAMPLES_FFT:
282     switch (pimpl->d_msdd_fft_mode) {
283     case MODE_IQ:
284     case MODE_MAG:
285       return 4;
286     case MODE_MAGDB:
287       return 1;
288     default:
289       assert (false); // bad mode
290     }
291   default:
292     assert (false); // bad mode
293   }
294 }
295
296 bool
297 msdd_source_base::start()
298 {
299   return msdd_source_base::open();
300 }
301
302 bool
303 msdd_source_base::stop()
304 {
305   return msdd_source_base::close();
306 }
307
308 void
309 msdd_source_base::write_request_packet(unsigned int number_samples)
310 {
311   unsigned int packet_size;
312   void* request_packet = msdd_source_base::make_request_packet(packet_size, number_samples);
313   int result_nbytes = ::write(pimpl->d_socket, request_packet, packet_size);
314   MSDD_DEBUG2("MSDD: wrote control command: " << result_nbytes)
315
316   // receive ack
317   result_nbytes = ::read (pimpl->d_socket, (unsigned char*) request_packet, packet_size);
318   MSDD_DEBUG2("MSDD: response: " << result_nbytes)
319 }
320
321
322 void* 
323 msdd_source_base::make_request_packet(unsigned int& size, unsigned int number_samples) {
324   switch (pimpl->d_msdd_command_type) {
325   case SAMPLES_REALTIME:
326     pimpl->make_request_iq_packet(pimpl->d_iq_request_packet, number_samples);
327     size = sizeof (pimpl->d_iq_request_packet);
328     return &pimpl->d_iq_request_packet;
329   case SAMPLES_FFT:
330     pimpl->make_request_fft_packet(pimpl->d_fft_request_packet);
331     size = sizeof (pimpl->d_fft_request_packet);
332     return &pimpl->d_fft_request_packet;
333   default:
334     assert (false); // bad mode
335   }
336 }
337
338 void 
339 msdd_source_base::Impl::make_request_fft_packet(msdd_request_fft_packet& packet) 
340 {
341   packet.command_type = SAMPLES_FFT;  // FFT samples Command
342   packet.foo_x20 = 0x20;
343   packet.center_freq_mhz = d_rx_freq;
344   packet.offset_freq_hz = 0;
345   packet.gain = (int) d_gain; // gain
346   packet.window_type = WINDOW_HANNING; // magic number
347   packet.fft_points = d_fft_points;
348   packet.decimation = d_deci_rate;
349   packet.fft_mode = MODE_MAGDB;
350   packet.number_sets = 1;
351 }
352
353 void 
354 msdd_source_base::Impl::make_request_iq_packet(msdd_request_iq_packet& packet, unsigned int number_samples) 
355 {
356   packet.command_type = SAMPLES_REALTIME;  // IQ samples Command
357   packet.foo0x18 = 0x18; // magic number
358   packet.center_freq_mhz = d_rx_freq;
359   packet.offset_freq_hz = 0;
360   packet.gain = (int) d_gain; // gain
361   packet.number = number_samples * 4;
362   packet.decimation = d_deci_rate;
363   packet.number_sets = 1;
364 }
365
366 int
367 msdd_source_base::work (int noutput_items,
368                         gr_vector_const_void_star &input_items,
369                         gr_vector_void_star &output_items)
370 {
371   int output_index (0);
372   int output_items_produced;
373   int bytes_read;
374   
375   MSDD_DEBUG("MSDD: requested items: " << noutput_items)
376   int noutput_items_desired = std::min (noutput_items, (int) pimpl->d_desired_sample_size);
377   MSDD_DEBUG("MSDD: desired items: " << noutput_items_desired)
378     
379   while (output_index < noutput_items_desired){
380
381     int nbytes = (pimpl->d_msdd_command_type == SAMPLES_REALTIME) ? 
382       ninput_bytes_reqd_for_noutput_items (noutput_items_desired - output_index) :
383       ninput_bytes_reqd_for_noutput_items (msdd_source_base::fft_points());
384     
385     nbytes = std::min (nbytes, OUTPUT_MAX);
386     MSDD_DEBUG2("MSDD: payload sizes: nbytes1: " << nbytes )
387     
388     // receive payload
389     int result_nbytes = msdd_source_base::readsock (pimpl->d_socket, pimpl->d_temp_buff.get(), nbytes);
390     MSDD_DEBUG("MSDD: reading bytes: " << nbytes << " received: " << result_nbytes)
391     if (result_nbytes > (int) nbytes){
392       // fprintf (stderr, "msdd_source: overrun\n");
393       fputs ("uO", stderr);
394       pimpl->d_noverruns++;
395       result_nbytes = nbytes; // truncate
396     }
397     
398     if (result_nbytes < 0)      // We've got a problem.  Usually board unplugged or powered down.
399       return -1;                // Indicate we're done.
400
401     if (result_nbytes != nbytes){       // not really an error, but unexpected
402       fprintf (stderr, "msdd_source: short read.  Expected %d, got %d\n",
403                nbytes, result_nbytes);
404     }
405
406     copy_from_msdd_buffer (output_items,
407                            output_index,
408                            noutput_items_desired - output_index,   // output_items_available
409                            output_items_produced,          // [out]
410                            pimpl->d_temp_buff.get(),                               // usrp_buffer
411                            result_nbytes,
412                            bytes_read);                    // [out]
413     
414     output_index += output_items_produced;
415     
416     if (pimpl->d_msdd_command_type == SAMPLES_FFT) break; 
417   }
418
419   MSDD_DEBUG("MSDD: items produced: " << output_items_produced << " index: " << output_index)
420   
421   //assert(false);
422   return output_index;
423 }
424
425
426 bool
427 msdd_source_base::set_decim_rate (unsigned int rate)
428 {
429   bool result (true);
430   switch (rate) {
431   case 1:
432     pimpl->d_deci_rate = D0;
433     break;
434   case 2:
435     pimpl->d_deci_rate = D1;
436     break;      
437   case 4:
438     pimpl->d_deci_rate = D2;
439     break;        
440   case 8:
441     pimpl->d_deci_rate = D3;
442     break;        
443   case 16:
444     pimpl->d_deci_rate = D4;
445     break;
446   case 32:
447     pimpl->d_deci_rate = D5;
448     break;
449   case 64:
450     pimpl->d_deci_rate = D6;
451     break;
452   case 128:
453     pimpl->d_deci_rate = D7;
454     break;
455   case 256:
456     pimpl->d_deci_rate = D8;
457     break;
458   default:
459     result = false;
460   }
461   
462   // Resubmit the control to update the decimation rate
463   write_request_packet(pimpl->d_desired_sample_size);
464
465   return result;
466 }
467 //
468 //bool
469 //msdd_source_base::set_nchannels (int nchan)
470 //{
471 //  // return d_usrp->set_nchannels (nchan);
472 //      return true;
473 //}
474 //
475 //bool
476 //msdd_source_base::set_mux (int mux)
477 //{
478 //  return d_usrp->set_mux (mux);
479 //}
480
481 bool
482 msdd_source_base::set_rx_freq (int channel, double freq)
483 {
484   assert (channel == 0);
485   bool result (false);
486   
487   if (freq >=  30e6 && freq <= 6e9) {
488     pimpl->d_rx_freq = (unsigned long) freq / 1000000;
489     result = true;
490   }
491
492   // Resubmit the control to update the RX frequency
493   write_request_packet(pimpl->d_desired_sample_size);
494   
495   return result;
496 }
497
498
499 unsigned long
500 msdd_source_base::set_fft_size (int channel, unsigned long fft_size)
501 {
502   assert (channel == 1);
503   
504   switch (fft_size) {
505   case 256:        
506     pimpl->d_fft_points = S256;
507     break;
508   case 512:
509     pimpl->d_fft_points = S512;       
510     break;
511   case 1024:
512     pimpl->d_fft_points = S1024;
513     break;        
514   case 2048:
515     pimpl->d_fft_points = S2048;
516     break;        
517   case 4096:
518     pimpl->d_fft_points = S4096;
519     break;        
520   case 8192:
521     pimpl->d_fft_points = S8192;
522     break;        
523   case 16384:
524     pimpl->d_fft_points = S16384;
525     break;        
526   case 32768:
527     pimpl->d_fft_points = S32768;
528     break;        
529   }
530
531   // Resubmit the control to update the FFT size
532   write_request_packet(pimpl->d_desired_sample_size);
533   
534   return msdd_source_base::fft_points();
535 }
536
537 //
538 //long
539 //msdd_source_base::fpga_master_clock_freq() const
540 //{
541 //  return d_usrp->fpga_master_clock_freq();
542 //}
543 //
544 //long
545 //msdd_source_base::converter_rate() const
546 //{
547 //  // return d_usrp->converter_rate();
548 //      return 8;
549 //}
550
551 unsigned int
552 msdd_source_base::decim_rate () const
553 {
554   return 1 << pimpl->d_deci_rate;
555 }
556 //
557 //int
558 //msdd_source_base::nchannels () const
559 //{
560 //  return d_usrp->nchannels ();
561 //}
562 //
563 //int
564 //msdd_source_base::mux () const
565 //{
566 //  return d_usrp->mux ();
567 //}
568
569 double
570 msdd_source_base::rx_freq (int channel) const
571 {
572   assert (channel == 0);
573   
574   return pimpl->d_rx_freq;
575 }
576
577 unsigned int
578 msdd_source_base::fft_points() const
579 {
580   return (1 << pimpl->d_fft_points);
581 }
582
583 int 
584 msdd_source_base::noverruns () const 
585
586   return pimpl->d_noverruns; 
587 }
588
589 //bool
590 //msdd_source_base::set_fpga_mode (int mode)
591 //{
592 //  return d_usrp->set_fpga_mode (mode);
593 //}
594 //
595 //bool
596 //msdd_source_base::set_ddc_phase (int channel, int phase)
597 //{
598 //  return d_usrp->set_ddc_phase(channel, phase);
599 //}
600 //
601 //bool
602 //msdd_source_base::set_dc_offset_cl_enable(int bits, int mask)
603 //{
604 //  return d_usrp->set_dc_offset_cl_enable(bits, mask);
605 //}
606
607 void
608 msdd_source_base::set_verbose (bool verbose)
609 {  
610   pimpl->d_verbose = verbose;
611 }
612 //
613 //bool
614 //msdd_source_base::write_aux_dac (int which_dboard, int which_dac, int value)
615 //{
616 //  return d_usrp->write_aux_dac (which_dboard, which_dac, value);
617 //}
618 //
619 //int
620 //msdd_source_base::read_aux_adc (int which_dboard, int which_adc)
621 //{
622 //  return d_usrp->read_aux_adc (which_dboard, which_adc);
623 //}
624 //
625 //bool
626 //msdd_source_base::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
627 //{
628 //  return d_usrp->write_eeprom (i2c_addr, eeprom_offset, buf);
629 //}
630 //
631 //std::string
632 //msdd_source_base::read_eeprom (int i2c_addr, int eeprom_offset, int len)
633 //{
634 //  return d_usrp->read_eeprom (i2c_addr, eeprom_offset, len);
635 //}
636 //
637 //bool
638 //msdd_source_base::write_i2c (int i2c_addr, const std::string buf)
639 //{
640 //  return d_usrp->write_i2c (i2c_addr, buf);
641 //}
642 //
643 //std::string
644 //msdd_source_base::read_i2c (int i2c_addr, int len)
645 //{
646 //  return d_usrp->read_i2c (i2c_addr, len);
647 //}
648 //
649 bool
650 msdd_source_base::set_pga (int which, double gain)
651 {
652   if (gain >= PGA_MIN & gain <= PGA_MAX) {
653     pimpl->d_gain = gain;
654
655     // Resubmit the control to update the PGA gain
656     write_request_packet(pimpl->d_desired_sample_size);
657
658     return true;
659   }
660   return false;
661 }
662
663 double
664 msdd_source_base::pga (int which) const
665 {
666   return pimpl->d_gain;
667 }
668
669 double
670 msdd_source_base::pga_min () const
671 {
672   return PGA_MIN;
673 }
674
675 double
676 msdd_source_base::pga_max () const
677 {
678   return PGA_MAX;
679 }
680
681 double
682 msdd_source_base::pga_db_per_step () const
683 {
684   return PGA_STEP;
685 }
686
687 //int
688 //msdd_source_base::daughterboard_id (int which) const
689 //{
690 //  return d_usrp->daughterboard_id (which);
691 //}
692 //
693 //
694 //bool
695 //msdd_source_base::set_adc_offset (int which, int offset)
696 //{
697 //  return d_usrp->set_adc_offset (which, offset);
698 //}
699 //
700 //bool
701 //msdd_source_base::set_dac_offset (int which, int offset, int offset_pin)
702 //{
703 //  return d_usrp->set_dac_offset (which, offset, offset_pin);
704 //}
705 //
706 //bool
707 //msdd_source_base::set_adc_buffer_bypass (int which, bool bypass)
708 //{
709 //  return d_usrp->set_adc_buffer_bypass (which, bypass);
710 //}
711
712 std::string
713 msdd_source_base::serial_number()
714 {
715   return "SoftTronics MSDD 6000";
716 }
717 //
718 //bool
719 //msdd_source_base::_write_oe (int which_dboard, int value, int mask)
720 //{
721 //  return d_usrp->_write_oe (which_dboard, value, mask);
722 //}
723 //
724 //bool
725 //msdd_source_base::write_io (int which_dboard, int value, int mask)
726 //{
727 //  return d_usrp->write_io (which_dboard, value, mask);
728 //}
729 //
730 //int
731 //msdd_source_base::read_io (int which_dboard)
732 //{
733 //  return d_usrp->read_io (which_dboard);
734 //}
735 //
736 //
737 //
738 //
739 //// internal routines...
740 //
741 //bool
742 //msdd_source_base::_write_fpga_reg (int regno, int value)
743 //{
744 //  return d_usrp->_write_fpga_reg (regno, value);
745 //}
746 //
747 //bool
748 //msdd_source_base::_write_fpga_reg_masked (int regno, int value, int mask)
749 //{
750 //  return d_usrp->_write_fpga_reg_masked (regno, value, mask);
751 //}
752 //
753 //int
754 //msdd_source_base::_read_fpga_reg (int regno)
755 //{
756 //  return d_usrp->_read_fpga_reg (regno);
757 //}
758 //
759 //bool
760 //msdd_source_base::_write_9862 (int which_codec, int regno, unsigned char value)
761 //{
762 //  return d_usrp->_write_9862 (which_codec, regno, value);
763 //}
764 //
765 //int
766 //msdd_source_base::_read_9862 (int which_codec, int regno) const
767 //{
768 //  return d_usrp->_read_9862 (which_codec, regno);
769 //}
770 //
771 //bool
772 //msdd_source_base::_write_spi (int optional_header, int enables,
773 //                             int format, std::string buf)
774 //{
775 //  return d_usrp->_write_spi (optional_header, enables, format, buf);
776 //}
777 //
778 //std::string
779 //msdd_source_base::_read_spi (int optional_header, int enables, int format, int len)
780 //{
781 //  return d_usrp->_read_spi (optional_header, enables, format, len);
782 //}
783 //
784 //bool
785 //msdd_source_base::set_format(unsigned int format)
786 //{
787 //  return d_usrp->set_format(format);
788 //}
789 //
790 //unsigned int
791 //msdd_source_base::format() const
792 //{
793 //  return d_usrp->format();
794 //}
795 //
796 //unsigned int
797 //msdd_source_base::make_format(int width, int shift, bool want_q, bool bypass_halfband)
798 //{
799 //  return usrp_standard_rx::make_format(width, shift, want_q, bypass_halfband);
800 //}
801 //
802 //int
803 //msdd_source_base::format_width(unsigned int format)
804 //{
805 //  return usrp_standard_rx::format_width(format);
806 //}
807 //
808 //int
809 //msdd_source_base::format_shift(unsigned int format)
810 //{
811 //  return usrp_standard_rx::format_shift(format);
812 //}
813 //
814 //bool
815 //msdd_source_base::format_want_q(unsigned int format)
816 //{
817 //  return usrp_standard_rx::format_want_q(format);
818 //}
819 //
820 //bool
821 //msdd_source_base::format_bypass_halfband(unsigned int format)
822 //{
823 //  return usrp_standard_rx::format_bypass_halfband(format);
824 //}
825
826 bool msdd_source_base::set_desired_packet_size (int which, unsigned long packet_size) {
827   bool result(false);
828   
829   if (pimpl->d_desired_sample_size < 2^32) { // FIXME: find maximum sample request for MSDD check if greater than 
830     pimpl->d_desired_sample_size = packet_size;
831   }
832
833   // Resubmit the control to update the packet size
834   write_request_packet(pimpl->d_desired_sample_size);
835
836   return result;
837 }
838
839 unsigned long msdd_source_base::desired_packet_size (int which) const {
840   return pimpl->d_desired_sample_size;
841 }