Holger Hans Peter Freyther | 22e9ac3 | 2010-07-05 16:02:04 +0800 | [diff] [blame] | 1 | /* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org> |
| 2 | * (C) 2009-2010 by On-Waves |
| 3 | * All Rights Reserved |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 2 of the License, or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License along |
| 16 | * with this program; if not, write to the Free Software Foundation, Inc., |
| 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 18 | * |
| 19 | */ |
| 20 | |
| 21 | #include <openbsc/osmo_bsc.h> |
Holger Hans Peter Freyther | b6d7014 | 2010-11-03 19:03:35 +0100 | [diff] [blame] | 22 | #include <openbsc/debug.h> |
| 23 | |
Holger Hans Peter Freyther | ef2d1bf | 2010-11-04 12:47:06 +0100 | [diff] [blame] | 24 | #include <osmocore/protocol/gsm_08_08.h> |
Holger Hans Peter Freyther | a62919e | 2010-11-04 11:59:41 +0100 | [diff] [blame] | 25 | #include <osmocore/gsm0808.h> |
| 26 | |
Holger Hans Peter Freyther | b6d7014 | 2010-11-03 19:03:35 +0100 | [diff] [blame] | 27 | #define return_when_not_connected(conn) \ |
| 28 | if (!conn->sccp_con) {\ |
| 29 | LOGP(DMSC, LOGL_ERROR, "MSC Connection not present.\n"); \ |
| 30 | return; \ |
| 31 | } |
| 32 | |
| 33 | #define return_when_not_connected_val(conn, ret) \ |
| 34 | if (!conn->sccp_con) {\ |
| 35 | LOGP(DMSC, LOGL_ERROR, "MSC Connection not present.\n"); \ |
| 36 | return ret; \ |
| 37 | } |
Holger Hans Peter Freyther | 22e9ac3 | 2010-07-05 16:02:04 +0800 | [diff] [blame] | 38 | |
Holger Hans Peter Freyther | 5f2184c | 2010-11-05 11:02:28 +0100 | [diff] [blame] | 39 | #define queue_msg_or_return(resp) \ |
| 40 | if (!resp) { \ |
| 41 | LOGP(DMSC, LOGL_ERROR, "Failed to allocate response.\n"); \ |
| 42 | return; \ |
| 43 | } \ |
| 44 | bsc_queue_for_msc(conn, resp); |
| 45 | |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 46 | static void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci) |
| 47 | { |
Holger Hans Peter Freyther | 313324e | 2010-11-04 12:28:32 +0100 | [diff] [blame] | 48 | struct msgb *resp; |
Holger Hans Peter Freyther | b6d7014 | 2010-11-03 19:03:35 +0100 | [diff] [blame] | 49 | return_when_not_connected(conn); |
Holger Hans Peter Freyther | 313324e | 2010-11-04 12:28:32 +0100 | [diff] [blame] | 50 | |
| 51 | resp = gsm0808_create_sapi_reject(dlci); |
Holger Hans Peter Freyther | 5f2184c | 2010-11-05 11:02:28 +0100 | [diff] [blame] | 52 | queue_msg_or_return(resp); |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | static void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, |
| 56 | struct msgb *msg, uint8_t chosen_encr) |
| 57 | { |
Holger Hans Peter Freyther | a62919e | 2010-11-04 11:59:41 +0100 | [diff] [blame] | 58 | struct msgb *resp; |
Holger Hans Peter Freyther | b6d7014 | 2010-11-03 19:03:35 +0100 | [diff] [blame] | 59 | return_when_not_connected(conn); |
Holger Hans Peter Freyther | a62919e | 2010-11-04 11:59:41 +0100 | [diff] [blame] | 60 | |
| 61 | LOGP(DMSC, LOGL_DEBUG, "CIPHER MODE COMPLETE from MS, forwarding to MSC\n"); |
| 62 | resp = gsm0808_create_cipher_complete(msg, chosen_encr); |
Holger Hans Peter Freyther | 5f2184c | 2010-11-05 11:02:28 +0100 | [diff] [blame] | 63 | queue_msg_or_return(resp); |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 64 | } |
| 65 | |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 66 | static int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, |
| 67 | uint16_t chosen_channel) |
| 68 | { |
Holger Hans Peter Freyther | 1b8e90a | 2010-11-05 11:10:46 +0100 | [diff] [blame^] | 69 | if (bsc_create_new_connection(conn, msg, chosen_channel) == 0) |
| 70 | return BSC_API_CONN_POL_ACCEPT; |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 71 | return BSC_API_CONN_POL_REJECT; |
| 72 | } |
| 73 | |
Holger Hans Peter Freyther | 767ff3c | 2010-11-04 12:18:00 +0100 | [diff] [blame] | 74 | static void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 75 | { |
Holger Hans Peter Freyther | 3623d6b | 2010-11-04 12:24:05 +0100 | [diff] [blame] | 76 | struct msgb *resp; |
Holger Hans Peter Freyther | b6d7014 | 2010-11-03 19:03:35 +0100 | [diff] [blame] | 77 | return_when_not_connected(conn); |
Holger Hans Peter Freyther | 3623d6b | 2010-11-04 12:24:05 +0100 | [diff] [blame] | 78 | |
| 79 | resp = gsm0808_create_dtap(msg, link_id); |
Holger Hans Peter Freyther | 5f2184c | 2010-11-05 11:02:28 +0100 | [diff] [blame] | 80 | queue_msg_or_return(resp); |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 81 | } |
| 82 | |
Holger Hans Peter Freyther | 8dd01ef | 2010-11-04 12:06:57 +0100 | [diff] [blame] | 83 | static void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause, |
| 84 | uint8_t chosen_channel, uint8_t encr_alg_id, |
| 85 | uint8_t speech_model) |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 86 | { |
Holger Hans Peter Freyther | 03a61d1 | 2010-11-04 12:09:45 +0100 | [diff] [blame] | 87 | struct msgb *resp; |
Holger Hans Peter Freyther | b6d7014 | 2010-11-03 19:03:35 +0100 | [diff] [blame] | 88 | return_when_not_connected(conn); |
Holger Hans Peter Freyther | 03a61d1 | 2010-11-04 12:09:45 +0100 | [diff] [blame] | 89 | |
| 90 | resp = gsm0808_create_assignment_completed(rr_cause, chosen_channel, |
| 91 | encr_alg_id, speech_model); |
Holger Hans Peter Freyther | 5f2184c | 2010-11-05 11:02:28 +0100 | [diff] [blame] | 92 | queue_msg_or_return(resp); |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 93 | } |
| 94 | |
Holger Hans Peter Freyther | 9ff6568 | 2010-11-05 10:37:17 +0100 | [diff] [blame] | 95 | static void bsc_assign_fail(struct gsm_subscriber_connection *conn, |
| 96 | uint8_t cause, uint8_t *rr_cause) |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 97 | { |
Holger Hans Peter Freyther | cfa3747 | 2010-11-05 10:59:45 +0100 | [diff] [blame] | 98 | struct msgb *resp; |
Holger Hans Peter Freyther | b6d7014 | 2010-11-03 19:03:35 +0100 | [diff] [blame] | 99 | return_when_not_connected(conn); |
Holger Hans Peter Freyther | cfa3747 | 2010-11-05 10:59:45 +0100 | [diff] [blame] | 100 | |
| 101 | resp = gsm0808_create_assignment_failure(cause, rr_cause); |
Holger Hans Peter Freyther | 5f2184c | 2010-11-05 11:02:28 +0100 | [diff] [blame] | 102 | queue_msg_or_return(resp); |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 103 | } |
| 104 | |
Holger Hans Peter Freyther | 0aa55a3 | 2010-11-03 19:01:58 +0100 | [diff] [blame] | 105 | static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause) |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 106 | { |
Holger Hans Peter Freyther | ef2d1bf | 2010-11-04 12:47:06 +0100 | [diff] [blame] | 107 | struct msgb *resp; |
Holger Hans Peter Freyther | b6d7014 | 2010-11-03 19:03:35 +0100 | [diff] [blame] | 108 | return_when_not_connected_val(conn, 1); |
Holger Hans Peter Freyther | ef2d1bf | 2010-11-04 12:47:06 +0100 | [diff] [blame] | 109 | |
| 110 | resp = gsm0808_create_clear_rqst(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE); |
| 111 | if (!resp) { |
| 112 | LOGP(DMSC, LOGL_ERROR, "Failed to allocate response.\n"); |
| 113 | return 0; |
| 114 | } |
| 115 | |
| 116 | bsc_queue_for_msc(conn, resp); |
Holger Hans Peter Freyther | 0aa55a3 | 2010-11-03 19:01:58 +0100 | [diff] [blame] | 117 | return 0; |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 118 | } |
| 119 | |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 120 | static struct bsc_api bsc_handler = { |
| 121 | .sapi_n_reject = bsc_sapi_n_reject, |
| 122 | .cipher_mode_compl = bsc_cipher_mode_compl, |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 123 | .compl_l3 = bsc_compl_l3, |
| 124 | .dtap = bsc_dtap, |
| 125 | .assign_compl = bsc_assign_compl, |
| 126 | .assign_fail = bsc_assign_fail, |
| 127 | .clear_request = bsc_clear_request, |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 128 | }; |
| 129 | |
Holger Hans Peter Freyther | 22e9ac3 | 2010-07-05 16:02:04 +0800 | [diff] [blame] | 130 | struct bsc_api *osmo_bsc_api() |
| 131 | { |
Holger Hans Peter Freyther | 7d23130 | 2010-09-16 17:26:35 +0800 | [diff] [blame] | 132 | return &bsc_handler; |
Holger Hans Peter Freyther | 22e9ac3 | 2010-07-05 16:02:04 +0800 | [diff] [blame] | 133 | } |