mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-bts.git
synced 2025-11-02 13:13:27 +00:00
ASCI: NCH / NOTIFICATION support
This adds very minimalistic support for notification of VBS/VGCS calls. Minimalistic in that we * only notify via PCH (not via NCH or FACCH) * only include notification in otherwise empty PAGING TYPE 1 This means that notification will cease to work once the PCH becomes too loaded and we never would send otherwise empty PAGING TYPE 1 anymore. Change-Id: I6f6f72d9a0123cb519b341d72a124aaa2117370e Requires: libosmocore.git I9586b5cb8514010d9358fcfc97c3d34741294522 Related: OS#5781
This commit is contained in:
@@ -32,5 +32,6 @@ noinst_HEADERS = \
|
||||
dtx_dl_amr_fsm.h \
|
||||
ta_control.h \
|
||||
nm_common_fsm.h \
|
||||
notification.h \
|
||||
osmux.h \
|
||||
$(NULL)
|
||||
|
||||
@@ -290,6 +290,11 @@ struct gsm_bts {
|
||||
bool pni; /* Primary Notification Identifier */
|
||||
} etws;
|
||||
|
||||
/* Advanced Speech Call Items (VBS/VGCS) + NCH related bits */
|
||||
struct {
|
||||
struct llist_head notifications;
|
||||
} asci;
|
||||
|
||||
struct paging_state *paging_state;
|
||||
struct llist_head bsc_oml_hosts;
|
||||
unsigned int rtp_jitter_buf_ms;
|
||||
|
||||
57
include/osmo-bts/notification.h
Normal file
57
include/osmo-bts/notification.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* Maintain and generate ASCI notifications */
|
||||
|
||||
/*
|
||||
* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0+
|
||||
*
|
||||
* Author: Harald Welte
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* one [concurrent] ASCI (VBS/VGCS) notification */
|
||||
struct asci_notification {
|
||||
struct llist_head list; /* linked to bts->asci.notifications */
|
||||
|
||||
/* Group call reference (TS 24.008 10.5.1.9 "Descriptive group or broadcast call reference") */
|
||||
uint8_t group_call_ref[5];
|
||||
|
||||
/* Group Channel Description (TS 44.018 10.5.2.14b) */
|
||||
struct {
|
||||
bool present;
|
||||
uint8_t value[255];
|
||||
uint8_t len;
|
||||
} chan_desc;
|
||||
|
||||
/* NCH DRX Information (TS 48.058 9.3.47) */
|
||||
struct {
|
||||
bool present;
|
||||
struct rsl_ie_nch_drx_info value;
|
||||
} nch_drx_info;
|
||||
};
|
||||
|
||||
int bts_asci_notification_add(struct gsm_bts *bts, const uint8_t *group_call_ref, const uint8_t *chan_desc,
|
||||
uint8_t chan_desc_len, const struct rsl_ie_nch_drx_info *nch_drx_info);
|
||||
|
||||
int bts_asci_notification_del(struct gsm_bts *bts, const uint8_t *group_call_ref);
|
||||
|
||||
int bts_asci_notification_reset(struct gsm_bts *bts);
|
||||
|
||||
const struct asci_notification *bts_asci_notification_get_next(struct gsm_bts *bts);
|
||||
|
||||
void append_group_call_information(struct bitvec *bv, const uint8_t *gcr, const uint8_t *ch_desc, uint8_t ch_desc_len);
|
||||
@@ -67,6 +67,7 @@ libbts_a_SOURCES = \
|
||||
nm_gprs_nse_fsm.c \
|
||||
nm_gprs_nsvc_fsm.c \
|
||||
nm_radio_carrier_fsm.c \
|
||||
notification.c \
|
||||
probes.d \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@@ -400,6 +400,8 @@ int bts_init(struct gsm_bts *bts)
|
||||
bts->smscb_queue_tgt_len = 2;
|
||||
bts->smscb_queue_hyst = 2;
|
||||
|
||||
INIT_LLIST_HEAD(&bts->asci.notifications);
|
||||
|
||||
INIT_LLIST_HEAD(&bts->bsc_oml_hosts);
|
||||
|
||||
/* register DTX DL FSM */
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <osmo-bts/nm_common_fsm.h>
|
||||
#include <osmo-bts/phy_link.h>
|
||||
#include <osmo-bts/cbch.h>
|
||||
#include <osmo-bts/notification.h>
|
||||
|
||||
#define X(s) (1 << (s))
|
||||
|
||||
@@ -64,6 +65,7 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint3
|
||||
bts->bsic = 0xff; /* invalid value */
|
||||
TALLOC_FREE(bts->mo.nm_attr);
|
||||
bts_cbch_reset(bts);
|
||||
bts_asci_notification_reset(bts);
|
||||
if (bts->c0_power_red_db > 0)
|
||||
bts_set_c0_pwr_red(bts, 0);
|
||||
|
||||
|
||||
155
src/common/notification.c
Normal file
155
src/common/notification.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/* Maintain and generate ASCI notifications */
|
||||
|
||||
/*
|
||||
* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0+
|
||||
*
|
||||
* Author: Harald Welte
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocom/core/bitvec.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
||||
|
||||
#include <osmo-bts/bts.h>
|
||||
#include <osmo-bts/logging.h>
|
||||
#include <osmo-bts/notification.h>
|
||||
|
||||
static struct asci_notification *bts_asci_notification_find(struct gsm_bts *bts, const uint8_t *group_call_ref)
|
||||
{
|
||||
struct asci_notification *n;
|
||||
llist_for_each_entry(n, &bts->asci.notifications, list) {
|
||||
if (!memcmp(n->group_call_ref, group_call_ref, sizeof(n->group_call_ref)))
|
||||
return n;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bts_asci_notification_add(struct gsm_bts *bts, const uint8_t *group_call_ref, const uint8_t *chan_desc,
|
||||
uint8_t chan_desc_len, const struct rsl_ie_nch_drx_info *nch_drx_info)
|
||||
{
|
||||
struct asci_notification *n;
|
||||
|
||||
if (bts_asci_notification_find(bts, group_call_ref))
|
||||
return -EEXIST;
|
||||
|
||||
n = talloc_zero(bts, struct asci_notification);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(n->group_call_ref, group_call_ref, sizeof(n->group_call_ref));
|
||||
if (chan_desc && chan_desc_len) {
|
||||
n->chan_desc.present = true;
|
||||
n->chan_desc.len = chan_desc_len;
|
||||
memcpy(&n->chan_desc.value, chan_desc, chan_desc_len);
|
||||
}
|
||||
if (nch_drx_info) {
|
||||
n->nch_drx_info.present = true;
|
||||
n->nch_drx_info.value = *nch_drx_info;
|
||||
}
|
||||
|
||||
LOGP(DASCI, LOGL_INFO, "Added ASCI Notification for group call reference %s\n",
|
||||
osmo_hexdump_nospc(n->group_call_ref, ARRAY_SIZE(n->group_call_ref)));
|
||||
|
||||
/* add at beginning of "queue" to make sure a new call is notified first */
|
||||
llist_add(&n->list, &bts->asci.notifications);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bts_asci_notification_del(struct gsm_bts *bts, const uint8_t *group_call_ref)
|
||||
{
|
||||
struct asci_notification *n = bts_asci_notification_find(bts, group_call_ref);
|
||||
if (!n)
|
||||
return -ENODEV;
|
||||
|
||||
LOGP(DASCI, LOGL_INFO, "Deleting ASCI Notification for group call reference %s\n",
|
||||
osmo_hexdump_nospc(n->group_call_ref, ARRAY_SIZE(n->group_call_ref)));
|
||||
|
||||
llist_del(&n->list);
|
||||
talloc_free(n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bts_asci_notification_reset(struct gsm_bts *bts)
|
||||
{
|
||||
struct asci_notification *n, *n2;
|
||||
|
||||
LOGP(DASCI, LOGL_INFO, "Deleting all %u ASCI Notifications of BTS\n",
|
||||
llist_count(&bts->asci.notifications));
|
||||
|
||||
llist_for_each_entry_safe(n, n2, &bts->asci.notifications, list) {
|
||||
llist_del(&n->list);
|
||||
talloc_free(n);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct asci_notification *bts_asci_notification_get_next(struct gsm_bts *bts)
|
||||
{
|
||||
struct asci_notification *n;
|
||||
|
||||
n = llist_first_entry_or_null(&bts->asci.notifications, struct asci_notification, list);
|
||||
if (!n)
|
||||
return NULL;
|
||||
|
||||
/* move to end of list to iterate over them */
|
||||
llist_del(&n->list);
|
||||
llist_add_tail(&n->list, &bts->asci.notifications);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*! append a "Group Call Information" CSN.1 structure to the caller-provided bit-vector.
|
||||
* \param[out] bv caller-provided output bit-vector
|
||||
* \param[in] gcr 5-byte group call reference
|
||||
* \param[in] ch_desc optional group channel description (may be NULL)
|
||||
* \param[in] ch_desc_len length of group channel description (in bytes) */
|
||||
void append_group_call_information(struct bitvec *bv, const uint8_t *gcr, const uint8_t *ch_desc, uint8_t ch_desc_len)
|
||||
{
|
||||
/* spec reference: TS 44.018 Section 9.1.21a */
|
||||
|
||||
/* <Group Call Reference : bit(36)> */
|
||||
struct bitvec *gcr_bv = bitvec_alloc(5*8, NULL);
|
||||
OSMO_ASSERT(gcr_bv);
|
||||
bitvec_unpack(gcr_bv, gcr);
|
||||
for (unsigned int i = 0; i < 36; i++)
|
||||
bitvec_set_bit(bv, bitvec_get_bit_pos(gcr_bv, i));
|
||||
|
||||
/* Group Channel Description */
|
||||
if (ch_desc && ch_desc_len) {
|
||||
struct bitvec *chd_bv = bitvec_alloc(ch_desc_len*8, NULL);
|
||||
OSMO_ASSERT(chd_bv);
|
||||
bitvec_unpack(chd_bv, ch_desc);
|
||||
bitvec_set_bit(bv, 1);
|
||||
/* <Channel Description : bit(24)> */
|
||||
for (unsigned int i = 0; i < ch_desc_len * 8; i++)
|
||||
bitvec_set_bit(bv, bitvec_get_bit_pos(chd_bv, i));
|
||||
bitvec_free(chd_bv);
|
||||
/* FIXME: hopping */
|
||||
bitvec_set_bit(bv, 0);
|
||||
} else {
|
||||
bitvec_set_bit(bv, 0);
|
||||
}
|
||||
|
||||
bitvec_free(gcr_bv);
|
||||
}
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <osmo-bts/paging.h>
|
||||
#include <osmo-bts/signal.h>
|
||||
#include <osmo-bts/pcu_if.h>
|
||||
#include <osmo-bts/notification.h>
|
||||
|
||||
#define MAX_PAGING_BLOCKS_CCCH 9
|
||||
#define MAX_BS_PA_MFRMS 9
|
||||
@@ -366,7 +367,8 @@ static void append_etws_prim_notif(struct bitvec *bv, bool is_first, uint8_t pag
|
||||
}
|
||||
|
||||
/* 3GPP TS 44.018 10.5.2.23 append P1 Rest Octets to given bit-vector */
|
||||
static void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro)
|
||||
static void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro,
|
||||
const struct asci_notification *notif)
|
||||
{
|
||||
/* Paging 1 RO (at least 10 bits before ETWS struct) */
|
||||
if (p1ro->nln_pch.present) {
|
||||
@@ -378,7 +380,14 @@ static void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets
|
||||
}
|
||||
bitvec_set_bit(bv, L); /* no Priority1 */
|
||||
bitvec_set_bit(bv, L); /* no Priority2 */
|
||||
bitvec_set_bit(bv, L); /* no Group Call Info */
|
||||
if (notif) {
|
||||
bitvec_set_bit(bv, H); /* Group Call Info */
|
||||
append_group_call_information(bv, notif->group_call_ref,
|
||||
notif->chan_desc.present ? notif->chan_desc.value : NULL,
|
||||
notif->chan_desc.len);
|
||||
} else {
|
||||
bitvec_set_bit(bv, L); /* no Group Call Info */
|
||||
}
|
||||
if (p1ro->packet_page_ind[0])
|
||||
bitvec_set_bit(bv, H); /* Packet Page Indication 1 */
|
||||
else
|
||||
@@ -405,7 +414,8 @@ static void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets
|
||||
|
||||
static int fill_paging_type_1(uint8_t *out_buf, const uint8_t *identity1_lv,
|
||||
uint8_t chan1, const uint8_t *identity2_lv,
|
||||
uint8_t chan2, const struct p1_rest_octets *p1ro)
|
||||
uint8_t chan2, const struct p1_rest_octets *p1ro,
|
||||
const struct asci_notification *notif)
|
||||
{
|
||||
struct gsm48_paging1 *pt1 = (struct gsm48_paging1 *) out_buf;
|
||||
unsigned int ro_len;
|
||||
@@ -436,7 +446,7 @@ static int fill_paging_type_1(uint8_t *out_buf, const uint8_t *identity1_lv,
|
||||
.data = cur,
|
||||
};
|
||||
|
||||
append_p1_rest_octets(&bv, p1ro);
|
||||
append_p1_rest_octets(&bv, p1ro, notif);
|
||||
}
|
||||
|
||||
return GSM_MACBLOCK_LEN;
|
||||
@@ -582,6 +592,7 @@ static void build_p1_rest_octets(struct p1_rest_octets *p1ro, struct gsm_bts *bt
|
||||
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
|
||||
int *is_empty)
|
||||
{
|
||||
const struct asci_notification *notif;
|
||||
struct llist_head *group_q;
|
||||
struct gsm_bts *bts = ps->bts;
|
||||
int group;
|
||||
@@ -607,12 +618,16 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g
|
||||
if (ps->bts->etws.prim_notif) {
|
||||
struct p1_rest_octets p1ro;
|
||||
build_p1_rest_octets(&p1ro, bts);
|
||||
len = fill_paging_type_1(out_buf, empty_id_lv, 0, NULL, 0, &p1ro);
|
||||
/* we intentioanally don't try to add notifications here, as ETWS is more critical */
|
||||
len = fill_paging_type_1(out_buf, empty_id_lv, 0, NULL, 0, &p1ro, NULL);
|
||||
} else if (llist_empty(group_q)) {
|
||||
/* There is nobody to be paged, send Type1 with two empty ID */
|
||||
//DEBUGP(DPAG, "Tx PAGING TYPE 1 (empty)\n");
|
||||
len = fill_paging_type_1(out_buf, empty_id_lv, 0,
|
||||
NULL, 0, NULL);
|
||||
/* for now, we only send VGCS/VBS notfication if we have nothing else to page;
|
||||
* this is the safe choice. For other situations with mobile identities in the
|
||||
* paging type 1, we'd need to check if there's sufficient space in the rest octets. */
|
||||
notif = bts_asci_notification_get_next(bts);
|
||||
len = fill_paging_type_1(out_buf, empty_id_lv, 0, NULL, 0, NULL, notif);
|
||||
*is_empty = 1;
|
||||
} else {
|
||||
struct paging_record *pr[4];
|
||||
@@ -688,19 +703,21 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g
|
||||
}
|
||||
} else if (num_pr == 1) {
|
||||
DEBUGP(DPAG, "Tx PAGING TYPE 1 (1 xMSI,1 empty)\n");
|
||||
/* TODO: check if we can include an ASCI notification */
|
||||
len = fill_paging_type_1(out_buf,
|
||||
pr[0]->u.normal.identity_lv,
|
||||
pr[0]->u.normal.chan_needed,
|
||||
NULL, 0, NULL);
|
||||
NULL, 0, NULL, NULL);
|
||||
} else {
|
||||
/* 2 (any type) or
|
||||
* 3 or 4, of which only 2 will be sent */
|
||||
DEBUGP(DPAG, "Tx PAGING TYPE 1 (2 xMSI)\n");
|
||||
/* TODO: check if we can include an ASCI notification */
|
||||
len = fill_paging_type_1(out_buf,
|
||||
pr[0]->u.normal.identity_lv,
|
||||
pr[0]->u.normal.chan_needed,
|
||||
pr[1]->u.normal.identity_lv,
|
||||
pr[1]->u.normal.chan_needed, NULL);
|
||||
pr[1]->u.normal.chan_needed, NULL, NULL);
|
||||
if (num_pr >= 3) {
|
||||
/* re-add #4 for next time */
|
||||
llist_add(&pr[2]->list, group_q);
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include <osmo-bts/l1sap.h>
|
||||
#include <osmo-bts/bts_model.h>
|
||||
#include <osmo-bts/pcuif_proto.h>
|
||||
#include <osmo-bts/notification.h>
|
||||
|
||||
//#define FAKE_CIPH_MODE_COMPL
|
||||
|
||||
@@ -775,6 +776,52 @@ static int rsl_rx_sms_bcast_cmd(struct gsm_bts_trx *trx, struct msgb *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 8.5.10 NOTIFICATION COMMAND */
|
||||
static int rsl_rx_notification_cmd(struct gsm_bts_trx *trx, struct msgb *msg)
|
||||
{
|
||||
struct abis_rsl_cchan_hdr *cch = msgb_l2(msg);
|
||||
struct tlv_parsed tp;
|
||||
uint8_t command_indicator;
|
||||
int rc;
|
||||
|
||||
if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) {
|
||||
LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__);
|
||||
return rsl_tx_error_report(trx, RSL_ERR_PROTO, &cch->chan_nr, NULL, msg);
|
||||
}
|
||||
|
||||
if (cch->chan_nr != RSL_CHAN_PCH_AGCH) {
|
||||
LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): chan nr is not Downlink CCCH\n", __func__);
|
||||
return rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT, &cch->chan_nr, NULL, msg);
|
||||
}
|
||||
|
||||
if (!TLVP_PRES_LEN(&tp, RSL_IE_CMD_INDICATOR, 1))
|
||||
return rsl_tx_error_report(trx, RSL_ERR_MAND_IE_ERROR, &cch->chan_nr, NULL, msg);
|
||||
command_indicator = *TLVP_VAL(&tp, RSL_IE_CMD_INDICATOR);
|
||||
|
||||
switch (command_indicator) {
|
||||
case RSL_CMD_INDICATOR_START:
|
||||
/* we need at least a Group Call Reference to start notification */
|
||||
if (!TLVP_PRES_LEN(&tp, RSL_IE_GROUP_CALL_REF, 5))
|
||||
return rsl_tx_error_report(trx, RSL_ERR_OPT_IE_ERROR, &cch->chan_nr, NULL, msg);
|
||||
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));
|
||||
break;
|
||||
case RSL_CMD_INDICATOR_STOP:
|
||||
if (!TLVP_PRES_LEN(&tp, RSL_IE_GROUP_CALL_REF, 5)) {
|
||||
/* interpret this as stopping of all notification */
|
||||
rc = bts_asci_notification_reset(trx->bts);
|
||||
} else {
|
||||
rc = bts_asci_notification_del(trx->bts, TLVP_VAL(&tp, RSL_IE_GROUP_CALL_REF));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT, &cch->chan_nr, NULL, msg);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* OSMO_ETWS_CMD - proprietary extension as TS 48.058 has no standardized way to do this :( */
|
||||
static int rsl_rx_osmo_etws_cmd(struct gsm_bts_trx *trx, struct msgb *msg)
|
||||
{
|
||||
@@ -3680,8 +3727,10 @@ static int rsl_rx_cchan(struct gsm_bts_trx *trx, struct msgb *msg)
|
||||
case RSL_MT_SMS_BC_CMD:
|
||||
ret = rsl_rx_sms_bcast_cmd(trx, msg);
|
||||
break;
|
||||
case RSL_MT_SMS_BC_REQ:
|
||||
case RSL_MT_NOT_CMD:
|
||||
ret = rsl_rx_notification_cmd(trx, msg);
|
||||
break;
|
||||
case RSL_MT_SMS_BC_REQ:
|
||||
LOGPLCHAN(msg->lchan, DRSL, LOGL_NOTICE, "unimplemented RSL cchan msg_type %s\n",
|
||||
rsl_msg_name(cch->c.msg_type));
|
||||
rsl_tx_error_report(trx, RSL_ERR_MSG_TYPE, &cch->chan_nr, NULL, msg);
|
||||
|
||||
Reference in New Issue
Block a user