/* * (C) 2023 by sysmocom - s.f.m.c. GmbH * * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation; either version 3 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * */ #include #include #include #include #include #include int g_gmm_log_cat[_OSMO_GPRS_GMM_LOGC_MAX] = { [0 ... _OSMO_GPRS_GMM_LOGC_MAX - 1] = DLGLOBAL }; void osmo_gprs_gmm_set_log_cat(enum osmo_gprs_gmm_log_cat logc, int logc_num) { OSMO_ASSERT(logc < _OSMO_GPRS_GMM_LOGC_MAX); g_gmm_log_cat[logc] = logc_num; gprs_gmm_ms_fsm_set_log_cat(logc_num); } /* 3GPP TS 24.008, 10.5.7.3 GPRS Timer */ int gprs_gmm_gprs_tmr_to_secs(uint8_t gprs_tmr) { switch (gprs_tmr & GPRS_TMR_UNIT_MASK) { case GPRS_TMR_2SECONDS: return 2 * (gprs_tmr & GPRS_TMR_FACT_MASK); default: case GPRS_TMR_MINUTE: return 60 * (gprs_tmr & GPRS_TMR_FACT_MASK); case GPRS_TMR_6MINUTE: return 360 * (gprs_tmr & GPRS_TMR_FACT_MASK); case GPRS_TMR_DEACTIVATED: return -1; } } /* This functions returns a tmr value such that * - f is monotonic * - f(s) <= s * - f(s) == s if a tmr exists with s = gprs_tmr_to_secs(tmr) * - the best possible resolution is used * where * f(s) = gprs_tmr_to_secs(gprs_secs_to_tmr_floor(s)) */ uint8_t gprs_gmm_secs_to_gprs_tmr_floor(int secs) { if (secs < 0) return GPRS_TMR_DEACTIVATED; if (secs < 2 * 32) return GPRS_TMR_2SECONDS | (secs / 2); if (secs < 60 * 2) /* Ensure monotonicity */ return GPRS_TMR_2SECONDS | GPRS_TMR_FACT_MASK; if (secs < 60 * 32) return GPRS_TMR_MINUTE | (secs / 60); if (secs < 360 * 6) /* Ensure monotonicity */ return GPRS_TMR_MINUTE | GPRS_TMR_FACT_MASK; if (secs < 360 * 32) return GPRS_TMR_6MINUTE | (secs / 360); return GPRS_TMR_6MINUTE | GPRS_TMR_FACT_MASK; } /* Decode TS 24.008 10.5.3.5a "Network name". * FIXME: This should be improved & moved to libosmocore at some point, since it is also used in CS MM. */ int gprs_gmm_decode_network_name(char *name, int name_len, const uint8_t *lv) { uint8_t in_len = lv[0]; int length, padding; name[0] = '\0'; if (in_len < 1) return -EINVAL; /* must be CB encoded */ if ((lv[1] & 0x70) != 0x00) return -ENOTSUP; padding = lv[1] & 0x03; length = ((in_len - 1) * 8 - padding) / 7; if (length <= 0) return 0; gsm_7bit_decode_n(name, name_len, lv + 2, length); return length; }