blob: 0f428cffe610788768948fb04d08dbe5f549c855 [file] [log] [blame]
Oliver Smith10632132023-05-12 12:14:22 +02001/* Filter/overlay bearer service selections across MS, RAN and CN limitations */
2/*
3 * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
4 * All Rights Reserved
5 *
6 * Author: Oliver Smith
7 *
8 * SPDX-License-Identifier: AGPL-3.0+
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
19 *
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include <osmocom/mgcp_client/mgcp_client.h>
25
26#include <osmocom/msc/csd_filter.h>
27
28static void add_all_geran_bs(struct csd_bs_list *list)
29{
30 /* See 3GPP TS 122.002 Bearer Services */
31 /* In order of preference. TODO: make configurable */
32
33 /* GSM-R */
34 csd_bs_list_add_bs(list, CSD_BS_24_T_V110_2k4);
35 csd_bs_list_add_bs(list, CSD_BS_25_T_V110_4k8);
36 csd_bs_list_add_bs(list, CSD_BS_26_T_V110_9k6);
37
38 /* Other */
39 csd_bs_list_add_bs(list, CSD_BS_21_T_V110_0k3);
40 csd_bs_list_add_bs(list, CSD_BS_22_T_V110_1k2);
41 csd_bs_list_add_bs(list, CSD_BS_21_NT_V110_0k3);
42 csd_bs_list_add_bs(list, CSD_BS_22_NT_V110_1k2);
43 csd_bs_list_add_bs(list, CSD_BS_24_NT_V110_2k4);
44 csd_bs_list_add_bs(list, CSD_BS_25_NT_V110_4k8);
45 csd_bs_list_add_bs(list, CSD_BS_26_NT_V110_9k6);
46 csd_bs_list_add_bs(list, CSD_BS_31_T_V110_1k2);
47 csd_bs_list_add_bs(list, CSD_BS_32_T_V110_2k4);
48 csd_bs_list_add_bs(list, CSD_BS_33_T_V110_4k8);
49 csd_bs_list_add_bs(list, CSD_BS_34_T_V110_9k6);
50}
51
52static void add_all_utran_bs(struct csd_bs_list *list)
53{
54 /* See 3GPP TS 122.002 Bearer Services */
55 /* In order of preference. TODO: make configurable */
56 csd_bs_list_add_bs(list, CSD_BS_21_NT_V110_0k3);
57 csd_bs_list_add_bs(list, CSD_BS_22_NT_V110_1k2);
58 csd_bs_list_add_bs(list, CSD_BS_24_NT_V110_2k4);
59 csd_bs_list_add_bs(list, CSD_BS_25_NT_V110_4k8);
60 csd_bs_list_add_bs(list, CSD_BS_26_NT_V110_9k6);
61}
62
63void csd_filter_set_ran(struct csd_filter *filter, enum osmo_rat_type ran_type)
64{
65 filter->ran = (struct csd_bs_list){};
66
67 switch (ran_type) {
68 default:
69 case OSMO_RAT_GERAN_A:
70 add_all_geran_bs(&filter->ran);
71 break;
72 case OSMO_RAT_UTRAN_IU:
73 add_all_utran_bs(&filter->ran);
74 break;
75 }
76}
77
78int csd_filter_run(struct csd_filter *filter, struct sdp_msg *result, const struct sdp_msg *remote)
79{
80 struct csd_bs_list *r = &result->bearer_services;
81 enum csd_bs a = filter->assignment;
82
83 *r = filter->ran;
84
85 if (filter->ms.count)
86 csd_bs_list_intersection(r, &filter->ms);
87 if (filter->bss.count)
88 csd_bs_list_intersection(r, &filter->bss);
89 if (remote->bearer_services.count)
90 csd_bs_list_intersection(r, &remote->bearer_services);
91
92 /* Future: If osmo-msc were able to trigger a re-assignment [...] see
93 * comment in codec_filter_run(). */
94
95 if (a) {
96 *r = (struct csd_bs_list){};
97 csd_bs_list_add_bs(r, a);
98 }
99
100 result->audio_codecs.count = 1;
101 result->audio_codecs.codec[0] = (struct sdp_audio_codec){
102 .payload_type = CODEC_CLEARMODE,
103 .subtype_name = "CLEARMODE",
104 .rate = 8000,
105 };
106
107 return 0;
108}
109
110
111int csd_filter_to_str_buf(char *buf, size_t buflen, const struct csd_filter *filter,
112 const struct sdp_msg *result, const struct sdp_msg *remote)
113{
114 struct osmo_strbuf sb = { .buf = buf, .len = buflen };
115 OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, result);
116 OSMO_STRBUF_PRINTF(sb, " (from:");
117
118 if (filter->assignment) {
119 OSMO_STRBUF_PRINTF(sb, " assigned=");
120 OSMO_STRBUF_APPEND(sb, csd_bs_to_str_buf, filter->assignment);
121 }
122
123 if (remote->bearer_services.count || osmo_sockaddr_str_is_nonzero(&remote->rtp)) {
124 OSMO_STRBUF_PRINTF(sb, " remote=");
125 OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, remote);
126 }
127
128 if (filter->ms.count) {
129 OSMO_STRBUF_PRINTF(sb, " MS={");
130 OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &filter->ms);
131 OSMO_STRBUF_PRINTF(sb, "}");
132 }
133
134 if (filter->bss.count) {
135 OSMO_STRBUF_PRINTF(sb, " bss={");
136 OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &filter->bss);
137 OSMO_STRBUF_PRINTF(sb, "}");
138 }
139
140 OSMO_STRBUF_PRINTF(sb, " RAN={");
141 OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &filter->ran);
142 OSMO_STRBUF_PRINTF(sb, "}");
143
144 OSMO_STRBUF_PRINTF(sb, ")");
145
146 return sb.chars_needed;
147}
148
149char *csd_filter_to_str_c(void *ctx, const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote)
150{
151 OSMO_NAME_C_IMPL(ctx, 128, "csd_filter_to_str_c-ERROR", csd_filter_to_str_buf, filter, result, remote)
152}
153
154const char *csd_filter_to_str(const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote)
155{
156 return csd_filter_to_str_c(OTC_SELECT, filter, result, remote);
157}