diff options
-rw-r--r-- | openbsc/include/openbsc/bssap.h | 38 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_data.h | 1 | ||||
-rw-r--r-- | openbsc/src/bsc_msc_ip.c | 8 | ||||
-rw-r--r-- | openbsc/src/bssap.c | 41 |
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, |