layer23: Added VTY command to display current states.
authorAndreas.Eversberg <jolly@eversberg.eu>
Wed, 16 Jun 2010 17:17:29 +0000 (17:17 +0000)
committerAndreas.Eversberg <jolly@eversberg.eu>
Wed, 16 Jun 2010 17:17:29 +0000 (17:17 +0000)
Also rejecting ASSIGNMENT COMMAND.

src/host/layer23/include/osmocom/gsm322.h
src/host/layer23/include/osmocom/gsm48_mm.h
src/host/layer23/include/osmocom/gsm48_rr.h
src/host/layer23/src/gsm48_cc.c
src/host/layer23/src/gsm48_mm.c
src/host/layer23/src/gsm48_rr.c
src/host/layer23/src/vty_interface.c

index 6cb1677..3a275b1 100755 (executable)
@@ -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 */
index ad71ce0..22c5983 100644 (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 */
index cde5433..4fc7547 100644 (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 */
index 7a56366..386fe80 100644 (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},
 };
index 9f08520..4b2e723 100644 (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"
 };
index ed03284..ef13893 100644 (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);
index 3e92166..5d43e97 100644 (file)
 #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);