aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-01-21 11:01:45 +0100
committerHarald Welte <laforge@gnumonks.org>2017-01-21 11:01:45 +0100
commit0512d9d2664fb0893aa4c096767f4e08d0362acb (patch)
tree6aa32cfcbf4269ec3e325167b7e8621dffb45655
parent0442fead33dece7027ba0f859a30bd65180442f8 (diff)
decoder for RLC-EPDAN, MDSP-CMD, L2-STATE and L2-TRANSM-STATUS
-rw-r--r--src/diag_gsm.c54
-rw-r--r--src/diag_log_gprs.c29
-rw-r--r--src/diag_log_gsm.c53
-rw-r--r--src/protocol/diag_log_gsm.h97
4 files changed, 227 insertions, 6 deletions
diff --git a/src/diag_gsm.c b/src/diag_gsm.c
index b05f6ca..594150c 100644
--- a/src/diag_gsm.c
+++ b/src/diag_gsm.c
@@ -71,7 +71,61 @@ const struct value_string diag_gprs_llme_st_vals[] = {
{ 0, NULL }
};
+const struct value_string diag_gsm_l2_sapi0_st_vals[] = {
+ { DIAG_SAPI0_ST_NULL, "NULL" },
+ { DIAG_SAPI0_ST_CON_PEND, "CONN_PEND" },
+ { DIAG_SAPI0_ST_IDLE, "IDLE" },
+ { DIAG_SAPI0_ST_EST_PEND, "EST_PEND" },
+ { DIAG_SAPI0_ST_REL_PEND, "REL_PEND" },
+ { DIAG_SAPI0_ST_LINK_EST, "LINK_ESTABLISHED" },
+ { DIAG_SAPI0_ST_TMR_RECOV, "TIMER_RECOVERY" },
+ { DIAG_SAPI0_ST_LINK_SUSP, "LINK_SUSPENDED" },
+ { DIAG_SAPI0_ST_UA_PEND, "UA_PENDING" },
+ { 0, NULL }
+};
+const struct value_string diag_gsm_l2_sapi3_st_vals[] = {
+ { DIAG_SAPI3_ST_NULL, "NULL" },
+ { DIAG_SAPI3_ST_CON_PEND, "CONN_PEND" },
+ { DIAG_SAPI3_ST_IDLE, "IDLE" },
+ { DIAG_SAPI3_ST_EST_PEND, "EST_PEND" },
+ { DIAG_SAPI3_ST_REL_PEND, "REL_PEND" },
+ { DIAG_SAPI3_ST_LINK_EST, "LINK_ESTABLISHED" },
+ { DIAG_SAPI3_ST_TMR_RECOV, "TIMER_RECOVERY" },
+ { DIAG_SAPI3_ST_UA_PEND, "UA_PENDING" },
+ { 0, NULL }
+};
+
+const struct value_string diag_gsm_l2_event_vals[] = {
+ { DIAG_L2_EV_NO_EVENT, "NONE" },
+ { DIAG_L2_EV_CONNECT_RECEIVED, "CON-RX" },
+ { DIAG_L2_EV_ESTABLISH_REQUEST, "EST.req" },
+ { DIAG_L2_EV_RELEASE_REQUEST, "REL.req" },
+ { DIAG_L2_EV_SUSPEND_REQUEST, "SUSP.req" },
+ { DIAG_L2_EV_RESUME_REQUEST, "RESUME.req" },
+ { DIAG_L2_EV_RECONNECT_REQUEST, "RECONN.req" },
+ { DIAG_L2_EV_DATA_REQUEST, "DATA.req" },
+ { DIAG_L2_EV_MDL_RELEASE_REQUEST, "MDL-REL.req" },
+ { DIAG_L2_EV_UA_RECEIVED, "UA-RX" },
+ { DIAG_L2_EV_DM_RECEIVED, "DM-RX" },
+ { DIAG_L2_EV_DISC_RECEIVED, "DISC-RX" },
+ { DIAG_L2_EV_SABM_RECEIVED, "SABM-RX" },
+ { DIAG_L2_EV_I_RECEIVED, "I-RX" },
+ { DIAG_L2_EV_UI_RECEIVED, "UI-RX" },
+ { DIAG_L2_EV_RR_RECEIVED, "RR-RX" },
+ { DIAG_L2_EV_REJ_RECEIVED, "REJ-RX" },
+ { DIAG_L2_EV_T200_TIMEOUT, "T200-EXP" },
+ { DIAG_L2_EV_CONTENTION_FAILED, "CONTENT-FAIL" },
+ { DIAG_L2_EV_ABORT_ESTABLISHMENT, "ABORT-EST" },
+ { DIAG_L2_EV_LINK_ESTABLISHED, "LINK-ESTABLISHED" },
+ { DIAG_L2_EV_RELEASE_CONFIRMED, "REL.conf" },
+ { DIAG_L2_EV_CLEAR_RECOVERY_CONDITION, "CLEAR-RECOV-COND" },
+ { DIAG_L2_EV_OPTIONAL_SEND, "OPT-SEND" },
+ { DIAG_L2_EV_RESET_L2, "RESET-L2" },
+ { DIAG_L2_EV_UA_SENT, "UA-SENT" },
+ { DIAG_L2_EV_FORCED_SUSPEND_REQ,"FORCED-SUSP.req" },
+ { 0, NULL }
+};
/* GSM_GPRS_LOG_PACKET_REQ_F */
struct diag_gsm_log_packet_req {
diff --git a/src/diag_log_gprs.c b/src/diag_log_gprs.c
index e7504d8..89e5e18 100644
--- a/src/diag_log_gprs.c
+++ b/src/diag_log_gprs.c
@@ -307,6 +307,29 @@ static void handle_gprs_rx_msg_metrics_a_v2(struct log_hdr *lh, struct msgb *msg
metr->msg_len, metr->usf);
}
+static inline uint32_t round_next_octet(uint32_t num_bits)
+{
+ uint32_t num_bytes = num_bits / 8;
+ if (num_bits % 8)
+ num_bytes++;
+ return num_bytes;
+}
+
+static void handle_egprs_rlc_epdan(struct log_hdr *lh, struct msgb *msg)
+{
+ struct diag_egprs_rlc_epdan *epd = (struct diag_egprs_rlc_epdan *) msgb_data(msg);
+
+ printf("EGPRS-RLC-EPDAN { tfi=%u, final_ack=%u, begin_of_win=%u, end_of_win=%u, esp=%u, starting_color_code=%u, gmsk=%u, psk=%u, ssn=%u, crrb_num_bits=%u, crrb=%s, ",
+ epd->tfi, epd->final_ack_ind, epd->begin_of_window, epd->end_of_window,
+ epd->esp, epd->starting_color_code, epd->gmsk_valid, epd->psk_valid,
+ epd->ssn, epd->crrb_num_bits,
+ osmo_hexdump_nospc(epd->crrb, round_next_octet(epd->crrb_num_bits)));
+ printf("urrb_num_bits=%u, urrb=%s, gmsk_bep=%u, psk_bep=%u, c_value=%u }\n",
+ epd->urrb_num_bits,
+ osmo_hexdump_nospc(epd->urrb, round_next_octet(epd->urrb_num_bits)),
+ epd->gmsk_bep, epd->psk_bep, epd->c_value);
+}
+
static const struct diag_log_dispatch_tbl log_tbl[] = {
/* LLC */
{ GSM(LOG_GPRS_LLC_ME_INFO_C), handle_llc_me_info }, /* requested? */
@@ -324,6 +347,7 @@ static const struct diag_log_dispatch_tbl log_tbl[] = {
{ GSM(LOG_GPRS_RLC_UL_ACKNACK_PARAMS_VER2_C), handle_ul_acknack_v2 },
{ GSM(LOG_GPRS_RLC_DL_ACKNACK_PARAMS_VER2_C), handle_dl_acknack_v2 },
{ GSM(LOG_EGPRS_RLC_UL_HEADER_C), handle_rlc_ul_header },
+ { GSM(LOG_EGPRS_RLC_EPDAN_C), handle_egprs_rlc_epdan },
{ 0x5206, diag_log_hdl_default },
/* MAC */
{ GSM(LOG_GPRS_MAC_STATE_C), handle_mac_state },
@@ -355,15 +379,10 @@ static const struct diag_log_dispatch_tbl log_tbl[] = {
{ 0x51f6, diag_log_hdl_default },
{ 0x51f7, diag_log_hdl_default },
- { 0x50c8, diag_log_hdl_default },
- { 0x50c9, diag_log_hdl_default },
-
- { 0x508c, diag_log_hdl_default },
//{ 0x508d, diag_log_hdl_default }, hardware cmd
{ 0x508f, diag_log_hdl_default },
{ 0x5209, diag_log_hdl_default },
- { 0x5211, diag_log_hdl_default },
};
static __attribute__((constructor)) void on_dso_load_gprs(void)
diff --git a/src/diag_log_gsm.c b/src/diag_log_gsm.c
index 8f44169..40290b6 100644
--- a/src/diag_log_gsm.c
+++ b/src/diag_log_gsm.c
@@ -39,9 +39,62 @@ 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)
+{
+ struct diag_mdsp_log_cmds *dmlcs = (struct diag_mdsp_log_cmds *) msgb_data(msg);
+ int i;
+
+ printf("MDSP-COMMANDS { num_cmds=%u, cmds=[ ", dmlcs->num_cmds);
+
+ for (i = 0; i < dmlcs->num_cmds; i++) {
+ struct diag_mdsp_log_cmd *cmd = &dmlcs->cmds[i];
+ printf("{ fn=%u, cnt=%u, seq=%u, cmd=%u, params=[ %u, %u, %u, %u, %u ] }",
+ cmd->fn, cmd->cnt, cmd->seq, cmd->cmd,
+ cmd->params[0], cmd->params[1], cmd->params[2], cmd->params[3],
+ cmd->params[4]);
+ if (i+1 != dmlcs->num_cmds)
+ printf(", ");
+
+ }
+ printf(" ] }\n");
+}
+
+static void handle_l2_state(struct log_hdr *lh, struct msgb *msg)
+{
+ struct diag_gsm_l2_state *l2s = (struct diag_gsm_l2_state *) msgb_data(msg);
+
+ printf("L2-STATE { sapi=%u, ", l2s->sapi);
+ switch (l2s->sapi) {
+ case 0:
+ printf("l2_state=%s, ",
+ get_value_string(diag_gsm_l2_sapi0_st_vals, l2s->l2_state));
+ break;
+ case 3:
+ printf("l2_state=%s, ",
+ get_value_string(diag_gsm_l2_sapi3_st_vals, l2s->l2_state));
+ break;
+ default:
+ break;
+ }
+ printf("l2_event=%s }\n",
+ get_value_string(diag_gsm_l2_event_vals, l2s->l2_event));
+}
+
+static void handle_l2_transm_status(struct log_hdr *lh, struct msgb *msg)
+{
+ struct diag_gsm_l2_transm_status *lts = (struct diag_gsm_l2_transm_status *) msgb_data(msg);
+
+ printf("L2-TRANSM-STATUS { sapi=%u, chan_type=%u, vs=%u, va=%u, vr=%u, retrans_ctr=%u, seq_err=%u, frame_type=%u, msg_entries=%u, seg_entries=%u }\n",
+ lts->sapi, lts->channel_type, lts->vs, lts->va, lts->vr, lts->retrans_ctr,
+ lts->seq_err, lts->frame_type, lts->msg_entries, lts->seg_entries);
+}
+
static const struct diag_log_dispatch_tbl log_tbl[] = {
{ GSM(LOG_GSM_RR_SIGNALING_MESSAGE_C), handle_rr_sig_msg },
{ 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},
};
static __attribute__((constructor)) void on_dso_load_gsm(void)
diff --git a/src/protocol/diag_log_gsm.h b/src/protocol/diag_log_gsm.h
index 946a213..a648014 100644
--- a/src/protocol/diag_log_gsm.h
+++ b/src/protocol/diag_log_gsm.h
@@ -11,11 +11,17 @@ enum diag_log_code_gsm {
LOG_GSM_AFC_ADJUST_C = 0x7c,
LOG_GSM_MON_BURST_C = 0x82,
LOG_GSM_BCCH_BURST_METRICS_C = 0x85,
+ LOG_GSM_MDSP_CMD_C = 0x8c,
LOG_GSM_GL1_HW_CMD_C = 0x8d,
- LOG_GSM_RR_STATE_C = 0x12c,
LOG_GSM_RR_SIGNALING_MESSAGE_C = 0x12f,
+ /* Layer2 (LAPDm) */
+ LOG_GSM_L2_STATE_C = 200,
+ LOG_GSM_L2_TRANSMISSION_STATUS_C = 201,
+ LOG_GSM_L2_OUTSTANDING_FRAME_C = 202,
+
+ LOG_GSM_RR_STATE_C = 300,
//= 303,
LOG_GSM_RR_CONTROL_CHANNEL_PARAMS_C = 306,
@@ -251,4 +257,93 @@ struct diag_gprs_llc_xid_info {
struct diag_xid_tuple8 ku;
} __attribute__ ((packed));
+struct diag_mdsp_log_cmd {
+ uint32_t fn;
+ uint16_t cnt;
+ uint16_t seq;
+ uint16_t cmd;
+ uint16_t params[5];
+} __attribute__ ((packed));
+
+struct diag_mdsp_log_cmds {
+ uint32_t num_cmds;
+ struct diag_mdsp_log_cmd cmds[16];
+} __attribute__ ((packed));
+
+
+enum diag_gsm_sapi0_state {
+ DIAG_SAPI0_ST_NULL,
+ DIAG_SAPI0_ST_CON_PEND,
+ DIAG_SAPI0_ST_IDLE,
+ DIAG_SAPI0_ST_EST_PEND,
+ DIAG_SAPI0_ST_REL_PEND,
+ DIAG_SAPI0_ST_LINK_EST,
+ DIAG_SAPI0_ST_TMR_RECOV,
+ DIAG_SAPI0_ST_LINK_SUSP,
+ DIAG_SAPI0_ST_UA_PEND,
+};
+const struct value_string diag_gsm_l2_sapi0_st_vals[10];
+
+enum diag_gsm_sapi3_state {
+ DIAG_SAPI3_ST_NULL,
+ DIAG_SAPI3_ST_CON_PEND,
+ DIAG_SAPI3_ST_IDLE,
+ DIAG_SAPI3_ST_EST_PEND,
+ DIAG_SAPI3_ST_REL_PEND,
+ DIAG_SAPI3_ST_LINK_EST,
+ DIAG_SAPI3_ST_TMR_RECOV,
+ DIAG_SAPI3_ST_UA_PEND,
+};
+const struct value_string diag_gsm_l2_sapi3_st_vals[9];
+
+enum diag_gsm_l2_event {
+ DIAG_L2_EV_NO_EVENT,
+ DIAG_L2_EV_CONNECT_RECEIVED,
+ DIAG_L2_EV_ESTABLISH_REQUEST,
+ DIAG_L2_EV_RELEASE_REQUEST,
+ DIAG_L2_EV_SUSPEND_REQUEST,
+ DIAG_L2_EV_RESUME_REQUEST,
+ DIAG_L2_EV_RECONNECT_REQUEST,
+ DIAG_L2_EV_DATA_REQUEST,
+ DIAG_L2_EV_MDL_RELEASE_REQUEST,
+ DIAG_L2_EV_UA_RECEIVED,
+ DIAG_L2_EV_DM_RECEIVED,
+ DIAG_L2_EV_DISC_RECEIVED,
+ DIAG_L2_EV_SABM_RECEIVED,
+ DIAG_L2_EV_I_RECEIVED,
+ DIAG_L2_EV_UI_RECEIVED,
+ DIAG_L2_EV_RR_RECEIVED,
+ DIAG_L2_EV_REJ_RECEIVED,
+ DIAG_L2_EV_T200_TIMEOUT,
+ DIAG_L2_EV_CONTENTION_FAILED,
+ DIAG_L2_EV_ABORT_ESTABLISHMENT,
+ DIAG_L2_EV_LINK_ESTABLISHED,
+ DIAG_L2_EV_RELEASE_CONFIRMED,
+ DIAG_L2_EV_CLEAR_RECOVERY_CONDITION,
+ DIAG_L2_EV_OPTIONAL_SEND,
+ DIAG_L2_EV_RESET_L2,
+ DIAG_L2_EV_UA_SENT,
+ DIAG_L2_EV_FORCED_SUSPEND_REQ,
+};
+const struct value_string diag_gsm_l2_event_vals[27];
+
+struct diag_gsm_l2_state {
+ uint8_t sapi;
+ uint8_t l2_state;
+ uint8_t l2_event;
+} __attribute__ ((packed));
+
+struct diag_gsm_l2_transm_status {
+ uint8_t sapi;
+ uint8_t channel_type;
+ uint8_t vs;
+ uint8_t va;
+ uint8_t vr;
+ uint8_t retrans_ctr;
+ uint8_t seq_err;
+ uint8_t frame_type;
+ uint8_t msg_entries;
+ uint8_t seg_entries;
+} __attribute__ ((packed));
+
struct msgb *diag_gsm_make_log_pack_req(uint16_t log_code, uint8_t zero_stats, uint8_t addl_info);