Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 1 | /* |
| 2 | * ipaccess audio handling |
| 3 | * |
| 4 | * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org> |
| 5 | * (C) 2009-2010 by On-Waves |
| 6 | * All Rights Reserved |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
Harald Welte | 9af6ddf | 2011-01-01 15:25:50 +0100 | [diff] [blame] | 9 | * it under the terms of the GNU Affero General Public License as published by |
| 10 | * the Free Software Foundation; either version 3 of the License, or |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 11 | * (at your option) any later version. |
| 12 | * |
| 13 | * This program is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
Harald Welte | 9af6ddf | 2011-01-01 15:25:50 +0100 | [diff] [blame] | 16 | * GNU Affero General Public License for more details. |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 17 | * |
Harald Welte | 9af6ddf | 2011-01-01 15:25:50 +0100 | [diff] [blame] | 18 | * You should have received a copy of the GNU Affero General Public License |
| 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 20 | * |
| 21 | */ |
| 22 | |
Neels Hofmeyr | a42855f | 2017-02-23 21:49:55 +0100 | [diff] [blame] | 23 | #include <openbsc/bsc_msc_data.h> |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 24 | #include <openbsc/osmo_bsc.h> |
Holger Hans Peter Freyther | e2fee35 | 2010-12-22 12:32:56 +0100 | [diff] [blame] | 25 | #include <openbsc/abis_rsl.h> |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 26 | #include <openbsc/gsm_data.h> |
| 27 | #include <openbsc/debug.h> |
| 28 | #include <openbsc/signal.h> |
Philipp Maier | 4b60d07 | 2017-04-09 12:32:51 +0200 | [diff] [blame^] | 29 | #include <osmocom/gsm/gsm0808.h> |
| 30 | #include <osmocom/gsm/gsm0808_utils.h> |
| 31 | #include <openbsc/osmo_bsc_sigtran.h> |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 32 | |
| 33 | #include <arpa/inet.h> |
| 34 | |
Philipp Maier | 4b60d07 | 2017-04-09 12:32:51 +0200 | [diff] [blame^] | 35 | /* Generate and send assignment complete message */ |
| 36 | static int send_aoip_ass_compl(struct gsm_subscriber_connection *conn, struct gsm_lchan *lchan) |
| 37 | { |
| 38 | struct msgb *resp; |
| 39 | struct sockaddr_storage rtp_addr; |
| 40 | struct sockaddr_in rtp_addr_in; |
| 41 | struct gsm0808_speech_codec sc; |
| 42 | |
| 43 | OSMO_ASSERT(lchan->abis_ip.ass_compl.valid == true); |
| 44 | |
| 45 | /* Package RTP-Address data */ |
| 46 | memset(&rtp_addr_in, 0, sizeof(rtp_addr_in)); |
| 47 | rtp_addr_in.sin_family = AF_INET; |
| 48 | rtp_addr_in.sin_port = htons(lchan->abis_ip.bound_port); |
| 49 | rtp_addr_in.sin_addr.s_addr = htonl(lchan->abis_ip.bound_ip); |
| 50 | memset(&rtp_addr, 0, sizeof(rtp_addr)); |
| 51 | memcpy(&rtp_addr, &rtp_addr_in, sizeof(rtp_addr_in)); |
| 52 | |
| 53 | /* Extrapolate speech codec from speech mode */ |
| 54 | gsm0808_speech_codec_from_chan_type(&sc, lchan->abis_ip.ass_compl.speech_mode); |
| 55 | |
| 56 | /* Generate message */ |
| 57 | resp = gsm0808_create_ass_compl(lchan->abis_ip.ass_compl.rr_cause, |
| 58 | lchan->abis_ip.ass_compl.chosen_channel, |
| 59 | lchan->abis_ip.ass_compl.encr_alg_id, |
| 60 | lchan->abis_ip.ass_compl.speech_mode, |
| 61 | &rtp_addr, |
| 62 | &sc, |
| 63 | NULL); |
| 64 | |
| 65 | if (!resp) { |
| 66 | LOGP(DMSC, LOGL_ERROR, "Failed to generate assignment completed message!\n"); \ |
| 67 | return -EINVAL; |
| 68 | } |
| 69 | |
| 70 | return osmo_bsc_sigtran_send(conn->sccp_con, resp); |
| 71 | } |
| 72 | |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 73 | static int handle_abisip_signal(unsigned int subsys, unsigned int signal, |
| 74 | void *handler_data, void *signal_data) |
| 75 | { |
| 76 | struct gsm_subscriber_connection *con; |
| 77 | struct gsm_lchan *lchan = signal_data; |
| 78 | int rc; |
Philipp Maier | 4b60d07 | 2017-04-09 12:32:51 +0200 | [diff] [blame^] | 79 | uint32_t rtp_ip; |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 80 | |
| 81 | if (subsys != SS_ABISIP) |
| 82 | return 0; |
| 83 | |
| 84 | con = lchan->conn; |
| 85 | if (!con || !con->sccp_con) |
| 86 | return 0; |
| 87 | |
| 88 | switch (signal) { |
| 89 | case S_ABISIP_CRCX_ACK: |
Holger Hans Peter Freyther | c121bb3 | 2012-12-26 10:17:42 +0100 | [diff] [blame] | 90 | /* |
| 91 | * TODO: handle handover here... then the audio should go to |
| 92 | * the old mgcp port.. |
| 93 | */ |
Philipp Maier | 4b60d07 | 2017-04-09 12:32:51 +0200 | [diff] [blame^] | 94 | |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 95 | /* we can ask it to connect now */ |
| 96 | LOGP(DMSC, LOGL_DEBUG, "Connecting BTS to port: %d conn: %d\n", |
| 97 | con->sccp_con->rtp_port, lchan->abis_ip.conn_id); |
| 98 | |
Philipp Maier | 4b60d07 | 2017-04-09 12:32:51 +0200 | [diff] [blame^] | 99 | /* If AoIP is in use, the rtp_ip, which has been communicated |
| 100 | * via the A interface as connect_ip */ |
| 101 | if(con->sccp_con->rtp_ip) |
| 102 | rtp_ip = con->sccp_con->rtp_ip; |
| 103 | else |
| 104 | rtp_ip = ntohl(INADDR_ANY); |
| 105 | |
| 106 | rc = rsl_ipacc_mdcx(lchan, rtp_ip, |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 107 | con->sccp_con->rtp_port, |
| 108 | lchan->abis_ip.rtp_payload2); |
| 109 | if (rc < 0) { |
| 110 | LOGP(DMSC, LOGL_ERROR, "Failed to send MDCX: %d\n", rc); |
| 111 | return rc; |
| 112 | } |
| 113 | break; |
Philipp Maier | 4b60d07 | 2017-04-09 12:32:51 +0200 | [diff] [blame^] | 114 | |
| 115 | case S_ABISIP_MDCX_ACK: |
| 116 | if (con->ho_lchan) { |
| 117 | /* NOTE: When an ho_lchan exists, the MDCX is part of an |
| 118 | * handover operation (intra-bsc). This means we will not |
| 119 | * inform the MSC about the event, which means that no |
| 120 | * assignment complete message is transmitted */ |
| 121 | LOGP(DMSC, LOGL_INFO," RTP connection handover complete\n"); |
| 122 | } else if (is_ipaccess_bts(con->bts) && con->sccp_con->rtp_ip) { |
| 123 | /* NOTE: This is only relevant on AoIP networks with |
| 124 | * IPA based base stations. See also osmo_bsc_api.c, |
| 125 | * function bsc_assign_compl() */ |
| 126 | LOGP(DMSC, LOGL_INFO, "Tx MSC ASSIGN COMPL (POSTPONED)\n"); |
| 127 | if (send_aoip_ass_compl(con, lchan) != 0) |
| 128 | return -EINVAL; |
| 129 | } |
| 130 | break; |
| 131 | break; |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | return 0; |
| 135 | } |
| 136 | |
| 137 | int osmo_bsc_audio_init(struct gsm_network *net) |
| 138 | { |
Pablo Neira Ayuso | bbc5b99 | 2011-05-06 12:12:31 +0200 | [diff] [blame] | 139 | osmo_signal_register_handler(SS_ABISIP, handle_abisip_signal, net); |
Holger Hans Peter Freyther | 620c2e6 | 2010-11-14 20:38:06 +0100 | [diff] [blame] | 140 | return 0; |
| 141 | } |