Revert r10379, which works at runtime but does not pass check or distcheck on Ubuntu...
[debian/gnuradio] / gr-msdd6000 / src / msdd6000.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 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.
20  */
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <msdd6000.h>
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <unistd.h>
29
30 #ifdef HAVE_ARPA_INET_H
31 #include <arpa/inet.h>
32 #endif
33 #ifdef HAVE_NETINET_IN_H
34 #include <netinet/in.h>
35 #endif
36 #ifdef HAVE_SYS_SOCKET_H
37 #include <sys/socket.h>
38 #endif
39
40 #define DEBUG(A)        printf("=debug=> %s\n", A)
41
42 static void 
43 optimize_socket(int socket);
44
45 /*
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
48  */
49 class MSDD6000::detail {
50 public:
51   struct sockaddr_in d_sockaddr;
52 };
53
54
55 MSDD6000::MSDD6000(char* addr)
56   : d_detail(new MSDD6000::detail())
57 {
58         d_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
59         
60         optimize_socket(d_sock);
61         
62         
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);
68         
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));
79         
80         // set default values
81         d_decim = 2;
82         d_ddc_gain = 2;
83         d_rf_attn = 0;
84         d_state = STATE_STOPPED;
85 }
86
87
88 static void
89 optimize_socket(int socket){
90 #define BANDWIDTH       1000000000/8
91 #define DELAY           0.5
92         int ret;
93
94         int sock_buf_size = static_cast<int>(2*BANDWIDTH*DELAY);
95         char textbuf[512];
96         snprintf(textbuf, sizeof(textbuf), "%d", sock_buf_size);
97         printf("sock_buf_size = %d\n", sock_buf_size);
98         
99         ret = setsockopt(socket, SOL_SOCKET, SO_SNDBUF,
100                          &sock_buf_size, sizeof(sock_buf_size));
101
102         ret = setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
103                          &sock_buf_size, sizeof(sock_buf_size));
104         
105         int uid = getuid();
106         if(uid!=0){
107                 printf(" ****** COULD NOT OPTIMIZE SYSTEM NETWORK PARAMETERS BECAUSE YOU ARE NOT RUNNING AS ROOT *******\n ****** YOUR MSDD6000 RECIEVER PERFORMANCE IS GOING TO BE TERRIBLE *******\n");
108                 return;
109         }
110
111
112         // SET UP SOME SYSTEM WIDE TCP SOCKET PARAMETERS
113         // FIXME seems like kind of a big hammer.  Are you sure you need this?
114         FILE* fd = fopen("/proc/sys/net/core/netdev_max_backlog", "w");
115         if (fd){
116           fwrite("10000", 1, strlen("10000"), fd);
117           fclose(fd);
118         }
119
120         fd = fopen("/proc/sys/net/core/rmem_max", "w");
121         if (fd){
122           fwrite(textbuf, 1, strlen(textbuf), fd);
123           fclose(fd);
124         }
125
126         fd = fopen("/proc/sys/net/core/wmem_max", "w");
127         if (fd){
128           fwrite(textbuf, 1, strlen(textbuf), fd);
129           fclose(fd);
130         }
131
132         // just incase these were rejected before because of max sizes...
133
134         ret = setsockopt( socket, SOL_SOCKET, SO_SNDBUF,
135                    (char *)&sock_buf_size, sizeof(sock_buf_size) );
136
137         ret = setsockopt( socket, SOL_SOCKET, SO_RCVBUF,
138                    (char *)&sock_buf_size, sizeof(sock_buf_size) );
139         
140 }
141
142
143 void MSDD6000::set_decim(int decim_pow2){
144         DEBUG("SETTING NEW DECIM");
145         d_decim = decim_pow2;
146
147         if(d_state==STATE_STARTED)
148                 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
149 }
150
151 void MSDD6000::set_rf_attn(int attn){
152         DEBUG("SETTING NEW RF ATTN");
153         d_rf_attn = attn;
154         if(d_state==STATE_STARTED)
155                 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
156 }
157
158 void MSDD6000::set_ddc_gain(int gain){
159         DEBUG("SETTING NEW DDC GAIN");
160         d_ddc_gain = gain;
161         if(d_state==STATE_STARTED)
162                 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
163 }
164
165 void MSDD6000::set_fc(int center_mhz, int offset_hz){
166         DEBUG("SETTING NEW FC");
167         d_fc_mhz = center_mhz;
168         d_offset_hz = offset_hz;
169         
170         if(d_state==STATE_STARTED)
171                 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
172 }
173
174
175 void MSDD6000::start(){
176         send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
177         d_state = STATE_STARTED;
178         }
179
180
181 void MSDD6000::stop(){
182         // new request with 0 decim tells it to halt
183         send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, 0, d_offset_hz);
184         d_state = STATE_STOPPED;
185         }
186
187
188 void MSDD6000::send_request(float freq_mhz, float rf_attn, float ddc_gain, float ddc_dec, float ddc_offset_hz){
189         static char buff[512];
190         sprintf(buff, "%f %f %f %f %f\n",freq_mhz, rf_attn, ddc_gain, ddc_dec, ddc_offset_hz);
191         printf("sending: %s\n", buff);
192         int flags = 0;
193         sendto( d_sock, buff, strlen(buff)+1, flags,
194                 (const sockaddr*)&(d_detail->d_sockaddr), sizeof(d_detail->d_sockaddr));
195         }
196
197
198 int  MSDD6000::read(char* buf, int size){
199         int flags = 0;
200         return recv(d_sock, buf, size, flags);
201         }
202
203