jolly has uploaded this change for review.
ASCI: Add Notification/FACCH support
When a VGCS/VBS call is established in a cell, NCH is used to notify
about ongoing calls to idle subscribers. Additionally Notification/FACCH
is used to notify subscribers in dedicated mode. This is performed by
broadcasting this messages to all active dedicated channels. The mobile
station can then indicate the call, so the user can join the call.
More importaint is the notification of the calling subscriber's MS,
which initiated the call. This is done on the early assigned channel.
The MS must know on which channel the call is placed. After leaving the
uplink, it must know where to access the uplink the next time.
Change-Id: I3ed14fa54a907891e492a7ada8e745a2c56cd46d
Related: OS#4851, OS#5781
---
M include/osmo-bts/notification.h
M src/common/notification.c
M src/common/rsl.c
3 files changed, 96 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/48/33448/1
diff --git a/include/osmo-bts/notification.h b/include/osmo-bts/notification.h
index a3bb854..85ac2f1 100644
--- a/include/osmo-bts/notification.h
+++ b/include/osmo-bts/notification.h
@@ -57,3 +57,5 @@
void append_group_call_information(struct bitvec *bv, const uint8_t *gcr, const uint8_t *ch_desc, uint8_t ch_desc_len);
int nch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf);
+int facch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf, const uint8_t *group_call_ref, const uint8_t *chan_desc,
+ uint8_t chan_desc_len);
diff --git a/src/common/notification.c b/src/common/notification.c
index e02d7ce..08d3baa 100644
--- a/src/common/notification.c
+++ b/src/common/notification.c
@@ -223,3 +223,34 @@
return GSM_MACBLOCK_LEN;
}
+
+int facch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf, const uint8_t *group_call_ref, const uint8_t *chan_desc,
+ uint8_t chan_desc_len)
+{
+ struct gsm48_hdr_sh *sh = (struct gsm48_hdr_sh *) out_buf;
+ unsigned int ro_len;
+
+ *sh = (struct gsm48_hdr_sh) {
+ .rr_short_pd = GSM48_PDISC_SH_RR,
+ .msg_type = GSM48_MT_RR_SH_FACCH,
+ .l2_header = 0,
+ };
+
+ /* Pad remaining octets with constant '2B'O */
+ ro_len = GSM_MACBLOCK_LEN - (sh->data - out_buf);
+ memset(sh->data, GSM_MACBLOCK_PADDING, ro_len);
+
+ struct bitvec bv = {
+ .data_len = ro_len,
+ .data = sh->data,
+ };
+
+ /* 0 < Group Call information > */
+ bitvec_set_bit(&bv, 0);
+ append_group_call_information(&bv, group_call_ref, chan_desc, chan_desc_len);
+
+ /* TODO: Additions in Release 6 */
+ /* TODO: Additions in Release 7 */
+
+ return GSM_MACBLOCK_LEN;
+}
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 9f615e6..98e3ba4 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -811,6 +811,45 @@
return 0;
}
+static int broadcast_facch(struct gsm_bts *bts, const uint8_t *group_call_ref, const uint8_t *chan_desc,
+ uint8_t chan_desc_len, int count)
+{
+ uint8_t notif[23];
+ struct msgb *msg, *cmsg;
+ struct gsm_bts_trx *trx;
+ struct gsm_lchan *lchan;
+ int tn, ln, n;
+ int rc;
+
+ rc = facch_gen_msg(bts, notif, group_call_ref, chan_desc, chan_desc_len);
+ if (rc < 0)
+ return rc;
+
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {
+ for (ln = 0; ln < ARRAY_SIZE(trx->ts[tn].lchan); ln++) {
+ lchan = &trx->ts[tn].lchan[ln];
+ if (lchan->type != GSM_LCHAN_SDCCH
+ && lchan->type != GSM_LCHAN_TCH_F
+ && lchan->type != GSM_LCHAN_TCH_H)
+ continue;
+ if (lchan->state != LCHAN_S_ACTIVE)
+ continue;
+ msg = rsl_rll_simple(RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan), 0x00, 0);
+ msg->l3h = msg->tail; /* emulate rsl_rx_rll() behaviour */
+ msgb_tl16v_put(msg, RSL_IE_L3_INFO, sizeof(notif), (uint8_t *) ¬if);
+ for (n = 1; n < count; n++) {
+ cmsg = msgb_copy(msg, "FACCH copy");
+ lapdm_rslms_recvmsg(cmsg, &lchan->lapdm_ch);
+ }
+ lapdm_rslms_recvmsg(msg, &lchan->lapdm_ch);
+ }
+ }
+ }
+
+ return 0;
+}
+
/* 8.5.10 NOTIFICATION COMMAND */
static int rsl_rx_notification_cmd(struct gsm_bts_trx *trx, struct msgb *msg)
{
@@ -841,6 +880,9 @@
rc = bts_asci_notification_add(trx->bts, TLVP_VAL(&tp, RSL_IE_GROUP_CALL_REF),
TLVP_VAL(&tp, RSL_IE_CHAN_DESC), TLVP_LEN(&tp, RSL_IE_CHAN_DESC),
(struct rsl_ie_nch_drx_info *) TLVP_VAL(&tp, RSL_IE_NCH_DRX_INFO));
+ /* Broadcast to FACCH */
+ broadcast_facch(trx->bts, TLVP_VAL(&tp, RSL_IE_GROUP_CALL_REF), TLVP_VAL(&tp, RSL_IE_CHAN_DESC),
+ TLVP_LEN(&tp, RSL_IE_CHAN_DESC), 3);
break;
case RSL_CMD_INDICATOR_STOP:
if (!TLVP_PRES_LEN(&tp, RSL_IE_GROUP_CALL_REF, 5)) {
To view, visit change 33448. To unsubscribe, or for help writing mail filters, visit settings.