blob: 2f44e931583378f9cfbc1b5d29070f49606fc2ee [file] [log] [blame]
Harald Welte77847ad2015-10-06 22:07:04 +02001/* Iu interface specific helper functions */
2
3/* (C) 2015 by Harald Welte <laforge@gnumonks.org>
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
Harald Welte393f2bd2015-09-11 17:13:51 +020021#include <stdint.h>
Harald Welte1d2c39d2015-09-11 17:49:37 +020022#include <string.h>
Harald Welte393f2bd2015-09-11 17:13:51 +020023
24#include <osmocom/core/utils.h>
25
Harald Welte77847ad2015-10-06 22:07:04 +020026/* decode a BCD-string as used inside ASN.1 encoded Iu interface protocols */
Harald Welte056984f2016-01-03 16:31:31 +010027int ranap_bcd_decode(char *out, size_t out_len, const uint8_t *in, size_t in_len)
Harald Welte393f2bd2015-09-11 17:13:51 +020028{
29 const uint8_t *ch;
30 char *outch = out;
31
32 for (ch = in; ch < in + in_len; ch++) {
33 char c = osmo_bcd2char(*ch & 0xF);
34 *outch++ = c;
35 if (outch + 1 >= out + out_len)
36 break;
37 c = osmo_bcd2char(*ch >> 4);
38 /* skip padding nibble at end */
39 if (c == 'F')
40 break;
41 *outch++ = c;
42 }
43 *outch++ = '\0';
44 return outch - out;
45}
46
Harald Welte77847ad2015-10-06 22:07:04 +020047/* decode an IMSI as used inside ASN.1 encoded Iu interface protocols */
Harald Welte056984f2016-01-03 16:31:31 +010048int ranap_imsi_encode(uint8_t *out, size_t out_len, const char *in)
Harald Welte393f2bd2015-09-11 17:13:51 +020049{
50 unsigned int len = strlen(in);
Harald Welte208b7b02015-09-11 17:35:52 +020051 unsigned int octlen;
Harald Welte393f2bd2015-09-11 17:13:51 +020052 uint8_t odd = (len & 0x01) == 1;
53 unsigned int off = 0;
54 unsigned int i;
55
Harald Welte208b7b02015-09-11 17:35:52 +020056 octlen = len/2;
Harald Welte393f2bd2015-09-11 17:13:51 +020057 if (odd)
Harald Welte208b7b02015-09-11 17:35:52 +020058 octlen++;
Harald Welte393f2bd2015-09-11 17:13:51 +020059
Harald Welte208b7b02015-09-11 17:35:52 +020060 for (i = 0; i < octlen; i++) {
Harald Welte393f2bd2015-09-11 17:13:51 +020061 uint8_t lower, upper;
62
Harald Welte208b7b02015-09-11 17:35:52 +020063 lower = osmo_char2bcd(in[off++]) & 0x0f;
64 if (odd && off == len)
Harald Welte393f2bd2015-09-11 17:13:51 +020065 upper = 0x0f;
66 else
Harald Welte208b7b02015-09-11 17:35:52 +020067 upper = osmo_char2bcd(in[off++]) & 0x0f;
Harald Welte393f2bd2015-09-11 17:13:51 +020068
69 out[i] = (upper << 4) | lower;
70 }
71 return i;
72}