-
Notifications
You must be signed in to change notification settings - Fork 4
/
bandplan.c
161 lines (145 loc) · 3.5 KB
/
bandplan.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// $Id$
// Routines for processing the file /usr/local/share/ka9q-radio/bandplan.txt
// containing general information about ham radio bandplans, other radio channels, etc
// This information is displayed in the 'Info' window by the 'radio' program
// Copyright 2018, Phil Karn, KA9Q
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(linux)
#include <bsd/string.h>
#endif
#include <ctype.h>
#include <math.h>
#include <limits.h>
#include "radio.h"
#include "bandplan.h"
char Bandplan_file[] = "bandplan.txt";
#define MAX_BANDPLANS 1000
struct bandplan Bandplans[MAX_BANDPLANS];
int Nbandplans;
// Sort callback function
static int compar(void const *a,void const *b){
const double f = *(double *)a;
const struct bandplan *bp = b;
if(f < bp->lower)
return -1;
if(f > bp->upper)
return 1;
else
return 0;
}
int Bandplan_init;
extern int init_bandplan(void);
// Look up a given frequency, return pointer to appropriate entry
struct bandplan *lookup_frequency(double f){
double key;
key = round(f) / 1.0e6;
if(!Bandplan_init){
init_bandplan();
Bandplan_init = 1;
}
return bsearch(&key,Bandplans,Nbandplans,sizeof(struct bandplan),compar);
}
// Read bandplan.txt, initialize data structures
int init_bandplan(){
char fname[PATH_MAX];
snprintf(fname,sizeof(fname),"%s/%s",Libdir,Bandplan_file);
FILE * const fp = fopen(fname,"r");
if(fp == NULL)
return -1;
char line[160];
memset(line,0,sizeof(line));
int i=0;
for(i=0; i < MAX_BANDPLANS && fgets(line,sizeof(line),fp) != NULL;){
if(line[0] == ';' || line[0] == '#')
continue;
char classes[160];
char modes[160];
double lower,upper;
int nchar = 0;
int r = sscanf(line,"%lf %lf %160s %160s %n",&lower,&upper,classes,modes,&nchar);
if(r < 4){
double center,bw;
r = sscanf(line,"%lf b%lf %160s %160s %n",¢er,&bw,classes,modes,&nchar);
if(r < 4)
continue;
lower = center - bw/2;
upper = center + bw/2;
}
memset(&Bandplans[i],0,sizeof(struct bandplan));
Bandplans[i].lower = lower;
Bandplans[i].upper = upper;
for(char *cp = classes;*cp != '\0';cp++){
switch(tolower(*cp)){
case '-':
Bandplans[i].classes = 0; // No privileges
break;
case 'e':
Bandplans[i].classes |= EXTRA_CLASS;
break;
case 'a':
Bandplans[i].classes |= ADVANCED_CLASS;
break;
case 'g':
Bandplans[i].classes |= GENERAL_CLASS;
break;
case 't':
Bandplans[i].classes |= TECHNICIAN_CLASS;
break;
case 'n':
Bandplans[i].classes |= NOVICE_CLASS;
break;
}
}
for(char *cp = modes;*cp != '\0';cp++){
switch(tolower(*cp)){
case '-':
Bandplans[i].modes = 0; // No modes!
break;
case 'c':
Bandplans[i].modes |= CW;
break;
case 'v':
Bandplans[i].modes |= VOICE;
break;
case 'i':
Bandplans[i].modes |= IMAGE;
break;
case 'd':
Bandplans[i].modes |= DATA;
break;
}
}
strlcpy(Bandplans[i].name,line + nchar,sizeof(Bandplans[i].name));
i++;
}
#if 0
fprintf(stderr,"%d entries read\n",i);
#endif
Nbandplans = i;
return 0;
}
#if 0
// Standalone test driver program
int main(){
double f;
struct bandplan const *bp;
while(1){
scanf("%lf",&f);
bp = lookup_frequency(f);
if(bp != NULL){
printf("%ld: %lf",f,bp->wavelength);
if(bp->modes & CW)
printf(" CW");
if(bp->modes & DATA)
printf(" Data");
if(bp->modes & VOICE)
printf(" Voice");
if(bp->modes & IMAGE)
printf(" Image");
printf("\n");
}
}
}
#endif