From: Harald Welte Date: Sun, 22 May 2011 18:10:34 +0000 (+0200) Subject: layer23: make LAPDm code mostly independent of 'struct osmocom_ms' X-Git-Url: http://git.rot13.org/?a=commitdiff_plain;h=7ad100b94e49f29d2f5c4586504840ee7df577c9;p=osmocom-bb.git layer23: make LAPDm code mostly independent of 'struct osmocom_ms' This is one step in the direction of re-using the lapdm code in osmo-bts. --- diff --git a/src/host/layer23/include/osmocom/bb/common/lapdm.h b/src/host/layer23/include/osmocom/bb/common/lapdm.h index 1214f0f..b5b8187 100644 --- a/src/host/layer23/include/osmocom/bb/common/lapdm.h +++ b/src/host/layer23/include/osmocom/bb/common/lapdm.h @@ -18,7 +18,6 @@ enum lapdm_state { }; struct lapdm_entity; -struct osmocom_ms; struct lapdm_msg_ctx { struct lapdm_datalink *dl; @@ -62,6 +61,9 @@ enum lapdm_dl_sapi { _NR_DL_SAPI }; +typedef int (*lapdm_cb_t)(struct msgb *msg, struct lapdm_entity *le, void *ctx); + +/* register message handler for messages that are sent from L2->L3 */ struct lapdm_entity { struct lapdm_datalink datalink[_NR_DL_SAPI]; int last_tx_dequeue; /* last entity that was dequeued */ @@ -69,16 +71,31 @@ struct lapdm_entity { void *l1_ctx; /* context for layer1 instance */ void *l3_ctx; /* context for layer3 instance */ + + lapdm_cb_t l1_cb; /* callback for sending stuff to L1 */ + lapdm_cb_t l3_cb; /* callback for sending stuff to L3 */ + + struct lapdm_channel *lapdm_ch; +}; + +/* the two lapdm_entities that form a GSM logical channel (ACCH + DCCH) */ +struct lapdm_channel { + struct llist_head list; + char *name; + struct lapdm_entity lapdm_acch; + struct lapdm_entity lapdm_dcch; }; const char *get_rsl_name(int value); extern const char *lapdm_state_names[]; /* initialize a LAPDm entity */ -void lapdm_init(struct lapdm_entity *le); +void lapdm_entity_init(struct lapdm_entity *le); +void lapdm_channel_init(struct lapdm_channel *lc); /* deinitialize a LAPDm entity */ -void lapdm_exit(struct lapdm_entity *le); +void lapdm_entity_exit(struct lapdm_entity *le); +void lapdm_channel_exit(struct lapdm_channel *lc); /* input into layer2 (from layer 1) */ int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, struct l1ctl_info_dl *l1i); @@ -89,14 +106,8 @@ int l2_ph_chan_conf(struct msgb *msg, struct osmocom_ms *ms, struct l1ctl_info_dl *dl); /* input into layer2 (from layer 3) */ -int rslms_recvmsg(struct msgb *msg, struct osmocom_ms *ms); - -/* sending messages up from L2 to L3 */ -int rslms_sendmsg(struct msgb *msg, struct osmocom_ms *ms); +int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc); -typedef int (*osmol2_cb_t)(struct msgb *msg, struct osmocom_ms *ms); - -/* register message handler for messages that are sent from L2->L3 */ -int osmol2_register_handler(struct osmocom_ms *ms, osmol2_cb_t cb); +int osmol2_register_handler(struct osmocom_ms *ms, lapdm_cb_t cb); #endif /* _OSMOCOM_LAPDM_H */ diff --git a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h index 9ca4114..de25af5 100644 --- a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h +++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h @@ -20,13 +20,6 @@ struct osmocom_ms; #include #include -/* A layer2 entity */ -struct osmol2_entity { - struct lapdm_entity lapdm_dcch; - struct lapdm_entity lapdm_acch; - osmol2_cb_t msg_handler; -}; - struct osmosap_entity { osmosap_cb_t msg_handler; }; @@ -58,7 +51,7 @@ struct osmocom_ms { struct gsm_settings settings; struct gsm_subscriber subscr; struct gsm_sim sim; - struct osmol2_entity l2_entity; + struct lapdm_channel lapdm_channel; struct osmosap_entity sap_entity; struct rx_meas_stat meas; struct gsm48_rrlayer rrlayer; diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c index 8c92244..0c6825b 100644 --- a/src/host/layer23/src/common/l1ctl.c +++ b/src/host/layer23/src/common/l1ctl.c @@ -222,9 +222,9 @@ printf("Dropping frame with %u bit errors\n", dl->num_biterr); /* determine LAPDm entity based on SACCH or not */ if (dl->link_id & 0x40) - le = &ms->l2_entity.lapdm_acch; + le = &ms->lapdm_channel.lapdm_acch; else - le = &ms->l2_entity.lapdm_dcch; + le = &ms->lapdm_channel.lapdm_dcch; /* make local stack copy of l1ctl_info_dl, as LAPDm will * overwrite skb hdr */ memcpy(&dl_cpy, dl, sizeof(dl_cpy)); @@ -249,9 +249,9 @@ static int rx_ph_data_conf(struct osmocom_ms *ms, struct msgb *msg) /* determine LAPDm entity based on SACCH or not */ if (dl->link_id & 0x40) - le = &ms->l2_entity.lapdm_acch; + le = &ms->lapdm_channel.lapdm_acch; else - le = &ms->l2_entity.lapdm_dcch; + le = &ms->lapdm_channel.lapdm_dcch; /* send it up into LAPDm */ l2_ph_data_conf(msg, le); diff --git a/src/host/layer23/src/common/lapdm.c b/src/host/layer23/src/common/lapdm.c index d062ee3..2d64f35 100644 --- a/src/host/layer23/src/common/lapdm.c +++ b/src/host/layer23/src/common/lapdm.c @@ -186,7 +186,7 @@ static void lapdm_dl_init(struct lapdm_datalink *dl, dl->entity = entity; } -void lapdm_init(struct lapdm_entity *le) +void lapdm_entity_init(struct lapdm_entity *le) { unsigned int i; @@ -194,6 +194,13 @@ void lapdm_init(struct lapdm_entity *le) lapdm_dl_init(&le->datalink[i], le); } +void lapdm_channel_init(struct lapdm_channel *lc) +{ + lapdm_entity_init(&lc->lapdm_acch); + lapdm_entity_init(&lc->lapdm_dcch); +} + + static void lapdm_dl_flush_send(struct lapdm_datalink *dl) { struct msgb *msg; @@ -220,7 +227,7 @@ static void lapdm_dl_flush_tx(struct lapdm_datalink *dl) dl->tx_length[i] = 0; } -void lapdm_exit(struct lapdm_entity *le) +void lapdm_entity_exit(struct lapdm_entity *le) { unsigned int i; struct lapdm_datalink *dl; @@ -234,6 +241,12 @@ void lapdm_exit(struct lapdm_entity *le) } } +void lapdm_channel_exit(struct lapdm_channel *lc) +{ + lapdm_entity_exit(&lc->lapdm_acch); + lapdm_entity_exit(&lc->lapdm_dcch); +} + static void lapdm_dl_newstate(struct lapdm_datalink *dl, uint32_t state) { LOGP(DLAPDM, LOGL_INFO, "new state %s -> %s\n", @@ -278,6 +291,18 @@ static void lapdm_pad_msgb(struct msgb *msg, uint8_t n201) memset(data, 0x2B, pad_len); } +/* input function that L2 calls when sending messages up to L3 */ +static int rslms_sendmsg(struct msgb *msg, struct lapdm_entity *le) +{ + if (!le->l3_cb) { + msgb_free(msg); + return -EIO; + } + + /* call the layer2 message handler that is registered */ + return le->l3_cb(msg, le, le->l3_ctx); +} + /* write a frame into the tx queue */ static int tx_ph_data_enqueue(struct lapdm_datalink *dl, struct msgb *msg, uint8_t chan_nr, uint8_t link_id, uint8_t n201) @@ -353,7 +378,7 @@ static int send_rslms_rll_l3(uint8_t msg_type, struct lapdm_msg_ctx *mctx, rsl_rll_push_l3(msg, msg_type, mctx->chan_nr, mctx->link_id, 1); /* send off the RSLms message to L3 */ - return rslms_sendmsg(msg, mctx->dl->entity->l3_ctx); + return rslms_sendmsg(msg, mctx->dl->entity); } /* Take a B4 format message from L1 and create RSLms UNIT DATA IND */ @@ -375,7 +400,7 @@ static int send_rslms_rll_l3_ui(struct lapdm_msg_ctx *mctx, struct msgb *msg) rllh->data[2] = RSL_IE_MS_POWER; rllh->data[3] = mctx->tx_power_ind; - return rslms_sendmsg(msg, mctx->dl->entity->l3_ctx); + return rslms_sendmsg(msg, mctx->dl->entity); } static int send_rll_simple(uint8_t msg_type, struct lapdm_msg_ctx *mctx) @@ -385,7 +410,7 @@ static int send_rll_simple(uint8_t msg_type, struct lapdm_msg_ctx *mctx) msg = rsl_rll_simple(msg_type, mctx->chan_nr, mctx->link_id, 1); /* send off the RSLms message to L3 */ - return rslms_sendmsg(msg, mctx->dl->entity->l3_ctx); + return rslms_sendmsg(msg, mctx->dl->entity); } static int rsl_rll_error(uint8_t cause, struct lapdm_msg_ctx *mctx) @@ -400,7 +425,7 @@ static int rsl_rll_error(uint8_t cause, struct lapdm_msg_ctx *mctx) tlv[0] = RSL_IE_RLM_CAUSE; tlv[1] = 1; tlv[2] = cause; - return rslms_sendmsg(msg, mctx->dl->entity->l3_ctx); + return rslms_sendmsg(msg, mctx->dl->entity); } static int check_length_ind(struct lapdm_msg_ctx *mctx, uint8_t length_ind) @@ -2023,9 +2048,10 @@ static int rslms_rx_rll_rel_req_idle(struct msgb *msg, struct lapdm_datalink *dl } /* L3 requests channel in idle state */ -static int rslms_rx_chan_rqd(struct osmocom_ms *ms, struct msgb *msg) +static int rslms_rx_chan_rqd(struct lapdm_channel *lc, struct msgb *msg) { struct abis_rsl_cchan_hdr *cch = msgb_l2(msg); + void *l1ctx = lc->lapdm_dcch.l1_ctx; int rc; if (msgb_l2len(msg) < sizeof(*cch) + 4 + 2 + 2) { @@ -2046,9 +2072,9 @@ static int rslms_rx_chan_rqd(struct osmocom_ms *ms, struct msgb *msg) } /* TA = 0 - delay */ - rc = l1ctl_tx_param_req(ms, 0 - cch->data[5], cch->data[7]); + rc = l1ctl_tx_param_req(l1ctx, 0 - cch->data[5], cch->data[7]); - rc = l1ctl_tx_rach_req(ms, cch->data[1], + rc = l1ctl_tx_rach_req(l1ctx, cch->data[1], ((cch->data[2] & 0x7f) << 8) | cch->data[3], cch->data[2] >> 7); msgb_free(msg); @@ -2078,7 +2104,7 @@ int l2_ph_chan_conf(struct msgb *msg, struct osmocom_ms *ms, ref->t3_low = tm.t3 & 0x7; ref->t3_high = tm.t3 >> 3; - return rslms_sendmsg(msg, ms); + return rslms_sendmsg(msg, &ms->lapdm_channel.lapdm_dcch); } /* Names for Radio Link Layer Management */ @@ -2169,7 +2195,7 @@ static struct l2downstate { (sizeof(l2downstatelist) / sizeof(struct l2downstate)) /* incoming RSLms RLL message from L3 */ -static int rslms_rx_rll(struct msgb *msg, struct osmocom_ms *ms) +static int rslms_rx_rll(struct msgb *msg, struct lapdm_channel *lc) { struct abis_rsl_rll_hdr *rllh = msgb_l2(msg); int msg_type = rllh->c.msg_type; @@ -2185,9 +2211,9 @@ static int rslms_rx_rll(struct msgb *msg, struct osmocom_ms *ms) } if (rllh->link_id & 0x40) - le = &ms->l2_entity.lapdm_acch; + le = &lc->lapdm_acch; else - le = &ms->l2_entity.lapdm_dcch; + le = &lc->lapdm_dcch; /* G.2.1 No action schall be taken on frames containing an unallocated * SAPI. @@ -2198,8 +2224,8 @@ static int rslms_rx_rll(struct msgb *msg, struct osmocom_ms *ms) return -EINVAL; } - LOGP(DRSL, LOGL_INFO, "(ms %s) RLL Message '%s' received in state %s\n", - ms->name, get_rsl_name(msg_type), lapdm_state_names[dl->state]); + LOGP(DRSL, LOGL_INFO, "(%p) RLL Message '%s' received in state %s\n", + lc->name, get_rsl_name(msg_type), lapdm_state_names[dl->state]); /* find function for current state and message */ for (i = 0; i < L2DOWNSLLEN; i++) { @@ -2226,7 +2252,7 @@ static int rslms_rx_rll(struct msgb *msg, struct osmocom_ms *ms) } /* incoming RSLms COMMON CHANNEL message from L3 */ -static int rslms_rx_com_chan(struct msgb *msg, struct osmocom_ms *ms) +static int rslms_rx_com_chan(struct msgb *msg, struct lapdm_channel *lc) { struct abis_rsl_cchan_hdr *cch = msgb_l2(msg); int msg_type = cch->c.msg_type; @@ -2240,7 +2266,7 @@ static int rslms_rx_com_chan(struct msgb *msg, struct osmocom_ms *ms) switch (msg_type) { case RSL_MT_CHAN_RQD: /* create and send RACH request */ - rc = rslms_rx_chan_rqd(ms, msg); + rc = rslms_rx_chan_rqd(lc, msg); break; default: LOGP(DRSL, LOGL_NOTICE, "Unknown COMMON CHANNEL msg %d!\n", @@ -2253,7 +2279,7 @@ static int rslms_rx_com_chan(struct msgb *msg, struct osmocom_ms *ms) } /* input into layer2 (from layer 3) */ -int rslms_recvmsg(struct msgb *msg, struct osmocom_ms *ms) +int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc) { struct abis_rsl_common_hdr *rslh = msgb_l2(msg); int rc = 0; @@ -2265,10 +2291,10 @@ int rslms_recvmsg(struct msgb *msg, struct osmocom_ms *ms) switch (rslh->msg_discr & 0xfe) { case ABIS_RSL_MDISC_RLL: - rc = rslms_rx_rll(msg, ms); + rc = rslms_rx_rll(msg, lc); break; case ABIS_RSL_MDISC_COM_CHAN: - rc = rslms_rx_com_chan(msg, ms); + rc = rslms_rx_com_chan(msg, lc); break; default: LOGP(DRSL, LOGL_ERROR, "unknown RSLms message " @@ -2280,22 +2306,12 @@ int rslms_recvmsg(struct msgb *msg, struct osmocom_ms *ms) return rc; } -/* input function that L2 calls when sending messages up to L3 */ -int rslms_sendmsg(struct msgb *msg, struct osmocom_ms *ms) -{ - if (!ms->l2_entity.msg_handler) { - msgb_free(msg); - return -EIO; - } - - /* call the layer2 message handler that is registered */ - return ms->l2_entity.msg_handler(msg, ms); -} - -/* register message handler for messages that are sent from L2->L3 */ -int osmol2_register_handler(struct osmocom_ms *ms, osmol2_cb_t cb) +int osmol2_register_handler(struct osmocom_ms *ms, lapdm_cb_t cb) { - ms->l2_entity.msg_handler = cb; + ms->lapdm_channel.lapdm_acch.l3_cb = cb; + ms->lapdm_channel.lapdm_dcch.l3_cb = cb; + ms->lapdm_channel.lapdm_acch.l3_ctx = ms; + ms->lapdm_channel.lapdm_dcch.l3_ctx = ms; return 0; } diff --git a/src/host/layer23/src/common/main.c b/src/host/layer23/src/common/main.c index 9705af5..abfb422 100644 --- a/src/host/layer23/src/common/main.c +++ b/src/host/layer23/src/common/main.c @@ -254,13 +254,11 @@ int main(int argc, char **argv) if (rc < 0) fprintf(stderr, "Failed during sap_open(), no SIM reader\n"); - ms->l2_entity.lapdm_dcch.l1_ctx = ms; - ms->l2_entity.lapdm_dcch.l3_ctx = ms; - lapdm_init(&ms->l2_entity.lapdm_dcch); - - ms->l2_entity.lapdm_acch.l1_ctx = ms; - ms->l2_entity.lapdm_acch.l3_ctx = ms; - lapdm_init(&ms->l2_entity.lapdm_acch); + ms->lapdm_channel.lapdm_dcch.l1_ctx = ms; + ms->lapdm_channel.lapdm_dcch.l3_ctx = ms; + ms->lapdm_channel.lapdm_acch.l1_ctx = ms; + ms->lapdm_channel.lapdm_acch.l3_ctx = ms; + lapdm_channel_init(&ms->lapdm_channel); rc = l23_app_init(ms); if (rc < 0) diff --git a/src/host/layer23/src/misc/app_cbch_sniff.c b/src/host/layer23/src/misc/app_cbch_sniff.c index bda9aae..ec11234 100644 --- a/src/host/layer23/src/misc/app_cbch_sniff.c +++ b/src/host/layer23/src/misc/app_cbch_sniff.c @@ -134,8 +134,9 @@ static int rcv_rll(struct osmocom_ms *ms, struct msgb *msg) return 0; } -static int rcv_rsl(struct msgb *msg, struct osmocom_ms *ms) +static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx) { + struct osmocom_ms *ms = l3ctx; struct abis_rsl_common_hdr *rslh = msgb_l2(msg); int rc = 0; diff --git a/src/host/layer23/src/misc/cell_log.c b/src/host/layer23/src/misc/cell_log.c index 3f51f87..ac0d206 100644 --- a/src/host/layer23/src/misc/cell_log.c +++ b/src/host/layer23/src/misc/cell_log.c @@ -297,7 +297,7 @@ static void start_rach(void) start_timer(RACH_WAIT); - rslms_recvmsg(nmsg, ms); + lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel); } static void start_sync(void) @@ -757,8 +757,9 @@ static int rcv_cch(struct osmocom_ms *ms, struct msgb *msg) return 0; } -static int rcv_rsl(struct msgb *msg, struct osmocom_ms *ms) +static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx) { + struct osmocom_ms *ms = l3ctx; struct abis_rsl_common_hdr *rslh = msgb_l2(msg); int rc = 0; diff --git a/src/host/layer23/src/misc/rslms.c b/src/host/layer23/src/misc/rslms.c index 93d22fd..02113a3 100644 --- a/src/host/layer23/src/misc/rslms.c +++ b/src/host/layer23/src/misc/rslms.c @@ -44,7 +44,7 @@ int rslms_tx_rll_req(struct osmocom_ms *ms, uint8_t msg_type, msg = rsl_rll_simple(msg_type, chan_nr, link_id, 1); - return rslms_recvmsg(msg, ms); + return lapdm_rslms_recvmsg(msg, ms); } /* Send a RLL request (including L3 info) to L2 */ @@ -53,7 +53,7 @@ int rslms_tx_rll_req_l3(struct osmocom_ms *ms, uint8_t msg_type, { rsl_rll_push_l3(msg, msg_type, chan_nr, link_id, 1); - return rslms_recvmsg(msg, ms); + return lapdm_rslms_recvmsg(msg, ms); } static int rslms_rx_udata_ind(struct msgb *msg, struct osmocom_ms *ms) diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c index 5bb580a..ed672c9 100644 --- a/src/host/layer23/src/mobile/app_mobile.c +++ b/src/host/layer23/src/mobile/app_mobile.c @@ -143,8 +143,7 @@ int mobile_exit(struct osmocom_ms *ms, int force) gsm_subscr_exit(ms); gsm48_cc_exit(ms); gsm_sim_exit(ms); - lapdm_exit(&ms->l2_entity.lapdm_acch); - lapdm_exit(&ms->l2_entity.lapdm_dcch); + lapdm_channel_exit(&ms->lapdm_channel); ms->shutdown = 2; /* being down */ vty_notify(ms, NULL); @@ -160,12 +159,11 @@ int mobile_init(struct osmocom_ms *ms) int rc; gsm_settings_arfcn(ms); - ms->l2_entity.lapdm_dcch.l1_ctx = ms; - ms->l2_entity.lapdm_dcch.l3_ctx = ms; - lapdm_init(&ms->l2_entity.lapdm_dcch); - ms->l2_entity.lapdm_acch.l1_ctx = ms; - ms->l2_entity.lapdm_acch.l3_ctx = ms; - lapdm_init(&ms->l2_entity.lapdm_acch); + ms->lapdm_channel.lapdm_dcch.l1_ctx = ms; + ms->lapdm_channel.lapdm_dcch.l3_ctx = ms; + ms->lapdm_channel.lapdm_acch.l1_ctx = ms; + ms->lapdm_channel.lapdm_acch.l3_ctx = ms; + lapdm_channel_init(&ms->lapdm_channel); gsm_sim_init(ms); gsm48_cc_init(ms); gsm_subscr_init(ms); diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c index 7911943..a6f8a02 100644 --- a/src/host/layer23/src/mobile/gsm48_rr.c +++ b/src/host/layer23/src/mobile/gsm48_rr.c @@ -74,6 +74,7 @@ #include #include +#include #include #include #include @@ -511,7 +512,7 @@ static int gsm48_send_rsl(struct osmocom_ms *ms, uint8_t msg_type, rsl_rll_push_l3(msg, msg_type, rr->cd_now.chan_nr, rr->cd_now.link_id, 1); - return rslms_recvmsg(msg, ms); + return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel); } /* push rsl header + release mode and send (RSL-SAP) */ @@ -523,12 +524,13 @@ static int gsm48_send_rsl_rel(struct osmocom_ms *ms, uint8_t msg_type, rsl_rll_push_hdr(msg, msg_type, rr->cd_now.chan_nr, rr->cd_now.link_id, 1); - return rslms_recvmsg(msg, ms); + return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel); } /* enqueue messages (RSL-SAP) */ -static int gsm48_rx_rsl(struct msgb *msg, struct osmocom_ms *ms) +static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx) { + struct osmocom_ms *ms = l3ctx; struct gsm48_rrlayer *rr = &ms->rrlayer; msgb_enqueue(&rr->rsl_upqueue, msg); @@ -1620,7 +1622,7 @@ fail: /* store ra until confirmed, then copy it with time into cr_hist */ rr->cr_ra = chan_req; - return rslms_recvmsg(nmsg, ms); + return lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel); } /* @@ -2763,7 +2765,7 @@ static int gsm48_rr_tx_meas_rep(struct osmocom_ms *ms) rsl_rll_push_hdr(nmsg, RSL_MT_UNIT_DATA_REQ, rr->cd_now.chan_nr, 0x40, 1); - return rslms_recvmsg(nmsg, ms); + return lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel); } /* @@ -5055,7 +5057,7 @@ int gsm48_rr_init(struct osmocom_ms *ms) INIT_LLIST_HEAD(&rr->downqueue); /* downqueue is handled here, so don't add_work */ - osmol2_register_handler(ms, &gsm48_rx_rsl); + osmol2_register_handler(ms, &rcv_rsl); start_rr_t_meas(rr, 1, 0);