diff --git a/.gitignore b/.gitignore index 85ba030..903b699 100644 --- a/.gitignore +++ b/.gitignore @@ -72,4 +72,5 @@ CTestTestfile.cmake bin build +gqrx-scan diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 722d89a..93c90ee 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,15 +2,26 @@ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", + "options": { + "cwd": "${workspaceRoot}/bin/Debug" + }, + "tasks": [ { "taskName": "Build", - "command": "gcc -g -o gqrx-scan gqrx-scan.c -lm", + "command": "make", "type": "shell", "group": { "kind": "build", "isDefault": true } + }, + { + "taskName": "Clean", + "command": "make clean", + "type": "shell", + "group": "build", + "problemMatcher": [] } ] } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index fb2428b..ac3113d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,6 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE} CACHE PATH "Libr # The following folder will be included include_directories("${PROJECT_SOURCE_DIR}") -add_executable(gqrx-scan ${PROJECT_SOURCE_DIR}/gqrx-scan.c) +add_executable(gqrx-scan ${PROJECT_SOURCE_DIR}/gqrx-scan.c ${PROJECT_SOURCE_DIR}/gqrx-prot.c) target_link_libraries(gqrx-scan m) install (TARGETS gqrx-scan DESTINATION bin) diff --git a/gqrx-prot.c b/gqrx-prot.c new file mode 100644 index 0000000..210c8d8 --- /dev/null +++ b/gqrx-prot.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gqrx-prot.h" + +// +// error - wrapper for perror +// +void error(char *msg) { + perror(msg); + exit(0); +} + +// +// Connect +// +int Connect (char *hostname, int portno) +{ + int sockfd, n; + struct sockaddr_in serveraddr; + struct hostent *server; + + + /* socket: create the socket */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + error("ERROR opening socket"); + + /* gethostbyname: get the server's DNS entry */ + server = gethostbyname(hostname); + if (server == NULL) { + fprintf(stderr,"ERROR, no such host as %s\n", hostname); + exit(0); + } + + /* build the server's Internet address */ + bzero((char *) &serveraddr, sizeof(serveraddr)); + serveraddr.sin_family = AF_INET; + bcopy((char *)server->h_addr, + (char *)&serveraddr.sin_addr.s_addr, server->h_length); + serveraddr.sin_port = htons(portno); + + /* connect: create a connection with the server */ + if (connect(sockfd, (const struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) + error("ERROR connecting"); + + return sockfd; +} +// +// Send +// +bool Send(int sockfd, char *buf) +{ + int n; + + n = write(sockfd, buf, strlen(buf)); + if (n < 0) + error("ERROR writing to socket"); + return true; +} + +// +// Recv +// +bool Recv(int sockfd, char *buf) +{ + int n; + + n = read(sockfd, buf, BUFSIZE); + if (n < 0) + error("ERROR reading from socket"); + buf[n]= '\0'; + return true; +} + + +// +// GQRX Protocol +// +bool GetCurrentFreq(int sockfd, long *freq) +{ + char buf[BUFSIZE]; + + Send(sockfd, "f\n"); + Recv(sockfd, buf); + + if (strcmp(buf, "RPRT 1") == 0 ) + return false; + + sscanf(buf, "%ld", freq); + return true; +} +bool SetFreq(int sockfd, long freq) +{ + char buf[BUFSIZE]; + + sprintf (buf, "F %ld\n", freq); + Send(sockfd, buf); + Recv(sockfd, buf); + + if (strcmp(buf, "RPRT 1") == 0 ) + return false; + + long freq_current = 0; + do + { + GetCurrentFreq(sockfd, &freq_current); + } while (freq_current != freq); + + return true; +} + +bool GetSignalLevel(int sockfd, double *dBFS) +{ + char buf[BUFSIZE]; + + Send(sockfd, "l\n"); + Recv(sockfd, buf); + + if (strcmp(buf, "RPRT 1") == 0 ) + return false; + + sscanf(buf, "%lf", dBFS); + *dBFS = round((*dBFS) * 10)/10; + + if (*dBFS == 0.0) + return false; + return true; +} + +bool GetSquelchLevel(int sockfd, double *dBFS) +{ + char buf[BUFSIZE]; + + Send(sockfd, "l SQL\n"); + Recv(sockfd, buf); + + if (strcmp(buf, "RPRT 1") == 0 ) + return false; + + sscanf(buf, "%lf", dBFS); + *dBFS = round((*dBFS) * 10)/10; + + return true; +} +// +// GetSignalLevelEx +// Get a bunch of sample with some delay and calculate the mean value +// +bool GetSignalLevelEx(int sockfd, double *dBFS, int n_samp) +{ + double temp_level; + *dBFS = 0; + int errors = 0; + for (int i = 0; i < n_samp; i++) + { + if ( GetSignalLevel(sockfd, &temp_level) ) + *dBFS = *dBFS + temp_level; + else + errors++; + usleep(1000); + } + *dBFS = *dBFS / (n_samp - errors); + return true; +} \ No newline at end of file diff --git a/gqrx-prot.h b/gqrx-prot.h new file mode 100644 index 0000000..b0dab79 --- /dev/null +++ b/gqrx-prot.h @@ -0,0 +1,43 @@ +#ifndef _GQRX_PROT_H_ +#define _GQRX_PROT_H_ + +#define BUFSIZE 1024 +#define FREQ_MAX 4096 +#define SAVED_FREQ_MAX 1000 +#define TAG_MAX 100 + + + + +// +// error - wrapper for perror +// +void error(char *msg); + +// +// Connect +// +int Connect (char *hostname, int portno); + +// +// Send +// +bool Send(int sockfd, char *buf); + +// +// Recv +// +bool Recv(int sockfd, char *buf); + +// +// GQRX Protocol +// +bool GetCurrentFreq(int sockfd, long *freq); +bool SetFreq(int sockfd, long freq); +bool GetSignalLevel(int sockfd, double *dBFS); +bool GetSquelchLevel(int sockfd, double *dBFS); +bool GetSignalLevelEx(int sockfd, double *dBFS, int n_samp); + + + +#endif /* _GQRX_PROT_H_ */ \ No newline at end of file diff --git a/gqrx-scan.c b/gqrx-scan.c index 158e111..e3c1c3f 100644 --- a/gqrx-scan.c +++ b/gqrx-scan.c @@ -22,10 +22,8 @@ #include #include -#define BUFSIZE 1024 -#define FREQ_MAX 4096 -#define SAVED_FREQ_MAX 1000 -#define TAG_MAX 100 +#include "gqrx-prot.h" + // // Globals @@ -45,165 +43,7 @@ int Frequencies_Max = 0; FREQ SavedFrequencies[SAVED_FREQ_MAX]; int SavedFreq_Max = 0; -/* - * error - wrapper for perror - */ -void error(char *msg) { - perror(msg); - exit(0); -} - -// -// Connect -// -int Connect (char *hostname, int portno) -{ - int sockfd, n; - struct sockaddr_in serveraddr; - struct hostent *server; - - - /* socket: create the socket */ - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) - error("ERROR opening socket"); - - /* gethostbyname: get the server's DNS entry */ - server = gethostbyname(hostname); - if (server == NULL) { - fprintf(stderr,"ERROR, no such host as %s\n", hostname); - exit(0); - } - /* build the server's Internet address */ - bzero((char *) &serveraddr, sizeof(serveraddr)); - serveraddr.sin_family = AF_INET; - bcopy((char *)server->h_addr, - (char *)&serveraddr.sin_addr.s_addr, server->h_length); - serveraddr.sin_port = htons(portno); - - /* connect: create a connection with the server */ - if (connect(sockfd, (const struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) - error("ERROR connecting"); - - return sockfd; -} -// -// Send -// -bool Send(int sockfd, char *buf) -{ - int n; - - n = write(sockfd, buf, strlen(buf)); - if (n < 0) - error("ERROR writing to socket"); - return true; -} - -// -// Recv -// -bool Recv(int sockfd, char *buf) -{ - int n; - - n = read(sockfd, buf, BUFSIZE); - if (n < 0) - error("ERROR reading from socket"); - buf[n]= '\0'; - return true; -} - -// -// GQRX Protocol -// -bool GetCurrentFreq(int sockfd, long *freq) -{ - char buf[BUFSIZE]; - - Send(sockfd, "f\n"); - Recv(sockfd, buf); - - if (strcmp(buf, "RPRT 1") == 0 ) - return false; - - sscanf(buf, "%ld", freq); - return true; -} -bool SetFreq(int sockfd, long freq) -{ - char buf[BUFSIZE]; - - sprintf (buf, "F %ld\n", freq); - Send(sockfd, buf); - Recv(sockfd, buf); - - if (strcmp(buf, "RPRT 1") == 0 ) - return false; - - long freq_current = 0; - do - { - GetCurrentFreq(sockfd, &freq_current); - } while (freq_current != freq); - - return true; -} - -bool GetSignalLevel(int sockfd, double *dBFS) -{ - char buf[BUFSIZE]; - - Send(sockfd, "l\n"); - Recv(sockfd, buf); - - if (strcmp(buf, "RPRT 1") == 0 ) - return false; - - sscanf(buf, "%lf", dBFS); - *dBFS = round((*dBFS) * 10)/10; - - if (*dBFS == 0.0) - return false; - return true; -} - -bool GetSquelchLevel(int sockfd, double *dBFS) -{ - char buf[BUFSIZE]; - - Send(sockfd, "l SQL\n"); - Recv(sockfd, buf); - - if (strcmp(buf, "RPRT 1") == 0 ) - return false; - - sscanf(buf, "%lf", dBFS); - *dBFS = round((*dBFS) * 10)/10; - - return true; -} -// -// GetSignalLevelEx -// Get a bunch of sample with some delay and calculate the mean value -// -bool GetSignalLevelEx(int sockfd, double *dBFS, int n_samp) -{ - double temp_level; - *dBFS = 0; - int errors = 0; - for (int i = 0; i < n_samp; i++) - { - if ( GetSignalLevel(sockfd, &temp_level) ) - *dBFS = *dBFS + temp_level; - else - errors++; - usleep(1000); - } - *dBFS = *dBFS / (n_samp - errors); - return true; -} // // Open @@ -239,7 +79,7 @@ bool prefix(const char *pre, const char *str) // // ReadFrequencies from gqrx file format // -long * ReadFrequencies (FILE *bookmarksfd) +bool ReadFrequencies (FILE *bookmarksfd) { char buf[BUFSIZE]; char *line; @@ -285,6 +125,7 @@ long * ReadFrequencies (FILE *bookmarksfd) } } Frequencies_Max = i; + return true; } @@ -370,7 +211,8 @@ bool SaveFreq(long freq_current) // AdjustFrequency // Fine tuning to reach max level // Perform a sweep between -15+15Khz around current_freq with 5kHz steps -// Return found frequency +// Return the found frequency +// long AdjustFrequency(int sockfd, long current_freq, long freq_interval) { long freq_min = current_freq - 10000; @@ -417,8 +259,8 @@ long AdjustFrequency(int sockfd, long current_freq, long freq_interval) usleep(150000); // Second pass - Fine tuning + - 5Khz (freq_steps input) with 1 khz steps - // Dived in two half, follow one until the level decreases if so follow the second half (hopefully this reduces the num of steps) - // tries to average out spikes, 3 sample + // Dived in two half, follow one until the level decreases if so follow the second half + // (hopefully this reduces the num of steps), tries to average out spikes, 3 sample double reference_level; GetSignalLevelEx( sockfd, &reference_level, 3); long reference_freq = current_freq;