summaryrefslogtreecommitdiffstats
path: root/src/host
diff options
context:
space:
mode:
authorAndreas.Eversberg2010-06-16 19:17:29 +0200
committerAndreas.Eversberg2010-06-16 19:17:29 +0200
commitf195635d31ecb7f9f7057418059c731104a4b912 (patch)
treed76da5fb23aee91664c902bf9edfefe01a0c972c /src/host
parentlayer23 VTY: "end" now ends configuration in all config subnodes. (diff)
downloadosmocom-f195635d31ecb7f9f7057418059c731104a4b912.tar.gz
osmocom-f195635d31ecb7f9f7057418059c731104a4b912.tar.xz
osmocom-f195635d31ecb7f9f7057418059c731104a4b912.zip
layer23: Added VTY command to display current states.
Also rejecting ASSIGNMENT COMMAND.
Diffstat (limited to 'src/host')
-rwxr-xr-xsrc/host/layer23/include/osmocom/gsm322.h3
-rw-r--r--src/host/layer23/include/osmocom/gsm48_mm.h2
-rw-r--r--src/host/layer23/include/osmocom/gsm48_rr.h1
-rw-r--r--src/host/layer23/src/gsm48_cc.c40
-rw-r--r--src/host/layer23/src/gsm48_mm.c54
-rw-r--r--src/host/layer23/src/gsm48_rr.c299
-rw-r--r--src/host/layer23/src/vty_interface.c53
7 files changed, 272 insertions, 180 deletions
diff --git a/src/host/layer23/include/osmocom/gsm322.h b/src/host/layer23/include/osmocom/gsm322.h
index 6cb1677..3a275b1 100755
--- a/src/host/layer23/include/osmocom/gsm322.h
+++ b/src/host/layer23/include/osmocom/gsm322.h
@@ -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 */
diff --git a/src/host/layer23/include/osmocom/gsm48_mm.h b/src/host/layer23/include/osmocom/gsm48_mm.h
index ad71ce0..22c5983 100644
--- a/src/host/layer23/include/osmocom/gsm48_mm.h
+++ b/src/host/layer23/include/osmocom/gsm48_mm.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 */
diff --git a/src/host/layer23/include/osmocom/gsm48_rr.h b/src/host/layer23/include/osmocom/gsm48_rr.h
index cde5433..4fc7547 100644
--- a/src/host/layer23/include/osmocom/gsm48_rr.h
+++ b/src/host/layer23/include/osmocom/gsm48_rr.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 */
diff --git a/src/host/layer23/src/gsm48_cc.c b/src/host/layer23/src/gsm48_cc.c
index 7a56366..386fe80 100644
--- a/src/host/layer23/src/gsm48_cc.c
+++ b/src/host/layer23/src/gsm48_cc.c
@@ -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},
};
diff --git a/src/host/layer23/src/gsm48_mm.c b/src/host/layer23/src/gsm48_mm.c
index 9f08520..4b2e723 100644
--- a/src/host/layer23/src/gsm48_mm.c
+++ b/src/host/layer23/src/gsm48_mm.c
@@ -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"
};
diff --git a/src/host/layer23/src/gsm48_rr.c b/src/host/layer23/src/gsm48_rr.c
index ed03284..ef13893 100644
--- a/src/host/layer23/src/gsm48_rr.c
+++ b/src/host/layer23/src/gsm48_rr.c
@@ -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)
{
@@ -3118,6 +3070,145 @@ static int gsm48_rr_rx_chan_rel(struct osmocom_ms *ms, struct msgb *msg)
}
/*
+ * 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);
diff --git a/src/host/layer23/src/vty_interface.c b/src/host/layer23/src/vty_interface.c
index 3e92166..5d43e97 100644
--- a/src/host/layer23/src/vty_interface.c
+++ b/src/host/layer23/src/vty_interface.c
@@ -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);