QO100Tx_Rx/kmlib/km_helper.cpp

429 lines
10 KiB
C++
Raw Permalink Normal View History

2025-10-20 20:11:21 +02:00
/*
* Raspberry PI / Zero AddOn Board specially for Ham Radio Applications
* ====================================================================
* Author: DJ0ABR
*
* (c) DJ0ABR
* www.dj0abr.de
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
kmhelper.cpp
===========
useful functions
*
*/
#include "../qo100trx.h"
#include <pwd.h>
int keeprunning = 1; // set to 0 at program end to exit all processes
char configfile[512] = {0};
// check if it is already running
int isRunning(char *prgname)
{
int num = 0;
char s[256];
sprintf(s,"ps -e | grep %s",prgname);
FILE *fp = popen(s,"r");
if(fp)
{
// gets the output of the system command
while (fgets(s, sizeof(s)-1, fp) != NULL)
{
if(strstr(s,prgname) && !strstr(s,"grep"))
{
if(++num == 2)
{
printf("%s is already running, do not start twice !\n",prgname);
pclose(fp);
return 1;
}
}
}
pclose(fp);
}
return 0;
}
void (*sigfunc)();
// signal handler
void sighandler(int signum)
{
//printf("\n\nprogram stopped by signal\n");
(*sigfunc)();
}
void install_signal_handler(void (*signalfunction)())
{
sigfunc = signalfunction;
// signal handler, mainly used if the user presses Ctrl-C
struct sigaction sigact;
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(SIGABRT, &sigact, NULL); // assert() error
//sigaction(SIGSEGV, &sigact, NULL);
// switch off signal 13 (broken pipe)
// instead handle the return value of the write or send function
signal(SIGPIPE, SIG_IGN);
}
void getParameters(int argc, char *argv[])
{
int opt;
while ((opt = getopt(argc, argv, "c:")) != -1)
{
switch (opt)
{
case 'c':
// specify config file name
if(optarg && strlen(optarg) > 2 && strlen(optarg) < (sizeof(configfile)-1))
{
strcpy(configfile,optarg);
}
else
{
printf("invalid Config File Parameter [-c Configfilename]: %s\n", optarg);
exit(0);
}
break;
}
}
}
// run external program and return it's output
char *runProgram(char *parameter, int maxlen)
{
//printf("run:<%s>\n",parameter);
FILE *fp = popen(parameter,"r");
if(fp)
{
*parameter = 0;
while (fgets(parameter+strlen(parameter), maxlen-1-strlen(parameter), fp) != NULL)
{
//printf("returns:<%s>\n", parameter);
}
pclose(fp);
return parameter;
}
else
printf("ERROR: cannot run: %s\n",parameter);
return NULL;
}
void showbitstring(char* title, uint8_t* data, int totallen, int anz)
{
printf("%s. len %d: ", title, totallen);
for (int i = 0; i < anz; i++)
printf("%01X ", data[i]);
printf("\n");
}
void showbytestring(char *title, uint8_t *data, int totallen, int anz)
{
printf("%s. len % 4d: ",title, totallen);
for(int i=0; i<anz; i++)
printf("%02X ",data[i]);
printf("\n");
}
void showbytestring16(char *title, uint16_t *data, int anz)
{
printf("%s. len %d: ",title,anz);
for(int i=0; i<anz; i++)
printf("%04X ",data[i]);
printf("\n");
}
void showbytestring32(char* title, uint32_t* data, int anz)
{
printf("%s. len %d: ", title, anz);
for (int i = 0; i < anz; i++)
printf("%08X ", data[i]);
printf("\n");
}
void showbytestringf(char* title, float* data, int totallen, int anz)
{
printf("%s. len %d: ", title, totallen);
for (int i = 0; i < anz; i++)
printf("%7.4f ", data[i]);
printf("\n");
}
// get own IP adress
char* ownIP()
{
static char ip[20] = { 0 };
struct ifaddrs* ifaddr, * ifa;
int s;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1)
{
printf("cannot read own IP address, getifaddrs faield. Check Networking\n");
return ip;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
continue;
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (ifa->ifa_addr->sa_family == AF_INET)
{
if (s != 0)
{
printf("getnameinfo() failed: %s\n", gai_strerror(s));
printf("cannot read own IP address, getnameinfo failed: %s. Check Networking\n", gai_strerror(s));
break;
}
if (strncmp(host, "127", 3) != 0)
{
strcpy(ip, host);
break;
}
}
}
freeifaddrs(ifaddr);
return ip;
}
char* cleanStr(char *s)
{
if(s[0] > ' ')
{
// remove trailing crlf
for(size_t j=0; j<strlen(s); j++)
if(s[j] == '\n' || s[j] == '\r') s[j] = 0;
return s; // nothing to do
}
for(size_t i=0; i<strlen(s); i++)
{
if(s[i] >= '0')
{
// i is on first character
memmove(s,s+i,strlen(s)-i);
s[strlen(s)-i] = 0;
// remove trailing crlf
for(size_t j=0; j<strlen(s); j++)
if(s[j] == 'n' || s[j] == '\r') s[j] = 0;
return s;
}
}
return NULL; // no text found in string
}
char *getword(char *s, int idx)
{
if(idx == 0)
{
for(size_t i=0; i<strlen(s); i++)
{
if(s[i] < '0')
{
s[i] = 0;
return s;
}
}
return NULL;
}
for(size_t j=0; j<strlen(s); j++)
{
if(s[j] > ' ')
{
char *start = s+j;
for(size_t k=0; k<strlen(start); k++)
{
if(start[k] == ' ' || start[k] == '\r' || start[k] == '\n')
{
start[k] = 0;
return start;
}
}
return start;
}
}
return NULL;
}
// read the value of an element from the config file
// Format:
// # ... comment
// ElementName-space-ElementValue
// the returned value is a static string and must be copied somewhere else
// before this function can be called again
char *getConfigElement(char *elemname)
{
if(strlen(configfile) < 2) return NULL;
static char s[501];
int found = 0;
char fn[1024];
if(strlen(configfile) > 512)
{
printf("config file path+name too long: %s\n",configfile);
exit(0);
}
strcpy(fn,configfile);
if(fn[0] == '~')
{
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
sprintf(fn,"%s%s",homedir,configfile+1);
}
//printf("read Configuration file %s\n",fn);
FILE *fr = fopen(fn,"rb");
if(!fr)
{
printf("!!! Configuration file %s not found !!!\n",fn);
exit(0);
}
while(1)
{
if(fgets(s,500,fr) == NULL) break;
// remove leading SPC or TAB
if(cleanStr(s) == 0) continue;
// check if its a comment
if(s[0] == '#') continue;
// get word on index
char *p = getword(s,0);
if(!p) break;
if(strcmp(p, elemname) == 0)
{
char val[500];
if(*(s+strlen(p)+1) == 0) continue;
p = getword(s+strlen(p)+1,1);
if(!p) break;
// replace , with .
char *pkomma = strchr(p,',');
if(pkomma) *pkomma = '.';
strcpy(val,p);
strcpy(s,val);
found = 1;
break;
}
}
fclose(fr);
if(found == 0) return NULL;
return s;
}
void getConfigElement_double(char *elemname, double *pv, double multiplier)
{
char *p = getConfigElement(elemname);
if(p) *pv = atof(p) * multiplier;
}
void getConfigElement_longlong(char *elemname, long long *pv, double multiplier)
{
char *p = getConfigElement(elemname);
if(p) *pv = (long long)(atof(p) * multiplier);
}
void getConfigElement_int(char *elemname, int *pv, double multiplier)
{
char *p = getConfigElement(elemname);
if(p) *pv = (int)(atof(p) * multiplier);
}
float measure_samplerate(int id, int samp, int prt)
{
static unsigned long lastus[10];
static unsigned long samples[10];
static int f[10];
static int cnt[10];
static int first=1;
if(first)
{
first = 0;
for(int i=0; i<10; i++)
{
f[i] = 1;
cnt[i] = 0;
}
}
// measure sample rate
struct timeval tv;
gettimeofday(&tv, NULL);
if(f[id])
{
f[id] = 0;
lastus[id] = tv.tv_sec * 1000000 + tv.tv_usec;
samples[id] = samp;
}
samples[id] += samp;
unsigned long tnow = tv.tv_sec * 1000000 + tv.tv_usec;
float sr = 0;
if(++(cnt[id]) >= prt)
{
cnt[id] = 0;
sr = (samples[id]*1e6)/(tnow - lastus[id]);
printf("%d: %.6f\n",id,sr/1e6);
}
return sr;
}
int measure_maxval(double v, int anz)
{
static double max = - 99999999;
static int cnt = 0;
v = fabs(v);
if(v > max)
{
max = v;
//printf("maxval: %f\n",max);
}
if(++cnt >= anz)
{
printf("maxval: %f\n",max);
max = - 99999999;
cnt = 0;
return 1;
}
return 0;
}