Applied patch to cleanup msdd
[debian/gnuradio] / gr-msdd6000 / src / msdd6000.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2008,2009 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 MSDD6000::~MSDD6000()
88 {
89     // printf("MSDD6000::Destructing\n");
90     close(d_sock);
91 }
92
93
94 static void
95 optimize_socket(int socket){
96 #define BANDWIDTH       1000000000/8
97 #define DELAY           0.5
98         int ret;
99
100         int sock_buf_size = static_cast<int>(2*BANDWIDTH*DELAY);
101         char textbuf[512];
102         snprintf(textbuf, sizeof(textbuf), "%d", sock_buf_size);
103         printf("sock_buf_size = %d\n", sock_buf_size);
104         
105         ret = setsockopt(socket, SOL_SOCKET, SO_SNDBUF,
106                          &sock_buf_size, sizeof(sock_buf_size));
107
108         ret = setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
109                          &sock_buf_size, sizeof(sock_buf_size));
110         
111         int uid = getuid();
112         if(uid!=0){
113                 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");
114                 return;
115         }
116
117
118         // SET UP SOME SYSTEM WIDE TCP SOCKET PARAMETERS
119         // FIXME seems like kind of a big hammer.  Are you sure you need this?
120         FILE* fd = fopen("/proc/sys/net/core/netdev_max_backlog", "w");
121         if (fd){
122           fwrite("10000", 1, strlen("10000"), fd);
123           fclose(fd);
124         }
125
126         fd = fopen("/proc/sys/net/core/rmem_max", "w");
127         if (fd){
128           fwrite(textbuf, 1, strlen(textbuf), fd);
129           fclose(fd);
130         }
131
132         fd = fopen("/proc/sys/net/core/wmem_max", "w");
133         if (fd){
134           fwrite(textbuf, 1, strlen(textbuf), fd);
135           fclose(fd);
136         }
137
138         // just incase these were rejected before because of max sizes...
139
140         ret = setsockopt( socket, SOL_SOCKET, SO_SNDBUF,
141                    (char *)&sock_buf_size, sizeof(sock_buf_size) );
142
143         ret = setsockopt( socket, SOL_SOCKET, SO_RCVBUF,
144                    (char *)&sock_buf_size, sizeof(sock_buf_size) );
145         
146 }
147
148
149 void MSDD6000::set_decim(int decim_pow2){
150         DEBUG("SETTING NEW DECIM");
151         d_decim = decim_pow2;
152
153         if(d_state==STATE_STARTED)
154                 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
155 }
156
157 void MSDD6000::set_rf_attn(int attn){
158         DEBUG("SETTING NEW RF ATTN");
159         d_rf_attn = attn;
160         if(d_state==STATE_STARTED)
161                 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
162 }
163
164 void MSDD6000::set_ddc_gain(int gain){
165         DEBUG("SETTING NEW DDC GAIN");
166         d_ddc_gain = gain;
167         if(d_state==STATE_STARTED)
168                 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
169 }
170
171 void MSDD6000::set_fc(int center_mhz, int offset_hz){
172         DEBUG("SETTING NEW FC");
173         d_fc_mhz = center_mhz;
174         d_offset_hz = offset_hz;
175         
176         if(d_state==STATE_STARTED)
177                 send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
178 }
179
180
181 void MSDD6000::start(){
182         send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz);
183         d_state = STATE_STARTED;
184         }
185
186
187 void MSDD6000::stop(){
188         // new request with 0 decim tells it to halt
189         send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, 0, d_offset_hz);
190         d_state = STATE_STOPPED;
191         }
192
193
194 void MSDD6000::send_request(float freq_mhz, float rf_attn, float ddc_gain, float ddc_dec, float ddc_offset_hz){
195         static char buff[512];
196         sprintf(buff, "%f %f %f %f %f\n",freq_mhz, rf_attn, ddc_gain, ddc_dec, ddc_offset_hz);
197         printf("sending: %s\n", buff);
198         int flags = 0;
199         sendto( d_sock, buff, strlen(buff)+1, flags,
200                 (const sockaddr*)&(d_detail->d_sockaddr), sizeof(d_detail->d_sockaddr));
201         }
202
203
204 int  MSDD6000::read(char* buf, int size){
205         int flags = 0;
206         return recv(d_sock, buf, size, flags);
207         }
208
209