Merge commit 'ba01fa44feb6deb0f0359f381eafe866991c06c1' into pablo/namespace

This commit is contained in:
Pablo Neira Ayuso 2011-05-15 14:39:08 +02:00
commit 6f9af5945e
48 changed files with 1323 additions and 218 deletions

View File

@ -1,3 +1,9 @@
libosmocore (0.3.0) natty; urgency=low
* New upstream version of libosmocore
-- Harald Welte <laforge@gnumonks.org> Tue, 10 May 2011 17:28:24 +0200
libosmocore (0.1.27) natty; urgency=low
* New upstream version of libosmocore.

View File

@ -1,5 +1,8 @@
usr/lib
usr/include
usr/include/osmocore
usr/include/osmocom
usr/include/osmocom/codec
usr/include/osmocom/core
usr/include/osmocom/crypt
usr/include/osmocom/gsm
usr/include/osmocom/vty

View File

@ -1,5 +1,8 @@
usr/lib
usr/include
usr/include/osmocore
usr/include/osmocom
usr/include/osmocom/codec
usr/include/osmocom/core
usr/include/osmocom/crypt
usr/include/osmocom/gsm
usr/include/osmocom/vty

View File

@ -3,7 +3,7 @@ osmocore_HEADERS = signal.h linuxlist.h timer.h select.h msgb.h bits.h \
gsmtap.h write_queue.h \
logging.h rate_ctr.h gsmtap_util.h \
plugin.h crc16.h panic.h process.h msgfile.h \
backtrace.h
backtrace.h conv.h application.h
if ENABLE_TALLOC
osmocore_HEADERS += talloc.h

View File

@ -0,0 +1,16 @@
#ifndef OSMO_APPLICATION_H
#define OSMO_APPLICATION_H
/**
* Routines for helping with the application setup.
*/
struct log_info;
struct log_target;
extern struct log_target *osmo_stderr_target;
void osmo_init_ignore_signals(void);
int osmo_init_logging(const struct log_info *);
#endif

View File

@ -1,6 +1,6 @@
#ifndef _OSMO_BACKTRACE_H_
#define _OSMO_BACKTRACE_H_
void generate_backtrace();
void osmo_generate_backtrace();
#endif

View File

@ -0,0 +1,101 @@
/*
* conv.h
*
* 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.
*/
#ifndef __OSMO_CONV_H__
#define __OSMO_CONV_H__
#include <stdint.h>
#include <osmocom/core/bits.h>
struct osmo_conv_code {
int N;
int K;
int len;
const uint8_t (*next_output)[2];
const uint8_t (*next_state)[2];
const uint8_t *next_term_output;
const uint8_t *next_term_state;
const int *puncture;
};
/* Encoding */
/* Low level API */
struct osmo_conv_encoder {
const struct osmo_conv_code *code;
int i_idx; /* Next input bit index */
int p_idx; /* Current puncture index */
uint8_t state; /* Current state */
};
void osmo_conv_encode_init(struct osmo_conv_encoder *encoder,
const struct osmo_conv_code *code);
int osmo_conv_encode_raw(struct osmo_conv_encoder *encoder,
const ubit_t *input, ubit_t *output, int n);
int osmo_conv_encode_finish(struct osmo_conv_encoder *encoder, ubit_t *output);
/* All-in-one */
int osmo_conv_encode(const struct osmo_conv_code *code,
const ubit_t *input, ubit_t *output);
/* Decoding */
/* Low level API */
struct osmo_conv_decoder {
const struct osmo_conv_code *code;
int n_states;
int len; /* Max o_idx (excl. termination) */
int o_idx; /* output index */
int p_idx; /* puncture index */
unsigned int *ae; /* accumulater error */
unsigned int *ae_next; /* next accumulated error (tmp in scan) */
uint8_t *state_history; /* state history [len][n_states] */
};
void osmo_conv_decode_init(struct osmo_conv_decoder *decoder,
const struct osmo_conv_code *code, int len);
void osmo_conv_decode_reset(struct osmo_conv_decoder *decoder);
void osmo_conv_decode_deinit(struct osmo_conv_decoder *decoder);
int osmo_conv_decode_scan(struct osmo_conv_decoder *decoder,
const sbit_t *input, int n);
int osmo_conv_decode_finish(struct osmo_conv_decoder *decoder,
const sbit_t *input);
int osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
ubit_t *output, int has_finish);
/* All-in-one */
int osmo_conv_decode(const struct osmo_conv_code *code,
const sbit_t *input, ubit_t *output);
#endif /* __OSMO_CONV_H__ */

View File

@ -22,13 +22,13 @@
#include <sys/types.h>
extern uint16_t const crc16_table[256];
extern uint16_t const osmo_crc16_table[256];
extern uint16_t crc16(uint16_t crc, const uint8_t *buffer, size_t len);
extern uint16_t osmo_crc16(uint16_t crc, const uint8_t *buffer, size_t len);
static inline uint16_t crc16_byte(uint16_t crc, const uint8_t data)
static inline uint16_t osmo_crc16_byte(uint16_t crc, const uint8_t data)
{
return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
return (crc >> 8) ^ osmo_crc16_table[(crc ^ data) & 0xff];
}
#endif /* __CRC16_H */

View File

@ -18,4 +18,8 @@ int gsmtap_sendmsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type, uint8_t ss,
int gsmtap_init(uint32_t dst_ip);
/* Create a local 'gsmtap sink' avoiding the UDP packets being rejected
* with ICMP reject messages */
int gsmtap_sink_init(uint32_t bind_ip);
#endif /* _GSMTAP_UTIL_H */

View File

@ -181,7 +181,7 @@ static inline void msgb_reserve(struct msgb *msg, int len)
static inline struct msgb *msgb_alloc_headroom(int size, int headroom,
const char *name)
{
static_assert(size > headroom, headroom_bigger);
osmo_static_assert(size > headroom, headroom_bigger);
struct msgb *msg = msgb_alloc(size, name);
if (msg)

View File

@ -22,12 +22,12 @@
#ifndef MSG_FILE_H
#define MSG_FILE_H
#include "linuxlist.h"
#include <osmocom/core/linuxlist.h>
/**
* One message in the list.
*/
struct msg_entry {
struct osmo_config_entry {
struct llist_head list;
/* number for everyone to use */
@ -40,10 +40,10 @@ struct msg_entry {
char *text;
};
struct msg_entries {
struct osmo_config_list {
struct llist_head entry;
};
struct msg_entries *msg_entry_parse(void *ctx, const char *filename);
struct osmo_config_list* osmo_config_list_parse(void *ctx, const char *filename);
#endif

View File

@ -5,7 +5,7 @@
typedef void (*osmo_panic_handler_t)(const char *fmt, va_list args);
void osmo_panic(const char *fmt, ...);
void osmo_set_panic_handler(osmo_panic_handler_t h);
extern void osmo_panic(const char *fmt, ...);
extern void osmo_set_panic_handler(osmo_panic_handler_t h);
#endif

View File

@ -1,6 +1,6 @@
#ifndef _OSMO_PLUGIN_H
#define _OSMO_PLUGIN_H
int plugin_load_all(const char *directory);
int osmo_plugin_load_all(const char *directory);
#endif

View File

@ -7,16 +7,16 @@
#define BSC_FD_WRITE 0x0002
#define BSC_FD_EXCEPT 0x0004
struct bsc_fd {
struct osmo_fd {
struct llist_head list;
int fd;
unsigned int when;
int (*cb)(struct bsc_fd *fd, unsigned int what);
int (*cb)(struct osmo_fd *fd, unsigned int what);
void *data;
unsigned int priv_nr;
};
int bsc_register_fd(struct bsc_fd *fd);
void bsc_unregister_fd(struct bsc_fd *fd);
int bsc_select_main(int polling);
int osmo_fd_register(struct osmo_fd *fd);
void osmo_fd_unregister(struct osmo_fd *fd);
int osmo_select_main(int polling);
#endif /* _BSC_SELECT_H */

View File

@ -1,15 +1,14 @@
#ifndef OSMOCORE_SIGNAL_H
#define OSMOCORE_SIGNAL_H
#ifndef OSMO_SIGNAL_H
#define OSMO_SIGNAL_H
typedef int signal_cbfn(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data);
typedef int osmo_signal_cbfn(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data);
/* Management */
int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
int osmo_signal_register_handler(unsigned int subsys, osmo_signal_cbfn *cbfn, void *data);
void osmo_signal_unregister_handler(unsigned int subsys, osmo_signal_cbfn *cbfn, void *data);
/* Dispatch */
void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data);
void osmo_signal_dispatch(unsigned int subsys, unsigned int signal, void *signal_data);
#endif /* OSMOCORE_SIGNAL_H */
#endif /* OSMO_SIGNAL_H */

View File

@ -1,33 +1,33 @@
#ifndef _STATISTICS_H
#define _STATISTICS_H
struct counter {
struct osmo_counter {
struct llist_head list;
const char *name;
const char *description;
unsigned long value;
};
static inline void counter_inc(struct counter *ctr)
static inline void osmo_counter_inc(struct osmo_counter *ctr)
{
ctr->value++;
}
static inline unsigned long counter_get(struct counter *ctr)
static inline unsigned long osmo_counter_get(struct osmo_counter *ctr)
{
return ctr->value;
}
static inline void counter_reset(struct counter *ctr)
static inline void osmo_counter_reset(struct osmo_counter *ctr)
{
ctr->value = 0;
}
struct counter *counter_alloc(const char *name);
void counter_free(struct counter *ctr);
struct osmo_counter *osmo_counter_alloc(const char *name);
void osmo_counter_free(struct osmo_counter *ctr);
int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data);
int osmo_counters_for_each(int (*handle_counter)(struct osmo_counter *, void *), void *data);
struct counter *counter_get_by_name(const char *name);
struct osmo_counter *osmo_counter_get_by_name(const char *name);
#endif /* _STATISTICS_H */

View File

@ -27,7 +27,7 @@
/**
* Timer management:
* - Create a struct timer_list
* - Create a struct osmo_timer_list
* - Fill out timeout and use add_timer or
* use schedule_timer to schedule a timer in
* x seconds and microseconds from now...
@ -41,7 +41,7 @@
* the timers.
*
*/
struct timer_list {
struct osmo_timer_list {
struct llist_head entry;
struct timeval timeout;
unsigned int active : 1;
@ -55,18 +55,18 @@ struct timer_list {
/**
* timer management
*/
void bsc_add_timer(struct timer_list *timer);
void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds);
void bsc_del_timer(struct timer_list *timer);
int bsc_timer_pending(struct timer_list *timer);
void osmo_timer_add(struct osmo_timer_list *timer);
void osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds);
void osmo_timer_del(struct osmo_timer_list *timer);
int osmo_timer_pending(struct osmo_timer_list *timer);
/**
* internal timer list management
*/
struct timeval *bsc_nearest_timer();
void bsc_prepare_timers();
int bsc_update_timers();
int bsc_timer_check(void);
struct timeval *osmo_timers_nearest();
void osmo_timers_prepare();
int osmo_timers_update();
int osmo_timers_check(void);
#endif

View File

@ -13,16 +13,16 @@ struct value_string {
const char *get_value_string(const struct value_string *vs, uint32_t val);
int get_string_value(const struct value_string *vs, const char *str);
char bcd2char(uint8_t bcd);
char osmo_bcd2char(uint8_t bcd);
/* only works for numbers in ascci */
uint8_t char2bcd(char c);
uint8_t osmo_char2bcd(char c);
int hexparse(const char *str, uint8_t *b, int max_len);
char *hexdump(const unsigned char *buf, int len);
char *hexdump_nospc(const unsigned char *buf, int len);
char *ubit_dump(const uint8_t *bits, unsigned int len);
int osmo_hexparse(const char *str, uint8_t *b, int max_len);
char *osmo_hexdump(const unsigned char *buf, int len);
char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len);
char *osmo_ubit_dump(const uint8_t *bits, unsigned int len);
#define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
#define osmo_static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
void osmo_str2lower(char *out, const char *in);
void osmo_str2upper(char *out, const char *in);

View File

@ -20,27 +20,27 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef write_queue_h
#define write_queue_h
#ifndef OSMO_WQUEUE_H
#define OSMO_WQUEUE_H
#include <osmocom/core/select.h>
#include <osmocom/core/msgb.h>
struct write_queue {
struct bsc_fd bfd;
struct osmo_wqueue {
struct osmo_fd bfd;
unsigned int max_length;
unsigned int current_length;
struct llist_head msg_queue;
int (*read_cb)(struct bsc_fd *fd);
int (*write_cb)(struct bsc_fd *fd, struct msgb *msg);
int (*except_cb)(struct bsc_fd *fd);
int (*read_cb)(struct osmo_fd *fd);
int (*write_cb)(struct osmo_fd *fd, struct msgb *msg);
int (*except_cb)(struct osmo_fd *fd);
};
void write_queue_init(struct write_queue *queue, int max_length);
void write_queue_clear(struct write_queue *queue);
int write_queue_enqueue(struct write_queue *queue, struct msgb *data);
int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what);
void osmo_wqueue_init(struct osmo_wqueue *queue, int max_length);
void osmo_wqueue_clear(struct osmo_wqueue *queue);
int osmo_wqueue_enqueue(struct osmo_wqueue *queue, struct msgb *data);
int osmo_wqueue_bfd_cb(struct osmo_fd *fd, unsigned int what);
#endif

View File

@ -1,4 +1,4 @@
osmogsm_HEADERS = comp128.h gsm0808.h gsm48_ie.h mncc.h rxlev_stat.h \
osmogsm_HEADERS = a5.h comp128.h gsm0808.h gsm48_ie.h mncc.h rxlev_stat.h \
gsm0480.h gsm48.h gsm_utils.h rsl.h tlv.h
SUBDIRS = protocol

View File

@ -0,0 +1,49 @@
/*
* a5.h
*
* 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.
*/
#ifndef __OSMO_A5_H__
#define __OSMO_A5_H__
#include <stdint.h>
#include <osmocom/core/bits.h>
static inline uint32_t
osmo_a5_fn_count(uint32_t fn)
{
int t1 = fn / (26 * 51);
int t2 = fn % 26;
int t3 = fn % 51;
return (t1 << 11) | (t3 << 5) | t2;
}
/* Notes:
* - key must be 8 bytes long (or NULL for A5/0)
* - the dl and ul pointer must be either NULL or 114 bits long
* - fn is the _real_ GSM frame number.
* (converted internally to fn_count)
*/
void osmo_a5(int n, uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
void osmo_a5_1(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
void osmo_a5_2(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
#endif /* __OSMO_A5_H__ */

View File

@ -29,7 +29,7 @@
struct telnet_connection {
struct llist_head entry;
void *priv;
struct bsc_fd fd;
struct osmo_fd fd;
struct vty *vty;
struct log_target *dbg;
};

View File

@ -2,7 +2,7 @@ SUBDIRS=. vty codec gsm
# This is _NOT_ the library release version, it's an API version.
# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
LIBVERSION=0:0:0
LIBVERSION=1:0:1
INCLUDES = $(all_includes) -I$(top_srcdir)/include
AM_CFLAGS = -fPIC -Wall
@ -14,11 +14,13 @@ libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c bits.c \
write_queue.c utils.c \
logging.c logging_syslog.c rate_ctr.c \
gsmtap_util.c crc16.c panic.c backtrace.c \
process.c
process.c conv.c application.c
if ENABLE_PLUGIN
libosmocore_la_SOURCES += plugin.c
libosmocore_la_LDFLAGS = -ldl
libosmocore_la_LDFLAGS = -version-info $(LIBVERSION) -ldl
else
libosmocore_la_LDFLAGS = -version-info $(LIBVERSION)
endif
if ENABLE_TALLOC

View File

@ -0,0 +1,49 @@
/* Utility functions to setup applications */
/*
* (C) 2011 by Holger Hans Peter Freyther
*
* 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.
*
*/
#include <osmocom/core/application.h>
#include <osmocom/core/logging.h>
#include <signal.h>
struct log_target *osmo_stderr_target;
void osmo_init_ignore_signals(void)
{
/* Signals that by default would terminate */
signal(SIGPIPE, SIG_IGN);
signal(SIGALRM, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGIO, SIG_IGN);
}
int osmo_init_logging(const struct log_info *log_info)
{
log_init(log_info);
osmo_stderr_target = log_target_create_stderr();
if (!osmo_stderr_target)
return -1;
log_add_target(osmo_stderr_target);
log_set_all_filter(osmo_stderr_target, 1);
return 0;
}

View File

@ -29,7 +29,7 @@
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
void generate_backtrace()
void osmo_generate_backtrace()
{
int i, nptrs;
void *buffer[100];

View File

@ -8,3 +8,4 @@ AM_CFLAGS = -fPIC -Wall
lib_LTLIBRARIES = libosmocodec.la
libosmocodec_la_SOURCES = gsm610.c gsm620.c gsm660.c gsm690.c
libosmocodec_la_LDFALGS = -version-info $(LIBVERSION)

View File

@ -0,0 +1,496 @@
/*
* conv.c
*
* Generic convolutional encoding / decoding
*
* 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.
*/
#include <alloca.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <osmocom/core/bits.h>
#include <osmocom/core/conv.h>
/* ------------------------------------------------------------------------ */
/* Encoding */
/* ------------------------------------------------------------------------ */
void
osmo_conv_encode_init(struct osmo_conv_encoder *encoder,
const struct osmo_conv_code *code)
{
memset(encoder, 0x00, sizeof(struct osmo_conv_encoder));
encoder->code = code;
}
static inline int
_conv_encode_do_output(struct osmo_conv_encoder *encoder,
uint8_t out, ubit_t *output)
{
const struct osmo_conv_code *code = encoder->code;
int o_idx = 0;
int j;
if (code->puncture) {
for (j=0; j<code->N; j++)
{
int bit_no = code->N - j - 1;
int r_idx = encoder->i_idx * code->N + j;
if (code->puncture[encoder->p_idx] == r_idx)
encoder->p_idx++;
else
output[o_idx++] = (out >> bit_no) & 1;
}
} else {
for (j=0; j<code->N; j++)
{
int bit_no = code->N - j - 1;
output[o_idx++] = (out >> bit_no) & 1;
}
}
return o_idx;
}
int
osmo_conv_encode_raw(struct osmo_conv_encoder *encoder,
const ubit_t *input, ubit_t *output, int n)
{
const struct osmo_conv_code *code = encoder->code;
uint8_t state;
int i;
int o_idx;
o_idx = 0;
state = encoder->state;
for (i=0; i<n; i++) {
int bit = input[i];
uint8_t out;
out = code->next_output[state][bit];
state = code->next_state[state][bit];
o_idx += _conv_encode_do_output(encoder, out, &output[o_idx]);
encoder->i_idx++;
}
encoder->state = state;
return o_idx;
}
int
osmo_conv_encode_finish(struct osmo_conv_encoder *encoder,
ubit_t *output)
{
const struct osmo_conv_code *code = encoder->code;
uint8_t state;
int n;
int i;
int o_idx;
n = code->K - 1;
o_idx = 0;
state = encoder->state;
for (i=0; i<n; i++) {
uint8_t out;
if (code->next_term_output) {
out = code->next_term_output[state];
state = code->next_term_state[state];
} else {
out = code->next_output[state][0];
state = code->next_state[state][0];
}
o_idx += _conv_encode_do_output(encoder, out, &output[o_idx]);
encoder->i_idx++;
}
encoder->state = state;
return o_idx;
}
int
osmo_conv_encode(const struct osmo_conv_code *code,
const ubit_t *input, ubit_t *output)
{
struct osmo_conv_encoder encoder;
int l;
osmo_conv_encode_init(&encoder, code);
l = osmo_conv_encode_raw(&encoder, input, output, code->len);
l += osmo_conv_encode_finish(&encoder, &output[l]);
return l;
}
/* ------------------------------------------------------------------------ */
/* Decoding (viterbi) */
/* ------------------------------------------------------------------------ */
#define MAX_AE 0x00ffffff
void
osmo_conv_decode_init(struct osmo_conv_decoder *decoder,
const struct osmo_conv_code *code, int len)
{
int n_states;
/* Init */
if (len <= 0)
len = code->len;
n_states = 1 << (code->K - 1);
memset(decoder, 0x00, sizeof(struct osmo_conv_decoder));
decoder->code = code;
decoder->n_states = n_states;
decoder->len = len;
/* Allocate arrays */
decoder->ae = malloc(sizeof(unsigned int) * n_states);
decoder->ae_next = malloc(sizeof(unsigned int) * n_states);
decoder->state_history = malloc(sizeof(uint8_t) * n_states * (len + decoder->code->K - 1));
/* Classic reset */
osmo_conv_decode_reset(decoder);
}
void
osmo_conv_decode_reset(struct osmo_conv_decoder *decoder)
{
int i;
/* Reset indexes */
decoder->o_idx = 0;
decoder->p_idx = 0;
/* Initial error (only state 0 is valid) */
decoder->ae[0] = 0;
for (i=1; i<decoder->n_states; i++) {
decoder->ae[i] = MAX_AE;
}
}
void
osmo_conv_decode_deinit(struct osmo_conv_decoder *decoder)
{
free(decoder->ae);
free(decoder->ae_next);
free(decoder->state_history);
memset(decoder, 0x00, sizeof(struct osmo_conv_decoder));
}
int
osmo_conv_decode_scan(struct osmo_conv_decoder *decoder,
const sbit_t *input, int n)
{
const struct osmo_conv_code *code = decoder->code;
int i, s, b, j;
int n_states;
unsigned int *ae;
unsigned int *ae_next;
uint8_t *state_history;
sbit_t *in_sym;
int i_idx, p_idx;
/* Prepare */
n_states = decoder->n_states;
ae = decoder->ae;
ae_next = decoder->ae_next;
state_history = &decoder->state_history[n_states * decoder->o_idx];
in_sym = alloca(sizeof(sbit_t) * code->N);
i_idx = 0;
p_idx = decoder->p_idx;
/* Scan the treillis */
for (i=0; i<n; i++)
{
/* Reset next accumulated error */
for (s=0; s<n_states; s++) {
ae_next[s] = MAX_AE;
}
/* Get input */
if (code->puncture) {
/* Hard way ... */
for (j=0; j<code->N; j++) {
int idx = ((decoder->o_idx + i) * code->N) + j;
if (idx == code->puncture[p_idx]) {
in_sym[j] = 0; /* Undefined */
p_idx++;
} else {
in_sym[j] = input[i_idx];
i_idx++;
}
}
} else {
/* Easy, just copy N bits */
memcpy(in_sym, &input[i_idx], code->N);
i_idx += code->N;
}
/* Scan all state */
for (s=0; s<n_states; s++)
{
/* Scan possible input bits */
for (b=0; b<2; b++)
{
int nae, ov, e;
uint8_t m;
/* Next output and state */
uint8_t out = code->next_output[s][b];
uint8_t state = code->next_state[s][b];
/* New error for this path */
nae = ae[s]; /* start from last error */
m = 1 << (code->N - 1); /* mask for 'out' bit selection */
for (j=0; j<code->N; j++) {
ov = (out & m) ? -127 : 127; /* sbit_t value for it */
e = ((int)in_sym[j]) - ov; /* raw error for this bit */
nae += (e * e) >> 9; /* acc the squared/scaled value */
m >>= 1; /* next mask bit */
}
/* Is it survivor ? */
if (ae_next[state] > nae) {
ae_next[state] = nae;
state_history[(n_states * i) + state] = s;
}
}
}
/* Copy accumulated error */
memcpy(ae, ae_next, sizeof(unsigned int) * n_states);
}
/* Update decoder state */
decoder->p_idx = p_idx;
decoder->o_idx += n;
return i_idx;
}
int
osmo_conv_decode_finish(struct osmo_conv_decoder *decoder,
const sbit_t *input)
{
const struct osmo_conv_code *code = decoder->code;
int i, s, j;
int n_states;
unsigned int *ae;
unsigned int *ae_next;
uint8_t *state_history;
sbit_t *in_sym;
int i_idx, p_idx;
/* Prepare */
n_states = decoder->n_states;
ae = decoder->ae;
ae_next = decoder->ae_next;
state_history = &decoder->state_history[n_states * decoder->o_idx];
in_sym = alloca(sizeof(sbit_t) * code->N);
i_idx = 0;
p_idx = decoder->p_idx;
/* Scan the treillis */
for (i=0; i<code->K-1; i++)
{
/* Reset next accumulated error */
for (s=0; s<n_states; s++) {
ae_next[s] = MAX_AE;
}
/* Get input */
if (code->puncture) {
/* Hard way ... */
for (j=0; j<code->N; j++) {
int idx = ((decoder->o_idx + i) * code->N) + j;
if (idx == code->puncture[p_idx]) {
in_sym[j] = 0; /* Undefined */
p_idx++;
} else {
in_sym[j] = input[i_idx];
i_idx++;
}
}
} else {
/* Easy, just copy N bits */
memcpy(in_sym, &input[i_idx], code->N);
i_idx += code->N;
}
/* Scan all state */
for (s=0; s<n_states; s++)
{
int nae, ov, e;
uint8_t m;
/* Next output and state */
uint8_t out;
uint8_t state;
if (code->next_term_output) {
out = code->next_term_output[s];
state = code->next_term_state[s];
} else {
out = code->next_output[s][0];
state = code->next_state[s][0];
}
/* New error for this path */
nae = ae[s]; /* start from last error */
m = 1 << (code->N - 1); /* mask for 'out' bit selection */
for (j=0; j<code->N; j++) {
int is = (int)in_sym[j];
if (is) {
ov = (out & m) ? -127 : 127; /* sbit_t value for it */
e = is - ov; /* raw error for this bit */
nae += (e * e) >> 9; /* acc the squared/scaled value */
}
m >>= 1; /* next mask bit */
}
/* Is it survivor ? */
if (ae_next[state] > nae) {
ae_next[state] = nae;
state_history[(n_states * i) + state] = s;
}
}
/* Copy accumulated error */
memcpy(ae, ae_next, sizeof(unsigned int) * n_states);
}
/* Update decoder state */
decoder->p_idx = p_idx;
decoder->o_idx += code->K - 1;
return i_idx;
}
int
osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
ubit_t *output, int has_finish)
{
const struct osmo_conv_code *code = decoder->code;
int min_ae;
uint8_t min_state, cur_state;
int i, s, n;
uint8_t *sh_ptr;
/* Find state with least error */
min_ae = MAX_AE;
min_state = 0xff;
for (s=0; s<decoder->n_states; s++)
{
if (decoder->ae[s] < min_ae) {
min_ae = decoder->ae[s];
min_state = s;
}
}
if (min_state == 0xff)
return -1;
/* Traceback */
cur_state = min_state;
n = decoder->o_idx;
sh_ptr = &decoder->state_history[decoder->n_states * (n-1)];
/* No output for the K-1 termination input bits */
if (has_finish) {
for (i=0; i<code->K-1; i++) {
cur_state = sh_ptr[cur_state];
sh_ptr -= decoder->n_states;
}
n -= code->K - 1;
}
/* Generate output backward */
for (i=n-1; i>=0; i--)
{
min_state = cur_state;
cur_state = sh_ptr[cur_state];
sh_ptr -= decoder->n_states;
if (code->next_state[cur_state][0] == min_state)
output[i] = 0;
else
output[i] = 1;
}
return min_ae;
}
int
osmo_conv_decode(const struct osmo_conv_code *code,
const sbit_t *input, ubit_t *output)
{
struct osmo_conv_decoder decoder;
int rv, l;
osmo_conv_decode_init(&decoder, code, 0);
l = osmo_conv_decode_scan(&decoder, input, code->len);
l = osmo_conv_decode_finish(&decoder, &input[l]);
rv = osmo_conv_decode_get_output(&decoder, output, 1);
osmo_conv_decode_deinit(&decoder);
return rv;
}

View File

@ -11,7 +11,7 @@
#include <osmocom/core/crc16.h>
/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
uint16_t const crc16_table[256] = {
uint16_t const osmo_crc16_table[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
@ -54,9 +54,9 @@ uint16_t const crc16_table[256] = {
*
* Returns the updated CRC value.
*/
uint16_t crc16(uint16_t crc, uint8_t const *buffer, size_t len)
uint16_t osmo_crc16(uint16_t crc, uint8_t const *buffer, size_t len)
{
while (len--)
crc = crc16_byte(crc, *buffer++);
crc = osmo_crc16_byte(crc, *buffer++);
return crc;
}

View File

@ -7,7 +7,8 @@ AM_CFLAGS = -fPIC -Wall
lib_LTLIBRARIES = libosmogsm.la
libosmogsm_la_SOURCES = rxlev_stat.c tlv_parser.c comp128.c gsm_utils.c \
libosmogsm_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c gsm_utils.c \
rsl.c gsm48.c gsm48_ie.c gsm0808.c \
gprs_cipher_core.c gsm0480.c
libosmogsm_la_LDFLAGS = -version-info $(LIBVERSION)
libosmogsm_la_LIBADD = $(top_builddir)/src/libosmocore.la

View File

@ -0,0 +1,311 @@
/*
* a5.c
*
* Full reimplementation of A5/1,2 (split and threadsafe)
*
* The logic behind the algorithm is taken from "A pedagogical implementation
* of the GSM A5/1 and A5/2 "voice privacy" encryption algorithms." by
* Marc Briceno, Ian Goldberg, and David Wagner.
*
* 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.
*/
#include <string.h>
#include <osmocom/gsm/a5.h>
void
osmo_a5(int n, uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
{
switch (n)
{
case 0:
if (dl)
memset(dl, 0x00, 114);
if (ul)
memset(ul, 0x00, 114);
break;
case 1:
osmo_a5_1(key, fn, dl, ul);
break;
case 2:
osmo_a5_2(key, fn, dl, ul);
break;
default:
/* a5/[3..7] not supported here/yet */
break;
}
}
/* ------------------------------------------------------------------------ */
/* A5/1&2 common stuff */
/* ------------------------------------------------------------------------ */
#define A5_R1_LEN 19
#define A5_R2_LEN 22
#define A5_R3_LEN 23
#define A5_R4_LEN 17 /* A5/2 only */
#define A5_R1_MASK ((1<<A5_R1_LEN)-1)
#define A5_R2_MASK ((1<<A5_R2_LEN)-1)
#define A5_R3_MASK ((1<<A5_R3_LEN)-1)
#define A5_R4_MASK ((1<<A5_R4_LEN)-1)
#define A5_R1_TAPS 0x072000 /* x^19 + x^5 + x^2 + x + 1 */
#define A5_R2_TAPS 0x300000 /* x^22 + x + 1 */
#define A5_R3_TAPS 0x700080 /* x^23 + x^15 + x^2 + x + 1 */
#define A5_R4_TAPS 0x010800 /* x^17 + x^5 + 1 */
static inline uint32_t
_a5_12_parity(uint32_t x)
{
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return x & 1;
}
static inline uint32_t
_a5_12_majority(uint32_t v1, uint32_t v2, uint32_t v3)
{
return (!!v1 + !!v2 + !!v3) >= 2;
}
static inline uint32_t
_a5_12_clock(uint32_t r, uint32_t mask, uint32_t taps)
{
return ((r << 1) & mask) | _a5_12_parity(r & taps);
}
/* ------------------------------------------------------------------------ */
/* A5/1 */
/* ------------------------------------------------------------------------ */
#define A51_R1_CLKBIT 0x000100
#define A51_R2_CLKBIT 0x000400
#define A51_R3_CLKBIT 0x000400
static inline void
_a5_1_clock(uint32_t r[], int force)
{
int cb[3], maj;
cb[0] = !!(r[0] & A51_R1_CLKBIT);
cb[1] = !!(r[1] & A51_R2_CLKBIT);
cb[2] = !!(r[2] & A51_R3_CLKBIT);
maj = _a5_12_majority(cb[0], cb[1], cb[2]);
if (force || (maj == cb[0]))
r[0] = _a5_12_clock(r[0], A5_R1_MASK, A5_R1_TAPS);
if (force || (maj == cb[1]))
r[1] = _a5_12_clock(r[1], A5_R2_MASK, A5_R2_TAPS);
if (force || (maj == cb[2]))
r[2] = _a5_12_clock(r[2], A5_R3_MASK, A5_R3_TAPS);
}
static inline uint8_t
_a5_1_get_output(uint32_t r[])
{
return (r[0] >> (A5_R1_LEN-1)) ^
(r[1] >> (A5_R2_LEN-1)) ^
(r[2] >> (A5_R3_LEN-1));
}
void
osmo_a5_1(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
{
uint32_t r[3] = {0, 0, 0};
uint32_t fn_count;
uint32_t b;
int i;
/* Key load */
for (i=0; i<64; i++)
{
b = ( key[7 - (i>>3)] >> (i&7) ) & 1;
_a5_1_clock(r, 1);
r[0] ^= b;
r[1] ^= b;
r[2] ^= b;
}
/* Frame count load */
fn_count = osmo_a5_fn_count(fn);
for (i=0; i<22; i++)
{
b = (fn_count >> i) & 1;
_a5_1_clock(r, 1);
r[0] ^= b;
r[1] ^= b;
r[2] ^= b;
}
/* Mix */
for (i=0; i<100; i++)
{
_a5_1_clock(r, 0);
}
/* Output */
for (i=0; i<114; i++) {
_a5_1_clock(r, 0);
if (dl)
dl[i] = _a5_1_get_output(r);
}
for (i=0; i<114; i++) {
_a5_1_clock(r, 0);
if (ul)
ul[i] = _a5_1_get_output(r);
}
}
/* ------------------------------------------------------------------------ */
/* A5/2 */
/* ------------------------------------------------------------------------ */
#define A52_R4_CLKBIT0 0x000400
#define A52_R4_CLKBIT1 0x000008
#define A52_R4_CLKBIT2 0x000080
static inline void
_a5_2_clock(uint32_t r[], int force)
{
int cb[3], maj;
cb[0] = !!(r[3] & A52_R4_CLKBIT0);
cb[1] = !!(r[3] & A52_R4_CLKBIT1);
cb[2] = !!(r[3] & A52_R4_CLKBIT2);
maj = (cb[0] + cb[1] + cb[2]) >= 2;
if (force || (maj == cb[0]))
r[0] = _a5_12_clock(r[0], A5_R1_MASK, A5_R1_TAPS);
if (force || (maj == cb[1]))
r[1] = _a5_12_clock(r[1], A5_R2_MASK, A5_R2_TAPS);
if (force || (maj == cb[2]))
r[2] = _a5_12_clock(r[2], A5_R3_MASK, A5_R3_TAPS);
r[3] = _a5_12_clock(r[3], A5_R4_MASK, A5_R4_TAPS);
}
static inline uint8_t
_a5_2_get_output(uint32_t r[], uint8_t *db)
{
uint8_t cb, tb;
tb = (r[0] >> (A5_R1_LEN-1)) ^
(r[1] >> (A5_R2_LEN-1)) ^
(r[2] >> (A5_R3_LEN-1));
cb = *db;
*db = ( tb ^
_a5_12_majority( r[0] & 0x08000, ~r[0] & 0x04000, r[0] & 0x1000) ^
_a5_12_majority(~r[1] & 0x10000, r[1] & 0x02000, r[1] & 0x0200) ^
_a5_12_majority( r[2] & 0x40000, r[2] & 0x10000, ~r[2] & 0x2000)
);
return cb;
}
void
osmo_a5_2(uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
{
uint32_t r[4] = {0, 0, 0, 0};
uint32_t fn_count;
uint32_t b;
uint8_t db = 0, o;
int i;
/* Key load */
for (i=0; i<64; i++)
{
b = ( key[7 - (i>>3)] >> (i&7) ) & 1;
_a5_2_clock(r, 1);
r[0] ^= b;
r[1] ^= b;
r[2] ^= b;
r[3] ^= b;
}
/* Frame count load */
fn_count = osmo_a5_fn_count(fn);
for (i=0; i<22; i++)
{
b = (fn_count >> i) & 1;
_a5_2_clock(r, 1);
r[0] ^= b;
r[1] ^= b;
r[2] ^= b;
r[3] ^= b;
}
r[0] |= 1 << 15;
r[1] |= 1 << 16;
r[2] |= 1 << 18;
r[3] |= 1 << 10;
/* Mix */
for (i=0; i<100; i++)
{
_a5_2_clock(r, 0);
}
_a5_2_get_output(r, &db);
/* Output */
for (i=0; i<114; i++) {
_a5_2_clock(r, 0);
o = _a5_2_get_output(r, &db);
if (dl)
dl[i] = o;
}
for (i=0; i<114; i++) {
_a5_2_clock(r, 0);
o = _a5_2_get_output(r, &db);
if (ul)
ul[i] = o;
}
}

View File

@ -53,7 +53,7 @@ int gprs_cipher_register(struct gprs_cipher_impl *ciph)
int gprs_cipher_load(const char *path)
{
/* load all plugins available from path */
return plugin_load_all(path);
return osmo_plugin_load_all(path);
}
/* function to be called by core code */

View File

@ -301,7 +301,7 @@ int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi)
uint8_t odd = (length & 0x1) == 1;
buf[0] = GSM48_IE_MOBILE_ID;
buf[2] = char2bcd(imsi[0]) << 4 | GSM_MI_TYPE_IMSI | (odd << 3);
buf[2] = osmo_char2bcd(imsi[0]) << 4 | GSM_MI_TYPE_IMSI | (odd << 3);
/* if the length is even we will fill half of the last octet */
if (odd)
@ -312,11 +312,11 @@ int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi)
for (i = 1; i < buf[1]; ++i) {
uint8_t lower, upper;
lower = char2bcd(imsi[++off]);
lower = osmo_char2bcd(imsi[++off]);
if (!odd && off + 1 == length)
upper = 0x0f;
else
upper = char2bcd(imsi[++off]) & 0x0f;
upper = osmo_char2bcd(imsi[++off]) & 0x0f;
buf[2 + i] = (upper << 4) | lower;
}
@ -349,15 +349,15 @@ int gsm48_mi_to_string(char *string, const int str_len, const uint8_t *mi,
case GSM_MI_TYPE_IMSI:
case GSM_MI_TYPE_IMEI:
case GSM_MI_TYPE_IMEISV:
*str_cur++ = bcd2char(mi[0] >> 4);
*str_cur++ = osmo_bcd2char(mi[0] >> 4);
for (i = 1; i < mi_len; i++) {
if (str_cur + 2 >= string + str_len)
return str_cur - string;
*str_cur++ = bcd2char(mi[i] & 0xf);
*str_cur++ = osmo_bcd2char(mi[i] & 0xf);
/* skip last nibble in last input byte when GSM_EVEN */
if( (i != mi_len-1) || (mi[0] & GSM_MI_ODD))
*str_cur++ = bcd2char(mi[i] >> 4);
*str_cur++ = osmo_bcd2char(mi[i] >> 4);
}
break;
default:

View File

@ -42,7 +42,8 @@
#include <string.h>
#include <errno.h>
static struct bsc_fd gsmtap_bfd = { .fd = -1 };
static struct osmo_fd gsmtap_bfd = { .fd = -1 };
static struct osmo_fd gsmtap_sink_bfd = { .fd = -1 };
static LLIST_HEAD(gsmtap_txqueue);
uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t link_id)
@ -136,7 +137,7 @@ int gsmtap_sendmsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type, uint8_t ss,
}
/* Callback from select layer if we can write to the socket */
static int gsmtap_fd_cb(struct bsc_fd *fd, unsigned int flags)
static int gsmtap_fd_cb(struct osmo_fd *fd, unsigned int flags)
{
struct msgb *msg;
int rc;
@ -175,7 +176,7 @@ int gsmtap_init(uint32_t dst_ip)
sin.sin_port = htons(GSMTAP_UDP_PORT);
sin.sin_addr.s_addr = htonl(dst_ip);
/* FIXME: create socket */
/* create socket */
rc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (rc < 0) {
perror("creating UDP socket");
@ -186,7 +187,7 @@ int gsmtap_init(uint32_t dst_ip)
if (rc < 0) {
perror("connecting UDP socket");
close(gsmtap_bfd.fd);
gsmtap_bfd.fd = 0;
gsmtap_bfd.fd = -1;
return rc;
}
@ -194,7 +195,59 @@ int gsmtap_init(uint32_t dst_ip)
gsmtap_bfd.cb = gsmtap_fd_cb;
gsmtap_bfd.data = NULL;
return bsc_register_fd(&gsmtap_bfd);
return osmo_fd_register(&gsmtap_bfd);
}
/* Callback from select layer if we can read from the sink socket */
static int gsmtap_sink_fd_cb(struct osmo_fd *fd, unsigned int flags)
{
int rc;
uint8_t buf[4096];
if (!(flags & BSC_FD_READ))
return 0;
rc = read(fd->fd, buf, sizeof(buf));
if (rc < 0) {
perror("reading from gsmtap sink fd");
return rc;
}
/* simply discard any data arriving on the socket */
return 0;
}
/* Create a local 'gsmtap sink' avoiding the UDP packets being rejected
* with ICMP reject messages */
int gsmtap_sink_init(uint32_t bind_ip)
{
int rc;
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(GSMTAP_UDP_PORT);
sin.sin_addr.s_addr = htonl(bind_ip);
rc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (rc < 0) {
perror("creating UDP socket");
return rc;
}
gsmtap_sink_bfd.fd = rc;
rc = bind(rc, (struct sockaddr *)&sin, sizeof(sin));
if (rc < 0) {
perror("binding UDP socket");
close(gsmtap_sink_bfd.fd);
gsmtap_sink_bfd.fd = -1;
return rc;
}
gsmtap_sink_bfd.when = BSC_FD_READ;
gsmtap_sink_bfd.cb = gsmtap_sink_fd_cb;
gsmtap_sink_bfd.data = NULL;
return osmo_fd_register(&gsmtap_sink_bfd);
}
#endif /* HAVE_SYS_SELECT_H */

View File

@ -143,29 +143,19 @@ static void _output(struct log_target *target, unsigned int subsys,
unsigned int level, char *file, int line, int cont,
const char *format, va_list ap)
{
char col[30];
char sub[30];
char tim[30];
char buf[4096];
char final[4096];
/* prepare the data */
col[0] = '\0';
sub[0] = '\0';
tim[0] = '\0';
buf[0] = '\0';
int ret, len = 0, offset = 0, rem = sizeof(buf);
/* are we using color */
if (target->use_color) {
const char *c = color(subsys);
if (c) {
snprintf(col, sizeof(col), "%s", color(subsys));
col[sizeof(col)-1] = '\0';
ret = snprintf(buf + offset, rem, "%s", color(subsys));
if (ret < 0)
goto err;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
}
}
vsnprintf(buf, sizeof(buf), format, ap);
buf[sizeof(buf)-1] = '\0';
if (!cont) {
if (target->print_timestamp) {
char *timestr;
@ -173,17 +163,30 @@ static void _output(struct log_target *target, unsigned int subsys,
tm = time(NULL);
timestr = ctime(&tm);
timestr[strlen(timestr)-1] = '\0';
snprintf(tim, sizeof(tim), "%s ", timestr);
tim[sizeof(tim)-1] = '\0';
ret = snprintf(buf + offset, rem, "%s ", timestr);
if (ret < 0)
goto err;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
}
snprintf(sub, sizeof(sub), "<%4.4x> %s:%d ", subsys, file, line);
sub[sizeof(sub)-1] = '\0';
ret = snprintf(buf + offset, rem, "<%4.4x> %s:%d ",
subsys, file, line);
if (ret < 0)
goto err;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
}
ret = vsnprintf(buf + offset, rem, format, ap);
if (ret < 0)
goto err;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
snprintf(final, sizeof(final), "%s%s%s%s%s", col, tim, sub, buf,
target->use_color ? "\033[0;m" : "");
final[sizeof(final)-1] = '\0';
target->output(target, level, final);
ret = snprintf(buf + offset, rem, "%s",
target->use_color ? "\033[0;m" : "");
if (ret < 0)
goto err;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
err:
buf[sizeof(buf)-1] = '\0';
target->output(target, level, buf);
}
@ -218,19 +221,10 @@ static void _logp(unsigned int subsys, int level, char *file, int line,
else if (osmo_log_info->filter_fn)
output = osmo_log_info->filter_fn(&log_context,
tar);
if (!output)
continue;
if (output) {
/* FIXME: copying the va_list is an ugly
* workaround against a bug hidden somewhere in
* _output. If we do not copy here, the first
* call to _output() will corrupt the va_list
* contents, and any further _output() calls
* with the same va_list will segfault */
va_list bp;
va_copy(bp, ap);
_output(tar, subsys, level, file, line, cont, format, bp);
va_end(bp);
}
_output(tar, subsys, level, file, line, cont, format, ap);
}
}
@ -448,7 +442,7 @@ const char *log_vty_command_string(const struct log_info *info)
size += strlen(loglevel_strs[i].str) + 1;
rem = size;
str = talloc_zero_size(NULL, size);
str = talloc_zero_size(tall_log_ctx, size);
if (!str)
return NULL;
@ -499,6 +493,7 @@ const char *log_vty_command_string(const struct log_info *info)
goto err;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
err:
str[size-1] = '\0';
return str;
}
@ -517,8 +512,9 @@ const char *log_vty_command_description(const struct log_info *info)
for (i = 0; i < LOGLEVEL_DEFS; i++)
size += strlen(loglevel_descriptions[i]) + 1;
size += strlen("Global setting for all subsystems") + 1;
rem = size;
str = talloc_zero_size(NULL, size);
str = talloc_zero_size(tall_log_ctx, size);
if (!str)
return NULL;
@ -528,6 +524,12 @@ const char *log_vty_command_description(const struct log_info *info)
goto err;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
ret = snprintf(str + offset, rem,
"Global setting for all subsystems\n");
if (ret < 0)
goto err;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
for (i = 0; i < info->num_cat; i++) {
ret = snprintf(str + offset, rem, "%s\n",
info->cat[i].description);
@ -543,6 +545,7 @@ const char *log_vty_command_description(const struct log_info *info)
OSMO_SNPRINTF_RET(ret, rem, offset, len);
}
err:
str[size-1] = '\0';
return str;
}

View File

@ -29,11 +29,13 @@
#include <unistd.h>
#include <string.h>
static struct msg_entry *alloc_entry(struct msg_entries *entries,
const char *mcc, const char *mnc,
const char *option, const char *text)
static struct osmo_config_entry *
alloc_entry(struct osmo_config_list *entries,
const char *mcc, const char *mnc,
const char *option, const char *text)
{
struct msg_entry *entry = talloc_zero(entries, struct msg_entry);
struct osmo_config_entry *entry =
talloc_zero(entries, struct osmo_config_entry);
if (!entry)
return NULL;
@ -46,11 +48,11 @@ static struct msg_entry *alloc_entry(struct msg_entries *entries,
return entry;
}
static struct msg_entries *alloc_entries(void *ctx)
static struct osmo_config_list *alloc_entries(void *ctx)
{
struct msg_entries *entries;
struct osmo_config_list *entries;
entries = talloc_zero(ctx, struct msg_entries);
entries = talloc_zero(ctx, struct osmo_config_list);
if (!entries)
return NULL;
@ -61,7 +63,7 @@ static struct msg_entries *alloc_entries(void *ctx)
/*
* split a line like 'foo:Text'.
*/
static void handle_line(struct msg_entries *entries, char *line)
static void handle_line(struct osmo_config_list *entries, char *line)
{
int i;
const int len = strlen(line);
@ -91,9 +93,9 @@ static void handle_line(struct msg_entries *entries, char *line)
/* nothing found */
}
struct msg_entries *msg_entry_parse(void *ctx, const char *filename)
struct osmo_config_list *osmo_config_list_parse(void *ctx, const char *filename)
{
struct msg_entries *entries;
struct osmo_config_list *entries;
size_t n;
char *line;
FILE *file;

View File

@ -38,7 +38,7 @@ static osmo_panic_handler_t osmo_panic_handler = (void*)0;
static void osmo_panic_default(const char *fmt, va_list args)
{
vfprintf(stderr, fmt, args);
generate_backtrace();
osmo_generate_backtrace();
abort();
}

View File

@ -32,7 +32,7 @@
#include <osmocom/core/plugin.h>
int plugin_load_all(const char *directory)
int osmo_plugin_load_all(const char *directory)
{
unsigned int num = 0;
char fname[PATH_MAX];
@ -55,7 +55,7 @@ int plugin_load_all(const char *directory)
return num;
}
#else
int plugin_load_all(const char *directory)
int osmo_plugin_load_all(const char *directory)
{
return 0;
}

View File

@ -82,7 +82,7 @@ static void interval_expired(struct rate_ctr *ctr, enum rate_ctr_intv intv)
ctr->intv[intv+1].rate += ctr->intv[intv].rate;
}
static struct timer_list rate_ctr_timer;
static struct osmo_timer_list rate_ctr_timer;
static uint64_t timer_ticks;
/* The one-second interval has expired */
@ -114,14 +114,14 @@ static void rate_ctr_timer_cb(void *data)
llist_for_each_entry(ctrg, &rate_ctr_groups, list)
rate_ctr_group_intv(ctrg);
bsc_schedule_timer(&rate_ctr_timer, 1, 0);
osmo_timer_schedule(&rate_ctr_timer, 1, 0);
}
int rate_ctr_init(void *tall_ctx)
{
tall_rate_ctr_ctx = tall_ctx;
rate_ctr_timer.cb = rate_ctr_timer_cb;
bsc_schedule_timer(&rate_ctr_timer, 1, 0);
osmo_timer_schedule(&rate_ctr_timer, 1, 0);
return 0;
}

View File

@ -31,10 +31,10 @@
#ifdef HAVE_SYS_SELECT_H
static int maxfd = 0;
static LLIST_HEAD(bsc_fds);
static LLIST_HEAD(osmo_fds);
static int unregistered_count;
int bsc_register_fd(struct bsc_fd *fd)
int osmo_fd_register(struct osmo_fd *fd)
{
int flags;
@ -52,29 +52,29 @@ int bsc_register_fd(struct bsc_fd *fd)
maxfd = fd->fd;
#ifdef BSC_FD_CHECK
struct bsc_fd *entry;
llist_for_each_entry(entry, &bsc_fds, list) {
struct osmo_fd *entry;
llist_for_each_entry(entry, &osmo_fds, list) {
if (entry == fd) {
fprintf(stderr, "Adding a bsc_fd that is already in the list.\n");
fprintf(stderr, "Adding a osmo_fd that is already in the list.\n");
return 0;
}
}
#endif
llist_add_tail(&fd->list, &bsc_fds);
llist_add_tail(&fd->list, &osmo_fds);
return 0;
}
void bsc_unregister_fd(struct bsc_fd *fd)
void osmo_fd_unregister(struct osmo_fd *fd)
{
unregistered_count++;
llist_del(&fd->list);
}
int bsc_select_main(int polling)
int osmo_select_main(int polling)
{
struct bsc_fd *ufd, *tmp;
struct osmo_fd *ufd, *tmp;
fd_set readset, writeset, exceptset;
int work = 0, rc;
struct timeval no_time = {0, 0};
@ -84,7 +84,7 @@ int bsc_select_main(int polling)
FD_ZERO(&exceptset);
/* prepare read and write fdsets */
llist_for_each_entry(ufd, &bsc_fds, list) {
llist_for_each_entry(ufd, &osmo_fds, list) {
if (ufd->when & BSC_FD_READ)
FD_SET(ufd->fd, &readset);
@ -95,21 +95,21 @@ int bsc_select_main(int polling)
FD_SET(ufd->fd, &exceptset);
}
bsc_timer_check();
osmo_timers_check();
if (!polling)
bsc_prepare_timers();
rc = select(maxfd+1, &readset, &writeset, &exceptset, polling ? &no_time : bsc_nearest_timer());
osmo_timers_prepare();
rc = select(maxfd+1, &readset, &writeset, &exceptset, polling ? &no_time : osmo_timers_nearest());
if (rc < 0)
return 0;
/* fire timers */
bsc_update_timers();
osmo_timers_update();
/* call registered callback functions */
restart:
unregistered_count = 0;
llist_for_each_entry_safe(ufd, tmp, &bsc_fds, list) {
llist_for_each_entry_safe(ufd, tmp, &osmo_fds, list) {
int flags = 0;
if (FD_ISSET(ufd->fd, &readset)) {

View File

@ -31,12 +31,13 @@ static LLIST_HEAD(signal_handler_list);
struct signal_handler {
struct llist_head entry;
unsigned int subsys;
signal_cbfn *cbfn;
osmo_signal_cbfn *cbfn;
void *data;
};
int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data)
int osmo_signal_register_handler(unsigned int subsys,
osmo_signal_cbfn *cbfn, void *data)
{
struct signal_handler *sig_data;
@ -57,7 +58,8 @@ int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data)
return 0;
}
void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data)
void osmo_signal_unregister_handler(unsigned int subsys,
osmo_signal_cbfn *cbfn, void *data)
{
struct signal_handler *handler;
@ -72,7 +74,8 @@ void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *dat
}
void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data)
void osmo_signal_dispatch(unsigned int subsys, unsigned int signal,
void *signal_data)
{
struct signal_handler *handler;

View File

@ -30,9 +30,9 @@ static LLIST_HEAD(counters);
void *tall_ctr_ctx;
struct counter *counter_alloc(const char *name)
struct osmo_counter *osmo_counter_alloc(const char *name)
{
struct counter *ctr = talloc_zero(tall_ctr_ctx, struct counter);
struct osmo_counter *ctr = talloc_zero(tall_ctr_ctx, struct osmo_counter);
if (!ctr)
return NULL;
@ -43,15 +43,16 @@ struct counter *counter_alloc(const char *name)
return ctr;
}
void counter_free(struct counter *ctr)
void osmo_counter_free(struct osmo_counter *ctr)
{
llist_del(&ctr->list);
talloc_free(ctr);
}
int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data)
int osmo_counters_for_each(int (*handle_counter)(struct osmo_counter *, void *),
void *data)
{
struct counter *ctr;
struct osmo_counter *ctr;
int rc = 0;
llist_for_each_entry(ctr, &counters, list) {
@ -63,9 +64,9 @@ int counters_for_each(int (*handle_counter)(struct counter *, void *), void *dat
return rc;
}
struct counter *counter_get_by_name(const char *name)
struct osmo_counter *osmo_counter_get_by_name(const char *name)
{
struct counter *ctr;
struct osmo_counter *ctr;
llist_for_each_entry(ctr, &counters, list) {
if (!strcmp(ctr->name, name))

View File

@ -31,9 +31,9 @@ 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)
void bsc_add_timer(struct timer_list *timer)
void osmo_timer_add(struct osmo_timer_list *timer)
{
struct timer_list *list_timer;
struct osmo_timer_list *list_timer;
/* TODO: Optimize and remember the closest item... */
timer->active = 1;
@ -47,7 +47,8 @@ void bsc_add_timer(struct timer_list *timer)
llist_add(&timer->entry, &timer_list);
}
void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds)
void
osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds)
{
struct timeval current_time;
@ -56,10 +57,10 @@ void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds)
currentTime += seconds * MICRO_SECONDS + microseconds;
timer->timeout.tv_sec = currentTime / MICRO_SECONDS;
timer->timeout.tv_usec = currentTime % MICRO_SECONDS;
bsc_add_timer(timer);
osmo_timer_add(timer);
}
void bsc_del_timer(struct timer_list *timer)
void osmo_timer_del(struct osmo_timer_list *timer)
{
if (timer->in_list) {
timer->active = 0;
@ -68,7 +69,7 @@ void bsc_del_timer(struct timer_list *timer)
}
}
int bsc_timer_pending(struct timer_list *timer)
int osmo_timer_pending(struct osmo_timer_list *timer)
{
return timer->active;
}
@ -79,7 +80,7 @@ int bsc_timer_pending(struct timer_list *timer)
* If the nearest timer timed out return NULL and then we will
* dispatch everything after the select
*/
struct timeval *bsc_nearest_timer()
struct timeval *osmo_timers_nearest()
{
struct timeval current_time;
@ -106,9 +107,9 @@ struct timeval *bsc_nearest_timer()
/*
* Find the nearest time and update s_nearest_time
*/
void bsc_prepare_timers()
void osmo_timers_prepare()
{
struct timer_list *timer, *nearest_timer = NULL;
struct osmo_timer_list *timer, *nearest_timer = NULL;
llist_for_each_entry(timer, &timer_list, entry) {
if (!nearest_timer || TIME_SMALLER(timer->timeout, nearest_timer->timeout)) {
nearest_timer = timer;
@ -125,10 +126,10 @@ void bsc_prepare_timers()
/*
* fire all timers... and remove them
*/
int bsc_update_timers()
int osmo_timers_update()
{
struct timeval current_time;
struct timer_list *timer, *tmp;
struct osmo_timer_list *timer, *tmp;
int work = 0;
gettimeofday(&current_time, NULL);
@ -166,16 +167,16 @@ restart:
llist_for_each_entry_safe(timer, tmp, &timer_list, entry) {
timer->handled = 0;
if (!timer->active) {
bsc_del_timer(timer);
osmo_timer_del(timer);
}
}
return work;
}
int bsc_timer_check(void)
int osmo_timers_check(void)
{
struct timer_list *timer;
struct osmo_timer_list *timer;
int i = 0;
llist_for_each_entry(timer, &timer_list, entry) {

View File

@ -35,7 +35,7 @@ int get_string_value(const struct value_string *vs, const char *str)
return -EINVAL;
}
char bcd2char(uint8_t bcd)
char osmo_bcd2char(uint8_t bcd)
{
if (bcd < 0xa)
return '0' + bcd;
@ -44,12 +44,12 @@ char bcd2char(uint8_t bcd)
}
/* only works for numbers in ascii */
uint8_t char2bcd(char c)
uint8_t osmo_char2bcd(char c)
{
return c - 0x30;
}
int hexparse(const char *str, uint8_t *b, int max_len)
int osmo_hexparse(const char *str, uint8_t *b, int max_len)
{
int i, l, v;
@ -78,7 +78,7 @@ int hexparse(const char *str, uint8_t *b, int max_len)
static char hexd_buff[4096];
static char *_hexdump(const unsigned char *buf, int len, char *delim)
static char *_osmo_hexdump(const unsigned char *buf, int len, char *delim)
{
int i;
char *cur = hexd_buff;
@ -95,7 +95,7 @@ static char *_hexdump(const unsigned char *buf, int len, char *delim)
return hexd_buff;
}
char *ubit_dump(const uint8_t *bits, unsigned int len)
char *osmo_ubit_dump(const uint8_t *bits, unsigned int len)
{
int i;
@ -125,14 +125,14 @@ char *ubit_dump(const uint8_t *bits, unsigned int len)
return hexd_buff;
}
char *hexdump(const unsigned char *buf, int len)
char *osmo_hexdump(const unsigned char *buf, int len)
{
return _hexdump(buf, len, " ");
return _osmo_hexdump(buf, len, " ");
}
char *hexdump_nospc(const unsigned char *buf, int len)
char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len)
{
return _hexdump(buf, len, "");
return _osmo_hexdump(buf, len, "");
}
#include "../config.h"

View File

@ -10,5 +10,6 @@ lib_LTLIBRARIES = libosmovty.la
libosmovty_la_SOURCES = buffer.c command.c vty.c vector.c utils.c \
telnet_interface.c logging_vty.c
libosmovty_la_LDFLAGS = -version-info $(LIBVERSION)
libosmovty_la_LIBADD = $(top_builddir)/src/libosmocore.la
endif

View File

@ -39,9 +39,9 @@ LLIST_HEAD(active_connections);
static void *tall_telnet_ctx;
/* per network data */
static int telnet_new_connection(struct bsc_fd *fd, unsigned int what);
static int telnet_new_connection(struct osmo_fd *fd, unsigned int what);
static struct bsc_fd server_socket = {
static struct osmo_fd server_socket = {
.when = BSC_FD_READ,
.cb = telnet_new_connection,
.priv_nr = 0,
@ -85,7 +85,7 @@ int telnet_init(void *tall_ctx, void *priv, int port)
server_socket.data = priv;
server_socket.fd = fd;
bsc_register_fd(&server_socket);
osmo_fd_register(&server_socket);
return 0;
}
@ -104,12 +104,12 @@ static void print_welcome(int fd)
ret = write(fd, host.app_info->copyright, strlen(host.app_info->copyright));
}
int telnet_close_client(struct bsc_fd *fd)
int telnet_close_client(struct osmo_fd *fd)
{
struct telnet_connection *conn = (struct telnet_connection*)fd->data;
close(fd->fd);
bsc_unregister_fd(fd);
osmo_fd_unregister(fd);
if (conn->dbg) {
log_del_target(conn->dbg);
@ -121,7 +121,7 @@ int telnet_close_client(struct bsc_fd *fd)
return 0;
}
static int client_data(struct bsc_fd *fd, unsigned int what)
static int client_data(struct osmo_fd *fd, unsigned int what)
{
struct telnet_connection *conn = fd->data;
int rc = 0;
@ -144,7 +144,7 @@ static int client_data(struct bsc_fd *fd, unsigned int what)
return rc;
}
static int telnet_new_connection(struct bsc_fd *fd, unsigned int what)
static int telnet_new_connection(struct osmo_fd *fd, unsigned int what)
{
struct telnet_connection *connection;
struct sockaddr_in sockaddr;
@ -162,7 +162,7 @@ static int telnet_new_connection(struct bsc_fd *fd, unsigned int what)
connection->fd.fd = new_connection;
connection->fd.when = BSC_FD_READ;
connection->fd.cb = client_data;
bsc_register_fd(&connection->fd);
osmo_fd_register(&connection->fd);
llist_add_tail(&connection->entry, &active_connections);
print_welcome(new_connection);
@ -182,7 +182,7 @@ static int telnet_new_connection(struct bsc_fd *fd, unsigned int what)
void vty_event(enum event event, int sock, struct vty *vty)
{
struct telnet_connection *connection = vty->priv;
struct bsc_fd *bfd = &connection->fd;
struct osmo_fd *bfd = &connection->fd;
if (vty->type != VTY_TERM)
return;

View File

@ -23,11 +23,11 @@
#include <osmocom/core/write_queue.h>
int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what)
int osmo_wqueue_bfd_cb(struct osmo_fd *fd, unsigned int what)
{
struct write_queue *queue;
struct osmo_wqueue *queue;
queue = container_of(fd, struct write_queue, bfd);
queue = container_of(fd, struct osmo_wqueue, bfd);
if (what & BSC_FD_READ)
queue->read_cb(fd);
@ -56,17 +56,17 @@ int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what)
return 0;
}
void write_queue_init(struct write_queue *queue, int max_length)
void osmo_wqueue_init(struct osmo_wqueue *queue, int max_length)
{
queue->max_length = max_length;
queue->current_length = 0;
queue->read_cb = NULL;
queue->write_cb = NULL;
queue->bfd.cb = write_queue_bfd_cb;
queue->bfd.cb = osmo_wqueue_bfd_cb;
INIT_LLIST_HEAD(&queue->msg_queue);
}
int write_queue_enqueue(struct write_queue *queue, struct msgb *data)
int osmo_wqueue_enqueue(struct osmo_wqueue *queue, struct msgb *data)
{
// if (queue->current_length + 1 >= queue->max_length)
// LOGP(DMSC, LOGL_ERROR, "The queue is full. Dropping not yet implemented.\n");
@ -78,7 +78,7 @@ int write_queue_enqueue(struct write_queue *queue, struct msgb *data)
return 0;
}
void write_queue_clear(struct write_queue *queue)
void osmo_wqueue_clear(struct osmo_wqueue *queue)
{
while (!llist_empty(&queue->msg_queue)) {
struct msgb *msg = msgb_dequeue(&queue->msg_queue);

View File

@ -23,9 +23,9 @@
#include <stdio.h>
static void dump_entries(struct msg_entries *entries)
static void dump_entries(struct osmo_config_list *entries)
{
struct msg_entry *entry;
struct osmo_config_entry *entry;
if (!entries) {
fprintf(stderr, "Failed to parse the file\n");
@ -40,10 +40,10 @@ static void dump_entries(struct msg_entries *entries)
int main(int argc, char **argv)
{
struct msg_entries *entries;
struct osmo_config_list *entries;
/* todo use msgfile_test.c.in and replace the path */
entries = msg_entry_parse(NULL, "msgconfig.cfg");
entries = osmo_config_list_parse(NULL, "msgconfig.cfg");
dump_entries(entries);
return 0;

View File

@ -27,17 +27,17 @@
static void timer_fired(void *data);
static struct timer_list timer_one = {
static struct osmo_timer_list timer_one = {
.cb = timer_fired,
.data = (void*)1,
};
static struct timer_list timer_two = {
static struct osmo_timer_list timer_two = {
.cb = timer_fired,
.data = (void*)2,
};
static struct timer_list timer_three = {
static struct osmo_timer_list timer_three = {
.cb = timer_fired,
.data = (void*)3,
};
@ -48,8 +48,8 @@ static void timer_fired(void *_data)
printf("Fired timer: %lu\n", data);
if (data == 1) {
bsc_schedule_timer(&timer_one, 3, 0);
bsc_del_timer(&timer_two);
osmo_timer_schedule(&timer_one, 3, 0);
osmo_timer_del(&timer_two);
} else if (data == 2) {
printf("Should not be fired... bug in del_timer\n");
} else if (data == 3) {
@ -63,13 +63,13 @@ int main(int argc, char** argv)
{
printf("Starting... timer\n");
bsc_schedule_timer(&timer_one, 3, 0);
bsc_schedule_timer(&timer_two, 5, 0);
bsc_schedule_timer(&timer_three, 4, 0);
osmo_timer_schedule(&timer_one, 3, 0);
osmo_timer_schedule(&timer_two, 5, 0);
osmo_timer_schedule(&timer_three, 4, 0);
#ifdef HAVE_SYS_SELECT_H
while (1) {
bsc_select_main(0);
osmo_select_main(0);
}
#else
printf("Select not supported on this platform!\n");