diff options
Diffstat (limited to 'gr-msdd6000/src/msdd6000_rs.cc')
-rw-r--r-- | gr-msdd6000/src/msdd6000_rs.cc | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/gr-msdd6000/src/msdd6000_rs.cc b/gr-msdd6000/src/msdd6000_rs.cc new file mode 100644 index 000000000..d78f2b4da --- /dev/null +++ b/gr-msdd6000/src/msdd6000_rs.cc @@ -0,0 +1,286 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <msdd6000_rs.h> + +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +#define DEBUG(A) printf("=debug=> %s\n", A) + +static void +optimize_socket(int socket); + +/* + * Holds types that need autoconf help. They're here and not in the .h file because + * here we've got access to config.h + */ +class MSDD6000_RS::detail { +public: + struct sockaddr_in d_sockaddr; +}; + + +MSDD6000_RS::MSDD6000_RS(char* addr) + : d_detail(new MSDD6000_RS::detail()) +{ + d_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + + optimize_socket(d_sock); + + + // set up remote sockaddr +// int s = inet_aton(addr, &d_adx); + d_detail->d_sockaddr.sin_family = AF_INET; + d_detail->d_sockaddr.sin_port = htons(10000); + int s = inet_aton(addr, &d_detail->d_sockaddr.sin_addr); + + // set up local sockaddr + struct in_addr d_myadx; + struct sockaddr_in d_mysockaddr; + short int port = 10010; + d_myadx.s_addr = INADDR_ANY; + d_mysockaddr.sin_family = AF_INET; + d_mysockaddr.sin_port = htons(port); + memcpy(&d_mysockaddr.sin_addr.s_addr, &d_myadx.s_addr, sizeof(in_addr)); + //d_sockaddr.sin_addr = INADDR_ANY; + s = bind(d_sock, (const sockaddr*) &d_mysockaddr, sizeof(d_mysockaddr)); + + // set default values + //d_decim = 2; + d_ddc_gain = 2; + d_rf_attn = 0; + d_fc_mhz = 3500; + d_offset_hz = 0; + d_ddc_gain = 0; + d_ddc_sample_rate_khz = 25600; + d_ddc_bw_khz = 25600; + d_start = 0; + d_state = STATE_STOPPED; +} + +MSDD6000_RS::~MSDD6000_RS() +{ + //printf("MSDD6000_RS::Destructing\n"); + close(d_sock); +} + + +static void +optimize_socket(int socket){ +#define BANDWIDTH 1000000000/8 +#define DELAY 0.5 + int ret; + + int sock_buf_size = static_cast<int>(2*BANDWIDTH*DELAY); + char textbuf[512]; + snprintf(textbuf, sizeof(textbuf), "%d", sock_buf_size); + printf("sock_buf_size = %d\n", sock_buf_size); + + ret = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, + &sock_buf_size, sizeof(sock_buf_size)); + + ret = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, + &sock_buf_size, sizeof(sock_buf_size)); + + int uid = getuid(); + if(uid!=0){ + 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"); + return; + } + + + // SET UP SOME SYSTEM WIDE TCP SOCKET PARAMETERS + // FIXME seems like kind of a big hammer. Are you sure you need this? + FILE* fd = fopen("/proc/sys/net/core/netdev_max_backlog", "w"); + if (fd){ + fwrite("10000", 1, strlen("10000"), fd); + fclose(fd); + } + + fd = fopen("/proc/sys/net/core/rmem_max", "w"); + if (fd){ + fwrite(textbuf, 1, strlen(textbuf), fd); + fclose(fd); + } + + fd = fopen("/proc/sys/net/core/wmem_max", "w"); + if (fd){ + fwrite(textbuf, 1, strlen(textbuf), fd); + fclose(fd); + } + + // just incase these were rejected before because of max sizes... + + ret = setsockopt( socket, SOL_SOCKET, SO_SNDBUF, + (char *)&sock_buf_size, sizeof(sock_buf_size) ); + + ret = setsockopt( socket, SOL_SOCKET, SO_RCVBUF, + (char *)&sock_buf_size, sizeof(sock_buf_size) ); + +} + + +//void MSDD6000_RS::set_decim(int decim_pow2){ +// DEBUG("SETTING NEW DECIM"); +// d_decim = decim_pow2; +// +// if(d_state==STATE_STARTED) +// send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz); +//} + +void MSDD6000_RS::set_rf_attn(int attn){ + DEBUG("SETTING NEW RF ATTN"); + d_rf_attn = attn; + if(d_state==STATE_STARTED) + 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); +} + +void MSDD6000_RS::set_ddc_gain(int gain){ + DEBUG("SETTING NEW DDC GAIN"); + d_ddc_gain = gain; + if(d_state==STATE_STARTED) + 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); +} + +void MSDD6000_RS::set_fc(int center_mhz, int offset_hz){ + DEBUG("SETTING NEW FC"); + d_fc_mhz = center_mhz; + d_offset_hz = offset_hz; + + 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); +// if(d_state==STATE_STARTED) +// send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_decim, d_offset_hz); +// send_request(d_fc_mhz, d_rf_attn, d_ddc_gain, d_ddc_sample_rate_khz, d_ddc_bw_khz, d_start); +// +} + +void MSDD6000_RS::set_ddc_samp_rate(float sample_rate_khz){ + DEBUG("SETTING NEW SAMPLE RATE"); + d_ddc_sample_rate_khz = sample_rate_khz; + 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); +} + +void MSDD6000_RS::set_ddc_bw(float bw_khz){ + DEBUG("SETTING NEW DDC BW"); + d_ddc_bw_khz = bw_khz; + 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); +} + +void MSDD6000_RS::start(){ + 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); + return; +} + +void MSDD6000_RS::stop(){ + // new request with 0 decim tells it to halt + stop_data(); +} + + +int MSDD6000_RS::start_data(){ + d_start = 1; + 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); + d_state = STATE_STARTED; + return 0; + } + + +int MSDD6000_RS::stop_data(){ + // new request with 0 decim tells it to halt + d_start = 0; + 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); + d_state = STATE_STOPPED; + return 0; + } + +/* Query functions */ +float MSDD6000_RS::pull_ddc_samp_rate(){ + return d_ddc_sample_rate_khz; +} +float MSDD6000_RS::pull_ddc_bw(){ + return d_ddc_bw_khz; +} + +float MSDD6000_RS::pull_rx_freq(){ + return d_fc_mhz; +} +int MSDD6000_RS::pull_ddc_gain(){ + return d_ddc_gain; +} + +int MSDD6000_RS::pull_rf_atten(){ + return d_rf_attn; +} + + +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){ + static char buff[512]; + // Send MSDD6000_RS control frame. + 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); + printf("sending: %s\n", buff); + int flags = 0; + sendto( d_sock, buff, strlen(buff)+1, flags, + (const sockaddr*)&(d_detail->d_sockaddr), sizeof(d_detail->d_sockaddr)); + } + + +int MSDD6000_RS::read(char* buf, int size){ + int flags = 0; + return recv(d_sock, buf, size, flags); + } + +int MSDD6000_RS::parse_control(char* buf, int size){ + //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); + + float downsamp; + float ddc_dec_rate; + float ddc_step_int; + float ddc_step_frac; + float ddc_samp_rate_khz; + float ddc_input_bw_khz; + float ddc_start; + + 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); + + // pull off sample rate + d_ddc_sample_rate_khz = ddc_samp_rate_khz; + printf("Sample Rate %f\n",d_ddc_sample_rate_khz); + // pull off bw + d_ddc_bw_khz = ddc_input_bw_khz; + printf("BW %f\n", d_ddc_bw_khz); + return 0; +} + + |