summaryrefslogtreecommitdiffstats
path: root/src/shared/libosmocore
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2010-07-27 20:50:57 +0200
committerSylvain Munaut <tnt@246tNt.com>2010-07-27 20:50:57 +0200
commita54a8d04c6e993159410fb19e3a150c499f0a419 (patch)
tree6b687728b9efcbdbae36ee517fc65d09ab48a3cb /src/shared/libosmocore
parent9e9f99c0a094a3b82a75bbac33cabc2be8a6bacb (diff)
parent7459d6cfd1765f8431b3d9a262eff332f9af807c (diff)
Merge commit '7459d6cfd1765f8431b3d9a262eff332f9af807c' into sylvain/pending
Diffstat (limited to 'src/shared/libosmocore')
-rw-r--r--src/shared/libosmocore/configure.in31
-rw-r--r--src/shared/libosmocore/include/osmocore/Makefile.am2
-rw-r--r--src/shared/libosmocore/include/osmocore/gsm0808.h4
-rw-r--r--src/shared/libosmocore/include/osmocore/msgb.h33
-rw-r--r--src/shared/libosmocore/include/osmocore/panic.h11
-rw-r--r--src/shared/libosmocore/include/osmocore/protocol/Makefile.am3
-rw-r--r--src/shared/libosmocore/include/osmocore/protocol/gsm_04_12.h31
-rw-r--r--src/shared/libosmocore/include/osmocore/rsl.h3
-rw-r--r--src/shared/libosmocore/src/Makefile.am2
-rw-r--r--src/shared/libosmocore/src/gsm0808.c15
-rw-r--r--src/shared/libosmocore/src/gsm_utils.c130
-rw-r--r--src/shared/libosmocore/src/panic.c71
-rw-r--r--src/shared/libosmocore/src/rsl.c26
-rw-r--r--src/shared/libosmocore/tests/sms/sms_test.c89
14 files changed, 405 insertions, 46 deletions
diff --git a/src/shared/libosmocore/configure.in b/src/shared/libosmocore/configure.in
index e3e178c0..c3e00610 100644
--- a/src/shared/libosmocore/configure.in
+++ b/src/shared/libosmocore/configure.in
@@ -35,25 +35,48 @@ dnl Generate the output
AM_CONFIG_HEADER(config.h)
AC_ARG_ENABLE(talloc,
- [ --disable-talloc Disable building talloc memory allocator ],
+ [AS_HELP_STRING(
+ [--disable-talloc],
+ [Disable building talloc memory allocator]
+ )],
[enable_talloc=0], [enable_talloc=1])
AM_CONDITIONAL(ENABLE_TALLOC, test "x$enable_talloc" = "x1")
AC_ARG_ENABLE(plugin,
- [ --disable-plugin Disable support for dlopen plugins ],
+ [AS_HELP_STRING(
+ [--disable-plugin],
+ [Disable support for dlopen plugins],
+ )],
[enable_plugin=0], [enable_plugin=1])
AM_CONDITIONAL(ENABLE_PLUGIN, test "x$enable_plugin" = "x1")
AC_ARG_ENABLE(tests,
- [ --disable-tests Disable building test programs ],
+ [AS_HELP_STRING(
+ [--disable-tests],
+ [Disable building test programs]
+ )],
[enable_tests=0], [enable_tests=1])
AM_CONDITIONAL(ENABLE_TESTS, test "x$enable_tests" = "x1")
AC_ARG_ENABLE(vty,
- [ --disable-vty Disable building VTY telnet interface ],
+ [AS_HELP_STRING(
+ [--disable-vty],
+ [Disable building VTY telnet interface]
+ )],
[enable_vty=0], [enable_vty=1])
AM_CONDITIONAL(ENABLE_VTY, test "x$enable_vty" = "x1")
+AC_ARG_ENABLE(panic_infloop,
+ [AS_HELP_STRING(
+ [--enable-panic-infloop],
+ [Trigger infinite loop on panic rather than fprintf/abort]
+ )],
+ [panic_infloop=1], [panic_infloop=0])
+if test "x$panic_infloop" = "x1"
+then
+ AC_DEFINE([PANIC_INFLOOP],[1],[Use infinite loop on panic rather than fprintf/abort])
+fi
+
AC_OUTPUT(
libosmocore.pc
diff --git a/src/shared/libosmocore/include/osmocore/Makefile.am b/src/shared/libosmocore/include/osmocore/Makefile.am
index 8334f148..ecdc65c9 100644
--- a/src/shared/libosmocore/include/osmocore/Makefile.am
+++ b/src/shared/libosmocore/include/osmocore/Makefile.am
@@ -2,7 +2,7 @@ osmocore_HEADERS = signal.h linuxlist.h timer.h select.h msgb.h \
tlv.h bitvec.h comp128.h statistics.h gsm_utils.h utils.h \
gsmtap.h write_queue.h rsl.h gsm48.h rxlev_stat.h mncc.h \
gsm48_ie.h logging.h gsm0808.h rate_ctr.h gsmtap_util.h \
- plugin.h crc16.h
+ plugin.h crc16.h panic.h
if ENABLE_TALLOC
osmocore_HEADERS += talloc.h
diff --git a/src/shared/libosmocore/include/osmocore/gsm0808.h b/src/shared/libosmocore/include/osmocore/gsm0808.h
index 9166e54f..2d609c9e 100644
--- a/src/shared/libosmocore/include/osmocore/gsm0808.h
+++ b/src/shared/libosmocore/include/osmocore/gsm0808.h
@@ -24,14 +24,14 @@
struct msgb;
-struct msgb *gsm0808_create_layer3(struct msgb *msg, uint16_t netcode, uint16_t countrycode, int lac, int ci);
+struct msgb *gsm0808_create_layer3(struct msgb *msg, uint16_t netcode, uint16_t countrycode, int lac, uint16_t ci);
struct msgb *gsm0808_create_reset(void);
struct msgb *gsm0808_create_clear_complete(void);
struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id);
struct msgb *gsm0808_create_cipher_reject(uint8_t cause);
struct msgb *gsm0808_create_classmark_update(const uint8_t *classmark, uint8_t length);
struct msgb *gsm0808_create_sapi_reject(uint8_t link_id);
-struct msgb *gsm0808_create_assignment_completed(struct gsm_lchan *lchan, uint8_t rr_cause,
+struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
uint8_t chosen_channel, uint8_t encr_alg_id,
uint8_t speech_mode);
struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause);
diff --git a/src/shared/libosmocore/include/osmocore/msgb.h b/src/shared/libosmocore/include/osmocore/msgb.h
index 2841dc56..354c5d88 100644
--- a/src/shared/libosmocore/include/osmocore/msgb.h
+++ b/src/shared/libosmocore/include/osmocore/msgb.h
@@ -23,6 +23,8 @@
#include <stdint.h>
#include "linuxlist.h"
+#define MSGB_DEBUG
+
struct msgb {
struct llist_head list;
@@ -58,6 +60,14 @@ extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg);
extern struct msgb *msgb_dequeue(struct llist_head *queue);
extern void msgb_reset(struct msgb *m);
+#ifdef MSGB_DEBUG
+#include <osmocore/panic.h>
+static inline void msgb_abort(struct msgb *msg, const char *text)
+{
+ osmo_panic("%s", text);
+}
+#endif
+
#define msgb_l1(m) ((void *)(m->l1h))
#define msgb_l2(m) ((void *)(m->l2h))
#define msgb_l3(m) ((void *)(m->l3h))
@@ -82,9 +92,24 @@ static inline unsigned int msgb_headlen(const struct msgb *msgb)
{
return msgb->len - msgb->data_len;
}
+
+static inline int msgb_tailroom(const struct msgb *msgb)
+{
+ return (msgb->head + msgb->data_len) - msgb->tail;
+}
+
+static inline int msgb_headroom(const struct msgb *msgb)
+{
+ return (msgb->data - msgb->head);
+}
+
static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)
{
unsigned char *tmp = msgb->tail;
+#ifdef MSGB_DEBUG
+ if (msgb_tailroom(msgb) < len)
+ msgb_abort(msgb, "Not enough tailroom\n");
+#endif
msgb->tail += len;
msgb->len += len;
return tmp;
@@ -132,6 +157,10 @@ static inline uint32_t msgb_get_u32(struct msgb *msgb)
}
static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)
{
+#ifdef MSGB_DEBUG
+ if (msgb_headroom(msgb) < len)
+ msgb_abort(msgb, "Not enough headroom\n");
+#endif
msgb->data -= len;
msgb->len += len;
return msgb->data;
@@ -141,10 +170,6 @@ static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
msgb->len -= len;
return msgb->data += len;
}
-static inline int msgb_tailroom(const struct msgb *msgb)
-{
- return (msgb->head + msgb->data_len) - msgb->tail;
-}
/* increase the headroom of an empty msgb, reducing the tailroom */
static inline void msgb_reserve(struct msgb *msg, int len)
diff --git a/src/shared/libosmocore/include/osmocore/panic.h b/src/shared/libosmocore/include/osmocore/panic.h
new file mode 100644
index 00000000..cee95358
--- /dev/null
+++ b/src/shared/libosmocore/include/osmocore/panic.h
@@ -0,0 +1,11 @@
+#ifndef OSMOCORE_PANIC_H
+#define OSMOCORE_PANIC_H
+
+#include <stdarg.h>
+
+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);
+
+#endif
diff --git a/src/shared/libosmocore/include/osmocore/protocol/Makefile.am b/src/shared/libosmocore/include/osmocore/protocol/Makefile.am
index 557950ec..5df9fe74 100644
--- a/src/shared/libosmocore/include/osmocore/protocol/Makefile.am
+++ b/src/shared/libosmocore/include/osmocore/protocol/Makefile.am
@@ -1,3 +1,4 @@
-osmocore_proto_HEADERS = gsm_04_08.h gsm_04_11.h gsm_04_80.h gsm_08_58.h gsm_12_21.h gsm_08_08.h
+osmocore_proto_HEADERS = gsm_04_08.h gsm_04_11.h gsm_04_80.h gsm_08_58.h \
+ gsm_12_21.h gsm_08_08.h gsm_04_12.h
osmocore_protodir = $(includedir)/osmocore/protocol
diff --git a/src/shared/libosmocore/include/osmocore/protocol/gsm_04_12.h b/src/shared/libosmocore/include/osmocore/protocol/gsm_04_12.h
new file mode 100644
index 00000000..bd9e0884
--- /dev/null
+++ b/src/shared/libosmocore/include/osmocore/protocol/gsm_04_12.h
@@ -0,0 +1,31 @@
+#ifndef PROTO_GSM_04_12_H
+#define PROTO_GSM_04_12_H
+
+#include <stdint.h>
+
+/* GSM TS 04.12 definitions for Short Message Service Cell Broadcast */
+
+#define GSM412_SEQ_FST_BLOCK 0x0
+#define GSM412_SEQ_SND_BLOCK 0x1
+#define GSM412_SEQ_TRD_BLOCK 0x2
+#define GSM412_SEQ_FTH_BLOCK 0x3
+#define GSM412_SEQ_FST_SCHED_BLOCK 0x8
+#define GSM413_SEQ_NULL_MSG 0xf
+
+struct gsm412_block_type {
+ uint8_t seq_nr : 4,
+ lb : 1,
+ lpd : 2,
+ spare : 1;
+} __attribute__((packed));
+
+struct gsm413_sched_msg {
+ uint8_t beg_slot_nr : 6,
+ type : 2;
+ uint8_t end_slot_nr : 6,
+ spare1 : 1, spare2: 1;
+ uint8_t cbsms_msg_map[6];
+ uint8_t data[0];
+} __attribute__((packed));
+
+#endif
diff --git a/src/shared/libosmocore/include/osmocore/rsl.h b/src/shared/libosmocore/include/osmocore/rsl.h
index cd84057b..54d67032 100644
--- a/src/shared/libosmocore/include/osmocore/rsl.h
+++ b/src/shared/libosmocore/include/osmocore/rsl.h
@@ -17,6 +17,9 @@ extern const struct tlv_definition rsl_att_tlvdef;
uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot);
/* decode channel number as per Section 9.3.1 */
int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot);
+/* Turns channel number into a string */
+const char *rsl_chan_nr_str(uint8_t chan_nr);
+
const char *rsl_err_name(uint8_t err);
const char *rsl_rlm_cause_name(uint8_t err);
diff --git a/src/shared/libosmocore/src/Makefile.am b/src/shared/libosmocore/src/Makefile.am
index a20fbc86..e197e179 100644
--- a/src/shared/libosmocore/src/Makefile.am
+++ b/src/shared/libosmocore/src/Makefile.am
@@ -13,7 +13,7 @@ libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c rxlev_stat.c \
tlv_parser.c bitvec.c comp128.c gsm_utils.c statistics.c \
write_queue.c utils.c rsl.c gsm48.c gsm48_ie.c \
logging.c gsm0808.c rate_ctr.c gsmtap_util.c \
- gprs_cipher_core.c crc16.c
+ gprs_cipher_core.c crc16.c panic.c
if ENABLE_PLUGIN
libosmocore_la_SOURCES += plugin.c
diff --git a/src/shared/libosmocore/src/gsm0808.c b/src/shared/libosmocore/src/gsm0808.c
index 1dc035b3..c8dc6645 100644
--- a/src/shared/libosmocore/src/gsm0808.c
+++ b/src/shared/libosmocore/src/gsm0808.c
@@ -27,10 +27,15 @@
#define BSSMAP_MSG_SIZE 512
#define BSSMAP_MSG_HEADROOM 128
-struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, int _ci)
+static void put_data_16(uint8_t *data, const uint16_t val)
+{
+ memcpy(data, &val, sizeof(val));
+}
+
+struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, uint16_t _ci)
{
uint8_t *data;
- uint16_t *ci;
+ uint8_t *ci;
struct msgb* msg;
struct gsm48_loc_area_id *lai;
@@ -56,8 +61,8 @@ struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc
lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
gsm48_generate_lai(lai, cc, nc, lac);
- ci = (uint16_t *) msgb_put(msg, 2);
- *ci = htons(_ci);
+ ci = msgb_put(msg, 2);
+ put_data_16(ci, htons(_ci));
/* copy the layer3 data */
data = msgb_put(msg, msgb_l3len(msg_l3) + 2);
@@ -187,7 +192,7 @@ struct msgb *gsm0808_create_sapi_reject(uint8_t link_id)
return msg;
}
-struct msgb *gsm0808_create_assignment_completed(struct gsm_lchan *lchan, uint8_t rr_cause,
+struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
uint8_t chosen_channel, uint8_t encr_alg_id,
uint8_t speech_mode)
{
diff --git a/src/shared/libosmocore/src/gsm_utils.c b/src/shared/libosmocore/src/gsm_utils.c
index dc97ceff..4b4e2c60 100644
--- a/src/shared/libosmocore/src/gsm_utils.c
+++ b/src/shared/libosmocore/src/gsm_utils.c
@@ -2,6 +2,7 @@
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by Nico Golde <nico@ngolde.de>
*
* All Rights Reserved
*
@@ -34,53 +35,140 @@
#include "../config.h"
-/* GSM 03.38 6.2.1 Charachter packing */
+/* ETSI GSM 03.38 6.2.1 and 6.2.1.1 default alphabet
+ * Greek symbols at hex positions 0x10 and 0x12-0x1a
+ * left out as they can't be handled with a char and
+ * since most phones don't display or write these
+ * characters this would only needlessly make the code
+ * more complex
+*/
+static unsigned char gsm_7bit_alphabet[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0xff, 0xff, 0x0d, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x20, 0x21, 0x22, 0x23, 0x02, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
+ 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
+ 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x3c, 0x2f, 0x3e, 0x14, 0x11, 0xff, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x28, 0x40, 0x29, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x0c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xff, 0x01, 0xff,
+ 0x03, 0xff, 0x7b, 0x7d, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5b, 0x7e, 0x5d, 0xff, 0x7c, 0xff, 0xff, 0xff,
+ 0xff, 0x5b, 0x0e, 0x1c, 0x09, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5d,
+ 0xff, 0xff, 0xff, 0xff, 0x5c, 0xff, 0x0b, 0xff, 0xff, 0xff, 0x5e, 0xff, 0xff, 0x1e, 0x7f,
+ 0xff, 0xff, 0xff, 0x7b, 0x0f, 0x1d, 0xff, 0x04, 0x05, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff,
+ 0xff, 0x7d, 0x08, 0xff, 0xff, 0xff, 0x7c, 0xff, 0x0c, 0x06, 0xff, 0xff, 0x7e, 0xff, 0xff
+};
+
+/* GSM 03.38 6.2.1 Character lookup for decoding */
+static int gsm_septet_lookup(uint8_t ch)
+{
+ int i = 0;
+ for(; i < sizeof(gsm_7bit_alphabet); i++){
+ if(gsm_7bit_alphabet[i] == ch)
+ return i;
+ }
+ return -1;
+}
+
+/* GSM 03.38 6.2.1 Character unpacking */
int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t length)
{
int i = 0;
int l = 0;
+ int septet_l = (length * 8) / 7;
+ uint8_t *rtext = calloc(septet_l, sizeof(uint8_t));
+ uint8_t tmp;
- /* FIXME: We need to account for user data headers here */
+ /* FIXME: We need to account for user data headers here */
i += l;
- for (; i < length; i ++)
- *(text ++) =
+ for (; i < septet_l; i++){
+ rtext[i] =
((user_data[(i * 7 + 7) >> 3] <<
(7 - ((i * 7 + 7) & 7))) |
(user_data[(i * 7) >> 3] >>
((i * 7) & 7))) & 0x7f;
+ }
+
+ for(i = 0; i < septet_l; i++){
+ /* this is an extension character */
+ if(rtext[i] == 0x1b && i + 1 < length){
+ tmp = rtext[i+1];
+ *(text++) = gsm_7bit_alphabet[0x7f + tmp];
+ i++;
+ continue;
+ }
+
+ *(text++) = gsm_septet_lookup(rtext[i]);
+ }
+
*text = '\0';
+ free(rtext);
- return i - l;
+ return i;
}
+/* GSM 03.38 6.2.1 Prepare character packing */
+static int gsm_septet_encode(uint8_t *result, const char *data)
+{
+ int i, y = 0;
+ uint8_t ch;
+ for(i = 0; i < strlen(data); i++){
+ ch = data[i];
+ switch(ch){
+ /* fall-through for extension characters */
+ case 0x0c:
+ case 0x5e:
+ case 0x7b:
+ case 0x7d:
+ case 0x5c:
+ case 0x5b:
+ case 0x7e:
+ case 0x5d:
+ case 0x7c:
+ result[y++] = 0x1b;
+ default:
+ result[y] = gsm_7bit_alphabet[ch];
+ break;
+ }
+ y++;
+ }
-/* GSM 03.38 6.2.1 Charachter packing */
+ return y;
+}
+
+/* GSM 03.38 6.2.1 Character packing */
int gsm_7bit_encode(uint8_t *result, const char *data)
{
- int i,j = 0;
- unsigned char ch1, ch2;
+ int i,y,z = 0;
+ /* prepare for the worst case, every character expanding to two bytes */
+ uint8_t *rdata = calloc(strlen(data) * 2, sizeof(uint8_t));
+ uint8_t cb, nb;
int shift = 0;
- for ( i=0; i<strlen(data); i++ ) {
+ y = gsm_septet_encode(rdata, data);
- ch1 = data[i] & 0x7F;
- ch1 = ch1 >> shift;
- ch2 = data[(i+1)] & 0x7F;
- ch2 = ch2 << (7-shift);
+ for(i = 0; i < y; i++) {
+ if(shift == 7 && i + 1 < y){
+ shift = 0;
+ continue;
+ }
- ch1 = ch1 | ch2;
+ cb = (rdata[i] & 0x7f) >> shift;
+ if(i + 1 < y){
+ nb = (rdata[i + 1] & 0x7f) << (7 - shift);
+ cb = cb | nb;
+ }
- result[j++] = ch1;
+ result[z++] = cb;
shift++;
-
- if ((shift == 7) && (i+1<strlen(data))) {
- shift = 0;
- i++;
- }
}
- return i;
+ free(rdata);
+ return z;
}
/* determine power control level for given dBm value, as indicated
diff --git a/src/shared/libosmocore/src/panic.c b/src/shared/libosmocore/src/panic.c
new file mode 100644
index 00000000..a25067de
--- /dev/null
+++ b/src/shared/libosmocore/src/panic.c
@@ -0,0 +1,71 @@
+/* Panic handling */
+/*
+ * (C) 2010 by 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 <osmocore/panic.h>
+
+#include "../config.h"
+
+
+static osmo_panic_handler_t osmo_panic_handler = (void*)0;
+
+
+#ifndef PANIC_INFLOOP
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void osmo_panic_default(const char *fmt, va_list args)
+{
+ vfprintf(stderr, fmt, args);
+ abort();
+}
+
+#else
+
+static void osmo_panic_default(const char *fmt, va_list args)
+{
+ while (1);
+}
+
+#endif
+
+
+void osmo_panic(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+
+ if (osmo_panic_handler)
+ osmo_panic_handler(fmt, args);
+ else
+ osmo_panic_default(fmt, args);
+
+ va_end(args);
+}
+
+
+void osmo_set_panic_handler(osmo_panic_handler_t *h)
+{
+ osmo_panic_handler = h;
+}
+
diff --git a/src/shared/libosmocore/src/rsl.c b/src/shared/libosmocore/src/rsl.c
index 7bc1712f..10fba9b2 100644
--- a/src/shared/libosmocore/src/rsl.c
+++ b/src/shared/libosmocore/src/rsl.c
@@ -183,6 +183,32 @@ int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *tim
return 0;
}
+const char *rsl_chan_nr_str(uint8_t chan_nr)
+{
+ static char str[20];
+ int ts = chan_nr & 7;
+ uint8_t cbits = chan_nr >> 3;
+
+ if (cbits == 0x01)
+ sprintf(str, "TCH/F on TS%d", ts);
+ else if ((cbits & 0x1e) == 0x02)
+ sprintf(str, "TCH/H(%u) on TS%d", cbits & 0x01, ts);
+ else if ((cbits & 0x1c) == 0x04)
+ sprintf(str, "SDCCH/4(%u) on TS%d", cbits & 0x03, ts);
+ else if ((cbits & 0x18) == 0x08)
+ sprintf(str, "SDCCH/8(%u) on TS%d", cbits & 0x07, ts);
+ else if (cbits == 0x10)
+ sprintf(str, "BCCH on TS%d", ts);
+ else if (cbits == 0x11)
+ sprintf(str, "RACH on TS%d", ts);
+ else if (cbits == 0x12)
+ sprintf(str, "PCH/AGCH on TS%d", ts);
+ else
+ sprintf(str, "UNKNOWN on TS%d", ts);
+
+ return str;
+}
+
static const struct value_string rsl_err_vals[] = {
{ RSL_ERR_RADIO_IF_FAIL, "Radio Interface Failure" },
{ RSL_ERR_RADIO_LINK_FAIL, "Radio Link Failure" },
diff --git a/src/shared/libosmocore/tests/sms/sms_test.c b/src/shared/libosmocore/tests/sms/sms_test.c
index f5183d54..9d87b5bc 100644
--- a/src/shared/libosmocore/tests/sms/sms_test.c
+++ b/src/shared/libosmocore/tests/sms/sms_test.c
@@ -1,5 +1,6 @@
/*
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
+ * (C) 2010 by Nico Golde <nico@ngolde.de>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -24,6 +25,56 @@
#include <sys/types.h>
#include <osmocore/msgb.h>
#include <osmocore/gsm_utils.h>
+#include <osmocore/utils.h>
+
+struct test_case {
+ const uint8_t *input;
+ const uint16_t input_length;
+
+ const uint8_t *expected;
+ const uint16_t expected_length;
+};
+
+static const char simple_text[] = "test text";
+static const uint8_t simple_enc[] = {
+ 0xf4, 0xf2, 0x9c, 0x0e, 0xa2, 0x97, 0xf1, 0x74
+};
+
+static const char escape_text[] = "!$ a more#^- complicated test@@?_\%! case";
+static const uint8_t escape_enc[] = {
+ 0x21, 0x01, 0x28, 0x0c, 0x6a, 0xbf, 0xe5, 0xe5, 0xd1,
+ 0x86, 0xd2, 0x02, 0x8d, 0xdf, 0x6d, 0x38, 0x3b, 0x3d,
+ 0x0e, 0xd3, 0xcb, 0x64, 0x10, 0xbd, 0x3c, 0xa7, 0x03,
+ 0x00, 0xbf, 0x48, 0x29, 0x04, 0x1a, 0x87, 0xe7, 0x65,
+};
+
+static const struct test_case test_encode[] =
+{
+ {
+ .input = simple_text,
+ .expected = simple_enc,
+ .expected_length = sizeof(simple_enc),
+ },
+ {
+ .input = escape_text,
+ .expected = escape_enc,
+ .expected_length = sizeof(escape_enc),
+ },
+};
+
+static const struct test_case test_decode[] =
+{
+ {
+ .input = simple_enc,
+ .input_length = sizeof(simple_enc),
+ .expected = simple_text,
+ },
+ {
+ .input = escape_enc,
+ .input_length = sizeof(escape_enc),
+ .expected = escape_text,
+ },
+};
int main(int argc, char** argv)
{
@@ -32,16 +83,40 @@ int main(int argc, char** argv)
uint8_t *sms;
uint8_t i;
- /* test 7-bit coding/decoding */
- const char *input = "test text";
uint8_t length;
uint8_t coded[256];
char result[256];
- length = gsm_7bit_encode(coded, input);
- gsm_7bit_decode(result, coded, length);
- if (strcmp(result, input) != 0) {
- printf("7 Bit coding failed... life sucks\n");
- printf("Wanted: '%s' got '%s'\n", input, result);
+ /* test 7-bit encoding */
+ for (i = 0; i < ARRAY_SIZE(test_encode); ++i) {
+ memset(coded, 0x42, sizeof(coded));
+ length = gsm_7bit_encode(coded, test_encode[i].input);
+
+ if (length != test_encode[i].expected_length) {
+ fprintf(stderr, "Failed to encode case %d. Got %d, expected %d\n",
+ i, length, test_encode[i].expected_length);
+ return -1;
+ }
+
+ if (memcmp(coded, test_encode[i].expected, length) != 0) {
+ fprintf(stderr, "Encoded content does not match for %d\n",
+ i);
+ return -1;
+ }
}
+
+ /* test 7-bit decoding */
+ for (i = 0; i < ARRAY_SIZE(test_decode); ++i) {
+ memset(result, 0x42, sizeof(coded));
+ gsm_7bit_decode(result, test_decode[i].input,
+ test_decode[i].input_length);
+
+ if (strcmp(result, test_decode[i].expected) != 0) {
+ fprintf(stderr, "Test case %d failed to decode.\n", i);
+ return -1;
+ }
+ }
+
+ printf("OK\n");
+ return 0;
}