summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2010-04-01 19:53:32 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2010-04-01 19:53:32 +0200
commit155e953e946f6e87e26bf8ab5f6d12fa8e02f860 (patch)
tree237160f83d4c30afa0eaf1e649c5fa381169f08b
parent1af7da8f15331258455877c6d5328d3e43b22b6c (diff)
Work on message handling of layer 3.
-rw-r--r--src/host/gsm48-andreas/gsm48_l3.h233
-rw-r--r--src/host/gsm48-andreas/gsm48_mm.c114
-rw-r--r--src/host/gsm48-andreas/gsm48_rr.c399
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;