FreeCalypso > hg > gsm-net-reveng
comparison pathloss/main.c @ 65:b3f04535eb14
pathloss: initial code, no distance calculation yet
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 25 Oct 2024 07:42:53 +0000 |
parents | |
children | 599fac1b882d |
comparison
equal
deleted
inserted
replaced
64:0364d77aca58 | 65:b3f04535eb14 |
---|---|
1 /* | |
2 * This program reads a file of input parameters for a GSM radio link | |
3 * and computes maximum reach distances per several common models. | |
4 */ | |
5 | |
6 #include <ctype.h> | |
7 #include <stdio.h> | |
8 #include <stdlib.h> | |
9 #include <string.h> | |
10 #include <strings.h> | |
11 | |
12 #define MAX_FIELDS 5 | |
13 static char linebuf[256], *fields[MAX_FIELDS]; | |
14 static unsigned nfields; | |
15 | |
16 static float freq_dl, freq_ul; | |
17 static float bts_power, bts_rxs, bts_ant_gain; | |
18 static float ms_power, ms_rxs; | |
19 static int band_set, bts_param_set, ms_param_set; | |
20 | |
21 static float bts_height, ms_height; | |
22 static int bts_height_set, ms_height_set; | |
23 | |
24 static float misc_loss; | |
25 | |
26 static void | |
27 parse_into_fields(filename, lineno) | |
28 char *filename; | |
29 { | |
30 char *cp; | |
31 | |
32 nfields = 0; | |
33 for (cp = linebuf; ; ) { | |
34 while (isspace(*cp)) | |
35 cp++; | |
36 if (*cp == '\0' || *cp == '#') | |
37 break; | |
38 if (nfields >= MAX_FIELDS) { | |
39 fprintf(stderr, "%s line %d: too many fields\n", | |
40 filename, lineno); | |
41 exit(1); | |
42 } | |
43 fields[nfields++] = cp; | |
44 while (*cp && !isspace(*cp)) | |
45 cp++; | |
46 if (*cp) | |
47 *cp++ = '\0'; | |
48 } | |
49 } | |
50 | |
51 static void | |
52 set_band(filename, lineno) | |
53 char *filename; | |
54 { | |
55 if (nfields != 2) { | |
56 fprintf(stderr, "%s line %d: band setting takes 1 argument\n", | |
57 filename, lineno); | |
58 exit(1); | |
59 } | |
60 if (!strcasecmp(fields[1], "PCS")) { | |
61 freq_dl = 1990.0f; | |
62 freq_ul = 1910.0f; | |
63 } else if (!strcasecmp(fields[1], "B5")) { | |
64 freq_dl = 894.0f; | |
65 freq_ul = 849.0f; | |
66 } else if (!strcasecmp(fields[1], "ISM")) { | |
67 freq_dl = 925.2f; | |
68 freq_ul = 880.2f; | |
69 } else { | |
70 fprintf(stderr, "%s line %d: unknown band name \"%s\"\n", | |
71 filename, lineno, fields[1]); | |
72 exit(1); | |
73 } | |
74 band_set = 1; | |
75 } | |
76 | |
77 static void | |
78 set_bts_param(filename, lineno) | |
79 char *filename; | |
80 { | |
81 if (nfields != 4) { | |
82 fprintf(stderr, | |
83 "%s line %d: bts-param setting takes 3 arguments\n", | |
84 filename, lineno); | |
85 exit(1); | |
86 } | |
87 bts_power = atof(fields[1]); | |
88 bts_rxs = atof(fields[2]); | |
89 bts_ant_gain = atof(fields[3]); | |
90 bts_param_set = 1; | |
91 } | |
92 | |
93 static void | |
94 set_bts_height(filename, lineno) | |
95 char *filename; | |
96 { | |
97 float val, mult; | |
98 | |
99 if (nfields != 3) { | |
100 fprintf(stderr, | |
101 "%s line %d: bts-height setting takes 2 arguments\n", | |
102 filename, lineno); | |
103 exit(1); | |
104 } | |
105 val = atof(fields[1]); | |
106 if (!strcmp(fields[2], "m")) | |
107 mult = 1.0f; | |
108 else if (!strcmp(fields[2], "ft")) | |
109 mult = 0.3048f; | |
110 else { | |
111 fprintf(stderr, | |
112 "%s line %d: height unit must be either m or ft\n", | |
113 filename, lineno); | |
114 exit(1); | |
115 } | |
116 bts_height = val * mult; | |
117 bts_height_set = 1; | |
118 } | |
119 | |
120 static void | |
121 set_ms_param(filename, lineno) | |
122 char *filename; | |
123 { | |
124 if (nfields != 3) { | |
125 fprintf(stderr, | |
126 "%s line %d: ms-param setting takes 2 arguments\n", | |
127 filename, lineno); | |
128 exit(1); | |
129 } | |
130 ms_power = atof(fields[1]); | |
131 ms_rxs = atof(fields[2]); | |
132 ms_param_set = 1; | |
133 } | |
134 | |
135 static void | |
136 set_ms_height(filename, lineno) | |
137 char *filename; | |
138 { | |
139 float val, mult; | |
140 | |
141 if (nfields != 3) { | |
142 fprintf(stderr, | |
143 "%s line %d: ms-height setting takes 2 arguments\n", | |
144 filename, lineno); | |
145 exit(1); | |
146 } | |
147 val = atof(fields[1]); | |
148 if (!strcmp(fields[2], "m")) | |
149 mult = 1.0f; | |
150 else if (!strcmp(fields[2], "ft")) | |
151 mult = 0.3048f; | |
152 else { | |
153 fprintf(stderr, | |
154 "%s line %d: height unit must be either m or ft\n", | |
155 filename, lineno); | |
156 exit(1); | |
157 } | |
158 ms_height = val * mult; | |
159 ms_height_set = 1; | |
160 } | |
161 | |
162 static void | |
163 add_loss_line(filename, lineno) | |
164 char *filename; | |
165 { | |
166 float val; | |
167 | |
168 if (nfields != 2) { | |
169 fprintf(stderr, "%s line %d: loss setting takes 1 argument\n", | |
170 filename, lineno); | |
171 exit(1); | |
172 } | |
173 val = atof(fields[1]); | |
174 misc_loss += val; | |
175 } | |
176 | |
177 static void | |
178 process_line(filename, lineno) | |
179 char *filename; | |
180 { | |
181 if (!strcmp(fields[0], "band")) | |
182 set_band(filename, lineno); | |
183 else if (!strcmp(fields[0], "bts-param")) | |
184 set_bts_param(filename, lineno); | |
185 else if (!strcmp(fields[0], "bts-height")) | |
186 set_bts_height(filename, lineno); | |
187 else if (!strcmp(fields[0], "ms-param")) | |
188 set_ms_param(filename, lineno); | |
189 else if (!strcmp(fields[0], "ms-height")) | |
190 set_ms_height(filename, lineno); | |
191 else if (!strcmp(fields[0], "loss")) | |
192 add_loss_line(filename, lineno); | |
193 else { | |
194 fprintf(stderr, "%s line %d: non-understood setting \"%s\"\n", | |
195 filename, lineno, fields[0]); | |
196 exit(1); | |
197 } | |
198 } | |
199 | |
200 static void | |
201 check_required_params(filename) | |
202 char *filename; | |
203 { | |
204 if (!band_set) { | |
205 fprintf(stderr, "error: %s failed to set band\n", filename); | |
206 exit(1); | |
207 } | |
208 if (!bts_param_set) { | |
209 fprintf(stderr, "error: %s failed to set bts-param\n", | |
210 filename); | |
211 exit(1); | |
212 } | |
213 if (!bts_height_set) { | |
214 fprintf(stderr, "error: %s failed to set bts-height\n", | |
215 filename); | |
216 exit(1); | |
217 } | |
218 if (!ms_param_set) { | |
219 fprintf(stderr, "error: %s failed to set ms-param\n", filename); | |
220 exit(1); | |
221 } | |
222 if (!ms_height_set) { | |
223 fprintf(stderr, "error: %s failed to set ms-height\n", | |
224 filename); | |
225 exit(1); | |
226 } | |
227 } | |
228 | |
229 static void | |
230 read_param_file(filename) | |
231 char *filename; | |
232 { | |
233 FILE *inf; | |
234 int lineno; | |
235 | |
236 inf = fopen(filename, "r"); | |
237 if (!inf) { | |
238 perror(filename); | |
239 exit(1); | |
240 } | |
241 for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) { | |
242 if (!index(linebuf, '\n')) { | |
243 fprintf(stderr, | |
244 "%s line %d: too long or missing newline\n", | |
245 filename, lineno); | |
246 exit(1); | |
247 } | |
248 parse_into_fields(filename, lineno); | |
249 if (nfields == 0) | |
250 continue; | |
251 process_line(filename, lineno); | |
252 } | |
253 fclose(inf); | |
254 check_required_params(filename); | |
255 } | |
256 | |
257 main(argc, argv) | |
258 char **argv; | |
259 { | |
260 float path_loss_dl, path_loss_ul; | |
261 | |
262 if (argc != 2) { | |
263 fprintf(stderr, "usage: %s param-file\n", argv[0]); | |
264 exit(1); | |
265 } | |
266 read_param_file(argv[1]); | |
267 /* do the math */ | |
268 path_loss_dl = bts_power + bts_ant_gain - ms_rxs - misc_loss; | |
269 path_loss_ul = ms_power + bts_ant_gain - bts_rxs - misc_loss; | |
270 printf("Path loss budget: %.2f dB DL, %.2f dB UL\n", path_loss_dl, | |
271 path_loss_ul); | |
272 /* distance calculations will go here */ | |
273 exit(0); | |
274 } |