layer23: Added VTY command to display current states.
Also rejecting ASSIGNMENT COMMAND.
This commit is contained in:
parent
4fff9fbd8e
commit
f195635d31
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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},
|
||||
};
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue