From 0512d9d2664fb0893aa4c096767f4e08d0362acb Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 21 Jan 2017 11:01:45 +0100 Subject: [PATCH] decoder for RLC-EPDAN, MDSP-CMD, L2-STATE and L2-TRANSM-STATUS --- src/diag_gsm.c | 54 +++++++++++++++++++++ src/diag_log_gprs.c | 29 +++++++++-- src/diag_log_gsm.c | 53 ++++++++++++++++++++ src/protocol/diag_log_gsm.h | 97 ++++++++++++++++++++++++++++++++++++- 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);