diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2010-04-01 19:53:32 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2010-04-01 19:53:32 +0200 |
commit | 155e953e946f6e87e26bf8ab5f6d12fa8e02f860 (patch) | |
tree | 237160f83d4c30afa0eaf1e649c5fa381169f08b | |
parent | 1af7da8f15331258455877c6d5328d3e43b22b6c (diff) |
Work on message handling of layer 3.
-rw-r--r-- | src/host/gsm48-andreas/gsm48_l3.h | 233 | ||||
-rw-r--r-- | src/host/gsm48-andreas/gsm48_mm.c | 114 | ||||
-rw-r--r-- | src/host/gsm48-andreas/gsm48_rr.c | 399 |
3 files changed, 395 insertions, 351 deletions
diff --git a/src/host/gsm48-andreas/gsm48_l3.h b/src/host/gsm48-andreas/gsm48_l3.h index 469e886f..4c0751bc 100644 --- a/src/host/gsm48-andreas/gsm48_l3.h +++ b/src/host/gsm48-andreas/gsm48_l3.h @@ -63,95 +63,101 @@ struct gsm48_mnss { /* interlayer primitives */ /* GSM 04.07 9.1.2 */ -#define RR_EST_REQ 0x8110 -#define RR_EST_IND 0x8112 -#define RR_EST_CNF 0x8111 -#define RR_REL_IND 0x8122 -#define RR_SYNC_IND 0x8132 -#define RR_DATA_REQ 0x8140 -#define RR_DATA_IND 0x8142 -#define RR_UNIT_DATA_IND 0x8152 -#define RR_ABORT_REQ 0x8160 -#define RR_ABORT_IND 0x8162 -#define RR_ACT_REQ 0x8170 - -struct gsm48_rr { +#define GSM48_RR_EST_REQ 0x10 +#define GSM48_RR_EST_IND 0x12 +#define GSM48_RR_EST_CNF 0x11 +#define GSM48_RR_REL_IND 0x22 +#define GSM48_RR_SYNC_IND 0x32 +#define GSM48_RR_DATA_REQ 0x40 +#define GSM48_RR_DATA_IND 0x42 +#define GSM48_RR_UNIT_DATA_IND 0x52 +#define GSM48_RR_ABORT_REQ 0x60 +#define GSM48_RR_ABORT_IND 0x62 +#define GSM48_RR_ACT_REQ 0x70 + +/* GSM 04.08 RR-SAP header */ +struct gsm48_rr_hdr { u_int32_t msg_type; /* RR_* primitive */ - struct msgb *msg; /* gsm48 msg */ - u_int8_t cause; + u_int8_t reject_cause; }; /* GSM 04.07 9.2.2 */ -#define GSM48_MMCC_EST_REQ 0x9110 todo: renumber -#define GSM48_MMCC_EST_IND 0x9112 -#define GSM48_MMCC_EST_CNF 0x9111 -#define GSM48_MMCC_REL_REQ 0x9120 -#define GSM48_MMCC_REL_IND 0x9122 -#define GSM48_MMCC_DATA_REQ 0x9130 -#define GSM48_MMCC_DATA_IND 0x9132 -#define GSM48_MMCC_UNIT_DATA_REQ 0x9140 -#define GSM48_MMCC_UNIT_DATA_IND 0x9142 -#define GSM48_MMCC_SYNC_IND 0x9152 -#define GSM48_MMCC_REEST_REQ 0x9160 -#define GSM48_MMCC_REEST_CNF 0x9161 -#define GSM48_MMCC_ERR_IND 0x9172 -#define GSM48_MMCC_PROMPT_IND 0x9182 -#define GSM48_MMCC_PROMPT_REJ 0x9184 -#define GSM48_MMSS_EST_REQ 0x9210 -#define GSM48_MMSS_EST_IND 0x9212 -#define GSM48_MMSS_EST_CNF 0x9211 -#define GSM48_MMSS_REL_REQ 0x9220 -#define GSM48_MMSS_REL_IND 0x9222 -#define GSM48_MMSS_DATA_REQ 0x9230 -#define GSM48_MMSS_DATA_IND 0x9232 -#define GSM48_MMSS_UNIT_DATA_REQ 0x9240 -#define GSM48_MMSS_UNIT_DATA_IND 0x9242 -#define GSM48_MMSS_REEST_REQ 0x9260 -#define GSM48_MMSS_REEST_CNF 0x9261 -#define GSM48_MMSS_ERR_IND 0x9272 -#define GSM48_MMSS_PROMPT_IND 0x9282 -#define GSM48_MMSS_PROMPT_REJ 0x9284 -#define GSM48_MMSMS_EST_REQ 0x9310 -#define GSM48_MMSMS_EST_IND 0x9312 -#define GSM48_MMSMS_EST_CNF 0x9311 -#define GSM48_MMSMS_REL_REQ 0x9320 -#define GSM48_MMSMS_REL_IND 0x9322 -#define GSM48_MMSMS_DATA_REQ 0x9330 -#define GSM48_MMSMS_DATA_IND 0x9332 -#define GSM48_MMSMS_UNIT_DATA_REQ 0x9340 -#define GSM48_MMSMS_UNIT_DATA_IND 0x9342 -#define GSM48_MMSMS_REEST_REQ 0x9360 -#define GSM48_MMSMS_REEST_CNF 0x9361 -#define GSM48_MMSMS_ERR_IND 0x9372 -#define GSM48_MMSMS_PROMPT_IND 0x9382 -#define GSM48_MMSMS_PROMPT_REJ 0x9384 +#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 + +/* GSM 04.08 MMxx-SAP header */ +struct gsm48_mmxx_hdr { + u_int32_t msg_type; /* RR_* primitive */ + u_int8_t reject_cause; +}; /* GSM 04.07 9.1.1 */ -#define GSM_RRSTATE_IDLE 0 -#define GSM_RRSTATE_CONN_PEND 1 -#define GSM_RRSTATE_DEDICATED 2 +#define GSM48_RR_ST_IDLE 0 +#define GSM48_RR_ST_CONN_PEND 1 +#define GSM48_RR_ST_DEDICATED 2 /* GSM 04.07 6.1.1 */ -#define GSM_MMRSTATE_NOTUPDATED 0 -#define GSM_MMRSTATE_WAIT 1 -#define GSM_MMRSTATE_UPDATED 2 +#define GSM48_MMR_ST_NOTUPDATED 0 +#define GSM48_MMR_ST_WAIT 1 +#define GSM48_MMR_ST_UPDATED 2 /* GSM 04.07 9.2.1 */ -#define GSM_MMCCSTATE_IDLE 0 -#define GSM_MMCCSTATE_CONN_PEND 1 -#define GSM_MMCCSTATE_DEDICATED 2 -#define GSM_MMCCSTATE_CONN_SUSP 3 -#define GSM_MMCCSTATE_REESTPEND 4 -#define GSM_MMSSSTATE_IDLE 0 -#define GSM_MMSSSTATE_CONN_PEND 1 -#define GSM_MMSSSTATE_DEDICATED 2 -#define GSM_MMSSSTATE_CONN_SUSP 3 -#define GSM_MMSSSTATE_REESTPEND 4 -#define GSM_MMSMSSTATE_IDLE 0 -#define GSM_MMSMSSTATE_CONN_PEND 1 -#define GSM_MMSMSSTATE_DEDICATED 2 -#define GSM_MMSMSSTATE_CONN_SUSP 3 -#define GSM_MMSMSSTATE_REESTPEND 4 +#define GSM48_MMCC_ST_IDLE 0 +#define GSM48_MMCC_ST_CONN_PEND 1 +#define GSM48_MMCC_ST_DEDICATED 2 +#define GSM48_MMCC_ST_CONN_SUSP 3 +#define GSM48_MMCC_ST_REESTPEND 4 +#define GSM48_MMSS_ST_IDLE 0 +#define GSM48_MMSS_ST_CONN_PEND 1 +#define GSM48_MMSS_ST_DEDICATED 2 +#define GSM48_MMSS_ST_CONN_SUSP 3 +#define GSM48_MMSS_ST_REESTPEND 4 +#define GSM48_MMSMS_ST_IDLE 0 +#define GSM48_MMSMS_ST_CONN_PEND 1 +#define GSM48_MMSMS_ST_DEDICATED 2 +#define GSM48_MMSMS_ST_CONN_SUSP 3 +#define GSM48_MMSMS_ST_REESTPEND 4 /* GSM 04.08 4.1.2.1 */ #define GSM48_MM_ST_NULL 0 @@ -188,34 +194,35 @@ struct gsm48_rr { #define GSM48_MM_SST_RX_VGCS_LIMITED 10 /* GSM 04.08 5.1.2.2 */ -#define GSM_CCSTATE_NULL 0 -#define GSM_CCSTATE_INITIATED 1 -#define GSM_CCSTATE_MO_CALL_PROC 3 -#define GSM_CCSTATE_CALL_DELIVERED 4 -#define GSM_CCSTATE_CALL_PRESENT 6 -#define GSM_CCSTATE_CALL_RECEIVED 7 -#define GSM_CCSTATE_CONNECT_REQUEST 8 -#define GSM_CCSTATE_MO_TERM_CALL_CONF 9 -#define GSM_CCSTATE_ACTIVE 10 -#define GSM_CCSTATE_DISCONNECT_REQ 12 -#define GSM_CCSTATE_DISCONNECT_IND 12 -#define GSM_CCSTATE_RELEASE_REQ 19 -#define GSM_CCSTATE_MO_ORIG_MODIFY 26 -#define GSM_CCSTATE_MO_TERM_MODIFY 27 -#define GSM_CCSTATE_CONNECT_IND 28 +#define GSM48_CC_ST_NULL 0 +#define GSM48_CC_ST_INITIATED 1 +#define GSM48_CC_ST_MO_CALL_PROC 3 +#define GSM48_CC_ST_CALL_DELIVERED 4 +#define GSM48_CC_ST_CALL_PRESENT 6 +#define GSM48_CC_ST_CALL_RECEIVED 7 +#define GSM48_CC_ST_CONNECT_REQUEST 8 +#define GSM48_CC_ST_MO_TERM_CALL_CONF 9 +#define GSM48_CC_ST_ACTIVE 10 +#define GSM48_CC_ST_DISCONNECT_REQ 12 +#define GSM48_CC_ST_DISCONNECT_IND 12 +#define GSM48_CC_ST_RELEASE_REQ 19 +#define GSM48_CC_ST_MO_ORIG_MODIFY 26 +#define GSM48_CC_ST_MO_TERM_MODIFY 27 +#define GSM48_CC_ST_CONNECT_IND 28 /* MM events */ -#define GSM48_MM_EVENT_NEW_LAI 0xa001 -#define GSM48_MM_EVENT_TIMEOUT_T3211 0xa002 -#define GSM48_MM_EVENT_TIMEOUT_T3212 0xa003 -#define GSM48_MM_EVENT_TIMEOUT_T3213 0xa004 -#define GSM48_MM_EVENT_IMSI_DETACH 0xa005 -#define GSM48_MM_EVENT_IMSI_ATTACH 0xa006 -#define GSM48_MM_EVENT_POWER_OFF 0xa007 -#define GSM48_MM_EVENT_PAGING 0xa009 -#define GSM48_MM_EVENT_AUTH_RESPONSE 0xa00a - -struct gsm48_mmevent { +#define GSM48_MM_EVENT_NEW_LAI 1 +#define GSM48_MM_EVENT_TIMEOUT_T3211 2 +#define GSM48_MM_EVENT_TIMEOUT_T3212 3 +#define GSM48_MM_EVENT_TIMEOUT_T3213 4 +#define GSM48_MM_EVENT_IMSI_DETACH 5 +#define GSM48_MM_EVENT_IMSI_ATTACH 6 +#define GSM48_MM_EVENT_POWER_OFF 7 +#define GSM48_MM_EVENT_PAGING 9 +#define GSM48_MM_EVENT_AUTH_RESPONSE 10 + +/* message for MM events */ +struct gsm48_mm_event { u_int32_t msg_type; u_int8_t sres[4]; @@ -237,11 +244,20 @@ struct gsm48_mmlayer { struct osmocom_ms *ms; int state; int substate; + + /* queue for MMxx-SAP message upwards */ + struct llist_head mm_upqueue; + + /* timers */ struct timer_list t3211; struct timer_list t3212; struct timer_list t3213; int t3212_value; + + /* list of MM connections */ struct llist_head mm_conn; + + /* network name */ char name_short[32]; char name_long[32]; }; @@ -279,6 +295,13 @@ struct gsm_rrlayer { struct osmocom_ms *ms; int state; + /* queue for RR-SAP message upwards */ + struct llist_head rr_upqueue; + + /* queue for messages while RR connection is built up */ + struct llist_head downqueue; + + /* timers */ struct timer_list t3122; struct timer_list t3124; struct timer_list t3126; diff --git a/src/host/gsm48-andreas/gsm48_mm.c b/src/host/gsm48-andreas/gsm48_mm.c index bccbcf69..abd57a0a 100644 --- a/src/host/gsm48-andreas/gsm48_mm.c +++ b/src/host/gsm48-andreas/gsm48_mm.c @@ -50,19 +50,59 @@ * messages */ -/* allocate GSM 04.08 rr-sap message (between MM and RR) */ -static struct msgb *gsm48_rr_msgb_alloc(void) +/* allocate GSM 04.08 message (MMxx-SAP) */ +static struct msgb *gsm48_mmxx_msgb_alloc(void) { struct msgb *msg; - msg = msgb_alloc_headroom(GSM48_MM_ALLOC_SIZE, GSM48_MM_ALLOC_HEADROOM, - "GSM 04.08 MM"); + msg = msgb_alloc_headroom(RR_ALLOC_SIZE+RR_ALLOC_HEADROOM, + RR_ALLOC_HEADROOM, "GSM 04.08 MMxx"); if (!msg) return NULL; return msg; } +/* queue message (MMxx-SAP) */ +int gsm48_mmxx_upmsg(struct osmocom_ms *ms, struct msgb *msg) +{ + struct gsm_mmlayer *mm = &ms->mmlayer; + + msgb_enqueue(&mm->mm_upqueue, msg); +} + +/* dequeue messages (RR-SAP) */ +int gsm48_rr_dequeue(struct osmocom_ms *ms) +{ + struct gsm_mmlayer *mm = &ms->mmlayer; + struct msgb *msg; + int work = 0; + + while ((msg = msgb_dequeue(&mm->mm_upqueue))) { + /* msg is freed there */ + gsm48_rcv_rr(ms, msg); + work = 1; /* work done */ + } + + return work; +} + +tomorrow: +finish this function +check names +do msg for MMxx +do msg in call control + + +/* push RR header and send to RR */ +static int gsm48_mm_to_rr(ms, msg, int msg_type) +{ + 1. push header + 2. add msg_type + + return gsm48_rr_downmsg(ms, msg); +} + /* * state transition */ @@ -87,7 +127,7 @@ static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate) mm->delay_detach = 0; - nmsg = gsm48_mm_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH); + nmsg = gsm48_l3_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH); if (!nmsg) return -ENOMEM; gsm48_mm_sendevent(ms, nmsg); @@ -109,7 +149,7 @@ static int gsm48_mm_return_idle(struct osmocom_ms *ms) if (mm->power_off) { struct msgb *nmsg; - nmsg = gsm48_mm_msgb_alloc(GSM48_MM_EVENT_POWER_OFF); + nmsg = gsm48_l3_msgb_alloc(GSM48_MM_EVENT_POWER_OFF); if (!nmsg) return -ENOMEM; gsm48_mm_sendevent(ms, nmsg); @@ -171,7 +211,7 @@ static int gsm48_mm_tx_mm_status(struct osmocom_ms *ms, u_int8_t reject) struct gsm48_hdr *ngh; u_int8_t *reject_cause; - nmsg = gsm48_mm_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (nmsg) return -ENOMEM; ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh)); @@ -181,7 +221,7 @@ static int gsm48_mm_tx_mm_status(struct osmocom_ms *ms, u_int8_t reject) gh->msg_type = GSM48_MT_MM_STATUS; *reject_cause = reject; - return gsm48_mm_sendmsg(ms, nmsg, RR_DATA_REQ); + return gsm48_mm_to_rr(ms, nmsg, RR_DATA_REQ); } /* 4.3.1.2 sending TMSI REALLOCATION COMPLETE message */ @@ -190,7 +230,7 @@ static int gsm48_mm_tx_tmsi_reall_cpl(struct osmocom_ms *ms) struct msgb *nmsg; struct gsm48_hdr *ngh; - nmsg = gsm48_mm_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (nmsg) return -ENOMEM; ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh)); @@ -198,7 +238,7 @@ static int gsm48_mm_tx_tmsi_reall_cpl(struct osmocom_ms *ms) gh->proto_discr = GSM48_PDISC_MM; gh->msg_type = GSM48_MT_MM_TMSI_REALL_COMPL; - return gsm48_mm_sendmsg(ms, nmsg, RR_DATA_REQ); + return gsm48_mm_to_rr(ms, nmsg, RR_DATA_REQ); } /* 4.3.1 TMSI REALLOCATION COMMAND is received */ @@ -283,7 +323,7 @@ static int gsm48_mm_rx_auth_req(struct osmocom_ms *ms, struct msgb *msg) /* 4.3.2.2 sending AUTHENTICATION RESPONSE */ static int gsm48_mm_tx_auth_rsp(struct osmocom_ms *ms, struct gsm48_mmevent *ev) { - struct msgb *msg = gsm48_mm_msgb_alloc(); + struct msgb *msg = gsm48_l3_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); struct gsm_mmevent *mmevent = arg; u_int8_t *sres = msgb_put(msg, 4); @@ -294,7 +334,7 @@ static int gsm48_mm_tx_auth_rsp(struct osmocom_ms *ms, struct gsm48_mmevent *ev) /* SRES */ memcpy(sres, ev->sres, 4); - return gsm48_mm_sendmsg(ms, nmsg, RR_DATA_REQ); + return gsm48_mm_to_rr(ms, nmsg, RR_DATA_REQ); } /* 4.3.2.5 AUTHENTICATION REJECT is received */ @@ -365,7 +405,7 @@ static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, u_int8_t mi_type) struct msgb *nmsg; struct gsm48_hdr *ngh; - nmsg = gsm48_mm_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (nmsg) return -ENOMEM; ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh)); @@ -376,7 +416,7 @@ static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, u_int8_t mi_type) /* MI */ gsm48_encode_mi(nmsg, subscr, mi_type); - return gsm48_mm_sendmsg(ms, nmsg, RR_DATA_REQ); + return gsm48_mm_to_rr(ms, nmsg, RR_DATA_REQ); } /* 4.3.4.1 sending IMSI DETACH INDICATION message */ @@ -387,7 +427,7 @@ static int gsm48_mm_tx_imsi_detach(struct osmocom_ms *ms, int rr_prim) struct gsm48_hdr *ngh; struct gsm48_classmark1 *classmark1; - nmsg = gsm48_mm_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (nmsg) return -ENOMEM; ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh)); @@ -401,7 +441,7 @@ static int gsm48_mm_tx_imsi_detach(struct osmocom_ms *ms, int rr_prim) /* MI */ gsm48_encode_mi(nmsg, subscr, mi_type); - return gsm48_mm_sendmsg(ms, nmsg, rr_prim); + return gsm48_mm_to_rr(ms, nmsg, rr_prim); } /* detach has ended */ @@ -516,7 +556,7 @@ static int gsm48_mm_release_conn(struct osmocom_ms *ms) msg_type = GSM48_MMSMS_REL_IND; break; } - nmsg = gsm48_mm_msgb_alloc(msg_type, conn->ref); + nmsg = gsm48_l3_msgb_alloc(msg_type, conn->ref); if (!nmsg) return -ENOMEM; gsm48_mmxx_upmsg(ms, nmsg); @@ -644,7 +684,7 @@ static void new_sim_ustate(struct gsm_subscriber *subscr, int state) /* cm reestablish request message from upper layer */ static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, void *arg) { - struct msgb *msg = gsm48_mm_msgb_alloc(); + struct msgb *msg = gsm48_l3_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); struct gsm48_service_request *serv_req = msgb_put(msg, 1 + 1 + sizeof(struct gsm48_classmark2)); u_int8_t *classmark2 = ((u_int8_t *)serv_req) + 1; @@ -662,26 +702,26 @@ static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, void *arg) gsm48_encode_mi(nmsg, subscr, mi_type); /* prio is optional for eMLPP */ - return gsm48_mm_sendmsg(ms, nmsg, RR_EST_REQ); + return gsm48_mm_to_rr(ms, nmsg, RR_EST_REQ); } /* cm service abort message from upper layer */ static int gsm48_mm_tx_cm_service_abort(struct osmocom_ms *ms, void *arg) { - struct msgb *msg = gsm48_mm_msgb_alloc(); + struct msgb *msg = gsm48_l3_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); msg->lchan = lchan; gh->proto_discr = GSM48_PDISC_MM; gh->msg_type = GSM48_MT_MM_CM_SERV_ABORT; - return gsm48_mm_sendmsg(ms, nmsg, RR_DATA_REQ); + return gsm48_mm_to_rr(ms, nmsg, RR_DATA_REQ); } /* cm reestablish request message from upper layer */ static int gsm48_mm_tx_cm_reest_req(struct osmocom_ms *ms, void *arg) { - struct msgb *msg = gsm48_mm_msgb_alloc(); + struct msgb *msg = gsm48_l3_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); u_int8_t *key_seq = msgb_put(msg, 1); u_int8_t *classmark2 = msgb_put(msg, 1 + sizeof(struct gsm48_classmark2)); @@ -706,7 +746,7 @@ static int gsm48_mm_tx_cm_reest_req(struct osmocom_ms *ms, void *arg) memcpy(ie, buf, 1 + sizeof(struct gsm48_loc_area_id)); } - return gsm48_mm_sendmsg(ms, nmsg, RR__REQ); + return gsm48_mm_to_rr(ms, nmsg, RR__REQ); } /* initiate a location update */ @@ -1333,7 +1373,7 @@ static void gsm48_mm_t3213(void *arg) static int gsm48_mm_est_loc_upd(struct osmocom_ms *ms, struct gsm_rr *est) { /* 4.4.4.1 */ - struct msgb *msg = gsm48_mm_msgb_alloc(); + struct msgb *msg = gsm48_l3_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); struct gsm48_loc_upd *loc_upd = msgb_put(msg, 7); u_int8_t *classmark1 = ((u_int8_t *)loc_upd) + 6; @@ -1355,7 +1395,7 @@ static int gsm48_mm_est_loc_upd(struct osmocom_ms *ms, struct gsm_rr *est) /* MI */ gsm48_encode_mi(nmsg, subscr, mi_type); - return gsm48_mm_sendmsg(ms, nmsg, RR_DATA_REQ); + return gsm48_mm_to_rr(ms, nmsg, RR_DATA_REQ); } /* RR is released after location update reject */ @@ -1492,30 +1532,6 @@ static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg) return rc; } -/* dequeue messages from rr-sap */ -int gsm48_mm_dequeue_rr(struct osmocom_ms *ms) -{ - struct gsm48_rrlayer *rr = &ms->rrlayer; - struct msgb *msg; - int work = 0; - - while ((msg = msgb_dequeue(&rr->rr_upqueue))) { - /* message is also freed here */ - gsm48_rcv_rr(ms, msg); - work = 1; /* work done */ - } - - return work; -} - - -/* queue message to upper layer at mmxx-sap */ -int gsm48_mmxx_upmsg(struct osmocom_ms *ms, struct msgb *msg) -{ - struct gsm48_mmlayer *mm = &ms->mmlayer; - - msgb_enqueue(&mm->mmxx_upqueue, msg); -} wichtig: nur eine MM connection zur zeit, da ja auch nur ein cm-service-request laufen kann. die anderen werden dann als "waiting" deklariert. diff --git a/src/host/gsm48-andreas/gsm48_rr.c b/src/host/gsm48-andreas/gsm48_rr.c index 9c992e35..8640ffbf 100644 --- a/src/host/gsm48-andreas/gsm48_rr.c +++ b/src/host/gsm48-andreas/gsm48_rr.c @@ -44,7 +44,7 @@ * state transition */ -const char *rr_state_names[] = { +static const char *gsm48_rr_state_names[] = { "IDLE", "CONN PEND", "DEDICATED", @@ -52,7 +52,7 @@ const char *rr_state_names[] = { static void new_rr_state(struct gsm_rrlayer *rr, int state) { - if (state < 0 || state >= (sizeof(rr_state_names) / sizeof(char *))) + if (state < 0 || state >= (sizeof(gsm48_rr_state_names) / sizeof(char *))) return; if (state == GSM_RRSTATE_IDLE) { @@ -79,26 +79,78 @@ static void new_rr_state(struct gsm_rrlayer *rr, int state) * messages */ -/* allocate GSM 04.08 radio ressource message (RR to L2) */ -wrong sap name, must be changed to msg48_rsl_msgb_alloc... +#define RR_ALLOC_SIZE 200 +#define RR_ALLOC_HEADROOM 56 + +/* names of RR-SAP */ +static const struct value_string gsm48_rr_msg_names[] = { + { GSM48_RR_EST_REQ, "RR_EST_REQ" }, + { GSM48_RR_EST_IND, "RR_EST_IND" }, + { GSM48_RR_EST_CNF, "RR_EST_CNF" }, + { GSM48_RR_REL_IND, "RR_REL_IND" }, + { GSM48_RR_SYNC_IND, "RR_SYNC_IND" }, + { GSM48_RR_DATA_REQ, "RR_DATA_REQ" }, + { GSM48_RR_DATA_IND, "RR_DATA_IND" }, + { GSM48_RR_UNIT_DATA_IND, "RR_UNIT_DATA_IND" }, + { GSM48_RR_ABORT_REQ, "RR_ABORT_REQ" }, + { GSM48_RR_ABORT_IND, "RR_ABORT_IND" }, + { GSM48_RR_ACT_REQ, "RR_ACT_REQ" }, + { 0, NULL } +}; + +const char *get_rr_name(int value) +{ + return get_value_string(rr_names, value); +} + +/* allocate GSM 04.08 layer 3 message */ +struct msgb *gsm48_l3_msgb_alloc(void) +{ + struct msgb *msg; + + msg = msgb_alloc_headroom(RR_ALLOC_SIZE+RR_ALLOC_HEADROOM, + RR_ALLOC_HEADROOM, "GSM 04.08 L3"); + if (!msg) + return NULL; + + return msg; +} + +/* allocate GSM 04.08 message (RR-SAP) */ static struct msgb *gsm48_rr_msgb_alloc(void) { struct msgb *msg; - msg = msgb_alloc_headroom(GSM48_RR_ALLOC_SIZE, GSM48_RR_ALLOC_HEADROOM, - "GSM 04.08 RR"); + msg = msgb_alloc_headroom(RR_ALLOC_SIZE+RR_ALLOC_HEADROOM, + RR_ALLOC_HEADROOM, "GSM 04.08 RR"); if (!msg) return NULL; return msg; } -/* queue message L2 -> RR */ +/* queue message (RR-SAP) */ int gsm48_rr_upmsg(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; + + msgb_enqueue(&rr->rr_upqueue, msg); +} - msgb_enqueue(&rr->up_queue, msg); +/* dequeue messages (RSL-SAP) */ +int gsm48_rsl_dequeue(struct osmocom_ms *ms) +{ + struct gsm_rrlayer *rr = &ms->rrlayer; + struct msgb *msg; + int work = 0; + + while ((msg = msgb_dequeue(&rsl->rsl_upqueue))) { + /* msg is freed there */ + gsm48_rcv_rsl(ms, msg); + work = 1; /* work done */ + } + + return work; } /* @@ -168,16 +220,16 @@ static void timeout_rr_t3126(void *arg) /* send rr status request */ static int gsm_rr_tx_rr_status(struct osmocom_ms *ms, uint8_t cause) { - struct gsm_rrlayer *rr = ms->rrlayer; - struct msgb *msg; - struct gsm48_hdr *gh; + struct gsm_rrlayer *rr = &ms->rrlayer; + struct msgb *nmsg; + struct gsm48_hdr *ngh; struct gsm48_rr_status *st; - msg = gsm48_rr_msgb_alloc(); - if (!msg) + nmsg = gsm48_l3_msgb_alloc(); + if (!nmsg) return -ENOMEM; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - st = (struct gsm48_rr_status *) msgb_put(msg, sizeof(*st)); + gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh)); + st = (struct gsm48_rr_status *) msgb_put(nmsg, sizeof(*st)); gh->proto = GSM48_PDISC_RR; gh->msg_type = GSM48_MT_RR_CIPH_M_COMPL; @@ -185,7 +237,7 @@ static int gsm_rr_tx_rr_status(struct osmocom_ms *ms, uint8_t cause) /* rr cause */ st->rr_cause = cause; - return rslms_data_req(ms, msg, 0); + return rslms_tx_rll_req_l3(ms, RSL_MT_DATA_REQ, chan_nr, 0, nmsg); } /* @@ -195,16 +247,16 @@ static int gsm_rr_tx_rr_status(struct osmocom_ms *ms, uint8_t cause) /* send chiperhing mode complete */ static int gsm_rr_tx_cip_mode_cpl(struct osmocom_ms *ms, uint8_t cr) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm_subscriber *subcr = ms->subscr; - struct msgb *msg; - struct gsm48_hdr *gh; + struct msgb *nmsg; + struct gsm48_hdr *ngh; u_int8_t buf[11], *ie; - msg = gsm48_rr_msgb_alloc(); - if (!msg) + nmsg = gsm48_l3_msgb_alloc(); + if (!nmsg) return -ENOMEM; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh)); gh->proto = GSM48_PDISC_RR; gh->msg_type = GSM48_MT_RR_CIPH_M_COMPL; @@ -212,17 +264,17 @@ static int gsm_rr_tx_cip_mode_cpl(struct osmocom_ms *ms, uint8_t cr) /* MI */ if (cr) { gsm48_generate_mid_from_imsi(ie, subscr->imei); - ie = msgb_put(msg, 1 + buf[1]); + ie = msgb_put(nmsg, 1 + buf[1]); memcpy(ie, buf + 1, 1 + buf[1]); } - return rslms_data_req(ms, msg, 0); + return rslms_tx_rll_req_l3(ms, RSL_MT_DATA_REQ, chan_nr, 0, nmsg); } /* receive ciphering mode command */ static int gsm_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_cip_mode_cmd *cm = (struct gsm48_cip_mode_cmd *)gh->data; int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cm); @@ -258,7 +310,7 @@ static int gsm_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg) /* Encode "Classmark 3" (10.5.2.20) */ static int gsm_rr_enc_cm3(struct osmocom_sm *ms, uint8_t *buf, uint8_t *len) { - struct gsm_support *sup = ms->support; + struct gsm_support *sup = &ms->support; struct bitvec bv; memset(&bv, 0, sizeof(bv)); @@ -371,7 +423,7 @@ static int gsm_rr_enc_cm3(struct osmocom_sm *ms, uint8_t *buf, uint8_t *len) /* encode classmark 2 */ static int gsm_rr_enc_cm2(struct osmocom_sm *ms, struct gsm48_classmark2 *cm) { - struct gsm_support *sup = ms->support; + struct gsm_support *sup = &ms->support; cm->pwr_lev = sup->pwr_lev; cm->a5_1 = sup->a5_1; @@ -393,19 +445,19 @@ static int gsm_rr_enc_cm2(struct osmocom_sm *ms, struct gsm48_classmark2 *cm) /* send classmark change */ static int gsm_rr_tx_cm_change(struct osmocom_ms *ms) { - struct gsm_rrlayer *rr = ms->rrlayer; - struct gsm_support *sup = ms->support; - struct msgb *msg; + struct gsm_rrlayer *rr = &ms->rrlayer; + struct gsm_support *sup = &ms->support; + struct msgb *nmsg; struct gsm48_hdr *gh; struct gsm48_cm_change *cc; int len; uint8_t buf[14]; - msg = gsm48_rr_msgb_alloc(); - if (!msg) + nmsg = gsm48_l3_msgb_alloc(); + if (!nmsg) return -ENOMEM; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - cc = (struct gsm48_cm_change *) msgb_put(msg, sizeof(*cc)); + gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh)); + cc = (struct gsm48_cm_change *) msgb_put(nmsg, sizeof(*cc)); gh->proto = GSM48_PDISC_RR; gh->msg_type = GSM48_MT_RR_CLSM_CHG; @@ -426,13 +478,13 @@ static int gsm_rr_tx_cm_change(struct osmocom_ms *ms) gsm_rr_enc_cm3(ms, buf + 2, &buf[1]); } - return rslms_data_req(ms, msg, 0); + return rslms_tx_rll_req_l3(ms, RSL_MT_DATA_REQ, chan_nr, 0, nmsg); } /* receiving classmark enquiry */ static int gsm_rr_rx_cm_enq(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_hdr *gh = msgb_l3(msg); int payload_len = msgb_l3len(msg) - sizeof(*gh); @@ -447,7 +499,7 @@ static int gsm_rr_rx_cm_enq(struct osmocom_ms *ms, struct msgb *msg) /* send channel request burst message */ static int gsm_rr_tx_chan_req(struct osmocom_ms *ms, int cause) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct msgb *msg; struct gsm_mm_hdr *mmh; uint8_t chan_req; @@ -582,7 +634,7 @@ static int gsm_rr_tx_chan_req(struct osmocom_ms *ms, int cause) /* send next channel request in conn pend state */ static int gsm_rr_rand_acc_cnf(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct msgb *nmsg; int s; @@ -1585,7 +1637,7 @@ static int gsm_match_mi(struct osmocom_ms *ms, u_int8_t mi) /* paging request 1 message */ static int gsm_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_rr_paging1 *pa = msgb_l3(msg); int payload_len = msgb_l3len(msg) - sizeof(*pa); int chan_first, chan_second; @@ -1628,7 +1680,7 @@ static int gsm_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg) /* paging request 2 message */ static int gsm_rr_rx_pag_req_2(struct osmocom_ms *ms, struct gsm_msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_rr_paging2 *pa = msgb_l3(msg); int payload_len = msgb_l3len(msg) - sizeof(*pa); uint32_t tmsi; @@ -1673,7 +1725,7 @@ static int gsm_rr_rx_pag_req_2(struct osmocom_ms *ms, struct gsm_msgb *msg) /* paging request 3 message */ static int gsm_rr_rx_pag_req_3(struct osmocom_ms *ms, struct gsm_msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_rr_paging3 *pa = msgb_l3(msg); int payload_len = msgb_l3len(msg) - sizeof(*pa); uint32_t tmsi; @@ -1721,7 +1773,7 @@ static int gsm_rr_rx_pag_req_3(struct osmocom_ms *ms, struct gsm_msgb *msg) /* match request reference agains request history */ static int gsm_match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *req) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; int i; for (i = 0; i < 3; i++) { @@ -1738,16 +1790,16 @@ static int gsm_match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *req) /* transmit assignment complete after establishing link */ static int gsm_rr_tx_ass_cpl(struct osmocom_ms *ms, uint8_t cause) { - struct gsm_rrlayer *rr = ms->rrlayer; - struct msgb *msg; + struct gsm_rrlayer *rr = &ms->rrlayer; + struct msgb *nmsg; struct gsm48_hdr *gh; struct gsm48_ass_cpl *ac; - msg = gsm48_rr_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (!msg) return -ENOMEM; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - ac = (struct gsm48_ass_cpl *) msgb_put(msg, sizeof(*ac)); + gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh)); + ac = (struct gsm48_ass_cpl *) msgb_put(nmsg, sizeof(*ac)); gh->proto = GSM48_PDISC_RR; gh->msg_type = GSM48_MT_RR_ASS_COMPL; @@ -1755,22 +1807,22 @@ static int gsm_rr_tx_ass_cpl(struct osmocom_ms *ms, uint8_t cause) /* RR_CAUSE */ ac->rr_cause = cause; - return rslms_data_req(ms, msg, 0); + return rslms_tx_rll_req_l3(ms, RSL_MT_DATA_REQ, chan_nr, 0, nmsg); } /* transmit failure to old link */ static int gsm_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause) { - struct gsm_rrlayer *rr = ms->rrlayer; - struct msgb *msg; + struct gsm_rrlayer *rr = &ms->rrlayer; + struct msgb *nmsg; struct gsm48_hdr *gh; struct gsm48_ass_fail *ac; - msg = gsm48_rr_msgb_alloc(); - if (!msg) + nmsg = gsm48_l3_msgb_alloc(); + if (!nmsg) return -ENOMEM; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - af = (struct gsm48_ass_fail *) msgb_put(msg, sizeof(*af)); + gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh)); + af = (struct gsm48_ass_fail *) msgb_put(nmsg, sizeof(*af)); gh->proto = GSM48_PDISC_RR; gh->msg_type = GSM48_MT_RR_ASS_COMPL; @@ -1778,13 +1830,13 @@ static int gsm_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause) /* RR_CAUSE */ af->rr_cause = cause; - return rslms_data_req(ms, msg, 0); + return rslms_tx_rll_req_l3(ms, RSL_MT_DATA_REQ, chan_nr, 0, nmsg); } /* receive immediate assignment */ static int gsm_rr_rx_imm_ass(struct osmocom_ms *ms, struct gsm_msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_imm_ass *ia = msgb_l3(msg); int payload_len = msgb_l3len(msg) - sizeof(*ia); @@ -1821,7 +1873,7 @@ todo channel structure and right management of channel IEs /* receive immediate assignment extended */ static int gsm_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct gsm_msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_imm_ass_ext *ia = msgb_l3(msg); int payload_len = msgb_l3len(msg) - sizeof(*ia); @@ -1870,7 +1922,7 @@ static int gsm_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct gsm_msgb *msg) /* receive immediate assignment reject */ static int gsm_rr_rx_imm_ass_rej(struct osmocom_ms *ms, struct gsm_msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_imm_ass_rej *ia = msgb_l3(msg); int payload_len = msgb_l3len(msg) - sizeof(*ia); int i; @@ -1913,7 +1965,7 @@ static int gsm_rr_rx_imm_ass_rej(struct osmocom_ms *ms, struct gsm_msgb *msg) /* receive additional assignment */ static int gsm_rr_rx_add_ass(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_add_ass *aa = (struct gsm48_add_ass *)gh->data; int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*aa); @@ -1933,17 +1985,17 @@ static int gsm_rr_rx_add_ass(struct osmocom_ms *ms, struct msgb *msg) static int gsm_rr_tx_meas_rep(struct osmocom_ms *ms) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm_rr_meas *meas = &rr->meas; - struct msgb *msg; + struct msgb *nmsg; struct gsm48_hdr *gh; struct gsm48_meas_res *mr; - msg = gsm48_rr_msgb_alloc(); - if (!msg) + nmsg = gsm48_l3_msgb_alloc(); + if (!nmsg) return -ENOMEM; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - mr = (struct gsm48_meas_res *) msgb_put(msg, sizeof(*mr)); + gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh)); + mr = (struct gsm48_meas_res *) msgb_put(nmsg, sizeof(*mr)); gh->proto = GSM48_PDISC_RR; gh->msg_type = GSM48_MT_RR_MEAS_RES; @@ -1993,7 +2045,7 @@ static int gsm_rr_tx_meas_rep(struct osmocom_ms *ms) bcch_f_nc6_hi = meas->bcch_f_nc[5] >> 2; bcch_f_nc6_lo = meas->bcch_f_nc[5] & 3; - //todo return rslms_data_req(ms, msg, 0); + return rslms_tx_rll_req_l3(ms, RSL_MT_, chan_nr, 0, nmsg); } /* @@ -2003,9 +2055,9 @@ static int gsm_rr_tx_meas_rep(struct osmocom_ms *ms) /* activate link and send establish request */ static int gsm_rr_dl_est(struct osmocom_ms *ms) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm_subscriber *subcr = ms->subscr; - struct msgb *msg; + struct msgb *nmsg; struct gsm48_hdr *gh; struct gsm48_pag_rsp *pa; @@ -2014,25 +2066,25 @@ static int gsm_rr_dl_est(struct osmocom_ms *ms) /* flush pending RACH requests */ rr->n_chan_req = 0; // just to be safe - msg = msgb_alloc_headroom(20, 16, "RAND_FLUSH"); - if (!msg) + nmsg = msgb_alloc_headroom(20, 16, "RAND_FLUSH"); + if (!nmsg) return -ENOMEM; rslms_tx_rll_req_l3(ms, RSL_MT_RAND_ACC_FLSH, chan_nr, 0, msg); /* send DL_EST_REQ */ - if (rr->rr_est_msg) { + if (rr->l3_est_msg) { /* use queued message */ - msg = rr->rr_est_msg; - rr->rr_est_msg = 0; + nmsg = rr->l3_est_msg; + rr->l3_est_msg = 0; } else { uint8_t mi[11]; /* create paging response */ - msg = gsm48_rr_msgb_alloc(); - if (!msg) + nmsg = gsm48_l3_msgb_alloc(); + if (!nmsg) return -ENOMEM; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - pr = (struct gsm48_pag_rsp *) msgb_put(msg, sizeof(*pr)); + gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh)); + pr = (struct gsm48_pag_rsp *) msgb_put(nmsg, sizeof(*pr)); /* key sequence */ if (subscr->key_valid) pr->key_seq = subscr->key_seq; @@ -2055,10 +2107,10 @@ static int gsm_rr_dl_est(struct osmocom_ms *ms) } /* activate channel */ - tx_ph_dm_est_req(ms, arfcn, rr->chan_desc.chan_desc.chan_nr); + tx_ph_dm_est_req(ms, arfcn, chan_nr); /* start establishmnet */ - return rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, rr->chan_desc.chan_desc.chan_nr, 0, msg); + return rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, chan_nr, 0, nmsg); } /* the link is established */ @@ -2070,7 +2122,7 @@ static int gsm_rr_estab_cnf(struct osmocom_ms *ms, struct msgb *msg) /* if MM has releases before confirm, we start release */ if (rr->state == GSM_RRSTATE_IDLE) { /* release message */ - nmsg = gsm48_rr_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (!nmsg) return -ENOMEM; /* start release */ @@ -2110,7 +2162,7 @@ static int gsm_rr_rel_cnf(struct osmocom_ms *ms, struct gsm_dl *dlmsg) /* establish request for dedicated mode */ static int gsm_rr_est_req(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm_mm_hdr *mmh = msgb->data; struct gsm48_hdr *gh = msgb_l3(msg); @@ -2175,7 +2227,7 @@ static int gsm_rr_est_req(struct osmocom_ms *ms, struct msgb *msg) /* send all queued messages down to layer 2 */ static int gsm_rr_dequeue_down(struct osmocom_ms *ms) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct msgb *msg; while((msg = msgb_dequeue(&rr->downqueue))) { @@ -2188,7 +2240,7 @@ static int gsm_rr_dequeue_down(struct osmocom_ms *ms) /* 3.4.2 transfer data in dedicated mode */ static int gsm_rr_data_req(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; if (rr->state != GSM_RRSTATE_DEDICATED) { msgb_free(msg) @@ -2215,7 +2267,9 @@ static int gsm_rr_data_req(struct osmocom_ms *ms, struct msgb *msg) /* 3.4.2 data from layer 2 to RR and upper layer*/ static int gsm_rr_data_ind(struct osmocom_ms *ms, struct msbg *msg) { + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_hdr *gh = msgb_l3(msg); + int payload_len = msgb_l3len(msg) - sizeof(*ia); u_int8_t pdisc = gh->proto_discr & 0x0f; if (pdisc == GSM48_PDISC_RR) { @@ -2248,17 +2302,22 @@ static int gsm_rr_data_ind(struct osmocom_ms *ms, struct msbg *msg) return rc; } - /* push header */ + /* pull off RSL header up to L3 message */ + msgb_pull(msg, msgb_l3(msg) - msg->data); + + /* push RR header */ msgb_push(msg, sizeof(struct gsm48_mm_hdr)); mmh = (struct gsm48_mm_hdr *)msg->data; - mmh->msg_type = RR_DATA_IND; + mmh->msg_type = GSM48_RR_DATA_IND; return gsm48_mm_upmsg(ms, msg); } /* unit data from layer 2 to RR layer */ +** MUST BE RECEIVED FROM QUEUE static int gsm_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg) { + struct gsm_rrlayer *rr = &ms->rrlayer; struct gsm48_hdr *gh = msgb_l3(msg); switch (gh->msg_type) { @@ -2349,48 +2408,6 @@ they queue must be flushed when rr fails #include <osmocore/utils.h> #include <osmocore/gsm48.h> -static const struct value_string rr_names[] = { - { RR_EST_REQ, "RR_EST_REQ" }, - { RR_EST_IND, "RR_EST_IND" }, - { RR_EST_CNF, "RR_EST_CNF" }, - { RR_REL_IND, "RR_REL_IND" }, - { RR_SYNC_IND, "RR_SYNC_IND" }, - { RR_DATA_REQ, "RR_DATA_REQ" }, - { RR_DATA_IND, "RR_DATA_IND" }, - { RR_UNIT_DATA_IND, "RR_UNIT_DATA_IND" }, - { RR_ABORT_REQ, "RR_ABORT_REQ" }, - { RR_ABORT_IND, "RR_ABORT_IND" }, - { RR_ACT_REQ, "RR_ACT_REQ" }, - { 0, NULL } -}; - -const char *get_rr_name(int value) -{ - return get_value_string(rr_names, value); -} - -move to mm -static int gsm48_mm_upmsg(struct osmocom_ms *ms, - struct msgb *msg, int msg_type) -{ - struct msgb *msg; - -#if 0 - DEBUGP(DRR, "(MS %s) Sending '%s' to MM.\n", ms->name, - get_rr_name(msg_type)); -#endif - - rrmsg->msg_type = msg_type; - - msg = msgb_alloc(sizeof(struct gsm_rr), "RR"); - if (!msg) - return -ENOMEM; - memcpy(msg->data, rrmsg, sizeof(struct gsm_rr)); - msgb_enqueue(&ms->rr.upqueue, msg); - - return 0; -} - static int gsm_rr_abort_req(struct osmocom_ms *ms, struct gsm_rr *rrmsg) { struct gsm_rrlayer *rr = ms->rrlayer; @@ -2399,7 +2416,7 @@ static int gsm_rr_abort_req(struct osmocom_ms *ms, struct gsm_rr *rrmsg) struct gsm_dl dlmsg; memset(&dlmsg, 0, sizeof(dlmsg)); - return gsm_send_dl(ms, DL_RELEASE_REQ, dlmsg); + return rslms_tx_rll_req_l3(ms, RSL_MT_REL_REQ, chan_nr, 0, nmsg); } new_rr_state(rr, GSM_RRSTATE_IDLE); } @@ -2408,42 +2425,42 @@ static int gsm_rr_act_req(struct osmocom_ms *ms, struct gsm_rr *rrmsg) { } -/* state trasitions for radio ressource messages (upper layer) */ +/* state trasitions for RR-SAP messages from up */ static struct rrdownstate { uint32_t states; int type; int (*rout) (struct osmocom_ms *ms, struct gsm_dl *rrmsg); } rrdownstatelist[] = { {SBIT(GSM_RRSTATE_IDLE), /* 3.3.1.1 */ - RR_EST_REQ, gsm_rr_est_req}, + GSM48_RR_EST_REQ, gsm_rr_est_req}, {SBIT(GSM_RRSTATE_DEDICATED), /* 3.4.2 */ - RR_DATA_REQ, gsm_rr_data_req}, + GSM48_RR_DATA_REQ, gsm_rr_data_req}, {SBIT(GSM_RRSTATE_CONN_PEND) | SBIT(GSM_RRSTATE_DEDICATED), - RR_ABORT_REQ, gsm_rr_abort_req}, + GSM48_RR_ABORT_REQ, gsm_rr_abort_req}, {SBIT(GSM_RRSTATE_DEDICATED), - RR_ACT_REQ, gsm_rr_act_req}, + GSM48_RR_ACT_REQ, gsm_rr_act_req}, }; #define RRDOWNSLLEN \ (sizeof(rrdownstatelist) / sizeof(struct rrdownstate)) -static int gsm48_rr_sendmsg(struct osmocom_ms *ms, struct gsm_rr *msg) +static int gsm48_rr_downmsg(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_mm_hdr *mmh = msgb->data; - int msg_type = mmh->msg_type; + struct gsm_rrlayer *rr = &ms->rrlayer; + struct gsm_rr_hdr *rrh = msgb->data; + int msg_type = rrh->msg_type; - DEBUGP(DRR, "(ms %s) Sending '%s' to DL in state %s\n", ms->name, - gsm48_rr_msg_name(msg_type), mm_state_names[mm->state]); + DEBUGP(DRR, "(ms %s) Message '%s' received in state %s\n", ms->name, + gsm48_rr_msg_names(msg_type), gsm48_rr_state_names[rr->state]); /* find function for current state and message */ for (i = 0; i < RRDOWNSLLEN; i++) if ((msg_type == rrdownstatelist[i].type) - && ((1 << mm->state) & rrdownstatelist[i].states)) + && ((1 << rr->state) & rrdownstatelist[i].states)) break; if (i == RRDOWNSLLEN) { DEBUGP(DRR, "Message unhandled at this state.\n"); free_msgb(msg); -todo: in all functions of this type: free_msgb must be called if unhandled. return 0; } @@ -2510,6 +2527,7 @@ static int gsm_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg) int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ac); struct tlv_parsed tp; struct gsm_rr_chan_desc cd; + struct msgb *nmsg; memset(&cd, 0, sizeof(cd)); @@ -2570,10 +2588,10 @@ static int gsm_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg) memcpy(&rr->chan_desc, cd, sizeof(cd)); /* start suspension of current link */ - nmsg = gsm48_rr_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (!nmsg) return -ENOMEM; - rslms_tx_rll_req_l3(ms, RSL_MT_SUSP_REQ, rr->chan_desc.chan_nr, 0, msg); + rslms_tx_rll_req_l3(ms, RSL_MT_SUSP_REQ, chan_nr, 0, msg); /* change into special assignment suspension state */ rr->assign_susp_state = 1; @@ -2615,6 +2633,7 @@ static int gsm_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg) int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ho); struct tlv_parsed tp; struct gsm_rr_chan_desc cd; + struct msgb *nmsg; memset(&cd, 0, sizeof(cd)); @@ -2653,10 +2672,10 @@ today: more IE parsing memcpy(&rr->chan_desc, cd, sizeof(cd)); /* start suspension of current link */ - nmsg = gsm48_rr_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (!nmsg) return -ENOMEM; - rslms_tx_rll_req_l3(ms, RSL_MT_SUSP_REQ, rr->chan_desc.chan_nr, 0, msg); + rslms_tx_rll_req_l3(ms, RSL_MT_SUSP_REQ, chan_nr, 0, msg); /* change into special handover suspension state */ rr->hando_susp_state = 1; @@ -2698,6 +2717,7 @@ static int gsm_rr_rel_ind(struct osmocom_ms *ms, struct msgb *msg) static int gsm_rr_rel_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg) { struct gsm_rrlayer *rr = ms->rrlayer; + struct msgb *nmsg; if (rr->hando_susp_state || rr->assign_susp_state) { struct msgb *msg; @@ -2705,11 +2725,11 @@ static int gsm_rr_rel_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg) /* change radio to new channel */ tx_ph_dm_est_req(ms, arfcn, rr->chan_desc.chan_desc.chan_nr); - nmsg = gsm48_rr_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (!nmsg) return -ENOMEM; /* send DL-ESTABLISH REQUEST */ - rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, rr->chan_desc.chan_desc.chan_nr, 0, nmsg); + rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, chan_nr, 0, nmsg); } if (rr->hando_susp_state) { @@ -2736,10 +2756,10 @@ static int gsm_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg) tx_ph_dm_est_req(ms, arfcn, rr->chan_desc.chan_desc.chan_nr); /* re-establish old link */ - nmsg = gsm48_rr_msgb_alloc(); + nmsg = gsm48_l3_msgb_alloc(); if (!nmsg) return -ENOMEM; - return rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, rr->chan_desc.chan_desc.chan_nr, 0, nmsg); + return rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, chan_nr, 0, nmsg); } rr->resume_last_state = 0; } @@ -2765,43 +2785,45 @@ static struct dldatastate { int (*rout) (struct osmocom_ms *ms, struct gsm_dl *dlmsg); } dldatastatelist[] = { {SBIT(GSM_RRSTATE_IDLE) | SBIT(GSM_RRSTATE_CONN_PEND), - DL_UNIT_DATA_IND, gsm_rr_unit_data_ind}, + RSL_MT_UNIT_DATA_IND, gsm_rr_unit_data_ind}, {SBIT(GSM_RRSTATE_DEDICATED), /* 3.4.2 */ - DL_DATA_IND, gsm_rr_data_ind}, + RSL_MT_DATA_IND, gsm_rr_data_ind}, {SBIT(GSM_RRSTATE_IDLE) | SBIT(GSM_RRSTATE_CONN_PEND), - DL_ESTABLISH_CNF, gsm_rr_estab_cnf}, + RSL_MT_ESTABLISH_CNF, gsm_rr_estab_cnf}, {SBIT(GSM_RRSTATE_DEDICATED), - DL_ESTABLISH_CNF, gsm_rr_estab_cnf_dedicated}, + RSL_MT_ESTABLISH_CNF, gsm_rr_estab_cnf_dedicated}, {SBIT(GSM_RRSTATE), - DL_CONNECT_CNF, gsm_rr_connect_cnf}, + RSL_MT_CONNECT_CNF, gsm_rr_connect_cnf}, {SBIT(GSM_RRSTATE), - DL_RELEASE_IND, gsm_rr_rel_ind}, + RSL_MT_RELEASE_IND, gsm_rr_rel_ind}, {SBIT(GSM_RRSTATE_IDLE) | SBIT(GSM_RRSTATE_CONN_PENDING), - DL_RELEASE_CNF, gsm_rr_rel_cnf}, + RSL_MT_RELEASE_CNF, gsm_rr_rel_cnf}, {SBIT(GSM_RRSTATE_DEDICATED), - DL_RELEASE_CNF, gsm_rr_rel_cnf_dedicated}, + RSL_MT_RELEASE_CNF, gsm_rr_rel_cnf_dedicated}, {SBIT(GSM_RRSTATE_CONN_PEND), /* 3.3.1.1.2 */ - DL_RANDOM_ACCESS_CNF, gsm_rr_rand_acc_cnf}, + RSL_MT_RANDOM_ACCESS_CNF, gsm_rr_rand_acc_cnf}, {SBIT(GSM_RRSTATE_DEDICATED), - DL_RANDOM_ACCESS_CNF, gsm_rr_rand_acc_cnf_dedicated}, + RSL_MT_RANDOM_ACCESS_CNF, gsm_rr_rand_acc_cnf_dedicated}, {SBIT(GSM_RRSTATE), - MDL_ERROR_IND, gsm_rr_mdl_error_ind}, + RSL_MT_MDL_ERROR_IND, gsm_rr_mdl_error_ind}, }; #define DLDATASLLEN \ (sizeof(dldatastatelist) / sizeof(struct dldatastate)) -static int gsm48_rcv_dl(struct osmocom_ms *ms, struct gsm_dl *dlmsg) +static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg) { - int msg_type = dlmsg->msg_type; + struct gsm_rrlayer *rr = &ms->rrlayer; + struct abis_rsl_rll_hdr *rlh = msgb_l2(msg); + int msg_type = rlh->msg_type; - DEBUGP(DRR, "(ms %s) Received '%s' from DL in state %s\n", ms->name, - gsm48_dl_msg_name(msg_type), mm_state_names[mm->state]); + DEBUGP(DRR, "(ms %s) Received '%s' from RSL in state %s\n", ms->name, + gsm48_rsl_msg_name(msg_type), rr_state_names[rr->state]); /* find function for current state and message */ for (i = 0; i < DLDATASLLEN; i++) if ((msg_type == dldatastatelist[i].type) - && ((1 << mm->state) & dldatastatelist[i].states)) + && ((1 << rr->state) & dldatastatelist[i].states)) break; if (i == DLDATASLLEN) { DEBUGP(DRR, "Message unhandled at this state.\n"); @@ -2818,25 +2840,10 @@ static int gsm48_rcv_dl(struct osmocom_ms *ms, struct gsm_dl *dlmsg) return rc; } -/* dequeue messages from dl */ -int gsm48_rr_queue(struct osmocom_ms *ms) -{ - struct gsm_rrlayer *rr = ms->rrlayer; - struct msgb *msg; - int work = 0; - - while ((msg = msgb_dequeue(&rr->up_queue))) { - /* msg is freed there */ - gsm48_rcv_dl(ms, msg); - work = 1; /* work done */ - } - - return work; -} - static void timeout_rr_t3124(void *arg) { struct gsm_rrlayer *rr = arg; + struct msgb *nmsg; /* stop sending more access bursts when timer expired */ hando_acc_left = 0; @@ -2848,30 +2855,31 @@ static void timeout_rr_t3124(void *arg) tx_ph_dm_est_req(ms, arfcn, rr->chan_desc.chan_desc.chan_nr); /* re-establish old link */ - msg = gsm48_rr_msgb_alloc(); - if (!msg) + nmsg = gsm48_l3_msgb_alloc(); + if (!nmsg) return -ENOMEM; - return rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, rr->chan_desc.chan_desc.chan_nr, 0, msg); + return rslms_tx_rll_req_l3(ms, RSL_MT_EST_REQ, chan_nr, 0, nmsg); todo } -struct gsm_rrlayer *gsm_new_rr(struct osmocom_ms *ms) +int gsm48_init_rr(struct osmocom_ms *ms) { - struct gsm_rrlayer *rr; + struct gsm_rrlayer *rr = &ms->rrlayer; - rr = calloc(1, sizeof(struct gsm_rrlayer)); - if (!rr) - return NULL; + memset(rr, 0, sizeof(*rr)); rr->ms = ms; - INIT_LLIST_HEAD(&rr->up_queue); + INIT_LLIST_HEAD(&rr->rr_upqueue); + INIT_LLIST_HEAD(&rr->downqueue); - return; + return 0; } -void gsm_destroy_rr(struct gsm_rrlayer *rr) +int gsm_exit_rr(struct osmocom_ms *ms) { + struct gsm_rrlayer *rr = &ms->rrlayer; + flush queues stop_rr_t3122(rr); @@ -2879,10 +2887,7 @@ void gsm_destroy_rr(struct gsm_rrlayer *rr) alle timer gestoppt?: todo stop t3122 when cell change - memset(rr, 0, sizeof(struct gsm_rrlayer)); - free(rr); - - return; + return 0; } /* send HANDOVER ACCESS burst (9.1.14) */ @@ -2898,7 +2903,7 @@ static int gsm_rr_tx_hando_access(struct osmocom_ms *ms) /* send next channel request in dedicated state */ static int gsm_rr_rand_acc_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg) { - struct gsm_rrlayer *rr = ms->rrlayer; + struct gsm_rrlayer *rr = &ms->rrlayer; struct msgb *nmsg; int s; |