blob: a25479f1b9f703857d3626de6427673e6a3bfe85 [file] [log] [blame]
Harald Welted284cd92010-03-01 21:58:31 +01001
2#include <string.h>
3#include <stdint.h>
4#include <errno.h>
Harald Welteb59f9352010-03-25 11:37:04 +08005#include <stdio.h>
Harald Welted284cd92010-03-01 21:58:31 +01006
Pablo Neira Ayuso83419342011-03-22 16:36:13 +01007#include <osmocom/core/utils.h>
Harald Welted284cd92010-03-01 21:58:31 +01008
Harald Welte8598f182011-08-17 14:19:27 +02009/*! \addtogroup utils
10 * @{
11 */
12
13/*! \file utils.c */
14
Harald Welteb59f9352010-03-25 11:37:04 +080015static char namebuf[255];
Harald Welte8598f182011-08-17 14:19:27 +020016
17/*! \brief get human-readable string for given value
18 * \param[in] vs Array of value_string tuples
19 * \param[in] val Value to be converted
20 * \returns pointer to human-readable string
21 */
Harald Welted284cd92010-03-01 21:58:31 +010022const char *get_value_string(const struct value_string *vs, uint32_t val)
23{
24 int i;
25
26 for (i = 0;; i++) {
27 if (vs[i].value == 0 && vs[i].str == NULL)
28 break;
29 if (vs[i].value == val)
30 return vs[i].str;
31 }
Harald Welteb59f9352010-03-25 11:37:04 +080032
33 snprintf(namebuf, sizeof(namebuf), "unknown 0x%x", val);
34 return namebuf;
Harald Welted284cd92010-03-01 21:58:31 +010035}
36
Harald Welte8598f182011-08-17 14:19:27 +020037/*! \brief get numeric value for given human-readable string
38 * \param[in] vs Array of value_string tuples
39 * \param[in] str human-readable string
40 * \returns numeric value (>0) or negative numer in case of error
41 */
Harald Welted284cd92010-03-01 21:58:31 +010042int get_string_value(const struct value_string *vs, const char *str)
43{
44 int i;
45
46 for (i = 0;; i++) {
47 if (vs[i].value == 0 && vs[i].str == NULL)
48 break;
49 if (!strcasecmp(vs[i].str, str))
50 return vs[i].value;
51 }
52 return -EINVAL;
53}
Harald Weltea73e2f92010-03-04 10:50:32 +010054
Harald Welte8598f182011-08-17 14:19:27 +020055/*! \brief Convert BCD-encoded digit into printable character
56 * \param[in] bcd A single BCD-encoded digit
57 * \returns single printable character
58 */
Pablo Neira Ayuso87f7b252011-05-07 12:43:08 +020059char osmo_bcd2char(uint8_t bcd)
Harald Weltea73e2f92010-03-04 10:50:32 +010060{
61 if (bcd < 0xa)
62 return '0' + bcd;
63 else
64 return 'A' + (bcd - 0xa);
65}
66
Holger Hans Peter Freyther121f3582010-11-19 19:20:46 +010067/* only works for numbers in ascii */
Pablo Neira Ayuso87f7b252011-05-07 12:43:08 +020068uint8_t osmo_char2bcd(char c)
Harald Weltea73e2f92010-03-04 10:50:32 +010069{
70 return c - 0x30;
71}
Harald Welte3eba9912010-07-30 10:37:29 +020072
Pablo Neira Ayuso87f7b252011-05-07 12:43:08 +020073int osmo_hexparse(const char *str, uint8_t *b, int max_len)
Harald Welte3eba9912010-07-30 10:37:29 +020074
75{
76 int i, l, v;
77
78 l = strlen(str);
79 if ((l&1) || ((l>>1) > max_len))
80 return -1;
81
82 memset(b, 0x00, max_len);
83
84 for (i=0; i<l; i++) {
85 char c = str[i];
86 if (c >= '0' && c <= '9')
87 v = c - '0';
88 else if (c >= 'a' && c <= 'f')
89 v = 10 + (c - 'a');
90 else if (c >= 'A' && c <= 'F')
91 v = 10 + (c - 'A');
92 else
93 return -1;
94 b[i>>1] |= v << (i&1 ? 0 : 4);
95 }
96
97 return i>>1;
98}
Harald Welte40481e82010-07-30 11:40:32 +020099
100static char hexd_buff[4096];
101
Pablo Neira Ayuso87f7b252011-05-07 12:43:08 +0200102static char *_osmo_hexdump(const unsigned char *buf, int len, char *delim)
Harald Welte40481e82010-07-30 11:40:32 +0200103{
104 int i;
105 char *cur = hexd_buff;
106
107 hexd_buff[0] = 0;
108 for (i = 0; i < len; i++) {
109 int len_remain = sizeof(hexd_buff) - (cur - hexd_buff);
Holger Hans Peter Freyther128d9e22011-07-15 16:07:23 +0200110 if (len_remain <= 0)
111 break;
Harald Weltedee47cd2010-07-30 11:43:30 +0200112 int rc = snprintf(cur, len_remain, "%02x%s", buf[i], delim);
Harald Welte40481e82010-07-30 11:40:32 +0200113 if (rc <= 0)
114 break;
115 cur += rc;
116 }
117 hexd_buff[sizeof(hexd_buff)-1] = 0;
118 return hexd_buff;
119}
Harald Weltedee47cd2010-07-30 11:43:30 +0200120
Harald Welte8598f182011-08-17 14:19:27 +0200121/*! \brief Convert a sequence of unpacked bits to ASCII string
122 * \param[in] bits A sequence of unpacked bits
123 * \param[in] len Length of bits
124 */
Pablo Neira Ayuso87f7b252011-05-07 12:43:08 +0200125char *osmo_ubit_dump(const uint8_t *bits, unsigned int len)
Harald Welte3d0ac5e2011-02-08 16:55:03 +0100126{
127 int i;
128
129 if (len > sizeof(hexd_buff)-1)
130 len = sizeof(hexd_buff)-1;
131 memset(hexd_buff, 0, sizeof(hexd_buff));
132
133 for (i = 0; i < len; i++) {
134 char outch;
135 switch (bits[i]) {
136 case 0:
137 outch = '0';
138 break;
139 case 0xff:
140 outch = '?';
141 break;
142 case 1:
143 outch = '1';
144 break;
145 default:
146 outch = 'E';
147 break;
148 }
149 hexd_buff[i] = outch;
150 }
151 hexd_buff[sizeof(hexd_buff)-1] = 0;
152 return hexd_buff;
153}
154
Harald Welte8598f182011-08-17 14:19:27 +0200155/*! \brief Convert binary sequence to hexadecimal ASCII string
156 * \param[in] buf pointer to sequence of bytes
157 * \param[in] len length of buf in number of bytes
158 * \returns pointer to zero-terminated string
159 *
160 * This function will print a sequence of bytes as hexadecimal numbers,
161 * adding one space character between each byte (e.g. "1a ef d9")
162 */
Pablo Neira Ayuso87f7b252011-05-07 12:43:08 +0200163char *osmo_hexdump(const unsigned char *buf, int len)
Harald Weltedee47cd2010-07-30 11:43:30 +0200164{
Pablo Neira Ayuso87f7b252011-05-07 12:43:08 +0200165 return _osmo_hexdump(buf, len, " ");
Harald Weltedee47cd2010-07-30 11:43:30 +0200166}
167
Harald Welte8598f182011-08-17 14:19:27 +0200168/*! \brief Convert binary sequence to hexadecimal ASCII string
169 * \param[in] buf pointer to sequence of bytes
170 * \param[in] len length of buf in number of bytes
171 * \returns pointer to zero-terminated string
172 *
173 * This function will print a sequence of bytes as hexadecimal numbers,
174 * without any space character between each byte (e.g. "1aefd9")
175 */
Pablo Neira Ayuso87f7b252011-05-07 12:43:08 +0200176char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len)
Harald Weltedee47cd2010-07-30 11:43:30 +0200177{
Pablo Neira Ayuso87f7b252011-05-07 12:43:08 +0200178 return _osmo_hexdump(buf, len, "");
Harald Weltedee47cd2010-07-30 11:43:30 +0200179}
Harald Welte28222962011-02-18 20:37:04 +0100180
181#include "../config.h"
182#ifdef HAVE_CTYPE_H
183#include <ctype.h>
Harald Welte8598f182011-08-17 14:19:27 +0200184/*! \brief Convert an entire string to lower case
185 * \param[out] out output string, caller-allocated
186 * \param[in] in input string
187 */
Harald Welte28222962011-02-18 20:37:04 +0100188void osmo_str2lower(char *out, const char *in)
189{
190 unsigned int i;
191
192 for (i = 0; i < strlen(in); i++)
193 out[i] = tolower(in[i]);
194 out[strlen(in)] = '\0';
195}
196
Harald Welte8598f182011-08-17 14:19:27 +0200197/*! \brief Convert an entire string to upper case
198 * \param[out] out output string, caller-allocated
199 * \param[in] in input string
200 */
Harald Welte28222962011-02-18 20:37:04 +0100201void osmo_str2upper(char *out, const char *in)
202{
203 unsigned int i;
204
205 for (i = 0; i < strlen(in); i++)
206 out[i] = toupper(in[i]);
207 out[strlen(in)] = '\0';
208}
209#endif /* HAVE_CTYPE_H */
Harald Welte8598f182011-08-17 14:19:27 +0200210
211/*! }@ */