diff options
author | Harald Welte <laforge@gnumonks.org> | 2009-08-09 14:45:18 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2009-08-09 14:45:18 +0200 |
commit | 66b6a8dde061e16fb2f102eb2de9b884a1941481 (patch) | |
tree | 86bed65b3975138d176185bd8fe8aa9e13b5531f /openbsc/src/gsm_utils.c | |
parent | 31f03a6df66ccfcaa3ae71663ac53bf7c2b80c59 (diff) |
move ms_pwr utility function to gsm_utils.c
also, they should both take the gsm_band parameter, not a BTS
Diffstat (limited to 'openbsc/src/gsm_utils.c')
-rw-r--r-- | openbsc/src/gsm_utils.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/openbsc/src/gsm_utils.c b/openbsc/src/gsm_utils.c index 0c25b28c6..185918ef9 100644 --- a/openbsc/src/gsm_utils.c +++ b/openbsc/src/gsm_utils.c @@ -21,9 +21,11 @@ * */ +#include <openbsc/gsm_data.h> #include <openbsc/gsm_utils.h> #include <stdlib.h> #include <string.h> +#include <errno.h> /* GSM 03.38 6.2.1 Charachter packing */ int gsm_7bit_decode(char *text, const u_int8_t *user_data, u_int8_t length) @@ -71,3 +73,77 @@ int gsm_7bit_encode(u_int8_t *result, const char *data) return out_length; } + +/* determine power control level for given dBm value, as indicated + * by the tables in chapter 4.1.1 of GSM TS 05.05 */ +int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm) +{ + switch (band) { + case GSM_BAND_400: + case GSM_BAND_900: + case GSM_BAND_850: + if (dbm >= 39) + return 0; + else if (dbm < 5) + return 19; + else + return 2 + ((39 - dbm) / 2); + break; + case GSM_BAND_1800: + if (dbm >= 36) + return 29; + else if (dbm >= 34) + return 30; + else if (dbm >= 32) + return 31; + else + return (30 - dbm) / 2; + break; + case GSM_BAND_1900: + if (dbm >= 33) + return 30; + else if (dbm >= 32) + return 31; + else + return (30 - dbm) / 2; + break; + } + return -EINVAL; +} + +int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl) +{ + lvl &= 0x1f; + + switch (band) { + case GSM_BAND_400: + case GSM_BAND_900: + case GSM_BAND_850: + if (lvl < 2) + return 39; + else if (lvl < 20) + return 39 - ((lvl - 2) * 2) ; + else + return 5; + break; + case GSM_BAND_1800: + if (lvl < 16) + return 30 - (lvl * 2); + else if (lvl < 29) + return 0; + else + return 36 - ((lvl - 29) * 2); + break; + case GSM_BAND_1900: + if (lvl < 16) + return 30 - (lvl * 2); + else if (lvl < 30) + return -EINVAL; + else + return 33 - (lvl - 30); + break; + } + return -EINVAL; +} + + |