Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 1 | /* A Media Gateway Control Protocol Media Gateway: RFC 3435 */ |
| 2 | /* The protocol implementation */ |
| 3 | |
| 4 | /* |
| 5 | * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org> |
| 6 | * (C) 2009-2010 by On-Waves |
| 7 | * All Rights Reserved |
| 8 | * |
Holger Hans Peter Freyther | de56c22 | 2011-01-16 17:45:14 +0100 | [diff] [blame] | 9 | * This program is free software: you can redistribute it and/or modify |
| 10 | * it under the terms of the GNU Affero General Public License as published by |
| 11 | * the Free Software Foundation, either version 3 of the License, or |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 12 | * (at your option) any later version. |
| 13 | * |
| 14 | * This program is distributed in the hope that it will be useful, |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
Holger Hans Peter Freyther | de56c22 | 2011-01-16 17:45:14 +0100 | [diff] [blame] | 17 | * GNU Affero General Public License for more details. |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 18 | * |
Holger Hans Peter Freyther | de56c22 | 2011-01-16 17:45:14 +0100 | [diff] [blame] | 19 | * You should have received a copy of the GNU Affero General Public License |
| 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 21 | * |
| 22 | */ |
| 23 | |
| 24 | #include <sys/types.h> |
| 25 | |
| 26 | #include <cellmgr_debug.h> |
| 27 | |
| 28 | #include <mgcp/mgcp.h> |
| 29 | #include <mgcp/mgcp_internal.h> |
Holger Hans Peter Freyther | 5fb3057 | 2010-08-06 15:56:01 +0000 | [diff] [blame] | 30 | #include <mgcp_ss7.h> |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 31 | |
| 32 | #include <osmocore/talloc.h> |
| 33 | |
| 34 | #include <osmocom/vty/command.h> |
| 35 | #include <osmocom/vty/vty.h> |
| 36 | |
| 37 | #include <string.h> |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 38 | #include <netdb.h> |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 39 | |
| 40 | static struct mgcp_config *g_cfg = NULL; |
| 41 | |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 42 | /* |
| 43 | * vty code for mgcp below |
| 44 | */ |
| 45 | static struct cmd_node mgcp_node = { |
| 46 | MGCP_NODE, |
| 47 | "%s(mgcp)#", |
| 48 | 1, |
| 49 | }; |
| 50 | |
Holger Hans Peter Freyther | ed30463 | 2010-10-27 19:32:53 +0200 | [diff] [blame] | 51 | extern void mgcp_write_extra(struct vty *vty); |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 52 | static int config_write_mgcp(struct vty *vty) |
| 53 | { |
| 54 | vty_out(vty, "mgcp%s", VTY_NEWLINE); |
| 55 | if (g_cfg->local_ip) |
| 56 | vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE); |
| 57 | if (g_cfg->bts_ip && strlen(g_cfg->bts_ip) != 0) |
Holger Hans Peter Freyther | a174318 | 2010-08-04 07:28:39 +0800 | [diff] [blame] | 58 | vty_out(vty, " mgw ip %s%s", g_cfg->bts_ip, VTY_NEWLINE); |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 59 | vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE); |
| 60 | vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE); |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 61 | vty_out(vty, " rtp base %u%s", g_cfg->rtp_base_port, VTY_NEWLINE); |
| 62 | vty_out(vty, " rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE); |
| 63 | if (g_cfg->audio_payload != -1) |
| 64 | vty_out(vty, " sdp audio payload number %d%s", g_cfg->audio_payload, VTY_NEWLINE); |
| 65 | if (g_cfg->audio_name) |
| 66 | vty_out(vty, " sdp audio payload name %s%s", g_cfg->audio_name, VTY_NEWLINE); |
| 67 | vty_out(vty, " loop %u%s", !!g_cfg->audio_loop, VTY_NEWLINE); |
| 68 | vty_out(vty, " number endpoints %u%s", g_cfg->number_endpoints - 1, VTY_NEWLINE); |
Holger Hans Peter Freyther | ed30463 | 2010-10-27 19:32:53 +0200 | [diff] [blame] | 69 | mgcp_write_extra(vty); |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 70 | |
| 71 | return CMD_SUCCESS; |
| 72 | } |
| 73 | |
| 74 | DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp", |
| 75 | SHOW_STR "Display information about the MGCP Media Gateway") |
| 76 | { |
| 77 | int i; |
| 78 | |
| 79 | vty_out(vty, "MGCP is up and running with %u endpoints:%s", g_cfg->number_endpoints - 1, VTY_NEWLINE); |
| 80 | for (i = 1; i < g_cfg->number_endpoints; ++i) { |
| 81 | struct mgcp_endpoint *endp = &g_cfg->endpoints[i]; |
| 82 | vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s traffic received bts: %u/%u remote: %u/%u%s", |
| 83 | i, endp->ci, |
| 84 | ntohs(endp->net_rtp), ntohs(endp->net_rtcp), |
| 85 | ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp), |
| 86 | inet_ntoa(endp->bts), endp->in_bts, endp->bts_state.lost_no, |
| 87 | endp->in_remote, endp->net_state.lost_no, |
| 88 | VTY_NEWLINE); |
| 89 | } |
| 90 | |
| 91 | return CMD_SUCCESS; |
| 92 | } |
| 93 | |
| 94 | DEFUN(cfg_mgcp, |
| 95 | cfg_mgcp_cmd, |
| 96 | "mgcp", |
| 97 | "Configure the MGCP") |
| 98 | { |
| 99 | vty->node = MGCP_NODE; |
| 100 | return CMD_SUCCESS; |
| 101 | } |
| 102 | |
| 103 | DEFUN(cfg_mgcp_local_ip, |
| 104 | cfg_mgcp_local_ip_cmd, |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 105 | "local ip IP", |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 106 | "Set the IP to be used in SDP records") |
| 107 | { |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 108 | struct hostent *hosts; |
| 109 | struct in_addr *addr; |
| 110 | |
| 111 | hosts = gethostbyname(argv[0]); |
| 112 | if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) { |
| 113 | vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE); |
| 114 | return CMD_WARNING; |
| 115 | } |
| 116 | |
| 117 | addr = (struct in_addr *) hosts->h_addr_list[0]; |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 118 | if (g_cfg->local_ip) |
| 119 | talloc_free(g_cfg->local_ip); |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 120 | g_cfg->local_ip = talloc_strdup(g_cfg, inet_ntoa(*addr)); |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 121 | return CMD_SUCCESS; |
| 122 | } |
| 123 | |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 124 | DEFUN(cfg_mgcp_mgw_ip, |
| 125 | cfg_mgcp_mgw_ip_cmd, |
| 126 | "mgw ip IP", |
| 127 | "Set the IP of the MGW for RTP forwarding") |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 128 | { |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 129 | struct hostent *hosts; |
| 130 | struct in_addr *addr; |
| 131 | |
| 132 | hosts = gethostbyname(argv[0]); |
| 133 | if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) { |
| 134 | vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE); |
| 135 | return CMD_WARNING; |
| 136 | } |
| 137 | |
| 138 | addr = (struct in_addr *) hosts->h_addr_list[0]; |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 139 | if (g_cfg->bts_ip) |
| 140 | talloc_free(g_cfg->bts_ip); |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 141 | g_cfg->bts_ip = talloc_strdup(g_cfg, inet_ntoa(*addr)); |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 142 | inet_aton(g_cfg->bts_ip, &g_cfg->bts_in); |
| 143 | return CMD_SUCCESS; |
| 144 | } |
| 145 | |
| 146 | DEFUN(cfg_mgcp_bind_ip, |
| 147 | cfg_mgcp_bind_ip_cmd, |
| 148 | "bind ip A.B.C.D", |
| 149 | "Bind the MGCP to this local addr") |
| 150 | { |
| 151 | if (g_cfg->source_addr) |
| 152 | talloc_free(g_cfg->source_addr); |
| 153 | g_cfg->source_addr = talloc_strdup(g_cfg, argv[0]); |
| 154 | return CMD_SUCCESS; |
| 155 | } |
| 156 | |
| 157 | DEFUN(cfg_mgcp_bind_port, |
| 158 | cfg_mgcp_bind_port_cmd, |
| 159 | "bind port <0-65534>", |
| 160 | "Bind the MGCP to this port") |
| 161 | { |
| 162 | unsigned int port = atoi(argv[0]); |
| 163 | g_cfg->source_port = port; |
| 164 | return CMD_SUCCESS; |
| 165 | } |
| 166 | |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 167 | DEFUN(cfg_mgcp_rtp_base_port, |
| 168 | cfg_mgcp_rtp_base_port_cmd, |
| 169 | "rtp base <0-65534>", |
| 170 | "Base port to use") |
| 171 | { |
| 172 | unsigned int port = atoi(argv[0]); |
| 173 | g_cfg->rtp_base_port = port; |
| 174 | return CMD_SUCCESS; |
| 175 | } |
| 176 | |
| 177 | DEFUN(cfg_mgcp_rtp_ip_dscp, |
| 178 | cfg_mgcp_rtp_ip_dscp_cmd, |
| 179 | "rtp ip-dscp <0-255>", |
| 180 | "Set the IP_TOS socket attribute on the RTP/RTCP sockets.\n" "The DSCP value.") |
| 181 | { |
| 182 | int dscp = atoi(argv[0]); |
| 183 | g_cfg->endp_dscp = dscp; |
| 184 | return CMD_SUCCESS; |
| 185 | } |
| 186 | |
| 187 | ALIAS_DEPRECATED(cfg_mgcp_rtp_ip_dscp, cfg_mgcp_rtp_ip_tos_cmd, |
| 188 | "rtp ip-tos <0-255>", |
| 189 | "Set the IP_TOS socket attribute on the RTP/RTCP sockets.\n" "The DSCP value.") |
| 190 | |
| 191 | |
| 192 | DEFUN(cfg_mgcp_sdp_payload_number, |
| 193 | cfg_mgcp_sdp_payload_number_cmd, |
| 194 | "sdp audio payload number <1-255>", |
| 195 | "Set the audio codec to use") |
| 196 | { |
| 197 | unsigned int payload = atoi(argv[0]); |
| 198 | g_cfg->audio_payload = payload; |
| 199 | return CMD_SUCCESS; |
| 200 | } |
| 201 | |
| 202 | DEFUN(cfg_mgcp_sdp_payload_name, |
| 203 | cfg_mgcp_sdp_payload_name_cmd, |
| 204 | "sdp audio payload name NAME", |
| 205 | "Set the audio name to use") |
| 206 | { |
| 207 | if (g_cfg->audio_name) |
| 208 | talloc_free(g_cfg->audio_name); |
| 209 | g_cfg->audio_name = talloc_strdup(g_cfg, argv[0]); |
| 210 | return CMD_SUCCESS; |
| 211 | } |
| 212 | |
| 213 | DEFUN(cfg_mgcp_loop, |
| 214 | cfg_mgcp_loop_cmd, |
| 215 | "loop (0|1)", |
| 216 | "Loop the audio") |
| 217 | { |
| 218 | g_cfg->audio_loop = atoi(argv[0]); |
| 219 | return CMD_SUCCESS; |
| 220 | } |
| 221 | |
| 222 | DEFUN(cfg_mgcp_number_endp, |
| 223 | cfg_mgcp_number_endp_cmd, |
| 224 | "number endpoints <0-65534>", |
| 225 | "The number of endpoints to allocate. This is not dynamic.") |
| 226 | { |
| 227 | /* + 1 as we start counting at one */ |
| 228 | g_cfg->number_endpoints = atoi(argv[0]) + 1; |
| 229 | return CMD_SUCCESS; |
| 230 | } |
| 231 | |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 232 | DEFUN(loop_endp, |
| 233 | loop_endp_cmd, |
| 234 | "loop-endpoint NAME (0|1)", |
| 235 | "Loop a given endpoint\n" |
| 236 | "The name in hex of the endpoint\n" "Disable the loop\n" "Enable the loop\n") |
| 237 | { |
| 238 | struct mgcp_endpoint *endp; |
| 239 | |
| 240 | int endp_no = strtoul(argv[0], NULL, 16); |
| 241 | if (endp_no < 1 || endp_no >= g_cfg->number_endpoints) { |
| 242 | vty_out(vty, "Loopback number %s/%d is invalid.%s", |
| 243 | argv[0], endp_no, VTY_NEWLINE); |
| 244 | return CMD_WARNING; |
| 245 | } |
| 246 | |
| 247 | |
| 248 | endp = &g_cfg->endpoints[endp_no]; |
| 249 | int loop = atoi(argv[1]); |
| 250 | |
| 251 | if (loop) |
| 252 | endp->conn_mode = MGCP_CONN_LOOPBACK; |
| 253 | else |
| 254 | endp->conn_mode = endp->orig_mode; |
| 255 | |
| 256 | return CMD_SUCCESS; |
| 257 | } |
| 258 | |
| 259 | DEFUN(ournode_exit, |
| 260 | ournode_exit_cmd, "exit", "Exit current mode and down to previous node\n") |
| 261 | { |
| 262 | switch (vty->node) { |
| 263 | case MGCP_NODE: |
| 264 | vty->node = CONFIG_NODE; |
| 265 | vty->index = NULL; |
| 266 | break; |
| 267 | } |
| 268 | |
| 269 | return CMD_SUCCESS; |
| 270 | } |
| 271 | |
| 272 | DEFUN(ournode_end, |
| 273 | ournode_end_cmd, "end", "End current mode and change to enable mode.") |
| 274 | { |
| 275 | switch (vty->node) { |
| 276 | case VIEW_NODE: |
| 277 | case ENABLE_NODE: |
| 278 | break; |
| 279 | case MGCP_NODE: |
| 280 | vty_config_unlock(vty); |
| 281 | vty->node = ENABLE_NODE; |
| 282 | vty->index = NULL; |
| 283 | vty->index_sub = NULL; |
| 284 | break; |
| 285 | } |
| 286 | |
| 287 | return CMD_SUCCESS; |
| 288 | } |
| 289 | |
| 290 | int mgcp_vty_init(void) |
| 291 | { |
| 292 | install_element_ve(&show_mgcp_cmd); |
| 293 | install_element(ENABLE_NODE, &loop_endp_cmd); |
| 294 | |
| 295 | install_element(CONFIG_NODE, &cfg_mgcp_cmd); |
| 296 | install_node(&mgcp_node, config_write_mgcp); |
| 297 | |
| 298 | install_default(MGCP_NODE); |
| 299 | install_element(MGCP_NODE, &ournode_exit_cmd); |
| 300 | install_element(MGCP_NODE, &ournode_end_cmd); |
| 301 | install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd); |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 302 | install_element(MGCP_NODE, &cfg_mgcp_mgw_ip_cmd); |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 303 | install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd); |
| 304 | install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd); |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 305 | install_element(MGCP_NODE, &cfg_mgcp_rtp_base_port_cmd); |
| 306 | install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd); |
| 307 | install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd); |
| 308 | install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd); |
| 309 | install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd); |
| 310 | install_element(MGCP_NODE, &cfg_mgcp_loop_cmd); |
| 311 | install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd); |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 312 | |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 313 | return 0; |
| 314 | } |
| 315 | |
Holger Hans Peter Freyther | e807376 | 2010-08-04 07:34:21 +0800 | [diff] [blame] | 316 | void mgcp_vty_set_config(struct mgcp_config *cfg) |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 317 | { |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 318 | g_cfg = cfg; |
Holger Hans Peter Freyther | fde865f | 2010-08-04 06:39:13 +0800 | [diff] [blame] | 319 | } |