Compare commits
7 Commits
master
...
hoernchen/
Author | SHA1 | Date |
---|---|---|
Eric Wild | acb80088b3 | |
Eric Wild | 4846c50521 | |
Eric Wild | 700ed13d11 | |
Eric Wild | a3ffa99436 | |
Eric Wild | 58111310e6 | |
Eric Wild | 6f9290d7b9 | |
Eric Wild | a8ea2dc983 |
37
README
37
README
|
@ -9,3 +9,40 @@ the necessary utility.
|
|||
In general all Qualcomm devices that export DIAG should be
|
||||
supported. We have tested it with the Quectel UC20, EC20 and
|
||||
EC25 devices.
|
||||
|
||||
The convenient way to create a pcap dump of the messages is to run
|
||||
./capture.sh -s /dev/ttyUSB0 -f outfilename.pcap
|
||||
This requires tcpdump, as well as the required permissions
|
||||
to capture, i.e. on ubuntu this can be conveniently achieved by
|
||||
sudo setcap cap_net_raw,cap_net_admin=ep /usr/sbin/tcpdump
|
||||
|
||||
In order to distinguish multiple different modems in the capture file
|
||||
passing a GSMTAP destination ip is possible with the -i parameter, i.e.
|
||||
./capture.sh -s /dev/ttyUSB0 -f outfilename.pcap -i 127.0.0.4
|
||||
This will "just work" on linux, since there is a default 127.0.0.0/8 route.
|
||||
|
||||
Additionally wireshark needs Edit->Preferences->Protocols->NAS-EPS
|
||||
"Force dissect as plain EPS" set to true, since capturing encrypted NAS
|
||||
messages is fairly useless (although possible), so unencrypted
|
||||
unprotected NAS messages are emitted, but wireshark will by default
|
||||
refuse to dissect plain messages because according to the spec most
|
||||
messages need to be at least integrity protected.
|
||||
|
||||
Ubuntus ModemManager will interfere with the modem, so it needs to be
|
||||
told to leave the modem alone. This can be accomplished by adding the
|
||||
following line to
|
||||
/etc/udev/rules.d/69-block-mm.rules :
|
||||
ATTRS{idVendor}=="2c7c" ATTRS{idProduct}=="0125", ENV{ID_MM_DEVICE_IGNORE}="1
|
||||
|
||||
This example is for quectel ec25-e, adjust the USB VID:PID according to
|
||||
what lsusb tells you about your particular modem. The rules then need to
|
||||
be reloaded and ModemManager restarted:
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger
|
||||
sudo systemctl restart ModemManager
|
||||
|
||||
There appears to be a bug on Ubuntu 18.04 and the ModemManager will still
|
||||
interfere, see
|
||||
https://bugs.launchpad.net/ubuntu/+source/modemmanager/+bug/1827328
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
-s|--serialpath) serialpath="$2"; shift ;;
|
||||
-i|--ip) gsmtapip="$2"; shift ;;
|
||||
-f|--filename) filename="$2"; shift ;;
|
||||
-Q|--qcdebug) qcdebug=1 ;;
|
||||
*) echo "unknown parameter: $1"; exit 1 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
#killall tcpdump
|
||||
|
||||
if [ -n "$gsmtapip" ]; then
|
||||
tcpdump -i any udp port 4729 and dst $gsmtapip -w $filename &
|
||||
tcpdump_pid=$!
|
||||
./src/osmo-qcdiag-log -s $serialpath -G -i $gsmtapip
|
||||
else
|
||||
tcpdump -i any udp port 4729 -w $filename &
|
||||
tcpdump_pid=$!
|
||||
./src/osmo-qcdiag-log -s $serialpath -G
|
||||
fi
|
||||
|
||||
kill -9 $tcpdump_pid
|
|
@ -2,7 +2,7 @@ CPPFLAGS ?= -g -O0 -Wall `pkg-config --cflags libosmocore` `pkg-config --cflags
|
|||
LIBS ?= `pkg-config --libs libosmocore` `pkg-config --libs qmi-glib`
|
||||
all: osmo-qcdiag-log
|
||||
|
||||
MODS_LOG = gprs_l1.c gprs_rlc.o gprs_mac.o diag_gsm.o diag_log.o diag_log_gsm.o diag_log_gprs.o diag_log_wcdma.o diag_log_umts.o diag_log_qmi.o diag_dpl.o diag_log_simcard.o diag_event.o
|
||||
MODS_LOG = gprs_l1.c gprs_rlc.o gprs_mac.o diag_gsm.o diag_log.o diag_log_gsm.o diag_log_gprs.o diag_log_wcdma.o diag_log_umts.o diag_log_lte.o diag_log_qmi.o diag_dpl.o diag_log_simcard.o diag_event.o
|
||||
|
||||
osmo-qcdiag-log: diagchar_hdlc.o diag_io.o osmo-qcdiag-log.o diag_msg.o protocol.o diag_cmd.o $(MODS_LOG)
|
||||
$(CC) $(CPPFLAGS) -o $@ $^ $(LIBS)
|
||||
|
|
|
@ -51,8 +51,7 @@ int diag_process_msg(struct diag_instance *di, struct msgb *msg)
|
|||
uint8_t cmd = msg->l2h[0];
|
||||
|
||||
if (di->gsmtap) {
|
||||
gsmtap_send_ex(di->gsmtap, GSMTAP_TYPE_QC_DIAG, 0, 0, 0,
|
||||
0, 0, 0, 0, msgb_l2(msg), msgb_l2len(msg));
|
||||
// process(di, msgb_l2(msg), msgb_l2len(msg));
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -75,6 +74,8 @@ int diag_process_msg(struct diag_instance *di, struct msgb *msg)
|
|||
msgb_free(msg);
|
||||
return 1;
|
||||
} else {
|
||||
/* swallow config messages */
|
||||
if(msg->l2h[0] != DIAG_LOG_CONFIG_F && msg->l2h[0] != DIAG_EXT_MSG_CONFIG_F)
|
||||
printf("Got %d bytes data of unknown payload type 0x%02x: %s\n",
|
||||
msgb_length(msg), msg->l2h[0],
|
||||
osmo_hexdump(msgb_data(msg), msgb_length(msg)));
|
||||
|
|
|
@ -120,7 +120,7 @@ int diag_dpl_set_if_log(struct diag_instance *di, uint8_t iface_id,
|
|||
/* LOG_DATA_PROTOCOL_LOGGING_C must be enabled */
|
||||
/* dpli_log_full_packet() used to log packet; maximum of 256 bytes per
|
||||
* diag message; DPLI_BUILD_LOG_PACKET */
|
||||
static void handle_pcap_msg(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_pcap_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct dpl_hdr *dh = (struct dpl_hdr *) msgb_data(msg);
|
||||
printf("PCAP(fl=0x%02x, ifn=0x%02x, prot=0x%02x, inst=%u, seq=%u, seg=%u): %s\n",
|
||||
|
@ -133,7 +133,9 @@ static const struct diag_log_dispatch_tbl log_tbl[] = {
|
|||
{ L1X(LOG_DATA_PROTOCOL_LOGGING_C), handle_pcap_msg },
|
||||
};
|
||||
|
||||
#if 0
|
||||
static __attribute__((constructor)) void on_dso_load_gsm(void)
|
||||
{
|
||||
diag_log_reg_dispatch(log_tbl, ARRAY_SIZE(log_tbl));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -152,8 +152,9 @@ static void diag_rx_event_report_f(struct diag_instance *di, struct msgb *msg)
|
|||
static const struct diag_cmd_dispatch_tbl cmd_tbl[] = {
|
||||
{ DIAG_EVENT_REPORT_F, diag_rx_event_report_f },
|
||||
};
|
||||
|
||||
#if 0
|
||||
static __attribute__((constructor)) void on_dso_load_event(void)
|
||||
{
|
||||
diag_cmd_reg_dispatch(cmd_tbl, ARRAY_SIZE(cmd_tbl));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -94,18 +94,29 @@ int diag_transmit_buf(struct diag_instance *di, const uint8_t *data, size_t data
|
|||
|
||||
struct msgb *diag_read_msg(struct diag_instance *di)
|
||||
{
|
||||
uint8_t buf[DIAG_MAX_HDLC_BUF_SIZE];
|
||||
static uint8_t buf[DIAG_MAX_HDLC_BUF_SIZE];
|
||||
struct diag_hdlc_decode_type hdlc_decode;
|
||||
struct msgb *msg;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
static int buf_items_left = 0;
|
||||
|
||||
// printf("--\nRx dump pre: %s\n", osmo_hexdump(buf, buf_items_left));
|
||||
/* read raw data into buffer */
|
||||
rc = read(di->fd, buf, sizeof(buf));
|
||||
if (rc <= 0) {
|
||||
fprintf(stderr, "Short read!\n");
|
||||
exit(1);
|
||||
|
||||
if(!buf_items_left) {
|
||||
rc = read(di->fd, buf+buf_items_left, sizeof(buf)-buf_items_left);
|
||||
if (rc <= 0) {
|
||||
fprintf(stderr, "Short read! %d -> exiting...\n", rc);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int read_total = rc + buf_items_left;
|
||||
unsigned int read_current = rc;
|
||||
|
||||
// printf("1 Rx dump total: %s\n", osmo_hexdump(buf, read_total));
|
||||
fflush(stdout);
|
||||
|
||||
if (!di->rx.msg) {
|
||||
di->rx.msg = msgb_alloc(DIAG_MAX_REQ_SIZE, "DIAG Rx");
|
||||
di->rx.msg->l2h = di->rx.msg->tail;
|
||||
|
@ -116,12 +127,27 @@ struct msgb *diag_read_msg(struct diag_instance *di)
|
|||
hdlc_decode.dest_ptr = msg->tail;
|
||||
hdlc_decode.dest_size = msgb_tailroom(msg);
|
||||
hdlc_decode.src_ptr = buf;
|
||||
hdlc_decode.src_size = rc;
|
||||
hdlc_decode.src_size = read_total;
|
||||
hdlc_decode.src_idx = 0;
|
||||
hdlc_decode.dest_idx = 0;
|
||||
|
||||
|
||||
rc = diag_hdlc_decode(&hdlc_decode);
|
||||
|
||||
|
||||
int consumed = hdlc_decode.dest_idx;
|
||||
int current_remaining_in_buf = read_total-consumed;
|
||||
// printf("rx %d->%d, rem %d %u \n", read_total, consumed, current_remaining_in_buf, hdlc_decode.src_idx-hdlc_decode.dest_idx);
|
||||
|
||||
if(hdlc_decode.dest_idx < read_total) {
|
||||
memmove(buf, buf+consumed, current_remaining_in_buf);
|
||||
buf_items_left = current_remaining_in_buf;
|
||||
} else
|
||||
buf_items_left = 0;
|
||||
|
||||
// printf("2 Rx dump total: %s\n", osmo_hexdump(buf, buf_items_left));
|
||||
|
||||
|
||||
if (msgb_length(msg) + hdlc_decode.dest_idx > DIAG_MAX_REQ_SIZE) {
|
||||
fprintf(stderr, "Dropping packet. pkt_size: %d, max: %d\n",
|
||||
msgb_length(msg) + hdlc_decode.dest_idx,
|
||||
|
@ -142,8 +168,9 @@ struct msgb *diag_read_msg(struct diag_instance *di)
|
|||
rc = crc_check(msgb_data(msg), msgb_length(msg));
|
||||
if (rc) {
|
||||
fprintf(stderr, "Bad CRC, dropping packet\n");
|
||||
//msgb_free(msg);
|
||||
//return NULL;
|
||||
printf("Rx broken crc: %s\n", msgb_hexdump(msg));
|
||||
msgb_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
msgb_get(msg, HDLC_FOOTER_LEN);
|
||||
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
|
||||
#define DIAG_INST_F_HEXDUMP 0x00000001
|
||||
#define DIAG_INST_F_GSMTAP_DIAG 0x00000002
|
||||
#define DIAG_INST_F_GSMTAP_DECODED 0x00000004
|
||||
|
||||
|
||||
#define DIAG_INST_RAT_2G 0x00000001
|
||||
#define DIAG_INST_RAT_3G 0x00000002
|
||||
#define DIAG_INST_RAT_4G 0x00000004
|
||||
|
||||
struct diag_instance {
|
||||
int fd;
|
||||
|
@ -16,6 +22,12 @@ struct diag_instance {
|
|||
} tx;
|
||||
struct gsmtap_inst *gsmtap;
|
||||
uint32_t flags;
|
||||
uint32_t gsm_arfcn;
|
||||
uint32_t umts_arfcn_ul;
|
||||
uint32_t umts_arfcn_dl;
|
||||
uint32_t lte_arfcn_ul;
|
||||
uint32_t lte_arfcn_dl;
|
||||
uint32_t rat_type; /* tracking for 2g NAS */
|
||||
};
|
||||
|
||||
struct msgb *msgb_alloc_diag(void);
|
||||
|
|
139
src/diag_log.c
139
src/diag_log.c
|
@ -43,6 +43,12 @@ struct diag_log_config_req_hdr {
|
|||
uint32_t operation;
|
||||
} __attribute((packed));
|
||||
|
||||
struct diag_log_config_get_ranges_rsp {
|
||||
struct diag_log_config_req_hdr hdr;
|
||||
uint32_t status;
|
||||
uint32_t last_valid_num[16];
|
||||
} __attribute((packed));
|
||||
|
||||
struct diag_log_config_set_mask {
|
||||
struct diag_log_config_req_hdr hdr;
|
||||
uint32_t equip_id;
|
||||
|
@ -50,6 +56,8 @@ struct diag_log_config_set_mask {
|
|||
uint8_t data[0];
|
||||
} __attribute((packed));
|
||||
|
||||
static struct diag_log_config_get_ranges_rsp msg_ranges;
|
||||
|
||||
struct msgb *gen_log_config_set_mask(uint32_t equip_id, uint32_t last_item)
|
||||
{
|
||||
struct msgb *msg = msgb_alloc(DIAG_MAX_REQ_SIZE, "Diag Tx");
|
||||
|
@ -66,7 +74,20 @@ struct msgb *gen_log_config_set_mask(uint32_t equip_id, uint32_t last_item)
|
|||
return msg;
|
||||
}
|
||||
|
||||
int log_config_set_mask_bit(struct msgb *msg, uint32_t bit_in)
|
||||
struct msgb *gen_log_config_get_ranges()
|
||||
{
|
||||
struct msgb *msg = msgb_alloc(DIAG_MAX_REQ_SIZE, "Diag Tx");
|
||||
struct diag_log_config_req_hdr *dlcsm;
|
||||
|
||||
msg->l2h = msgb_put(msg, sizeof(*dlcsm));
|
||||
dlcsm = (struct diag_log_config_req_hdr *) msg->l2h;
|
||||
dlcsm->msg_type = DIAG_LOG_CONFIG_F;
|
||||
dlcsm->operation = LOG_CONFIG_RETRIEVE_ID_RANGES_OP;
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
int log_config_set_mask_bit(struct msgb *msg, uint32_t bit_in, uint8_t value)
|
||||
{
|
||||
struct diag_log_config_set_mask *dlcsm;
|
||||
dlcsm = (struct diag_log_config_set_mask *) msg->l2h;
|
||||
|
@ -79,7 +100,7 @@ int log_config_set_mask_bit(struct msgb *msg, uint32_t bit_in)
|
|||
return -1;
|
||||
}
|
||||
|
||||
mask[byte] |= (1 << bit);
|
||||
mask[byte] |= value ? (1 << bit) : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -102,40 +123,48 @@ void diag_log_reg_dispatch(const struct diag_log_dispatch_tbl *tbl, unsigned int
|
|||
}
|
||||
}
|
||||
|
||||
void diag_log_enable_all_supported_family(struct diag_instance *di, uint8_t family)
|
||||
void diag_log_set_all_supported_family(struct diag_instance *di, uint8_t family, uint8_t bitvalue)
|
||||
{
|
||||
struct msgb *msg, *rx;
|
||||
unsigned int i, size;
|
||||
unsigned int family_base = (family & 0xf) << 12;
|
||||
unsigned int max = 0;
|
||||
// unsigned int max = 0;
|
||||
family = family & 0xF;
|
||||
|
||||
for (i = family_base; i < family_base + 0x1000; i++) {
|
||||
if (log_handlers[i]) {
|
||||
if (max < i)
|
||||
max = i;
|
||||
}
|
||||
// for (i = family_base; i < family_base + 0x1000; i++) {
|
||||
// if (log_handlers[i]) {
|
||||
// if (max < i)
|
||||
// max = i;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (family == 1)
|
||||
// max = 0x1586;
|
||||
|
||||
// if (!max)
|
||||
// return;
|
||||
|
||||
// size = max - family_base;
|
||||
|
||||
size = msg_ranges.last_valid_num[family];
|
||||
if(!size) {
|
||||
printf("family %u: size 0, skipping...\n", family);
|
||||
return;
|
||||
}
|
||||
|
||||
if (family == 1)
|
||||
max = 0x1586;
|
||||
|
||||
if (!max)
|
||||
return;
|
||||
|
||||
size = max - family_base;
|
||||
printf("family %u: allocating log mask of size %u\n", family, size);
|
||||
msg = gen_log_config_set_mask(family, size);
|
||||
for (i = family_base; i < family_base + 0x1000; i++) {
|
||||
if (log_handlers[i])
|
||||
log_config_set_mask_bit(msg, i-family_base);
|
||||
log_config_set_mask_bit(msg, i-family_base, bitvalue);
|
||||
}
|
||||
|
||||
if (family == 1) {
|
||||
for (i = 0x572; i < 0x585; i++) {
|
||||
printf("Setting log 0x%04x\n", i);
|
||||
log_config_set_mask_bit(msg, i);
|
||||
}
|
||||
}
|
||||
// if (family == 1) {
|
||||
// for (i = 0x572; i < 0x585; i++) {
|
||||
// printf("Setting log 0x%04x\n", i);
|
||||
// log_config_set_mask_bit(msg, i);
|
||||
// }
|
||||
// }
|
||||
|
||||
rx = diag_transceive_msg(di, msg);
|
||||
if (rx->l2h[0] != DIAG_LOG_CONFIG_F)
|
||||
|
@ -147,9 +176,33 @@ void diag_log_enable_all_supported_family(struct diag_instance *di, uint8_t fami
|
|||
void diag_log_enable_all_supported(struct diag_instance *di)
|
||||
{
|
||||
unsigned int i;
|
||||
struct msgb *msg, *rx;
|
||||
struct diag_log_config_get_ranges_rsp *res;
|
||||
|
||||
/* max bit num not yet received */
|
||||
if(msg_ranges.hdr.msg_type != DIAG_LOG_CONFIG_F) {
|
||||
msg = gen_log_config_get_ranges();
|
||||
rx = diag_transceive_msg(di, msg);
|
||||
res = (struct diag_log_config_get_ranges_rsp *) (msgb_data(rx));
|
||||
if(sizeof(struct diag_log_config_get_ranges_rsp) == msgb_length(rx))
|
||||
msg_ranges = *res;
|
||||
}
|
||||
for (i = 0; i < 0xF; i++) {
|
||||
printf("max size for family %x: %u\n", i, res->last_valid_num[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0xF; i++) {
|
||||
diag_log_enable_all_supported_family(di, i);
|
||||
diag_log_set_all_supported_family(di, i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void diag_log_disable_all_supported(struct diag_instance *di)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 0xF; i++) {
|
||||
diag_log_set_all_supported_family(di, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,23 +212,43 @@ void diag_log_handle(struct diag_instance *di, struct msgb *msg)
|
|||
struct log_hdr *lh;
|
||||
|
||||
dlh = (struct diag_log_hdr *) msg->data;
|
||||
/* FIXME: verify length */
|
||||
msg->l3h = msgb_pull(msg, sizeof(*dlh));
|
||||
|
||||
lh = (struct log_hdr *) msg->l3h;
|
||||
/* FIXME: verify length */
|
||||
msgb_pull(msg, sizeof(*lh));
|
||||
if (sizeof(struct diag_log_hdr) < msgb_length(msg))
|
||||
msg->l3h = msgb_pull(msg, sizeof(*dlh));
|
||||
else {
|
||||
printf("size mismatch! %d\n", __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("LOG(0x%04x|%u|%u): ", lh->code,
|
||||
diag_ts_to_epoch(lh->ts), diag_ts_to_fn(lh->ts));
|
||||
if (dlh->len != msgb_length(msg)) {
|
||||
printf("size mismatch! %d\n", __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
lh = (struct log_hdr *)msg->l3h;
|
||||
|
||||
if (sizeof(struct log_hdr) < msgb_length(msg))
|
||||
msgb_pull(msg, sizeof(*lh));
|
||||
else {
|
||||
printf("size mismatch! %d\n", __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lh->len != (msgb_length(msg) + sizeof(struct log_hdr))) {
|
||||
printf("size mismatch! %d %d:%d\n", __LINE__, lh->len, msgb_length(msg));
|
||||
return;
|
||||
}
|
||||
|
||||
// printf("LOG(0x%04x|%u|%u): ", lh->code,
|
||||
// diag_ts_to_epoch(lh->ts), diag_ts_to_fn(lh->ts));
|
||||
|
||||
if (log_handlers[lh->code])
|
||||
log_handlers[lh->code](lh, msg);
|
||||
log_handlers[lh->code](di, lh, msg);
|
||||
else
|
||||
printf("%s\n", osmo_hexdump(lh->data, lh->len));
|
||||
}
|
||||
|
||||
void diag_log_hdl_default(struct log_hdr *lh, struct msgb *msg)
|
||||
void diag_log_hdl_default(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
printf("%s\n", osmo_hexdump(lh->data, lh->len));
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "diag_io.h"
|
||||
#include "protocol/protocol.h"
|
||||
|
||||
typedef void diag_log_handler(struct log_hdr *lh, struct msgb *msg);
|
||||
typedef void diag_log_handler(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg);
|
||||
|
||||
struct diag_log_dispatch_tbl {
|
||||
uint16_t code;
|
||||
|
@ -16,11 +16,12 @@ void diag_log_handle(struct diag_instance *di, struct msgb *msg);
|
|||
/* called by individual modules to register their own decoders */
|
||||
void diag_log_reg_dispatch(const struct diag_log_dispatch_tbl *tbl, unsigned int size);
|
||||
|
||||
void diag_log_enable_all_supported_family(struct diag_instance *di, uint8_t family);
|
||||
void diag_log_set_all_supported_family(struct diag_instance *di, uint8_t family, uint8_t bitvalue);
|
||||
void diag_log_enable_all_supported(struct diag_instance *di);
|
||||
void diag_log_disable_all_supported(struct diag_instance *di);
|
||||
|
||||
/* functions for log configuration */
|
||||
struct msgb *gen_log_config_set_mask(uint32_t equip_id, uint32_t last_item);
|
||||
int log_config_set_mask_bit(struct msgb *msg, uint32_t bit_in);
|
||||
int log_config_set_mask_bit(struct msgb *msg, uint32_t bit_in, uint8_t enabled);
|
||||
|
||||
void diag_log_hdl_default(struct log_hdr *lh, struct msgb *msg);
|
||||
void diag_log_hdl_default(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg);
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
#include "diag_log.h"
|
||||
#include "protocol/diag_log_gsm.h"
|
||||
#include "protocol/diag_log_gprs_rlc.h"
|
||||
|
@ -25,7 +29,7 @@
|
|||
#include "protocol/diag_log_gprs_l1.h"
|
||||
|
||||
|
||||
static void handle_grr_state_msg(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_grr_state_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_gprs_grr_state *rrs = (struct diag_gprs_grr_state *) msgb_data(msg);
|
||||
|
||||
|
@ -33,7 +37,7 @@ static void handle_grr_state_msg(struct log_hdr *lh, struct msgb *msg)
|
|||
get_value_string(diag_gprs_grr_st_vals, rrs->grr_state));
|
||||
}
|
||||
|
||||
static void handle_rlc_ul_abnrml_rls(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_rlc_ul_abnrml_rls(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_rlc_ul_abnrml_rls_counts *arc;
|
||||
arc = (struct gprs_rlc_ul_abnrml_rls_counts *) msgb_data(msg);
|
||||
|
@ -42,17 +46,57 @@ static void handle_rlc_ul_abnrml_rls(struct log_hdr *lh, struct msgb *msg)
|
|||
arc->access_reject_cnt, arc->arc_retry_cnt, arc->arc_wo_retry_cnt, arc->arc_sys_info_cnt);
|
||||
}
|
||||
|
||||
static void handle_mac_sign_msg(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_mac_sign_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
uint32_t ctype = 0;
|
||||
uint16_t arfcn = di->gsm_arfcn;
|
||||
uint8_t *data;
|
||||
unsigned int len;
|
||||
struct gprs_mac_signalling_msg *msm;
|
||||
msm = (struct gprs_mac_signalling_msg *) msgb_data(msg);
|
||||
printf("MAC-SIGN-MSG { chan_type=%s, msg_type=%s, msg=%s }\n",
|
||||
get_value_string(gprs_mac_chan_type_vals, msm->chan_type),
|
||||
get_value_string(gprs_mac_msg_type_vals, msm->msg_type),
|
||||
osmo_hexdump(msm->msg, msm->msg_len));
|
||||
di->rat_type = DIAG_INST_RAT_2G;
|
||||
// printf("MAC-SIGN-MSG { chan_type=%s, msg_type=%s, msg=%s }\n",
|
||||
// get_value_string(gprs_mac_chan_type_vals, msm->chan_type),
|
||||
// get_value_string(gprs_mac_msg_type_vals, msm->msg_type),
|
||||
// osmo_hexdump(msm->msg, msm->msg_len));
|
||||
|
||||
if(msm->msg_type == PACKET_CHANNEL_REQUEST)
|
||||
return;
|
||||
if(msm->chan_type == 255)
|
||||
return;
|
||||
|
||||
switch(msm->chan_type & 0x7f){
|
||||
case PACCH_RRBP_CHANNEL:
|
||||
case UL_PACCH_CHANNEL:
|
||||
case DL_PACCH_CHANNEL:
|
||||
ctype = GSMTAP_CHANNEL_PACCH;
|
||||
break;
|
||||
default:
|
||||
printf("Unhandled MAC-SIGN-MSG: %s %u: %s\n",
|
||||
get_value_string(gprs_mac_chan_type_vals, msm->chan_type & 0x7f),
|
||||
msm->msg_len,
|
||||
osmo_hexdump(msgb_data(msg), msm->msg_len));
|
||||
return;
|
||||
}
|
||||
|
||||
arfcn = msm->chan_type & 0x80 ? arfcn: arfcn | GSMTAP_ARFCN_F_UPLINK;
|
||||
|
||||
data = msm->msg;
|
||||
len = msm->msg_len;
|
||||
|
||||
/* prepend flag */
|
||||
data--;
|
||||
*data = 1 << 6; /* PAYLOAD_TYPE_CTRL_NO_OPT_OCTET */
|
||||
len++;
|
||||
|
||||
|
||||
/* abis due to no lapdm header */
|
||||
if (di->gsmtap && di->flags & DIAG_INST_F_GSMTAP_DECODED) {
|
||||
gsmtap_send_ex(di->gsmtap, GSMTAP_TYPE_UM, arfcn, 0, ctype, 0, 0, 0, 0, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_llc_me_info(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_llc_me_info(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_gprs_llme_info *gli;
|
||||
gli = (struct diag_gprs_llme_info *) msgb_data(msg);
|
||||
|
@ -62,7 +106,7 @@ static void handle_llc_me_info(struct log_hdr *lh, struct msgb *msg)
|
|||
osmo_hexdump_nospc(gli->enc_key, sizeof(gli->enc_key)));
|
||||
}
|
||||
|
||||
static void handle_llc_xid_info(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_llc_xid_info(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_gprs_llc_xid_info *glxi;
|
||||
|
||||
|
@ -82,7 +126,7 @@ static void handle_llc_xid_info(struct log_hdr *lh, struct msgb *msg)
|
|||
}
|
||||
|
||||
|
||||
static void handle_llc_pdu_stats(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_llc_pdu_stats(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_gprs_llc_stats *gls;
|
||||
gls = (struct diag_gprs_llc_stats *) msgb_data(msg);
|
||||
|
@ -94,7 +138,7 @@ static void handle_llc_pdu_stats(struct log_hdr *lh, struct msgb *msg)
|
|||
gls->llpdu_tx, gls->llpdu_rx, gls->llpdu_fcs_err, gls->llpdu_frm_rej, gls->llpdu_tlli_err, gls->llpdu_addr_err, gls->llpdu_short_err);
|
||||
}
|
||||
|
||||
static void handle_mac_state(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_mac_state(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_mac_state_change *msc;
|
||||
msc = (struct gprs_mac_state_change *) msgb_data(msg);
|
||||
|
@ -116,7 +160,7 @@ static void handle_mac_state(struct log_hdr *lh, struct msgb *msg)
|
|||
get_value_string(gprs_mac_mode_vals, msc->mac_mode), name);
|
||||
}
|
||||
|
||||
static void handle_mac_dl_tbf_est(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_mac_dl_tbf_est(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_mac_dl_tbf_est *dte;
|
||||
dte = (struct gprs_mac_dl_tbf_est *) msgb_data(msg);
|
||||
|
@ -125,7 +169,7 @@ static void handle_mac_dl_tbf_est(struct log_hdr *lh, struct msgb *msg)
|
|||
dte->dl_tfi, dte->rlc_mode, dte->dl_ts_bmap, dte->is_egprs_tbf, dte->egprs_win_size, dte->egprs_link_qual_mode, dte->bep_period2);
|
||||
}
|
||||
|
||||
static void handle_mac_ul_tbf_est(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_mac_ul_tbf_est(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_mac_ul_tbf_est *ute;
|
||||
ute = (struct gprs_mac_ul_tbf_est *) msgb_data(msg);
|
||||
|
@ -134,7 +178,7 @@ static void handle_mac_ul_tbf_est(struct log_hdr *lh, struct msgb *msg)
|
|||
ute->tbf_req_cause, ute->acc_granted, ute->radio_prio, ute->peak_tput, ute->ul_tfi, ute->rlc_mode, ute->ul_ts_bmap, ute->is_egprs_tbf, ute->egprs_win_size, ute->resegment, ute->bep_period2);
|
||||
}
|
||||
|
||||
static void handle_mac_dl_tbf_rel(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_mac_dl_tbf_rel(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_mac_tbf_release *tr;
|
||||
tr = (struct gprs_mac_tbf_release *) msgb_data(msg);
|
||||
|
@ -142,7 +186,7 @@ static void handle_mac_dl_tbf_rel(struct log_hdr *lh, struct msgb *msg)
|
|||
printf("MAC-DL-TBF-REL { tfi=%u, fail_cause=%u }\n", tr->tfi, tr->fail_cause);
|
||||
}
|
||||
|
||||
static void handle_mac_ul_tbf_rel(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_mac_ul_tbf_rel(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_mac_tbf_release *tr;
|
||||
tr = (struct gprs_mac_tbf_release *) msgb_data(msg);
|
||||
|
@ -150,7 +194,7 @@ static void handle_mac_ul_tbf_rel(struct log_hdr *lh, struct msgb *msg)
|
|||
printf("MAC-DL-TBF-REL { tfi=%u, fail_cause=%u }\n", tr->tfi, tr->fail_cause);
|
||||
}
|
||||
|
||||
static void handle_mac_dl_acknack(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_mac_dl_acknack(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_mac_dl_acknack *da;
|
||||
da = (struct gprs_mac_dl_acknack *) msgb_data(msg);
|
||||
|
@ -159,7 +203,7 @@ static void handle_mac_dl_acknack(struct log_hdr *lh, struct msgb *msg)
|
|||
osmo_hexdump(msgb_data(msg)+1, msgb_length(msg)-1));
|
||||
}
|
||||
|
||||
static void handle_mac_ul_acknack(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_mac_ul_acknack(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
//struct gprs_mac_ul_acknack *ua;
|
||||
//ua = (struct gprs_mac_ul_acknack *) msgb_data(msg);
|
||||
|
@ -168,7 +212,7 @@ static void handle_mac_ul_acknack(struct log_hdr *lh, struct msgb *msg)
|
|||
osmo_hexdump(msgb_data(msg), msgb_length(msg)));
|
||||
}
|
||||
|
||||
static void handle_rlc_ul_evt_cnt(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_rlc_ul_evt_cnt(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_rlc_ul_event_counts *uec;
|
||||
uec = (struct gprs_rlc_ul_event_counts *) msgb_data(msg);
|
||||
|
@ -177,7 +221,7 @@ static void handle_rlc_ul_evt_cnt(struct log_hdr *lh, struct msgb *msg)
|
|||
uec->llc_event_cnt, uec->mac_event_cnt, uec->pl1_event_cnt, uec->tmr_event_cnt);
|
||||
}
|
||||
|
||||
static void handle_rlc_ul_stats(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_rlc_ul_stats(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_rlc_ul_stats *uls;
|
||||
uls = (struct gprs_rlc_ul_stats *) msgb_data(msg);
|
||||
|
@ -187,7 +231,7 @@ static void handle_rlc_ul_stats(struct log_hdr *lh, struct msgb *msg)
|
|||
get_value_string(gprs_rlc_ul_substate_vals, uls->rlc_ul_substate));
|
||||
}
|
||||
|
||||
static void handle_rlc_dl_stats(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_rlc_dl_stats(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_rlc_dl_stats *dls;
|
||||
dls = (struct gprs_rlc_dl_stats *) msgb_data(msg);
|
||||
|
@ -196,7 +240,7 @@ static void handle_rlc_dl_stats(struct log_hdr *lh, struct msgb *msg)
|
|||
get_value_string(gprs_rlc_dl_state_vals, dls->rlc_dl_state));
|
||||
}
|
||||
|
||||
static void handle_rlc_ul_header(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_rlc_ul_header(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_rlc_ul_header *ulh;
|
||||
ulh = (struct gprs_rlc_ul_header *) msgb_data(msg);
|
||||
|
@ -206,7 +250,7 @@ static void handle_rlc_ul_header(struct log_hdr *lh, struct msgb *msg)
|
|||
osmo_hexdump(ulh->ul_hdr, sizeof(ulh->ul_hdr)));
|
||||
}
|
||||
|
||||
static void handle_rlc_rel(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_rlc_rel(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_rlc_release_ind *rli;
|
||||
rli = (struct gprs_rlc_release_ind *) msgb_data(msg);
|
||||
|
@ -218,12 +262,26 @@ static void handle_rlc_rel(struct log_hdr *lh, struct msgb *msg)
|
|||
printf("RLC-%cL-RELEASE { tfi=%u, cause=%u }\n", ud, rli->tfi, rli->cause);
|
||||
}
|
||||
|
||||
static void handle_gmm_ota_msg(struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
printf("GMM-OTA-MESSAGE { FIXME }\n");
|
||||
static void handle_gmm_ota_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{ uint32_t ctype = 0;
|
||||
uint16_t arfcn = di->gsm_arfcn;
|
||||
uint8_t *data;
|
||||
unsigned int len;
|
||||
struct gprs_sm_gmm_ota_msg *msm;
|
||||
msm = (struct gprs_sm_gmm_ota_msg *) msgb_data(msg);
|
||||
di->rat_type = DIAG_INST_RAT_2G;
|
||||
|
||||
arfcn = msm->chan_type ? arfcn: arfcn | GSMTAP_ARFCN_F_UPLINK;
|
||||
|
||||
data = msm->msg;
|
||||
len = msm->msg_len;
|
||||
|
||||
if (di->gsmtap && di->flags & DIAG_INST_F_GSMTAP_DECODED) {
|
||||
gsmtap_send_ex(di->gsmtap, GSMTAP_TYPE_ABIS, arfcn, 0, ctype, 0, 0, 0, 0, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_ul_acknack_v2(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_ul_acknack_v2(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_rlc_ul_acknack_params_v2 *ula;
|
||||
ula = (struct gprs_rlc_ul_acknack_params_v2 *) msgb_data(msg);
|
||||
|
@ -233,7 +291,7 @@ static void handle_ul_acknack_v2(struct log_hdr *lh, struct msgb *msg)
|
|||
ula->countdown_val, ula->va, ula->vs, ula->stall_ind, ula->rrb_high32, ula->rrb_low32);
|
||||
}
|
||||
|
||||
static void handle_dl_acknack_v2(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_dl_acknack_v2(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_rlc_dl_acknack_params_v2 *dla;
|
||||
dla = (struct gprs_rlc_dl_acknack_params_v2 *) msgb_data(msg);
|
||||
|
@ -243,7 +301,7 @@ static void handle_dl_acknack_v2(struct log_hdr *lh, struct msgb *msg)
|
|||
get_value_string(gprs_coding_schemes, dla->coding_scheme), dla->rrb_high32, dla->rrb_low32);
|
||||
}
|
||||
|
||||
static void handle_tx_sched_res(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_tx_sched_res(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_tx_sched_res *tsr;
|
||||
tsr = (struct gprs_tx_sched_res *) msgb_data(msg);
|
||||
|
@ -264,7 +322,7 @@ static void handle_tx_sched_res(struct log_hdr *lh, struct msgb *msg)
|
|||
printf(" ] }\n");
|
||||
}
|
||||
|
||||
static void handle_gprs_power_control(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_gprs_power_control(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_power_control *gpc;
|
||||
gpc = (struct gprs_power_control *) msgb_data(msg);
|
||||
|
@ -275,7 +333,7 @@ static void handle_gprs_power_control(struct log_hdr *lh, struct msgb *msg)
|
|||
gpc->alpha, gpc->derived_c, gpc->pmax);
|
||||
}
|
||||
|
||||
static void handle_gprs_xfer_sum(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_gprs_xfer_sum(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_xfer_sum *gxs;
|
||||
gxs = (struct gprs_xfer_sum *) msgb_data(msg);
|
||||
|
@ -285,7 +343,7 @@ static void handle_gprs_xfer_sum(struct log_hdr *lh, struct msgb *msg)
|
|||
gxs->dl_ptcch_ts, gxs->ta, gxs->usf_granularity, gxs->ul_bitmap_tn, gxs->dl_bitmap_tn);
|
||||
}
|
||||
|
||||
static void handle_gprs_aif_sum(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_gprs_aif_sum(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_air_if_summary *gaifs;
|
||||
gaifs = (struct gprs_air_if_summary *) msgb_data(msg);
|
||||
|
@ -294,7 +352,7 @@ static void handle_gprs_aif_sum(struct log_hdr *lh, struct msgb *msg)
|
|||
gaifs->fn, gaifs->band_ind, gaifs->dl_ts, gaifs->ul_ts, gaifs->rx_power);
|
||||
}
|
||||
|
||||
static void handle_gprs_rx_msg_metrics_a_v2(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_gprs_rx_msg_metrics_a_v2(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct gprs_rx_msg_metr_a_v2 *metr;
|
||||
metr = (struct gprs_rx_msg_metr_a_v2 *) msgb_data(msg);
|
||||
|
@ -315,7 +373,7 @@ static inline uint32_t round_next_octet(uint32_t num_bits)
|
|||
return num_bytes;
|
||||
}
|
||||
|
||||
static void handle_egprs_rlc_epdan(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_egprs_rlc_epdan(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_egprs_rlc_epdan *epd = (struct diag_egprs_rlc_epdan *) msgb_data(msg);
|
||||
|
||||
|
@ -331,6 +389,7 @@ static void handle_egprs_rlc_epdan(struct log_hdr *lh, struct msgb *msg)
|
|||
}
|
||||
|
||||
static const struct diag_log_dispatch_tbl log_tbl[] = {
|
||||
#if 0
|
||||
/* LLC */
|
||||
{ GSM(LOG_GPRS_LLC_ME_INFO_C), handle_llc_me_info }, /* requested? */
|
||||
{ GSM(LOG_GPRS_LLC_PDU_STATS_C), handle_llc_pdu_stats }, /* requested? */
|
||||
|
@ -351,15 +410,17 @@ static const struct diag_log_dispatch_tbl log_tbl[] = {
|
|||
{ 0x5206, diag_log_hdl_default },
|
||||
/* MAC */
|
||||
{ GSM(LOG_GPRS_MAC_STATE_C), handle_mac_state },
|
||||
#endif
|
||||
{ GSM(LOG_GPRS_MAC_SIGNALLING_MESSAGE_C), handle_mac_sign_msg },
|
||||
{ GSM(LOG_GPRS_SM_GMM_OTA_MESSAGE_C), handle_gmm_ota_msg },
|
||||
#if 0
|
||||
{ GSM(LOG_GPRS_MAC_DL_TBF_ESTABLISH_C), handle_mac_dl_tbf_est },
|
||||
{ GSM(LOG_GPRS_MAC_UL_TBF_ESTABLISH_C), handle_mac_ul_tbf_est },
|
||||
{ GSM(LOG_EGPRS_MAC_DL_ACKNACK_C), handle_mac_dl_acknack },
|
||||
{ GSM(LOG_EGPRS_MAC_UL_ACKNACK_C), handle_mac_ul_acknack },
|
||||
{ GSM(LOG_GPRS_MAC_DL_TBF_RELEASE_C), handle_mac_dl_tbf_rel },
|
||||
{ GSM(LOG_GPRS_MAC_UL_TBF_RELEASE_C), handle_mac_ul_tbf_rel },
|
||||
/* SM/GMM */
|
||||
{ GSM(LOG_GPRS_SM_GMM_OTA_MESSAGE_C), handle_gmm_ota_msg },
|
||||
|
||||
|
||||
/* Layer 1 */
|
||||
{ 0x5230, diag_log_hdl_default },
|
||||
|
@ -383,6 +444,7 @@ static const struct diag_log_dispatch_tbl log_tbl[] = {
|
|||
{ 0x508f, diag_log_hdl_default },
|
||||
|
||||
{ 0x5209, diag_log_hdl_default },
|
||||
#endif
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void on_dso_load_gprs(void)
|
||||
|
|
|
@ -18,20 +18,66 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
#include "diag_log.h"
|
||||
#include "protocol/diag_log_gsm.h"
|
||||
|
||||
struct dirty_fcch {
|
||||
uint16_t arfcn_band;
|
||||
/* don't care about anyhting else */
|
||||
};
|
||||
|
||||
static void handle_rr_sig_msg(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_rr_sig_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
uint32_t ctype = 0;
|
||||
uint16_t arfcn = di->gsm_arfcn;
|
||||
uint8_t *data;
|
||||
unsigned int len;
|
||||
struct diag_gsm_rr_msg *rm = (struct diag_gsm_rr_msg *) msgb_data(msg);
|
||||
|
||||
printf("RR: %s %02x %u: %s\n",
|
||||
get_value_string(diag_gsm_l2_chantype_vals, rm->chan_type & 0x7f),
|
||||
rm->msg_type, rm->length, osmo_hexdump(msgb_data(msg), rm->length));
|
||||
di->rat_type = DIAG_INST_RAT_2G;
|
||||
// printf("RR: %s %02x %u: %s\n",
|
||||
// get_value_string(diag_gsm_l2_chantype_vals, rm->chan_type & 0x7f),
|
||||
// rm->msg_type, rm->length, osmo_hexdump(msgb_data(msg), rm->length));
|
||||
|
||||
switch(rm->chan_type & 0x7f){
|
||||
case DIAG_GSM_L2_CHAN_TYPE_DCCH: ctype =GSMTAP_CHANNEL_SDCCH; break;
|
||||
case DIAG_GSM_L2_CHAN_TYPE_BCCH: ctype =GSMTAP_CHANNEL_BCCH; break;
|
||||
case DIAG_GSM_L2_CHAN_TYPE_RACH: ctype =GSMTAP_CHANNEL_RACH; break;
|
||||
case DIAG_GSM_L2_CHAN_TYPE_CCCH: ctype =GSMTAP_CHANNEL_CCCH; break;
|
||||
case DIAG_GSM_L2_CHAN_TYPE_SACCH: ctype =GSMTAP_CHANNEL_SDCCH | GSMTAP_CHANNEL_ACCH; break;
|
||||
case DIAG_GSM_L2_CHAN_TYPE_SDCCH: ctype =GSMTAP_CHANNEL_SDCCH; break;
|
||||
case DIAG_GSM_L2_CHAN_TYPE_FACCH_F: ctype =GSMTAP_CHANNEL_TCH_F | GSMTAP_CHANNEL_ACCH; break;
|
||||
case DIAG_GSM_L2_CHAN_TYPE_FACCH_H: ctype =GSMTAP_CHANNEL_TCH_H | GSMTAP_CHANNEL_ACCH; break;
|
||||
default:
|
||||
printf("Unhandled RR: %s %u: %s\n",
|
||||
get_value_string(diag_gsm_l2_chantype_vals, rm->chan_type & 0x7f),
|
||||
rm->length,
|
||||
osmo_hexdump(msgb_data(msg), rm->length));
|
||||
return;
|
||||
}
|
||||
|
||||
arfcn = rm->chan_type & 0x80 ? arfcn : arfcn | GSMTAP_ARFCN_F_UPLINK;
|
||||
|
||||
data = rm->data;
|
||||
len = rm->length;
|
||||
|
||||
/* skip l2 pseudo len */
|
||||
if (ctype == GSMTAP_CHANNEL_BCCH || ctype == GSMTAP_CHANNEL_CCCH){
|
||||
data++;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* abis due to no lapdm header */
|
||||
if (di->gsmtap && di->flags & DIAG_INST_F_GSMTAP_DECODED) {
|
||||
gsmtap_send_ex(di->gsmtap, GSMTAP_TYPE_ABIS, arfcn, 0, ctype, 0, 0, 0, 0, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_rr_state_msg(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_rr_state_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_gsm_rr_state *rrs = (struct diag_gsm_rr_state *) msgb_data(msg);
|
||||
printf("RR-STATE { state=%s, substate=%u, status=%u, mode=%u }\n",
|
||||
|
@ -40,7 +86,7 @@ static void handle_rr_state_msg(struct log_hdr *lh, struct msgb *msg)
|
|||
|
||||
}
|
||||
|
||||
static void handle_mdsp_cmd(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_mdsp_cmd(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_mdsp_log_cmds *dmlcs = (struct diag_mdsp_log_cmds *) msgb_data(msg);
|
||||
int i;
|
||||
|
@ -60,7 +106,7 @@ static void handle_mdsp_cmd(struct log_hdr *lh, struct msgb *msg)
|
|||
printf(" ] }\n");
|
||||
}
|
||||
|
||||
static void handle_l2_state(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_l2_state(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_gsm_l2_state *l2s = (struct diag_gsm_l2_state *) msgb_data(msg);
|
||||
|
||||
|
@ -81,7 +127,7 @@ static void handle_l2_state(struct log_hdr *lh, struct msgb *msg)
|
|||
get_value_string(diag_gsm_l2_event_vals, l2s->l2_event));
|
||||
}
|
||||
|
||||
static void handle_l2_transm_status(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_l2_transm_status(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_gsm_l2_transm_status *lts = (struct diag_gsm_l2_transm_status *) msgb_data(msg);
|
||||
|
||||
|
@ -92,12 +138,23 @@ static void handle_l2_transm_status(struct log_hdr *lh, struct msgb *msg)
|
|||
lts->seq_err, lts->frame_type, lts->msg_entries, lts->seg_entries);
|
||||
}
|
||||
|
||||
static void handle_arfcn(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct dirty_fcch *rm = (struct dirty_fcch *) msgb_data(msg);
|
||||
di->gsm_arfcn = rm->arfcn_band & 0x0FFF;
|
||||
}
|
||||
|
||||
static const struct diag_log_dispatch_tbl log_tbl[] = {
|
||||
{ GSM(LOG_GSM_RR_SIGNALING_MESSAGE_C), handle_rr_sig_msg },
|
||||
{ GSM(LOG_GSM_RR_CELL_INFO_C), handle_arfcn },
|
||||
{ GSM(LOG_GSM_FCCH_DECODE_C), handle_arfcn },
|
||||
{ GSM(LOG_GSM_SCH_DECODE_C), handle_arfcn },
|
||||
#if 0
|
||||
{ GSM(LOG_GSM_RR_STATE_C), handle_rr_state_msg },
|
||||
{ GSM(LOG_GSM_MDSP_CMD_C), handle_mdsp_cmd },
|
||||
{ GSM(LOG_GSM_L2_STATE_C), handle_l2_state },
|
||||
{ GSM(LOG_GSM_L2_TRANSMISSION_STATUS_C), handle_l2_transm_status},
|
||||
#endif
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void on_dso_load_gsm(void)
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
#include "diag_log.h"
|
||||
#include "protocol/diag_log_lte.h"
|
||||
|
||||
struct sub_chan_map {
|
||||
uint8_t is_ul;
|
||||
uint8_t qc_id;
|
||||
uint8_t gsmtap_lte_rrc_msg;
|
||||
};
|
||||
|
||||
|
||||
static struct sub_chan_map rrc_subtype_map_lt9_13_22[] = {
|
||||
{0, 1, GSMTAP_LTE_RRC_SUB_BCCH_BCH_Message },
|
||||
{0, 2, GSMTAP_LTE_RRC_SUB_BCCH_DL_SCH_Message},
|
||||
{0, 3, GSMTAP_LTE_RRC_SUB_MCCH_Message },
|
||||
{0, 4, GSMTAP_LTE_RRC_SUB_PCCH_Message },
|
||||
{0, 5, GSMTAP_LTE_RRC_SUB_DL_CCCH_Message },
|
||||
{0, 6, GSMTAP_LTE_RRC_SUB_DL_DCCH_Message },
|
||||
{1, 7, GSMTAP_LTE_RRC_SUB_UL_CCCH_Message },
|
||||
{1, 8, GSMTAP_LTE_RRC_SUB_UL_DCCH_Message },
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct sub_chan_map rrc_subtype_map_9to12[] = {
|
||||
{0,8, GSMTAP_LTE_RRC_SUB_BCCH_BCH_Message },
|
||||
{0,9, GSMTAP_LTE_RRC_SUB_BCCH_DL_SCH_Message },
|
||||
{0,10, GSMTAP_LTE_RRC_SUB_MCCH_Message },
|
||||
{0,11, GSMTAP_LTE_RRC_SUB_PCCH_Message },
|
||||
{0,12, GSMTAP_LTE_RRC_SUB_DL_CCCH_Message },
|
||||
{0,13, GSMTAP_LTE_RRC_SUB_DL_DCCH_Message },
|
||||
{1,14, GSMTAP_LTE_RRC_SUB_UL_CCCH_Message },
|
||||
{1,15, GSMTAP_LTE_RRC_SUB_UL_DCCH_Message },
|
||||
};
|
||||
|
||||
static struct sub_chan_map rrc_subtype_map_14_15_16[] = {
|
||||
{0,1, GSMTAP_LTE_RRC_SUB_BCCH_BCH_Message },
|
||||
{0,2, GSMTAP_LTE_RRC_SUB_BCCH_DL_SCH_Message },
|
||||
{0,4, GSMTAP_LTE_RRC_SUB_MCCH_Message },
|
||||
{0,5, GSMTAP_LTE_RRC_SUB_PCCH_Message },
|
||||
{0,6, GSMTAP_LTE_RRC_SUB_DL_CCCH_Message },
|
||||
{0,7, GSMTAP_LTE_RRC_SUB_DL_DCCH_Message },
|
||||
{1,8, GSMTAP_LTE_RRC_SUB_UL_CCCH_Message },
|
||||
{1,9, GSMTAP_LTE_RRC_SUB_UL_DCCH_Message },
|
||||
};
|
||||
|
||||
|
||||
static struct sub_chan_map rrc_subtype_map_19_26[] = {
|
||||
{0,1, GSMTAP_LTE_RRC_SUB_BCCH_BCH_Message },
|
||||
{0,3, GSMTAP_LTE_RRC_SUB_BCCH_DL_SCH_Message },
|
||||
{0,6, GSMTAP_LTE_RRC_SUB_MCCH_Message },
|
||||
{0,7, GSMTAP_LTE_RRC_SUB_PCCH_Message },
|
||||
{0,8, GSMTAP_LTE_RRC_SUB_DL_CCCH_Message },
|
||||
{0,9, GSMTAP_LTE_RRC_SUB_DL_DCCH_Message },
|
||||
{1,10,GSMTAP_LTE_RRC_SUB_UL_CCCH_Message },
|
||||
{1,11,GSMTAP_LTE_RRC_SUB_UL_DCCH_Message },
|
||||
{0,45, GSMTAP_LTE_RRC_SUB_BCCH_BCH_Message_NB },
|
||||
{0,46, GSMTAP_LTE_RRC_SUB_BCCH_BCH_Message_NB },
|
||||
{0,47, GSMTAP_LTE_RRC_SUB_PCCH_Message_NB },
|
||||
{0,48, GSMTAP_LTE_RRC_SUB_DL_CCCH_Message_NB },
|
||||
{0,49, GSMTAP_LTE_RRC_SUB_DL_DCCH_Message_NB },
|
||||
{1,50, GSMTAP_LTE_RRC_SUB_UL_CCCH_Message_NB },
|
||||
{1,52, GSMTAP_LTE_RRC_SUB_UL_DCCH_Message_NB },
|
||||
};
|
||||
|
||||
static struct sub_chan_map rrc_subtype_map_20[] = {
|
||||
{0,1, GSMTAP_LTE_RRC_SUB_BCCH_BCH_Message , },
|
||||
{0,2, GSMTAP_LTE_RRC_SUB_BCCH_DL_SCH_Message, },
|
||||
{0,4, GSMTAP_LTE_RRC_SUB_MCCH_Message, },
|
||||
{0,5, GSMTAP_LTE_RRC_SUB_PCCH_Message, },
|
||||
{0,6, GSMTAP_LTE_RRC_SUB_DL_CCCH_Message, },
|
||||
{0,7, GSMTAP_LTE_RRC_SUB_DL_DCCH_Message, },
|
||||
{1,8, GSMTAP_LTE_RRC_SUB_UL_CCCH_Message, },
|
||||
{1,9, GSMTAP_LTE_RRC_SUB_UL_DCCH_Message },
|
||||
{0,54, GSMTAP_LTE_RRC_SUB_BCCH_BCH_Message_NB, },
|
||||
{0,55, GSMTAP_LTE_RRC_SUB_BCCH_BCH_Message_NB, },
|
||||
{0,56, GSMTAP_LTE_RRC_SUB_PCCH_Message_NB, },
|
||||
{0,57, GSMTAP_LTE_RRC_SUB_DL_CCCH_Message_NB, },
|
||||
{0,58, GSMTAP_LTE_RRC_SUB_DL_DCCH_Message_NB, },
|
||||
{1,59, GSMTAP_LTE_RRC_SUB_UL_CCCH_Message_NB, },
|
||||
{1,61, GSMTAP_LTE_RRC_SUB_UL_DCCH_Message_NB },
|
||||
};
|
||||
|
||||
struct chan_map_result {
|
||||
uint8_t is_ul;
|
||||
uint8_t chan;
|
||||
};
|
||||
|
||||
struct lte_cell_info_dirty_012 {
|
||||
uint16_t band;
|
||||
uint16_t dl_arfcn;
|
||||
uint16_t ul_arfcn;
|
||||
/* don't care about anything else */
|
||||
};
|
||||
|
||||
struct lte_cell_info_dirty_2plus {
|
||||
uint16_t band;
|
||||
uint32_t dl_arfcn;
|
||||
uint32_t ul_arfcn;
|
||||
/* don't care about anything else */
|
||||
};
|
||||
|
||||
#define MAPC(xx) \
|
||||
for(i=0; i < ARRAY_SIZE(xx); i++) {\
|
||||
if(inout->chan == xx[i].qc_id){ \
|
||||
inout->chan = xx[i].gsmtap_lte_rrc_msg; \
|
||||
inout->is_ul = xx[i].is_ul; \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
static int find_map_in_ver(int version, struct chan_map_result* inout) {
|
||||
unsigned int i = 0;
|
||||
if(version < 9 || version == 13 || version == 22)
|
||||
MAPC(rrc_subtype_map_lt9_13_22)
|
||||
else if(version >= 9 && version <= 12)
|
||||
MAPC(rrc_subtype_map_9to12)
|
||||
else if(version >= 14 && version <= 16)
|
||||
MAPC(rrc_subtype_map_14_15_16)
|
||||
else if(version == 19 || version == 26)
|
||||
MAPC(rrc_subtype_map_19_26)
|
||||
else if(version == 20)
|
||||
MAPC(rrc_subtype_map_20)
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void handle_lte_rrc_ota_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
uint16_t arfcn = 0;
|
||||
uint8_t* data;
|
||||
struct chan_map_result mc;
|
||||
struct diag_lte_rrc_ota_base_8plus_msg *r8p;
|
||||
struct diag_lte_rrc_ota_base_msg *rrm = (struct diag_lte_rrc_ota_base_msg *) msgb_data(msg);
|
||||
|
||||
di->rat_type = DIAG_INST_RAT_4G;
|
||||
|
||||
if (rrm->ext_ver < 8 || rrm->ext_ver > 24) {
|
||||
printf("Unhandled LTE OTA rel: %u\n", rrm->ext_ver);
|
||||
return;
|
||||
}
|
||||
r8p = (struct diag_lte_rrc_ota_base_8plus_msg *)msgb_data(msg);
|
||||
data = msgb_data(msg) + sizeof(struct diag_lte_rrc_ota_base_8plus_msg);
|
||||
|
||||
if (msgb_length(msg) - sizeof(struct diag_lte_rrc_ota_base_8plus_msg) != r8p->len) {
|
||||
printf("Unhandled LTE OTA rel len: %u %u\n", rrm->ext_ver, r8p->len);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (r8p->channel_type) {
|
||||
case 254:
|
||||
case 255:
|
||||
return;
|
||||
}
|
||||
|
||||
mc.chan = r8p->channel_type;
|
||||
if (find_map_in_ver(r8p->hdr.ext_ver, &mc) < 0)
|
||||
printf("Unhandled LTE OTA rel len: %u %u\n", rrm->ext_ver, r8p->len);
|
||||
|
||||
arfcn = mc.is_ul ? di->lte_arfcn_ul : di->lte_arfcn_dl;
|
||||
arfcn = mc.is_ul ? arfcn | GSMTAP_ARFCN_F_UPLINK: arfcn;
|
||||
|
||||
// printf("lte m: %s\n", osmo_hexdump(data, 1));
|
||||
|
||||
|
||||
if (di->gsmtap && di->flags & DIAG_INST_F_GSMTAP_DECODED) {
|
||||
gsmtap_send_ex(di->gsmtap, GSMTAP_TYPE_LTE_RRC, arfcn, 0, mc.chan, 0, 0, 0, 0, data ,r8p->len);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_lte_rrc_cell_info(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
|
||||
uint8_t* data;
|
||||
|
||||
struct diag_lte_rrc_ota_base_8plus_msg *r8p;
|
||||
struct diag_lte_rrc_ota_base_msg *rrm = (struct diag_lte_rrc_ota_base_msg *) msgb_data(msg);
|
||||
|
||||
uint8_t ver = *(uint8_t *) msgb_data(msg);
|
||||
if(ver < 3) {
|
||||
struct lte_cell_info_dirty_012* i = (struct lte_cell_info_dirty_012 *) msgb_data(msg);
|
||||
di->lte_arfcn_dl = i->dl_arfcn;
|
||||
di->lte_arfcn_ul = i->ul_arfcn;
|
||||
} else {
|
||||
struct lte_cell_info_dirty_2plus* i = (struct lte_cell_info_dirty_2plus *) msgb_data(msg);
|
||||
di->lte_arfcn_dl = i->dl_arfcn;
|
||||
di->lte_arfcn_ul = i->ul_arfcn;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void handle_lte_nas_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
uint16_t arfcn = 0;
|
||||
uint8_t* data;
|
||||
uint32_t len;
|
||||
bool sec_hdr = false;
|
||||
bool is_ul = false;
|
||||
|
||||
di->rat_type = DIAG_INST_RAT_4G;
|
||||
|
||||
data = msgb_data(msg) + sizeof(struct diag_lte_rrc_nas_msg);
|
||||
len = msgb_length(msg) - sizeof(struct diag_lte_rrc_nas_msg);
|
||||
|
||||
switch(lh->code) {
|
||||
case LTE(LOG_LTE_NAS_ESM_OTA_IN_SEC_MSG_LOG_C):
|
||||
case LTE(LOG_LTE_NAS_ESM_OTA_OUT_SEC_MSG_LOG_C):
|
||||
case LTE(LOG_LTE_NAS_EMM_OTA_IN_SEC_MSG_LOG_C):
|
||||
case LTE(LOG_LTE_NAS_EMM_OTA_OUT_SEC_MSG_LOG_C):
|
||||
sec_hdr = true;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(lh->code) {
|
||||
case LTE(LOG_LTE_NAS_ESM_OTA_IN_MSG_LOG_C):
|
||||
case LTE(LOG_LTE_NAS_EMM_OTA_IN_MSG_LOG_C):
|
||||
case LTE(LOG_LTE_NAS_ESM_OTA_IN_SEC_MSG_LOG_C):
|
||||
case LTE(LOG_LTE_NAS_EMM_OTA_IN_SEC_MSG_LOG_C):
|
||||
is_ul = true;
|
||||
break;
|
||||
}
|
||||
|
||||
arfcn = is_ul ? di->lte_arfcn_ul : di->lte_arfcn_dl;
|
||||
if (di->gsmtap && di->flags & DIAG_INST_F_GSMTAP_DECODED) {
|
||||
gsmtap_send_ex(di->gsmtap, GSMTAP_TYPE_LTE_NAS, is_ul ? arfcn | GSMTAP_ARFCN_F_UPLINK : arfcn, 0, sec_hdr ? GSMTAP_LTE_NAS_SEC_HEADER : GSMTAP_LTE_NAS_PLAIN, 0, 0, 0, 0, data , len);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct diag_log_dispatch_tbl log_tbl[] = {
|
||||
{ LTE(LOG_LTE_RRC_OTA_MSG_LOG_C), handle_lte_rrc_ota_msg },
|
||||
{ LTE(LOG_LTE_NAS_ESM_OTA_IN_MSG_LOG_C), handle_lte_nas_msg },
|
||||
{ LTE(LOG_LTE_NAS_ESM_OTA_OUT_MSG_LOG_C), handle_lte_nas_msg },
|
||||
{ LTE(LOG_LTE_NAS_EMM_OTA_IN_MSG_LOG_C), handle_lte_nas_msg },
|
||||
{ LTE(LOG_LTE_NAS_EMM_OTA_OUT_MSG_LOG_C), handle_lte_nas_msg },
|
||||
// { LTE(LOG_LTE_NAS_ESM_OTA_IN_SEC_MSG_LOG_C), handle_lte_nas_msg },
|
||||
// { LTE(LOG_LTE_NAS_ESM_OTA_OUT_SEC_MSG_LOG_C), handle_lte_nas_msg },
|
||||
// { LTE(LOG_LTE_NAS_EMM_OTA_IN_SEC_MSG_LOG_C), handle_lte_nas_msg },
|
||||
// { LTE(LOG_LTE_NAS_EMM_OTA_OUT_SEC_MSG_LOG_C), handle_lte_nas_msg },
|
||||
{ LTE(LOG_LTE_RRC_SERV_CELL_INFO_LOG_C), handle_lte_rrc_cell_info },
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void on_dso_load_lte(void)
|
||||
{
|
||||
diag_log_reg_dispatch(log_tbl, ARRAY_SIZE(log_tbl));
|
||||
}
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
/* A small wrapper around libqmi-glib to give us a human-readable string
|
||||
* representation of QMI messages that we receive from DIAG */
|
||||
static int dump_qmi_msg(const uint8_t *data, unsigned int len)
|
||||
static int dump_qmi_msg(struct diag_instance *di, const uint8_t *data, unsigned int len)
|
||||
{
|
||||
GByteArray *buffer;
|
||||
GError *error = NULL;
|
||||
|
@ -49,9 +49,9 @@ static int dump_qmi_msg(const uint8_t *data, unsigned int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void handle_qmi_msg(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_qmi_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
dump_qmi_msg(lh->data, lh->len);
|
||||
dump_qmi_msg(di, lh->data, lh->len);
|
||||
}
|
||||
|
||||
#define CORE(x) (0x1000 + x)
|
||||
|
@ -97,7 +97,9 @@ static const struct diag_log_dispatch_tbl log_tbl[] = {
|
|||
{ LOG_QMI_PORT_TX(15), handle_qmi_msg },
|
||||
};
|
||||
|
||||
#if 0
|
||||
static __attribute__((constructor)) void on_dso_load_qmi(void)
|
||||
{
|
||||
diag_log_reg_dispatch(log_tbl, ARRAY_SIZE(log_tbl));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -27,13 +27,13 @@
|
|||
#include "protocol/diagcmd.h"
|
||||
#include "protocol/diag_log_1x.h"
|
||||
|
||||
static void handle_uim_data(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_uim_data(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct diag_log_uim_msg *uim = (struct diag_log_uim_msg *) msgb_data(msg);
|
||||
printf("UIM_DATA { %s }\n", msgb_hexdump(msg));
|
||||
}
|
||||
|
||||
static void handle_uim_ds_data(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_uim_ds_data(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
printf("UIM_DS_DATA {}\n");
|
||||
}
|
||||
|
@ -43,8 +43,9 @@ static const struct diag_log_dispatch_tbl log_tbl[] = {
|
|||
{ L1X(LOG_UIM_DATA_C), handle_uim_data },
|
||||
{ L1X(LOG_UIM_DS_DATA_C), handle_uim_ds_data },
|
||||
};
|
||||
|
||||
#if 0
|
||||
static __attribute__((constructor)) void on_dso_load_gsm(void)
|
||||
{
|
||||
diag_log_reg_dispatch(log_tbl, ARRAY_SIZE(log_tbl));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,14 +1,30 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
#include "diag_log.h"
|
||||
#include "protocol/diag_log_umts.h"
|
||||
|
||||
static void handle_nas_msg(struct log_hdr *lh, struct msgb *msg)
|
||||
static void handle_nas_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
uint16_t arfcn = 0;
|
||||
struct diag_umts_nas_ota_msg *nas = (struct diag_umts_nas_ota_msg *) msgb_data(msg);
|
||||
|
||||
printf("NAS: %cL %u: %s\n", nas->direction ? 'U':'D', nas->msg_length,
|
||||
osmo_hexdump(msgb_data(msg), nas->msg_length));
|
||||
/* track rat, don't duplicate rrc message contents here for != 2g */
|
||||
if(di->rat_type != DIAG_INST_RAT_2G)
|
||||
return;
|
||||
|
||||
// printf("NAS: %cL %u: %s\n", nas->direction ? 'U':'D', nas->msg_length,
|
||||
// osmo_hexdump(msgb_data(msg), nas->msg_length));
|
||||
|
||||
arfcn = nas->direction ? di->umts_arfcn_ul : di->umts_arfcn_dl;
|
||||
arfcn = nas->direction ? arfcn | GSMTAP_ARFCN_F_UPLINK: arfcn;
|
||||
|
||||
if (di->gsmtap && di->flags & DIAG_INST_F_GSMTAP_DECODED) {
|
||||
gsmtap_send_ex(di->gsmtap, GSMTAP_TYPE_ABIS, arfcn, 0, 0, 0, 0, 0, 0, nas->data, nas->msg_length);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct diag_log_dispatch_tbl log_tbl[] = {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
#include "diag_log.h"
|
||||
|
@ -81,21 +83,71 @@ const struct value_string rrc_chan_types[] = {
|
|||
{ DIAG_UMTS_RRC_CHT_DL_BCCH_BCH,"BCCH/BCH" },
|
||||
{ DIAG_UMTS_RRC_CHT_DL_BCCH_FACH, "BCCH/FACH" },
|
||||
{ DIAG_UMTS_RRC_CHT_DL_PCCH, "PCCH" },
|
||||
{ DIAG_UMTS_RRC_CHT_EXTENSION_SIB, "unknown" },
|
||||
{ DIAG_UMTS_RRC_CHT_SIB_CONTAINER, "unknown" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static void handle_rrc_sig_msg(struct log_hdr *lh, struct msgb *msg)
|
||||
|
||||
struct wcdma_cell_id {
|
||||
uint32_t ul_arfcn;
|
||||
uint32_t dl_arfcn;
|
||||
uint32_t cell_id;
|
||||
};
|
||||
|
||||
static void handle_rrc_sig_msg(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
uint32_t ctype = 0;
|
||||
uint16_t arfcn = 0;
|
||||
struct diag_umts_rrc_msg *rrm = (struct diag_umts_rrc_msg *) msgb_data(msg);
|
||||
|
||||
printf("RRC: %s %u %u: %s\n",
|
||||
get_value_string(rrc_chan_types, rrm->chan_type),
|
||||
rrm->rb_id, rrm->length,
|
||||
osmo_hexdump(msgb_data(msg), rrm->length));
|
||||
di->rat_type = DIAG_INST_RAT_3G;
|
||||
|
||||
// printf("RRC: %s %u %u: %s\n",
|
||||
// get_value_string(rrc_chan_types, rrm->chan_type),
|
||||
// rrm->rb_id, rrm->length,
|
||||
// osmo_hexdump(msgb_data(msg), rrm->length));
|
||||
|
||||
switch(rrm->chan_type){
|
||||
case 254:
|
||||
case 255:
|
||||
case DIAG_UMTS_RRC_CHT_EXTENSION_SIB:
|
||||
case DIAG_UMTS_RRC_CHT_SIB_CONTAINER:
|
||||
return;
|
||||
case DIAG_UMTS_RRC_CHT_UL_CCCH: ctype =GSMTAP_RRC_SUB_UL_CCCH_Message; break;
|
||||
case DIAG_UMTS_RRC_CHT_UL_DCCH: ctype =GSMTAP_RRC_SUB_UL_DCCH_Message; break;
|
||||
case DIAG_UMTS_RRC_CHT_DL_CCCH: ctype =GSMTAP_RRC_SUB_DL_CCCH_Message; break;
|
||||
case DIAG_UMTS_RRC_CHT_DL_DCCH: ctype =GSMTAP_RRC_SUB_DL_DCCH_Message; break;
|
||||
case DIAG_UMTS_RRC_CHT_DL_BCCH_BCH: ctype =GSMTAP_RRC_SUB_BCCH_BCH_Message; break;
|
||||
case DIAG_UMTS_RRC_CHT_DL_BCCH_FACH: ctype =GSMTAP_RRC_SUB_BCCH_FACH_Message; break;
|
||||
case DIAG_UMTS_RRC_CHT_DL_PCCH: ctype =GSMTAP_RRC_SUB_PCCH_Message; break;
|
||||
default:
|
||||
printf("Unhandled RRC: %s %u %u: %s\n",
|
||||
get_value_string(rrc_chan_types, rrm->chan_type),
|
||||
rrm->rb_id, rrm->length,
|
||||
osmo_hexdump(msgb_data(msg), rrm->length));
|
||||
return;
|
||||
}
|
||||
|
||||
arfcn = rrm->chan_type < DIAG_UMTS_RRC_CHT_DL_CCCH ? di->umts_arfcn_ul | GSMTAP_ARFCN_F_UPLINK: di->umts_arfcn_dl;
|
||||
|
||||
if (di->gsmtap && di->flags & DIAG_INST_F_GSMTAP_DECODED) {
|
||||
gsmtap_send_ex(di->gsmtap, GSMTAP_TYPE_UMTS_RRC, arfcn, 0, ctype, 0, 0, 0, 0, rrm->msg,rrm->length);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_cell_id(struct diag_instance *di, struct log_hdr *lh, struct msgb *msg)
|
||||
{
|
||||
struct wcdma_cell_id *rrm = (struct wcdma_cell_id *) msgb_data(msg);
|
||||
|
||||
di->umts_arfcn_dl =rrm->dl_arfcn;
|
||||
di->umts_arfcn_ul =rrm->ul_arfcn;
|
||||
}
|
||||
|
||||
|
||||
static const struct diag_log_dispatch_tbl log_tbl[] = {
|
||||
{ WCDMA(LOG_WCDMA_SIGNALING_MSG_C), handle_rrc_sig_msg },
|
||||
{ WCDMA(LOG_WCDMA_CELL_ID_C), handle_cell_id },
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void on_dso_load_umts(void)
|
||||
|
|
|
@ -38,7 +38,15 @@ struct diag_set_rt_mask_req {
|
|||
uint32_t runtime_mask[1];
|
||||
};
|
||||
|
||||
struct diag_set_all_rt_mask_req {
|
||||
uint8_t cmd_code;
|
||||
uint8_t sub_cmd;
|
||||
uint16_t _pad;
|
||||
uint32_t runtime_mask;
|
||||
};
|
||||
|
||||
#define MSG_EXT_SUBCMD_SET_RT_MASK 4
|
||||
#define MSG_EXT_SUBCMD_SET_ALL_RT_MASK 5
|
||||
|
||||
struct msgb *gen_msg_config_set_rt_mask(uint16_t ssid, uint32_t runtime_mask)
|
||||
{
|
||||
|
@ -56,6 +64,40 @@ struct msgb *gen_msg_config_set_rt_mask(uint16_t ssid, uint32_t runtime_mask)
|
|||
return msg;
|
||||
}
|
||||
|
||||
struct msgb *gen_msg_config_set_all_rt_mask(uint32_t runtime_mask)
|
||||
{
|
||||
struct msgb *msg = msgb_alloc(DIAG_MAX_REQ_SIZE, "Diag Msg Config");
|
||||
struct diag_set_all_rt_mask_req *dsrmr;
|
||||
|
||||
msg->l2h = msgb_put(msg, sizeof(*dsrmr));
|
||||
dsrmr = (struct diag_set_all_rt_mask_req *) msgb_l2(msg);
|
||||
dsrmr->cmd_code = DIAG_EXT_MSG_CONFIG_F;
|
||||
dsrmr->sub_cmd = MSG_EXT_SUBCMD_SET_ALL_RT_MASK;
|
||||
osmo_store32le(runtime_mask, &dsrmr->runtime_mask);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
int diag_msg_config_set_all_rt_mask(struct diag_instance *di, uint32_t runtime_mask)
|
||||
{
|
||||
struct msgb *msg = gen_msg_config_set_all_rt_mask(runtime_mask);
|
||||
struct msgb *rx;
|
||||
struct diag_set_all_rt_mask_req *res;
|
||||
int rc = 0;
|
||||
|
||||
rx = diag_transceive_msg(di, msg);
|
||||
res = (struct diag_set_all_rt_mask_req *) (msgb_l2(rx));
|
||||
if ((rx->l2h[0] != DIAG_EXT_MSG_CONFIG_F) || res->cmd_code != DIAG_EXT_MSG_CONFIG_F ||
|
||||
res->sub_cmd != MSG_EXT_SUBCMD_SET_ALL_RT_MASK ||
|
||||
osmo_load32le(&res->runtime_mask) != runtime_mask) {
|
||||
fprintf(stderr, "Error setting all RT mask\n");
|
||||
rc = -1;
|
||||
}
|
||||
msgb_free(rx);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int diag_msg_config_set_rt_mask(struct diag_instance *di, uint16_t ssid, uint32_t runtime_mask)
|
||||
{
|
||||
struct msgb *msg = gen_msg_config_set_rt_mask(ssid, runtime_mask);
|
||||
|
@ -64,8 +106,8 @@ int diag_msg_config_set_rt_mask(struct diag_instance *di, uint16_t ssid, uint32_
|
|||
int rc = 0;
|
||||
|
||||
rx = diag_transceive_msg(di, msg);
|
||||
res = (struct diag_set_rt_mask_req *) (msgb_l2(msg)+1);
|
||||
if ((rx->l2h[0] != DIAG_EXT_MSG_CONFIG_F) || res->cmd_code != MSG_EXT_SUBCMD_SET_RT_MASK ||
|
||||
res = (struct diag_set_rt_mask_req *) (msgb_l2(rx));
|
||||
if ((rx->l2h[0] != DIAG_EXT_MSG_CONFIG_F) || res->cmd_code != DIAG_EXT_MSG_CONFIG_F ||
|
||||
res->sub_cmd != MSG_EXT_SUBCMD_SET_RT_MASK ||
|
||||
osmo_load16le(&res->ssid_start) != ssid ||
|
||||
osmo_load16le(&res->ssid_end) != ssid ||
|
||||
|
@ -183,7 +225,9 @@ static const struct diag_cmd_dispatch_tbl cmd_tbl[] = {
|
|||
{ DIAG_QSR_EXT_MSG_TERSE_F, diag_rx_ext_msg_terse_f },
|
||||
};
|
||||
|
||||
#if 0
|
||||
static __attribute__((constructor)) void on_dso_load_msg(void)
|
||||
{
|
||||
diag_cmd_reg_dispatch(cmd_tbl, ARRAY_SIZE(cmd_tbl));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -6,3 +6,5 @@
|
|||
|
||||
struct msgb *gen_msg_config_set_rt_mask(uint16_t ssid, uint32_t runtime_mask);
|
||||
int diag_msg_config_set_rt_mask(struct diag_instance *di, uint16_t ssid, uint32_t runtime_mask);
|
||||
int diag_msg_config_set_all_rt_mask(struct diag_instance *di, uint32_t runtime_mask);
|
||||
|
||||
|
|
|
@ -31,11 +31,15 @@
|
|||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/serial.h>
|
||||
#include <osmocom/core/gsmtap_util.h>
|
||||
#include <osmocom/core/gsmtap.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
#include "diag_io.h"
|
||||
#include "diag_log.h"
|
||||
|
@ -46,6 +50,11 @@
|
|||
#include "protocol/diagcmd.h"
|
||||
#include "protocol/diag_log_gsm.h"
|
||||
|
||||
struct diag_instance di;
|
||||
static char *serial_path = 0;
|
||||
static uint32_t cfg_flags = 0;
|
||||
static char *gsmtap_ip = "localhost";
|
||||
|
||||
static void do_configure(struct diag_instance *di)
|
||||
{
|
||||
static uint8_t timestamp[] = { DIAG_TS_F };
|
||||
|
@ -55,33 +64,39 @@ static void do_configure(struct diag_instance *di)
|
|||
static const uint8_t disable_evt_report[] = {
|
||||
DIAG_EVENT_REPORT_F, 0x00
|
||||
};
|
||||
static const uint8_t disable_log[] = {
|
||||
DIAG_LOG_CONFIG_F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
diag_transceive_buf_ign(di, timestamp, sizeof(timestamp));
|
||||
// diag_transceive_buf_ign(di, timestamp, sizeof(timestamp));
|
||||
/* response: 3d 67 a8 81 d4 46 6d d9 00 */
|
||||
|
||||
/* enable|disable the event report */
|
||||
#if 1
|
||||
#if 0
|
||||
diag_transceive_buf_ign(di, enable_evt_report, sizeof(enable_evt_report));
|
||||
#else
|
||||
diag_transceive_buf_ign(di, disable_evt_report, sizeof(disable_evt_report));
|
||||
diag_transceive_buf_ign(di, disable_log, sizeof(disable_log));
|
||||
diag_msg_config_set_all_rt_mask(di, 0);
|
||||
// diag_transceive_buf_ign(di, disable_evt_report, sizeof(disable_evt_report));
|
||||
/* response: 40 00 00 */
|
||||
#endif
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_LINUX_DATA, 0xffffffff);
|
||||
/* response: 5d 5d 04 41 00 41 00 01 00 ff ff ff ff */
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_DS_ATCOP, 0xffffffff);
|
||||
/* response: 5d 5d 04 94 13 94 13 01 00 ff ff ff ff */
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_DS, 0xffffffff);
|
||||
/* response: 5d 5d 04 88 13 88 13 01 00 ff ff ff ff */
|
||||
//diag_msg_config_set_rt_mask(di, MSG_SSID_DS_IPA, 0xffffffff);
|
||||
/* response: 5d 5d 04 a6 13 a6 13 01 00 ff ff ff ff */
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_DS_GPRS, 0xffffffff);
|
||||
/* response: 5d 5d 04 91 13 91 13 01 00 ff ff ff ff */
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_DS_GSM, 0xffffffff);
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_DS_UMTS, 0xffffffff);
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_DS_SOCKETS, 0xffffffff);
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_DS_SIO, 0xffffffff);
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_DS_APPS, 0xffffffff);
|
||||
diag_msg_config_set_rt_mask(di, MSG_SSID_DIAG, 0xffffffff);
|
||||
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_LINUX_DATA, 0xffffffff);
|
||||
// /* response: 5d 5d 04 41 00 41 00 01 00 ff ff ff ff */
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_DS_ATCOP, 0xffffffff);
|
||||
// /* response: 5d 5d 04 94 13 94 13 01 00 ff ff ff ff */
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_DS, 0xffffffff);
|
||||
// /* response: 5d 5d 04 88 13 88 13 01 00 ff ff ff ff */
|
||||
// //diag_msg_config_set_rt_mask(di, MSG_SSID_DS_IPA, 0xffffffff);
|
||||
// /* response: 5d 5d 04 a6 13 a6 13 01 00 ff ff ff ff */
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_DS_GPRS, 0xffffffff);
|
||||
// /* response: 5d 5d 04 91 13 91 13 01 00 ff ff ff ff */
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_DS_GSM, 0xffffffff);
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_DS_UMTS, 0xffffffff);
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_DS_SOCKETS, 0xffffffff);
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_DS_SIO, 0xffffffff);
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_DS_APPS, 0xffffffff);
|
||||
// diag_msg_config_set_rt_mask(di, MSG_SSID_DIAG, 0xffffffff);
|
||||
|
||||
#if 0
|
||||
printf("GSM\n");
|
||||
|
@ -141,35 +156,167 @@ static void enable_pcap(struct diag_instance *di, uint8_t if_num)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void signal_handler(int s)
|
||||
{
|
||||
struct termios tio;
|
||||
switch (s) {
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
diag_log_disable_all_supported(&di);
|
||||
/* graceful exit by immediate read timeout */
|
||||
tcgetattr(di.fd, &tio);
|
||||
tio.c_cflag &= CRTSCTS;
|
||||
tio.c_cc[VMIN] = 0;
|
||||
tio.c_cc[VTIME] = 1;
|
||||
tcsetattr(di.fd, TCSANOW, &tio);
|
||||
// exit(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_help()
|
||||
{
|
||||
printf( " Some useful help...\n"
|
||||
" -h --help This help text\n"
|
||||
" -s --serial-path path to modem serial port, i.e /dev/ttyUSB0\n"
|
||||
" Any combination of the following output flags:\n"
|
||||
" -G --gsmtap GSMTAP messages sent to localhost\n"
|
||||
" -Q --qcomdbg plain QC DIAG GSMTAP messages\n"
|
||||
" -H --hexdump console output of rx/tx messages\n"
|
||||
" -i --ip address the GSMTAP packets should be sent to (default 127.0.0.1)\n"
|
||||
);
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
{
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
static struct option long_options[] = {
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ "gsmtap", 0, 0, 'G' },
|
||||
{ "qcomdbg", 0, 0, 'Q' },
|
||||
{ "hexdump", 0, 0, 'H' },
|
||||
{ "serial-path", 1, 0, 's' },
|
||||
{ "ip", 1, 0, 'i' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hGQHs:i:", long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_help();
|
||||
exit(0);
|
||||
case 'G':
|
||||
cfg_flags |= DIAG_INST_F_GSMTAP_DECODED;
|
||||
break;
|
||||
case 'Q':
|
||||
cfg_flags |= DIAG_INST_F_GSMTAP_DIAG;
|
||||
break;
|
||||
case 'H':
|
||||
cfg_flags |= DIAG_INST_F_HEXDUMP;
|
||||
break;
|
||||
case 's':
|
||||
serial_path = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
gsmtap_ip = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* special function that allows to bind to local nonlocal ips like 127.0.0.x with x != 1 */
|
||||
static int gsmtap_source_add_local_sink(struct gsmtap_inst *gti)
|
||||
{
|
||||
int rc;
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t ss_len = sizeof(ss);
|
||||
|
||||
if (gti->ofd_wq_mode)
|
||||
return -1;
|
||||
|
||||
rc = getpeername(gsmtap_inst_fd(gti), (struct sockaddr *)&ss, &ss_len);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = osmo_sock_init_sa((struct sockaddr *)&ss, SOCK_DGRAM,
|
||||
IPPROTO_UDP,
|
||||
OSMO_SOCK_F_BIND |
|
||||
OSMO_SOCK_F_UDP_REUSEADDR);
|
||||
if (rc >= 0)
|
||||
return rc;
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct diag_instance di;
|
||||
struct termios tio;
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Invoke with %s PATH_TO_SERIAL\n",
|
||||
argv[0]);
|
||||
handle_options(argc, argv);
|
||||
log_init(0,0);
|
||||
|
||||
if (!serial_path) {
|
||||
printf("Invoke with %s -s PATH_TO_SERIAL\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (!cfg_flags) {
|
||||
printf("no output options (-G/-Q/-H) specified?! exiting...\n");
|
||||
print_help();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset(&di, 0, sizeof(di));
|
||||
di.fd = osmo_serial_init(argv[1], 921600);
|
||||
//di.flags = 1;
|
||||
if (di.fd < 0)
|
||||
di.fd = osmo_serial_init(serial_path, 921600);
|
||||
if (di.fd < 0) {
|
||||
printf("can't open serial port: errno %d\n", di.fd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
di.gsmtap = gsmtap_source_init("localhost", GSMTAP_UDP_PORT, 0);
|
||||
di.flags = DIAG_INST_F_GSMTAP_DIAG;
|
||||
gsmtap_source_add_sink(di.gsmtap);
|
||||
/* blocking reads */
|
||||
rc = tcgetattr(di.fd, &tio);
|
||||
tio.c_cflag &= CRTSCTS;
|
||||
tio.c_cc[VMIN] = 1;
|
||||
tio.c_cc[VTIME] = 0;
|
||||
rc = tcsetattr(di.fd, TCSANOW, &tio);
|
||||
|
||||
di.gsmtap = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 0);
|
||||
if (di.gsmtap == 0) {
|
||||
printf("error initializing gsmtap source!\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
di.flags = cfg_flags;
|
||||
rc = gsmtap_source_add_local_sink(di.gsmtap);
|
||||
if (rc < 0) {
|
||||
printf("error initializing gsmtap sink!\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("\n===> CONFIGURING\n");
|
||||
|
||||
do_configure(&di);
|
||||
diag_dpl_get_sup_if(&di);
|
||||
for (i = 1; i < 0x56; i++) {
|
||||
diag_dpl_get_if_desc(&di, i);
|
||||
enable_pcap(&di, i);
|
||||
}
|
||||
// diag_dpl_get_sup_if(&di);
|
||||
// for (i = 1; i < 0x56; i++) {
|
||||
// diag_dpl_get_if_desc(&di, i);
|
||||
// enable_pcap(&di, i);
|
||||
// }
|
||||
|
||||
/* Handle keyboard interrupts */
|
||||
signal(SIGINT, &signal_handler);
|
||||
signal(SIGTERM, &signal_handler);
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
signal(SIGUSR2, &signal_handler);
|
||||
|
||||
|
||||
printf("\n===> ENTERING MAIN\n");
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ enum gprs_tx_ul_chan_t {
|
|||
DIAG_TX_UL_CH_T_UL_PTCCH,
|
||||
DIAG_TX_UL_CH_T_UL_PACCH_PDTCH,
|
||||
};
|
||||
const struct value_string gprs_tx_ul_chans[4];
|
||||
extern const struct value_string gprs_tx_ul_chans[4];
|
||||
|
||||
enum gprs_coding_scheme {
|
||||
DIAG_GPRS_CS_CS1,
|
||||
|
@ -91,7 +91,7 @@ enum gprs_coding_scheme {
|
|||
DIAG_GPRS_CS_MCS8,
|
||||
DIAG_GPRS_CS_MCS9,
|
||||
};
|
||||
const struct value_string gprs_coding_schemes[16];
|
||||
extern const struct value_string gprs_coding_schemes[16];
|
||||
|
||||
struct gprs_tx_sched_res {
|
||||
uint32_t fn;
|
||||
|
|
|
@ -70,6 +70,14 @@ struct gprs_mac_signalling_msg {
|
|||
uint8_t msg[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* LOG_GPRS_SM_GMM_OTA_MESSAGE_C */
|
||||
struct gprs_sm_gmm_ota_msg {
|
||||
uint8_t chan_type;
|
||||
uint8_t msg_type;
|
||||
uint16_t msg_len;
|
||||
uint8_t msg[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* LOG_GPRS_MAC_DL_TBF_ESTABLISH_C */
|
||||
struct gprs_mac_dl_tbf_est {
|
||||
uint8_t dl_tfi;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
enum diag_log_code_gsm {
|
||||
LOG_GSM_POWER_SCAN_C = 0x64,
|
||||
LOG_GSM_FCCH_DECODE_C = 0x65,
|
||||
LOG_GSM_SCH_DECODE_C = 0x66,
|
||||
LOG_GSM_NCELL_ACQ_C = 0x75,
|
||||
LOG_GSM_AFC_ADJUST_C = 0x7c,
|
||||
LOG_GSM_MON_BURST_C = 0x82,
|
||||
|
@ -24,6 +25,7 @@ enum diag_log_code_gsm {
|
|||
LOG_GSM_RR_STATE_C = 300,
|
||||
//= 303,
|
||||
LOG_GSM_RR_CONTROL_CHANNEL_PARAMS_C = 306,
|
||||
LOG_GSM_RR_CELL_INFO_C = 308,
|
||||
|
||||
LOG_GPRS_INDICATORS_C = 500,
|
||||
LOG_GPRS_GENERAL_PARAMS_C = 501,
|
||||
|
@ -192,7 +194,7 @@ enum diag_gprs_llme_state {
|
|||
DIAG_GPRS_LLMES_TLLI_ASS = 1,
|
||||
DIAG_GPRS_LLMES_TEST_MODE = 2,
|
||||
};
|
||||
const struct value_string diag_gprs_llme_st_vals[4];
|
||||
extern const struct value_string diag_gprs_llme_st_vals[4];
|
||||
|
||||
/* LOG_GPRS_LLC_ME_INFO_C */
|
||||
struct diag_gprs_llme_info {
|
||||
|
@ -282,7 +284,7 @@ enum diag_gsm_sapi0_state {
|
|||
DIAG_SAPI0_ST_LINK_SUSP,
|
||||
DIAG_SAPI0_ST_UA_PEND,
|
||||
};
|
||||
const struct value_string diag_gsm_l2_sapi0_st_vals[10];
|
||||
extern const struct value_string diag_gsm_l2_sapi0_st_vals[10];
|
||||
|
||||
enum diag_gsm_sapi3_state {
|
||||
DIAG_SAPI3_ST_NULL,
|
||||
|
@ -294,7 +296,7 @@ enum diag_gsm_sapi3_state {
|
|||
DIAG_SAPI3_ST_TMR_RECOV,
|
||||
DIAG_SAPI3_ST_UA_PEND,
|
||||
};
|
||||
const struct value_string diag_gsm_l2_sapi3_st_vals[9];
|
||||
extern const struct value_string diag_gsm_l2_sapi3_st_vals[9];
|
||||
|
||||
enum diag_gsm_l2_event {
|
||||
DIAG_L2_EV_NO_EVENT,
|
||||
|
@ -325,7 +327,7 @@ enum diag_gsm_l2_event {
|
|||
DIAG_L2_EV_UA_SENT,
|
||||
DIAG_L2_EV_FORCED_SUSPEND_REQ,
|
||||
};
|
||||
const struct value_string diag_gsm_l2_event_vals[28];
|
||||
extern const struct value_string diag_gsm_l2_event_vals[28];
|
||||
|
||||
struct diag_gsm_l2_state {
|
||||
uint8_t sapi;
|
||||
|
@ -343,7 +345,7 @@ enum diag_gsm_l2_chantype {
|
|||
DIAG_L2_CHT_FACCH_F = 6,
|
||||
DIAG_L2_CHT_FACCH_H = 7,
|
||||
};
|
||||
const struct value_string diag_gsm_l2_chantype_vals[9];
|
||||
extern const struct value_string diag_gsm_l2_chantype_vals[9];
|
||||
|
||||
struct diag_gsm_l2_transm_status {
|
||||
uint8_t sapi;
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define LTE(x) (0xb000 + x)
|
||||
|
||||
enum diag_log_code_lte {
|
||||
LOG_LTE_RRC_OTA_MSG_LOG_C = 0xc0,
|
||||
LOG_LTE_RRC_SERV_CELL_INFO_LOG_C = 0xc2,
|
||||
|
||||
LOG_LTE_NAS_ESM_OTA_IN_SEC_MSG_LOG_C = 0xE0,
|
||||
LOG_LTE_NAS_ESM_OTA_OUT_SEC_MSG_LOG_C = 0xE1,
|
||||
|
||||
LOG_LTE_NAS_ESM_OTA_IN_MSG_LOG_C = 0xe2,
|
||||
LOG_LTE_NAS_ESM_OTA_OUT_MSG_LOG_C = 0xe3,
|
||||
|
||||
LOG_LTE_NAS_EMM_OTA_IN_SEC_MSG_LOG_C = 0xEA,
|
||||
LOG_LTE_NAS_EMM_OTA_OUT_SEC_MSG_LOG_C = 0xEB,
|
||||
|
||||
LOG_LTE_NAS_EMM_OTA_IN_MSG_LOG_C = 0xec,
|
||||
LOG_LTE_NAS_EMM_OTA_OUT_MSG_LOG_C = 0xed,
|
||||
|
||||
};
|
||||
|
||||
enum diag_lte_rrc_chtype {
|
||||
DIAG_UMTS_RRC_CHT_UL_CCCH = 0,
|
||||
DIAG_UMTS_RRC_CHT_UL_DCCH = 1,
|
||||
DIAG_UMTS_RRC_CHT_DL_CCCH = 2,
|
||||
DIAG_UMTS_RRC_CHT_DL_DCCH = 3,
|
||||
DIAG_UMTS_RRC_CHT_DL_BCCH_BCH = 4,
|
||||
DIAG_UMTS_RRC_CHT_DL_BCCH_FACH = 5,
|
||||
DIAG_UMTS_RRC_CHT_DL_PCCH = 6,
|
||||
DIAG_UMTS_RRC_CHT_EXTENSION_SIB = 9,
|
||||
DIAG_UMTS_RRC_CHT_SIB_CONTAINER = 10,
|
||||
};
|
||||
|
||||
struct diag_lte_rrc_ota_base_msg {
|
||||
uint8_t ext_ver;
|
||||
uint8_t rrc_release;
|
||||
uint8_t rrc_version;
|
||||
uint8_t bearer;
|
||||
uint16_t cellid;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct diag_lte_rrc_ota_base_pre8_msg {
|
||||
struct diag_lte_rrc_ota_base_msg hdr;
|
||||
uint16_t freq;
|
||||
uint16_t sfn;
|
||||
uint8_t channel_type;
|
||||
uint16_t len;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
struct diag_lte_rrc_ota_base_8plus_msg {
|
||||
struct diag_lte_rrc_ota_base_msg hdr;
|
||||
uint32_t freq;
|
||||
uint16_t sfn;
|
||||
uint8_t channel_type;
|
||||
uint8_t sib_mask_pad[4];
|
||||
uint16_t len;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
struct diag_lte_rrc_nas_msg {
|
||||
uint8_t ext_ver;
|
||||
uint8_t rrc_release;
|
||||
uint8_t rrc_version_minor;
|
||||
uint8_t rrc_version_major;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
|
@ -23,6 +23,8 @@ enum diag_umts_rrc_chtype {
|
|||
DIAG_UMTS_RRC_CHT_DL_BCCH_BCH = 4,
|
||||
DIAG_UMTS_RRC_CHT_DL_BCCH_FACH = 5,
|
||||
DIAG_UMTS_RRC_CHT_DL_PCCH = 6,
|
||||
DIAG_UMTS_RRC_CHT_EXTENSION_SIB = 9,
|
||||
DIAG_UMTS_RRC_CHT_SIB_CONTAINER = 10,
|
||||
};
|
||||
|
||||
enum diag_umts_rrc_state {
|
||||
|
|
Loading…
Reference in New Issue