Compare commits

...

19 Commits

Author SHA1 Message Date
Holger Hans Peter Freyther
b0ee082bb0 Bump version
Configurable timeout.
2010-05-05 17:52:40 +08:00
Holger Hans Peter Freyther
81f6a4c0bf bsc_msc_ip: Add VTY code for ping/pong timeout. 2010-05-05 17:46:08 +08:00
Holger Hans Peter Freyther
3978de52c1 bsc_msc_ip: Do not send a ping when the timeout is negative 2010-05-05 17:42:32 +08:00
Holger Hans Peter Freyther
7faf692cb7 bsc_msc_ip: Make the ping/pong timeouts configurable
Take the timeouts from the struct.
2010-05-05 17:39:22 +08:00
Holger Hans Peter Freyther
0cf25d5154 nat: Improve log messages. Refer to ip and fd. 2010-05-05 17:03:44 +08:00
Holger Hans Peter Freyther
08db178271 nat: Make ping/pong timeout configurable. 2010-05-05 16:57:38 +08:00
Holger Hans Peter Freyther
936d8c1b64 Work with later libosmocore. 2010-05-03 19:38:01 +08:00
Harald Welte
3170305e56 move gsm48_construct_ra() to libosmocore 2010-05-03 19:36:58 +08:00
Harald Welte
0f3490dd03 'struct gprs_ra_id' is now defined in libosmocore 2010-05-03 19:36:41 +08:00
Holger Hans Peter Freyther
61e5e7bd8b Bump version..
* ping pong and possible crash fix.
2010-05-03 17:27:07 +08:00
Holger Hans Peter Freyther
f7b06fbe0c bsc: Speculative crash fix.
Make sure the sccp_cc_timeout is stopped when we delete the
associated data. There is one crash report that indicates that
we have a pending timer that is inside freed memory.

A crash could have occured when the connection to the MSC was
lost while have unconfirmed connections.
2010-05-03 16:13:02 +08:00
Holger Hans Peter Freyther
45403b1804 nat/bsc: Send PONG on PING, send PING from the BSC too
We do want to send PING/PONG in both ways to have a heartbeat
on the TCP connection. When switching over to SCTP we can rely
on the builtin heartbeat functionality.
2010-05-03 11:51:07 +08:00
Holger Hans Peter Freyther
6782cea4bf nat: Send a IPA PING down the stream and wait for the pong.
We will send a ping every 20 seconds and if we have no pong
within 5 seconds we will close down the BSC connection and
wait for a reconnect. We will start this after having
authenticated the BSC and we stop the timer when destructing
the BSC connection.
2010-05-02 19:31:14 +08:00
Holger Hans Peter Freyther
ec7ecab66f nat: Allow to only show statistics for a given BSC Cfg. 2010-05-02 19:31:14 +08:00
Holger Hans Peter Freyther
d1287e379b nat: Do not allow a BSC to send auth messages twice. 2010-05-02 19:31:13 +08:00
Holger Hans Peter Freyther
3fb44f3e61 nat: Fix vty output for connected BSCs 2010-05-02 19:31:13 +08:00
Holger Hans Peter Freyther
d48bfe0e93 bssap: Store the link_id in the new msgb->cb.
Work with a new version of libosmocore that gets rid of
additional pointers.
2010-05-01 15:22:40 +08:00
Holger Hans Peter Freyther
41cdaf520d remove any reference to 'struct gsm_bts_link' 2010-05-01 15:19:14 +08:00
Harald Welte
f94418a129 gsm_04_11.c: Use msgb->l4h instead of sms->smsh, as the latter is gone 2010-05-01 15:18:37 +08:00
12 changed files with 228 additions and 55 deletions

View File

@@ -1,7 +1,7 @@
dnl Process this file with autoconf to produce a configure script
AC_INIT
AM_INIT_AUTOMAKE(openbsc, 0.3.99.2onwaves)
AM_INIT_AUTOMAKE(openbsc, 0.3.99.5onwaves)
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])

View File

@@ -93,6 +93,10 @@ struct bsc_connection {
/* a timeout node */
struct timer_list id_timeout;
/* pong timeout */
struct timer_list ping_timeout;
struct timer_list pong_timeout;
/* a back pointer */
struct bsc_nat *nat;
};
@@ -210,6 +214,11 @@ struct bsc_nat {
int msc_port;
int first_contact;
/* timeouts */
int auth_timeout;
int ping_timeout;
int pong_timeout;
struct bsc_endpoint *bsc_endpoints;
/* filter */

View File

@@ -85,11 +85,6 @@ typedef int gsm_cbfn(unsigned int hooknum,
struct msgb *msg,
void *data, void *param);
/* communications link with a BTS */
struct gsm_bts_link {
struct gsm_bts *bts;
};
struct sccp_connection;
/* Real authentication information containing Ki */
@@ -678,6 +673,8 @@ struct gsm_network {
char *bsc_token;
char *msc_ip;
int msc_port;
int ping_timeout;
int pong_timeout;
};
#define SMS_HDR_SIZE 128
@@ -779,14 +776,6 @@ const char *bts_gprs_mode_name(enum bts_gprs_mode mode);
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
/* A parsed GPRS routing area */
struct gprs_ra_id {
u_int16_t mnc;
u_int16_t mcc;
u_int16_t lac;
u_int8_t rac;
};
int gsm48_ra_id_by_bts(u_int8_t *buf, struct gsm_bts *bts);
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);

View File

@@ -60,13 +60,17 @@ static struct log_target *stderr_target;
struct gsm_network *bsc_gsmnet = 0;
static const char *config_file = "openbsc.cfg";
static char *msc_address = NULL;
static struct bsc_msc_connection *msc_con;
static struct in_addr local_addr;
static LLIST_HEAD(active_connections);
static struct write_queue mgcp_agent;
static const char *rf_ctl = NULL;
extern int ipacc_rtp_direct;
/* msc handling */
static struct bsc_msc_connection *msc_con;
static struct timer_list msc_ping_timeout;
static struct timer_list msc_pong_timeout;
extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, int, void *), const char *cfg_file);
extern int bsc_shutdown_net(struct gsm_network *net);
@@ -95,6 +99,7 @@ struct bss_sccp_connection_data *bss_sccp_create_data()
void bss_sccp_free_data(struct bss_sccp_connection_data *data)
{
bsc_del_timer(&data->T10);
bsc_del_timer(&data->sccp_cc_timeout);
bsc_del_timer(&data->sccp_it);
if (data->sccp)
bsc_free_queued(data->sccp);
@@ -867,10 +872,54 @@ static void msc_connection_was_lost(struct bsc_msc_connection *msc)
bss_force_close(bss);
}
bsc_del_timer(&msc_ping_timeout);
bsc_del_timer(&msc_pong_timeout);
msc->is_authenticated = 0;
bsc_msc_schedule_connect(msc);
}
static void msc_pong_timeout_cb(void *data)
{
LOGP(DMSC, LOGL_ERROR, "MSC didn't answer PING. Closing connection.\n");
bsc_msc_lost(msc_con);
}
static void send_ping(void)
{
struct msgb *msg;
msg = msgb_alloc_headroom(4096, 128, "ping");
if (!msg) {
LOGP(DMSC, LOGL_ERROR, "Failed to create PING.\n");
return;
}
msg->l2h = msgb_put(msg, 1);
msg->l2h[0] = IPAC_MSGT_PING;
msc_queue_write(msg, IPAC_PROTO_IPACCESS);
}
static void msc_ping_timeout_cb(void *data)
{
if (bsc_gsmnet->ping_timeout < 0)
return;
send_ping();
/* send another ping in 20 seconds */
bsc_schedule_timer(&msc_ping_timeout, bsc_gsmnet->ping_timeout, 0);
/* also start a pong timer */
bsc_schedule_timer(&msc_pong_timeout, bsc_gsmnet->pong_timeout, 0);
}
static void msc_connection_connected(struct bsc_msc_connection *con)
{
msc_ping_timeout_cb(con);
}
/*
* callback with IP access data
*/
@@ -903,6 +952,8 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
initialize_if_needed();
else if (msg->l2h[0] == IPAC_MSGT_ID_GET) {
send_id_get_response(bfd->fd);
} else if (msg->l2h[0] == IPAC_MSGT_PONG) {
bsc_del_timer(&msc_pong_timeout);
}
} else if (hh->proto == IPAC_PROTO_SCCP) {
sccp_system_incoming(msg);
@@ -1131,7 +1182,11 @@ int main(int argc, char **argv)
exit(1);
}
msc_ping_timeout.cb = msc_ping_timeout_cb;
msc_pong_timeout.cb = msc_pong_timeout_cb;
msc_con->connection_loss = msc_connection_was_lost;
msc_con->connected = msc_connection_connected;
msc_con->write_queue.read_cb = ipaccess_a_fd_cb;
msc_con->write_queue.write_cb = msc_sccp_do_write;
bsc_msc_connect(msc_con);

View File

@@ -40,6 +40,8 @@
#define BSSMAP_MSG_SIZE 512
#define BSSMAP_MSG_HEADROOM 128
#define LINK_ID_CB 0
static void bts_queue_send(struct msgb *msg, int link_id);
static void bssmap_free_secondary(struct bss_sccp_connection_data *data);
@@ -1236,7 +1238,7 @@ static void bts_queue_send(struct msgb *msg, int link_id)
if (msg->lchan->sapis[link_id & 0x7] != LCHAN_SAPI_UNUSED) {
rsl_data_request(msg, link_id);
} else {
msg->smsh = (unsigned char*) link_id;
msg->cb[LINK_ID_CB] = link_id;
msgb_enqueue(&data->gsm_queue, msg);
++data->gsm_queue_size;
@@ -1252,7 +1254,7 @@ static void bts_queue_send(struct msgb *msg, int link_id)
LOGP(DMSC, LOGL_DEBUG, "Queueing GSM0408 message on %p. Queue size: %d\n",
data->sccp, data->gsm_queue_size + 1);
msg->smsh = (unsigned char*) link_id;
msg->cb[LINK_ID_CB] = link_id;
msgb_enqueue(&data->gsm_queue, msg);
++data->gsm_queue_size;
}
@@ -1278,7 +1280,7 @@ void bts_send_queued(struct bss_sccp_connection_data *data)
while (!llist_empty(&data->gsm_queue)) {
/* this is not allowed to fail */
msg = msgb_dequeue(&data->gsm_queue);
rsl_data_request(msg, (int) msg->smsh);
rsl_data_request(msg, msg->cb[LINK_ID_CB]);
}
data->gsm_queue_size = 0;
@@ -1300,7 +1302,7 @@ void bts_unblock_queue(struct bss_sccp_connection_data *data)
/* now queue them again to send RSL establish and such */
while (!llist_empty(&head)) {
msg = msgb_dequeue(&head);
bts_queue_send(msg, (int) msg->smsh);
bts_queue_send(msg, msg->cb[LINK_ID_CB]);
}
}

View File

@@ -675,7 +675,7 @@ static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans,
GSM411_RP_CAUSE_INV_MAND_INF);
return -EIO;
}
msg->smsh = tpdu;
msg->l4h = tpdu;
DEBUGP(DSMS, "DST(%u,%s)\n", dst_len, hexdump(dst, dst_len));

View File

@@ -257,7 +257,6 @@ int gsm0480_send_ussd_response(const struct msgb *in_msg, const char *response_t
if (((strlen(response_text) * 7) % 8) != 0)
response_len += 1;
msg->bts_link = in_msg->bts_link;
msg->lchan = in_msg->lchan;
/* First put the payload text into the message */
@@ -304,7 +303,6 @@ int gsm0480_send_ussd_reject(const struct msgb *in_msg,
struct msgb *msg = gsm48_msgb_alloc();
struct gsm48_hdr *gh;
msg->bts_link = in_msg->bts_link;
msg->lchan = in_msg->lchan;
/* First insert the problem code */

View File

@@ -300,6 +300,8 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c
net->msc_ip = talloc_strdup(net, "127.0.0.1");
net->msc_port = 5000;
net->ping_timeout = 20;
net->pong_timeout = 5;
return net;
}
@@ -454,33 +456,6 @@ const char *gsm_auth_policy_name(enum gsm_auth_policy policy)
return get_value_string(auth_policy_names, policy);
}
/* this should not be here but in gsm_04_08... but that creates
in turn a dependency nightmare (abis_nm depending on 04_08, ...) */
static int gsm48_construct_ra(u_int8_t *buf, const struct gprs_ra_id *raid)
{
u_int16_t mcc = raid->mcc;
u_int16_t mnc = raid->mnc;
buf[0] = ((mcc / 100) % 10) | (((mcc / 10) % 10) << 4);
buf[1] = (mcc % 10);
/* I wonder who came up with the stupidity of encoding the MNC
* differently depending on how many digits its decimal number has! */
if (mnc < 100) {
buf[1] |= 0xf0;
buf[2] = ((mnc / 10) % 10) | ((mnc % 10) << 4);
} else {
buf[1] |= (mnc % 10) << 4;
buf[2] = ((mnc / 100) % 10) | (((mcc / 10) % 10) << 4);
}
*(u_int16_t *)(buf+3) = htons(raid->lac);
buf[5] = raid->rac;
return 6;
}
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts)
{
raid->mcc = bts->network->country_code;

View File

@@ -108,6 +108,58 @@ static void send_reset_ack(struct bsc_connection *bsc)
bsc_send_data(bsc, gsm_reset_ack, sizeof(gsm_reset_ack), IPAC_PROTO_SCCP);
}
static void send_ping(struct bsc_connection *bsc)
{
static const u_int8_t id_ping[] = {
IPAC_MSGT_PING,
};
bsc_send_data(bsc, id_ping, sizeof(id_ping), IPAC_PROTO_IPACCESS);
}
static void send_pong(struct bsc_connection *bsc)
{
static const u_int8_t id_pong[] = {
IPAC_MSGT_PONG,
};
bsc_send_data(bsc, id_pong, sizeof(id_pong), IPAC_PROTO_IPACCESS);
}
static void bsc_pong_timeout(void *_bsc)
{
struct bsc_connection *bsc = _bsc;
LOGP(DNAT, LOGL_ERROR, "BSC Nr: %d PONG timeout.\n", bsc->cfg->nr);
bsc_close_connection(bsc);
}
static void bsc_ping_timeout(void *_bsc)
{
struct bsc_connection *bsc = _bsc;
if (bsc->nat->ping_timeout < 0)
return;
send_ping(bsc);
/* send another ping in 20 seconds */
bsc_schedule_timer(&bsc->ping_timeout, bsc->nat->ping_timeout, 0);
/* also start a pong timer */
bsc_schedule_timer(&bsc->pong_timeout, bsc->nat->pong_timeout, 0);
}
static void start_ping_pong(struct bsc_connection *bsc)
{
bsc->pong_timeout.data = bsc;
bsc->pong_timeout.cb = bsc_pong_timeout;
bsc->ping_timeout.data = bsc;
bsc->ping_timeout.cb = bsc_ping_timeout;
bsc_ping_timeout(bsc);
}
static void send_id_ack(struct bsc_connection *bsc)
{
static const u_int8_t id_ack[] = {
@@ -437,6 +489,8 @@ void bsc_close_connection(struct bsc_connection *connection)
/* stop the timeout timer */
bsc_del_timer(&connection->id_timeout);
bsc_del_timer(&connection->ping_timeout);
bsc_del_timer(&connection->pong_timeout);
/* remove all SCCP connections */
llist_for_each_entry_safe(sccp_patch, tmp, &nat->sccp_connections, list_entry) {
@@ -477,18 +531,27 @@ static void ipaccess_auth_bsc(struct tlv_parsed *tvp, struct bsc_connection *bsc
struct bsc_config *conf;
const char* token = (const char *) TLVP_VAL(tvp, IPAC_IDTAG_UNITNAME);
if (bsc->cfg) {
LOGP(DNAT, LOGL_ERROR, "Reauth on fd %d bsc nr %d\n",
bsc->write_queue.bfd.fd, bsc->cfg->nr);
return;
}
llist_for_each_entry(conf, &bsc->nat->bsc_configs, entry) {
if (strcmp(conf->token, token) == 0) {
counter_inc(conf->stats.net.reconn);
bsc->authenticated = 1;
bsc->cfg = conf;
bsc_del_timer(&bsc->id_timeout);
LOGP(DNAT, LOGL_NOTICE, "Authenticated bsc nr: %d lac: %d\n", conf->nr, conf->lac);
LOGP(DNAT, LOGL_NOTICE, "Authenticated bsc nr: %d lac: %d on fd %d\n",
conf->nr, conf->lac, bsc->write_queue.bfd.fd);
start_ping_pong(bsc);
return;
}
}
LOGP(DNAT, LOGL_ERROR, "No bsc found for token %s.\n", token);
LOGP(DNAT, LOGL_ERROR, "No bsc found for token %s on fd: %d.\n", token,
bsc->write_queue.bfd.fd);
}
static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg)
@@ -597,6 +660,7 @@ static int ipaccess_bsc_read_cb(struct bsc_fd *bfd)
int error;
struct bsc_connection *bsc = bfd->data;
struct msgb *msg = ipaccess_read_msg(bfd, &error);
struct ipaccess_head *hh;
if (!msg) {
if (error == 0)
@@ -616,6 +680,21 @@ static int ipaccess_bsc_read_cb(struct bsc_fd *bfd)
LOGP(DNAT, LOGL_DEBUG, "MSG from BSC: %s proto: %d\n", hexdump(msg->data, msg->len), msg->l2h[0]);
/* Handle messages from the BSC */
hh = (struct ipaccess_head *) msg->data;
/* stop the pong timeout */
if (hh->proto == IPAC_PROTO_IPACCESS) {
if (msg->l2h[0] == IPAC_MSGT_PONG) {
bsc_del_timer(&bsc->pong_timeout);
msgb_free(msg);
return 0;
} else if (msg->l2h[0] == IPAC_MSGT_PING) {
send_pong(bsc);
msgb_free(msg);
return 0;
}
}
/* FIXME: Currently no PONG is sent to the BSC */
/* FIXME: Currently no ID ACK is sent to the BSC */
forward_sccp_to_msc(bsc, msg);
@@ -687,7 +766,8 @@ static int ipaccess_listen_bsc_cb(struct bsc_fd *bfd, unsigned int what)
return -2;
}
LOGP(DNAT, LOGL_NOTICE, "Registered new BSC\n");
LOGP(DNAT, LOGL_NOTICE, "BSC connection on %d with IP: %s\n",
ret, inet_ntoa(sa.sin_addr));
llist_add(&bsc->list_entry, &nat->bsc_connections);
send_id_ack(bsc);
send_id_req(bsc);
@@ -698,7 +778,7 @@ static int ipaccess_listen_bsc_cb(struct bsc_fd *bfd, unsigned int what)
*/
bsc->id_timeout.data = bsc;
bsc->id_timeout.cb = ipaccess_close_bsc;
bsc_schedule_timer(&bsc->id_timeout, 2, 0);
bsc_schedule_timer(&bsc->id_timeout, nat->auth_timeout, 0);
return 0;
}

View File

@@ -53,6 +53,9 @@ struct bsc_nat *bsc_nat_alloc(void)
nat->stats.msc.reconn = counter_alloc("nat.msc.conn");
nat->msc_ip = talloc_strdup(nat, "127.0.0.1");
nat->msc_port = 5000;
nat->auth_timeout = 2;
nat->ping_timeout = 20;
nat->pong_timeout = 5;
return nat;
}

View File

@@ -57,6 +57,9 @@ static int config_write_nat(struct vty *vty)
vty_out(vty, " insi deny %s%s", _nat->imsi_deny, VTY_NEWLINE);
vty_out(vty, " msc ip %s%s", _nat->msc_ip, VTY_NEWLINE);
vty_out(vty, " msc port %d%s", _nat->msc_port, VTY_NEWLINE);
vty_out(vty, " timeout auth %d%s", _nat->auth_timeout, VTY_NEWLINE);
vty_out(vty, " timeout ping %d%s", _nat->ping_timeout, VTY_NEWLINE);
vty_out(vty, " timeout pong %d%s", _nat->pong_timeout, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -112,7 +115,7 @@ DEFUN(show_bsc, show_bsc_cmd, "show bsc connections",
llist_for_each_entry(con, &_nat->bsc_connections, list_entry) {
getpeername(con->write_queue.bfd.fd, (struct sockaddr *) &sock, &len);
vty_out(vty, "BSC lac: %d, %d auth: %d fd: %d peername: %s%s",
vty_out(vty, "BSC nr: %d lac: %d auth: %d fd: %d peername: %s%s",
con->cfg ? con->cfg->nr : -1,
con->cfg ? con->cfg->lac : -1,
con->authenticated, con->write_queue.bfd.fd,
@@ -142,11 +145,16 @@ DEFUN(show_bsc_cfg, show_bsc_cfg_cmd, "show bsc config",
DEFUN(show_stats,
show_stats_cmd,
"show statistics",
"show statistics [NR]",
SHOW_STR "Display network statistics")
{
struct bsc_config *conf;
int nr = -1;
if (argc == 1)
nr = atoi(argv[0]);
vty_out(vty, "NAT statistics%s", VTY_NEWLINE);
vty_out(vty, " SCCP Connections %lu total, %lu calls%s",
counter_get(_nat->stats.sccp.conn),
@@ -158,6 +166,9 @@ DEFUN(show_stats,
counter_get(_nat->stats.bsc.auth_fail), VTY_NEWLINE);
llist_for_each_entry(conf, &_nat->bsc_configs, entry) {
if (argc == 1 && nr != conf->nr)
continue;
vty_out(vty, " BSC lac: %d nr: %d%s",
conf->lac, conf->nr, VTY_NEWLINE);
vty_out(vty, " SCCP Connnections %lu total, %lu calls%s",
@@ -248,6 +259,33 @@ DEFUN(cfg_nat_msc_port,
return CMD_SUCCESS;
}
DEFUN(cfg_nat_auth_time,
cfg_nat_auth_time_cmd,
"timeout auth <1-256>",
"The time to wait for an auth response.")
{
_nat->auth_timeout = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_nat_ping_time,
cfg_nat_ping_time_cmd,
"timeout ping NR",
"Send a ping every NR seconds. Negative to disable.")
{
_nat->ping_timeout = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_nat_pong_time,
cfg_nat_pong_time_cmd,
"timeout pong NR",
"Wait NR seconds for the PONG response. Should be smaller than ping.")
{
_nat->pong_timeout = atoi(argv[0]);
return CMD_SUCCESS;
}
/* per BSC configuration */
DEFUN(cfg_bsc, cfg_bsc_cmd, "bsc BSC_NR", "Select a BSC to configure")
{
@@ -379,6 +417,9 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
install_element(NAT_NODE, &cfg_nat_imsi_deny_cmd);
install_element(NAT_NODE, &cfg_nat_msc_ip_cmd);
install_element(NAT_NODE, &cfg_nat_msc_port_cmd);
install_element(NAT_NODE, &cfg_nat_auth_time_cmd);
install_element(NAT_NODE, &cfg_nat_ping_time_cmd);
install_element(NAT_NODE, &cfg_nat_pong_time_cmd);
/* BSC subgroups */
install_element(NAT_NODE, &cfg_bsc_cmd);

View File

@@ -480,6 +480,8 @@ static int config_write_net(struct vty *vty)
vty_out(vty, " bsc_token %s%s", gsmnet->bsc_token, VTY_NEWLINE);
vty_out(vty, " msc ip %s%s", gsmnet->msc_ip, VTY_NEWLINE);
vty_out(vty, " msc port %d%s", gsmnet->msc_port, VTY_NEWLINE);
vty_out(vty, " timeout ping %d%s", gsmnet->ping_timeout, VTY_NEWLINE);
vty_out(vty, " timeout pong %d%s", gsmnet->pong_timeout, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1335,6 +1337,23 @@ DEFUN(cfg_net_msc_port,
return CMD_SUCCESS;
}
DEFUN(cfg_net_ping_time,
cfg_net_ping_time_cmd,
"timeout ping NR",
"Set the PING interval, negative for not sending PING")
{
gsmnet->ping_timeout = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_net_pong_time,
cfg_net_pong_time_cmd,
"timeout pong NR",
"Set the time to wait for a PONG.")
{
gsmnet->pong_timeout = atoi(argv[0]);
return CMD_SUCCESS;
}
#define DECLARE_TIMER(number, doc) \
DEFUN(cfg_net_T##number, \
@@ -2070,6 +2089,8 @@ int bsc_vty_init(struct gsm_network *net)
install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
install_element(GSMNET_NODE, &cfg_net_msc_ip_cmd);
install_element(GSMNET_NODE, &cfg_net_msc_port_cmd);
install_element(GSMNET_NODE, &cfg_net_ping_time_cmd);
install_element(GSMNET_NODE, &cfg_net_pong_time_cmd);
install_element(GSMNET_NODE, &cfg_bts_cmd);
install_node(&bts_node, config_write_bts);