doxygen API documentation for libosmo-e1d

If we actually expect 3rd party applications to use libosmo-e1d to talk
to osmo-e1d, we'd better add some basic documentation on how this API
shall be used.

Change-Id: Ib4a97045bca276fbd3892f801898a436de7dc39b
This commit is contained in:
Harald Welte 2022-11-03 22:07:39 +01:00 committed by Oliver Smith
parent e443318da4
commit 20419bdf55
7 changed files with 1911 additions and 58 deletions

1716
Doxyfile.in Normal file

File diff suppressed because it is too large Load Diff

View File

@ -136,6 +136,14 @@ AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
AC_MSG_RESULT([$enable_ext_tests])
AM_CONDITIONAL(ENABLE_EXT_TESTS, test "x$enable_ext_tests" = "xyes")
AC_ARG_ENABLE(doxygen,
[AS_HELP_STRING(
[--disable-doxygen],
[Disable generation of documentation using doxygen],
)],
[doxygen=$enableval], [doxygen="yes"])
AC_PATH_PROG(DOXYGEN,doxygen,false)
AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false && test "x$doxygen" = "xyes")
# https://www.freedesktop.org/software/systemd/man/daemon.html
@ -156,6 +164,7 @@ AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])
AC_OUTPUT(
Makefile
Doxyfile
contrib/Makefile
contrib/systemd/Makefile
contrib/osmo-e1d.spec

View File

@ -46,10 +46,12 @@ autoreconf --install --force
./configure --enable-sanitize --enable-werror $CONFIG
$MAKE $PARALLEL_MAKE
$MAKE check || cat-testlogs.sh
# Do distcheck with --disable-manuals as workaround, because it doesn't build
# the usermanual pdf for some reason and then fails at "make install" because
# it doesn't exist. Spent a lot of time on debugging it, not worth fixing now.
DISTCHECK_CONFIGURE_FLAGS="$CONFIG --disable-manuals" $MAKE distcheck || cat-testlogs.sh
# Do distcheck with --disable options as workaround, because it doesn't build
# the usermanual pdf / doxygen html files for some reason and then fails at
# "make install" because it doesn't exist. Spent a lot of time on debugging it,
# not worth fixing now.
DISTCHECK_CONFIGURE_FLAGS="$CONFIG --disable-manuals --disable-doxygen" \
$MAKE distcheck || cat-testlogs.sh
if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
make -C "$base/doc/manuals" publish

View File

@ -2,3 +2,33 @@ SUBDIRS = \
examples \
manuals \
$(NULL)
HTML = \
$(top_builddir)/doc/e1d/html/index.html \
$(NULL)
if HAVE_DOXYGEN
html_DATA = $(top_builddir)/doc/html.tar
doc: $(html_DATA)
$(html_DATA): apidoc
.PHONY: apidoc
apidoc: $(HTML)
cd $(top_builddir)/doc && tar cf html.tar */html
$(top_builddir)/doc/e1d/html/index.html:
rm -rf $(top_builddir)/doc/e1d; mkdir -p $(top_builddir)/doc/e1d
cd $(top_builddir) && $(DOXYGEN) Doxyfile
install-data-hook:
cd $(DESTDIR)$(htmldir) && tar xf html.tar && rm -f html.tar
uninstall-hook:
cd $(DESTDIR)$(htmldir) && rm -rf e1d
DX_CLEAN = e1d/{html,latex}/* html.tar e1d/doxygen_sqlite3.db
endif
MOSTLYCLEANFILES = $(DX_CLEAN)

View File

@ -5,7 +5,7 @@ The `osmo-e1d` executable offers the following command-line arguments:
=== SYNOPSIS
*osmo-e1d* [-h] [-d 'DBGMASK'] [-c 'CONFIGFILE']
*osmo-e1d* [-h] [-V] [-d 'DBGMASK'] [-c 'CONFIGFILE']
=== OPTIONS

View File

@ -1,7 +1,9 @@
/*
* proto.h
*
* (C) 2019 by Sylvain Munaut <tnt@246tNt.com>
/*! \file proto.h
* Specification of the IPC protocol used on the CTL UNIX domain socket between
* osmo-e1d and its client programs.
*/
/* (C) 2019 by Sylvain Munaut <tnt@246tNt.com>
* (C) 2020 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
@ -30,106 +32,122 @@
#include <osmocom/core/utils.h>
/* E1DP_CMD_INTF_QUERY
* filter: intf (optional)
* in: n/a
* out: array of osmo_e1dp_intf_info
*
* E1DP_CMD_LINE_QUERY
* filter: intf (required), line (optional)
* in: n/a
* out: array of osmo_e1dp_line_info
*
* E1DP_CMD_TS_QUERY
* filter: intf (required), line (required), ts (optional)
* in: n/a
* out: array of osmo_e1dp_ts_info
*
* E1DP_CMD_LINE_CONFIG
* filter: intf (required), line (required)
* in: osmo_e1dp_line_config
* out: osmo_e1dp_line_info
*
* E1DP_CMD_TS_OPEN
* filter: intf (required), line (required), ts (required)
* in: osmo_e1dp_ts_config
* out: osmo_e1dp_ts_info with the opened TS (or an invalid one with id == -1 for errors)
* + message with the file descriptor
*/
/*! e1d CTL protocol message type definition. Split in 'type' and 'command' portion. */
enum osmo_e1dp_msg_type {
/*! Query information about E1 interface(s).
* filter: intf (optional); in: n/a out: array of osmo_e1dp_intf_info */
E1DP_CMD_INTF_QUERY = 0x00,
/*! Query information about E1 line(s).
* filter: intf (required), line (optional); in: n/a; out: array of osmo_e1dp_line_info */
E1DP_CMD_LINE_QUERY = 0x01,
/*! Query information about E1 timeslot(s).
* filter: intf (required), line (required), ts (optional); in: n/a; out: array of osmo_e1dp_ts_info */
E1DP_CMD_TS_QUERY = 0x02,
/*! Configure a given E1 line.
* filter: intf (required), line (required); in: osmo_e1dp_line_config; out: osmo_e1dp_line_info */
E1DP_CMD_LINE_CONFIG = 0x03,
/*! Open a given E1 timeslot.
* filter: intf (required), line (required), ts (required); in: osmo_e1dp_ts_config;
* out: osmo_e1dp_ts_info with the opened TS (or an invalid one with id == -1 for errors)
* + message with the file descriptor */
E1DP_CMD_TS_OPEN = 0x04,
/*! Message is an event */
E1DP_EVT_TYPE = 0x40,
/*! Message is a response */
E1DP_RESP_TYPE = 0x80,
/*! Message is an error */
E1DP_ERR_TYPE = 0xc0,
/*! Mask to separate type from command */
E1DP_TYPE_MSK = 0xc0,
};
/*! e1d CTL protocol line mode. */
enum osmo_e1dp_line_mode {
/*! Line is switched off */
E1DP_LMODE_OFF = 0x00,
/*! Line is used in channelized mode with (64kBps) timeslots */
E1DP_LMODE_CHANNELIZED = 0x20,
/*! Line is used as superchannel (31TS combined together) */
E1DP_LMODE_SUPERCHANNEL = 0x21,
/*! Line is used in E1oIP mode (not available to CTL clients) */
E1DP_LMODE_E1OIP = 0x22,
};
/*! e1d CTL protocol timeslot mode. */
enum osmo_e1dp_ts_mode {
/*! Timeslot is switched off. */
E1DP_TSMODE_OFF = 0x00,
/*! Timeslot is in RAW mode, containing transparent 64kBps bitstream. */
E1DP_TSMODE_RAW = 0x10,
/*! Timeslot is in HLDC-FCS mode; e1d will run software HDLC processor. */
E1DP_TSMODE_HDLCFCS = 0x11,
};
/* osmo_e1dp_ts_config.flags */
/*! Flag that can be used as osmo_e1dp_ts_config.flags to force opening a TS. */
#define E1DP_TS_OPEN_F_FORCE 0x80
/* the idea here is to use the first byte as a version number, to prevent incompatible
/*! Magic value. the idea here is to use the first byte as a version number, to prevent incompatible
* clients from connecting to e1d */
#define E1DP_MAGIC 0x01e1
/*! Maximum length of a protocol message */
#define E1DP_MAX_LEN 4096
/*! magic value used to indicate superchannel instead of timeslot. */
#define E1DP_TS_SUPERCHAN 0xfe
/*! magic value to indicate given field (interface/line/timeslot) is
* unspecified/invalid. */
#define E1DP_INVALID 0xff
/*! default location of osmo-e1d CTL protocol UNIX domain socket */
#define E1DP_DEFAULT_SOCKET "/tmp/osmo-e1d.ctl"
/*! Maximum length of HDLC messages */
#define E1DP_MAX_SIZE_HDLC 264
/*! message header of osmo-e1d CTL protocol. */
struct osmo_e1dp_msg_hdr {
uint16_t magic;
uint16_t len;
uint16_t magic; /*< magic value (E1DP_MAGIC) */
uint16_t len; /*< length of message (octets) */
uint8_t type;
uint8_t intf;
uint8_t line;
uint8_t ts;
uint8_t type; /*< message type (enum osmo_e1dp_msg_type) */
uint8_t intf; /*< E1 interface number (or E1DP_INVALID) */
uint8_t line; /*< E1 line number (or E1DP_INVALID) */
uint8_t ts; /*< timeslot number (or E1DP_INVALID) */
} __attribute__((packed));
/*! Information about an E1 interface */
struct osmo_e1dp_intf_info {
uint8_t id;
uint8_t n_lines;
uint8_t id; /*< Numeric identifier of E1 interface */
uint8_t n_lines; /*< number of E1 lines within this interface */
} __attribute__((packed));
/*! Configuration of an E1 line */
struct osmo_e1dp_line_config {
uint8_t mode;
uint8_t mode; /*< E1 line mode (enum osmo_e1dp_line_mode) */
} __attribute__((packed));
/*! Information about an E1 line */
struct osmo_e1dp_line_info {
uint8_t id;
struct osmo_e1dp_line_config cfg;
uint8_t status; /* TBD */
uint8_t id; /*< E1 line number */
struct osmo_e1dp_line_config cfg; /*! E1 line configuration */
uint8_t status; /*!< TBD */
} __attribute__((packed));
/*! Configuration of an E1 timeslot */
struct osmo_e1dp_ts_config {
uint8_t mode;
uint8_t flags;
uint16_t read_bufsize;
uint8_t mode; /*< timeslot mode (enum osmo_e1dp_ts_mode) */
uint8_t flags; /*< flags (currently only E1DP_TS_OPEN_F_FORCE) */
uint16_t read_bufsize; /*< size of read buffer (in octets) */
} __attribute__((packed));
/*! Information about an E1 timeslot */
struct osmo_e1dp_ts_info {
uint8_t id;
struct osmo_e1dp_ts_config cfg;
uint8_t status; /* TBD */
uint8_t id; /*< E1 timeslot number */
struct osmo_e1dp_ts_config cfg; /*< E1 timeslot configuration */
uint8_t status; /*< TBD */
} __attribute__((packed));

View File

@ -22,6 +22,28 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*! \file proto_clnt.c
* e1d protocol client library (libosmo-e1d).
*
* This library implements ways how an external client (application
* program) can talk to osmo-e1d. The primary purpose is to open
* specific E1 timeslots in order to receive and/or transmit data on
* them.
*
* Each such open timeslot is represented to the client program as a
* file descriptor, which the client can read and/or write as usual.
* This is implemented using underlying UNIX domain sockets and file
* descriptor passing.
*
* In addition to opening timeslots, client applications can also query
* osmo-e1d for information about its E1 interfaces, E1 lines and E1 timeslots.
*
* The functions provided by this client library are implemented as
* synchronous/blocking calls to osmo-e1d. This means that an API call
* will be blocking until there is a response received from osmo-e1d.
*
*/
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
@ -43,9 +65,10 @@
#include "log.h"
/*! Internal representation of client program connected to the CTL socket */
struct osmo_e1dp_client {
void *ctx;
struct osmo_fd ctl_fd;
void *ctx; /*!< talloc context */
struct osmo_fd ctl_fd; /*!< osmo-fd wrapped unix domain (CTL) socket to @osmo-e1d@ */
};
@ -85,6 +108,10 @@ err:
}
/*! Create a new client talking to the CTL server socket of osmo-e1d.
* \param[in] ctx talloc context from which this client is allocated
* \param[in] path path of the CTL unix domain socket of osmo-e1d
* \returns handle to newly-created client; NULL in case of errors */
struct osmo_e1dp_client *
osmo_e1dp_client_create(void *ctx, const char *path)
{
@ -113,6 +140,9 @@ err:
}
/*! Destroy a previously created client. Closes socket and releases memory.
* \param[in] clnt Client previously returned from osmo_e1dp_client_create().
*/
void
osmo_e1dp_client_destroy(struct osmo_e1dp_client *clnt)
{
@ -192,6 +222,12 @@ err:
return rc;
}
/*! Query osmo-e1d for information about a specific E1 interface.
* \param[in] clnt Client previously returned from osmo_e1dp_client_create().
* \param[out] ii callee-allocated array of interface information structures.
* \param[out] n caller-provided pointer to integer. Will contain number of entries in ii.
* \param[in] intf E1 interface number to query, or E1DP_INVALID to query all interfaces.
* \returns zero in case of success; negative in case of error. */
int
osmo_e1dp_client_intf_query(struct osmo_e1dp_client *clnt,
struct osmo_e1dp_intf_info **ii, int *n,
@ -223,6 +259,14 @@ osmo_e1dp_client_intf_query(struct osmo_e1dp_client *clnt,
return 0;
}
/*! Query osmo-e1d for information about a specific E1 line.
* \param[in] clnt Client previously returned from osmo_e1dp_client_create().
* \param[out] li callee-allocated array of line information structures.
* \param[out] n caller-provided pointer to integer. Will contain number of entries in li.
* \param[in] intf E1 interface number to query.
* \param[in] line E1 line number (within interface) to query, or E1DP_INVALID to query all lines within the
* interface.
* \returns zero in case of success; negative in case of error. */
int
osmo_e1dp_client_line_query(struct osmo_e1dp_client *clnt,
struct osmo_e1dp_line_info **li, int *n,
@ -254,6 +298,15 @@ osmo_e1dp_client_line_query(struct osmo_e1dp_client *clnt,
return 0;
}
/*! Query osmo-e1d for information about a specific E1 timeslot.
* \param[in] clnt Client previously returned from osmo_e1dp_client_create().
* \param[out] ti callee-allocated array of timeslot information structures.
* \param[out] n caller-provided pointer to integer. Will contain number of entries in ti.
* \param[in] intf E1 interface number to query.
* \param[in] line E1 line number (within interface) to query.
* \param[in] ts E1 timeslot numer (within line) to query, or E1DP_INVALID to query all of the timeslots
* within the line.
* \returns zero in case of success; negative in case of error. */
int
osmo_e1dp_client_ts_query(struct osmo_e1dp_client *clnt,
struct osmo_e1dp_ts_info **ti, int *n,
@ -285,6 +338,12 @@ osmo_e1dp_client_ts_query(struct osmo_e1dp_client *clnt,
return 0;
}
/*! Configure a specific E1 line in osmo-e1d.
* \param[in] clnt Client previously returned from osmo_e1dp_client_create().
* \param[in] intf E1 interface number to configure.
* \param[in] line E1 line number (within interface) to configure.
* \param[in] mode E1 line mode to set on line.
* \returns zero in case of success; negative in case of error. */
int
osmo_e1dp_client_line_config(struct osmo_e1dp_client *clnt,
uint8_t intf, uint8_t line, enum osmo_e1dp_line_mode mode)
@ -350,6 +409,14 @@ _client_ts_open(struct osmo_e1dp_client *clnt,
return tsfd;
}
/*! Open a specific E1 timeslot of osmo-e1d.
* \param[in] clnt Client previously returned from osmo_e1dp_client_create().
* \param[in] intf E1 interface number of line containing timeslot.
* \param[in] line E1 line number (within interface) of line containing timeslot.
* \param[in] ts E1 timeslot number (within line) to open.
* \param[in] mode timeslot mode (RAW, HDLC-FCE) in which to open timeslot.
* \param[in] read_bufsize size of read buffer (in octets) to use.
* \returns file descriptor of opened timeslot in case of success; negative in case of error. */
int
osmo_e1dp_client_ts_open(struct osmo_e1dp_client *clnt,
uint8_t intf, uint8_t line, uint8_t ts,
@ -358,6 +425,17 @@ osmo_e1dp_client_ts_open(struct osmo_e1dp_client *clnt,
return _client_ts_open(clnt, intf, line, ts, mode, read_bufsize, 0);
}
/*! Force-Open a specific E1 timeslot of osmo-e1d.
* The normal (non-force) opening of a timeslot will fail in case the given timeslot is already
* open (by either this or some other client). Using the open_force variant you can force osmo-e1d
* to disregard the existing client/timeslot and transfer ownership of the timeslot to this client.
* \param[in] clnt Client previously returned from osmo_e1dp_client_create().
* \param[in] intf E1 interface number of line containing timeslot.
* \param[in] line E1 line number (within interface) of line containing timeslot.
* \param[in] ts E1 timeslot number (within line) to open.
* \param[in] mode timeslot mode (RAW, HDLC-FCE) in which to open timeslot.
* \param[in] read_bufsize size of read buffer (in octets) to use.
* \returns file descriptor of opened timeslot in case of success; negative in case of error. */
int
osmo_e1dp_client_ts_open_force(struct osmo_e1dp_client *clnt,
uint8_t intf, uint8_t line, uint8_t ts,