Skip to content
This repository has been archived by the owner on Jan 27, 2021. It is now read-only.

Commit

Permalink
Merge pull request keenerd#18 from hayguen/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
hayguen authored Sep 17, 2016
2 parents ddb009c + 99c3e08 commit 53ccc38
Show file tree
Hide file tree
Showing 6 changed files with 808 additions and 91 deletions.
94 changes: 94 additions & 0 deletions README.rtlfm_cmdfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@

rtl_fm now has option '-C' for a command file, from which a list of frequencies are read.
So it's similar to using a frequency range, as with "-f 118M:137M:25k"
The difference is, that you can parametrize one frequency per line together with
- the tuner gain
- condition for triggering
- measurement duration
and a command to execute.
Lines starting with '#' are skipped / interpreted as comments.
Parameters a seperated by comma.

Here's an example:
---
# freq in Hz or special keyword, gain in dB, trig_crit (in/out/lt/gt), trig_level, trig_tolerance, #meas, #blocks, trigger_command
# windows: rtl_fm -f 105.2m -E rdc -w 350k -s 200k -m 2.2m -B 200000 -C cmdfile.csv -n -v
# rtl_fm -f 105.2m -E rdc -w 350k -s 200k -m 2.2m -W 4 -B 10000 -C cmdfile.csv -n -v
# linux: ./rtl_fm -f 105.2m -E rdc -w 350k -s 200k -m 2.2m -B 200000 -C cmdfile.csv -n -v
#
# windows command examples:
# cmd.exe, /C echo hello world
# cmd.exe, /C start notepad
# calc.exe
#
# linux examples:
# ssmtp
# sendxmpp
## for piping some message to ssmtp or sendxmpp you'll need to write small scripts

# 'adcmax' keyword in first column activates measurement of max adc value at capture rate to determine optimum gain and avoid oversteering
# 'adcrms' keyword activates rms calculation at capture rate. for usual it's similar to adcmax. there are differences in case of oversteering
# activate verbose output (option '-v') to get the output. The maximum possible sample value is 128.
# You should have approx. 6 dB headroom to allow measuring stronger signals, that means measured baseline values should be below 64.
# An the other side you'll want to measure weaker signals, so the measured baseline value should be above a minimum of approx 8 or 16.
adcmax,
adcrms,
100.7m, 30, in, 0, 1, 10, 100,
33.0m, 20,out,60, 3, 10, 400, /home/odroid/test/simple.sh, frq !freq! gain !gain! measured !mlevel! tenth dB !crit! { !reflevel! +/- !reftol! tenth dB }
# now check for optimal gain in some steps, which should be done per frequency!:
100.7m, 0, gt, 400, 1, 1, 100,
100.7m, 3, gt, 400, 1, 1, 100,
100.7m, 6, gt, 400, 1, 1, 100,
100.7m, 12, gt, 400, 1, 1, 100,
100.7m, 18, gt, 400, 1, 1, 100,

---

* first frequency is 100.7 MHz, tuned with ~ 30 dB tuner gain;
condition is 'in' { 0 +/- 1 } dB,
with 10 measurements, averaging the rms level in dB.
Each single measurement is processed after decimation of block/buffer-size many samples (see option -W).
The resulting number of decimated samples might get too small to allow a reliable measurement.
This number also depends on the capture rate: ensure minimum capture rate with option '-m'. This is also important for reducing aliases.
Check the output 'block length after decimation is ... samples'!
If condition for measured level is true, then a command can be triggered, which is executed in background.
Then, a next trigger for this frequency is blocked for 100 measurements.
There is nothing triggered for 100.7 MHz.

* 2nd frequency is 33.0 MHz, tuned with ~ 20 dB tuner gain;
condition is 'out' { 60 +/- 3 } dB,
with 10 measurements.
That means, the trigger is activated when averaged level is below 57 dB or above 63 dB.
Next trigger for this frequency is blocked for 400 measurements.
Triggered command is the shell script '/home/odroid/test/simple.sh',
with the arguments 'frq !freq! gain !gain! measured !mlevel! tenth dB !crit! { !reflevel! +/- !reftol! tenth dB }'.
You can use following keywords in the arguments, which need to be free standing!:
- !freq!
current frequency in Hz

- !gain!
current tuner gain in tenth dB to allow easier evaluation from scripts.

- !mlevel!
average measured level in tenth dB

- !crit!
one of "in", "out", "<" or ">" for the tested condition

- !reflevel!
condition's reference level in tenth dB

- !reftol!
condition's reference tolerance in tenth dB


Application might be monitoring of some stations
and triggering a notification, e.g. via ssmtp or sendxmpp,
when a stations power level is below it's expected value.

Another application might be triggering a recording with a second RTL dongle.


Send comments, suggestions or reports to
Hayati Ayguen <[email protected]>

68 changes: 68 additions & 0 deletions src/convenience/convenience.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#ifndef _WIN32
#include <unistd.h>
#else
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#include <process.h>
#define _USE_MATH_DEFINES
#endif

Expand All @@ -43,6 +45,8 @@ double atofs(char *s)
int len;
double suff = 1.0;
len = strlen(s);
/* allow formatting spaces from .csv command file */
while ( len > 1 && isspace(s[len-1]) ) --len;
last = s[len-1];
s[len-1] = '\0';
switch (last) {
Expand Down Expand Up @@ -325,4 +329,68 @@ int verbose_device_search(char *s)
return -1;
}

#ifndef _WIN32

void executeInBackground( char * file, char * args, char * searchStr[], char * replaceStr[] )
{
pid_t pid;
char * argv[256] = { NULL };
int k, argc = 0;
argv[argc++] = file;
if (args) {
argv[argc] = strtok(args, " ");
while (argc < 256 && argv[argc]) {
argv[++argc] = strtok(NULL, " ");
for (k=0; argv[argc] && searchStr && replaceStr && searchStr[k] && replaceStr[k]; k++) {
if (!strcmp(argv[argc], searchStr[k])) {
argv[argc] = replaceStr[k];
break;
}
}
}
}

pid = fork();
switch (pid)
{
case -1:
/* Fork() has failed */
fprintf(stderr, "error: fork for '%s' failed!\n", file);
break;
case 0:
execvp(file, argv);
fprintf(stderr, "error: execv of '%s' from within fork failed!\n", file);
exit(10);
break;
default:
/* This is processed by the parent */
break;
}
}

#else

void executeInBackground( char * file, char * args, char * searchStr[], char * replaceStr[] )
{
char * argv[256] = { NULL };
int k, argc = 0;
argv[argc++] = file;
if (args) {
argv[argc] = strtok(args, " \t");
while (argc < 256 && argv[argc]) {
argv[++argc] = strtok(NULL, " \t");
for (k=0; argv[argc] && searchStr && replaceStr && searchStr[k] && replaceStr[k]; k++) {
if (!strcmp(argv[argc], searchStr[k])) {
argv[argc] = replaceStr[k];
break;
}
}
}
}

spawnvp(P_NOWAIT, file, argv);
}

#endif

// vim: tabstop=8:softtabstop=8:shiftwidth=8:noexpandtab
3 changes: 3 additions & 0 deletions src/convenience/convenience.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,7 @@ int verbose_reset_buffer(rtlsdr_dev_t *dev);

int verbose_device_search(char *s);


void executeInBackground( char * file, char * args, char * searchStr[], char * replaceStr[] );

#endif /*__CONVENIENCE_H*/
5 changes: 3 additions & 2 deletions src/librtlsdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1493,10 +1493,11 @@ int rtlsdr_get_direct_sampling(rtlsdr_dev_t *dev)

int rtlsdr_set_ds_mode(rtlsdr_dev_t *dev, enum rtlsdr_ds_mode mode, uint32_t freq_threshold)
{
uint32_t center_freq;
if (!dev)
return -1;

uint32_t center_freq = rtlsdr_get_center_freq(dev);
center_freq = rtlsdr_get_center_freq(dev);
if ( !center_freq )
return -2;

Expand Down Expand Up @@ -1524,11 +1525,11 @@ int rtlsdr_set_ds_mode(rtlsdr_dev_t *dev, enum rtlsdr_ds_mode mode, uint32_t fre

static int rtlsdr_update_ds(rtlsdr_dev_t *dev, uint32_t freq)
{
int new_ds = 0;
int curr_ds = rtlsdr_get_direct_sampling(dev);
if ( curr_ds < 0 )
return -1;

int new_ds = 0;
switch (dev->direct_sampling_mode) {
default:
case RTLSDR_DS_IQ: break;
Expand Down
Loading

0 comments on commit 53ccc38

Please sign in to comment.