diff options
| author | Harald Welte <laforge@gnumonks.org> | 2011-08-16 23:26:52 +0200 | 
|---|---|---|
| committer | Harald Welte <laforge@gnumonks.org> | 2011-08-16 23:26:52 +0200 | 
| commit | bd598e3c5eff85ed3958909584d3d8e1e2235b41 (patch) | |
| tree | 1b47f59c634cc1139be16e4625f7809c4d3e4460 | |
| parent | 300e78d3e5714449e73a056dd5878adab97c6423 (diff) | |
start to add doxygen documentation to libosmocore headers
| -rw-r--r-- | include/osmocom/core/bits.h | 48 | ||||
| -rw-r--r-- | include/osmocom/core/logging.h | 25 | ||||
| -rw-r--r-- | include/osmocom/core/msgb.h | 234 | ||||
| -rw-r--r-- | include/osmocom/core/select.h | 30 | ||||
| -rw-r--r-- | include/osmocom/core/socket.h | 43 | ||||
| -rw-r--r-- | include/osmocom/core/statistics.h | 28 | ||||
| -rw-r--r-- | include/osmocom/core/timer.h | 51 | ||||
| -rw-r--r-- | include/osmocom/core/utils.h | 65 | ||||
| -rw-r--r-- | include/osmocom/core/write_queue.h | 35 | 
9 files changed, 507 insertions, 52 deletions
| diff --git a/include/osmocom/core/bits.h b/include/osmocom/core/bits.h index eb22d07c..9f8e1fb5 100644 --- a/include/osmocom/core/bits.h +++ b/include/osmocom/core/bits.h @@ -3,9 +3,13 @@  #include <stdint.h> -typedef int8_t  sbit_t;		/* soft bit (-127...127) */ -typedef uint8_t ubit_t;		/* unpacked bit (0 or 1) */ -typedef uint8_t pbit_t;		/* packed bis (8 bits in a byte) */ +/*! \file bits.h + *  \brief Osmocom bit level support code + */ + +typedef int8_t  sbit_t;		/*!< \brief soft bit (-127...127) */ +typedef uint8_t ubit_t;		/*!< \brief unpacked bit (0 or 1) */ +typedef uint8_t pbit_t;		/*!< \brief packed bis (8 bits in a byte) */  /*     NOTE on the endianess of pbit_t: @@ -13,7 +17,9 @@ typedef uint8_t pbit_t;		/* packed bis (8 bits in a byte) */     Bit i in a pbit_t array is array[i/8] & (1<<(7-i%8))  */ -/* determine how many bytes we would need for 'num_bits' packed bits */ +/*! \brief determine how many bytes we would need for \a num_bits packed bits + *  \param[in] num_bits Number of packed bits + */  static inline unsigned int osmo_pbit_bytesize(unsigned int num_bits)  {  	unsigned int pbit_bytesize = num_bits / 8; @@ -24,20 +30,42 @@ static inline unsigned int osmo_pbit_bytesize(unsigned int num_bits)  	return pbit_bytesize;  } -/* convert unpacked bits to packed bits, return length in bytes */ +/*! \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); -/* 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); -/* 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); -/* 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); diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h index 154ee198..537dc609 100644 --- a/include/osmocom/core/logging.h +++ b/include/osmocom/core/logging.h @@ -1,11 +1,17 @@  #ifndef _OSMOCORE_LOGGING_H  #define _OSMOCORE_LOGGING_H +/*! \file logging.h + *  \brief Osmocom logging framework + */ +  #include <stdio.h>  #include <stdint.h>  #include <osmocom/core/linuxlist.h> +/*! \brief Maximum number of logging contexts */  #define LOG_MAX_CTX		8 +/*! \brief Maximum number of logging filters */  #define LOG_MAX_FILTERS	8  #define DEBUG @@ -21,9 +27,21 @@  void logp(int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6))); -/* new logging interface */ +/*! \brief Log a new message through the Osmocom logging framework + *  \param[in] ss logging subsystem (e.g. \ref DLGLOBAL) + *  \param[in] level logging level (e.g. \ref LOGL_NOTICE) + *  \param[in] fmt format string + *  \param[in] args variable argument list + */  #define LOGP(ss, level, fmt, args...) \  	logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args) + +/*! \brief Continue a log message through the Osmocom logging framework + *  \param[in] ss logging subsystem (e.g. \ref DLGLOBAL) + *  \param[in] level logging level (e.g. \ref LOGL_NOTICE) + *  \param[in] fmt format string + *  \param[in] args variable argument list + */  #define LOGPC(ss, level, fmt, args...) \  	logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args) @@ -151,7 +169,12 @@ struct log_target *log_target_create_syslog(const char *ident, int option,  					    int facility);  int log_target_file_reopen(struct log_target *tgt); +/*! \brief Add a new logging target + */  void log_add_target(struct log_target *target); + +/*! \brief Deelete an existing logging target + */  void log_del_target(struct log_target *target);  /* Generate command string for VTY use */ diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 915c4a04..c579b8a7 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -24,45 +24,85 @@  #include <osmocom/core/linuxlist.h>  #include <osmocom/core/utils.h> +/*! \file msgb.h + *  \brief Osmocom message buffers + * The Osmocom message buffers are modelled after the 'struct skb' + * inside the Linux kernel network stack.  As they exist in userspace, + * they are much simplified.  However, terminology such as headroom, + * tailroom, push/pull/put etc. remains the same. + */ +  #define MSGB_DEBUG +/*! \brief Osmocom message buffer */  struct msgb { -	struct llist_head list; +	struct llist_head list; /*!< \brief linked list header */  	/* Part of which TRX logical channel we were received / transmitted */  	/* FIXME: move them into the control buffer */  	union { -		void *dst; +		void *dst; /*!< \brief reference of origin/destination */  		struct gsm_bts_trx *trx;  	}; -	struct gsm_lchan *lchan; - -	/* the Layer1 header (if any) */ -	unsigned char *l1h; -	/* the A-bis layer 2 header: OML, RSL(RLL), NS */ -	unsigned char *l2h; -	/* the layer 3 header. For OML: FOM; RSL: 04.08; GPRS: BSSGP */ -	unsigned char *l3h; -	/* the layer 4 header */ -	unsigned char *l4h; - -	/* the 'control buffer', large enough to contain 5 pointers */ -	unsigned long cb[5]; - -	uint16_t data_len; -	uint16_t len; - -	unsigned char *head; -	unsigned char *tail; -	unsigned char *data; -	unsigned char _data[0]; +	struct gsm_lchan *lchan; /*!< \brief logical channel */ + +	unsigned char *l1h; /*!< \brief pointer to Layer1 header (if any) */ +	unsigned char *l2h; /*!< \brief pointer to A-bis layer 2 header: OML, RSL(RLL), NS */ +	unsigned char *l3h; /*!< \brief pointer to Layer 3 header. For OML: FOM; RSL: 04.08; GPRS: BSSGP */ +	unsigned char *l4h; /*!< \brief pointer to layer 4 header */ + +	unsigned long cb[5]; /*!< \brief control buffer */ + +	uint16_t data_len;   /*!< \brief length of underlying data array */ +	uint16_t len;	     /*!< \brief length of bytes used in msgb */ + +	unsigned char *head;	/*!< \brief start of underlying memory buffer */ +	unsigned char *tail;	/*!< \brief end of message in buffer */ +	unsigned char *data;	/*!< \brief start of message in buffer */ +	unsigned char _data[0]; /*!< \brief optional immediate data array */  }; +/*! \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 + */  extern struct msgb *msgb_alloc(uint16_t size, const char *name); + +/*! \brief Release given message buffer + * \param[in] m Message buffer to be free'd + */  extern void msgb_free(struct msgb *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 + */  extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg); + +/*! \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. + */  extern struct msgb *msgb_dequeue(struct llist_head *queue); + +/*! \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. + */  extern void msgb_reset(struct msgb *m);  #ifdef MSGB_DEBUG @@ -74,41 +114,99 @@ extern void msgb_reset(struct msgb *m);  #define MSGB_ABORT(msg, fmt, args ...)  #endif +/*! \brief obtain L1 header of msgb */  #define msgb_l1(m)	((void *)(m->l1h)) +/*! \brief obtain L2 header of msgb */  #define msgb_l2(m)	((void *)(m->l2h)) +/*! \brief obtain L3 header of msgb */  #define msgb_l3(m)	((void *)(m->l3h)) +/*! \brief obtain SMS header of msgb */  #define msgb_sms(m)	((void *)(m->l4h)) +/*! \brief determine length of L1 message + *  \param[in] msgb message buffer + *  \returns size of L1 message in bytes + * + * This function computes the number of bytes between the tail of the + * message and the layer 1 header. + */  static inline unsigned int msgb_l1len(const struct msgb *msgb)  {  	return msgb->tail - (uint8_t *)msgb_l1(msgb);  } +/*! \brief determine length of L2 message + *  \param[in] msgb message buffer + *  \returns size of L2 message in bytes + * + * This function computes the number of bytes between the tail of the + * message and the layer 2 header. + */  static inline unsigned int msgb_l2len(const struct msgb *msgb)  {  	return msgb->tail - (uint8_t *)msgb_l2(msgb);  } +/*! \brief determine length of L3 message + *  \param[in] msgb message buffer + *  \returns size of L3 message in bytes + * + * This function computes the number of bytes between the tail of the + * message and the layer 3 header. + */  static inline unsigned int msgb_l3len(const struct msgb *msgb)  {  	return msgb->tail - (uint8_t *)msgb_l3(msgb);  } +/*! \brief determine the length of the header + *  \param[in] msgb message buffer + *  \returns number of bytes between start of buffer and start of msg + * + * This function computes the length difference between the underlying + * data buffer and the used section of the \a msgb. + */  static inline unsigned int msgb_headlen(const struct msgb *msgb)  {  	return msgb->len - msgb->data_len;  } +/*! \brief determine how much tail room is left in msgb + *  \param[in] msgb message buffer + *  \returns number of bytes remaining at end of msgb + * + * This function computes the amount of octets left in the underlying + * data buffer after the end of the message. + */  static inline int msgb_tailroom(const struct msgb *msgb)  {  	return (msgb->head + msgb->data_len) - msgb->tail;  } +/*! \brief determine the amount of headroom in msgb + *  \param[in] msgb message buffer + *  \returns number of bytes left ahead of message start in msgb + * + * This function computes the amount of bytes left in the underlying + * data buffer before the start of the actual message. + */  static inline int msgb_headroom(const struct msgb *msgb)  {  	return (msgb->data - msgb->head);  } +/*! \brief append data to end of message buffer + *  \param[in] msgb message buffer + *  \param[in] len number of bytes to append to message + *  \returns pointer to start of newly-appended data + * + * This function will move the \a tail pointer of the message buffer \a + * len bytes further, thus enlarging the message by \a len bytes. + * + * The return value is a pointer to start of the newly added section at + * the end of the message and can be used for actually filling/copying + * data into it. + */  static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)  {  	unsigned char *tmp = msgb->tail; @@ -119,17 +217,32 @@ static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)  	msgb->len += len;  	return tmp;  } + +/*! \brief append a uint8 value to the end of the message + *  \param[in] msgb message buffer + *  \param[in] word unsigned 8bit byte to be appended + */  static inline void msgb_put_u8(struct msgb *msgb, uint8_t word)  {  	uint8_t *space = msgb_put(msgb, 1);  	space[0] = word & 0xFF;  } + +/*! \brief append a uint16 value to the end of the message + *  \param[in] msgb message buffer + *  \param[in] word unsigned 16bit byte to be appended + */  static inline void msgb_put_u16(struct msgb *msgb, uint16_t word)  {  	uint8_t *space = msgb_put(msgb, 2);  	space[0] = word >> 8 & 0xFF;  	space[1] = word & 0xFF;  } + +/*! \brief append a uint32 value to the end of the message + *  \param[in] msgb message buffer + *  \param[in] word unsigned 32bit byte to be appended + */  static inline void msgb_put_u32(struct msgb *msgb, uint32_t word)  {  	uint8_t *space = msgb_put(msgb, 4); @@ -138,6 +251,11 @@ static inline void msgb_put_u32(struct msgb *msgb, uint32_t word)  	space[2] = word >> 8 & 0xFF;  	space[3] = word & 0xFF;  } + +/*! \brief remove data from end of message + *  \param[in] msgb message buffer + *  \param[in] len number of bytes to remove from end + */  static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len)  {  	unsigned char *tmp = msgb->data; @@ -145,21 +263,46 @@ static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len)  	msgb->len -= len;  	return tmp;  } +/*! \brief remove uint8 from end of message + *  \param[in] msgb message buffer + *  \returns 8bit value taken from end of msgb + */  static inline uint8_t msgb_get_u8(struct msgb *msgb)  {  	uint8_t *space = msgb_get(msgb, 1);  	return space[0];  } +/*! \brief remove uint16 from end of message + *  \param[in] msgb message buffer + *  \returns 16bit value taken from end of msgb + */  static inline uint16_t msgb_get_u16(struct msgb *msgb)  {  	uint8_t *space = msgb_get(msgb, 2);  	return space[0] << 8 | space[1];  } +/*! \brief remove uint32 from end of message + *  \param[in] msgb message buffer + *  \returns 32bit value taken from end of msgb + */  static inline uint32_t msgb_get_u32(struct msgb *msgb)  {  	uint8_t *space = msgb_get(msgb, 4);  	return space[0] << 24 | space[1] << 16 | space[2] << 8 | space[3];  } + +/*! \brief prepend (push) some data to start of message + *  \param[in] msgb message buffer + *  \param[in] len number of bytes to pre-pend + *  \returns pointer to newly added portion at start of \a msgb + * + * This function moves the \a data pointer of the \ref msgb further + * to the front (by \a len bytes), thereby enlarging the message by \a + * len bytes. + * + * The return value is a pointer to the newly added section in the + * beginning of the message.  It can be used to fill/copy data into it. + */  static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)  {  	if (msgb_headroom(msgb) < (int) len) @@ -169,19 +312,48 @@ static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)  	msgb->len += len;  	return msgb->data;  } +/*! \brief remove (pull) a header from the front of the message buffer + *  \param[in] msgb message buffer + *  \param[in] len number of octets to be pulled + *  \returns pointer to new start of msgb + * + * This function moves the \a data pointer of the \ref msgb further back + * in the message, thereby shrinking the size of the message by \a len + * bytes. + */  static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)  {  	msgb->len -= len;  	return msgb->data += len;  } -/* increase the headroom of an empty msgb, reducing the tailroom */ +/*! \brief Increase headroom of empty msgb, reducing the tailroom + *  \param[in] msg message buffer + *  \param[in] len amount of extra octets to be reserved as headroom + * + * This function reserves some memory at the beginning of the underlying + * data buffer.  The idea is to reserve space in case further headers + * have to be pushed to the \ref msgb during further processing. + * + * Calling this function leads to undefined reusults if it is called on + * a non-empty \ref msgb. + */  static inline void msgb_reserve(struct msgb *msg, int len)  {  	msg->data += len;  	msg->tail += len;  } +/*! \brief Allocate message buffer with specified headroom + *  \param[in] size size in bytes, including headroom + *  \param[in] headroom headroom in bytes + *  \param[in] name human-readable name + *  \returns allocated message buffer with specified headroom + * + * This function is a convenience wrapper around \ref msgb_alloc + * followed by \ref msgb_reserve in order to create a new \ref msgb with + * user-specified amount of headroom. + */  static inline struct msgb *msgb_alloc_headroom(int size, int headroom,  						const char *name)  { @@ -194,10 +366,22 @@ static inline struct msgb *msgb_alloc_headroom(int size, int headroom,  }  /* non inline functions to ease binding */ + +/*! \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); + +/*! \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); -/* set the talloc context for msgb_alloc[_headroom] */ +/*! \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);  #endif /* _MSGB_H */ diff --git a/include/osmocom/core/select.h b/include/osmocom/core/select.h index 476c564e..b1b82672 100644 --- a/include/osmocom/core/select.h +++ b/include/osmocom/core/select.h @@ -3,20 +3,48 @@  #include <osmocom/core/linuxlist.h> +/*! \file select.h + *  \brief select loop abstraction + */ + +/*! \brief Indicate interest in reading from the file descriptor */  #define BSC_FD_READ	0x0001 +/*! \brief Indicate interest in writing to the file descriptor */  #define BSC_FD_WRITE	0x0002 +/*! \brief Indicate interest in exceptions from the file descriptor */  #define BSC_FD_EXCEPT	0x0004 +/*! \brief Structure representing a file dsecriptor */  struct osmo_fd { -	struct llist_head list; +	/*! linked list for internal management */ +	struct llist_head list;	 +	/*! actual operating-system level file decriptor */  	int fd; +	/*! bit-mask or of \ref BSC_FD_READ, \ref BSC_FD_WRITE and/or +	 * \ref BSC_FD_EXCEPT */  	unsigned int when; +	/*! call-back function to be called once file descriptor becomes +	 * available */  	int (*cb)(struct osmo_fd *fd, unsigned int what); +	/*! data pointer passed through to call-back function */  	void *data; +	/*! private number, extending \a data */  	unsigned int priv_nr;  }; +/*! \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); + +/*! \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); + +/*! \brief select main loop integration + *  \param[in] polling should we pollonly (1) or block on select (0) + */  int osmo_select_main(int polling); +  #endif /* _BSC_SELECT_H */ diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index 612b12c8..e915f78d 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -1,6 +1,10 @@  #ifndef _OSMOCORE_SOCKET_H  #define _OSMOCORE_SOCKET_H +/*! \file socket.h + *  \brief Osmocom socket convenience functions + */ +  #include <stdint.h>  struct sockaddr; @@ -10,16 +14,53 @@ struct sockaddr;  #define OSMO_SOCK_F_BIND	(1 << 1)  #define OSMO_SOCK_F_NONBLOCK	(1 << 2) +/*! \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); +/*! \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); +/*! \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); -/* 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, unsigned int addrlen);  #endif /* _OSMOCORE_SOCKET_H */ diff --git a/include/osmocom/core/statistics.h b/include/osmocom/core/statistics.h index 18493277..04816c16 100644 --- a/include/osmocom/core/statistics.h +++ b/include/osmocom/core/statistics.h @@ -1,33 +1,53 @@  #ifndef _STATISTICS_H  #define _STATISTICS_H +/*! \file statistics.h + *  \brief Common routines regarding statistics */ + +/*! structure representing a single counter */  struct osmo_counter { -	struct llist_head list; -	const char *name; -	const char *description; -	unsigned long value; +	struct llist_head list;		/*!< \brief internal list head */ +	const char *name;		/*!< \brief human-readable name */ +	const char *description;	/*!< \brief humn-readable description */ +	unsigned long value;		/*!< \brief current value */  }; +/*! \brief Increment counter */  static inline void osmo_counter_inc(struct osmo_counter *ctr)  {  	ctr->value++;  } +/*! \brief Get current value of counter */  static inline unsigned long osmo_counter_get(struct osmo_counter *ctr)  {  	return ctr->value;  } +/*! \brief Reset current value of counter to 0 */  static inline void osmo_counter_reset(struct osmo_counter *ctr)  {  	ctr->value = 0;  } +/*! \brief Allocate a new counter */  struct osmo_counter *osmo_counter_alloc(const char *name); + +/*! \brief Free the specified counter + *  \param[ctr] Counter + */  void osmo_counter_free(struct osmo_counter *ctr); +/*! \brief Iteate over all counters + *  \param[in] handle_counter Call-back function + *  \param[in] data Private dtata handed through to \a handle_counter + */  int osmo_counters_for_each(int (*handle_counter)(struct osmo_counter *, void *), void *data); +/*! \brief Resolve counter by human-readable name + *  \param[in] name human-readable name of counter + *  \returns pointer to counter (\ref osmo_counter) or NULL otherwise + */  struct osmo_counter *osmo_counter_get_by_name(const char *name);  #endif /* _STATISTICS_H */ diff --git a/include/osmocom/core/timer.h b/include/osmocom/core/timer.h index 6c2e8c50..326a0c88 100644 --- a/include/osmocom/core/timer.h +++ b/include/osmocom/core/timer.h @@ -18,6 +18,10 @@   *   */ +/*! \file timer.h + *  \brief Osmocom timer handling routines + */ +  #ifndef TIMER_H  #define TIMER_H @@ -41,27 +45,58 @@   *        the timers.   *   */ +/*! \brief A structure representing a single instance of a timer */  struct osmo_timer_list { -	struct llist_head entry; -	struct timeval timeout; -	unsigned int active  : 1; -	unsigned int handled : 1; -	unsigned int in_list : 1; +	struct llist_head entry;  /*!< \brief linked list header */ +	struct timeval timeout;   /*!< \brief expiration time */ +	unsigned int active  : 1; /*!< \brief is it active? */ +	unsigned int handled : 1; /*!< \brief did we already handle it */ +	unsigned int in_list : 1; /*!< \brief is it in the global list? */ -	void (*cb)(void*); -	void *data; +	void (*cb)(void*);	  /*!< \brief call-back called at timeout */ +	void *data;		  /*!< \brief user data for callback */  };  /**   * timer management   */ + +/*! \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); + +/*! \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); + +/*! \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); + +/*! \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); -/** +/*   * internal timer list management   */  struct timeval *osmo_timers_nearest(void); diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h index a1a18e30..1e5fab70 100644 --- a/include/osmocom/core/utils.h +++ b/include/osmocom/core/utils.h @@ -1,32 +1,93 @@  #ifndef OSMOCORE_UTIL_H  #define OSMOCORE_UTIL_H +/*! \file utils.h + *  \brief General-purpose utilities in the Osmocom core library + */ + +/*! \brief Determine number of elements in an array of static size */  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/*! \brief Return the maximum of two specified values */  #define OSMO_MAX(a, b) (a) >= (b) ? (a) : (b) +/*! \brief Return the minimum of two specified values */  #define OSMO_MIN(a, b) (a) >= (b) ? (b) : (a)  #include <stdint.h> +/*! \brief A mapping between human-readable string and numeric value */  struct value_string { -	unsigned int value; -	const char *str; +	unsigned int value;	/*!< \brief numeric value */ +	const char *str;	/*!< \brief human-readable string */  }; +/*! \fn get_value_string(const struct value_string *vs, uint32_t val) + * \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); + +/*! \fn get_string_value(const struct value_string *vs, const char *str) + * \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); +/*! \fn osmo_bcd2char(uint8_t bcd) + * \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);  /* only works for numbers in ascci */  uint8_t osmo_char2bcd(char c);  int osmo_hexparse(const char *str, uint8_t *b, int max_len); + +/*! \fn osmo_hexdump(const unsigned char *buf, int len) + * \brief Convert binary sequence to hexadecimal ASCII string + * This function will print a sequence of bytes as hexadecimal numbers, + * adding one space character between each byte (e.g. "1a ef d9") + * \param[in] buf pointer to sequence of bytes + * \param[in] len length of buf in number of bytes + * \returns pointer to zero-terminated string + */  char *osmo_hexdump(const unsigned char *buf, int len); + +/*! \fn osmo_hexdump_nospc(const unsigned char *buf, int len) + * \brief Convert binary sequence to hexadecimal ASCII string + * This function will print a sequence of bytes as hexadecimal numbers, + * without any space character between each byte (e.g. "1aefd9") + * \param[in] buf pointer to sequence of bytes + * \param[in] len length of buf in number of bytes + * \returns pointer to zero-terminated string + */  char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len); + +/*! \fn osmo_ubit_dump(const uint8_t *bits, unsigned int len) + * \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);  #define osmo_static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1]; +/*! \fn osmo_str2lower(char *out, const char *in) + * \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); + +/*! \fn osmo_str2upper(char *out, const char *in) + * \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);  #define OSMO_SNPRINTF_RET(ret, rem, offset, len)		\ diff --git a/include/osmocom/core/write_queue.h b/include/osmocom/core/write_queue.h index 41748d72..373b64ff 100644 --- a/include/osmocom/core/write_queue.h +++ b/include/osmocom/core/write_queue.h @@ -23,24 +23,59 @@  #ifndef OSMO_WQUEUE_H  #define OSMO_WQUEUE_H +/*! \file write_queue.h + *  \brief Osmocom write queues + */ +  #include <osmocom/core/select.h>  #include <osmocom/core/msgb.h> +/*! write queue instance */  struct osmo_wqueue { +	/*! \brief osmocom file descriptor */  	struct osmo_fd bfd; +	/*! \brief maximum length of write queue */  	unsigned int max_length; +	/*! \brief current length of write queue */  	unsigned int current_length; +	/*! \brief actual linked list implementing the queue */  	struct llist_head msg_queue; +	/*! \brief call-back in case qeueue is readable */  	int (*read_cb)(struct osmo_fd *fd); +	/*! \brief call-back in case qeueue is writable */  	int (*write_cb)(struct osmo_fd *fd, struct msgb *msg); +	/*! \brief call-back in case qeueue has exceptions */  	int (*except_cb)(struct osmo_fd *fd);  }; +/*! \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); + +/*! \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); + +/*! \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); + +/*! \brief Select loop function for write queue handling + *  \param[in] fd osmocom file descriptor + *  \param[in] what bit-mas | 
