aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2009-10-23 13:01:18 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2009-11-20 17:35:45 +0100
commit3fe910b9f1391ff576e9583dc813f267f4e4cead (patch)
tree627971edb135b1d01abe846a7efaa281a76e16c6
parent097bdeb77de0aad435dc99a89ca1b586e8872b55 (diff)
[bssap] First go at implementing channel assignment...
-rw-r--r--openbsc/include/openbsc/bssap.h38
-rw-r--r--openbsc/include/openbsc/gsm_data.h1
-rw-r--r--openbsc/src/bsc_msc_ip.c8
-rw-r--r--openbsc/src/bssap.c41
4 files changed, 77 insertions, 11 deletions
diff --git a/openbsc/include/openbsc/bssap.h b/openbsc/include/openbsc/bssap.h
index 809cbfd7d..1d0f69f20 100644
--- a/openbsc/include/openbsc/bssap.h
+++ b/openbsc/include/openbsc/bssap.h
@@ -265,6 +265,44 @@ enum gsm0808_cause {
GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC = 96,
};
+/* GSM 08.08 3.2.2.11 Channel Type */
+enum gsm0808_chan_indicator {
+ GSM0808_CHAN_SPEECH = 1,
+ GSM0808_CHAN_DATA = 2,
+ GSM0808_CHAN_SIGN = 3,
+};
+
+enum gsm0808_chan_rate_type_data {
+ GSM0808_DATA_FULL_BM = 0x8,
+ GSM0808_DATA_HALF_LM = 0x9,
+ GSM0808_DATA_FULL_RPREF = 0xa,
+ GSM0808_DATA_HALF_PREF = 0xb,
+ GSM0808_DATA_FULL_PREF_NO_CHANGE = 0x1a,
+ GSM0808_DATA_HALF_PREF_NO_CHANGE = 0x1b,
+ GSM0808_DATA_MULTI_MASK = 0x20,
+ GSM0808_DATA_MULTI_MASK_NO_CHANGE = 0x30,
+};
+
+enum gsm0808_chan_rate_type_speech {
+ GSM0808_SPEECH_FULL_BM = 0x8,
+ GSM0808_SPEECH_HALF_LM = 0x9,
+ GSM0808_SPEECH_FULL_PREF= 0xa,
+ GSM0808_SPEECH_HALF_PREF= 0xb,
+ GSM0808_SPEECH_FULL_PREF_NO_CHANGE = 0x1a,
+ GSM0808_SPEECH_HALF_PREF_NO_CHANGE = 0x1b,
+ GSM0808_SPEECH_PERM = 0xf,
+ GSM0808_SPEECH_PERM_NO_CHANGE = 0x1f,
+};
+
+enum gsm0808_permitted_speech {
+ GSM0808_PERM_FR1 = 0x01,
+ GSM0808_PERM_FR2 = 0x11,
+ GSM0808_PERM_FR3 = 0x21,
+ GSM0808_PERM_HR1 = GSM0808_PERM_FR1 | 0x4,
+ GSM0808_PERM_HR2 = GSM0808_PERM_FR2 | 0x4,
+ GSM0808_PERM_HR3 = GSM0808_PERM_FR3 | 0x4,
+};
+
int bssmap_rcvmsg_dt1(struct sccp_connection *conn, struct msgb *msg, unsigned int length);
int bssmap_rcvmsg_udt(struct gsm_network *net, struct msgb *msg, unsigned int length);
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index b79722102..f7774fefd 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -129,7 +129,6 @@ struct bss_sccp_connection_data {
/* audio handling */
int rtp_port;
- int rtp_payload2;
/* Queue SCCP and GSM0408 messages */
struct llist_head gsm_queue;
diff --git a/openbsc/src/bsc_msc_ip.c b/openbsc/src/bsc_msc_ip.c
index 27603a7eb..d82f06fc2 100644
--- a/openbsc/src/bsc_msc_ip.c
+++ b/openbsc/src/bsc_msc_ip.c
@@ -325,8 +325,12 @@ static int handle_modify_ack(struct msgb *msg)
/* modify RSL */
rc = gsm48_rx_rr_modif_ack(msg);
+ if (rc < 0)
+ gsm0808_send_assignment_failure(msg->lchan,
+ GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
+ else
+ gsm0808_send_assignment_compl(msg->lchan, 0);
- gsm0808_send_assignment_compl(msg->lchan, 0);
return 1;
}
@@ -440,7 +444,7 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
rc = rsl_ipacc_mdcx(lchan, ntohl(local_addr.s_addr),
lchan->msc_data->rtp_port,
ts->abis_ip.conn_id,
- lchan->msc_data->rtp_payload2);
+ ts->abis_ip.rtp_payload2);
if (rc < 0) {
DEBUGP(DMSC, "Failed to send connect: %d\n", rc);
return rc;
diff --git a/openbsc/src/bssap.c b/openbsc/src/bssap.c
index 63bcc956b..0343d6d84 100644
--- a/openbsc/src/bssap.c
+++ b/openbsc/src/bssap.c
@@ -24,6 +24,7 @@
#include <openbsc/gsm_04_08.h>
#include <openbsc/gsm_subscriber.h>
#include <openbsc/debug.h>
+#include <openbsc/mgcp.h>
#include <openbsc/signal.h>
#include <openbsc/tlv.h>
#include <openbsc/paging.h>
@@ -251,7 +252,8 @@ static int bssmap_handle_assignm_req(struct sccp_connection *conn,
{
struct tlv_parsed tp;
struct bss_sccp_connection_data *msc_data;
- int ret = 0;
+ u_int8_t *data;
+ u_int8_t multiplex;
if (!msg->lchan || !msg->lchan->msc_data) {
DEBUGP(DMSC, "No lchan/msc_data in cipher mode command.\n");
@@ -271,19 +273,42 @@ static int bssmap_handle_assignm_req(struct sccp_connection *conn,
goto reject;
}
+ multiplex = TLVP_VAL(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)[1] & 0x1f;
+
/*
- * currently only activation of speach on the
- * existing channel is supported. This means we
- * will send a Channel Modify message and take it
- * from there.
- * Setup channel type, timer
+ * Currently we only support a limited subset of all
+ * possible channel types. The limitation ends by not using
+ * multi-slot, limiting the channel coding, speech...
*/
- //gsm48_lchan_modify();
+ if (TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE) != 3) {
+ DEBUGP(DMSC, "ChannelType len !=3 not supported: %d\n",
+ TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE));
+ goto reject;
+ }
+
+ data = (u_int8_t *) TLVP_VAL(&tp, GSM0808_IE_CHANNEL_TYPE);
+ if ((data[0] & 0xf) != 0x1) {
+ DEBUGP(DMSC, "ChannelType != speech: %d\n", data[0]);
+ goto reject;
+ }
+ if (data[1] != GSM0808_SPEECH_FULL_PREF) {
+ DEBUGP(DMSC, "ChannelType full not preferred: %d\n", data[1]);
+ goto reject;
+ }
+
+ if (data[2] != GSM0808_PERM_FR2) {
+ DEBUGP(DMSC, "ChannelType FR2 not supported\n");
+ goto reject;
+ }
+
+ /* modify the channel now */
msc_data->T10.cb = bssmap_t10_fired;
msc_data->T10.data = conn;
bsc_schedule_timer(&msc_data->T10, GSM0808_T10_VALUE);
- return ret;
+
+ msc_data->rtp_port = rtp_calculate_port(multiplex, rtp_base_port);
+ return gsm48_lchan_modify(msg->lchan, GSM48_CMODE_SPEECH_EFR);
reject:
gsm0808_send_assignment_failure(msg->lchan,