FreeCalypso > hg > gsm-net-reveng
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pathloss/main.c Fri Oct 25 07:42:53 2024 +0000 @@ -0,0 +1,274 @@ +/* + * This program reads a file of input parameters for a GSM radio link + * and computes maximum reach distances per several common models. + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +#define MAX_FIELDS 5 +static char linebuf[256], *fields[MAX_FIELDS]; +static unsigned nfields; + +static float freq_dl, freq_ul; +static float bts_power, bts_rxs, bts_ant_gain; +static float ms_power, ms_rxs; +static int band_set, bts_param_set, ms_param_set; + +static float bts_height, ms_height; +static int bts_height_set, ms_height_set; + +static float misc_loss; + +static void +parse_into_fields(filename, lineno) + char *filename; +{ + char *cp; + + nfields = 0; + for (cp = linebuf; ; ) { + while (isspace(*cp)) + cp++; + if (*cp == '\0' || *cp == '#') + break; + if (nfields >= MAX_FIELDS) { + fprintf(stderr, "%s line %d: too many fields\n", + filename, lineno); + exit(1); + } + fields[nfields++] = cp; + while (*cp && !isspace(*cp)) + cp++; + if (*cp) + *cp++ = '\0'; + } +} + +static void +set_band(filename, lineno) + char *filename; +{ + if (nfields != 2) { + fprintf(stderr, "%s line %d: band setting takes 1 argument\n", + filename, lineno); + exit(1); + } + if (!strcasecmp(fields[1], "PCS")) { + freq_dl = 1990.0f; + freq_ul = 1910.0f; + } else if (!strcasecmp(fields[1], "B5")) { + freq_dl = 894.0f; + freq_ul = 849.0f; + } else if (!strcasecmp(fields[1], "ISM")) { + freq_dl = 925.2f; + freq_ul = 880.2f; + } else { + fprintf(stderr, "%s line %d: unknown band name \"%s\"\n", + filename, lineno, fields[1]); + exit(1); + } + band_set = 1; +} + +static void +set_bts_param(filename, lineno) + char *filename; +{ + if (nfields != 4) { + fprintf(stderr, + "%s line %d: bts-param setting takes 3 arguments\n", + filename, lineno); + exit(1); + } + bts_power = atof(fields[1]); + bts_rxs = atof(fields[2]); + bts_ant_gain = atof(fields[3]); + bts_param_set = 1; +} + +static void +set_bts_height(filename, lineno) + char *filename; +{ + float val, mult; + + if (nfields != 3) { + fprintf(stderr, + "%s line %d: bts-height setting takes 2 arguments\n", + filename, lineno); + exit(1); + } + val = atof(fields[1]); + if (!strcmp(fields[2], "m")) + mult = 1.0f; + else if (!strcmp(fields[2], "ft")) + mult = 0.3048f; + else { + fprintf(stderr, + "%s line %d: height unit must be either m or ft\n", + filename, lineno); + exit(1); + } + bts_height = val * mult; + bts_height_set = 1; +} + +static void +set_ms_param(filename, lineno) + char *filename; +{ + if (nfields != 3) { + fprintf(stderr, + "%s line %d: ms-param setting takes 2 arguments\n", + filename, lineno); + exit(1); + } + ms_power = atof(fields[1]); + ms_rxs = atof(fields[2]); + ms_param_set = 1; +} + +static void +set_ms_height(filename, lineno) + char *filename; +{ + float val, mult; + + if (nfields != 3) { + fprintf(stderr, + "%s line %d: ms-height setting takes 2 arguments\n", + filename, lineno); + exit(1); + } + val = atof(fields[1]); + if (!strcmp(fields[2], "m")) + mult = 1.0f; + else if (!strcmp(fields[2], "ft")) + mult = 0.3048f; + else { + fprintf(stderr, + "%s line %d: height unit must be either m or ft\n", + filename, lineno); + exit(1); + } + ms_height = val * mult; + ms_height_set = 1; +} + +static void +add_loss_line(filename, lineno) + char *filename; +{ + float val; + + if (nfields != 2) { + fprintf(stderr, "%s line %d: loss setting takes 1 argument\n", + filename, lineno); + exit(1); + } + val = atof(fields[1]); + misc_loss += val; +} + +static void +process_line(filename, lineno) + char *filename; +{ + if (!strcmp(fields[0], "band")) + set_band(filename, lineno); + else if (!strcmp(fields[0], "bts-param")) + set_bts_param(filename, lineno); + else if (!strcmp(fields[0], "bts-height")) + set_bts_height(filename, lineno); + else if (!strcmp(fields[0], "ms-param")) + set_ms_param(filename, lineno); + else if (!strcmp(fields[0], "ms-height")) + set_ms_height(filename, lineno); + else if (!strcmp(fields[0], "loss")) + add_loss_line(filename, lineno); + else { + fprintf(stderr, "%s line %d: non-understood setting \"%s\"\n", + filename, lineno, fields[0]); + exit(1); + } +} + +static void +check_required_params(filename) + char *filename; +{ + if (!band_set) { + fprintf(stderr, "error: %s failed to set band\n", filename); + exit(1); + } + if (!bts_param_set) { + fprintf(stderr, "error: %s failed to set bts-param\n", + filename); + exit(1); + } + if (!bts_height_set) { + fprintf(stderr, "error: %s failed to set bts-height\n", + filename); + exit(1); + } + if (!ms_param_set) { + fprintf(stderr, "error: %s failed to set ms-param\n", filename); + exit(1); + } + if (!ms_height_set) { + fprintf(stderr, "error: %s failed to set ms-height\n", + filename); + exit(1); + } +} + +static void +read_param_file(filename) + char *filename; +{ + FILE *inf; + int lineno; + + inf = fopen(filename, "r"); + if (!inf) { + perror(filename); + exit(1); + } + for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) { + if (!index(linebuf, '\n')) { + fprintf(stderr, + "%s line %d: too long or missing newline\n", + filename, lineno); + exit(1); + } + parse_into_fields(filename, lineno); + if (nfields == 0) + continue; + process_line(filename, lineno); + } + fclose(inf); + check_required_params(filename); +} + +main(argc, argv) + char **argv; +{ + float path_loss_dl, path_loss_ul; + + if (argc != 2) { + fprintf(stderr, "usage: %s param-file\n", argv[0]); + exit(1); + } + read_param_file(argv[1]); + /* do the math */ + path_loss_dl = bts_power + bts_ant_gain - ms_rxs - misc_loss; + path_loss_ul = ms_power + bts_ant_gain - bts_rxs - misc_loss; + printf("Path loss budget: %.2f dB DL, %.2f dB UL\n", path_loss_dl, + path_loss_ul); + /* distance calculations will go here */ + exit(0); +}