diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2011-09-02 22:21:13 +0200 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2011-09-02 22:21:13 +0200 |
commit | 176f72a2edad961773a832f5499c16cc8b318441 (patch) | |
tree | 921da4dfcf3bb704511a383bce7910e1675de9f5 /src/shared/libosmocore/src/gsm | |
parent | d7410b752fc36e811c500f10718f0b73f2aa60f5 (diff) | |
parent | fe28dedd4c25b5f0f3df39d5e33ce3639574406c (diff) |
Merge commit 'fe28dedd4c25b5f0f3df39d5e33ce3639574406c'
Diffstat (limited to 'src/shared/libosmocore/src/gsm')
-rw-r--r-- | src/shared/libosmocore/src/gsm/abis_nm.c | 33 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/gsm48_ie.c | 168 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/gsm_utils.c | 40 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/lapdm.c | 42 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/rsl.c | 66 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm/tlv_parser.c | 40 |
6 files changed, 285 insertions, 104 deletions
diff --git a/src/shared/libosmocore/src/gsm/abis_nm.c b/src/shared/libosmocore/src/gsm/abis_nm.c index b54657d6..5c3647ca 100644 --- a/src/shared/libosmocore/src/gsm/abis_nm.c +++ b/src/shared/libosmocore/src/gsm/abis_nm.c @@ -20,6 +20,12 @@ * */ +/*! \addtogroup oml + * @{ + */ + +/*! \file abis_nm.c */ + #include <stdint.h> #include <errno.h> @@ -30,7 +36,7 @@ #include <osmocom/gsm/protocol/gsm_12_21.h> #include <osmocom/gsm/abis_nm.h> -/* unidirectional messages from BTS to BSC */ +/*! \brief unidirectional messages from BTS to BSC */ const enum abis_nm_msgtype abis_nm_reports[4] = { NM_MT_SW_ACTIVATED_REP, NM_MT_TEST_REP, @@ -38,14 +44,14 @@ const enum abis_nm_msgtype abis_nm_reports[4] = { NM_MT_FAILURE_EVENT_REP, }; -/* messages without ACK/NACK */ +/*! \brief messages without ACK/NACK */ const enum abis_nm_msgtype abis_nm_no_ack_nack[3] = { NM_MT_MEAS_RES_REQ, NM_MT_STOP_MEAS, NM_MT_START_MEAS, }; -/* Messages related to software load */ +/*! \brief messages related to software load */ const enum abis_nm_msgtype abis_nm_sw_load_msgs[9] = { NM_MT_LOAD_INIT_ACK, NM_MT_LOAD_INIT_NACK, @@ -59,6 +65,7 @@ const enum abis_nm_msgtype abis_nm_sw_load_msgs[9] = { NM_MT_SW_ACTIVATED_REP, }; +/*! \brief All NACKs (negative acknowledgements */ const enum abis_nm_msgtype abis_nm_nacks[33] = { NM_MT_LOAD_INIT_NACK, NM_MT_LOAD_END_NACK, @@ -133,6 +140,7 @@ static const struct value_string nack_names[] = { { 0, NULL } }; +/*! \brief Get human-readable string for OML NACK message type */ const char *abis_nm_nack_name(uint8_t nack) { return get_value_string(nack_names, nack); @@ -177,6 +185,7 @@ static const struct value_string nack_cause_names[] = { { 0, NULL } }; +/*! \brief Get human-readable string for NACK cause */ const char *abis_nm_nack_cause_name(uint8_t cause) { return get_value_string(nack_cause_names, cause); @@ -192,6 +201,7 @@ static const struct value_string event_type_names[] = { { 0, NULL } }; +/*! \brief Get human-readable string for OML event type */ const char *abis_nm_event_type_name(uint8_t cause) { return get_value_string(event_type_names, cause); @@ -208,12 +218,13 @@ static const struct value_string severity_names[] = { { 0, NULL } }; +/*! \brief Get human-readable string for perceived OML severity */ const char *abis_nm_severity_name(uint8_t cause) { return get_value_string(severity_names, cause); } -/* Attributes that the BSC can set, not only get, according to Section 9.4 */ +/*! \brief Attributes that the BSC can set, not only get, according to Section 9.4 */ const enum abis_nm_attr abis_nm_att_settable[] = { NM_ATT_ADD_INFO, NM_ATT_ADD_TEXT, @@ -242,6 +253,7 @@ const enum abis_nm_attr abis_nm_att_settable[] = { NM_ATT_MEAS_TYPE, }; +/*! \brief GSM A-bis OML TLV parser definition */ const struct tlv_definition abis_nm_att_tlvdef = { .def = { [NM_ATT_ABIS_CHANNEL] = { TLV_TYPE_FIXED, 3 }, @@ -311,6 +323,7 @@ const struct tlv_definition abis_nm_att_tlvdef = { }, }; +/*! \brief Human-readable strings for A-bis OML Object Class */ const struct value_string abis_nm_obj_class_names[] = { { NM_OC_SITE_MANAGER, "SITE-MANAGER" }, { NM_OC_BTS, "BTS" }, @@ -332,6 +345,7 @@ const struct value_string abis_nm_obj_class_names[] = { { 0, NULL } }; +/*! \brief Get human-readable string for OML Operational State */ const char *abis_nm_opstate_name(uint8_t os) { switch (os) { @@ -360,6 +374,7 @@ static const struct value_string avail_names[] = { { 0, NULL } }; +/*! \brief Get human-readable string for OML Availability State */ const char *abis_nm_avail_name(uint8_t avail) { return get_value_string(avail_names, avail); @@ -377,11 +392,13 @@ static struct value_string test_names[] = { { 0, NULL } }; +/*! \brief Get human-readable string for OML test */ const char *abis_nm_test_name(uint8_t test) { return get_value_string(test_names, test); } +/*! \brief Human-readable names for OML administrative state */ const struct value_string abis_nm_adm_state_names[] = { { NM_STATE_LOCKED, "Locked" }, { NM_STATE_UNLOCKED, "Unlocked" }, @@ -390,6 +407,10 @@ const struct value_string abis_nm_adm_state_names[] = { { 0, NULL } }; +/*! \brief write a human-readable OML header to the debug log + * \param[in] ss Logging sub-system + * \param[in] foh A-bis OML FOM header + */ void abis_nm_debugp_foh(int ss, struct abis_om_fom_hdr *foh) { DEBUGP(ss, "OC=%s(%02x) INST=(%02x,%02x,%02x) ", @@ -411,6 +432,7 @@ static const enum abis_nm_chan_comb chcomb4pchan[] = { /* FIXME: bounds check */ }; +/*! \brief Obtain OML Channel Combination for phnsical channel config */ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) { if (pchan < ARRAY_SIZE(chcomb4pchan)) @@ -419,6 +441,7 @@ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan) return -EINVAL; } +/*! \brief Obtain physical channel config for OML Channel Combination */ enum abis_nm_chan_comb abis_nm_pchan4chcomb(uint8_t chcomb) { int i; @@ -428,3 +451,5 @@ enum abis_nm_chan_comb abis_nm_pchan4chcomb(uint8_t chcomb) } return GSM_PCHAN_NONE; } + +/*! }@ */ diff --git a/src/shared/libosmocore/src/gsm/gsm48_ie.c b/src/shared/libosmocore/src/gsm/gsm48_ie.c index 863e6365..c10d0ed7 100644 --- a/src/shared/libosmocore/src/gsm/gsm48_ie.c +++ b/src/shared/libosmocore/src/gsm/gsm48_ie.c @@ -659,6 +659,18 @@ int gsm48_encode_more(struct msgb *msg) return 0; } +static int32_t smod(int32_t n, int32_t m) +{ + int32_t res; + + res = n % m; + + if (res <= 0) + res += m; + + return res; +} + /* decode "Cell Channel Description" (10.5.2.1b) and other frequency lists */ int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd, uint8_t len, uint8_t mask, uint8_t frqt) @@ -739,35 +751,35 @@ int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd, if (w[1]) f[w[1]].mask |= frqt; if (w[2]) - f[((w[1] - 512 + w[2] - 1) % 1023) + 1].mask |= frqt; + f[smod(w[1] - 512 + w[2], 1023)].mask |= frqt; if (w[3]) - f[((w[1] + w[3] - 1) % 1023) + 1].mask |= frqt; + f[smod(w[1] + w[3], 1023)].mask |= frqt; if (w[4]) - f[((w[1] - 512 + ((w[2] - 256 + w[4] - 1) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] - 512 + smod(w[2] - 256 + w[4], 511), 1023)].mask |= frqt; if (w[5]) - f[((w[1] + ((w[3] - 256 + w[5] - 1) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] + smod(w[3] - 256 + w[5], 511), 1023)].mask |= frqt; if (w[6]) - f[((w[1] - 512 + ((w[2] + w[6] - 1) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] - 512 + smod(w[2] + w[6], 511), 1023)].mask |= frqt; if (w[7]) - f[((w[1] + ((w[3] + w[7] - 1) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] + smod(w[3] + w[7], 511), 1023)].mask |= frqt; if (w[8]) - f[((w[1] - 512 + ((w[2] - 256 + ((w[4] - 128 + w[8] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] - 512 + smod(w[2] - 256 + smod(w[4] - 128 + w[8] , 255), 511), 1023)].mask |= frqt; if (w[9]) - f[((w[1] + ((w[3] - 256 + ((w[5] - 128 + w[9] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] + smod(w[3] - 256 + smod(w[5] - 128 + w[9] , 255), 511), 1023)].mask |= frqt; if (w[10]) - f[((w[1] - 512 + ((w[2] + ((w[6] - 128 + w[10] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] - 512 + smod(w[2] + smod(w[6] - 128 + w[10], 255), 511), 1023)].mask |= frqt; if (w[11]) - f[((w[1] + ((w[3] + ((w[7] - 128 + w[11] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] + smod(w[3] + smod(w[7] - 128 + w[11], 255), 511), 1023)].mask |= frqt; if (w[12]) - f[((w[1] - 512 + ((w[2] - 256 + ((w[4] + w[12] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] - 512 + smod(w[2] - 256 + smod(w[4] + w[12], 255), 511), 1023)].mask |= frqt; if (w[13]) - f[((w[1] + ((w[3] - 256 + ((w[5] + w[13] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] + smod(w[3] - 256 + smod(w[5] + w[13], 255), 511), 1023)].mask |= frqt; if (w[14]) - f[((w[1] - 512 + ((w[2] + ((w[6] + w[14] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] - 512 + smod(w[2] + smod(w[6] + w[14], 255), 511), 1023)].mask |= frqt; if (w[15]) - f[((w[1] + ((w[3] + ((w[7] + w[15] - 1) % 255)) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] + smod(w[3] + smod(w[7] + w[15], 255), 511), 1023)].mask |= frqt; if (w[16]) - f[((w[1] - 512 + ((w[2] - 256 + ((w[4] - 128 + ((w[8] - 64 + w[16] - 1) % 127)) % 255)) % 511)) % 1023) + 1].mask |= frqt; + f[smod(w[1] - 512 + smod(w[2] - 256 + smod(w[4] - 128 + smod(w[8] - 64 + w[16], 127), 255), 511), 1023)].mask |= frqt; return 0; } @@ -818,37 +830,37 @@ int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd, if (w[1]) f[(w[0] + w[1]) % 1024].mask |= frqt; if (w[2]) - f[(w[0] + ((w[1] - 256 + w[2] - 1) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 256 + w[2], 511)) % 1024].mask |= frqt; if (w[3]) - f[(w[0] + ((w[1] + w[3] - 1) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + w[3], 511)) % 1024].mask |= frqt; if (w[4]) - f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + w[4] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 256 + smod(w[2] - 128 + w[4], 255), 511)) % 1024].mask |= frqt; if (w[5]) - f[(w[0] + ((w[1] + ((w[3] - 128 + w[5] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 128 + w[5], 255), 511)) % 1024].mask |= frqt; if (w[6]) - f[(w[0] + ((w[1] - 256 + ((w[2] + w[6] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 256 + smod(w[2] + w[6], 255), 511)) % 1024].mask |= frqt; if (w[7]) - f[(w[0] + ((w[1] + ((w[3] + w[7] - 1) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + w[7], 255), 511)) % 1024].mask |= frqt; if (w[8]) - f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + ((w[4] - 64 + w[8] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 256 + smod(w[2] - 128 + smod(w[4] - 64 + w[8] , 127), 255), 511)) % 1024].mask |= frqt; if (w[9]) - f[(w[0] + ((w[1] + ((w[3] - 128 + ((w[5] - 64 + w[9] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 128 + smod(w[5] - 64 + w[9] , 127), 255), 511)) % 1024].mask |= frqt; if (w[10]) - f[(w[0] + ((w[1] - 256 + ((w[2] + ((w[6] - 64 + w[10] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 256 + smod(w[2] + smod(w[6] - 64 + w[10], 127), 255), 511)) % 1024].mask |= frqt; if (w[11]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 64 + w[11] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 64 + w[11], 127), 255), 511)) % 1024].mask |= frqt; if (w[12]) - f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + ((w[4] + w[12] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 256 + smod(w[2] - 128 + smod(w[4] + w[12], 127), 255), 511)) % 1024].mask |= frqt; if (w[13]) - f[(w[0] + ((w[1] + ((w[3] - 128 + ((w[5] + w[13] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 128 + smod(w[5] + w[13], 127), 255), 511)) % 1024].mask |= frqt; if (w[14]) - f[(w[0] + ((w[1] - 256 + ((w[2] + ((w[6] + w[14] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 256 + smod(w[2] + smod(w[6] + w[14], 127), 255), 511)) % 1024].mask |= frqt; if (w[15]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] + w[15] - 1) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] + w[15], 127), 255), 511)) % 1024].mask |= frqt; if (w[16]) - f[(w[0] + ((w[1] - 256 + ((w[2] - 128 + ((w[4] - 64 + ((w[8] - 32 + w[16] - 1) % 63)) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 256 + smod(w[2] - 128 + smod(w[4] - 64 + smod(w[8] - 32 + w[16], 63), 127), 255), 511)) % 1024].mask |= frqt; if (w[17]) - f[(w[0] + ((w[1] + ((w[3] - 128 + ((w[5] - 64 + ((w[9] - 32 + w[17] - 1) % 63)) % 127)) % 255)) % 511) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 128 + smod(w[5] - 64 + smod(w[9] - 32 + w[17], 63), 127), 255), 511)) % 1024].mask |= frqt; return 0; } @@ -907,45 +919,45 @@ int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd, if (w[1]) f[(w[0] + w[1]) % 1024].mask |= frqt; if (w[2]) - f[(w[0] + ((w[1] - 128 + w[2] - 1) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + w[2], 255)) % 1024].mask |= frqt; if (w[3]) - f[(w[0] + ((w[1] + w[3] - 1) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + w[3], 255)) % 1024].mask |= frqt; if (w[4]) - f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + w[4] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + w[4], 127), 255)) % 1024].mask |= frqt; if (w[5]) - f[(w[0] + ((w[1] + ((w[3] - 64 + w[5] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 64 + w[5], 127), 255)) % 1024].mask |= frqt; if (w[6]) - f[(w[0] + ((w[1] - 128 + ((w[2] + w[6] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + smod(w[2] + w[6], 127), 255)) % 1024].mask |= frqt; if (w[7]) - f[(w[0] + ((w[1] + ((w[3] + w[7] - 1) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + w[7], 127), 255)) % 1024].mask |= frqt; if (w[8]) - f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] - 32 + w[8] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + smod(w[4] - 32 + w[8] , 63), 127), 255)) % 1024].mask |= frqt; if (w[9]) - f[(w[0] + ((w[1] + ((w[3] - 64 + ((w[5] - 32 + w[9] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 64 + smod(w[5] - 32 + w[9] , 63), 127), 255)) % 1024].mask |= frqt; if (w[10]) - f[(w[0] + ((w[1] - 128 + ((w[2] + ((w[6] - 32 + w[10] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + smod(w[2] + smod(w[6] - 32 + w[10], 63), 127), 255)) % 1024].mask |= frqt; if (w[11]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 32 + w[11] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 32 + w[11], 63), 127), 255)) % 1024].mask |= frqt; if (w[12]) - f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] + w[12] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + smod(w[4] + w[12], 63), 127), 255)) % 1024].mask |= frqt; if (w[13]) - f[(w[0] + ((w[1] + ((w[3] - 64 + ((w[5] + w[13] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 64 + smod(w[5] + w[13], 63), 127), 255)) % 1024].mask |= frqt; if (w[14]) - f[(w[0] + ((w[1] - 128 + ((w[2] + ((w[6] + w[14] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + smod(w[2] + smod(w[6] + w[14], 63), 127), 255)) % 1024].mask |= frqt; if (w[15]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] + w[15] - 1) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] + w[15], 63), 127), 255)) % 1024].mask |= frqt; if (w[16]) - f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] - 32 + ((w[8] - 16 + w[16] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + smod(w[4] - 32 + smod(w[8] - 16 + w[16], 31), 63), 127), 255)) % 1024].mask |= frqt; if (w[17]) - f[(w[0] + ((w[1] + ((w[3] - 64 + ((w[5] - 32 + ((w[9] - 16 + w[17] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 64 + smod(w[5] - 32 + smod(w[9] - 16 + w[17], 31), 63), 127), 255)) % 1024].mask |= frqt; if (w[18]) - f[(w[0] + ((w[1] - 128 + ((w[2] + ((w[6] - 32 + ((w[10] - 16 + w[18] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + smod(w[2] + smod(w[6] - 32 + smod(w[10] - 16 + w[18], 31), 63), 127), 255)) % 1024].mask |= frqt; if (w[19]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 32 + ((w[11] - 16 + w[19] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 32 + smod(w[11] - 16 + w[19], 31), 63), 127), 255)) % 1024].mask |= frqt; if (w[20]) - f[(w[0] + ((w[1] - 128 + ((w[2] - 64 + ((w[4] + ((w[12] - 16 + w[20] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + smod(w[4] + smod(w[12] - 16 + w[20], 31), 63), 127), 255)) % 1024].mask |= frqt; if (w[21]) - f[(w[0] + ((w[1] + ((w[3] - 64 + ((w[5] + ((w[13] - 16 + w[21] - 1) % 31)) % 63)) % 127)) % 255) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 64 + smod(w[5] + smod(w[13] - 16 + w[21], 31), 63), 127), 255)) % 1024].mask |= frqt; return 0; } @@ -1018,59 +1030,59 @@ int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd, if (w[1]) f[(w[0] + w[1]) % 1024].mask |= frqt; if (w[2]) - f[(w[0] + ((w[1] - 64 + w[2] - 1) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + w[2], 127)) % 1024].mask |= frqt; if (w[3]) - f[(w[0] + ((w[1] + w[3] - 1) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + w[3], 127)) % 1024].mask |= frqt; if (w[4]) - f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + w[4] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + w[4], 63), 127)) % 1024].mask |= frqt; if (w[5]) - f[(w[0] + ((w[1] + ((w[3] - 32 + w[5] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 32 + w[5], 63), 127)) % 1024].mask |= frqt; if (w[6]) - f[(w[0] + ((w[1] - 64 + ((w[2] + w[6] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] + w[6], 63), 127)) % 1024].mask |= frqt; if (w[7]) - f[(w[0] + ((w[1] + ((w[3] + w[7] - 1) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + w[7], 63), 127)) % 1024].mask |= frqt; if (w[8]) - f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] - 16 + w[8] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] - 16 + w[8] , 31), 63), 127)) % 1024].mask |= frqt; if (w[9]) - f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] - 16 + w[9] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] - 16 + w[9] , 31), 63), 127)) % 1024].mask |= frqt; if (w[10]) - f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] - 16 + w[10] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] - 16 + w[10], 31), 63), 127)) % 1024].mask |= frqt; if (w[11]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 16 + w[11] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 16 + w[11], 31), 63), 127)) % 1024].mask |= frqt; if (w[12]) - f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] + w[12] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] + w[12], 31), 63), 127)) % 1024].mask |= frqt; if (w[13]) - f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] + w[13] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] + w[13], 31), 63), 127)) % 1024].mask |= frqt; if (w[14]) - f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] + w[14] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] + w[14], 31), 63), 127)) % 1024].mask |= frqt; if (w[15]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] + w[15] - 1) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] + w[15], 31), 63), 127)) % 1024].mask |= frqt; if (w[16]) - f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] - 16 + ((w[8] - 8 + w[16] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] - 16 + smod(w[8] - 8 + w[16], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[17]) - f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] - 16 + ((w[9] - 8 + w[17] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] - 16 + smod(w[9] - 8 + w[17], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[18]) - f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] - 16 + ((w[10] - 8 + w[18] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] - 16 + smod(w[10] - 8 + w[18], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[19]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 16 + ((w[11] - 8 + w[19] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 16 + smod(w[11] - 8 + w[19], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[20]) - f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] + ((w[12] - 8 + w[20] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] + smod(w[12] - 8 + w[20], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[21]) - f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] + ((w[13] - 8 + w[21] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] + smod(w[13] - 8 + w[21], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[22]) - f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] + ((w[14] - 8 + w[22] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] + smod(w[14] - 8 + w[22], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[23]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] + ((w[15] - 8 + w[23] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] + smod(w[15] - 8 + w[23], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[24]) - f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] - 16 + ((w[8] + w[24] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] - 16 + smod(w[8] + w[24], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[25]) - f[(w[0] + ((w[1] + ((w[3] - 32 + ((w[5] - 16 + ((w[9] + w[25] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] - 16 + smod(w[9] + w[25], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[26]) - f[(w[0] + ((w[1] - 64 + ((w[2] + ((w[6] - 16 + ((w[10] + w[26] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] - 16 + smod(w[10] + w[26], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[27]) - f[(w[0] + ((w[1] + ((w[3] + ((w[7] - 16 + ((w[11] + w[27] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 16 + smod(w[11] + w[27], 15), 31), 63), 127)) % 1024].mask |= frqt; if (w[28]) - f[(w[0] + ((w[1] - 64 + ((w[2] - 32 + ((w[4] + ((w[12] + w[28] - 1) % 15)) % 31)) % 63)) % 127) + 1) % 1024].mask |= frqt; + f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] + smod(w[12] + w[28], 15), 31), 63), 127)) % 1024].mask |= frqt; return 0; } diff --git a/src/shared/libosmocore/src/gsm/gsm_utils.c b/src/shared/libosmocore/src/gsm/gsm_utils.c index 1fa61168..8d072a1f 100644 --- a/src/shared/libosmocore/src/gsm/gsm_utils.c +++ b/src/shared/libosmocore/src/gsm/gsm_utils.c @@ -22,6 +22,46 @@ * */ +/*! \mainpage libosmogsm Documentation + * + * \section sec_intro Introduction + * This library is a collection of common code used in various + * GSM related sub-projects inside the Osmocom family of projects. It + * includes A5/1 and A5/2 ciphers, COMP128v1, a LAPDm implementation, + * a GSM TLV parser, SMS utility routines as well as + * protocol definitions for a series of protocols: + * * Um L2 (04.06) + * * Um L3 (04.08) + * * A-bis RSL (08.58) + * * A-bis OML (08.59, 12.21) + * * A (08.08) + * \n\n + * Please note that C language projects inside Osmocom are typically + * single-threaded event-loop state machine designs. As such, + * routines in libosmogsm are not thread-safe. If you must use them in + * a multi-threaded context, you have to add your own locking. + * + * \section sec_copyright Copyright and License + * Copyright © 2008-2011 - Harald Welte, Holger Freyther and contributors\n + * All rights reserved. \n\n + * The source code of libosmogsm is licensed under the terms of the GNU + * General Public License as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later + * version.\n + * See <http://www.gnu.org/licenses/> or COPYING included in the source + * code package istelf.\n + * The information detailed here is provided AS IS with NO WARRANTY OF + * ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. + * \n\n + * + * \section sec_contact Contact and Support + * Community-based support is available at the OpenBSC mailing list + * <http://lists.osmocom.org/mailman/listinfo/openbsc>\n + * Commercial support options available upon request from + * <http://sysmocom.de/> + */ + //#include <openbsc/gsm_data.h> #include <osmocom/core/utils.h> #include <osmocom/gsm/gsm_utils.h> diff --git a/src/shared/libosmocore/src/gsm/lapdm.c b/src/shared/libosmocore/src/gsm/lapdm.c index 470a5b2a..f99c1193 100644 --- a/src/shared/libosmocore/src/gsm/lapdm.c +++ b/src/shared/libosmocore/src/gsm/lapdm.c @@ -21,7 +21,14 @@ * */ -/* Notes on Buffering: rcv_buffer, tx_queue, tx_hist, send_buffer, send_queue +/*! \addtogroup lapdm + * @{ + */ + +/*! \file lapdm.c */ + +/*! + * Notes on Buffering: rcv_buffer, tx_queue, tx_hist, send_buffer, send_queue * * RX data is stored in the rcv_buffer (pointer). If the message is complete, it * is removed from rcv_buffer pointer and forwarded to L3. If the RX data is @@ -184,6 +191,10 @@ static void lapdm_dl_init(struct lapdm_datalink *dl, dl->entity = entity; } +/*! \brief initialize a LAPDm entity and all datalinks inside + * \param[in] le LAPDm entity + * \param[in] mode \ref lapdm_mode (BTS/MS) + */ void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode) { unsigned int i; @@ -194,13 +205,19 @@ void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode) lapdm_entity_set_mode(le, mode); } +/*! \brief initialize a LAPDm channel and all its channels + * \param[in] lc \ref lapdm_channel to be initialized + * \param[in] mode \ref lapdm_mode (BTS/MS) + * + * This really is a convenience wrapper around calling \ref + * lapdm_entity_init twice. + */ void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode) { lapdm_entity_init(&lc->lapdm_acch, mode); lapdm_entity_init(&lc->lapdm_dcch, mode); } - static void lapdm_dl_flush_send(struct lapdm_datalink *dl) { struct msgb *msg; @@ -227,6 +244,7 @@ static void lapdm_dl_flush_tx(struct lapdm_datalink *dl) dl->tx_length[i] = 0; } +/*! \brief flush and release all resoures in LAPDm entity */ void lapdm_entity_exit(struct lapdm_entity *le) { unsigned int i; @@ -241,6 +259,11 @@ void lapdm_entity_exit(struct lapdm_entity *le) } } +/* \brief lfush and release all resources in LAPDm channel + * + * A convenience wrapper calling \ref lapdm_entity_exit on both + * entities inside the \ref lapdm_channel + */ void lapdm_channel_exit(struct lapdm_channel *lc) { lapdm_entity_exit(&lc->lapdm_acch); @@ -355,7 +378,7 @@ static struct msgb *tx_dequeue_msgb(struct lapdm_entity *le) return msg; } -/* dequeue a msg that's pending transmission via L1 and wrap it into +/*! \brief dequeue a msg that's pending transmission via L1 and wrap it into * a osmo_phsap_prim */ int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp) { @@ -1702,6 +1725,7 @@ static int l2_ph_rach_ind(struct lapdm_entity *le, uint8_t ra, uint32_t fn, uint static int l2_ph_chan_conf(struct msgb *msg, struct lapdm_entity *le, uint32_t frame_nr); +/*! \brief Receive a PH-SAP primitive from L1 */ int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le) { struct osmo_phsap_prim *pp = (struct osmo_phsap_prim *) oph; @@ -2411,7 +2435,7 @@ static int rslms_rx_com_chan(struct msgb *msg, struct lapdm_channel *lc) return rc; } -/* input into layer2 (from layer 3) */ +/*! \brief Receive a RSLms \ref msgb from Layer 3 */ int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc) { struct abis_rsl_common_hdr *rslh = msgb_l2(msg); @@ -2439,6 +2463,7 @@ int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc) return rc; } +/*! \brief Set the \ref lapdm_mode of a LAPDm entity */ int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode) { switch (mode) { @@ -2463,6 +2488,7 @@ int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode) return 0; } +/*! \brief Set the \ref lapdm_mode of a LAPDm channel*/ int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode) { int rc; @@ -2474,6 +2500,7 @@ int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode) return lapdm_entity_set_mode(&lc->lapdm_acch, mode); } +/*! \brief Set the L1 callback and context of a LAPDm channel */ void lapdm_channel_set_l1(struct lapdm_channel *lc, osmo_prim_cb cb, void *ctx) { lc->lapdm_dcch.l1_prim_cb = cb; @@ -2482,6 +2509,7 @@ void lapdm_channel_set_l1(struct lapdm_channel *lc, osmo_prim_cb cb, void *ctx) lc->lapdm_acch.l1_ctx = ctx; } +/*! \brief Set the L3 callback and context of a LAPDm channel */ void lapdm_channel_set_l3(struct lapdm_channel *lc, lapdm_cb_t cb, void *ctx) { lc->lapdm_dcch.l3_cb = cb; @@ -2490,6 +2518,7 @@ void lapdm_channel_set_l3(struct lapdm_channel *lc, lapdm_cb_t cb, void *ctx) lc->lapdm_acch.l3_ctx = ctx; } +/*! \brief Reset an entire LAPDm entity and all its datalinks */ void lapdm_entity_reset(struct lapdm_entity *le) { struct lapdm_datalink *dl; @@ -2510,19 +2539,24 @@ void lapdm_entity_reset(struct lapdm_entity *le) } } +/*! \brief Reset a LAPDm channel with all its entities */ void lapdm_channel_reset(struct lapdm_channel *lc) { lapdm_entity_reset(&lc->lapdm_dcch); lapdm_entity_reset(&lc->lapdm_acch); } +/*! \brief Set the flags of a LAPDm entity */ void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags) { le->flags = flags; } +/*! \brief Set the flags of all LAPDm entities in a LAPDm channel */ void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags) { lapdm_entity_set_flags(&lc->lapdm_dcch, flags); lapdm_entity_set_flags(&lc->lapdm_acch, flags); } + +/*! }@ */ diff --git a/src/shared/libosmocore/src/gsm/rsl.c b/src/shared/libosmocore/src/gsm/rsl.c index c497ba95..db276a2a 100644 --- a/src/shared/libosmocore/src/gsm/rsl.c +++ b/src/shared/libosmocore/src/gsm/rsl.c @@ -28,9 +28,18 @@ #include <osmocom/gsm/tlv.h> #include <osmocom/gsm/rsl.h> +/*! \addtogroup rsl + * @{ + */ + +/*! \file rsl.c */ + +/*! \brief Size for RSL \ref msgb_alloc */ #define RSL_ALLOC_SIZE 200 +/*! \brief Headroom size for RSL \ref msgb_alloc */ #define RSL_ALLOC_HEADROOM 56 +/*! \brief Initialize a RSL RLL header */ void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type) { dh->c.msg_discr = ABIS_RSL_MDISC_RLL; @@ -39,6 +48,7 @@ void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type) dh->ie_link_id = RSL_IE_LINK_IDENT; } +/*! \brief Initialize a RSL Common Channel header */ void rsl_init_cchan_hdr(struct abis_rsl_cchan_hdr *ch, uint8_t msg_type) { ch->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN; @@ -46,6 +56,7 @@ void rsl_init_cchan_hdr(struct abis_rsl_cchan_hdr *ch, uint8_t msg_type) ch->ie_chan = RSL_IE_CHAN_NR; } +/* \brief TLV parser definition for RSL */ const struct tlv_definition rsl_att_tlvdef = { .def = { [RSL_IE_CHAN_NR] = { TLV_TYPE_TV }, @@ -126,7 +137,7 @@ const struct tlv_definition rsl_att_tlvdef = { }, }; -/* encode channel number as per Section 9.3.1 */ +/*! \brief Encode channel number as per Section 9.3.1 */ uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot) { uint8_t ret; @@ -153,6 +164,12 @@ uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot) return ret; } +/*! \brief Decode RSL channel number + * \param[in] chan_nr Channel Number + * \param[out] type Channel Type + * \param[out] subch Sub-channel Number + * \param[out] timeslot Timeslot + */ int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot) { *timeslot = chan_nr & 0x7; @@ -184,6 +201,7 @@ int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *tim return 0; } +/*! \brief Get human-readable string for RSL channel number */ const char *rsl_chan_nr_str(uint8_t chan_nr) { static char str[20]; @@ -245,6 +263,7 @@ static const struct value_string rsl_err_vals[] = { { 0, NULL } }; +/*! \brief Get human-readable name for RSL Error */ const char *rsl_err_name(uint8_t err) { return get_value_string(rsl_err_vals, err); @@ -321,11 +340,48 @@ static const struct value_string rsl_msgt_names[] = { }; +/*! \brief Get human-readable string for RSL Message Type */ const char *rsl_msg_name(uint8_t msg_type) { return get_value_string(rsl_msgt_names, msg_type); } +/*! \brief ip.access specific */ +static const struct value_string rsl_ipac_msgt_names[] = { + { RSL_MT_IPAC_PDCH_ACT, "IPAC_PDCH_ACT" }, + { RSL_MT_IPAC_PDCH_ACT_ACK, "IPAC_PDCH_ACT_ACK" }, + { RSL_MT_IPAC_PDCH_ACT_NACK, "IPAC_PDCH_ACT_NACK" }, + { RSL_MT_IPAC_PDCH_DEACT, "IPAC_PDCH_DEACT" }, + { RSL_MT_IPAC_PDCH_DEACT_ACK, "IPAC_PDCH_DEACT_ACK" }, + { RSL_MT_IPAC_PDCH_DEACT_NACK, "IPAC_PDCH_DEACT_NACK" }, + { RSL_MT_IPAC_CONNECT_MUX, "IPAC_CONNECT_MUX" }, + { RSL_MT_IPAC_CONNECT_MUX_ACK, "IPAC_CONNECT_MUX_ACK" }, + { RSL_MT_IPAC_CONNECT_MUX_NACK, "IPAC_CONNECT_MUX_NACK" }, + { RSL_MT_IPAC_BIND_MUX, "IPAC_BIND_MUX" }, + { RSL_MT_IPAC_BIND_MUX_ACK, "IPAC_BIND_MUX_ACK" }, + { RSL_MT_IPAC_BIND_MUX_NACK, "IPAC_BIND_MUX_NACK" }, + { RSL_MT_IPAC_DISC_MUX, "IPAC_DISC_MUX" }, + { RSL_MT_IPAC_DISC_MUX_ACK, "IPAC_DISC_MUX_ACK" }, + { RSL_MT_IPAC_DISC_MUX_NACK, "IPAC_DISC_MUX_NACK" }, + { RSL_MT_IPAC_CRCX, "IPAC_CRCX" }, + { RSL_MT_IPAC_CRCX_ACK, "IPAC_CRCX_ACK" }, + { RSL_MT_IPAC_CRCX_NACK, "IPAC_CRCX_NACK" }, + { RSL_MT_IPAC_MDCX, "IPAC_MDCX" }, + { RSL_MT_IPAC_MDCX_ACK, "IPAC_MDCX_ACK" }, + { RSL_MT_IPAC_MDCX_NACK, "IPAC_MDCX_NACK" }, + { RSL_MT_IPAC_DLCX_IND, "IPAC_DLCX_IND" }, + { RSL_MT_IPAC_DLCX, "IPAC_DLCX" }, + { RSL_MT_IPAC_DLCX_ACK, "IPAC_DLCX_ACK" }, + { RSL_MT_IPAC_DLCX_NACK, "IPAC_DLCX_NACK" }, + { 0, NULL } +}; + +/*! \brief Get human-readable name of ip.access RSL msg type */ +const char *rsl_ipac_msg_name(uint8_t msg_type) +{ + return get_value_string(rsl_ipac_msgt_names, msg_type); +} + static const struct value_string rsl_rlm_cause_strs[] = { { RLL_CAUSE_T200_EXPIRED, "Timer T200 expired (N200+1) times" }, { RLL_CAUSE_REEST_REQ, "Re-establishment request" }, @@ -344,6 +400,7 @@ static const struct value_string rsl_rlm_cause_strs[] = { { 0, NULL }, }; +/*! \brief Get human-readable string for RLM cause */ const char *rsl_rlm_cause_name(uint8_t err) { return get_value_string(rsl_rlm_cause_strs, err); @@ -387,7 +444,7 @@ int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf) } } -/* Push a RSL RLL header */ +/*! \brief Push a RSL RLL header onto an existing msgb */ void rsl_rll_push_hdr(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr, uint8_t link_id, int transparent) { @@ -404,7 +461,7 @@ void rsl_rll_push_hdr(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr, msg->l2h = (uint8_t *)rh; } -/* Push a RSL RLL header with L3_INFO IE */ +/*! \brief Push a RSL RLL header with L3_INFO IE */ void rsl_rll_push_l3(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr, uint8_t link_id, int transparent) { @@ -420,6 +477,7 @@ void rsl_rll_push_l3(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr, rsl_rll_push_hdr(msg, msg_type, chan_nr, link_id, transparent); } +/*! \brief Create msgb with RSL RLL header */ struct msgb *rsl_rll_simple(uint8_t msg_type, uint8_t chan_nr, uint8_t link_id, int transparent) { @@ -445,3 +503,5 @@ struct msgb *rsl_rll_simple(uint8_t msg_type, uint8_t chan_nr, return msg; } + +/*! }@ */ diff --git a/src/shared/libosmocore/src/gsm/tlv_parser.c b/src/shared/libosmocore/src/gsm/tlv_parser.c index 1e4c6b5f..c832d56f 100644 --- a/src/shared/libosmocore/src/gsm/tlv_parser.c +++ b/src/shared/libosmocore/src/gsm/tlv_parser.c @@ -3,8 +3,14 @@ #include <osmocom/core/utils.h> #include <osmocom/gsm/tlv.h> +/*! \addtogroup tlv + * @{ + */ +/*! \file tlv.c */ + struct tlv_definition tvlv_att_def; +/*! \brief Dump pasred TLV structure to stdout */ int tlv_dump(struct tlv_parsed *dec) { int i; @@ -17,14 +23,14 @@ int tlv_dump(struct tlv_parsed *dec) return 0; } -/* o_tag: output: tag found - * o_len: output: length of the data - * o_val: output: pointer to the data - * def: input: a structure defining the valid TLV tags / configurations - * buf: input: the input data buffer to be parsed - * buf_len: input: the length of the input data buffer - * - * Also, returns the number of bytes consumed by the TLV entry +/*! \brief Parse a single TLV encoded IE + * \param[out] o_tag the tag of the IE that was found + * \param[out] o_len length of the IE that was found + * \param[out] o_val pointer to the data of the IE that was found + * \param[in] def structure defining the valid TLV tags / configurations + * \param[in] buf the input data buffer to be parsed + * \param[in] buf_len length of the input data buffer + * \returns number of bytes consumed by the TLV entry / IE parsed */ int tlv_parse_one(uint8_t *o_tag, uint16_t *o_len, const uint8_t **o_val, const struct tlv_definition *def, @@ -101,12 +107,14 @@ int tlv_parse_one(uint8_t *o_tag, uint16_t *o_len, const uint8_t **o_val, return len; } -/* dec: output: a caller-allocated pointer to a struct tlv_parsed, - * def: input: a structure defining the valid TLV tags / configurations - * buf: input: the input data buffer to be parsed - * buf_len: input: the length of the input data buffer - * lv_tag: input: an initial LV tag at the start of the buffer - * lv_tag2: input: a second initial LV tag following lv_tag +/*! \brief Parse an entire buffer of TLV encoded Information Eleemnts + * \param[out] dec caller-allocated pointer to \ref tlv_parsed + * \param[in] def structure defining the valid TLV tags / configurations + * \param[in] buf the input data buffer to be parsed + * \param[in] buf_len length of the input data buffer + * \param[in] lv_tag an initial LV tag at the start of the buffer + * \param[in] lv_tag2 a second initial LV tag following the \a lv_tag + * \returns number of bytes consumed by the TLV entry / IE parsed */ int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def, const uint8_t *buf, int buf_len, uint8_t lv_tag, @@ -158,7 +166,7 @@ int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def, return num_parsed; } -/* take a master (src) tlvdev and fill up all empty slots in 'dst' */ +/*! \brief take a master (src) tlvdev and fill up all empty slots in 'dst' */ void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src) { int i; @@ -177,3 +185,5 @@ static __attribute__((constructor)) void on_dso_load_tlv(void) for (i = 0; i < ARRAY_SIZE(tvlv_att_def.def); i++) tvlv_att_def.def[i].type = TLV_TYPE_TvLV; } + +/*! }@ */ |