3 * Copyright 2008 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <msdd6000_rs.h>
30 #ifdef HAVE_ARPA_INET_H
31 #include <arpa/inet.h>
33 #ifdef HAVE_NETINET_IN_H
34 #include <netinet/in.h>
36 #ifdef HAVE_SYS_SOCKET_H
37 #include <sys/socket.h>
40 #define DEBUG(A) printf("=debug=> %s\n", A)
43 optimize_socket(int socket);
46 * Holds types that need autoconf help. They're here and not in the .h file because
47 * here we've got access to config.h
49 class MSDD6000_RS::detail {
51 struct sockaddr_in d_sockaddr;
55 MSDD6000_RS::MSDD6000_RS(char* addr)
56 : d_detail(new MSDD6000_RS::detail())
58 d_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
60 optimize_socket(d_sock);
63 // set up remote sockaddr
64 // int s = inet_aton(addr, &d_adx);
65 d_detail->d_sockaddr.sin_family = AF_INET;
66 d_detail->d_sockaddr.sin_port = htons(10000);
67 int s = inet_aton(addr, &d_detail->d_sockaddr.sin_addr);
69 // set up local sockaddr
70 struct in_addr d_myadx;
71 struct sockaddr_in d_mysockaddr;
72 short int port = 10010;
73 d_myadx.s_addr = INADDR_ANY;
74 d_mysockaddr.sin_family = AF_INET;
75 d_mysockaddr.sin_port = htons(port);
76 memcpy(&d_mysockaddr.sin_addr.s_addr, &d_myadx.s_addr, sizeof(in_addr));
77 //d_sockaddr.sin_addr = INADDR_ANY;
78 s = bind(d_sock, (const sockaddr*) &d_mysockaddr, sizeof(d_mysockaddr));
87 d_ddc_sample_rate_khz = 25600;
90 d_state = STATE_STOPPED;
93 MSDD6000_RS::~MSDD6000_RS()
95 //printf("MSDD6000_RS::Destructing\n");
101 optimize_socket(int socket){
102 #define BANDWIDTH 1000000000/8
106 int sock_buf_size = static_cast<int>(2*BANDWIDTH*DELAY);
108 snprintf(textbuf, sizeof(textbuf), "%d", sock_buf_size);
109 printf("sock_buf_size = %d\n", sock_buf_size);
111 ret = setsockopt(socket, SOL_SOCKET, SO_SNDBUF,
112 &sock_buf_size, sizeof(sock_buf_size));
114 ret = setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
115 &sock_buf_size, sizeof(sock_buf_size));
119 printf(" ****** COULD NOT OPTIMIZE SYSTEM NETWORK PARAMETERS BECAUSE YOU ARE NOT RUNNING AS ROOT *******\n ****** YOUR MSDD6000_RS RECIEVER PERFORMANCE IS GOING TO BE TERRIBLE *******\n");
124 // SET UP SOME SYSTEM WIDE TCP SOCKET PARAMETERS
125 // FIXME seems like kind of a big hammer. Are you sure you need this?
126 FILE* fd = fopen("/proc/sys/net/core/netdev_max_backlog", "w");
128 fwrite("10000", 1, strlen("10000"), fd);
132 fd = fopen("/proc/sys/net/core/rmem_max", "w");
134 fwrite(textbuf, 1, strlen(textbuf), fd);
138 fd = fopen("/proc/sys/net/core/wmem_max", "w");
140 fwrite(textbuf, 1, strlen(textbuf), fd);
144 // just incase these were rejected before because of max sizes...
146 ret = setsockopt( socket, SOL_SOCKET, SO_SNDBUF,
147 (char *)&sock_buf_size, sizeof(sock_buf_size) );
149 ret = setsockopt( socket, SOL_SOCKET, SO_RCVBUF,
150 (char *)&sock_buf_size, sizeof(sock_buf_size) );
155 //void MSDD6000_RS::set_decim(int decim_pow2){
156 // DEBUG("SETTING NEW DECIM");
157 // d_decim = decim_pow2;
159 // if(d_state==STATE_STARTED)
160 // send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
163 void MSDD6000_RS::set_rf_attn(int attn){
164 DEBUG("SETTING NEW RF ATTN");
166 if(d_state==STATE_STARTED)
167 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
170 void MSDD6000_RS::set_ddc_gain(int gain){
171 DEBUG("SETTING NEW DDC GAIN");
173 if(d_state==STATE_STARTED)
174 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
177 void MSDD6000_RS::set_fc(int center_mhz, int offset_hz){
178 DEBUG("SETTING NEW FC");
179 d_fc_mhz = center_mhz;
180 d_offset_hz = offset_hz;
182 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
183 // if(d_state==STATE_STARTED)
184 // send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
185 // send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
189 void MSDD6000_RS::set_ddc_samp_rate(float sample_rate_khz){
190 DEBUG("SETTING NEW SAMPLE RATE");
191 d_ddc_sample_rate_khz = sample_rate_khz;
192 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
195 void MSDD6000_RS::set_ddc_bw(float bw_khz){
196 DEBUG("SETTING NEW DDC BW");
197 d_ddc_bw_khz = bw_khz;
198 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
201 void MSDD6000_RS::start(){
202 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
206 void MSDD6000_RS::stop(){
207 // new request with 0 decim tells it to halt
212 int MSDD6000_RS::start_data(){
214 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
215 d_state = STATE_STARTED;
220 int MSDD6000_RS::stop_data(){
221 // new request with 0 decim tells it to halt
223 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_offset_hz, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start);
224 d_state = STATE_STOPPED;
228 /* Query functions */
229 float MSDD6000_RS::pull_ddc_samp_rate(){
230 return d_ddc_sample_rate_khz;
232 float MSDD6000_RS::pull_ddc_bw(){
236 float MSDD6000_RS::pull_rx_freq(){
239 int MSDD6000_RS::pull_ddc_gain(){
243 int MSDD6000_RS::pull_rf_atten(){
248 void MSDD6000_RS::send_request(float freq_mhz, float rf_attn, float ddc_gain, float ddc_offset_hz, float ddc_samp_rate_khz, float ddc_input_bw_khz, float ddc_start){
249 static char buff[512];
250 // Send MSDD6000_RS control frame.
251 sprintf(buff, "%f %f %f %f %f %f %f\n",freq_mhz, rf_attn, ddc_gain, ddc_offset_hz, ddc_samp_rate_khz, ddc_input_bw_khz, ddc_start); //ddc_dec, ddc_offset_hz);
252 printf("sending: %s\n", buff);
254 sendto( d_sock, buff, strlen(buff)+1, flags,
255 (const sockaddr*)&(d_detail->d_sockaddr), sizeof(d_detail->d_sockaddr));
259 int MSDD6000_RS::read(char* buf, int size){
261 return recv(d_sock, buf, size, flags);
264 int MSDD6000_RS::parse_control(char* buf, int size){
265 //packet_len = sprintf(&txbuff[6], "%f %f %f %f %f %f %f",downsamp,ddc_dec_rate,ddc_step_int,ddc_step_frac,ddc_samp_rate_khz,ddc_input_bw_khz,ddc_start);
271 float ddc_samp_rate_khz;
272 float ddc_input_bw_khz;
275 sscanf(&buf[6],"%f %f %f %f %f %f %f",&downsamp,&ddc_dec_rate,&ddc_step_int,&ddc_step_frac,&ddc_samp_rate_khz,&ddc_input_bw_khz,&ddc_start);
277 // pull off sample rate
278 d_ddc_sample_rate_khz = ddc_samp_rate_khz;
279 printf("Sample Rate %f\n",d_ddc_sample_rate_khz);
281 d_ddc_bw_khz = ddc_input_bw_khz;
282 printf("BW %f\n", d_ddc_bw_khz);