summaryrefslogtreecommitdiffstats
path: root/src/shared/libosmocore/src
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2011-09-02 22:21:13 +0200
committerSylvain Munaut <tnt@246tNt.com>2011-09-02 22:21:13 +0200
commit176f72a2edad961773a832f5499c16cc8b318441 (patch)
tree921da4dfcf3bb704511a383bce7910e1675de9f5 /src/shared/libosmocore/src
parentd7410b752fc36e811c500f10718f0b73f2aa60f5 (diff)
parentfe28dedd4c25b5f0f3df39d5e33ce3639574406c (diff)
Merge commit 'fe28dedd4c25b5f0f3df39d5e33ce3639574406c'
Diffstat (limited to 'src/shared/libosmocore/src')
-rw-r--r--src/shared/libosmocore/src/Makefile.am4
-rw-r--r--src/shared/libosmocore/src/application.c52
-rw-r--r--src/shared/libosmocore/src/backtrace.c10
-rw-r--r--src/shared/libosmocore/src/bits.c102
-rw-r--r--src/shared/libosmocore/src/bitvec.c53
-rw-r--r--src/shared/libosmocore/src/conv.c33
-rw-r--r--src/shared/libosmocore/src/gsm/abis_nm.c33
-rw-r--r--src/shared/libosmocore/src/gsm/gsm48_ie.c168
-rw-r--r--src/shared/libosmocore/src/gsm/gsm_utils.c40
-rw-r--r--src/shared/libosmocore/src/gsm/lapdm.c42
-rw-r--r--src/shared/libosmocore/src/gsm/rsl.c66
-rw-r--r--src/shared/libosmocore/src/gsm/tlv_parser.c40
-rw-r--r--src/shared/libosmocore/src/gsmtap_util.c57
-rw-r--r--src/shared/libosmocore/src/logging.c98
-rw-r--r--src/shared/libosmocore/src/logging_syslog.c14
-rw-r--r--src/shared/libosmocore/src/msgb.c51
-rw-r--r--src/shared/libosmocore/src/panic.c8
-rw-r--r--src/shared/libosmocore/src/rate_ctr.c19
-rw-r--r--src/shared/libosmocore/src/select.c19
-rw-r--r--src/shared/libosmocore/src/serial.c209
-rw-r--r--src/shared/libosmocore/src/signal.c24
-rw-r--r--src/shared/libosmocore/src/socket.c49
-rw-r--r--src/shared/libosmocore/src/timer.c36
-rw-r--r--src/shared/libosmocore/src/utils.c51
-rw-r--r--src/shared/libosmocore/src/vty/command.c30
-rw-r--r--src/shared/libosmocore/src/vty/telnet_interface.c15
-rw-r--r--src/shared/libosmocore/src/vty/utils.c13
-rw-r--r--src/shared/libosmocore/src/vty/vty.c83
-rw-r--r--src/shared/libosmocore/src/write_queue.c28
29 files changed, 1293 insertions, 154 deletions
diff --git a/src/shared/libosmocore/src/Makefile.am b/src/shared/libosmocore/src/Makefile.am
index bbe6286d..739095c8 100644
--- a/src/shared/libosmocore/src/Makefile.am
+++ b/src/shared/libosmocore/src/Makefile.am
@@ -30,3 +30,7 @@ endif
if ENABLE_MSGFILE
libosmocore_la_SOURCES += msgfile.c
endif
+
+if ENABLE_SERIAL
+libosmocore_la_SOURCES += serial.c
+endif
diff --git a/src/shared/libosmocore/src/application.c b/src/shared/libosmocore/src/application.c
index b7e943d7..e0d989e5 100644
--- a/src/shared/libosmocore/src/application.c
+++ b/src/shared/libosmocore/src/application.c
@@ -21,6 +21,45 @@
*
*/
+/*! \file application.c
+ * \brief Routines for helping with the osmocom application setup.
+ */
+
+/*! \mainpage libosmocore Documentation
+ * \section sec_intro Introduction
+ * This library is a collection of common code used in various
+ * sub-projects inside the Osmocom family of projects. It includes a
+ * logging framework, select() loop abstraction, timers with callbacks,
+ * bit vectors, bit packing/unpacking, convolutional decoding, GSMTAP, a
+ * generic plugin interface, statistics counters, memory allocator,
+ * socket abstraction, message buffers, etc.
+ * \n\n
+ * Please note that C language projects inside Osmocom are typically
+ * single-threaded event-loop state machine designs. As such,
+ * routines in libosmocore 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 libosmocore 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 <osmocom/core/application.h>
#include <osmocom/core/logging.h>
@@ -33,6 +72,7 @@
struct log_target *osmo_stderr_target;
+/*! \brief Ignore \ref SIGPIPE, \ref SIGALRM, \ref SIGHUP and \ref SIGIO */
void osmo_init_ignore_signals(void)
{
/* Signals that by default would terminate */
@@ -42,6 +82,13 @@ void osmo_init_ignore_signals(void)
signal(SIGIO, SIG_IGN);
}
+/*! \brief Initialize the osmocom logging framework
+ * \param[in] log_info Array of available logging sub-systems
+ * \returns 0 on success, -1 in case of error
+ *
+ * This function initializes the osmocom logging systems. It also
+ * creates the default (stderr) logging target.
+ */
int osmo_init_logging(const struct log_info *log_info)
{
log_init(log_info, NULL);
@@ -54,6 +101,11 @@ int osmo_init_logging(const struct log_info *log_info)
return 0;
}
+/*! \brief Turn the current process into a background daemon
+ *
+ * This function will fork the process, exit the parent and set umask,
+ * create a new session, close stdin/stdout/stderr and chdir to /tmp
+ */
int osmo_daemonize(void)
{
int rc;
diff --git a/src/shared/libosmocore/src/backtrace.c b/src/shared/libosmocore/src/backtrace.c
index dfe03059..189a3cec 100644
--- a/src/shared/libosmocore/src/backtrace.c
+++ b/src/shared/libosmocore/src/backtrace.c
@@ -22,6 +22,10 @@
*
*/
+/*! \file backtrace.c
+ * \brief Routines realted to generating call back traces
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <osmocom/core/utils.h>
@@ -29,6 +33,12 @@
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
+
+/*! \brief Generate and print a call back-trace
+ *
+ * This function will generate a function call back-trace of the
+ * current process and print it to stdout
+ */
void osmo_generate_backtrace(void)
{
int i, nptrs;
diff --git a/src/shared/libosmocore/src/bits.c b/src/shared/libosmocore/src/bits.c
index ff5d176c..9eb2d690 100644
--- a/src/shared/libosmocore/src/bits.c
+++ b/src/shared/libosmocore/src/bits.c
@@ -3,7 +3,20 @@
#include <osmocom/core/bits.h>
-/* convert unpacked bits to packed bits, return length in bytes */
+/*! \addtogroup bits
+ * @{
+ */
+
+/*! \file bits.c
+ * \brief Osmocom bit level support code
+ */
+
+
+/*! \brief convert unpacked bits to packed bits, return length in bytes
+ * \param[out] out output buffer of packed bits
+ * \param[in] in input buffer of unpacked bits
+ * \param[in] num_bits number of bits
+ */
int osmo_ubit2pbit(pbit_t *out, const ubit_t *in, unsigned int num_bits)
{
unsigned int i;
@@ -27,7 +40,11 @@ int osmo_ubit2pbit(pbit_t *out, const ubit_t *in, unsigned int num_bits)
return outptr - out;
}
-/* convert packed bits to unpacked bits, return length in bytes */
+/*! \brief convert packed bits to unpacked bits, return length in bytes
+ * \param[out] out output buffer of unpacked bits
+ * \param[in] in input buffer of packed bits
+ * \param[in] num_bits number of bits
+ */
int osmo_pbit2ubit(ubit_t *out, const pbit_t *in, unsigned int num_bits)
{
unsigned int i;
@@ -64,8 +81,15 @@ int osmo_pbit2ubit(ubit_t *out, const pbit_t *in, unsigned int num_bits)
return cur - out;
}
-/* convert unpacked bits to packed bits (extended options but slower),
- * return length in bytes (max written ofs of output buffer + 1) */
+/*! \brief convert unpacked bits to packed bits (extended options)
+ * \param[out] out output buffer of packed bits
+ * \param[in] out_ofs offset into output buffer
+ * \param[in] in input buffer of unpacked bits
+ * \param[in] in_ofs offset into input buffer
+ * \param[in] num_bits number of bits
+ * \param[in] lsb_mode Encode bits in LSB orde instead of MSB
+ * \returns length in bytes (max written offset of output buffer + 1)
+ */
int osmo_ubit2pbit_ext(pbit_t *out, unsigned int out_ofs,
const ubit_t *in, unsigned int in_ofs,
unsigned int num_bits, int lsb_mode)
@@ -82,8 +106,15 @@ int osmo_ubit2pbit_ext(pbit_t *out, unsigned int out_ofs,
return ((out_ofs + num_bits - 1) >> 3) + 1;
}
-/* convert packed bits to unpacked bits (extended options but slower),
- * return length in bytes (max written ofs of output buffer + 1) */
+/*! \brief convert packed bits to unpacked bits (extended options)
+ * \param[out] out output buffer of unpacked bits
+ * \param[in] out_ofs offset into output buffer
+ * \param[in] in input buffer of packed bits
+ * \param[in] in_ofs offset into input buffer
+ * \param[in] num_bits number of bits
+ * \param[in] lsb_mode Encode bits in LSB orde instead of MSB
+ * \returns length in bytes (max written offset of output buffer + 1)
+ */
int osmo_pbit2ubit_ext(ubit_t *out, unsigned int out_ofs,
const pbit_t *in, unsigned int in_ofs,
unsigned int num_bits, int lsb_mode)
@@ -96,3 +127,62 @@ int osmo_pbit2ubit_ext(ubit_t *out, unsigned int out_ofs,
}
return out_ofs + num_bits;
}
+
+/* generalized bit reversal function, Chapter 7 "Hackers Delight" */
+uint32_t osmo_bit_reversal(uint32_t x, enum osmo_br_mode k)
+{
+ if (k & 1) x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1;
+ if (k & 2) x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2;
+ if (k & 4) x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4;
+ if (k & 8) x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8;
+ if (k & 16) x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;
+
+ return x;
+}
+
+/* generalized bit reversal function, Chapter 7 "Hackers Delight" */
+uint32_t osmo_revbytebits_32(uint32_t x)
+{
+ x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1;
+ x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2;
+ x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4;
+
+ return x;
+}
+
+uint32_t osmo_revbytebits_8(uint8_t x)
+{
+ x = (x & 0x55) << 1 | (x & 0xAA) >> 1;
+ x = (x & 0x33) << 2 | (x & 0xCC) >> 2;
+ x = (x & 0x0F) << 4 | (x & 0xF0) >> 4;
+
+ return x;
+}
+
+void osmo_revbytebits_buf(uint8_t *buf, int len)
+{
+ unsigned int i;
+ unsigned int unaligned_cnt;
+ int len_remain = len;
+
+ unaligned_cnt = ((unsigned long)buf & 3);
+ for (i = 0; i < unaligned_cnt; i++) {
+ buf[i] = osmo_revbytebits_8(buf[i]);
+ len_remain--;
+ if (len_remain <= 0)
+ return;
+ }
+
+ for (i = unaligned_cnt; i < len; i += 4) {
+ uint32_t *cur = (uint32_t *) (buf + i);
+ *cur = osmo_revbytebits_32(*cur);
+ len_remain -= 4;
+ }
+
+ for (i = len - len_remain; i < len; i++) {
+ buf[i] = osmo_revbytebits_8(buf[i]);
+ len_remain--;
+ }
+}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/bitvec.c b/src/shared/libosmocore/src/bitvec.c
index 4fd38349..8a086b81 100644
--- a/src/shared/libosmocore/src/bitvec.c
+++ b/src/shared/libosmocore/src/bitvec.c
@@ -20,6 +20,13 @@
*
*/
+/*! \addtogroup bitvec
+ * @{
+ */
+
+/*! \file bitvec.c
+ * \brief Osmocom bit vector abstraction
+ */
#include <errno.h>
#include <stdint.h>
@@ -59,7 +66,11 @@ static uint8_t bitval2mask(enum bit_value bit, uint8_t bitnum)
return bitval;
}
-/* check if the bit is 0 or 1 for a given position inside a bitvec */
+/*! \brief check if the bit is 0 or 1 for a given position inside a bitvec
+ * \param[in] bv the bit vector on which to check
+ * \param[in] bitnr the bit number inside the bit vector to check
+ * \returns
+ */
enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr)
{
unsigned int bytenum = bytenum_from_bitnum(bitnr);
@@ -77,7 +88,10 @@ enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr)
return ZERO;
}
-/* check if the bit is L or H for a given position inside a bitvec */
+/*! \brief check if the bit is L or H for a given position inside a bitvec
+ * \param[in] bv the bit vector on which to check
+ * \param[in] bitnr the bit number inside the bit vector to check
+ */
enum bit_value bitvec_get_bit_pos_high(const struct bitvec *bv,
unsigned int bitnr)
{
@@ -96,7 +110,11 @@ enum bit_value bitvec_get_bit_pos_high(const struct bitvec *bv,
return L;
}
-/* get the Nth set bit inside the bit vector */
+/*! \brief get the Nth set bit inside the bit vector
+ * \param[in] bv the bit vector to use
+ * \param[in] n the bit number to get
+ * \returns the bit number (offset) of the Nth set bit in \a bv
+ */
unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n)
{
unsigned int i, k = 0;
@@ -112,7 +130,11 @@ unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n)
return 0;
}
-/* set the bit at a given position inside a bitvec */
+/*! \brief set a bit at given position in a bit vector
+ * \param[in] bv bit vector on which to operate
+ * \param[in] bitnum number of bit to be set
+ * \param[in] bit value to which the bit is to be set
+ */
int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr,
enum bit_value bit)
{
@@ -134,7 +156,10 @@ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr,
return 0;
}
-/* set the next bit inside a bitvec */
+/*! \brief set the next bit inside a bitvec
+ * \param[in] bv bit vector to be used
+ * \param[in] bit value of the bit to be set
+ */
int bitvec_set_bit(struct bitvec *bv, enum bit_value bit)
{
int rc;
@@ -146,7 +171,7 @@ int bitvec_set_bit(struct bitvec *bv, enum bit_value bit)
return rc;
}
-/* get the next bit (low/high) inside a bitvec */
+/*! \brief get the next bit (low/high) inside a bitvec */
int bitvec_get_bit_high(struct bitvec *bv)
{
int rc;
@@ -158,7 +183,11 @@ int bitvec_get_bit_high(struct bitvec *bv)
return rc;
}
-/* set multiple bits (based on array of bitvals) at current pos */
+/*! \brief set multiple bits (based on array of bitvals) at current pos
+ * \param[in] bv bit vector
+ * \param[in] bits array of \ref bit_value
+ * \param[in] count number of bits to set
+ */
int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count)
{
int i, rc;
@@ -172,7 +201,7 @@ int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count)
return 0;
}
-/* set multiple bits (based on numeric value) at current pos */
+/*! \brief set multiple bits (based on numeric value) at current pos */
int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits)
{
int i, rc;
@@ -189,7 +218,7 @@ int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits)
return 0;
}
-/* get multiple bits (based on numeric value) from current pos */
+/*! \brief get multiple bits (based on numeric value) from current pos */
int bitvec_get_uint(struct bitvec *bv, int num_bits)
{
int i;
@@ -207,7 +236,7 @@ int bitvec_get_uint(struct bitvec *bv, int num_bits)
return ui;
}
-/* pad all remaining bits up to num_bits */
+/*! \brief pad all remaining bits up to num_bits */
int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit)
{
unsigned int i;
@@ -218,7 +247,7 @@ int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit)
return 0;
}
-/* find first bit set in bit vector */
+/*! \brief find first bit set in bit vector */
int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n,
enum bit_value val)
{
@@ -231,3 +260,5 @@ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n,
return -1;
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/conv.c b/src/shared/libosmocore/src/conv.c
index 70bdffba..f47d75cd 100644
--- a/src/shared/libosmocore/src/conv.c
+++ b/src/shared/libosmocore/src/conv.c
@@ -22,6 +22,14 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+/*! \addtogroup conv
+ * @{
+ */
+
+/*! \file conv.c
+ * \file Osmocom convolutional encoder and decoder
+ */
+
#include <alloca.h>
#include <stdint.h>
#include <stdlib.h>
@@ -35,6 +43,10 @@
/* Encoding */
/* ------------------------------------------------------------------------ */
+/*! \brief Initialize a convolutional encoder
+ * \param[in,out] encoder Encoder state to initialize
+ * \param[in] code Description of convolutional code
+ */
void
osmo_conv_encode_init(struct osmo_conv_encoder *encoder,
const struct osmo_conv_code *code)
@@ -138,6 +150,15 @@ osmo_conv_encode_finish(struct osmo_conv_encoder *encoder,
return o_idx;
}
+/*! \brief All-in-one convolutional encoding function
+ * \param[in] code description of convolutional code to be used
+ * \param[in] input array of unpacked bits (uncoded)
+ * \param[out] output array of unpacked bits (encoded)
+ *
+ * This is an all-in-one function, taking care of
+ * \ref osmo_conv_init, \ref osmo_conv_encode_raw and
+ * \ref osmo_conv_encode_finish.
+ */
int
osmo_conv_encode(const struct osmo_conv_code *code,
const ubit_t *input, ubit_t *output)
@@ -476,6 +497,16 @@ osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
return min_ae;
}
+/*! \brief All-in-one convolutional decoding function
+ * \param[in] code description of convolutional code to be used
+ * \param[in] input array of soft bits (coded)
+ * \param[out] output array of unpacked bits (decoded)
+ *
+ * This is an all-in-one function, taking care of
+ * \ref osmo_conv_decode_init, \ref osmo_conv_decode_scan,
+ * \ref osmo_conv_decode_finish, \ref osmo_conv_decode_get_output and
+ * \ref osmo_conv_decode_deinit.
+ */
int
osmo_conv_decode(const struct osmo_conv_code *code,
const sbit_t *input, ubit_t *output)
@@ -494,3 +525,5 @@ osmo_conv_decode(const struct osmo_conv_code *code,
return rv;
}
+
+/*! }@ */
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;
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/gsmtap_util.c b/src/shared/libosmocore/src/gsmtap_util.c
index c8c26c62..0e4d61e5 100644
--- a/src/shared/libosmocore/src/gsmtap_util.c
+++ b/src/shared/libosmocore/src/gsmtap_util.c
@@ -42,6 +42,17 @@
#include <string.h>
#include <errno.h>
+/*! \addtogroup gsmtap
+ * @{
+ */
+/*! \file gsmtap_util.c */
+
+
+/*! \brief convert RSL channel number to GSMTAP channel type
+ * \param[in] rsl_cantype RSL channel type
+ * \param[in] link_id RSL link identifier
+ * \returns GSMTAP channel type
+ */
uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t link_id)
{
uint8_t ret = GSMTAP_CHANNEL_UNKNOWN;
@@ -77,7 +88,20 @@ uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t link_id)
return ret;
}
-/* receive a message from L1/L2 and put it in GSMTAP */
+/*! \brief create L1/L2 data and put it into GSMTAP
+ * \param[in] arfcn GSM ARFCN (Channel Number)
+ * \param[in] ts GSM time slot
+ * \param[in] chan_type Channel Type
+ * \param[in] ss Sub-slot
+ * \param[in] fn GSM Frame Number
+ * \param[in] signal_dbm Signal Strength (dBm)
+ * \param[in] snr Signal/Noise Ratio (SNR)
+ * \param[in] data Pointer to data buffer
+ * \param[in] len Length of \ref data
+ *
+ * This function will allocate a new msgb and fill it with a GSMTAP
+ * header containing the information
+ */
struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
uint8_t ss, uint32_t fn, int8_t signal_dbm,
uint8_t snr, const uint8_t *data, unsigned int len)
@@ -115,8 +139,15 @@ struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
#include <sys/socket.h>
#include <netinet/in.h>
-/* Open a GSMTAP source (sending) socket, conncet it to host/port and
- * return resulting fd */
+/*! \brief Create a new (sending) GSMTAP source socket
+ * \param[in] host host name or IP address in string format
+ * \param[in] port UDP port number in host byte order
+ *
+ * Opens a GSMTAP source (sending) socket, conncet it to host/port and
+ * return resulting fd. If \a host is NULL, the destination address
+ * will be localhost. If \a port is 0, the default \ref
+ * GSMTAP_UDP_PORT will be used.
+ * */
int gsmtap_source_init_fd(const char *host, uint16_t port)
{
if (port == 0)
@@ -128,6 +159,7 @@ int gsmtap_source_init_fd(const char *host, uint16_t port)
OSMO_SOCK_F_CONNECT);
}
+/*! \brief Add a local sink to an existing GSMTAP source and return fd */
int gsmtap_source_add_sink_fd(int gsmtap_fd)
{
struct sockaddr_storage ss;
@@ -148,6 +180,10 @@ int gsmtap_source_add_sink_fd(int gsmtap_fd)
return -ENODEV;
}
+/*! \brief Send a \ref msgb through a GSMTAP source
+ * \param[in] gti GSMTAP instance
+ * \param[in] msgb message buffer
+ */
int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg)
{
if (!gti)
@@ -172,7 +208,7 @@ int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg)
}
}
-/* receive a message from L1/L2 and put it in GSMTAP */
+/*! \brief receive a message from L1/L2 and put it in GSMTAP */
int gsmtap_send(struct gsmtap_inst *gti, uint16_t arfcn, uint8_t ts,
uint8_t chan_type, uint8_t ss, uint32_t fn,
int8_t signal_dbm, uint8_t snr, const uint8_t *data,
@@ -228,7 +264,7 @@ static int gsmtap_sink_fd_cb(struct osmo_fd *fd, unsigned int flags)
return 0;
}
-/* Add a local sink to an existing GSMTAP source instance */
+/*! \brief Add a local sink to an existing GSMTAP source instance */
int gsmtap_source_add_sink(struct gsmtap_inst *gti)
{
int fd;
@@ -251,7 +287,16 @@ int gsmtap_source_add_sink(struct gsmtap_inst *gti)
return fd;
}
-/* like gsmtap_init2() but integrated with libosmocore select.c */
+
+/*! \brief Open GSMTAP source socket, connect and register osmo_fd
+ * \param[in] host host name or IP address in string format
+ * \param[in] port UDP port number in host byte order
+ * \param[in] osmo_wq_mode Register \ref osmo_wqueue (1) or not (0)
+ *
+ * Open GSMTAP source (sending) socket, connect it to host/port,
+ * allocate 'struct gsmtap_inst' and optionally osmo_fd/osmo_wqueue
+ * registration. This means it is like \ref gsmtap_init2 but integrated
+ * with libosmocore \ref select */
struct gsmtap_inst *gsmtap_source_init(const char *host, uint16_t port,
int ofd_wq_mode)
{
diff --git a/src/shared/libosmocore/src/logging.c b/src/shared/libosmocore/src/logging.c
index 11d63ac9..9dd63e73 100644
--- a/src/shared/libosmocore/src/logging.c
+++ b/src/shared/libosmocore/src/logging.c
@@ -20,6 +20,12 @@
*
*/
+/* \addtogroup logging
+ * @{
+ */
+
+/* \file logging.c */
+
#include "../config.h"
#include <stdarg.h>
@@ -113,16 +119,22 @@ static int subsys_lib2index(int subsys)
return (subsys * -1) + (osmo_log_info->num_cat_user-1);
}
+/*! \brief Parse a human-readable log level into a numeric value */
int log_parse_level(const char *lvl)
{
return get_string_value(loglevel_strs, lvl);
}
+/*! \brief convert a numeric log level into human-readable string */
const char *log_level_str(unsigned int lvl)
{
return get_value_string(loglevel_strs, lvl);
}
+/*! \brief parse a human-readable log category into numeric form
+ * \param[in] category human-readable log category name
+ * \returns numeric category value, or -EINVAL otherwise
+ */
int log_parse_category(const char *category)
{
int i;
@@ -137,8 +149,10 @@ int log_parse_category(const char *category)
return -EINVAL;
}
-/*
- * Parse the category mask.
+/*! \brief parse the log category mask
+ * \param[in] target log target to be configured
+ * \param[in] _mask log category mask string
+ *
* The format can be this: category1:category2:category3
* or category1,2:category2,3:...
*/
@@ -157,6 +171,11 @@ void log_parse_category_mask(struct log_target* target, const char *_mask)
for (i = 0; i < osmo_log_info->num_cat; ++i) {
char* colon = strstr(category_token, ",");
int length = strlen(category_token);
+ int cat_length = strlen(osmo_log_info->cat[i].name);
+
+ /* Use longest length not to match subocurrences. */
+ if (cat_length > length)
+ length = cat_length;
if (!osmo_log_info->cat[i].name)
continue;
@@ -238,8 +257,9 @@ err:
target->output(target, level, buf);
}
-static void _logp(int subsys, int level, char *file, int line,
- int cont, const char *format, va_list ap)
+/*! \brief vararg version of logging function */
+void osmo_vlogp(int subsys, int level, char *file, int line,
+ int cont, const char *format, va_list ap)
{
struct log_target *tar;
@@ -294,7 +314,7 @@ void logp(int subsys, char *file, int line, int cont,
va_list ap;
va_start(ap, format);
- _logp(subsys, LOGL_DEBUG, file, line, cont, format, ap);
+ osmo_vlogp(subsys, LOGL_DEBUG, file, line, cont, format, ap);
va_end(ap);
}
@@ -303,25 +323,42 @@ void logp2(int subsys, unsigned int level, char *file, int line, int cont, const
va_list ap;
va_start(ap, format);
- _logp(subsys, level, file, line, cont, format, ap);
+ osmo_vlogp(subsys, level, file, line, cont, format, ap);
va_end(ap);
}
+/*! \brief Register a new log target with the logging core
+ * \param[in] target Log target to be registered
+ */
void log_add_target(struct log_target *target)
{
llist_add_tail(&target->entry, &osmo_log_target_list);
}
+/*! \brief Unregister a log target from the logging core
+ * \param[in] target Log target to be unregistered
+ */
void log_del_target(struct log_target *target)
{
llist_del(&target->entry);
}
+/*! \brief Reset (clear) the logging context */
void log_reset_context(void)
{
memset(&log_context, 0, sizeof(log_context));
}
+/*! \brief Set the logging context
+ * \param[in] ctx_nr logging context number
+ * \param[in] value value to which the context is to be set
+ *
+ * A logging context is something like the subscriber identity to which
+ * the currently processed message relates, or the BTS through which it
+ * was received. As soon as this data is known, it can be set using
+ * this function. The main use of context information is for logging
+ * filters.
+ */
int log_set_context(uint8_t ctx_nr, void *value)
{
if (ctx_nr > LOG_MAX_CTX)
@@ -332,6 +369,14 @@ int log_set_context(uint8_t ctx_nr, void *value)
return 0;
}
+/*! \brief Enable the \ref LOG_FILTER_ALL log filter
+ * \param[in] target Log target to be affected
+ * \param[in] all enable (1) or disable (0) the ALL filter
+ *
+ * When the \ref LOG_FILTER_ALL filter is enabled, all log messages will
+ * be printed. It acts as a wildcard. Setting it to \a 1 means there
+ * is no filtering.
+ */
void log_set_all_filter(struct log_target *target, int all)
{
if (all)
@@ -340,16 +385,28 @@ void log_set_all_filter(struct log_target *target, int all)
target->filter_map &= ~LOG_FILTER_ALL;
}
+/*! \brief Enable or disable the use of colored output
+ * \param[in] target Log target to be affected
+ * \param[in] use_color Use color (1) or don't use color (0)
+ */
void log_set_use_color(struct log_target *target, int use_color)
{
target->use_color = use_color;
}
+/*! \brief Enable or disable printing of timestamps while logging
+ * \param[in] target Log target to be affected
+ * \param[in] print_timestamp Enable (1) or disable (0) timestamps
+ */
void log_set_print_timestamp(struct log_target *target, int print_timestamp)
{
target->print_timestamp = print_timestamp;
}
+/*! \brief Set the global log level for a given log target
+ * \param[in] target Log target to be affected
+ * \param[in] log_level New global log level
+ */
void log_set_log_level(struct log_target *target, int log_level)
{
target->loglevel = log_level;
@@ -371,6 +428,7 @@ static void _file_output(struct log_target *target, unsigned int level,
fflush(target->tgt_file.out);
}
+/*! \brief Create a new log target skeleton */
struct log_target *log_target_create(void)
{
struct log_target *target;
@@ -406,6 +464,7 @@ struct log_target *log_target_create(void)
return target;
}
+/*! \brief Create the STDERR log target */
struct log_target *log_target_create_stderr(void)
{
/* since C89/C99 says stderr is a macro, we can safely do this! */
@@ -425,6 +484,10 @@ struct log_target *log_target_create_stderr(void)
#endif /* stderr */
}
+/*! \brief Create a new file-based log target
+ * \param[in] fname File name of the new log file
+ * \returns Log target in case of success, NULL otherwise
+ */
struct log_target *log_target_create_file(const char *fname)
{
struct log_target *target;
@@ -445,6 +508,11 @@ struct log_target *log_target_create_file(const char *fname)
return target;
}
+/*! \brief Find a registered log target
+ * \param[in] type Log target type
+ * \param[in] fname File name
+ * \returns Log target (if found), NULL otherwise
+ */
struct log_target *log_target_find(int type, const char *fname)
{
struct log_target *tgt;
@@ -461,6 +529,7 @@ struct log_target *log_target_find(int type, const char *fname)
return NULL;
}
+/*! \brief Unregister, close and delete a log target */
void log_target_destroy(struct log_target *target)
{
@@ -482,7 +551,7 @@ void log_target_destroy(struct log_target *target)
talloc_free(target);
}
-/* close and re-open a log file (for log file rotation) */
+/*! \brief close and re-open a log file (for log file rotation) */
int log_target_file_reopen(struct log_target *target)
{
fclose(target->tgt_file.out);
@@ -496,7 +565,9 @@ int log_target_file_reopen(struct log_target *target)
return 0;
}
-/* This generates the logging command string for VTY. */
+/*! \brief Generates the logging command string for VTY
+ * \param[in] unused_info Deprecated parameter, no longer used!
+ */
const char *log_vty_command_string(const struct log_info *unused_info)
{
struct log_info *info = osmo_log_info;
@@ -571,7 +642,9 @@ err:
return str;
}
-/* This generates the logging command description for VTY. */
+/*! \brief Generates the logging command description for VTY
+ * \param[in] unused_info Deprecated parameter, no longer used!
+ */
const char *log_vty_command_description(const struct log_info *unused_info)
{
struct log_info *info = osmo_log_info;
@@ -629,6 +702,11 @@ err:
return str;
}
+/*! \brief Initialize the Osmocom logging core
+ * \param[in] inf Information regarding logging categories
+ * \param[in] ctx \ref talloc context for logging allocations
+ * \returns 0 in case of success, negative in case of error
+ */
int log_init(const struct log_info *inf, void *ctx)
{
int i;
@@ -669,3 +747,5 @@ int log_init(const struct log_info *inf, void *ctx)
return 0;
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/logging_syslog.c b/src/shared/libosmocore/src/logging_syslog.c
index 4f043b1d..b07b7fe6 100644
--- a/src/shared/libosmocore/src/logging_syslog.c
+++ b/src/shared/libosmocore/src/logging_syslog.c
@@ -19,6 +19,12 @@
*
*/
+/*! \addtogroup logging
+ * @{
+ */
+
+/*! \file logging_syslog.c */
+
#include "../config.h"
#ifdef HAVE_SYSLOG_H
@@ -57,6 +63,12 @@ static void _syslog_output(struct log_target *target,
syslog(logp2syslog_level(level), "%s", log);
}
+/*! \brief Create a new logging target for syslog logging
+ * \param[in] ident syslog string identifier
+ * \param[in] option syslog options
+ * \param[in] facility syslog facility
+ * \returns Log target in case of success, NULL in case of error
+ */
struct log_target *log_target_create_syslog(const char *ident, int option,
int facility)
{
@@ -76,3 +88,5 @@ struct log_target *log_target_create_syslog(const char *ident, int option,
}
#endif /* HAVE_SYSLOG_H */
+
+/* }@ */
diff --git a/src/shared/libosmocore/src/msgb.c b/src/shared/libosmocore/src/msgb.c
index f9841ed1..a403580b 100644
--- a/src/shared/libosmocore/src/msgb.c
+++ b/src/shared/libosmocore/src/msgb.c
@@ -18,6 +18,12 @@
*
*/
+/*! \addtogroup msgb
+ * @{
+ */
+
+/*! \file msgb.c
+ */
#include <unistd.h>
#include <string.h>
@@ -30,6 +36,14 @@
void *tall_msgb_ctx;
+/*! \brief Allocate a new message buffer
+ * \param[in] size Length in octets, including headroom
+ * \param[in] name Human-readable name to be associated with msgb
+ *
+ * This function allocates a 'struct msgb' as well as the underlying
+ * memory buffer for the actual message data (size specified by \a size)
+ * using the talloc memory context previously set by \ref msgb_set_talloc_ctx
+ */
struct msgb *msgb_alloc(uint16_t size, const char *name)
{
struct msgb *msg;
@@ -50,16 +64,33 @@ struct msgb *msgb_alloc(uint16_t size, const char *name)
return msg;
}
+/*! \brief Release given message buffer
+ * \param[in] m Message buffer to be free'd
+ */
void msgb_free(struct msgb *m)
{
talloc_free(m);
}
+/*! \brief Enqueue message buffer to tail of a queue
+ * \param[in] queue linked list header of queue
+ * \param[in] msgb message buffer to be added to the queue
+ *
+ * The function will append the specified message buffer \a msg to the
+ * queue implemented by \ref llist_head \a queue
+ */
void msgb_enqueue(struct llist_head *queue, struct msgb *msg)
{
llist_add_tail(&msg->list, queue);
}
+/*! \brief Dequeue message buffer from head of queue
+ * \param[in] queue linked list header of queue
+ * \returns message buffer (if any) or NULL if queue empty
+ *
+ * The function will remove the first message buffer from the queue
+ * implemented by 'ref llist_head \a queue.
+ */
struct msgb *msgb_dequeue(struct llist_head *queue)
{
struct llist_head *lh;
@@ -73,6 +104,13 @@ struct msgb *msgb_dequeue(struct llist_head *queue)
return llist_entry(lh, struct msgb, list);
}
+/*! \brief Re-set all message buffer pointers
+ * \param[in] m message buffer that is to be resetted
+ *
+ * This will re-set the various internal pointers into the underlying
+ * message buffer, i.e. remvoe all headroom and treat the msgb as
+ * completely empty. It also initializes the control buffer to zero.
+ */
void msgb_reset(struct msgb *msg)
{
msg->len = 0;
@@ -89,17 +127,30 @@ void msgb_reset(struct msgb *msg)
memset(&msg->cb, 0, sizeof(msg->cb));
}
+/*! \brief get pointer to data section of message buffer
+ * \param[in] msg message buffer
+ * \returns pointer to data section of message buffer
+ */
uint8_t *msgb_data(const struct msgb *msg)
{
return msg->data;
}
+/*! \brief get length of message buffer
+ * \param[in] msg message buffer
+ * \returns length of data section in message buffer
+ */
uint16_t msgb_length(const struct msgb *msg)
{
return msg->len;
}
+/*! \brief Set the talloc context for \ref msgb_alloc
+ * \param[in] ctx talloc context to be used as root for msgb allocations
+ */
void msgb_set_talloc_ctx(void *ctx)
{
tall_msgb_ctx = ctx;
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/panic.c b/src/shared/libosmocore/src/panic.c
index d4452264..be644ff1 100644
--- a/src/shared/libosmocore/src/panic.c
+++ b/src/shared/libosmocore/src/panic.c
@@ -20,6 +20,12 @@
*
*/
+/*! \addtogroup utils
+ * @{
+ */
+
+/*! \file panic.c */
+
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/core/panic.h>
#include <osmocom/core/backtrace.h>
@@ -52,6 +58,7 @@ static void osmo_panic_default(const char *fmt, va_list args)
#endif
+/*! \brief Terminate the current program with a panic */
void osmo_panic(const char *fmt, ...)
{
va_list args;
@@ -67,6 +74,7 @@ void osmo_panic(const char *fmt, ...)
}
+/*! \brief Set the panic handler */
void osmo_set_panic_handler(osmo_panic_handler_t h)
{
osmo_panic_handler = h;
diff --git a/src/shared/libosmocore/src/rate_ctr.c b/src/shared/libosmocore/src/rate_ctr.c
index 6d771a44..24166b84 100644
--- a/src/shared/libosmocore/src/rate_ctr.c
+++ b/src/shared/libosmocore/src/rate_ctr.c
@@ -20,6 +20,13 @@
*
*/
+/*! \addtogroup rate_ctr
+ * @{
+ */
+
+/*! \file rate_ctr.c */
+
+
#include <stdint.h>
#include <string.h>
@@ -33,6 +40,11 @@ static LLIST_HEAD(rate_ctr_groups);
static void *tall_rate_ctr_ctx;
+/*! \brief Allocate a new group of counters according to description
+ * \param[in] ctx \ref talloc context
+ * \param[in] desc Rate counter group description
+ * \param[in] idx Index of new counter group
+ */
struct rate_ctr_group *rate_ctr_group_alloc(void *ctx,
const struct rate_ctr_group_desc *desc,
unsigned int idx)
@@ -58,12 +70,14 @@ struct rate_ctr_group *rate_ctr_group_alloc(void *ctx,
return group;
}
+/*! \brief Free the memory for the specified group of counters */
void rate_ctr_group_free(struct rate_ctr_group *grp)
{
llist_del(&grp->list);
talloc_free(grp);
}
+/*! \brief Add a number to the counter */
void rate_ctr_add(struct rate_ctr *ctr, int inc)
{
ctr->current += inc;
@@ -117,6 +131,7 @@ static void rate_ctr_timer_cb(void *data)
osmo_timer_schedule(&rate_ctr_timer, 1, 0);
}
+/*! \brief Initialize the counter module */
int rate_ctr_init(void *tall_ctx)
{
tall_rate_ctr_ctx = tall_ctx;
@@ -126,6 +141,7 @@ int rate_ctr_init(void *tall_ctx)
return 0;
}
+/*! \brief Search for counter group based on group name and index */
struct rate_ctr_group *rate_ctr_get_group_by_name_idx(const char *name, const unsigned int idx)
{
struct rate_ctr_group *ctrg;
@@ -142,6 +158,7 @@ struct rate_ctr_group *rate_ctr_get_group_by_name_idx(const char *name, const un
return NULL;
}
+/*! \brief Search for counter group based on group name */
const struct rate_ctr *rate_ctr_get_by_name(const struct rate_ctr_group *ctrg, const char *name)
{
int i;
@@ -159,3 +176,5 @@ const struct rate_ctr *rate_ctr_get_by_name(const struct rate_ctr_group *ctrg, c
}
return NULL;
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/select.c b/src/shared/libosmocore/src/select.c
index 4b002ae5..c0705d31 100644
--- a/src/shared/libosmocore/src/select.c
+++ b/src/shared/libosmocore/src/select.c
@@ -30,10 +30,21 @@
#ifdef HAVE_SYS_SELECT_H
+/*! \addtogroup select
+ * @{
+ */
+
+/*! \file select.c
+ * \brief select loop abstraction
+ */
+
static int maxfd = 0;
static LLIST_HEAD(osmo_fds);
static int unregistered_count;
+/*! \brief Register a new file descriptor with select loop abstraction
+ * \param[in] fd osmocom file descriptor to be registered
+ */
int osmo_fd_register(struct osmo_fd *fd)
{
int flags;
@@ -75,12 +86,18 @@ int osmo_fd_register(struct osmo_fd *fd)
return 0;
}
+/*! \brief Unregister a file descriptor from select loop abstraction
+ * \param[in] fd osmocom file descriptor to be unregistered
+ */
void osmo_fd_unregister(struct osmo_fd *fd)
{
unregistered_count++;
llist_del(&fd->list);
}
+/*! \brief select main loop integration
+ * \param[in] polling should we pollonly (1) or block on select (0)
+ */
int osmo_select_main(int polling)
{
struct osmo_fd *ufd, *tmp;
@@ -150,4 +167,6 @@ restart:
return work;
}
+/*! }@ */
+
#endif /* _HAVE_SYS_SELECT_H */
diff --git a/src/shared/libosmocore/src/serial.c b/src/shared/libosmocore/src/serial.c
new file mode 100644
index 00000000..26cf59d7
--- /dev/null
+++ b/src/shared/libosmocore/src/serial.c
@@ -0,0 +1,209 @@
+/*
+ * serial.c
+ *
+ * Utility functions to deal with serial ports
+ *
+ * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it 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.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*! \addtogroup serial
+ * @{
+ */
+
+/*! \file serial.c
+ * \file Osmocom serial port helpers
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <linux/serial.h>
+
+
+#include <osmocom/core/serial.h>
+
+
+#if 0
+# define dbg_perror(x) perror(x)
+#else
+# define dbg_perror(x) do { } while (0)
+#endif
+
+/*! \brief Open serial device and does base init
+ * \param[in] dev Path to the device node to open
+ * \param[in] baudrate Baudrate constant (speed_t: B9600, B...)
+ * \returns >=0 file descriptor in case of success or negative errno.
+ */
+int
+osmo_serial_init(const char *dev, speed_t baudrate)
+{
+ int rc, fd=0, v24;
+ struct termios tio;
+
+ /* Open device */
+ fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
+ if (fd < 0) {
+ dbg_perror("open");
+ return -errno;
+ }
+
+ /* Configure serial interface */
+ rc = tcgetattr(fd, &tio);
+ if (rc < 0) {
+ dbg_perror("tcgetattr()");
+ rc = -errno;
+ goto error;
+ }
+
+ cfsetispeed(&tio, baudrate);
+ cfsetospeed(&tio, baudrate);
+
+ tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
+ tio.c_cflag |= (CREAD | CLOCAL | CS8);
+ tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+ tio.c_iflag |= (INPCK | ISTRIP);
+ tio.c_iflag &= ~(ISTRIP | IXON | IXOFF | IGNBRK | INLCR | ICRNL | IGNCR);
+ tio.c_oflag &= ~(OPOST | ONLCR);
+
+ rc = tcsetattr(fd, TCSANOW, &tio);
+ if (rc < 0) {
+ dbg_perror("tcsetattr()");
+ rc = -errno;
+ goto error;
+ }
+
+ /* Set ready to read/write */
+ v24 = TIOCM_DTR | TIOCM_RTS;
+ rc = ioctl(fd, TIOCMBIS, &v24);
+ if (rc < 0) {
+ dbg_perror("ioctl(TIOCMBIS)");
+ rc = -errno;
+ goto error;
+ }
+
+ return fd;
+
+error:
+ if (fd)
+ close(fd);
+ return rc;
+}
+
+static int
+_osmo_serial_set_baudrate(int fd, speed_t baudrate)
+{
+ int rc;
+ struct termios tio;
+
+ rc = tcgetattr(fd, &tio);
+ if (rc < 0) {
+ dbg_perror("tcgetattr()");
+ return -errno;
+ }
+ cfsetispeed(&tio, baudrate);
+ cfsetospeed(&tio, baudrate);
+
+ rc = tcsetattr(fd, TCSANOW, &tio);
+ if (rc < 0) {
+ dbg_perror("tcgetattr()");
+ return -errno;
+ }
+
+ return 0;
+}
+
+/*! \brief Change current baudrate
+ * \param[in] fd File descriptor of the open device
+ * \param[in] baudrate Baudrate constant (speed_t: B9600, B...)
+ * \returns 0 for success or negative errno.
+ */
+int
+osmo_serial_set_baudrate(int fd, speed_t baudrate)
+{
+ osmo_serial_clear_custom_baudrate(fd);
+ return _osmo_serial_set_baudrate(fd, baudrate);
+}
+
+/*! \brief Change current baudrate to a custom one using OS specific method
+ * \param[in] fd File descriptor of the open device
+ * \param[in] baudrate Baudrate as integer
+ * \returns 0 for success or negative errno.
+ *
+ * This function might not work on all OS or with all type of serial adapters
+ */
+int
+osmo_serial_set_custom_baudrate(int fd, int baudrate)
+{
+ int rc;
+ struct serial_struct ser_info;
+
+ rc = ioctl(fd, TIOCGSERIAL, &ser_info);
+ if (rc < 0) {
+ dbg_perror("ioctl(TIOCGSERIAL)");
+ return -errno;
+ }
+
+ ser_info.flags = ASYNC_SPD_CUST | ASYNC_LOW_LATENCY;
+ ser_info.custom_divisor = ser_info.baud_base / baudrate;
+
+ rc = ioctl(fd, TIOCSSERIAL, &ser_info);
+ if (rc < 0) {
+ dbg_perror("ioctl(TIOCSSERIAL)");
+ return -errno;
+ }
+
+ return _osmo_serial_set_baudrate(fd, B38400); /* 38400 is a kind of magic ... */
+}
+
+/*! \brief Clear any custom baudrate
+ * \param[in] fd File descriptor of the open device
+ * \returns 0 for success or negative errno.
+ *
+ * This function might not work on all OS or with all type of serial adapters
+ */
+int
+osmo_serial_clear_custom_baudrate(int fd)
+{
+ int rc;
+ struct serial_struct ser_info;
+
+ rc = ioctl(fd, TIOCGSERIAL, &ser_info);
+ if (rc < 0) {
+ dbg_perror("ioctl(TIOCGSERIAL)");
+ return -errno;
+ }
+
+ ser_info.flags = ASYNC_LOW_LATENCY;
+ ser_info.custom_divisor = 0;
+
+ rc = ioctl(fd, TIOCSSERIAL, &ser_info);
+ if (rc < 0) {
+ dbg_perror("ioctl(TIOCSSERIAL)");
+ return -errno;
+ }
+
+ return 0;
+}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/signal.c b/src/shared/libosmocore/src/signal.c
index bc339bb9..7ddc2e04 100644
--- a/src/shared/libosmocore/src/signal.c
+++ b/src/shared/libosmocore/src/signal.c
@@ -25,6 +25,12 @@
#include <string.h>
#include <errno.h>
+/*! \addtogroup signal
+ * @{
+ */
+/*! \file signal.c */
+
+
void *tall_sigh_ctx;
static LLIST_HEAD(signal_handler_list);
@@ -36,6 +42,11 @@ struct signal_handler {
};
+/*! \brief Register a new signal handler
+ * \param[in] subsys Subsystem number
+ * \param[in] cbfn Callback function
+ * \param[in] data Data passed through to callback
+ */
int osmo_signal_register_handler(unsigned int subsys,
osmo_signal_cbfn *cbfn, void *data)
{
@@ -58,6 +69,11 @@ int osmo_signal_register_handler(unsigned int subsys,
return 0;
}
+/*! \brief Unregister signal handler
+ * \param[in] subsys Subsystem number
+ * \param[in] cbfn Callback function
+ * \param[in] data Data passed through to callback
+ */
void osmo_signal_unregister_handler(unsigned int subsys,
osmo_signal_cbfn *cbfn, void *data)
{
@@ -73,7 +89,11 @@ void osmo_signal_unregister_handler(unsigned int subsys,
}
}
-
+/*! \brief dispatch (deliver) a new signal to all registered handlers
+ * \param[in] subsys Subsystem number
+ * \param[in] signal Signal number,
+ * \param[in] signal_data Data to be passed along to handlers
+ */
void osmo_signal_dispatch(unsigned int subsys, unsigned int signal,
void *signal_data)
{
@@ -85,3 +105,5 @@ void osmo_signal_dispatch(unsigned int subsys, unsigned int signal,
(*handler->cbfn)(subsys, signal, handler->data, signal_data);
}
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/socket.c b/src/shared/libosmocore/src/socket.c
index f1fcccd5..1a1d71dc 100644
--- a/src/shared/libosmocore/src/socket.c
+++ b/src/shared/libosmocore/src/socket.c
@@ -1,5 +1,13 @@
#include "../config.h"
+/*! \addtogroup socket
+ * @{
+ */
+
+/*! \file socket.c
+ * \brief Osmocom socket convenience functions
+ */
+
#ifdef HAVE_SYS_SOCKET_H
#include <osmocom/core/logging.h>
@@ -18,6 +26,18 @@
#include <netdb.h>
#include <ifaddrs.h>
+/*! \brief Initialize a socket (including bind/connect)
+ * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC
+ * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
+ * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
+ * \param[in] host remote host name or IP address in string form
+ * \param[in] port remote port number in host byte order
+ * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT
+ *
+ * This function creates a new socket of the designated \a family, \a
+ * type and \a proto and optionally binds or connects it, depending on
+ * the value of \a flags parameter.
+ */
int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
const char *host, uint16_t port, unsigned int flags)
{
@@ -93,6 +113,18 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
return sfd;
}
+/*! \brief Initialize a socket and fill \ref osmo_fd
+ * \param[out] osmocom file descriptor (will be filled in)
+ * \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC
+ * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
+ * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
+ * \param[in] host remote host name or IP address in string form
+ * \param[in] port remote port number in host byte order
+ * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT
+ *
+ * This function creates (and optionall binds/connects) a socket using
+ * \ref osmo_sock_init, but also fills the \a ofd structure.
+ */
int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto,
const char *host, uint16_t port, unsigned int flags)
{
@@ -114,6 +146,15 @@ int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto,
return sfd;
}
+/*! \brief Initialize a socket and fill \ref sockaddr
+ * \param[out] ss socket address (will be filled in)
+ * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
+ * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
+ * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT
+ *
+ * This function creates (and optionall binds/connects) a socket using
+ * \ref osmo_sock_init, but also fills the \a ss structure.
+ */
int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,
uint8_t proto, unsigned int flags)
{
@@ -177,7 +218,11 @@ static int sockaddr_equal(const struct sockaddr *a,
return 0;
}
-/* determine if the given address is a local address */
+/*! \brief Determine if the given address is a local address
+ * \param[in] addr Socket Address
+ * \param[in] addrlen Length of socket address in bytes
+ * \returns 1 if address is local, 0 otherwise.
+ */
int osmo_sockaddr_is_local(struct sockaddr *addr, socklen_t addrlen)
{
struct ifaddrs *ifaddr, *ifa;
@@ -198,3 +243,5 @@ int osmo_sockaddr_is_local(struct sockaddr *addr, socklen_t addrlen)
}
#endif /* HAVE_SYS_SOCKET_H */
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/timer.c b/src/shared/libosmocore/src/timer.c
index bd11a46c..ed2b2963 100644
--- a/src/shared/libosmocore/src/timer.c
+++ b/src/shared/libosmocore/src/timer.c
@@ -18,6 +18,13 @@
*
*/
+/*! \addtogroup timer
+ * @{
+ */
+
+/*! \file timer.c
+ */
+
#include <assert.h>
#include <string.h>
#include <osmocom/core/timer.h>
@@ -31,6 +38,10 @@ static struct timeval s_select_time;
#define TIME_SMALLER(left, right) \
(left.tv_sec*MICRO_SECONDS+left.tv_usec) <= (right.tv_sec*MICRO_SECONDS+right.tv_usec)
+
+/*! \brief add a new timer to the timer management
+ * \param[in] timer the timer that should be added
+ */
void osmo_timer_add(struct osmo_timer_list *timer)
{
struct osmo_timer_list *list_timer;
@@ -47,6 +58,16 @@ void osmo_timer_add(struct osmo_timer_list *timer)
llist_add(&timer->entry, &timer_list);
}
+/*! \brief schedule a timer at a given future relative time
+ * \param[in] timer the to-be-added timer
+ * \param[in] seconds number of seconds from now
+ * \param[in] microseconds number of microseconds from now
+ *
+ * This function can be used to (re-)schedule a given timer at a
+ * specified number of seconds+microseconds in the future. It will
+ * internally add it to the timer management data structures, thus
+ * osmo_timer_add() is automatically called.
+ */
void
osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds)
{
@@ -60,6 +81,12 @@ osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds
osmo_timer_add(timer);
}
+/*! \brief delete a timer from timer management
+ * \param[in] timer the to-be-deleted timer
+ *
+ * This function can be used to delete a previously added/scheduled
+ * timer from the timer management code.
+ */
void osmo_timer_del(struct osmo_timer_list *timer)
{
if (timer->in_list) {
@@ -69,6 +96,13 @@ void osmo_timer_del(struct osmo_timer_list *timer)
}
}
+/*! \brief check if given timer is still pending
+ * \param[in] timer the to-be-checked timer
+ * \return 1 if pending, 0 otherwise
+ *
+ * This function can be used to determine whether a given timer
+ * has alredy expired (returns 0) or is still pending (returns 1)
+ */
int osmo_timer_pending(struct osmo_timer_list *timer)
{
return timer->active;
@@ -184,3 +218,5 @@ int osmo_timers_check(void)
}
return i;
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/utils.c b/src/shared/libosmocore/src/utils.c
index e1d4c893..a25479f1 100644
--- a/src/shared/libosmocore/src/utils.c
+++ b/src/shared/libosmocore/src/utils.c
@@ -6,7 +6,19 @@
#include <osmocom/core/utils.h>
+/*! \addtogroup utils
+ * @{
+ */
+
+/*! \file utils.c */
+
static char namebuf[255];
+
+/*! \brief get human-readable string for given value
+ * \param[in] vs Array of value_string tuples
+ * \param[in] val Value to be converted
+ * \returns pointer to human-readable string
+ */
const char *get_value_string(const struct value_string *vs, uint32_t val)
{
int i;
@@ -22,6 +34,11 @@ const char *get_value_string(const struct value_string *vs, uint32_t val)
return namebuf;
}
+/*! \brief get numeric value for given human-readable string
+ * \param[in] vs Array of value_string tuples
+ * \param[in] str human-readable string
+ * \returns numeric value (>0) or negative numer in case of error
+ */
int get_string_value(const struct value_string *vs, const char *str)
{
int i;
@@ -35,6 +52,10 @@ int get_string_value(const struct value_string *vs, const char *str)
return -EINVAL;
}
+/*! \brief Convert BCD-encoded digit into printable character
+ * \param[in] bcd A single BCD-encoded digit
+ * \returns single printable character
+ */
char osmo_bcd2char(uint8_t bcd)
{
if (bcd < 0xa)
@@ -97,6 +118,10 @@ static char *_osmo_hexdump(const unsigned char *buf, int len, char *delim)
return hexd_buff;
}
+/*! \brief Convert a sequence of unpacked bits to ASCII string
+ * \param[in] bits A sequence of unpacked bits
+ * \param[in] len Length of bits
+ */
char *osmo_ubit_dump(const uint8_t *bits, unsigned int len)
{
int i;
@@ -127,11 +152,27 @@ char *osmo_ubit_dump(const uint8_t *bits, unsigned int len)
return hexd_buff;
}
+/*! \brief Convert binary sequence to hexadecimal ASCII string
+ * \param[in] buf pointer to sequence of bytes
+ * \param[in] len length of buf in number of bytes
+ * \returns pointer to zero-terminated string
+ *
+ * This function will print a sequence of bytes as hexadecimal numbers,
+ * adding one space character between each byte (e.g. "1a ef d9")
+ */
char *osmo_hexdump(const unsigned char *buf, int len)
{
return _osmo_hexdump(buf, len, " ");
}
+/*! \brief Convert binary sequence to hexadecimal ASCII string
+ * \param[in] buf pointer to sequence of bytes
+ * \param[in] len length of buf in number of bytes
+ * \returns pointer to zero-terminated string
+ *
+ * This function will print a sequence of bytes as hexadecimal numbers,
+ * without any space character between each byte (e.g. "1aefd9")
+ */
char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len)
{
return _osmo_hexdump(buf, len, "");
@@ -140,6 +181,10 @@ char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len)
#include "../config.h"
#ifdef HAVE_CTYPE_H
#include <ctype.h>
+/*! \brief Convert an entire string to lower case
+ * \param[out] out output string, caller-allocated
+ * \param[in] in input string
+ */
void osmo_str2lower(char *out, const char *in)
{
unsigned int i;
@@ -149,6 +194,10 @@ void osmo_str2lower(char *out, const char *in)
out[strlen(in)] = '\0';
}
+/*! \brief Convert an entire string to upper case
+ * \param[out] out output string, caller-allocated
+ * \param[in] in input string
+ */
void osmo_str2upper(char *out, const char *in)
{
unsigned int i;
@@ -158,3 +207,5 @@ void osmo_str2upper(char *out, const char *in)
out[strlen(in)] = '\0';
}
#endif /* HAVE_CTYPE_H */
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/vty/command.c b/src/shared/libosmocore/src/vty/command.c
index 1c8df61a..ab1eacaa 100644
--- a/src/shared/libosmocore/src/vty/command.c
+++ b/src/shared/libosmocore/src/vty/command.c
@@ -40,6 +40,11 @@ Boston, MA 02111-1307, USA. */
#include <osmocom/core/talloc.h>
+/*! \addtogroup command
+ * @{
+ */
+/*! \file command.c */
+
#define CONFIGFILE_MASK 022
void *tall_vty_cmd_ctx;
@@ -81,7 +86,9 @@ struct cmd_node config_node = {
/* Default motd string. */
const char *default_motd = "";
-/* This is called from main when a daemon is invoked with -v or --version. */
+/*! \brief print the version (and optionally copyright) information
+ *
+ * This is called from main when a daemon is invoked with -v or --version. */
void print_version(int print_copyright)
{
printf("%s version %s\n", host.app_info->name, host.app_info->version);
@@ -114,7 +121,7 @@ char *argv_concat(const char **argv, int argc, int shift)
return str;
}
-/* Install top node of command vector. */
+/*! \brief Install top node of command vector. */
void install_node(struct cmd_node *node, int (*func) (struct vty *))
{
vector_set_index(cmdvec, node->node, node);
@@ -151,7 +158,7 @@ static int is_config(struct vty *vty)
return vty->node > CONFIG_NODE;
}
-/* Sort each node's command element according to command string. */
+/*! \brief Sort each node's command element according to command string. */
void sort_node(void)
{
unsigned int i, j;
@@ -181,7 +188,7 @@ void sort_node(void)
}
}
-/* Breaking up string into each command piece. I assume given
+/*! Breaking up string into each command piece. I assume given
character is separated by a space character. Return value is a
vector which includes char ** data element. */
vector cmd_make_strvec(const char *string)
@@ -231,7 +238,7 @@ vector cmd_make_strvec(const char *string)
}
}
-/* Free allocated string vector. */
+/*! \brief Free allocated string vector. */
void cmd_free_strvec(vector v)
{
unsigned int i;
@@ -247,7 +254,7 @@ void cmd_free_strvec(vector v)
vector_free(v);
}
-/* Fetch next description. Used in cmd_make_descvec(). */
+/*! \brief Fetch next description. Used in \ref cmd_make_descvec(). */
static char *cmd_desc_str(const char **string)
{
const char *cp, *start;
@@ -282,7 +289,7 @@ static char *cmd_desc_str(const char **string)
return token;
}
-/* New string vector. */
+/*! \brief New string vector. */
static vector cmd_make_descvec(const char *string, const char *descstr)
{
int multiple = 0;
@@ -389,7 +396,7 @@ static int cmd_cmdsize(vector strvec)
return size;
}
-/* Return prompt character of specified node. */
+/*! \brief Return prompt character of specified node. */
const char *cmd_prompt(enum node_type node)
{
struct cmd_node *cnode;
@@ -398,7 +405,10 @@ const char *cmd_prompt(enum node_type node)
return cnode->prompt;
}
-/* Install a command into a node. */
+/*! \brief Install a command into a node
+ * \param[in] ntype Node Type
+ * \param[cmd] element to be installed
+ */
void install_element(enum node_type ntype, struct cmd_element *cmd)
{
struct cmd_node *cnode;
@@ -3227,3 +3237,5 @@ void cmd_init(int terminal)
}
srand(time(NULL));
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/vty/telnet_interface.c b/src/shared/libosmocore/src/vty/telnet_interface.c
index 1a285102..ed64cdab 100644
--- a/src/shared/libosmocore/src/vty/telnet_interface.c
+++ b/src/shared/libosmocore/src/vty/telnet_interface.c
@@ -33,6 +33,11 @@
#include <osmocom/vty/buffer.h>
#include <osmocom/vty/command.h>
+/*! \addtogroup telnet_interface
+ * @{
+ */
+/*! \file telnet_interface.c */
+
/* per connection data */
LLIST_HEAD(active_connections);
@@ -47,6 +52,11 @@ static struct osmo_fd server_socket = {
.priv_nr = 0,
};
+/*! \brief Initialize telnet based VTY interface
+ * \param[in] tall_ctx \ref talloc context
+ * \param[in] priv private data to be passed to callback
+ * \param[in] port UDP port number
+ */
int telnet_init(void *tall_ctx, void *priv, int port)
{
struct sockaddr_in sock_addr;
@@ -55,6 +65,7 @@ int telnet_init(void *tall_ctx, void *priv, int port)
tall_telnet_ctx = talloc_named_const(tall_ctx, 1,
"telnet_connection");
+ /* FIXME: use new socket.c code of libosmocore */
fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd < 0) {
@@ -109,6 +120,7 @@ static void print_welcome(int fd)
write(fd, host.app_info->copyright, strlen(host.app_info->copyright));
}
+/*! \brief close a telnet connection */
int telnet_close_client(struct osmo_fd *fd)
{
struct telnet_connection *conn = (struct telnet_connection*)fd->data;
@@ -183,7 +195,7 @@ static int telnet_new_connection(struct osmo_fd *fd, unsigned int what)
return 0;
}
-/* callback from VTY code */
+/*! \brief callback from core VTY code about VTY related events */
void vty_event(enum event event, int sock, struct vty *vty)
{
struct telnet_connection *connection = vty->priv;
@@ -209,3 +221,4 @@ void vty_event(enum event event, int sock, struct vty *vty)
}
}
+/*! }@ */
diff --git a/src/shared/libosmocore/src/vty/utils.c b/src/shared/libosmocore/src/vty/utils.c
index 7797e62d..47b9931f 100644
--- a/src/shared/libosmocore/src/vty/utils.c
+++ b/src/shared/libosmocore/src/vty/utils.c
@@ -30,6 +30,17 @@
#include <osmocom/vty/vty.h>
+/* \file utils.c */
+
+/*! \addtogroup rate_ctr
+ * @{
+ */
+
+/*! \brief print a rate counter group to given VTY
+ * \param[in] vty The VTY to which it should be printed
+ * \param[in] prefix Any additional log prefix ahead of each line
+ * \param[in] ctrg Rate counter group to be printed
+ */
void vty_out_rate_ctr_group(struct vty *vty, const char *prefix,
struct rate_ctr_group *ctrg)
{
@@ -48,3 +59,5 @@ void vty_out_rate_ctr_group(struct vty *vty, const char *prefix,
VTY_NEWLINE);
};
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/vty/vty.c b/src/shared/libosmocore/src/vty/vty.c
index 1f3237ad..5f5e6a4c 100644
--- a/src/shared/libosmocore/src/vty/vty.c
+++ b/src/shared/libosmocore/src/vty/vty.c
@@ -1,4 +1,42 @@
+/*! \mainpage libosmovty 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
+ * has been imported/derived from the GNU Zebra project.
+ * \n\n
+ * libosmovty implements the interactive command-line on the VTY
+ * (Virtual TTY) as well as configuration file parsing.
+ * \n\n
+ * Please note that C language projects inside Osmocom are typically
+ * single-threaded event-loop state machine designs. As such,
+ * routines in libosmovty 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 © 1997-2007 - Kuninhiro Ishiguro\n
+ * Copyright © 2008-2011 - Harald Welte, Holger Freyther and contributors\n
+ * All rights reserved. \n\n
+ * The source code of libosmovty 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 <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
@@ -18,6 +56,11 @@
#include <osmocom/vty/buffer.h>
#include <osmocom/core/talloc.h>
+/* \addtogroup vty
+ * @{
+ */
+/*! \file vty.c */
+
#define SYSCONFDIR "/usr/local/etc"
/* our callback, located in telnet_interface.c */
@@ -44,7 +87,7 @@ static void vty_clear_buf(struct vty *vty)
memset(vty->buf, 0, vty->max);
}
-/* Allocate new vty struct. */
+/*! \brief Allocate a new vty interface structure */
struct vty *vty_new(void)
{
struct vty *new = talloc_zero(tall_vty_ctx, struct vty);
@@ -137,7 +180,7 @@ static void vty_auth(struct vty *vty, char *buf)
}
}
-/* Close vty interface. */
+/*! \brief Close a given vty interface. */
void vty_close(struct vty *vty)
{
int i;
@@ -178,13 +221,17 @@ void vty_close(struct vty *vty)
talloc_free(vty);
}
+/*! \brief Return if this VTY is a shell or not */
int vty_shell(struct vty *vty)
{
return vty->type == VTY_SHELL ? 1 : 0;
}
-/* VTY standard output function. */
+/*! \brief VTY standard output function
+ * \param[in] vty VTY to which we should print
+ * \param[in] format variable-length format string
+ */
int vty_out(struct vty *vty, const char *format, ...)
{
va_list args;
@@ -241,6 +288,7 @@ int vty_out(struct vty *vty, const char *format, ...)
return len;
}
+/*! \brief print a newline on the given VTY */
int vty_out_newline(struct vty *vty)
{
char *p = vty_newline(vty);
@@ -248,15 +296,24 @@ int vty_out_newline(struct vty *vty)
return 0;
}
+/*! \brief return the current index of a given VTY */
void *vty_current_index(struct vty *vty)
{
return vty->index;
}
+
+/*! \brief return the current node of a given VTY */
int vty_current_node(struct vty *vty)
{
return vty->node;
}
+/*! \brief Lock the configuration to a given VTY
+ * \param[in] vty VTY to which the config shall be locked
+ * \returns 1 on success, 0 on error
+ *
+ * This shall be used to make sure only one VTY at a given time has
+ * access to modify the configuration */
int vty_config_lock(struct vty *vty)
{
if (vty_config == 0) {
@@ -266,6 +323,10 @@ int vty_config_lock(struct vty *vty)
return vty->config;
}
+/*! \brief Unlock the configuration from a given VTY
+ * \param[in] vty VTY from which the configuration shall be unlocked
+ * \returns 0 in case of success
+ */
int vty_config_unlock(struct vty *vty)
{
if (vty_config == 1 && vty->config == 1) {
@@ -1182,7 +1243,7 @@ static void vty_buffer_reset(struct vty *vty)
vty_redraw_line(vty);
}
-/* Read data via vty socket. */
+/*! \brief Read data via vty socket. */
int vty_read(struct vty *vty)
{
int i;
@@ -1401,7 +1462,7 @@ vty_read_file(FILE *confp, void *priv)
return 0;
}
-/* Create new vty structure. */
+/*! \brief Create new vty structure. */
struct vty *
vty_create (int vty_sock, void *priv)
{
@@ -1590,7 +1651,7 @@ struct cmd_node vty_node = {
1,
};
-/* Reset all VTY status. */
+/*! \brief Reset all VTY status. */
void vty_reset(void)
{
unsigned int i;
@@ -1647,6 +1708,10 @@ void vty_init_vtysh(void)
}
extern void *tall_bsc_ctx;
+
+/*! \brief Initialize VTY layer
+ * \param[in] app_info application information
+ */
/* Install vty's own commands like `who' command. */
void vty_init(struct vty_app_info *app_info)
{
@@ -1680,6 +1745,10 @@ void vty_init(struct vty_app_info *app_info)
install_element(VTY_NODE, &no_vty_login_cmd);
}
+/*! \brief Read the configuration file using the VTY code
+ * \param[in] file_name file name of the configuration file
+ * \param[in] priv private data to be passed to \ref vty_read_file
+ */
int vty_read_config_file(const char *file_name, void *priv)
{
FILE *cfile;
@@ -1696,3 +1765,5 @@ int vty_read_config_file(const char *file_name, void *priv)
return rc;
}
+
+/*! }@ */
diff --git a/src/shared/libosmocore/src/write_queue.c b/src/shared/libosmocore/src/write_queue.c
index a5921042..9ddc3af4 100644
--- a/src/shared/libosmocore/src/write_queue.c
+++ b/src/shared/libosmocore/src/write_queue.c
@@ -23,6 +23,19 @@
#include <osmocom/core/write_queue.h>
+/*! \addtogroup write_queue
+ * @{
+ */
+
+/*! \file write_queue.c */
+
+/*! \brief Select loop function for write queue handling
+ * \param[in] fd osmocom file descriptor
+ * \param[in] what bit-mask of events that have happened
+ *
+ * This function is provided so that it can be registered with the
+ * select loop abstraction code (\ref osmo_fd::cb).
+ */
int osmo_wqueue_bfd_cb(struct osmo_fd *fd, unsigned int what)
{
struct osmo_wqueue *queue;
@@ -56,6 +69,10 @@ int osmo_wqueue_bfd_cb(struct osmo_fd *fd, unsigned int what)
return 0;
}
+/*! \brief Initialize a \ref osmo_wqueue structure
+ * \param[in] queue Write queue to operate on
+ * \param[in] max_length Maximum length of write queue
+ */
void osmo_wqueue_init(struct osmo_wqueue *queue, int max_length)
{
queue->max_length = max_length;
@@ -66,6 +83,10 @@ void osmo_wqueue_init(struct osmo_wqueue *queue, int max_length)
INIT_LLIST_HEAD(&queue->msg_queue);
}
+/*! \brief Enqueue a new \ref msgb into a write queue
+ * \param[in] queue Write queue to be used
+ * \param[in] data to-be-enqueued message buffer
+ */
int osmo_wqueue_enqueue(struct osmo_wqueue *queue, struct msgb *data)
{
// if (queue->current_length + 1 >= queue->max_length)
@@ -78,6 +99,11 @@ int osmo_wqueue_enqueue(struct osmo_wqueue *queue, struct msgb *data)
return 0;
}
+/*! \brief Clear a \ref osmo_wqueue
+ * \param[in] queue Write queue to be cleared
+ *
+ * This function will clear (remove/release) all messages in it.
+ */
void osmo_wqueue_clear(struct osmo_wqueue *queue)
{
while (!llist_empty(&queue->msg_queue)) {
@@ -88,3 +114,5 @@ void osmo_wqueue_clear(struct osmo_wqueue *queue)
queue->current_length = 0;
queue->bfd.when &= ~BSC_FD_WRITE;
}
+
+/*! }@ */