blob: 28149c0233f877af58e87b0e80f3234905bcb694 [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file gsmtap_util.c
2 * GSMTAP support code in libosmocore. */
Harald Weltee779c362010-06-29 20:51:13 +02003/*
Harald Welte93713a52017-07-12 23:43:40 +02004 * (C) 2010-2017 by Harald Welte <laforge@gnumonks.org>
Harald Weltee779c362010-06-29 20:51:13 +02005 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24#include "../config.h"
25
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010026#include <osmocom/core/gsmtap_util.h>
27#include <osmocom/core/logging.h>
28#include <osmocom/core/gsmtap.h>
29#include <osmocom/core/msgb.h>
Harald Welte33cb71a2011-05-21 18:54:32 +020030#include <osmocom/core/talloc.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010031#include <osmocom/core/select.h>
Harald Welte33cb71a2011-05-21 18:54:32 +020032#include <osmocom/core/socket.h>
Harald Welte95871da2017-05-15 12:11:36 +020033#include <osmocom/core/byteswap.h>
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010034#include <osmocom/gsm/protocol/gsm_04_08.h>
35#include <osmocom/gsm/rsl.h>
Harald Weltee779c362010-06-29 20:51:13 +020036
Harald Welte33cb71a2011-05-21 18:54:32 +020037#include <sys/types.h>
Harald Weltee4764422011-05-22 12:25:57 +020038
Harald Weltee779c362010-06-29 20:51:13 +020039#include <stdio.h>
40#include <unistd.h>
41#include <stdint.h>
42#include <string.h>
43#include <errno.h>
44
Harald Welte47379ca2011-08-17 16:35:24 +020045/*! \addtogroup gsmtap
46 * @{
Neels Hofmeyr17518fe2017-06-20 04:35:06 +020047 * GSMTAP utility routines. Encapsulates GSM messages over UDP.
48 *
49 * \file gsmtap_util.c */
Harald Welte47379ca2011-08-17 16:35:24 +020050
51
Neels Hofmeyr87e45502017-06-20 00:17:59 +020052/*! convert RSL channel number to GSMTAP channel type
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +010053 * \param[in] rsl_chantype RSL channel type
Harald Welte47379ca2011-08-17 16:35:24 +020054 * \param[in] link_id RSL link identifier
55 * \returns GSMTAP channel type
56 */
Harald Weltee779c362010-06-29 20:51:13 +020057uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t link_id)
58{
59 uint8_t ret = GSMTAP_CHANNEL_UNKNOWN;
60
61 switch (rsl_chantype) {
62 case RSL_CHAN_Bm_ACCHs:
63 ret = GSMTAP_CHANNEL_TCH_F;
64 break;
65 case RSL_CHAN_Lm_ACCHs:
66 ret = GSMTAP_CHANNEL_TCH_H;
67 break;
68 case RSL_CHAN_SDCCH4_ACCH:
69 ret = GSMTAP_CHANNEL_SDCCH4;
70 break;
71 case RSL_CHAN_SDCCH8_ACCH:
72 ret = GSMTAP_CHANNEL_SDCCH8;
73 break;
74 case RSL_CHAN_BCCH:
75 ret = GSMTAP_CHANNEL_BCCH;
76 break;
77 case RSL_CHAN_RACH:
78 ret = GSMTAP_CHANNEL_RACH;
79 break;
80 case RSL_CHAN_PCH_AGCH:
81 /* it could also be AGCH... */
82 ret = GSMTAP_CHANNEL_PCH;
83 break;
Harald Welte3b7cd0b2017-07-27 14:12:15 +020084 case RSL_CHAN_OSMO_PDCH:
85 ret = GSMTAP_CHANNEL_PDCH;
86 break;
Harald Weltee779c362010-06-29 20:51:13 +020087 }
88
89 if (link_id & 0x40)
90 ret |= GSMTAP_CHANNEL_ACCH;
91
92 return ret;
93}
94
Harald Welte93713a52017-07-12 23:43:40 +020095/*! convert GSMTAP channel type to RSL channel number + Link ID
96 * \param[in] gsmtap_chantype GSMTAP channel type
97 * \param[out] rsl_chantype RSL channel mumber
98 * \param[out] link_id RSL link identifier
99 */
100void chantype_gsmtap2rsl(uint8_t gsmtap_chantype, uint8_t *rsl_chantype,
101 uint8_t *link_id)
102{
103 switch (gsmtap_chantype & ~GSMTAP_CHANNEL_ACCH & 0xff) {
104 case GSMTAP_CHANNEL_TCH_F: // TCH/F, FACCH/F
105 *rsl_chantype = RSL_CHAN_Bm_ACCHs;
106 break;
107 case GSMTAP_CHANNEL_TCH_H: // TCH/H, FACCH/H
108 *rsl_chantype = RSL_CHAN_Lm_ACCHs;
109 break;
110 case GSMTAP_CHANNEL_SDCCH4: // SDCCH/4
111 *rsl_chantype = RSL_CHAN_SDCCH4_ACCH;
112 break;
113 case GSMTAP_CHANNEL_SDCCH8: // SDCCH/8
114 *rsl_chantype = RSL_CHAN_SDCCH8_ACCH;
115 break;
116 case GSMTAP_CHANNEL_BCCH: // BCCH
117 *rsl_chantype = RSL_CHAN_BCCH;
118 break;
119 case GSMTAP_CHANNEL_RACH: // RACH
120 *rsl_chantype = RSL_CHAN_RACH;
121 break;
122 case GSMTAP_CHANNEL_PCH: // PCH
123 case GSMTAP_CHANNEL_AGCH: // AGCH
124 *rsl_chantype = RSL_CHAN_PCH_AGCH;
125 break;
126 case GSMTAP_CHANNEL_PDCH:
Harald Welte3b7cd0b2017-07-27 14:12:15 +0200127 *rsl_chantype = RSL_CHAN_OSMO_PDCH;
Harald Welte93713a52017-07-12 23:43:40 +0200128 break;
129 }
130
131 *link_id = gsmtap_chantype & GSMTAP_CHANNEL_ACCH ? 0x40 : 0x00;
132}
133
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200134/*! create an arbitrary type GSMTAP message
Sylvain Munautabf66e72011-09-26 13:23:19 +0200135 * \param[in] type The GSMTAP_TYPE_xxx constant of the message to create
Harald Welte47379ca2011-08-17 16:35:24 +0200136 * \param[in] arfcn GSM ARFCN (Channel Number)
137 * \param[in] ts GSM time slot
138 * \param[in] chan_type Channel Type
139 * \param[in] ss Sub-slot
140 * \param[in] fn GSM Frame Number
141 * \param[in] signal_dbm Signal Strength (dBm)
142 * \param[in] snr Signal/Noise Ratio (SNR)
143 * \param[in] data Pointer to data buffer
144 * \param[in] len Length of \ref data
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200145 * \return dynamically allocated message buffer containing data
Harald Welte47379ca2011-08-17 16:35:24 +0200146 *
147 * This function will allocate a new msgb and fill it with a GSMTAP
148 * header containing the information
149 */
Sylvain Munaut15ae7152011-09-26 13:05:07 +0200150struct msgb *gsmtap_makemsg_ex(uint8_t type, uint16_t arfcn, uint8_t ts, uint8_t chan_type,
Harald Weltee34a9402010-06-29 22:31:21 +0200151 uint8_t ss, uint32_t fn, int8_t signal_dbm,
152 uint8_t snr, const uint8_t *data, unsigned int len)
Harald Weltee779c362010-06-29 20:51:13 +0200153{
154 struct msgb *msg;
155 struct gsmtap_hdr *gh;
156 uint8_t *dst;
157
Harald Weltee779c362010-06-29 20:51:13 +0200158 msg = msgb_alloc(sizeof(*gh) + len, "gsmtap_tx");
159 if (!msg)
Harald Weltee34a9402010-06-29 22:31:21 +0200160 return NULL;
Harald Weltee779c362010-06-29 20:51:13 +0200161
162 gh = (struct gsmtap_hdr *) msgb_put(msg, sizeof(*gh));
163
164 gh->version = GSMTAP_VERSION;
165 gh->hdr_len = sizeof(*gh)/4;
Sylvain Munaut15ae7152011-09-26 13:05:07 +0200166 gh->type = type;
Harald Weltee779c362010-06-29 20:51:13 +0200167 gh->timeslot = ts;
168 gh->sub_slot = ss;
Harald Welte95871da2017-05-15 12:11:36 +0200169 gh->arfcn = osmo_htons(arfcn);
Harald Weltee779c362010-06-29 20:51:13 +0200170 gh->snr_db = snr;
171 gh->signal_dbm = signal_dbm;
Harald Welte95871da2017-05-15 12:11:36 +0200172 gh->frame_number = osmo_htonl(fn);
Harald Weltee779c362010-06-29 20:51:13 +0200173 gh->sub_type = chan_type;
174 gh->antenna_nr = 0;
175
176 dst = msgb_put(msg, len);
177 memcpy(dst, data, len);
178
Harald Weltee34a9402010-06-29 22:31:21 +0200179 return msg;
180}
181
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200182/*! create L1/L2 data and put it into GSMTAP
Sylvain Munautabf66e72011-09-26 13:23:19 +0200183 * \param[in] arfcn GSM ARFCN (Channel Number)
184 * \param[in] ts GSM time slot
185 * \param[in] chan_type Channel Type
186 * \param[in] ss Sub-slot
187 * \param[in] fn GSM Frame Number
188 * \param[in] signal_dbm Signal Strength (dBm)
189 * \param[in] snr Signal/Noise Ratio (SNR)
190 * \param[in] data Pointer to data buffer
191 * \param[in] len Length of \ref data
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200192 * \return message buffer or NULL in case of error
Sylvain Munautabf66e72011-09-26 13:23:19 +0200193 *
194 * This function will allocate a new msgb and fill it with a GSMTAP
195 * header containing the information
196 */
Sylvain Munaut15ae7152011-09-26 13:05:07 +0200197struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
198 uint8_t ss, uint32_t fn, int8_t signal_dbm,
199 uint8_t snr, const uint8_t *data, unsigned int len)
200{
201 return gsmtap_makemsg_ex(GSMTAP_TYPE_UM, arfcn, ts, chan_type,
202 ss, fn, signal_dbm, snr, data, len);
203}
204
Harald Weltee4764422011-05-22 12:25:57 +0200205#ifdef HAVE_SYS_SOCKET_H
206
207#include <sys/socket.h>
208#include <netinet/in.h>
209
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200210/*! Create a new (sending) GSMTAP source socket
Harald Welte47379ca2011-08-17 16:35:24 +0200211 * \param[in] host host name or IP address in string format
212 * \param[in] port UDP port number in host byte order
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200213 * \return file descriptor of the new socket
Harald Welte47379ca2011-08-17 16:35:24 +0200214 *
215 * Opens a GSMTAP source (sending) socket, conncet it to host/port and
216 * return resulting fd. If \a host is NULL, the destination address
217 * will be localhost. If \a port is 0, the default \ref
218 * GSMTAP_UDP_PORT will be used.
219 * */
Harald Welte33cb71a2011-05-21 18:54:32 +0200220int gsmtap_source_init_fd(const char *host, uint16_t port)
221{
222 if (port == 0)
223 port = GSMTAP_UDP_PORT;
224 if (host == NULL)
225 host = "localhost";
226
Pablo Neira Ayuso0849c9a2011-06-09 15:04:30 +0200227 return osmo_sock_init(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, host, port,
228 OSMO_SOCK_F_CONNECT);
Harald Welte33cb71a2011-05-21 18:54:32 +0200229}
230
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200231/*! Add a local sink to an existing GSMTAP source and return fd
Harald Weltede6e4982012-12-06 21:25:27 +0100232 * \param[in] gsmtap_fd file descriptor of the gsmtap socket
233 * \returns file descriptor of locally bound receive socket
234 *
235 * In case the GSMTAP socket is connected to a local destination
236 * IP/port, this function creates a corresponding receiving socket
237 * bound to that destination IP + port.
238 *
239 * In case the gsmtap socket is not connected to a local IP/port, or
240 * creation of the receiving socket fails, a negative error code is
241 * returned.
242 */
Harald Welte33cb71a2011-05-21 18:54:32 +0200243int gsmtap_source_add_sink_fd(int gsmtap_fd)
244{
245 struct sockaddr_storage ss;
246 socklen_t ss_len = sizeof(ss);
247 int rc;
248
249 rc = getpeername(gsmtap_fd, (struct sockaddr *)&ss, &ss_len);
250 if (rc < 0)
251 return rc;
252
253 if (osmo_sockaddr_is_local((struct sockaddr *)&ss, ss_len) == 1) {
Pablo Neira Ayuso0849c9a2011-06-09 15:04:30 +0200254 rc = osmo_sock_init_sa((struct sockaddr *)&ss, SOCK_DGRAM,
255 IPPROTO_UDP, OSMO_SOCK_F_BIND);
Harald Welte33cb71a2011-05-21 18:54:32 +0200256 if (rc >= 0)
257 return rc;
258 }
259
260 return -ENODEV;
261}
262
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200263/*! Send a \ref msgb through a GSMTAP source
Harald Welte47379ca2011-08-17 16:35:24 +0200264 * \param[in] gti GSMTAP instance
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +0100265 * \param[in] msg message buffer
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200266 * \return 0 in case of success; negative in case of error
Harald Welte47379ca2011-08-17 16:35:24 +0200267 */
Harald Welte33cb71a2011-05-21 18:54:32 +0200268int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg)
269{
Harald Welte13692a62011-05-22 20:06:11 +0200270 if (!gti)
271 return -ENODEV;
272
Harald Welte33cb71a2011-05-21 18:54:32 +0200273 if (gti->ofd_wq_mode)
274 return osmo_wqueue_enqueue(&gti->wq, msg);
275 else {
276 /* try immediate send and return error if any */
277 int rc;
278
279 rc = write(gsmtap_inst_fd(gti), msg->data, msg->len);
280 if (rc <= 0) {
281 return rc;
282 } else if (rc >= msg->len) {
283 msgb_free(msg);
284 return 0;
285 } else {
286 /* short write */
287 return -EIO;
288 }
289 }
290}
291
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200292/*! send an arbitrary type through GSMTAP.
Sylvain Munautabf66e72011-09-26 13:23:19 +0200293 * See \ref gsmtap_makemsg_ex for arguments
294 */
Sylvain Munaut15ae7152011-09-26 13:05:07 +0200295int gsmtap_send_ex(struct gsmtap_inst *gti, uint8_t type, uint16_t arfcn, uint8_t ts,
Harald Welte33cb71a2011-05-21 18:54:32 +0200296 uint8_t chan_type, uint8_t ss, uint32_t fn,
297 int8_t signal_dbm, uint8_t snr, const uint8_t *data,
298 unsigned int len)
Harald Weltee34a9402010-06-29 22:31:21 +0200299{
300 struct msgb *msg;
301
Harald Welte13692a62011-05-22 20:06:11 +0200302 if (!gti)
303 return -ENODEV;
304
Sylvain Munaut15ae7152011-09-26 13:05:07 +0200305 msg = gsmtap_makemsg_ex(type, arfcn, ts, chan_type, ss, fn, signal_dbm,
Harald Weltee34a9402010-06-29 22:31:21 +0200306 snr, data, len);
307 if (!msg)
308 return -ENOMEM;
309
Harald Welte33cb71a2011-05-21 18:54:32 +0200310 return gsmtap_sendmsg(gti, msg);
Harald Weltee779c362010-06-29 20:51:13 +0200311}
312
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200313/*! send a message from L1/L2 through GSMTAP.
Sylvain Munautabf66e72011-09-26 13:23:19 +0200314 * See \ref gsmtap_makemsg for arguments
315 */
Sylvain Munaut15ae7152011-09-26 13:05:07 +0200316int gsmtap_send(struct gsmtap_inst *gti, uint16_t arfcn, uint8_t ts,
317 uint8_t chan_type, uint8_t ss, uint32_t fn,
318 int8_t signal_dbm, uint8_t snr, const uint8_t *data,
319 unsigned int len)
320{
321 return gsmtap_send_ex(gti, GSMTAP_TYPE_UM, arfcn, ts, chan_type, ss, fn,
322 signal_dbm, snr, data, len);
323}
324
Harald Weltee779c362010-06-29 20:51:13 +0200325/* Callback from select layer if we can write to the socket */
Harald Welte33cb71a2011-05-21 18:54:32 +0200326static int gsmtap_wq_w_cb(struct osmo_fd *ofd, struct msgb *msg)
Harald Weltee779c362010-06-29 20:51:13 +0200327{
Harald Weltee779c362010-06-29 20:51:13 +0200328 int rc;
329
Harald Welte33cb71a2011-05-21 18:54:32 +0200330 rc = write(ofd->fd, msg->data, msg->len);
Harald Weltee779c362010-06-29 20:51:13 +0200331 if (rc < 0) {
Harald Weltee779c362010-06-29 20:51:13 +0200332 return rc;
333 }
334 if (rc != msg->len) {
Harald Weltee779c362010-06-29 20:51:13 +0200335 return -EIO;
336 }
337
Harald Weltee779c362010-06-29 20:51:13 +0200338 return 0;
339}
340
Harald Welted58ba462011-04-27 10:57:49 +0200341/* Callback from select layer if we can read from the sink socket */
Pablo Neira Ayusof7f89d02011-05-07 12:42:40 +0200342static int gsmtap_sink_fd_cb(struct osmo_fd *fd, unsigned int flags)
Harald Welted58ba462011-04-27 10:57:49 +0200343{
344 int rc;
345 uint8_t buf[4096];
346
347 if (!(flags & BSC_FD_READ))
348 return 0;
349
350 rc = read(fd->fd, buf, sizeof(buf));
351 if (rc < 0) {
Harald Welted58ba462011-04-27 10:57:49 +0200352 return rc;
353 }
354 /* simply discard any data arriving on the socket */
355
356 return 0;
357}
358
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200359/*! Add a local sink to an existing GSMTAP source and return fd
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200360 * \param[in] gsmtap_fd file descriptor of the gsmtap socket
361 * \returns file descriptor of locally bound receive socket
362 *
363 * In case the GSMTAP socket is connected to a local destination
364 * IP/port, this function creates a corresponding receiving socket
365 * bound to that destination IP + port.
366 *
367 * In case the gsmtap socket is not connected to a local IP/port, or
368 * creation of the receiving socket fails, a negative error code is
369 * returned.
370 *
371 * The file descriptor of the receiving socket is automatically added
372 * to the libosmocore select() handling.
373 */
Harald Welte33cb71a2011-05-21 18:54:32 +0200374int gsmtap_source_add_sink(struct gsmtap_inst *gti)
Harald Welted58ba462011-04-27 10:57:49 +0200375{
Harald Welte9d862c82016-11-26 00:10:07 +0100376 int fd, rc;
Harald Welted58ba462011-04-27 10:57:49 +0200377
Harald Welte33cb71a2011-05-21 18:54:32 +0200378 fd = gsmtap_source_add_sink_fd(gsmtap_inst_fd(gti));
379 if (fd < 0)
380 return fd;
Harald Welted58ba462011-04-27 10:57:49 +0200381
Harald Welte33cb71a2011-05-21 18:54:32 +0200382 if (gti->ofd_wq_mode) {
383 struct osmo_fd *sink_ofd;
384
385 sink_ofd = &gti->sink_ofd;
386 sink_ofd->fd = fd;
387 sink_ofd->when = BSC_FD_READ;
388 sink_ofd->cb = gsmtap_sink_fd_cb;
389
Harald Welte9d862c82016-11-26 00:10:07 +0100390 rc = osmo_fd_register(sink_ofd);
391 if (rc < 0) {
392 close(fd);
393 return rc;
394 }
Harald Welted58ba462011-04-27 10:57:49 +0200395 }
396
Harald Welte33cb71a2011-05-21 18:54:32 +0200397 return fd;
398}
Harald Welted58ba462011-04-27 10:57:49 +0200399
Harald Welte47379ca2011-08-17 16:35:24 +0200400
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200401/*! Open GSMTAP source socket, connect and register osmo_fd
Harald Welte47379ca2011-08-17 16:35:24 +0200402 * \param[in] host host name or IP address in string format
403 * \param[in] port UDP port number in host byte order
Katerina Barone-Adesic28c6a02013-02-15 13:27:59 +0100404 * \param[in] ofd_wq_mode Register \ref osmo_wqueue (1) or not (0)
Harald Welte2d2e2cc2016-04-25 12:11:20 +0200405 * \return callee-allocated \ref gsmtap_inst
Harald Welte47379ca2011-08-17 16:35:24 +0200406 *
407 * Open GSMTAP source (sending) socket, connect it to host/port,
408 * allocate 'struct gsmtap_inst' and optionally osmo_fd/osmo_wqueue
409 * registration. This means it is like \ref gsmtap_init2 but integrated
410 * with libosmocore \ref select */
Harald Welte33cb71a2011-05-21 18:54:32 +0200411struct gsmtap_inst *gsmtap_source_init(const char *host, uint16_t port,
412 int ofd_wq_mode)
413{
414 struct gsmtap_inst *gti;
Harald Welte9d862c82016-11-26 00:10:07 +0100415 int fd, rc;
Harald Welted58ba462011-04-27 10:57:49 +0200416
Harald Welte33cb71a2011-05-21 18:54:32 +0200417 fd = gsmtap_source_init_fd(host, port);
418 if (fd < 0)
419 return NULL;
420
421 gti = talloc_zero(NULL, struct gsmtap_inst);
422 gti->ofd_wq_mode = ofd_wq_mode;
423 gti->wq.bfd.fd = fd;
424 gti->sink_ofd.fd = -1;
425
426 if (ofd_wq_mode) {
427 osmo_wqueue_init(&gti->wq, 64);
428 gti->wq.write_cb = &gsmtap_wq_w_cb;
429
Harald Welte9d862c82016-11-26 00:10:07 +0100430 rc = osmo_fd_register(&gti->wq.bfd);
431 if (rc < 0) {
432 close(fd);
433 return NULL;
434 }
Harald Welte33cb71a2011-05-21 18:54:32 +0200435 }
436
437 return gti;
Harald Welted58ba462011-04-27 10:57:49 +0200438}
439
Harald Weltee4764422011-05-22 12:25:57 +0200440#endif /* HAVE_SYS_SOCKET_H */
Harald Weltede6e4982012-12-06 21:25:27 +0100441
Harald Welteaa3ba462017-07-13 00:01:02 +0200442const struct value_string gsmtap_gsm_channel_names[] = {
443 { GSMTAP_CHANNEL_UNKNOWN, "UNKNOWN" },
444 { GSMTAP_CHANNEL_BCCH, "BCCH" },
445 { GSMTAP_CHANNEL_CCCH, "CCCH" },
446 { GSMTAP_CHANNEL_RACH, "RACH" },
447 { GSMTAP_CHANNEL_AGCH, "AGCH" },
448 { GSMTAP_CHANNEL_PCH, "PCH" },
449 { GSMTAP_CHANNEL_SDCCH, "SDCCH" },
450 { GSMTAP_CHANNEL_SDCCH4, "SDCCH/4" },
451 { GSMTAP_CHANNEL_SDCCH8, "SDCCH/8" },
452 { GSMTAP_CHANNEL_TCH_F, "TCH/F/FACCH/F" },
453 { GSMTAP_CHANNEL_TCH_H, "TCH/H/FACCH/H" },
454 { GSMTAP_CHANNEL_PACCH, "PACCH" },
455 { GSMTAP_CHANNEL_CBCH52, "CBCH" },
456 { GSMTAP_CHANNEL_PDCH, "PDCH" } ,
457 { GSMTAP_CHANNEL_PTCCH, "PTTCH" },
458 { GSMTAP_CHANNEL_CBCH51, "CBCH" },
459 { GSMTAP_CHANNEL_ACCH | GSMTAP_CHANNEL_SDCCH, "LSACCH" },
460 { GSMTAP_CHANNEL_ACCH | GSMTAP_CHANNEL_SDCCH4, "SACCH/4" },
461 { GSMTAP_CHANNEL_ACCH | GSMTAP_CHANNEL_SDCCH8, "SACCH/8" },
462 { GSMTAP_CHANNEL_ACCH | GSMTAP_CHANNEL_TCH_F, "SACCH/F" },
463 { GSMTAP_CHANNEL_ACCH | GSMTAP_CHANNEL_TCH_H, "SACCH/H" },
464 { 0, NULL }
465};
466
467/* for debugging */
468const struct value_string gsmtap_type_names[] = {
469 { GSMTAP_TYPE_UM, "GSM Um (MS<->BTS)" },
470 { GSMTAP_TYPE_ABIS, "GSM Abis (BTS<->BSC)" },
471 { GSMTAP_TYPE_UM_BURST, "GSM Um burst (MS<->BTS)" },
472 { GSMTAP_TYPE_SIM, "SIM Card" },
473 { GSMTAP_TYPE_TETRA_I1, "TETRA V+D" },
474 { GSMTAP_TYPE_TETRA_I1_BURST, "TETRA bursts" },
475 { GSMTAP_TYPE_WMX_BURST, "WiMAX burst" },
476 { GSMTAP_TYPE_GMR1_UM, "GMR-1 air interfeace (MES-MS<->GTS)"},
477 { GSMTAP_TYPE_UMTS_RLC_MAC, "UMTS RLC/MAC" },
478 { GSMTAP_TYPE_UMTS_RRC, "UMTS RRC" },
479 { GSMTAP_TYPE_LTE_RRC, "LTE RRC" },
480 { GSMTAP_TYPE_LTE_MAC, "LTE MAC" },
481 { GSMTAP_TYPE_LTE_MAC_FRAMED, "LTE MAC with context hdr" },
482 { GSMTAP_TYPE_OSMOCORE_LOG, "libosmocore logging" },
483 { GSMTAP_TYPE_QC_DIAG, "Qualcomm DIAG" },
484 { 0, NULL }
485};
486
Harald Weltede6e4982012-12-06 21:25:27 +0100487/*! @} */