2010-04-25 16:28:24 +00:00
|
|
|
#ifndef _GSM48_MM_H
|
|
|
|
#define _GSM48_MM_H
|
|
|
|
|
|
|
|
/* GSM 04.07 9.2.2 */
|
|
|
|
#define GSM48_MMXX_MASK 0xf00
|
|
|
|
#define GSM48_MMCC_CLASS 0x100
|
|
|
|
#define GSM48_MMSS_CLASS 0x200
|
|
|
|
#define GSM48_MMSMS_CLASS 0x300
|
|
|
|
#define GSM48_MMCC_EST_REQ 0x110
|
|
|
|
#define GSM48_MMCC_EST_IND 0x112
|
|
|
|
#define GSM48_MMCC_EST_CNF 0x111
|
|
|
|
#define GSM48_MMCC_REL_REQ 0x120
|
|
|
|
#define GSM48_MMCC_REL_IND 0x122
|
|
|
|
#define GSM48_MMCC_DATA_REQ 0x130
|
|
|
|
#define GSM48_MMCC_DATA_IND 0x132
|
|
|
|
#define GSM48_MMCC_UNIT_DATA_REQ 0x140
|
|
|
|
#define GSM48_MMCC_UNIT_DATA_IND 0x142
|
|
|
|
#define GSM48_MMCC_SYNC_IND 0x152
|
|
|
|
#define GSM48_MMCC_REEST_REQ 0x160
|
|
|
|
#define GSM48_MMCC_REEST_CNF 0x161
|
|
|
|
#define GSM48_MMCC_ERR_IND 0x172
|
|
|
|
#define GSM48_MMCC_PROMPT_IND 0x182
|
|
|
|
#define GSM48_MMCC_PROMPT_REJ 0x184
|
|
|
|
#define GSM48_MMSS_EST_REQ 0x210
|
|
|
|
#define GSM48_MMSS_EST_IND 0x212
|
|
|
|
#define GSM48_MMSS_EST_CNF 0x211
|
|
|
|
#define GSM48_MMSS_REL_REQ 0x220
|
|
|
|
#define GSM48_MMSS_REL_IND 0x222
|
|
|
|
#define GSM48_MMSS_DATA_REQ 0x230
|
|
|
|
#define GSM48_MMSS_DATA_IND 0x232
|
|
|
|
#define GSM48_MMSS_UNIT_DATA_REQ 0x240
|
|
|
|
#define GSM48_MMSS_UNIT_DATA_IND 0x242
|
|
|
|
#define GSM48_MMSS_REEST_REQ 0x260
|
|
|
|
#define GSM48_MMSS_REEST_CNF 0x261
|
|
|
|
#define GSM48_MMSS_ERR_IND 0x272
|
|
|
|
#define GSM48_MMSS_PROMPT_IND 0x282
|
|
|
|
#define GSM48_MMSS_PROMPT_REJ 0x284
|
|
|
|
#define GSM48_MMSMS_EST_REQ 0x310
|
|
|
|
#define GSM48_MMSMS_EST_IND 0x312
|
|
|
|
#define GSM48_MMSMS_EST_CNF 0x311
|
|
|
|
#define GSM48_MMSMS_REL_REQ 0x320
|
|
|
|
#define GSM48_MMSMS_REL_IND 0x322
|
|
|
|
#define GSM48_MMSMS_DATA_REQ 0x330
|
|
|
|
#define GSM48_MMSMS_DATA_IND 0x332
|
|
|
|
#define GSM48_MMSMS_UNIT_DATA_REQ 0x340
|
|
|
|
#define GSM48_MMSMS_UNIT_DATA_IND 0x342
|
|
|
|
#define GSM48_MMSMS_REEST_REQ 0x360
|
|
|
|
#define GSM48_MMSMS_REEST_CNF 0x361
|
|
|
|
#define GSM48_MMSMS_ERR_IND 0x372
|
|
|
|
#define GSM48_MMSMS_PROMPT_IND 0x382
|
|
|
|
#define GSM48_MMSMS_PROMPT_REJ 0x384
|
|
|
|
|
|
|
|
#define MMXX_ALLOC_SIZE 256
|
|
|
|
#define MMXX_ALLOC_HEADROOM 64
|
|
|
|
|
|
|
|
/* MMxx-SAP header */
|
|
|
|
struct gsm48_mmxx_hdr {
|
|
|
|
int msg_type; /* MMxx_* primitive */
|
|
|
|
uint32_t ref; /* reference to transaction */
|
|
|
|
uint32_t transaction_id; /* transaction identifier */
|
2011-10-31 17:08:12 +00:00
|
|
|
uint8_t sapi; /* sapi */
|
2010-04-25 16:28:24 +00:00
|
|
|
uint8_t emergency; /* emergency type of call */
|
|
|
|
uint8_t cause; /* cause used for release */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* GSM 6.1.2 */
|
|
|
|
#define GSM48_MMR_REG_REQ 0x01
|
|
|
|
#define GSM48_MMR_REG_CNF 0x02
|
|
|
|
#define GSM48_MMR_NREG_REQ 0x03
|
|
|
|
#define GSM48_MMR_NREG_IND 0x04
|
|
|
|
|
|
|
|
/* MMR-SAP header */
|
|
|
|
struct gsm48_mmr {
|
|
|
|
int msg_type;
|
|
|
|
|
|
|
|
uint8_t cause;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* GSM 04.07 9.2.1 */
|
|
|
|
#define GSM48_MMXX_ST_IDLE 0
|
|
|
|
#define GSM48_MMXX_ST_CONN_PEND 1
|
|
|
|
#define GSM48_MMXX_ST_DEDICATED 2
|
|
|
|
#define GSM48_MMXX_ST_CONN_SUSP 3
|
|
|
|
#define GSM48_MMXX_ST_REESTPEND 4
|
|
|
|
|
|
|
|
/* GSM 04.08 4.1.2.1 */
|
|
|
|
#define GSM48_MM_ST_NULL 0
|
|
|
|
#define GSM48_MM_ST_LOC_UPD_INIT 3
|
|
|
|
#define GSM48_MM_ST_WAIT_OUT_MM_CONN 5
|
|
|
|
#define GSM48_MM_ST_MM_CONN_ACTIVE 6
|
|
|
|
#define GSM48_MM_ST_IMSI_DETACH_INIT 7
|
|
|
|
#define GSM48_MM_ST_PROCESS_CM_SERV_P 8
|
|
|
|
#define GSM48_MM_ST_WAIT_NETWORK_CMD 9
|
|
|
|
#define GSM48_MM_ST_LOC_UPD_REJ 10
|
|
|
|
#define GSM48_MM_ST_WAIT_RR_CONN_LUPD 13
|
|
|
|
#define GSM48_MM_ST_WAIT_RR_CONN_MM_CON 14
|
|
|
|
#define GSM48_MM_ST_WAIT_RR_CONN_IMSI_D 15
|
|
|
|
#define GSM48_MM_ST_WAIT_REEST 17
|
|
|
|
#define GSM48_MM_ST_WAIT_RR_ACTIVE 18
|
|
|
|
#define GSM48_MM_ST_MM_IDLE 19
|
|
|
|
#define GSM48_MM_ST_WAIT_ADD_OUT_MM_CON 20
|
|
|
|
#define GSM48_MM_ST_MM_CONN_ACTIVE_VGCS 21
|
|
|
|
#define GSM48_MM_ST_WAIT_RR_CONN_VGCS 22
|
|
|
|
#define GSM48_MM_ST_LOC_UPD_PEND 23
|
|
|
|
#define GSM48_MM_ST_IMSI_DETACH_PEND 24
|
|
|
|
#define GSM48_MM_ST_RR_CONN_RELEASE_NA 25
|
|
|
|
|
|
|
|
/* GSM 04.08 4.1.2.1 */
|
|
|
|
#define GSM48_MM_SST_NORMAL_SERVICE 1
|
|
|
|
#define GSM48_MM_SST_ATTEMPT_UPDATE 2
|
|
|
|
#define GSM48_MM_SST_LIMITED_SERVICE 3
|
|
|
|
#define GSM48_MM_SST_NO_IMSI 4
|
|
|
|
#define GSM48_MM_SST_NO_CELL_AVAIL 5
|
|
|
|
#define GSM48_MM_SST_LOC_UPD_NEEDED 6
|
|
|
|
#define GSM48_MM_SST_PLMN_SEARCH 7
|
|
|
|
#define GSM48_MM_SST_PLMN_SEARCH_NORMAL 8
|
|
|
|
#define GSM48_MM_SST_RX_VGCS_NORMAL 9
|
|
|
|
#define GSM48_MM_SST_RX_VGCS_LIMITED 10
|
|
|
|
|
|
|
|
/* MM events */
|
2010-05-01 18:21:03 +00:00
|
|
|
#define GSM48_MM_EVENT_CELL_SELECTED 1
|
|
|
|
#define GSM48_MM_EVENT_NO_CELL_FOUND 2
|
|
|
|
#define GSM48_MM_EVENT_TIMEOUT_T3210 3
|
|
|
|
#define GSM48_MM_EVENT_TIMEOUT_T3211 4
|
|
|
|
#define GSM48_MM_EVENT_TIMEOUT_T3212 5
|
|
|
|
#define GSM48_MM_EVENT_TIMEOUT_T3213 6
|
2010-04-25 16:28:24 +00:00
|
|
|
#define GSM48_MM_EVENT_TIMEOUT_T3220 7
|
|
|
|
#define GSM48_MM_EVENT_TIMEOUT_T3230 8
|
|
|
|
#define GSM48_MM_EVENT_TIMEOUT_T3240 9
|
|
|
|
#define GSM48_MM_EVENT_IMSI_DETACH 10
|
|
|
|
#define GSM48_MM_EVENT_POWER_OFF 11
|
|
|
|
#define GSM48_MM_EVENT_PAGING 12
|
|
|
|
#define GSM48_MM_EVENT_AUTH_RESPONSE 13
|
|
|
|
#define GSM48_MM_EVENT_SYSINFO 14
|
2010-05-01 18:21:03 +00:00
|
|
|
#define GSM48_MM_EVENT_USER_PLMN_SEL 15
|
[layer23/mobile] Improvement and fixes of idle mode process
This patch introduces cell re-relection. When camping on a cell, it
scanns neighbour cells. If a 'better' cell is found, the cell is selected.
If the cell is in a different location area, a location upating is
performed under certain conditions.
The 'better' cell depends on various informations that are broadcasted on
the BCCH of a neihbour cell and of course the RX level. Most operators
don't set these informations, so the 'better' cell depend on a better
RX level for the same location area, or a much better RX level (6 dBm)
at a different location area.
There were many issues at the idle mode process that has been fixed.
Expecially when moving, the state machines got stuck, so no more cell search
was possible, or no further calls / location updating was possible.
In order to see the process of cell selection, enter the VTY interface and
enable the network monitor:
enable
monitor network 1 (where '1' is the instance of the MS)
In order to see the current state of the processes, enter:
show ms
2011-07-17 09:12:15 +00:00
|
|
|
#define GSM48_MM_EVENT_LOST_COVERAGE 16
|
2010-04-25 16:28:24 +00:00
|
|
|
|
|
|
|
/* message for MM events */
|
|
|
|
struct gsm48_mm_event {
|
|
|
|
uint32_t msg_type;
|
|
|
|
|
|
|
|
uint8_t sres[4];
|
|
|
|
};
|
|
|
|
|
|
|
|
/* GSM 04.08 MM timers */
|
|
|
|
#define GSM_T3210_MS 20, 0
|
|
|
|
#define GSM_T3211_MS 15, 0
|
|
|
|
/* T3212 is given by SYSTEM INFORMATION */
|
|
|
|
#define GSM_T3213_MS 4, 0
|
|
|
|
#define GSM_T3220_MS 5, 0
|
|
|
|
#define GSM_T3230_MS 15, 0
|
|
|
|
#define GSM_T3240_MS 10, 0
|
|
|
|
#define GSM_T3241_MS 300, 0
|
|
|
|
|
|
|
|
/* MM sublayer instance */
|
|
|
|
struct gsm48_mmlayer {
|
|
|
|
struct osmocom_ms *ms;
|
|
|
|
int state;
|
|
|
|
int substate;
|
|
|
|
|
|
|
|
/* queue for RR-SAP, MMxx-SAP, MMR-SAP, events message upwards */
|
|
|
|
struct llist_head rr_upqueue;
|
|
|
|
struct llist_head mmxx_upqueue;
|
|
|
|
struct llist_head mmr_downqueue;
|
|
|
|
struct llist_head event_queue;
|
|
|
|
|
|
|
|
/* timers */
|
2011-05-15 12:23:02 +00:00
|
|
|
struct osmo_timer_list t3210, t3211, t3212, t3213;
|
|
|
|
struct osmo_timer_list t3220, t3230, t3240;
|
2010-04-25 16:28:24 +00:00
|
|
|
int t3212_value;
|
2010-05-02 17:13:47 +00:00
|
|
|
int start_t3211; /* remember to start timer */
|
2010-04-25 16:28:24 +00:00
|
|
|
|
|
|
|
/* list of MM connections */
|
|
|
|
struct llist_head mm_conn;
|
|
|
|
|
|
|
|
/* network name */
|
|
|
|
char name_short[32];
|
|
|
|
char name_long[32];
|
|
|
|
|
|
|
|
/* location update */
|
|
|
|
uint8_t lupd_pending; /* current pending loc. upd. */
|
|
|
|
uint8_t lupd_type; /* current coded type */
|
|
|
|
uint8_t lupd_attempt; /* attempt counter */
|
|
|
|
uint8_t lupd_ra_failure;/* random access failed */
|
|
|
|
uint8_t lupd_rej_cause; /* cause of last reject */
|
2010-05-01 18:21:03 +00:00
|
|
|
uint8_t lupd_periodic; /* periodic update pending */
|
2010-06-06 18:19:46 +00:00
|
|
|
uint8_t lupd_retry; /* pending T3211/T3213 to */
|
2010-06-13 13:51:30 +00:00
|
|
|
uint16_t lupd_mcc, lupd_mnc, lupd_lac;
|
2010-04-25 16:28:24 +00:00
|
|
|
|
|
|
|
/* imsi detach */
|
|
|
|
uint8_t delay_detach; /* do detach when possible */
|
|
|
|
|
|
|
|
/* other */
|
2010-08-29 11:05:07 +00:00
|
|
|
uint8_t est_cause; /* cause of establishment msg */
|
2010-04-25 16:28:24 +00:00
|
|
|
int mr_substate; /* rem most recent substate */
|
2010-07-14 10:21:35 +00:00
|
|
|
uint8_t power_off_idle; /* waits for IDLE before po */
|
2011-10-31 17:08:12 +00:00
|
|
|
|
|
|
|
/* sapi 3 */
|
|
|
|
int sapi3_link;
|
2010-04-25 16:28:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* MM connection entry */
|
|
|
|
struct gsm48_mm_conn {
|
|
|
|
struct llist_head list;
|
|
|
|
struct gsm48_mmlayer *mm;
|
|
|
|
|
2019-10-13 17:10:52 +00:00
|
|
|
/* ref and type form a unique tuple */
|
2010-04-25 16:28:24 +00:00
|
|
|
uint32_t ref; /* reference to trans */
|
|
|
|
uint8_t protocol;
|
|
|
|
uint8_t transaction_id;
|
2011-10-31 17:08:12 +00:00
|
|
|
uint8_t sapi;
|
2010-04-25 16:28:24 +00:00
|
|
|
|
|
|
|
int state;
|
|
|
|
};
|
|
|
|
|
2011-03-16 08:52:01 +00:00
|
|
|
uint8_t gsm48_current_pwr_lev(struct gsm_settings *set, uint16_t arfcn);
|
2010-04-25 16:28:24 +00:00
|
|
|
int gsm48_mm_init(struct osmocom_ms *ms);
|
|
|
|
int gsm48_mm_exit(struct osmocom_ms *ms);
|
|
|
|
struct msgb *gsm48_mmr_msgb_alloc(int msg_type);
|
|
|
|
struct msgb *gsm48_mmevent_msgb_alloc(int msg_type);
|
|
|
|
int gsm48_mmevent_msg(struct osmocom_ms *ms, struct msgb *msg);
|
|
|
|
int gsm48_mmr_downmsg(struct osmocom_ms *ms, struct msgb *msg);
|
|
|
|
int gsm48_rr_dequeue(struct osmocom_ms *ms);
|
|
|
|
int gsm48_mmxx_dequeue(struct osmocom_ms *ms);
|
|
|
|
int gsm48_mmr_dequeue(struct osmocom_ms *ms);
|
|
|
|
int gsm48_mmevent_dequeue(struct osmocom_ms *ms);
|
|
|
|
int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg);
|
|
|
|
struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
|
2011-10-31 17:08:12 +00:00
|
|
|
uint8_t transaction_id, uint8_t sapi);
|
2010-04-25 16:28:24 +00:00
|
|
|
const char *get_mmr_name(int value);
|
2013-05-17 05:57:01 +00:00
|
|
|
const char *get_mm_name(int value);
|
2010-04-25 16:28:24 +00:00
|
|
|
const char *get_mmxx_name(int value);
|
2010-06-16 17:17:29 +00:00
|
|
|
extern const char *gsm48_mm_state_names[];
|
|
|
|
extern const char *gsm48_mm_substate_names[];
|
2010-04-25 16:28:24 +00:00
|
|
|
|
|
|
|
#endif /* _GSM48_MM_H */
|