diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/shared/libosmocore/configure.in | 31 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocore/Makefile.am | 2 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocore/gsm0808.h | 4 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocore/msgb.h | 33 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocore/panic.h | 11 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocore/protocol/Makefile.am | 3 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocore/protocol/gsm_04_12.h | 31 | ||||
-rw-r--r-- | src/shared/libosmocore/include/osmocore/rsl.h | 3 | ||||
-rw-r--r-- | src/shared/libosmocore/src/Makefile.am | 2 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm0808.c | 15 | ||||
-rw-r--r-- | src/shared/libosmocore/src/gsm_utils.c | 130 | ||||
-rw-r--r-- | src/shared/libosmocore/src/panic.c | 71 | ||||
-rw-r--r-- | src/shared/libosmocore/src/rsl.c | 26 | ||||
-rw-r--r-- | src/shared/libosmocore/tests/sms/sms_test.c | 89 |
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; } |