Ejemplo n.º 1
0
static void *demod_thread_fn(void *arg)
{
	while (!do_exit) {
		safe_cond_wait(&ready, &ready_m);
		pthread_rwlock_wrlock(&both.rw);
		downsample(&both);
		memcpy(left.buf,  both.buf, 2*both.len_out);
		memcpy(right.buf, both.buf, 2*both.len_out);
		pthread_rwlock_unlock(&both.rw);
		rotate_90(left.buf, left.len_in);
		downsample(&left);
		memcpy(left_demod.buf, left.buf, 2*left.len_out);
		demodulate(&left_demod);
		if (dc_filter) {
			dc_block_filter(&left_demod);}
		//if (oversample) {
		//	downsample(&left);}
		arbitrary_upsample(left_demod.result, stereo.buf_left, left_demod.result_len, stereo.bl_len);
		rotate_m90(right.buf, right.len_in);
		downsample(&right);
		memcpy(right_demod.buf, right.buf, 2*right.len_out);
		demodulate(&right_demod);
		if (dc_filter) {
			dc_block_filter(&right_demod);}
		//if (oversample) {
		//	downsample(&right);}
		arbitrary_upsample(right_demod.result, stereo.buf_right, right_demod.result_len, stereo.br_len);
		output();
	}
	rtlsdr_cancel_async(dev);
	return 0;
}
Ejemplo n.º 2
0
static void sighandler(int signum)
{
	fprintf(stderr, "Signal caught, exiting!\n");
	if (!do_exit) {
      rtlsdr_cancel_async(dev);
      do_exit = 1;
    }
}
Ejemplo n.º 3
0
static void sighandler(int signum) {
    if (signum == SIGPIPE) {
        signal(SIGPIPE,SIG_IGN);
    } else {
        fprintf(stderr, "Signal caught, exiting!\n");
    }
    do_exit = 1;
    rtlsdr_cancel_async(dev);
}
Ejemplo n.º 4
0
static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
{
	if (ctx) {
		if (fwrite(buf, 1, len, (FILE*)ctx) != len) {
			fprintf(stderr, "Short write, samples lost, exiting!\n");
			rtlsdr_cancel_async(dev);
		}
	}
}
Ejemplo n.º 5
0
BOOL WINAPI
sighandler(int signum) {
    if (CTRL_C_EVENT == signum) {
        fprintf(stderr, "Signal caught, exiting!\n");
        do_exit = 1;
        rtlsdr_cancel_async(dev);
        return TRUE;
    }
    return FALSE;
}
Ejemplo n.º 6
0
static void *demod_thread_fn(void *arg)
{
	struct fm_state *fm2 = arg;
	while (!do_exit) {
		full_demod(fm2);
		if (fm2->exit_flag) {
			do_exit = 1;
			rtlsdr_cancel_async(dev);}
	}
	return 0;
}
Ejemplo n.º 7
0
static void sighandler(int signum)
{

	if (dev != NULL)
		rtlsdr_cancel_async(dev);
	if (signum != 0) {
		aprintf_stderr("Signal caught, exiting! (signal %d)", signum);
		announce_exceptioncode(marto_rtl_tcp_andro_core_RtlTcp_EXIT_SIGNAL_CAUGHT);
	}

	do_exit = 1;
}
Ejemplo n.º 8
0
static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
{
	if (ctx) {
		if (do_exit)
			return;

		if ((bytes_to_read > 0) && (bytes_to_read < len)) {
			len = bytes_to_read;
			do_exit = 1;
			rtlsdr_cancel_async(dev);
		}

		if (fwrite(buf, 1, len, (FILE*)ctx) != len) {
			fprintf(stderr, "Short write, samples lost, exiting!\n");
			rtlsdr_cancel_async(dev);
		}

		if (bytes_to_read > 0)
			bytes_to_read -= len;
	}
}
Ejemplo n.º 9
0
void	dabStick::stopReader	(void) {
	if (workerHandle == NULL)
	   return;

	rtlsdr_cancel_async (device);
	if (workerHandle != NULL) {
	   while (!workerHandle -> isFinished ()) 
	      usleep (10);

	   delete	workerHandle;
	}
	workerHandle	= NULL;
}
Ejemplo n.º 10
0
static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
{
	if (ctx) {
		if (do_exit)
			return;

		if ((bytes_to_read > 0) && (bytes_to_read < len)) {
			len = bytes_to_read;
			do_exit = 1;
			rtlsdr_cancel_async(dev);
		}

//		if (fwrite(buf, 1, len, (FILE*)ctx) != len) {

//    buf_offset=0;
//    while (buf_offset<len) // len always is 262144
//    {
//      sendto_len = ( (buf_offset+LEN_UDP_PACKET) <= len)? LEN_UDP_PACKET : (len-buf_offset);
//
////      fprintf(stderr, "%u %u %u\n", len, buf_offset, sendto_len);
//
//      if ( ( sendto_flag=sendto(fd, buf + buf_offset, sendto_len, 0, (struct sockaddr*)&addr,sizeof(addr)) ) != sendto_len) {
//        fprintf(stderr, "Short write, samples lost, exiting! %u %u %u\n", sendto_len, sendto_flag, buf_offset);
//        rtlsdr_cancel_async(dev);
//        break;
//      }
//      buf_offset = buf_offset + sendto_len;
//    }

    sendto_len = LEN_UDP_PACKET;
    if ( ( sendto_flag=sendto(fd, buf, sendto_len, 0, (struct sockaddr*)&addr,sizeof(addr)) ) != sendto_len) {
      fprintf(stderr, "Short write, samples lost, exiting! %u %u\n", sendto_len, sendto_flag);
      rtlsdr_cancel_async(dev);
    }

		if (bytes_to_read > 0)
			bytes_to_read -= len;
	}
}
Ejemplo n.º 11
0
static void *demod_thread_fn(void *arg)
{
	struct fm_state *fm2 = arg;
	while (!do_exit) {
		sem_wait(&data_ready);
		full_demod(fm2->buf, fm2->buf_len, fm2);
		if (!fm2->term_squelch_hits) {
			continue;}
		if (fm2->squelch_hits > fm2->term_squelch_hits) {
			do_exit = 1;
			rtlsdr_cancel_async(dev);}
	}
	return 0;
}
Ejemplo n.º 12
0
/* rtlsdr stream callback  -----------------------------------------------------
* callback for receiving RF data
*-----------------------------------------------------------------------------*/
void stream_callback_rtlsdr(unsigned char *buf, uint32_t len, void *ctx)
{
    /* copy stream data to global buffer */
    mlock(hbuffmtx);
    memcpy(&sdrstat.buff[(sdrstat.buffcnt%MEMBUFFLEN)*2*RTLSDR_DATABUFF_SIZE],
        buf,2*RTLSDR_DATABUFF_SIZE);
    unmlock(hbuffmtx);

    mlock(hreadmtx);
    sdrstat.buffcnt++;
    unmlock(hreadmtx);

    if (sdrstat.stopflag) rtlsdr_cancel_async(dev);
}
Ejemplo n.º 13
0
void rtl_destroy(rtl r)
{
    DEBUG("Destroying rtl...\n");

    _rtl_set_state(r, RTL_EXITING);

    rtlsdr_cancel_async(r->device);

    pthread_join(r->thread, NULL);
    pthread_mutex_destroy( & r->buffer_m);
    pthread_mutex_destroy( & r->state_m);

    rtlsdr_close(r->device);
    free(r);
}
Ejemplo n.º 14
0
//  Decimate everything by 16x, except 288kHz by 4x
//  and 1152kHz, 2048kHz by 8x
void RTLSDRThread::callback(const quint8* buf, qint32 len)
{
	SampleVector::iterator it = m_convertBuffer.begin();

	if (m_samplerate < 800000)
		decimate4(&it, buf, len);
	else if ((m_samplerate == 1152000)||(m_samplerate == 2048000))
		decimate8(&it, buf, len);
	else
		decimate16(&it, buf, len);

	m_sampleFifo->write(m_convertBuffer.begin(), it);

	if(!m_running)
		rtlsdr_cancel_async(m_dev);
}
Ejemplo n.º 15
0
void CRtlSdr::close() {
    log_t.isConnected = false;
    // Stop thread
    if (dongle.dev != NULL)
        rtlsdr_cancel_async(dongle.dev);
    // Join on leave
#ifdef WIN32
    if (dongle.thread.p != 0)
#else
    if (dongle.thread != 0)
#endif
        pthread_join(dongle.thread, NULL);
    // Close rtl device
    int r = rtlsdr_close(dongle.dev);
    if (r < 0) {
        qDebug() << "Failed to close rtlsdr device " << dongle.dev_index << "\n";
    }
}
Ejemplo n.º 16
0
void read_callback(unsigned char* buf, uint32_t len, void* ctx)
{
    printf(".");
    fflush(stdout);
    fwrite(buf, 1, len, outf);
    buffers_received++;

    if(quit_please || buffers_received == 20) {
        printf("Final callback, shutting down.\n");

        printf("Closing output file...\n");
        fclose(outf);

        printf("Stopping RTL-SDR streaming...\n");
        rtlsdr_cancel_async(rtlsdr);

        exit(0);

        printf("Closing RTL-SDR...\n");
        rtlsdr_close(rtlsdr);

        exit(0);
    }
}
Ejemplo n.º 17
0
static void rtlsdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx) {
    struct dm_state *demod = ctx;
    int i;

	if (do_exit || do_exit_async)
		return;

	if ((bytes_to_read > 0) && (bytes_to_read < len)) {
		len = bytes_to_read;
		do_exit = 1;
		rtlsdr_cancel_async(dev);
	}

	if (demod->signal_grabber) {
		//fprintf(stderr, "[%d] sg_index - len %d\n", demod->sg_index, len );
		memcpy(&demod->sg_buf[demod->sg_index], iq_buf, len);
		demod->sg_len = len;
		demod->sg_index += len;
		if (demod->sg_index + len > SIGNAL_GRABBER_BUFFER)
			demod->sg_index = 0;
	}

	// AM demodulation
	envelope_detect(iq_buf, demod->temp_buf, len/2);
	baseband_low_pass_filter(demod->temp_buf, demod->am_buf, len/2, &demod->lowpass_filter_state);

	// FM demodulation
	if (demod->enable_FM_demod) {
		baseband_demod_FM(iq_buf, demod->fm_buf, len/2, &demod->demod_FM_state);
	}

	// Handle special input formats
	if(!demod->out_file) {				// If output file is specified we always assume I/Q input
		if (demod->debug_mode == 1) {	// The IQ buffer is really AM demodulated data
			memcpy(demod->am_buf, iq_buf, len);
		} else if (demod->debug_mode == 2) {	// The IQ buffer is really FM demodulated data
			fprintf(stderr, "Reading FM modulated data not implemented yet!\n");
		}
	}

	if (demod->analyze || (demod->out_file == stdout)) {	// We don't want to decode devices when outputting to stdout
		pwm_analyze(demod, demod->am_buf, len / 2);
	} else {
		// Detect a package and loop through demodulators with pulse data
		int package_type = 1;	// Just to get us started
		while(package_type) {
			package_type = pulse_detect_package(demod->am_buf, demod->fm_buf, len/2, demod->level_limit, samp_rate, &demod->pulse_data, &demod->fsk_pulse_data);
			if (package_type == 1) {
				if(demod->analyze_pulses) fprintf(stderr, "Detected OOK package\n");
				for (i = 0; i < demod->r_dev_num; i++) {
					switch (demod->r_devs[i]->modulation) {
						case OOK_PULSE_PCM_RZ:
							pulse_demod_pcm(&demod->pulse_data, demod->r_devs[i]);
							break;
						case OOK_PULSE_PPM_RAW:
							pulse_demod_ppm(&demod->pulse_data, demod->r_devs[i]);
							break;
						case OOK_PULSE_PWM_PRECISE:
							pulse_demod_pwm_precise(&demod->pulse_data, demod->r_devs[i]);
							break;
						case OOK_PULSE_PWM_RAW:
							pulse_demod_pwm(&demod->pulse_data, demod->r_devs[i]);
							break;
						case OOK_PULSE_PWM_TERNARY:
							pulse_demod_pwm_ternary(&demod->pulse_data, demod->r_devs[i]);
							break;
						case OOK_PULSE_MANCHESTER_ZEROBIT:
							pulse_demod_manchester_zerobit(&demod->pulse_data, demod->r_devs[i]);
							break;
						case OOK_PULSE_CLOCK_BITS:
							pulse_demod_clock_bits(&demod->pulse_data, demod->r_devs[i]);
							break;
						case OOK_PULSE_PWM_OSV1:
							pulse_demod_osv1(&demod->pulse_data, demod->r_devs[i]);
							break;
						// FSK decoders
						case FSK_PULSE_PCM:
						case FSK_PULSE_PWM_RAW:
							break;
						default:
							fprintf(stderr, "Unknown modulation %d in protocol!\n", demod->r_devs[i]->modulation);
					}
				} // for demodulators
				if(debug_output > 1) pulse_data_print(&demod->pulse_data);
				if(demod->analyze_pulses) pulse_analyzer(&demod->pulse_data, samp_rate);
			} else if (package_type == 2) {
				if(demod->analyze_pulses) fprintf(stderr, "Detected FSK package\n");
				for (i = 0; i < demod->r_dev_num; i++) {
					switch (demod->r_devs[i]->modulation) {
						// OOK decoders
						case OOK_PULSE_PCM_RZ:
						case OOK_PULSE_PPM_RAW:
						case OOK_PULSE_PWM_PRECISE:
						case OOK_PULSE_PWM_RAW:
						case OOK_PULSE_PWM_TERNARY:
						case OOK_PULSE_MANCHESTER_ZEROBIT:
						case OOK_PULSE_CLOCK_BITS:
						case OOK_PULSE_PWM_OSV1:
							break;
						case FSK_PULSE_PCM:
							pulse_demod_pcm(&demod->fsk_pulse_data, demod->r_devs[i]);
							break;
						case FSK_PULSE_PWM_RAW:
							pulse_demod_pwm(&demod->fsk_pulse_data, demod->r_devs[i]);
							break;
						default:
							fprintf(stderr, "Unknown modulation %d in protocol!\n", demod->r_devs[i]->modulation);
					}
				} // for demodulators
				if(debug_output > 1) pulse_data_print(&demod->fsk_pulse_data);
				if(demod->analyze_pulses) pulse_analyzer(&demod->fsk_pulse_data, samp_rate);
			}
		}
	}

	if (demod->out_file) {
		uint8_t* out_buf = iq_buf;				// Default is to dump IQ samples
		if (demod->debug_mode == 1) {			// AM data
			out_buf = (uint8_t*)demod->am_buf;
		} else if (demod->debug_mode == 2) {	// FM data
			out_buf = (uint8_t*)demod->fm_buf;
		}
		if (fwrite(out_buf, 1, len, demod->out_file) != len) {
			fprintf(stderr, "Short write, samples lost, exiting!\n");
			rtlsdr_cancel_async(dev);
		}
	}

	if (bytes_to_read > 0)
		bytes_to_read -= len;

        time_t rawtime;
        time(&rawtime);
	if (frequencies > 1) {
		if (difftime(rawtime, rawtime_old) > DEFAULT_HOP_TIME || events >= DEFAULT_HOP_EVENTS) {
			rawtime_old = rawtime;
			events = 0;
			do_exit_async = 1;
			rtlsdr_cancel_async(dev);
		}
	}
    if (duration > 0 && rawtime >= stop_time) {
      do_exit_async = do_exit = 1;
      fprintf(stderr, "Time expired, exiting!\n");
      rtlsdr_cancel_async(dev);
    }
}
Ejemplo n.º 18
0
int main(int argc, char** argv) {
    uint32_t opt;

    int32_t  rtl_result;
    int32_t  rtl_count;
    char     rtl_vendor[256], rtl_product[256], rtl_serial[256];

    initrx_options();
    initDecoder_options();

    /* RX buffer allocation */
    rx_state.iSamples=malloc(sizeof(float)*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE);
    rx_state.qSamples=malloc(sizeof(float)*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE);

    /* Stop condition setup */
    rx_state.exit_flag   = false;
    rx_state.decode_flag = false;
    uint32_t nLoop = 0;


    if (argc <= 1)
        usage();

    while ((opt = getopt(argc, argv, "f:c:l:g:a:o:p:u:d:n:i:H:Q:S")) != -1) {
        switch (opt) {
        case 'f': // Frequency
            rx_options.dialfreq = (uint32_t)atofs(optarg);
            break;
        case 'c': // Callsign
            sprintf(dec_options.rcall, "%.12s", optarg);
            break;
        case 'l': // Locator / Grid
            sprintf(dec_options.rloc, "%.6s", optarg);
            break;
        case 'g': // Small signal amplifier gain
            rx_options.gain = atoi(optarg);
            if (rx_options.gain < 0) rx_options.gain = 0;
            if (rx_options.gain > 49) rx_options.gain = 49;
            rx_options.gain *= 10;
            break;
        case 'a': // Auto gain
            rx_options.autogain = atoi(optarg);
            if (rx_options.autogain < 0) rx_options.autogain = 0;
            if (rx_options.autogain > 1) rx_options.autogain = 1;
            break;
        case 'o': // Fine frequency correction
            rx_options.shift = atoi(optarg);
            break;
        case 'p':
            rx_options.ppm = atoi(optarg);
            break;
        case 'u': // Upconverter frequency
            rx_options.upconverter = (uint32_t)atofs(optarg);
            break;
        case 'd': // Direct Sampling
            rx_options.directsampling = (uint32_t)atofs(optarg);
            break;
        case 'n': // Stop after n iterations
            rx_options.maxloop = (uint32_t)atofs(optarg);
            break;
        case 'i': // Select the device to use
            rx_options.device = (uint32_t)atofs(optarg);
            break;
        case 'H': // Decoder option, use a hastable
            dec_options.usehashtable = 1;
            break;
        case 'Q': // Decoder option, faster
            dec_options.quickmode = 1;
            break;
        case 'S': // Decoder option, single pass mode (same as original wsprd)
            dec_options.subtraction = 0;
            dec_options.npasses = 1;
            break;
        default:
            usage();
            break;
        }
    }

    if (rx_options.dialfreq == 0) {
        fprintf(stderr, "Please specify a dial frequency.\n");
        fprintf(stderr, " --help for usage...\n");
        exit(1);
    }

    if (dec_options.rcall[0] == 0) {
        fprintf(stderr, "Please specify your callsign.\n");
        fprintf(stderr, " --help for usage...\n");
        exit(1);
    }

    if (dec_options.rloc[0] == 0) {
        fprintf(stderr, "Please specify your locator.\n");
        fprintf(stderr, " --help for usage...\n");
        exit(1);
    }

    /* Calcule shift offset */
    rx_options.realfreq = rx_options.dialfreq + rx_options.shift + rx_options.upconverter;

    /* Store the frequency used for the decoder */
    dec_options.freq = rx_options.dialfreq;

    /* If something goes wrong... */
    signal(SIGINT, &sigint_callback_handler);
    signal(SIGTERM, &sigint_callback_handler);
    signal(SIGILL, &sigint_callback_handler);
    signal(SIGFPE, &sigint_callback_handler);
    signal(SIGSEGV, &sigint_callback_handler);
    signal(SIGABRT, &sigint_callback_handler);

    /* Init & parameter the device */
    rtl_count = rtlsdr_get_device_count();
    if (!rtl_count) {
        fprintf(stderr, "No supported devices found\n");
        return EXIT_FAILURE;
    }


    fprintf(stderr, "Found %d device(s):\n", rtl_count);
    for (uint32_t i=0; i<rtl_count; i++) {
        rtlsdr_get_device_usb_strings(i, rtl_vendor, rtl_product, rtl_serial);
        fprintf(stderr, "  %d:  %s, %s, SN: %s\n", i, rtl_vendor, rtl_product, rtl_serial);
    }
    fprintf(stderr, "\nUsing device %d: %s\n", rx_options.device, rtlsdr_get_device_name(rx_options.device));


    rtl_result = rtlsdr_open(&rtl_device, rx_options.device);
    if (rtl_result < 0) {
        fprintf(stderr, "ERROR: Failed to open rtlsdr device #%d.\n", rx_options.device);
        return EXIT_FAILURE;
    }

    if (rx_options.directsampling) {
        rtl_result = rtlsdr_set_direct_sampling(rtl_device, rx_options.directsampling);
        if (rtl_result < 0) {
            fprintf(stderr, "ERROR: Failed to set direct sampling\n");
            rtlsdr_close(rtl_device);
            return EXIT_FAILURE;
        }
    }

    rtl_result = rtlsdr_set_sample_rate(rtl_device, SAMPLING_RATE);
    if (rtl_result < 0) {
        fprintf(stderr, "ERROR: Failed to set sample rate\n");
        rtlsdr_close(rtl_device);
        return EXIT_FAILURE;
    }


    rtl_result = rtlsdr_set_tuner_gain_mode(rtl_device, 1);
    if (rtl_result < 0) {
        fprintf(stderr, "ERROR: Failed to enable manual gain\n");
        rtlsdr_close(rtl_device);
        return EXIT_FAILURE;
    }


    if (rx_options.autogain) {
        rtl_result = rtlsdr_set_tuner_gain_mode(rtl_device, 0);
        if (rtl_result != 0) {
            fprintf(stderr, "ERROR: Failed to set tuner gain\n");
            rtlsdr_close(rtl_device);
            return EXIT_FAILURE;
        }
    } else {
        rtl_result = rtlsdr_set_tuner_gain(rtl_device, rx_options.gain);
        if (rtl_result != 0) {
            fprintf(stderr, "ERROR: Failed to set tuner gain\n");
            rtlsdr_close(rtl_device);
            return EXIT_FAILURE;
        }
    }


    if (rx_options.ppm != 0) {
        rtl_result = rtlsdr_set_freq_correction(rtl_device, rx_options.ppm);
        if (rtl_result < 0) {
            fprintf(stderr, "ERROR: Failed to set ppm error\n");
            rtlsdr_close(rtl_device);
            return EXIT_FAILURE;
        }
    }


    rtl_result = rtlsdr_set_center_freq(rtl_device, rx_options.realfreq + FS4_RATE + 1500);
    if (rtl_result < 0) {
        fprintf(stderr, "ERROR: Failed to set frequency\n");
        rtlsdr_close(rtl_device);
        return EXIT_FAILURE;
    }


    rtl_result = rtlsdr_reset_buffer(rtl_device);
    if (rtl_result < 0) {
        fprintf(stderr, "ERROR: Failed to reset buffers.\n");
        rtlsdr_close(rtl_device);
        return EXIT_FAILURE;
    }

    /* Print used parameter */
    time_t rawtime;
    time ( &rawtime );
    struct tm *gtm = gmtime(&rawtime);
    printf("\nStarting rtlsdr-wsprd (%04d-%02d-%02d, %02d:%02dz) -- Version 0.2\n",
           gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, gtm->tm_hour, gtm->tm_min);
    printf("  Callsign     : %s\n", dec_options.rcall);
    printf("  Locator      : %s\n", dec_options.rloc);
    printf("  Dial freq.   : %d Hz\n", rx_options.dialfreq);
    printf("  Real freq.   : %d Hz\n", rx_options.realfreq);
    printf("  PPM factor   : %d\n", rx_options.ppm);
    if(rx_options.autogain)
        printf("  Auto gain    : enable\n");
    else
        printf("  Gain         : %d dB\n", rx_options.gain/10);


    /* Time alignment stuff */
    struct timeval lTime;
    gettimeofday(&lTime, NULL);
    uint32_t sec   = lTime.tv_sec % 120;
    uint32_t usec  = sec * 1000000 + lTime.tv_usec;
    uint32_t uwait = 120000000 - usec;
    printf("Wait for time sync (start in %d sec)\n\n", uwait/1000000);

    /* Prepare a low priority param for the decoder thread */
    struct sched_param param;
    pthread_attr_init(&dec.tattr);
    pthread_attr_setschedpolicy(&dec.tattr, SCHED_RR);
    pthread_attr_getschedparam(&dec.tattr, &param);
    param.sched_priority = 90;  // = sched_get_priority_min();
    pthread_attr_setschedparam(&dec.tattr, &param);

    /* Create a thread and stuff for separate decoding
       Info : https://computing.llnl.gov/tutorials/pthreads/
    */
    pthread_rwlock_init(&dec.rw, NULL);
    pthread_cond_init(&dec.ready_cond, NULL);
    pthread_mutex_init(&dec.ready_mutex, NULL);
    pthread_create(&dongle.thread, NULL, rtlsdr_rx, NULL);
    pthread_create(&dec.thread, &dec.tattr, wsprDecoder, NULL);


    /* Main loop : Wait, read, decode */
    while (!rx_state.exit_flag && !(rx_options.maxloop && (nLoop >= rx_options.maxloop))) {
        /* Wait for time Sync on 2 mins */
        gettimeofday(&lTime, NULL);
        sec   = lTime.tv_sec % 120;
        usec  = sec * 1000000 + lTime.tv_usec;
        uwait = 120000000 - usec + 10000;  // Adding 10ms, to be sure to reach this next minute
        usleep(uwait);
        //printf("SYNC! RX started\n");

        /* Use the Store the date at the begin of the frame */
        time ( &rawtime );
        gtm = gmtime(&rawtime);
        sprintf(rx_options.date,"%02d%02d%02d", gtm->tm_year - 100, gtm->tm_mon + 1, gtm->tm_mday);
        sprintf(rx_options.uttime,"%02d%02d", gtm->tm_hour, gtm->tm_min);

        /* Start to store the samples */
        initSampleStorage();

        while( (rx_state.exit_flag == false) &&
                (rx_state.iqIndex < (SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE) ) ) {
            usleep(250000);
        }
        nLoop++;
    }

    /* Stop the RX and free the blocking function */
    rtlsdr_cancel_async(rtl_device);

    /* Close the RTL device */
    rtlsdr_close(rtl_device);

    printf("Bye!\n");

    /* Wait the thread join (send a signal before to terminate the job) */
    pthread_mutex_lock(&dec.ready_mutex);
    pthread_cond_signal(&dec.ready_cond);
    pthread_mutex_unlock(&dec.ready_mutex);
    pthread_join(dec.thread, NULL);
    pthread_join(dongle.thread, NULL);

    /* Destroy the lock/cond/thread */
    pthread_rwlock_destroy(&dec.rw);
    pthread_cond_destroy(&dec.ready_cond);
    pthread_mutex_destroy(&dec.ready_mutex);
    pthread_exit(NULL);

    return EXIT_SUCCESS;
}
Ejemplo n.º 19
0
int main(int argc, char **argv)
{
#ifndef _WIN32
	struct sigaction sigact;
#endif
	struct fm_state fm; 
	char *filename = NULL;
	int n_read, r, opt, wb_mode = 0;
	int i, gain = AUTO_GAIN; // tenths of a dB
	uint8_t *buffer;
	uint32_t dev_index = 0;
	int device_count;
	int ppm_error = 0;
	char vendor[256], product[256], serial[256];
	fm_init(&fm);
	//    pthread_mutex_init(&data_ready, NULL);
	//    pthread_mutex_init(&data_write, NULL);

	while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:EFA:NWMULRDC")) != -1) {
		switch (opt) {
		case 'd':
			dev_index = atoi(optarg);
			break;
		case 'f':
			if (strchr(optarg, ':'))
				{frequency_range(&fm, optarg);}
			else
			{
				fm.freqs[fm.freq_len] = (uint32_t)atofs(optarg);
				fm.freq_len++;
			}
			break;
		case 'g':
			gain = (int)(atof(optarg) * 10);
			break;
		case 'l':
			fm.squelch_level = (int)atof(optarg);
			break;
		case 's':
			fm.sample_rate = (uint32_t)atofs(optarg);
			break;
		case 'r':
			fm.output_rate = (int)atofs(optarg);
			break;
		case 'o':
			fm.post_downsample = (int)atof(optarg);
			if (fm.post_downsample < 1 || fm.post_downsample > MAXIMUM_OVERSAMPLE) {
				fprintf(stderr, "Oversample must be between 1 and %i\n", MAXIMUM_OVERSAMPLE);}
			break;
		case 't':
			fm.conseq_squelch = (int)atof(optarg);
			if (fm.conseq_squelch < 0) {
				fm.conseq_squelch = -fm.conseq_squelch;
				fm.terminate_on_squelch = 1;
			}
			break;
		case 'p':
			ppm_error = atoi(optarg);
			break;
		case 'E':
			fm.edge = 1;
			break;
		case 'F':
			fm.fir_enable = 1;
			break;
		case 'A':
			if (strcmp("std",  optarg) == 0) {
				fm.custom_atan = 0;}
			if (strcmp("fast", optarg) == 0) {
				fm.custom_atan = 1;}
			if (strcmp("lut",  optarg) == 0) {
				atan_lut_init();
				fm.custom_atan = 2;}
			break;
		case 'D':
			fm.deemph = 1;
			break;
		case 'C':
			fm.dc_block = 1;
			break;
		case 'N':
			fm.mode_demod = &fm_demod;
			break;
		case 'W':
			wb_mode = 1;
			fm.mode_demod = &fm_demod;
			fm.sample_rate = 170000;
			fm.output_rate = 32000;
			fm.custom_atan = 1;
			fm.post_downsample = 4;
			fm.deemph = 1;
			fm.squelch_level = 0;
			break;
		case 'M':
			fm.mode_demod = &am_demod;
			break;
		case 'U':
			fm.mode_demod = &usb_demod;
			break;
		case 'L':
			fm.mode_demod = &lsb_demod;
			break;
		case 'R':
			fm.mode_demod = &raw_demod;
			break;
		default:
			usage();
			break;
		}
	}
	/* quadruple sample_rate to limit to Δθ to ±π/2 */
	fm.sample_rate *= fm.post_downsample;

	if (fm.freq_len == 0) {
		fprintf(stderr, "Please specify a frequency.\n");
		exit(1);
	}

	if (fm.freq_len > 1) {
		fm.terminate_on_squelch = 0;
	}

	if (argc <= optind) {
		//usage();
		filename = "-";
	} else {
		filename = argv[optind];
	}

	buffer = malloc(lcm_post[fm.post_downsample] * DEFAULT_BUF_LENGTH * sizeof(uint8_t));

	device_count = rtlsdr_get_device_count();
	if (!device_count) {
		fprintf(stderr, "No supported devices found.\n");
		exit(1);
	}

	fprintf(stderr, "Found %d device(s):\n", device_count);
	for (i = 0; i < device_count; i++) {
		rtlsdr_get_device_usb_strings(i, vendor, product, serial);
		fprintf(stderr, "  %d:  %s, %s, SN: %s\n", i, vendor, product, serial);
	}
	fprintf(stderr, "\n");

	fprintf(stderr, "Using device %d: %s\n",
		dev_index, rtlsdr_get_device_name(dev_index));

	r = rtlsdr_open(&dev, dev_index);
	if (r < 0) {
		fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index);
		exit(1);
	}
#ifndef _WIN32
	sigact.sa_handler = sighandler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigaction(SIGPIPE, &sigact, NULL);
#else
	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE );
#endif

	/* WBFM is special */
	if (wb_mode) {
		fm.freqs[0] += 16000;
	}

	if (fm.deemph) {
		fm.deemph_a = (int)round(1.0/((1.0-exp(-1.0/(fm.output_rate * 75e-6)))));
	}

	optimal_settings(&fm, 0, 0);
	build_fir(&fm);

	/* Set the tuner gain */
	if (gain == AUTO_GAIN) {
		r = rtlsdr_set_tuner_gain_mode(dev, 0);
	} else {
		r = rtlsdr_set_tuner_gain_mode(dev, 1);
		r = rtlsdr_set_tuner_gain(dev, gain);
	}
	if (r != 0) {
		fprintf(stderr, "WARNING: Failed to set tuner gain.\n");
	} else if (gain == AUTO_GAIN) {
		fprintf(stderr, "Tuner gain set to automatic.\n");
	} else {
		fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0);
	}
	r = rtlsdr_set_freq_correction(dev, ppm_error);

	if (strcmp(filename, "-") == 0) { /* Write samples to stdout */
		fm.file = stdout;
#ifdef _WIN32
		_setmode(_fileno(fm.file), _O_BINARY);
#endif
	} else {
		fm.file = fopen(filename, "wb");
		if (!fm.file) {
			fprintf(stderr, "Failed to open %s\n", filename);
			exit(1);
		}
	}

	/* Reset endpoint before we start reading from it (mandatory) */
	r = rtlsdr_reset_buffer(dev);
	if (r < 0) {
		fprintf(stderr, "WARNING: Failed to reset buffers.\n");}

	pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(&fm));
	rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&fm),
			      DEFAULT_ASYNC_BUF_NUMBER,
			      lcm_post[fm.post_downsample] * DEFAULT_BUF_LENGTH);

	if (do_exit) {
		fprintf(stderr, "\nUser cancel, exiting...\n");}
	else {
		fprintf(stderr, "\nLibrary error %d, exiting...\n", r);}
	rtlsdr_cancel_async(dev);
	//    pthread_mutex_destroy(&data_ready);
	//    pthread_mutex_destroy(&data_write);

	if (fm.file != stdout) {
		fclose(fm.file);}

	rtlsdr_close(dev);
    free(fm.buf);
	free (buffer);
	return r >= 0 ? r : -r;
}
Ejemplo n.º 20
0
static int do_sdr_decode(struct dab_state_t* dab, int frequency, int gain)
{
  struct sigaction sigact;
  uint32_t dev_index = 0;
  int32_t device_count;
  int i,r;
  char vendor[256], product[256], serial[256];
  uint32_t samp_rate = 2048000;

  memset(&sdr,0,sizeof(struct sdr_state_t));

  sdr.frequency = frequency;

  //fprintf(stderr,"%i\n",sdr.frequency);

  /*---------------------------------------------------
    Looking for device and open connection
    ----------------------------------------------------*/
  if (dab->device_type == DAB_DEVICE_RTLSDR) {
    sdr.convert_unsigned = 1;

    device_count = rtlsdr_get_device_count();
    if (!device_count) {
      fprintf(stderr, "No supported devices found.\n");
      exit(1);
    }

    fprintf(stderr, "Found %d device(s):\n", device_count);
    for (i = 0; i < device_count; i++) {
      rtlsdr_get_device_usb_strings(i, vendor, product, serial);
      fprintf(stderr, "  %d:  %s, %s, SN: %s\n", i, vendor, product, serial);
    }
    fprintf(stderr, "\n");

    fprintf(stderr, "Using device %d: %s\n",dev_index, rtlsdr_get_device_name(dev_index));

    r = rtlsdr_open(&dev, dev_index);
    if (r < 0) {
      fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index);
      exit(1);
    }

    int gains[100];
    int count = rtlsdr_get_tuner_gains(dev, gains);
    fprintf(stderr, "Supported gain values (%d): ", count);
    for (i = 0; i < count; i++)
      fprintf(stderr, "%.1f ", gains[i] / 10.0);
    fprintf(stderr, "\n");
  }
  else if (dab->device_type == DAB_DEVICE_HACKRF) {
    sdr.convert_unsigned = 0;
    r = hackrf_init();
    if( r != HACKRF_SUCCESS ) {
      hackrf_err("hackrf_init() failed", r);
      return EXIT_FAILURE;
    }

    const char* serial_number = nullptr;
    r = hackrf_open_by_serial(serial_number, &hackrf);
    if( r != HACKRF_SUCCESS ) {
      hackrf_err("hackrf_open() failed", r);
      return EXIT_FAILURE;
    }
  }
  else
  {
    r = -1;
    return EXIT_FAILURE;
  }

  /*-------------------------------------------------
    Set Frequency & Sample Rate
    --------------------------------------------------*/
  if (dab->device_type == DAB_DEVICE_RTLSDR) {
    /* Set the sample rate */
    r = rtlsdr_set_sample_rate(dev, samp_rate);
    if (r < 0)
      fprintf(stderr, "WARNING: Failed to set sample rate.\n");

    /* Set the frequency */
    r = rtlsdr_set_center_freq(dev, sdr.frequency);
    if (r < 0)
      fprintf(stderr, "WARNING: Failed to set center freq.\n");
    else
      fprintf(stderr, "Tuned to %u Hz.\n", sdr.frequency);

    /*------------------------------------------------
      Setting gain  
      -------------------------------------------------*/
    if (gain == AUTO_GAIN) {
      r = rtlsdr_set_tuner_gain_mode(dev, 0);
    } else {
      r = rtlsdr_set_tuner_gain_mode(dev, 1);
      r = rtlsdr_set_tuner_gain(dev, gain);
    }
    if (r != 0) {
      fprintf(stderr, "WARNING: Failed to set tuner gain.\n");
    } else if (gain == AUTO_GAIN) {
      fprintf(stderr, "Tuner gain set to automatic.\n");
    } else {
      fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0);
    }
    /*-----------------------------------------------
      /  Reset endpoint (mandatory) 
      ------------------------------------------------*/
    r = rtlsdr_reset_buffer(dev);
  }
  else if (dab->device_type == DAB_DEVICE_HACKRF) {
    int sample_rate_hz = samp_rate;
    fprintf(stderr, "call hackrf_sample_rate_set(%u Hz/%.03f MHz)\n", sample_rate_hz, (sample_rate_hz/1e6));
    int r = hackrf_set_sample_rate_manual(hackrf, sample_rate_hz, 1);
    if( r != HACKRF_SUCCESS ) {
      hackrf_err("hackrf_sample_rate_set() failed", r);
      return EXIT_FAILURE;
    }

    /* possible settings 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28 */
    int baseband_filter_bw_hz = 2500000;
    fprintf(stderr, "call hackrf_baseband_filter_bandwidth_set(%d Hz/%.03f MHz)\n",
        baseband_filter_bw_hz, ((float)baseband_filter_bw_hz/1e6));
    r = hackrf_set_baseband_filter_bandwidth(hackrf, baseband_filter_bw_hz);
    if( r != HACKRF_SUCCESS ) {
      hackrf_err("hackrf_baseband_filter_bandwidth_set()", r);
      return EXIT_FAILURE;
    }

    r = hackrf_set_vga_gain(hackrf, hackrf_vga_gain);
    r |= hackrf_set_lna_gain(hackrf, hackrf_lna_gain);

    if( r != HACKRF_SUCCESS ) {
      hackrf_err("hackrf_vga gain/lna gain", r);
      return EXIT_FAILURE;
    }

    r = hackrf_set_freq(hackrf, sdr.frequency);
    if( r != HACKRF_SUCCESS ) {
      hackrf_err("hackrf_set_freq()", r);
      return EXIT_FAILURE;
    }
  }
  /*-----------------------------------------------
  / Signal handler
  ------------------------------------------------*/
  sigact.sa_handler = sighandler;
  sigemptyset(&sigact.sa_mask);
  sigact.sa_flags = 0;
  sigaction(SIGINT, &sigact, NULL);
  sigaction(SIGTERM, &sigact, NULL);
  sigaction(SIGQUIT, &sigact, NULL);
  sigaction(SIGPIPE, &sigact, NULL);
  /*-----------------------------------------------
  / start demod thread & rtl read 
  -----------------------------------------------*/

  fprintf(stderr,"Waiting for sync...\n");

  sdr_init(&sdr);
  //dab_fic_parser_init(&sinfo);
  //dab_analyzer_init(&ana);
  pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(dab));
  if (dab->device_type == DAB_DEVICE_RTLSDR) {
    rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&sdr),
        DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH);
  }
  else if (dab->device_type == DAB_DEVICE_HACKRF) {
    r = hackrf_start_rx(hackrf, hackrf_callback, (void *)(&sdr));

    if( r != HACKRF_SUCCESS ) {
      hackrf_err("hackrf_start_x()", r);
      return EXIT_FAILURE;
    }

    while( ((r=hackrf_is_streaming(hackrf)) == HACKRF_TRUE) &&
        (do_exit == false) ) {
      sleep(1);
      fprintf(stderr, "samples: low: %02.2f%%, saturating: %02.2f%%\n",
          num_low_power * 100.0 / DEFAULT_BUF_LENGTH,
          num_saturated * 100.0 / DEFAULT_BUF_LENGTH);
    }
    hackrf_err("hackrf_is_streaming", r);
  }


  if (do_exit) {
    fprintf(stderr, "\nUser cancel, exiting...\n");}
  else {
    fprintf(stderr, "\nLibrary error %d, exiting...\n", r);}
  if (dab->device_type == DAB_DEVICE_RTLSDR) {
    rtlsdr_cancel_async(dev);
    //dab_demod_close(&dab);
    rtlsdr_close(dev);
  }
  else if (dab->device_type == DAB_DEVICE_HACKRF) {
    if (hackrf != NULL)
    {
      r = hackrf_stop_rx(hackrf);
      if( r != HACKRF_SUCCESS ) {
        hackrf_err("hackrf_stop_rx() failed", r);
      }
      else {
        fprintf(stderr, "hackrf_stop_rx() done\n");
      }

      r = hackrf_close(hackrf);
      if( r != HACKRF_SUCCESS )
      {
        hackrf_err("hackrf_close() failed", r);
      }
      else {
        fprintf(stderr, "hackrf_close() done\n");
      }
    }

    hackrf_exit();
  }
  return 1;
}
Ejemplo n.º 21
0
int main(int argc, char **argv)
{
	struct sigaction sigact;
	char *filename = NULL;
	int r, opt;
	int i, gain = AUTO_GAIN; /* tenths of a dB */
	int dev_index = 0;
	int dev_given = 0;
	int ppm_error = 0;
	int custom_ppm = 0;
	int left_freq = 161975000;
	int right_freq = 162025000;
	int sample_rate = 12000;
	int output_rate = 48000;
	int dongle_freq, dongle_rate, delta;
	int edge = 0;
	pthread_cond_init(&ready, NULL);
	pthread_mutex_init(&ready_m, NULL);

	while ((opt = getopt(argc, argv, "l:r:s:o:EODd:g:p:h")) != -1)
	{
		switch (opt) {
		case 'l':
			left_freq = (int)atofs(optarg);
			break;
		case 'r':
			right_freq = (int)atofs(optarg);
			break;
		case 's':
			sample_rate = (int)atofs(optarg);
			break;
		case 'o':
			output_rate = (int)atofs(optarg);
			break;
		case 'E':
			edge = !edge;
			break;
		case 'D':
			dc_filter = !dc_filter;
			break;
		case 'O':
			oversample = !oversample;
			break;
		case 'd':
			dev_index = verbose_device_search(optarg);
			dev_given = 1;
			break;
		case 'g':
			gain = (int)(atof(optarg) * 10);
			break;
		case 'p':
			ppm_error = atoi(optarg);
			custom_ppm = 1;
			break;
		case 'h':
		default:
			usage();
			return 2;
		}
	}

	if (argc <= optind) {
		filename = "-";
	} else {
		filename = argv[optind];
	}

	if (left_freq > right_freq) {
		usage();
		return 2;
	}

	/* precompute rates */
	dongle_freq = left_freq/2 + right_freq/2;
	if (edge) {
		dongle_freq -= sample_rate/2;}
	delta = right_freq - left_freq;
	if (delta > 1.2e6) {
		fprintf(stderr, "Frequencies may be at most 1.2MHz apart.");
		exit(1);
	}
	if (delta < 0) {
		fprintf(stderr, "Left channel must be lower than right channel.");
		exit(1);
	}
	i = (int)log2(2.4e6 / delta);
	dongle_rate = delta * (1<<i);
	both.rate_in = dongle_rate;
	both.rate_out = delta * 2;
	i = (int)log2(both.rate_in/both.rate_out);
	both.downsample_passes = i;
	both.downsample = 1 << i;
	left.rate_in = both.rate_out;
	i = (int)log2(left.rate_in / sample_rate);
	left.downsample_passes = i;
	left.downsample = 1 << i;
	left.rate_out = left.rate_in / left.downsample;
	
	right.rate_in = left.rate_in;
	right.rate_out = left.rate_out;
	right.downsample = left.downsample;
	right.downsample_passes = left.downsample_passes;

	if (left.rate_out > output_rate) {
		fprintf(stderr, "Channel bandwidth too high or output bandwidth too low.");
		exit(1);
	}

	stereo.rate = output_rate;

	if (edge) {
		fprintf(stderr, "Edge tuning enabled.\n");
	} else {
		fprintf(stderr, "Edge tuning disabled.\n");
	}
	if (dc_filter) {
		fprintf(stderr, "DC filter enabled.\n");
	} else {
		fprintf(stderr, "DC filter disabled.\n");
	}
	fprintf(stderr, "Buffer size: %0.2f mS\n", 1000 * (double)DEFAULT_BUF_LENGTH / (double)dongle_rate);
	fprintf(stderr, "Downsample factor: %i\n", both.downsample * left.downsample);
	fprintf(stderr, "Low pass: %i Hz\n", left.rate_out);
	fprintf(stderr, "Output: %i Hz\n", output_rate);

	/* precompute lengths */
	both.len_in  = DEFAULT_BUF_LENGTH;
	both.len_out = both.len_in / both.downsample;
	left.len_in  = both.len_out;
	right.len_in = both.len_out;
	left.len_out = left.len_in / left.downsample;
	right.len_out = right.len_in / right.downsample;
	left_demod.buf_len = left.len_out;
	left_demod.result_len = left_demod.buf_len / 2;
	right_demod.buf_len = left_demod.buf_len;
	right_demod.result_len = left_demod.result_len;
	stereo.bl_len = (int)((long)(DEFAULT_BUF_LENGTH/2) * (long)output_rate / (long)dongle_rate);
	stereo.br_len = stereo.bl_len;
	stereo.result_len = stereo.br_len * 2;
	stereo.rate = output_rate;

	if (!dev_given) {
		dev_index = verbose_device_search("0");
	}

	if (dev_index < 0) {
		exit(1);
	}

	downsample_init(&both);
	downsample_init(&left);
	downsample_init(&right);
	demod_init(&left_demod);
	demod_init(&right_demod);
	stereo_init(&stereo);

	r = rtlsdr_open(&dev, (uint32_t)dev_index);
	if (r < 0) {
		fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index);
		exit(1);
	}
	sigact.sa_handler = sighandler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigaction(SIGPIPE, &sigact, NULL);

	if (strcmp(filename, "-") == 0) { /* Write samples to stdout */
		file = stdout;
		setvbuf(stdout, NULL, _IONBF, 0);
	} else {
		file = fopen(filename, "wb");
		if (!file) {
			fprintf(stderr, "Failed to open %s\n", filename);
			exit(1);
		}
	}

	/* Set the tuner gain */
	if (gain == AUTO_GAIN) {
		verbose_auto_gain(dev);
	} else {
		gain = nearest_gain(dev, gain);
		verbose_gain_set(dev, gain);
	}

	if (!custom_ppm) {
		verbose_ppm_eeprom(dev, &ppm_error);
	}
	verbose_ppm_set(dev, ppm_error);
	//r = rtlsdr_set_agc_mode(dev, 1);

	/* Set the tuner frequency */
	verbose_set_frequency(dev, dongle_freq);

	/* Set the sample rate */
	verbose_set_sample_rate(dev, dongle_rate);

	/* Reset endpoint before we start reading from it (mandatory) */
	verbose_reset_buffer(dev);

	pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(NULL));
	rtlsdr_read_async(dev, rtlsdr_callback, (void *)(NULL),
			      DEFAULT_ASYNC_BUF_NUMBER,
			      DEFAULT_BUF_LENGTH);

	if (do_exit) {
		fprintf(stderr, "\nUser cancel, exiting...\n");}
	else {
		fprintf(stderr, "\nLibrary error %d, exiting...\n", r);}
	rtlsdr_cancel_async(dev);
	safe_cond_signal(&ready, &ready_m);
	pthread_cond_destroy(&ready);
	pthread_mutex_destroy(&ready_m);

	if (file != stdout) {
		fclose(file);}

	rtlsdr_close(dev);
	return r >= 0 ? r : -r;
}
Ejemplo n.º 22
0
int main(int argc, char* argv[])
{
    int rv;
    async_started = 0;
    quit_please = 0;
    buffers_received = 0;

    signal(SIGINT, sighandler);

    printf("Opening output file...\n");
    outf = fopen("rtlsdr_out.bin", "w");
    if(outf == NULL) {
        printf("Error opening output file: %d.\nExiting.\n", errno);
        return 1;
    }

    rv = rtlsdr_get_device_count();

    if(rv == 0) {
        printf("No RTL-SDR devices found, exiting.\n");
        return 2;
    }

    printf("Found %d device(s).\n", rv);

    printf("Opening the first, '%s'...\n", rtlsdr_get_device_name(0));
    rv = rtlsdr_open(&rtlsdr, 0);
    if(rv != 0) {
        printf("Error opening device: %d\nExiting.\n", rv);
        return 3;
    }

    printf("Setting frequency to 315MHz...\n");
    rv = rtlsdr_set_center_freq(rtlsdr, 315000000);
    if(rv != 0) {
        printf("Error setting frequency: %d\nExiting.\n", rv);
        return 4;
    }
    printf("Frequency set to %uHz.\n", rtlsdr_get_center_freq(rtlsdr));

    printf("Setting gain mode to automatic.\n");
    rv = rtlsdr_set_tuner_gain_mode(rtlsdr, 0);
    if(rv != 0) {
        printf("Error setting gain mode: %d\nExiting.\n", rv);
        return 5;
    }
    printf("Gain currently set to %d.\n", rtlsdr_get_tuner_gain(rtlsdr));

    printf("Setting sample rate to 240kHz...\n");
    rv = rtlsdr_set_sample_rate(rtlsdr, 240000);
    if(rv != 0) {
        printf("Error setting sample rate: %d\nExiting.\n", rv);
        return 6;
    }
    printf("Sample rate set to %u.\n", rtlsdr_get_sample_rate(rtlsdr));

    printf("Setting AGC on...\n");
    rv = rtlsdr_set_agc_mode(rtlsdr, 1);
    if(rv != 0) {
        printf("Error setting AGC: %d\nExiting.\n", rv);
        return 7;
    }
    
    
    printf("Clearing buffer and streaming data...\n");
    rv = rtlsdr_reset_buffer(rtlsdr);
    if(rv != 0) {
        printf("Error clearing buffer: %d\nExiting.\n", rv);
        return 8;
    }

    async_started = 1;

    rv = rtlsdr_read_async(rtlsdr, read_callback, NULL, 0, 0);
    if(rv != 0) {
        printf("Error setting up async streaming: %d\nExiting.\n", rv);
        return 9;
    }

    rtlsdr_cancel_async(rtlsdr);
    rtlsdr_close(rtlsdr);
    return 0;

}
Ejemplo n.º 23
0
int main(int argc, char **argv)
{
#ifndef _WIN32
	struct sigaction sigact;
#endif
	struct fm_state fm; 
	char *filename = NULL;
	int n_read;
	int r, opt;
	int i, gain = AUTO_GAIN; // tenths of a dB
	uint8_t *buffer;
	uint32_t dev_index = 0;
	int device_count;
	char vendor[256], product[256], serial[256];
	fm.freqs[0] = 100000000;
	fm.sample_rate = DEFAULT_SAMPLE_RATE;
	fm.squelch_level = 150;
	fm.term_squelch_hits = 0;
	fm.freq_len = 0;
	fm.edge = 0;
	fm.fir_enable = 0;
	fm.prev_index = -1;
	fm.post_downsample = 1;  // once this works, default = 4
	fm.custom_atan = 0;
	sem_init(&data_ready, 0, 0);

	while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:EFA")) != -1) {
		switch (opt) {
		case 'd':
			dev_index = atoi(optarg);
			break;
		case 'f':
			fm.freqs[fm.freq_len] = (uint32_t)atof(optarg);
			fm.freq_len++;
			break;
		case 'g':
			gain = (int)(atof(optarg) * 10);
			break;
		case 'l':
			fm.squelch_level = (int)atof(optarg);
			break;
		case 's':
			fm.sample_rate = (uint32_t)atof(optarg);
			break;
		case 'o':
			fm.post_downsample = (int)atof(optarg);
			break;
		case 't':
			fm.term_squelch_hits = (int)atof(optarg);
			break;
		case 'E':
			fm.edge = 1;
			break;
		case 'F':
			fm.fir_enable = 1;
			break;
		case 'A':
			fm.custom_atan = 1;
			break;
		default:
			usage();
			break;
		}
	}
	/* quadruple sample_rate to limit to Δθ to ±π/2 */
	fm.sample_rate *= fm.post_downsample;

	if (argc <= optind) {
		usage();
	} else {
		filename = argv[optind];
	}

	buffer = malloc(DEFAULT_BUF_LENGTH * sizeof(uint8_t));

	device_count = rtlsdr_get_device_count();
	if (!device_count) {
		fprintf(stderr, "No supported devices found.\n");
		exit(1);
	}

	fprintf(stderr, "Found %d device(s):\n", device_count);
	for (i = 0; i < device_count; i++) {
		rtlsdr_get_device_usb_strings(i, vendor, product, serial);
		fprintf(stderr, "  %d:  %s, %s, SN: %s\n", i, vendor, product, serial);
	}
	fprintf(stderr, "\n");

	fprintf(stderr, "Using device %d: %s\n",
		dev_index, rtlsdr_get_device_name(dev_index));

	r = rtlsdr_open(&dev, dev_index);
	if (r < 0) {
		fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index);
		exit(1);
	}
#ifndef _WIN32
	sigact.sa_handler = sighandler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigaction(SIGPIPE, &sigact, NULL);
#else
	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE );
#endif

	optimal_settings(&fm, 0, 0);
	build_fir(&fm);

	/* Set the tuner gain */
	if (gain == AUTO_GAIN) {
		r = rtlsdr_set_tuner_gain_mode(dev, 0);
	} else {
		r = rtlsdr_set_tuner_gain_mode(dev, 1);
		r = rtlsdr_set_tuner_gain(dev, gain);
	}
	if (r != 0) {
		fprintf(stderr, "WARNING: Failed to set tuner gain.\n");
	} else if (gain == AUTO_GAIN) {
		fprintf(stderr, "Tuner gain set to automatic.\n");
	} else {
		fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0);
	}

	if (strcmp(filename, "-") == 0) { /* Write samples to stdout */
		fm.file = stdout;
	} else {
		fm.file = fopen(filename, "wb");
		if (!fm.file) {
			fprintf(stderr, "Failed to open %s\n", filename);
			exit(1);
		}
	}

	/* Reset endpoint before we start reading from it (mandatory) */
	r = rtlsdr_reset_buffer(dev);
	if (r < 0) {
		fprintf(stderr, "WARNING: Failed to reset buffers.\n");}

	pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(&fm));
	rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&fm),
			      DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH);

	if (do_exit) {
		fprintf(stderr, "\nUser cancel, exiting...\n");}
	else {
		fprintf(stderr, "\nLibrary error %d, exiting...\n", r);}
	rtlsdr_cancel_async(dev);

	if (fm.file != stdout)
		fclose(fm.file);

	rtlsdr_close(dev);
	free (buffer);
	return r >= 0 ? r : -r;
}
Ejemplo n.º 24
0
static int do_sdr_decode(struct dab_state_t* dab, int frequency, int gain)
{
  struct sigaction sigact;
  uint32_t dev_index = 0;
  int32_t device_count;
  int i,r;
  char vendor[256], product[256], serial[256];
  uint32_t samp_rate = 2048000;

  memset(&sdr,0,sizeof(struct sdr_state_t));

  sdr.frequency = frequency;

  //fprintf(stderr,"%i\n",sdr.frequency);

  /*---------------------------------------------------
    Looking for device and open connection
    ----------------------------------------------------*/
  device_count = rtlsdr_get_device_count();
  if (!device_count) {
    fprintf(stderr, "No supported devices found.\n");
    exit(1);
  }

  fprintf(stderr, "Found %d device(s):\n", device_count);
  for (i = 0; i < device_count; i++) {
    rtlsdr_get_device_usb_strings(i, vendor, product, serial);
    fprintf(stderr, "  %d:  %s, %s, SN: %s\n", i, vendor, product, serial);
  }
  fprintf(stderr, "\n");
  
  fprintf(stderr, "Using device %d: %s\n",dev_index, rtlsdr_get_device_name(dev_index));
  
  r = rtlsdr_open(&dev, dev_index);
  if (r < 0) {
    fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index);
    exit(1);
  }

  int gains[100];
  int count = rtlsdr_get_tuner_gains(dev, gains);
  fprintf(stderr, "Supported gain values (%d): ", count);
  for (i = 0; i < count; i++)
    fprintf(stderr, "%.1f ", gains[i] / 10.0);
  fprintf(stderr, "\n");

  /*-------------------------------------------------
    Set Frequency & Sample Rate
    --------------------------------------------------*/
  /* Set the sample rate */
  r = rtlsdr_set_sample_rate(dev, samp_rate);
  if (r < 0)
    fprintf(stderr, "WARNING: Failed to set sample rate.\n");
  
  /* Set the frequency */
  r = rtlsdr_set_center_freq(dev, sdr.frequency);
  if (r < 0)
    fprintf(stderr, "WARNING: Failed to set center freq.\n");
  else
    fprintf(stderr, "Tuned to %u Hz.\n", sdr.frequency);

  /*------------------------------------------------
    Setting gain  
    -------------------------------------------------*/
  if (gain == AUTO_GAIN) {
    r = rtlsdr_set_tuner_gain_mode(dev, 0);
  } else {
    r = rtlsdr_set_tuner_gain_mode(dev, 1);
    r = rtlsdr_set_tuner_gain(dev, gain);
  }
  if (r != 0) {
    fprintf(stderr, "WARNING: Failed to set tuner gain.\n");
  } else if (gain == AUTO_GAIN) {
    fprintf(stderr, "Tuner gain set to automatic.\n");
  } else {
    fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0);
  }
  /*-----------------------------------------------
  /  Reset endpoint (mandatory) 
  ------------------------------------------------*/
  r = rtlsdr_reset_buffer(dev);
  /*-----------------------------------------------
  / Signal handler
  ------------------------------------------------*/
  sigact.sa_handler = sighandler;
  sigemptyset(&sigact.sa_mask);
  sigact.sa_flags = 0;
  sigaction(SIGINT, &sigact, NULL);
  sigaction(SIGTERM, &sigact, NULL);
  sigaction(SIGQUIT, &sigact, NULL);
  sigaction(SIGPIPE, &sigact, NULL);
  /*-----------------------------------------------
  / start demod thread & rtl read 
  -----------------------------------------------*/

  fprintf(stderr,"Waiting for sync...\n");

  sdr_init(&sdr);
  //dab_fic_parser_init(&sinfo);
  //dab_analyzer_init(&ana);
  pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(dab));
  rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&sdr),
			      DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH);

  if (do_exit) {
    fprintf(stderr, "\nUser cancel, exiting...\n");}
  else {
    fprintf(stderr, "\nLibrary error %d, exiting...\n", r);}
  rtlsdr_cancel_async(dev);
  //dab_demod_close(&dab);
  rtlsdr_close(dev);
  return 1;
}
Ejemplo n.º 25
0
// cancel all read operations
//
int stop_the_radio()
{
    
    int i;
    
    // need to make sure the radio is actually running
    
    
    if(!radio_running) {
        return(0);
    }
    else {
        radio_running = 0;
        do_exit = 1;
    }
    
    post("stopping...", 0);
    
	if (do_exit) {
		sprintf(errmesg, "\nUser cancel, exiting...\n");
        post(errmesg,0);
    }
    
    // we'll figure out where library error goes later - apparently when the library
    // error occurs, control breaks out of the read loop but do_exit is not set tz
    /*
     else {
     sprintf(errmesg, "\nLibrary error %d, exiting...\n", r);
     post(errmesg,0);
     }
     */
    
    
	rtlsdr_cancel_async(dongle.dev);
    post("merging threads...");
	pthread_join(dongle.thread, NULL);

    safe_cond_signal(&controller.hop, &controller.hop_m);
	pthread_join(controller.thread, NULL);
    
    // cleanup thread overhead
    
    post("cleanup...");
	//dongle_cleanup(&dongle);

	controller_cleanup(&controller);
 
	rtlsdr_close(dongle.dev);
	// return r >= 0 ? r : -r;
    
    do_exit = 0;    // reset thread kill flag
    
    // zero out the circular buffer; - should probably use memset
    
    post("clearing buffers...");
    for(i = 0 ; i < CIRCMAX; i++ ) {
        circ_buf_left[i] = 0;
    }
    
    return(0);
    
    
    
}
Ejemplo n.º 26
0
void rtlsdrCallback(unsigned char *buf, uint32_t len, void *ctx) {
    struct mag_buf *outbuf;
    struct mag_buf *lastbuf;
    uint32_t slen;
    unsigned next_free_buffer;
    unsigned free_bufs;
    unsigned block_duration;

    static int was_odd = 0; // paranoia!!
    static int dropping = 0;

    MODES_NOTUSED(ctx);

    // Lock the data buffer variables before accessing them
    pthread_mutex_lock(&Modes.data_mutex);
    if (Modes.exit) {
        rtlsdr_cancel_async(Modes.dev); // ask our caller to exit
    }

    next_free_buffer = (Modes.first_free_buffer + 1) % MODES_MAG_BUFFERS;
    outbuf = &Modes.mag_buffers[Modes.first_free_buffer];
    lastbuf = &Modes.mag_buffers[(Modes.first_free_buffer + MODES_MAG_BUFFERS - 1) % MODES_MAG_BUFFERS];
    free_bufs = (Modes.first_filled_buffer - next_free_buffer + MODES_MAG_BUFFERS) % MODES_MAG_BUFFERS;

    // Paranoia! Unlikely, but let's go for belt and suspenders here

    if (len != MODES_RTL_BUF_SIZE) {
        fprintf(stderr, "weirdness: rtlsdr gave us a block with an unusual size (got %u bytes, expected %u bytes)\n",
                (unsigned)len, (unsigned)MODES_RTL_BUF_SIZE);

        if (len > MODES_RTL_BUF_SIZE) {
            // wat?! Discard the start.
            unsigned discard = (len - MODES_RTL_BUF_SIZE + 1) / 2;
            outbuf->dropped += discard;
            buf += discard*2;
            len -= discard*2;
        }
    }

    if (was_odd) {
        // Drop a sample so we are in sync with I/Q samples again (hopefully)
        ++buf;
        --len;
        ++outbuf->dropped;
    }

    was_odd = (len & 1);
    slen = len/2;

    if (free_bufs == 0 || (dropping && free_bufs < MODES_MAG_BUFFERS/2)) {
        // FIFO is full. Drop this block.
        dropping = 1;
        outbuf->dropped += slen;
        pthread_mutex_unlock(&Modes.data_mutex);
        return;
    }

    dropping = 0;
    pthread_mutex_unlock(&Modes.data_mutex);

    // Compute the sample timestamp and system timestamp for the start of the block
    outbuf->sampleTimestamp = lastbuf->sampleTimestamp + 12e6 * (lastbuf->length + outbuf->dropped) / Modes.sample_rate;
    block_duration = 1e9 * slen / Modes.sample_rate;

    // Get the approx system time for the start of this block
    clock_gettime(CLOCK_REALTIME, &outbuf->sysTimestamp);
    outbuf->sysTimestamp.tv_nsec -= block_duration;
    normalize_timespec(&outbuf->sysTimestamp);

    // Copy trailing data from last block (or reset if not valid)
    if (outbuf->dropped == 0 && lastbuf->length >= Modes.trailing_samples) {
        memcpy(outbuf->data, lastbuf->data + lastbuf->length - Modes.trailing_samples, Modes.trailing_samples * sizeof(uint16_t));
    } else {
        memset(outbuf->data, 0, Modes.trailing_samples * sizeof(uint16_t));
    }

    // Convert the new data
    outbuf->length = slen;
    convert_samples(buf, &outbuf->data[Modes.trailing_samples], slen, &outbuf->total_power);

    // Push the new data to the demodulation thread
    pthread_mutex_lock(&Modes.data_mutex);

    Modes.mag_buffers[next_free_buffer].dropped = 0;
    Modes.mag_buffers[next_free_buffer].length = 0;  // just in case
    Modes.first_free_buffer = next_free_buffer;

    // accumulate CPU while holding the mutex, and restart measurement
    end_cpu_timing(&reader_thread_start, &Modes.reader_cpu_accumulator);
    start_cpu_timing(&reader_thread_start);

    pthread_cond_signal(&Modes.data_cond);
    pthread_mutex_unlock(&Modes.data_mutex);
}
Ejemplo n.º 27
0
int main (int argc, char **argv)
{
  struct sigaction sigact;
  uint32_t dev_index = 0;
  int32_t device_count;
  int i,r;
  char vendor[256], product[256], serial[256];
  uint32_t samp_rate = 2048000;

  int gain = AUTO_GAIN;
  dab_state dab;

  if (argc > 1) {
    dab.frequency = atoi(argv[1]);
  } else {
    //dab.frequency = 220352000;
    dab.frequency = 222064000;
  }
  //fprintf(stderr,"%i\n",dab.frequency);

  fprintf(stderr,"\n");
  fprintf(stderr,"rtldab %s \n",VERSION);
  fprintf(stderr,"build: %s %s\n", __DATE__,__TIME__);
  fprintf(stderr,"\n");
  fprintf(stderr,"   _____ _______ _      _____          ____  \n");
  fprintf(stderr,"  |  __ \\__   __| |    |  __ \\   /\\   |  _ \\ \n");
  fprintf(stderr,"  | |__) | | |  | |    | |  | | /  \\  | |_) |\n");
  fprintf(stderr,"  |  _  /  | |  | |    | |  | |/ /\\ \\ |  _ < \n");
  fprintf(stderr,"  | | \\ \\  | |  | |____| |__| / ____ \\| |_) |\n");
  fprintf(stderr,"  |_|  \\_\\ |_|  |______|_____/_/    \\_\\____/ \n");
  fprintf(stderr,"\n");
  fprintf(stderr,"\n\nrtl-dab Copyright (C) 2012  David May \n");
  fprintf(stderr,"This program comes with ABSOLUTELY NO WARRANTY\n");
  fprintf(stderr,"This is free software, and you are welcome to\n");
  fprintf(stderr,"redistribute it under certain conditions\n\n\n");
  fprintf(stderr,"--------------------------------\n");
  fprintf(stderr,"Many thanks to the osmocom team!\n");
  fprintf(stderr,"--------------------------------\n\n");


  /*---------------------------------------------------
    Looking for device and open connection
    ----------------------------------------------------*/
  device_count = rtlsdr_get_device_count();
  if (!device_count) {
    fprintf(stderr, "No supported devices found.\n");
    exit(1);
  }
  
  fprintf(stderr, "Found %d device(s):\n", device_count);
  for (i = 0; i < device_count; i++) {
    rtlsdr_get_device_usb_strings(i, vendor, product, serial);
    fprintf(stderr, "  %d:  %s, %s, SN: %s\n", i, vendor, product, serial);
  }
  fprintf(stderr, "\n");
  
  fprintf(stderr, "Using device %d: %s\n",dev_index, rtlsdr_get_device_name(dev_index));
  
  r = rtlsdr_open(&dev, dev_index);
  if (r < 0) {
    fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index);
    exit(1);
  }

  /*-------------------------------------------------
    Set Frequency & Sample Rate
    --------------------------------------------------*/
  /* Set the sample rate */
  r = rtlsdr_set_sample_rate(dev, samp_rate);
  if (r < 0)
    fprintf(stderr, "WARNING: Failed to set sample rate.\n");
  
  /* Set the frequency */
  r = rtlsdr_set_center_freq(dev, dab.frequency);
  if (r < 0)
    fprintf(stderr, "WARNING: Failed to set center freq.\n");
  else
    fprintf(stderr, "Tuned to %u Hz.\n", dab.frequency);

  /*------------------------------------------------
    Setting gain  
    -------------------------------------------------*/
  if (gain == AUTO_GAIN) {
    r = rtlsdr_set_tuner_gain_mode(dev, 0);
  } else {
    r = rtlsdr_set_tuner_gain_mode(dev, 1);
    r = rtlsdr_set_tuner_gain(dev, gain);
  }
  if (r != 0) {
    fprintf(stderr, "WARNING: Failed to set tuner gain.\n");
  } else if (gain == AUTO_GAIN) {
    fprintf(stderr, "Tuner gain set to automatic.\n");
  } else {
    fprintf(stderr, "Tuner gain set to %0.2f dB.\n", gain/10.0);
  }
  /*-----------------------------------------------
  /  Reset endpoint (mandatory) 
  ------------------------------------------------*/
  r = rtlsdr_reset_buffer(dev);
  /*-----------------------------------------------
  / Signal handler
  ------------------------------------------------*/
  sigact.sa_handler = sighandler;
  sigemptyset(&sigact.sa_mask);
  sigact.sa_flags = 0;
  sigaction(SIGINT, &sigact, NULL);
  sigaction(SIGTERM, &sigact, NULL);
  sigaction(SIGQUIT, &sigact, NULL);
  sigaction(SIGPIPE, &sigact, NULL);
  /*-----------------------------------------------
  / start demod thread & rtl read 
  -----------------------------------------------*/
  dab_demod_init(&dab);
  dab_fic_parser_init(&sinfo);
  dab_analyzer_init(&ana);
  pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(&dab));
  rtlsdr_read_async(dev, rtlsdr_callback, (void *)(&dab),
			      DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH);

  if (do_exit) {
    fprintf(stderr, "\nUser cancel, exiting...\n");}
  else {
    fprintf(stderr, "\nLibrary error %d, exiting...\n", r);}
  rtlsdr_cancel_async(dev);
  //dab_demod_close(&dab);
  rtlsdr_close(dev);
  return 1;
}
Ejemplo n.º 28
0
//
//=========================================================================
//
int main(int argc, char **argv) {
    int j;

    // Set sane defaults
    modesInitConfig();
    signal(SIGINT, sigintHandler); // Define Ctrl/C handler (exit program)

    // Parse the command line options
    for (j = 1; j < argc; j++) {
        int more = j+1 < argc; // There are more arguments

        if (!strcmp(argv[j],"--device-index") && more) {
            Modes.dev_index = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--gain") && more) {
            Modes.gain = (int) atof(argv[++j])*10; // Gain is in tens of DBs
        } else if (!strcmp(argv[j],"--enable-agc")) {
            Modes.enable_agc++;
        } else if (!strcmp(argv[j],"--freq") && more) {
            Modes.freq = (int) strtoll(argv[++j],NULL,10);
        } else if (!strcmp(argv[j],"--ifile") && more) {
            Modes.filename = strdup(argv[++j]);
        } else if (!strcmp(argv[j],"--fix")) {
            Modes.nfix_crc = 1;
        } else if (!strcmp(argv[j],"--no-fix")) {
            Modes.nfix_crc = 0;
        } else if (!strcmp(argv[j],"--no-crc-check")) {
            Modes.check_crc = 0;
        } else if (!strcmp(argv[j],"--phase-enhance")) {
            Modes.phase_enhance = 1;
        } else if (!strcmp(argv[j],"--raw")) {
            Modes.raw = 1;
        } else if (!strcmp(argv[j],"--net")) {
            Modes.net = 1;
        } else if (!strcmp(argv[j],"--modeac")) {
            Modes.mode_ac = 1;
        } else if (!strcmp(argv[j],"--net-beast")) {
            Modes.beast = 1;
        } else if (!strcmp(argv[j],"--net-only")) {
            Modes.net = 1;
            Modes.net_only = 1;
       } else if (!strcmp(argv[j],"--net-heartbeat") && more) {
            Modes.net_heartbeat_rate = atoi(argv[++j]) * 15;
       } else if (!strcmp(argv[j],"--net-ro-size") && more) {
            Modes.net_output_raw_size = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-ro-rate") && more) {
            Modes.net_output_raw_rate = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-ro-port") && more) {
            if (Modes.beast) // Required for legacy backward compatibility
                {Modes.net_output_beast_port = atoi(argv[++j]);;}
            else
                {Modes.net_output_raw_port = atoi(argv[++j]);}
        } else if (!strcmp(argv[j],"--net-ri-port") && more) {
            Modes.net_input_raw_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-bo-port") && more) {
            Modes.net_output_beast_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-bi-port") && more) {
            Modes.net_input_beast_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-http-port") && more) {
            Modes.net_http_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--net-sbs-port") && more) {
            Modes.net_output_sbs_port = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--onlyaddr")) {
            Modes.onlyaddr = 1;
        } else if (!strcmp(argv[j],"--metric")) {
            Modes.metric = 1;
        } else if (!strcmp(argv[j],"--aggressive")) {
            Modes.nfix_crc = MODES_MAX_BITERRORS;
        } else if (!strcmp(argv[j],"--interactive")) {
            Modes.interactive = 1;
        } else if (!strcmp(argv[j],"--interactive-rows") && more) {
            Modes.interactive_rows = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--interactive-ttl") && more) {
            Modes.interactive_display_ttl = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--lat") && more) {
            Modes.fUserLat = atof(argv[++j]);
        } else if (!strcmp(argv[j],"--lon") && more) {
            Modes.fUserLon = atof(argv[++j]);
        } else if (!strcmp(argv[j],"--debug") && more) {
            char *f = argv[++j];
            while(*f) {
                switch(*f) {
                case 'D': Modes.debug |= MODES_DEBUG_DEMOD; break;
                case 'd': Modes.debug |= MODES_DEBUG_DEMODERR; break;
                case 'C': Modes.debug |= MODES_DEBUG_GOODCRC; break;
                case 'c': Modes.debug |= MODES_DEBUG_BADCRC; break;
                case 'p': Modes.debug |= MODES_DEBUG_NOPREAMBLE; break;
                case 'n': Modes.debug |= MODES_DEBUG_NET; break;
                case 'j': Modes.debug |= MODES_DEBUG_JS; break;
                default:
                    fprintf(stderr, "Unknown debugging flag: %c\n", *f);
                    exit(1);
                    break;
                }
                f++;
            }
        } else if (!strcmp(argv[j],"--stats")) {
            Modes.stats = 1;
        } else if (!strcmp(argv[j],"--snip") && more) {
            snipMode(atoi(argv[++j]));
            exit(0);
        } else if (!strcmp(argv[j],"--help")) {
            showHelp();
            exit(0);
        } else if (!strcmp(argv[j],"--ppm") && more) {
            Modes.ppm_error = atoi(argv[++j]);
        } else if (!strcmp(argv[j],"--quiet")) {
            Modes.quiet = 1;
        } else if (!strcmp(argv[j],"--mlat")) {
            Modes.mlat = 1;
        } else if (!strcmp(argv[j],"--interactive-rtl1090")) {
            Modes.interactive = 1;
            Modes.interactive_rtl1090 = 1;
        } else {
            fprintf(stderr,
                "Unknown or not enough arguments for option '%s'.\n\n",
                argv[j]);
            showHelp();
            exit(1);
        }
    }

#ifndef _WIN32
    // Setup for SIGWINCH for handling lines
    if (Modes.interactive) {signal(SIGWINCH, sigWinchCallback);}
#endif

    // Initialization
    modesInit();

    if (Modes.net_only) {
        fprintf(stderr,"Net-only mode, no RTL device or file open.\n");
    } else if (Modes.filename == NULL) {
        modesInitRTLSDR();
    } else {
        if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') {
            Modes.fd = STDIN_FILENO;
        } else if ((Modes.fd = open(Modes.filename,O_RDONLY)) == -1) {
            perror("Opening data file");
            exit(1);
        }
    }
    if (Modes.net) modesInitNet();

    // If the user specifies --net-only, just run in order to serve network
    // clients without reading data from the RTL device
    while (Modes.net_only) {
        if (Modes.exit) exit(0); // If we exit net_only nothing further in main()
        backgroundTasks();
        usleep(100000);
    }

    // Create the thread that will read the data from the device.
    pthread_create(&Modes.reader_thread, NULL, readerThreadEntryPoint, NULL);
    pthread_mutex_lock(&Modes.data_mutex);

    while (Modes.exit == 0) {

        if (Modes.iDataReady == 0) {
            pthread_cond_wait(&Modes.data_cond,&Modes.data_mutex); // This unlocks Modes.data_mutex, and waits for Modes.data_cond 
            continue;                                              // Once (Modes.data_cond) occurs, it locks Modes.data_mutex
        }

        // Modes.data_mutex is Locked, and (Modes.iDataReady != 0)
        if (Modes.iDataReady) { // Check we have new data, just in case!!
 
            Modes.iDataOut &= (MODES_ASYNC_BUF_NUMBER-1); // Just incase

            // Translate the next lot of I/Q samples into Modes.magnitude
            computeMagnitudeVector(Modes.pData[Modes.iDataOut]);

            Modes.stSystemTimeBlk = Modes.stSystemTimeRTL[Modes.iDataOut];

            // Update the input buffer pointer queue
            Modes.iDataOut   = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataOut + 1); 
            Modes.iDataReady = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn - Modes.iDataOut);   

            // If we lost some blocks, correct the timestamp
            if (Modes.iDataLost) {
                Modes.timestampBlk += (MODES_ASYNC_BUF_SAMPLES * 6 * Modes.iDataLost);
                Modes.iDataLost = 0;
            }

            // It's safe to release the lock now
            pthread_cond_signal (&Modes.data_cond);
            pthread_mutex_unlock(&Modes.data_mutex);

            // Process data after releasing the lock, so that the capturing
            // thread can read data while we perform computationally expensive
            // stuff at the same time.
            detectModeS(Modes.magnitude, MODES_ASYNC_BUF_SAMPLES);

            // Update the timestamp ready for the next block
            Modes.timestampBlk += (MODES_ASYNC_BUF_SAMPLES*6);

        } else {
            pthread_cond_signal (&Modes.data_cond);
            pthread_mutex_unlock(&Modes.data_mutex);
        }

        backgroundTasks();
        pthread_mutex_lock(&Modes.data_mutex);
    }

    // If --stats were given, print statistics
    if (Modes.stats) {
        printf("\n\n");
        if (Modes.interactive)
            interactiveShowData();
        printf("%d ModeA/C detected\n",                           Modes.stat_ModeAC);
        printf("%d valid Mode-S preambles\n",                     Modes.stat_valid_preamble);
        printf("%d DF-?? fields corrected for length\n",          Modes.stat_DF_Len_Corrected);
        printf("%d DF-?? fields corrected for type\n",            Modes.stat_DF_Type_Corrected);
        printf("%d demodulated with 0 errors\n",                  Modes.stat_demodulated0);
        printf("%d demodulated with 1 error\n",                   Modes.stat_demodulated1);
        printf("%d demodulated with 2 errors\n",                  Modes.stat_demodulated2);
        printf("%d demodulated with > 2 errors\n",                Modes.stat_demodulated3);
        printf("%d with good crc\n",                              Modes.stat_goodcrc);
        printf("%d with bad crc\n",                               Modes.stat_badcrc);
        printf("%d errors corrected\n",                           Modes.stat_fixed);
        for (j = 0;  j < MODES_MAX_BITERRORS;  j++) {
            printf("   %d with %d bit %s\n", Modes.stat_bit_fix[j], j+1, (j==0)?"error":"errors");
        }
        if (Modes.phase_enhance) {
            printf("%d phase enhancement attempts\n",                 Modes.stat_out_of_phase);
            printf("%d phase enhanced demodulated with 0 errors\n",   Modes.stat_ph_demodulated0);
            printf("%d phase enhanced demodulated with 1 error\n",    Modes.stat_ph_demodulated1);
            printf("%d phase enhanced demodulated with 2 errors\n",   Modes.stat_ph_demodulated2);
            printf("%d phase enhanced demodulated with > 2 errors\n", Modes.stat_ph_demodulated3);
            printf("%d phase enhanced with good crc\n",               Modes.stat_ph_goodcrc);
            printf("%d phase enhanced with bad crc\n",                Modes.stat_ph_badcrc);
            printf("%d phase enhanced errors corrected\n",            Modes.stat_ph_fixed);
            for (j = 0;  j < MODES_MAX_BITERRORS;  j++) {
                printf("   %d with %d bit %s\n", Modes.stat_ph_bit_fix[j], j+1, (j==0)?"error":"errors");
            }
        }
        printf("%d total usable messages\n",                      Modes.stat_goodcrc + Modes.stat_ph_goodcrc + Modes.stat_fixed + Modes.stat_ph_fixed);
    }

    if (Modes.filename == NULL) {
        rtlsdr_cancel_async(Modes.dev);  // Cancel rtlsdr_read_async will cause data input thread to terminate cleanly
        rtlsdr_close(Modes.dev);
    }
    pthread_cond_destroy(&Modes.data_cond);     // Thread cleanup
    pthread_mutex_destroy(&Modes.data_mutex);
    pthread_join(Modes.reader_thread,NULL);     // Wait on reader thread exit
#ifndef _WIN32
    pthread_exit(0);
#else
    return (0);
#endif
}
Ejemplo n.º 29
0
/* stop front-end --------------------------------------------------------------
* stop grabber of front end
* args   : none
* return : none
*-----------------------------------------------------------------------------*/
extern void rtlsdr_quit(void) 
{
    rtlsdr_cancel_async(dev);
    rtlsdr_close(dev);
}