diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2010-07-27 20:50:57 +0200 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2010-07-27 20:50:57 +0200 |
commit | a54a8d04c6e993159410fb19e3a150c499f0a419 (patch) | |
tree | 6b687728b9efcbdbae36ee517fc65d09ab48a3cb /src/shared/libosmocore/src | |
parent | 9e9f99c0a094a3b82a75bbac33cabc2be8a6bacb (diff) | |
parent | 7459d6cfd1765f8431b3d9a262eff332f9af807c (diff) |
Merge commit '7459d6cfd1765f8431b3d9a262eff332f9af807c' into sylvain/pending
Diffstat (limited to 'src/shared/libosmocore/src')
-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 |
5 files changed, 217 insertions, 27 deletions
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" }, |