layer23: Added VTY command to display current states.

Also rejecting ASSIGNMENT COMMAND.
This commit is contained in:
Andreas.Eversberg 2010-06-16 17:17:29 +00:00
parent 4fff9fbd8e
commit f195635d31
7 changed files with 272 additions and 180 deletions

View File

@ -191,5 +191,8 @@ int gsm322_dump_ba_list(struct gsm322_cellsel *cs, uint16_t mcc, uint16_t mnc,
void (*print)(void *, const char *, ...), void *priv);
void start_cs_timer(struct gsm322_cellsel *cs, int sec, int micro);
void start_loss_timer(struct gsm322_cellsel *cs, int sec, int micro);
extern const char *plmn_a_state_names[];
extern const char *plmn_m_state_names[];
extern const char *cs_state_names[];
#endif /* _GSM322_H */

View File

@ -221,5 +221,7 @@ struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
uint8_t transaction_id);
const char *get_mmr_name(int value);
const char *get_mmxx_name(int value);
extern const char *gsm48_mm_state_names[];
extern const char *gsm48_mm_substate_names[];
#endif /* _GSM48_MM_H */

View File

@ -154,5 +154,6 @@ int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,
int gsm48_rr_enc_cm2(struct osmocom_ms *ms, struct gsm48_classmark2 *cm);
int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg);
int gsm48_rr_los(struct osmocom_ms *ms);
extern const char *gsm48_rr_state_names[];
#endif /* _GSM48_RR_H */

View File

@ -246,7 +246,6 @@ static void new_cc_state(struct gsm_trans *trans, int state)
static void gsm48_cc_timeout(void *arg)
{
struct gsm_trans *trans = arg;
struct osmocom_ms *ms = trans->ms;
int disconnect = 0, release = 0, abort = 1;
int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER;
int mo_location = GSM48_CAUSE_LOC_PRN_S_LU;
@ -1817,46 +1816,63 @@ static struct downstate {
/* mobile originating call establishment */
{SBIT(GSM_CSTATE_NULL), /* 5.2.1 */
MNCC_SETUP_REQ, gsm48_cc_init_mm},
{SBIT(GSM_CSTATE_MM_CONNECTION_PEND), /* 5.2.1 */
MNCC_REL_REQ, gsm48_cc_abort_mm},
/* mobile terminating call establishment */
{SBIT(GSM_CSTATE_CALL_PRESENT), /* 5.2.2.3.1 */
MNCC_CALL_CONF_REQ, gsm48_cc_tx_call_conf},
{SBIT(GSM_CSTATE_MO_TERM_CALL_CONF), /* 5.2.2.3.2 */
MNCC_ALERT_REQ, gsm48_cc_tx_alerting},
{SBIT(GSM_CSTATE_MO_TERM_CALL_CONF) |
SBIT(GSM_CSTATE_CALL_RECEIVED), /* 5.2.2.5 */
MNCC_SETUP_RSP, gsm48_cc_tx_connect},
/* signalling during call */
{SBIT(GSM_CSTATE_ACTIVE), /* 5.3.1 */
MNCC_NOTIFY_REQ, gsm48_cc_tx_notify},
{ALL_STATES, /* 5.5.7.1 */
MNCC_START_DTMF_REQ, gsm48_cc_tx_start_dtmf},
{ALL_STATES, /* 5.5.7.3 */
MNCC_STOP_DTMF_REQ, gsm48_cc_tx_stop_dtmf},
{SBIT(GSM_CSTATE_ACTIVE),
MNCC_HOLD_REQ, gsm48_cc_tx_hold},
{SBIT(GSM_CSTATE_ACTIVE),
MNCC_RETRIEVE_REQ, gsm48_cc_tx_retrieve},
{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ),
MNCC_FACILITY_REQ, gsm48_cc_tx_facility},
{SBIT(GSM_CSTATE_ACTIVE),
MNCC_USERINFO_REQ, gsm48_cc_tx_userinfo},
/* clearing */
{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_DISCONNECT_IND) -
SBIT(GSM_CSTATE_RELEASE_REQ) -
SBIT(GSM_CSTATE_DISCONNECT_REQ), /* 5.4.3.1 */
MNCC_DISC_REQ, gsm48_cc_tx_disconnect},
{SBIT(GSM_CSTATE_INITIATED),
MNCC_REJ_REQ, gsm48_cc_tx_release_compl},
{ALL_STATES - SBIT(GSM_CSTATE_NULL) -
SBIT(GSM_CSTATE_RELEASE_REQ), /* ??? */
MNCC_REL_REQ, gsm48_cc_tx_release},
/* modify */
{SBIT(GSM_CSTATE_ACTIVE),
MNCC_MODIFY_REQ, gsm48_cc_tx_modify},
{SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
MNCC_MODIFY_RSP, gsm48_cc_tx_modify_complete},
{SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
MNCC_MODIFY_REJ, gsm48_cc_tx_modify_reject},
};
@ -1923,56 +1939,78 @@ static struct datastate {
/* mobile originating call establishment */
{SBIT(GSM_CSTATE_INITIATED), /* 5.2.1.3 */
GSM48_MT_CC_CALL_PROC, gsm48_cc_rx_call_proceeding},
{SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) |
SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.4.1 */
MNCC_PROGRESS_REQ, gsm48_cc_rx_progress},
{SBIT(GSM_CSTATE_INITIATED) |
SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.5 */
GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting},
{SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) |
SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.6 */
GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect},
/* mobile terminating call establishment */
{SBIT(GSM_CSTATE_NULL), /* 5.2.2.1 */
GSM48_MT_CC_SETUP, gsm48_cc_rx_setup},
{SBIT(GSM_CSTATE_CALL_PRESENT), /* 5.2.2.6 */
GSM48_MT_CC_CONNECT_ACK, gsm48_cc_rx_connect_ack},
/* signalling during call */
{SBIT(GSM_CSTATE_ACTIVE), /* 5.3.1 */
GSM48_MT_CC_NOTIFY, gsm48_cc_rx_notify},
{ALL_STATES, /* 8.4 */
GSM48_MT_CC_STATUS_ENQ, gsm48_cc_rx_status_enq},
{ALL_STATES, /* 5.5.7.2 */
GSM48_MT_CC_START_DTMF_ACK, gsm48_cc_rx_start_dtmf_ack},
{ALL_STATES, /* 5.5.7.2 */
GSM48_MT_CC_START_DTMF_REJ, gsm48_cc_rx_start_dtmf_rej},
{ALL_STATES, /* 5.5.7.4 */
GSM48_MT_CC_STOP_DTMF_ACK, gsm48_cc_rx_stop_dtmf_ack},
{SBIT(GSM_CSTATE_ACTIVE),
GSM48_MT_CC_HOLD_ACK, gsm48_cc_rx_hold_ack},
{SBIT(GSM_CSTATE_ACTIVE),
GSM48_MT_CC_HOLD_REJ, gsm48_cc_rx_hold_rej},
{SBIT(GSM_CSTATE_ACTIVE),
GSM48_MT_CC_RETR_ACK, gsm48_cc_rx_retrieve_ack},
{SBIT(GSM_CSTATE_ACTIVE),
GSM48_MT_CC_RETR_REJ, gsm48_cc_rx_retrieve_rej},
{ALL_STATES - SBIT(GSM_CSTATE_NULL),
GSM48_MT_CC_FACILITY, gsm48_cc_rx_facility},
{SBIT(GSM_CSTATE_ACTIVE),
GSM48_MT_CC_USER_INFO, gsm48_cc_rx_userinfo},
/* clearing */
{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ) -
SBIT(GSM_CSTATE_DISCONNECT_IND), /* 5.4.4.1.1 */
GSM48_MT_CC_DISCONNECT, gsm48_cc_rx_disconnect},
{ALL_STATES - SBIT(GSM_CSTATE_NULL), /* 5.4.3.3 & 5.4.5!!!*/
GSM48_MT_CC_RELEASE, gsm48_cc_rx_release},
{ALL_STATES, /* 5.4.4.1.3 */
GSM48_MT_CC_RELEASE_COMPL, gsm48_cc_rx_release_compl},
/* modify */
{SBIT(GSM_CSTATE_ACTIVE),
GSM48_MT_CC_MODIFY, gsm48_cc_rx_modify},
{SBIT(GSM_CSTATE_MO_TERM_MODIFY),
GSM48_MT_CC_MODIFY_COMPL, gsm48_cc_rx_modify_complete},
{SBIT(GSM_CSTATE_MO_TERM_MODIFY),
GSM48_MT_CC_MODIFY_REJECT, gsm48_cc_rx_modify_reject},
};

View File

@ -819,45 +819,45 @@ static int gsm48_mm_to_rr(struct osmocom_ms *ms, struct msgb *msg,
* state transition
*/
static const char *gsm48_mm_state_names[] = {
const char *gsm48_mm_state_names[] = {
"NULL",
"undefined 1",
"undefined 2",
"LOC_UPD_INIT",
"location updating initiated",
"undefined 4",
"WAIT_OUT_MM_CONN",
"MM_CONN_ACTIVE",
"IMSI_DETACH_INIT",
"PROCESS_CM_SERV_P",
"WAIT_NETWORK_CMD",
"LOC_UPD_REJ",
"wait for outgoing MM connection",
"MM connection active",
"IMSI detach initiated",
"process CM service prompt",
"wait for network command",
"location updating reject",
"undefined 11",
"undefined 12",
"WAIT_RR_CONN_LUPD",
"WAIT_RR_CONN_MM_CON",
"WAIT_RR_CONN_IMSI_D",
"wait for RR connection (location updating)",
"wait for RR connection (MM connection)",
"wait for RR connection (IMSI detach)",
"undefined 16",
"WAIT_REEST",
"WAIT_RR_ACTIVE",
"MM_IDLE",
"WAIT_ADD_OUT_MM_CON",
"wait for re-establishment",
"wait for RR connection active",
"MM idle",
"wait for additional outgoing MM connection",
"MM_CONN_ACTIVE_VGCS",
"WAIT_RR_CONN_VGCS",
"LOC_UPD_PEND",
"IMSI_DETACH_PEND",
"RR_CONN_RELEASE_NA"
"location updating pending",
"IMSI detach pending",
"RR connection release not allowed"
};
static const char *gsm48_mm_substate_names[] = {
const char *gsm48_mm_substate_names[] = {
"NULL",
"NORMAL_SERVICE",
"ATTEMPT_UPDATE",
"LIMITED_SERVICE",
"NO_IMSI",
"NO_CELL_AVAIL",
"LOC_UPD_NEEDED",
"PLMN_SEARCH",
"PLMN_SEARCH_NORMAL",
"normal service",
"attempting to update",
"limited service",
"no IMSI",
"no cell available",
"location updating needed",
"PLMN search",
"PLMN search (normal)",
"RX_VGCS_NORMAL",
"RX_VGCS_LIMITED"
};

View File

@ -192,11 +192,11 @@ static int gsm48_decode_ba_range(const uint8_t *ba, uint8_t ba_len,
* state transition
*/
static const char *gsm48_rr_state_names[] = {
"IDLE",
"CONN PEND",
"DEDICATED",
"REL PEND",
const char *gsm48_rr_state_names[] = {
"idle",
"connection pending",
"dedicated",
"release pending",
};
static void new_rr_state(struct gsm48_rrlayer *rr, int state)
@ -2507,54 +2507,6 @@ static int gsm48_match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *ref)
return 0;
}
/* 9.1.3 sending ASSIGNMENT COMPLETE */
static int gsm48_rr_tx_ass_cpl(struct osmocom_ms *ms, uint8_t cause)
{
struct msgb *nmsg;
struct gsm48_hdr *gh;
struct gsm48_ass_cpl *ac;
LOGP(DRR, LOGL_INFO, "ASSIGNMENT COMPLETE (cause #%d)\n", cause);
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
ac = (struct gsm48_ass_cpl *) msgb_put(nmsg, sizeof(*ac));
gh->proto_discr = GSM48_PDISC_RR;
gh->msg_type = GSM48_MT_RR_ASS_COMPL;
/* RR_CAUSE */
ac->rr_cause = cause;
return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
}
/* 9.1.4 sending ASSIGNMENT FAILURE */
static int gsm48_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause)
{
struct msgb *nmsg;
struct gsm48_hdr *gh;
struct gsm48_ass_fail *af;
LOGP(DRR, LOGL_INFO, "ASSIGNMENT FAILURE (cause #%d)\n", cause);
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
af = (struct gsm48_ass_fail *) msgb_put(nmsg, sizeof(*af));
gh->proto_discr = GSM48_PDISC_RR;
gh->msg_type = GSM48_MT_RR_ASS_COMPL;
/* RR_CAUSE */
af->rr_cause = cause;
return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
}
/* 9.1.18 IMMEDIATE ASSIGNMENT is received */
static int gsm48_rr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
{
@ -3117,6 +3069,145 @@ static int gsm48_rr_rx_chan_rel(struct osmocom_ms *ms, struct msgb *msg)
return gsm48_send_rsl(ms, RSL_MT_REL_REQ, nmsg);
}
/*
* assignment and handover
*/
/* 9.1.3 sending ASSIGNMENT COMPLETE */
static int gsm48_rr_tx_ass_cpl(struct osmocom_ms *ms, uint8_t cause)
{
struct msgb *nmsg;
struct gsm48_hdr *gh;
struct gsm48_ass_cpl *ac;
LOGP(DRR, LOGL_INFO, "ASSIGNMENT COMPLETE (cause #%d)\n", cause);
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
ac = (struct gsm48_ass_cpl *) msgb_put(nmsg, sizeof(*ac));
gh->proto_discr = GSM48_PDISC_RR;
gh->msg_type = GSM48_MT_RR_ASS_COMPL;
/* RR_CAUSE */
ac->rr_cause = cause;
return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
}
/* 9.1.4 sending ASSIGNMENT FAILURE */
static int gsm48_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause)
{
struct msgb *nmsg;
struct gsm48_hdr *gh;
struct gsm48_ass_fail *af;
LOGP(DRR, LOGL_INFO, "ASSIGNMENT FAILURE (cause #%d)\n", cause);
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
af = (struct gsm48_ass_fail *) msgb_put(nmsg, sizeof(*af));
gh->proto_discr = GSM48_PDISC_RR;
gh->msg_type = GSM48_MT_RR_ASS_COMPL;
/* RR_CAUSE */
af->rr_cause = cause;
return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
}
/* 9.1.2 ASSIGNMENT COMMAND is received */
static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
{
// struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_ass_cmd *ac = (struct gsm48_ass_cmd *)gh->data;
int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ac);
struct tlv_parsed tp;
struct gsm48_rr_cd cd;
LOGP(DRR, LOGL_INFO, "ASSIGNMENT COMMAND\n");
memset(&cd, 0, sizeof(cd));
if (payload_len < 0) {
LOGP(DRR, LOGL_NOTICE, "Short read of ASSIGNMENT COMMAND message.\n");
return gsm48_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
}
tlv_parse(&tp, &gsm48_rr_att_tlvdef, ac->data, payload_len, 0, 0);
#if 0
/* channel description */
memcpy(&cd.chan_desc, &ac->chan_desc, sizeof(chan_desc));
/* power command */
cd.power_command = ac->power_command;
/* frequency list, after timer */
tlv_copy(&cd.fl, sizeof(fl_after), &tp, GSM48_IE_FRQLIST_AFTER);
/* cell channel description */
tlv_copy(&cd.ccd, sizeof(ccd), &tp, GSM48_IE_CELL_CH_DESC);
/* multislot allocation */
tlv_copy(&cd.multia, sizeof(ma), &tp, GSM48_IE_MSLOT_DESC);
/* channel mode */
tlv_copy(&cd.chanmode, sizeof(chanmode), &tp, GSM48_IE_CHANMODE_1);
/* mobile allocation, after time */
tlv_copy(&cd.moba_after, sizeof(moba_after), &tp, GSM48_IE_MOB_AL_AFTER);
/* starting time */
tlv_copy(&cd.start, sizeof(start), &tp, GSM_IE_START_TIME);
/* frequency list, before time */
tlv_copy(&cd.fl_before, sizeof(fl_before), &tp, GSM48_IE_FRQLIST_BEFORE);
/* channel description, before time */
tlv_copy(&cd.chan_desc_before, sizeof(cd_before), &tp, GSM48_IE_CHDES_1_BEFORE);
/* frequency channel sequence, before time */
tlv_copy(&cd.fcs_before, sizeof(fcs_before), &tp, GSM48_IE_FRQSEQ_BEFORE);
/* mobile allocation, before time */
tlv_copy(&cd.moba_before, sizeof(moba_before), &tp, GSM48_IE_MOB_AL_BEFORE);
/* cipher mode setting */
if (TLVP_PRESENT(&tp, GSM48_IE_CIP_MODE_SET))
cd.cipher = *TLVP_VAL(&tp, GSM48_IE_CIP_MODE_SET);
else
cd.cipher = 0;
if (no CA) {
LOGP(DRR, LOGL_INFO, "No current cell allocation available.\n");
return gsm48_rr_tx_ass_fail(ms, GSM48_GSM48_RR_CAUSE_NO_CELL_ALLOC_A);
}
if (not supported) {
LOGP(DRR, LOGL_INFO, "New channel is not supported.\n");
return gsm48_rr_tx_ass_fail(ms, GSM48_RR_CAUSE_CHAN_MODE_UNACCEPT);
}
if (freq not supported) {
LOGP(DRR, LOGL_INFO, "New frequency is not supported.\n");
return gsm48_rr_tx_ass_fail(ms, GSM48_RR_CAUSE_FREQ_NOT_IMPL);
}
/* store current channel descriptions, to return in case of failure */
memcpy(&rr->chan_last, &rr->chan_desc, sizeof(*cd));
/* copy new description */
memcpy(&rr->chan_desc, cd, sizeof(cd));
/* start suspension of current link */
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, msg);
/* change into special assignment suspension state */
rr->assign_susp_state = 1;
rr->resume_last_state = 0;
#else
return gsm48_rr_tx_ass_fail(ms, GSM48_RR_CAUSE_FREQ_NOT_IMPL);
#endif
return 0;
}
/*
* radio ressource requests
*/
@ -3285,10 +3376,10 @@ static int gsm48_rr_data_ind(struct osmocom_ms *ms, struct msgb *msg)
case GSM48_MT_RR_ADD_ASS:
rc = gsm48_rr_rx_add_ass(ms, msg);
break;
#if 0
case GSM48_MT_RR_ASS_CMD:
rc = gsm48_rr_rx_ass_cmd(ms, msg);
break;
#if 0
case GSM48_MT_RR_CIP_MODE_CMD:
rc = gsm48_rr_rx_cip_mode_cmd(ms, msg);
break;
@ -3787,12 +3878,6 @@ incomplete
todo:
add support structure
initialize support structure
queue messages (rslms_data_req) if channel changes
flush rach msg in all cases: during sending, after its done, and when aborted
stop timers on abort
wird beim abbruch immer der gepufferte cm-service-request entfernt, auch beim verschicken?:
measurement reports
@ -3800,15 +3885,6 @@ todo rr_sync_ind when receiving ciph, re ass, channel mode modify
todo change procedures, release procedure
during procedures, like "channel assignment" or "handover", rr requests must be queued
they must be dequeued when complete
they queue must be flushed when rr fails
#include <osmocore/protocol/gsm_04_08.h>
#include <osmocore/msgb.h>
#include <osmocore/utils.h>
#include <osmocore/gsm48.h>
static int gsm48_rr_act_req(struct osmocom_ms *ms, struct gsm48_rr *rrmsg)
{
}
@ -3839,87 +3915,6 @@ static int tlv_copy(void *dest, int dest_len, struct tlv_parsed *tp, uint8_t ie)
return 0;
}
static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = ms->rrlayer;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_ass_cmd *ac = (struct gsm48_ass_cmd *)gh->data;
int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ac);
struct tlv_parsed tp;
struct gsm48_rr_chan_desc cd;
struct msgb *nmsg;
memset(&cd, 0, sizeof(cd));
if (payload_len < 0) {
LOGP(DRR, LOGL_NOTICE, "Short read of ASSIGNMENT COMMAND message.\n");
return gsm48_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
}
tlv_parse(&tp, &gsm48_rr_att_tlvdef, ac->data, payload_len, 0, 0);
/* channel description */
memcpy(&cd.chan_desc, &ac->chan_desc, sizeof(chan_desc));
/* power command */
cd.power_command = ac->power_command;
/* frequency list, after timer */
tlv_copy(&cd.fl, sizeof(fl_after), &tp, GSM48_IE_FRQLIST_AFTER);
/* cell channel description */
tlv_copy(&cd.ccd, sizeof(ccd), &tp, GSM48_IE_CELL_CH_DESC);
/* multislot allocation */
tlv_copy(&cd.multia, sizeof(ma), &tp, GSM48_IE_MSLOT_DESC);
/* channel mode */
tlv_copy(&cd.chanmode, sizeof(chanmode), &tp, GSM48_IE_CHANMODE_1);
/* mobile allocation, after time */
tlv_copy(&cd.moba_after, sizeof(moba_after), &tp, GSM48_IE_MOB_AL_AFTER);
/* starting time */
tlv_copy(&cd.start, sizeof(start), &tp, GSM_IE_START_TIME);
/* frequency list, before time */
tlv_copy(&cd.fl_before, sizeof(fl_before), &tp, GSM48_IE_FRQLIST_BEFORE);
/* channel description, before time */
tlv_copy(&cd.chan_desc_before, sizeof(cd_before), &tp, GSM48_IE_CHDES_1_BEFORE);
/* frequency channel sequence, before time */
tlv_copy(&cd.fcs_before, sizeof(fcs_before), &tp, GSM48_IE_FRQSEQ_BEFORE);
/* mobile allocation, before time */
tlv_copy(&cd.moba_before, sizeof(moba_before), &tp, GSM48_IE_MOB_AL_BEFORE);
/* cipher mode setting */
if (TLVP_PRESENT(&tp, GSM48_IE_CIP_MODE_SET))
cd.cipher = *TLVP_VAL(&tp, GSM48_IE_CIP_MODE_SET);
else
cd.cipher = 0;
if (no CA) {
LOGP(DRR, LOGL_INFO, "No current cell allocation available.\n");
return gsm48_rr_tx_rr_status(ms, GSM48_RR_CAUSE_NO_CELL_ALLOC_A);
}
if (not supported) {
LOGP(DRR, LOGL_INFO, "New channel is not supported.\n");
return gsm48_rr_tx_rr_status(ms, RR_CAUSE_CHAN_MODE_UNACCEPT);
}
if (freq not supported) {
LOGP(DRR, LOGL_INFO, "New frequency is not supported.\n");
return gsm48_rr_tx_rr_status(ms, RR_CAUSE_FREQ_NOT_IMPLEMENTED);
}
/* store current channel descriptions, to return in case of failure */
memcpy(&rr->chan_last, &rr->chan_desc, sizeof(*cd));
/* copy new description */
memcpy(&rr->chan_desc, cd, sizeof(cd));
/* start suspension of current link */
nmsg = gsm48_l3_msgb_alloc();
if (!nmsg)
return -ENOMEM;
gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, msg);
/* change into special assignment suspension state */
rr->assign_susp_state = 1;
rr->resume_last_state = 0;
return 0;
}
/* decode "Cell Description" (10.5.2.2) */
static int gsm48_decode_cell_desc(struct gsm48_cell_desc *cd, uint16_t *arfcn, uint8_t *ncc uint8_t *bcc)
@ -3953,7 +3948,7 @@ static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_ho_cmd *ho = (struct gsm48_ho_cmd *)gh->data;
int payload_len = msgb_l3len(msg) - sizeof(*gh) - wirklich sizeof(*ho);
struct tlv_parsed tp;
struct gsm48_rr_chan_desc cd;
struct gsm48_rr_cd cd;
struct msgb *nmsg;
memset(&cd, 0, sizeof(cd));
@ -4012,7 +4007,7 @@ static int gsm48_rr_estab_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
rr->resume_last_state = 0;
gsm48_rr_tx_ass_cpl(ms, GSM48_RR_CAUSE_NORMAL);
} else {
gsm48_rr_tx_ass_fail(ms, RR_CAUSE_PROTO_ERR_UNSPEC);
gsm48_rr_tx_ass_fail(ms, GSM48_RR_CAUSE_PROTO_ERR_UNSPEC);
}
/* transmit queued frames during ho / ass transition */
gsm48_rr_dequeue_down(ms);

View File

@ -29,8 +29,11 @@
#include <vty/buffer.h>
#include <vty/vty.h>
#include <osmocore/gsm48.h>
#include <osmocom/osmocom_data.h>
#include <osmocom/networks.h>
#include <osmocom/mncc.h>
#include <osmocom/transaction.h>
int mncc_call(struct osmocom_ms *ms, char *number);
int mncc_hangup(struct osmocom_ms *ms);
@ -128,6 +131,54 @@ DEFUN(show_support, show_support_cmd, "show support [ms_name]",
return CMD_SUCCESS;
}
static void gsm_states_dump(struct osmocom_ms *ms, struct vty *vty)
{
struct gsm_trans *trans;
vty_out(vty, "Current state of MS '%s'%s", ms->name, VTY_NEWLINE);
if (ms->settings.plmn_mode == PLMN_MODE_AUTO)
vty_out(vty, " automatic network selection: %s%s",
plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
else
vty_out(vty, " manual network selection: %s%s",
plmn_m_state_names[ms->plmn.state], VTY_NEWLINE);
vty_out(vty, " cell selection: %s%s",
cs_state_names[ms->cellsel.state], VTY_NEWLINE);
vty_out(vty, " radio ressource layer: %s%s",
gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
vty_out(vty, " mobility management layer: %s",
gsm48_mm_state_names[ms->mmlayer.state]);
if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
vty_out(vty, ", %s",
gsm48_mm_substate_names[ms->mmlayer.substate]);
vty_out(vty, "%s", VTY_NEWLINE);
llist_for_each_entry(trans, &ms->trans_list, entry) {
vty_out(vty, " call control: %s%s",
gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
}
}
DEFUN(show_states, show_states_cmd, "show states [ms_name]",
SHOW_STR "Display current states of given MS\n"
"Name of MS (see \"show ms\")")
{
struct osmocom_ms *ms;
if (argc) {
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
gsm_states_dump(ms, vty);
} else {
llist_for_each_entry(ms, &ms_list, entity) {
gsm_states_dump(ms, vty);
vty_out(vty, "%s", VTY_NEWLINE);
}
}
return CMD_SUCCESS;
}
DEFUN(show_subscr, show_subscr_cmd, "show subscriber [ms_name]",
SHOW_STR "Display information about subscriber\n"
"Name of MS (see \"show ms\")")
@ -694,6 +745,8 @@ int ms_vty_init(void)
install_element(VIEW_NODE, &show_subscr_cmd);
install_element(ENABLE_NODE, &show_support_cmd);
install_element(VIEW_NODE, &show_support_cmd);
install_element(ENABLE_NODE, &show_states_cmd);
install_element(VIEW_NODE, &show_states_cmd);
install_element(ENABLE_NODE, &show_cell_cmd);
install_element(VIEW_NODE, &show_cell_cmd);
install_element(ENABLE_NODE, &show_cell_si_cmd);