From 88c6eeaa7d117dc270da1c29c131e192c0b49c8c Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 1 Mar 2010 18:52:04 +0100 Subject: [mgcp] Set the right variable back to NULL --- openbsc/src/mgcp/mgcp_protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index f7ef5470d..a825e92f5 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -732,7 +732,7 @@ void mgcp_free_endp(struct mgcp_endpoint *endp) if (endp->local_options) { talloc_free(endp->local_options); - endp->callid = NULL; + endp->local_options = NULL; } if (!endp->cfg->early_bind) { -- cgit v1.2.3 From 774f0723bf74448288b061502a03095b7c425dff Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 1 Mar 2010 18:53:05 +0100 Subject: [mgcp] Do not print potentially many messages... --- openbsc/src/mgcp/mgcp_network.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c index b76ca4732..924e6fc44 100644 --- a/openbsc/src/mgcp/mgcp_network.c +++ b/openbsc/src/mgcp/mgcp_network.c @@ -125,10 +125,8 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what) } /* do not forward aynthing... maybe there is a packet from the bts */ - if (endp->ci == CI_UNUSED) { - LOGP(DMGCP, LOGL_ERROR, "Unknown message on endpoint: 0x%x\n", ENDPOINT_NUMBER(endp)); + if (endp->ci == CI_UNUSED) return -1; - } /* * Figure out where to forward it to. This code assumes that we -- cgit v1.2.3 From c38b5884ff7c61b3e4e357ad8c4b8c6960834cde Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 30 Mar 2010 12:43:33 +0200 Subject: [mgcp] Fix format string usage --- openbsc/src/mgcp/mgcp_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c index 147a765f0..6369fee0a 100644 --- a/openbsc/src/mgcp/mgcp_main.c +++ b/openbsc/src/mgcp/mgcp_main.c @@ -77,7 +77,7 @@ static void print_help() static void print_version() { printf("%s\n\n", openbsc_version); - printf(openbsc_copyright); + printf("%s", openbsc_copyright); } static void handle_options(int argc, char** argv) -- cgit v1.2.3 From f5b6aa60ce3b74ba615d75e6a8e88b78d84345b1 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 30 Mar 2010 12:43:53 +0200 Subject: [mgcp] Move mgcp init into the main method... --- openbsc/src/mgcp/mgcp_main.c | 17 +++++++++++++++-- openbsc/src/mgcp/mgcp_vty.c | 10 ---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c index 6369fee0a..6210e5941 100644 --- a/openbsc/src/mgcp/mgcp_main.c +++ b/openbsc/src/mgcp/mgcp_main.c @@ -40,6 +40,8 @@ #include #include +#include + #include "../../bscconfig.h" /* this is here for the vty... it will never be called */ @@ -74,7 +76,7 @@ static void print_help() printf(" -c --config-file filename The config file to use.\n"); } -static void print_version() +static void print_mgcp_version() { printf("%s\n\n", openbsc_version); printf("%s", openbsc_copyright); @@ -105,7 +107,7 @@ static void handle_options(int argc, char** argv) config_file = talloc_strdup(tall_bsc_ctx, optarg); break; case 'V': - print_version(); + print_mgcp_version(); exit(0); break; default: @@ -235,3 +237,14 @@ int main(int argc, char** argv) return 0; } + +struct gsm_network; +int bsc_vty_init(struct gsm_network *dummy) +{ + cmd_init(1); + vty_init(); + + mgcp_vty_init(); + return 0; +} + diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c index f13b3cfa7..ac8e873d3 100644 --- a/openbsc/src/mgcp/mgcp_vty.c +++ b/openbsc/src/mgcp/mgcp_vty.c @@ -327,13 +327,3 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg) return !!g_cfg->forward_ip; } -struct gsm_network; -int bsc_vty_init(struct gsm_network *dummy) -{ - cmd_init(1); - vty_init(); - - mgcp_vty_init(); - return 0; -} - -- cgit v1.2.3 From 95e4d34f06567521087121fb5fbdc0f9c9d48ae7 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 30 Mar 2010 13:00:10 +0200 Subject: [mgcp] The networking code needs a source addrs.. Make the source address mandantory and complain about complain when it is missing. The address is mandantory as it needs to be put into the MGCP messages... --- openbsc/src/mgcp/mgcp_vty.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c index ac8e873d3..6773d889f 100644 --- a/openbsc/src/mgcp/mgcp_vty.c +++ b/openbsc/src/mgcp/mgcp_vty.c @@ -274,6 +274,11 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg) if (!g_cfg->bts_ip) fprintf(stderr, "No BTS ip address specified. This will allow everyone to connect.\n"); + if (!g_cfg->source_addr) { + fprintf(stderr, "You need to specify a bind address.\n"); + return -1; + } + if (mgcp_endpoints_allocate(g_cfg) != 0) { fprintf(stderr, "Failed to allocate endpoints: %d. Quitting.\n", g_cfg->number_endpoints); return -1; -- cgit v1.2.3 From b71517f07ec46558bc6032bdaa27650f8bef634d Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 5 Apr 2010 18:13:40 +0200 Subject: [sccp] Add a force_free method for connections E.g. when the underlying connection transport medium is gone one needs to force to close SCCP connections, add this helper. It will remove the connection from the list of connections and it will free the data. --- openbsc/include/sccp/sccp.h | 5 +++++ openbsc/src/sccp/sccp.c | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/openbsc/include/sccp/sccp.h b/openbsc/include/sccp/sccp.h index 2e1478812..604a2ac72 100644 --- a/openbsc/include/sccp/sccp.h +++ b/openbsc/include/sccp/sccp.h @@ -105,6 +105,11 @@ int sccp_connection_send_it(struct sccp_connection *connection); int sccp_connection_close(struct sccp_connection *connection, int cause); int sccp_connection_free(struct sccp_connection *connection); +/** + * internal.. + */ +int sccp_connection_force_free(struct sccp_connection *conn); + /** * Create a new socket. Set your callbacks and then call bind to open * the connection. diff --git a/openbsc/src/sccp/sccp.c b/openbsc/src/sccp/sccp.c index 4bd87c8ed..e0fd02e0e 100644 --- a/openbsc/src/sccp/sccp.c +++ b/openbsc/src/sccp/sccp.c @@ -1198,6 +1198,17 @@ int sccp_connection_free(struct sccp_connection *connection) return 0; } +int sccp_connection_force_free(struct sccp_connection *con) +{ + if (con->connection_state > SCCP_CONNECTION_STATE_NONE && + con->connection_state < SCCP_CONNECTION_STATE_RELEASE_COMPLETE) + llist_del(&con->list); + + con->connection_state = SCCP_CONNECTION_STATE_REFUSED; + sccp_connection_free(con); + return 0; +} + struct sccp_connection *sccp_connection_socket(void) { return talloc_zero(tall_sccp_ctx, struct sccp_connection); -- cgit v1.2.3 From 13d67b7ea331fdc6a0ef271a5839221c44f2d0d5 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 30 Mar 2010 15:41:03 +0200 Subject: [mgcp] Remove the sending of RSIP This message is ignored by the call agent and we were sending this on the first request which we maybe should not ignore... --- openbsc/include/openbsc/mgcp.h | 1 - openbsc/src/mgcp/mgcp_main.c | 13 ------------- openbsc/src/mgcp/mgcp_protocol.c | 17 ----------------- 3 files changed, 31 deletions(-) diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index f7e800bd8..6a07cd111 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -115,7 +115,6 @@ void mgcp_free_endp(struct mgcp_endpoint *endp); * format helper functions */ struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg); -struct msgb *mgcp_create_rsip(void); struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans, const char *data); diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c index 6210e5941..23e66a917 100644 --- a/openbsc/src/mgcp/mgcp_main.c +++ b/openbsc/src/mgcp/mgcp_main.c @@ -53,7 +53,6 @@ void subscr_put() { abort(); } #warning "Make use of the rtp proxy code" static struct bsc_fd bfd; -static int first_request = 1; static struct mgcp_config *cfg; const char *openbsc_version = "OpenBSC MGCP " PACKAGE_VERSION; const char *openbsc_copyright = @@ -138,18 +137,6 @@ static int read_call_agent(struct bsc_fd *fd, unsigned int what) return -1; } - if (first_request) { - first_request = 0; - resp = mgcp_create_rsip(); - - if (resp) { - sendto(bfd.fd, resp->l2h, msgb_l2len(resp), 0, - (struct sockaddr *) &addr, sizeof(addr)); - msgb_free(resp); - } - return 0; - } - /* handle message now */ msg->l2h = msgb_put(msg, rc); resp = mgcp_handle_message(cfg, msg); diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index a825e92f5..5ae35702a 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -194,23 +194,6 @@ static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp, return mgcp_create_response_with_data(200, msg, trans_id, sdp_record); } -/* send a static record */ -struct msgb *mgcp_create_rsip(void) -{ - struct msgb *msg; - int len; - - msg = mgcp_msgb_alloc(); - if (!msg) - return NULL; - - len = snprintf((char *) msg->data, 2048, - "RSIP %u *@mgw MGCP 1.0\n" - "RM: restart\n", generate_transaction_id()); - msg->l2h = msgb_put(msg, len); - return msg; -} - /* * handle incoming messages: * - this can be a command (four letters, space, transaction id) -- cgit v1.2.3 From 52a66aa27ea7bec819245c1bedc2156a53206773 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 31 Mar 2010 06:16:45 +0200 Subject: [mgcp] Switch from DEBUG to LOGP in the mgcp_main.c --- openbsc/src/mgcp/mgcp_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c index 23e66a917..81f91280c 100644 --- a/openbsc/src/mgcp/mgcp_main.c +++ b/openbsc/src/mgcp/mgcp_main.c @@ -206,11 +206,11 @@ int main(int argc, char** argv) if (bsc_register_fd(&bfd) != 0) { - DEBUGP(DMGCP, "Failed to register the fd\n"); + LOGP(DMGCP, LOGL_FATAL, "Failed to register the fd\n"); return -1; } - DEBUGP(DMGCP, "Configured for MGCP.\n"); + LOGP(DMGCP, LOGL_NOTICE, "Configured for MGCP.\n"); } /* initialisation */ -- cgit v1.2.3 From e7d2ae69c90d3eb27454ca0de8e5db9be34cad40 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 31 Mar 2010 06:26:44 +0200 Subject: [mgcp] Remove unused method from the mgcp This was removed when sending the RSIP was removed from the code. --- openbsc/src/mgcp/mgcp_protocol.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index 5ae35702a..7ad4e0a1f 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -119,12 +119,6 @@ static int generate_call_id(struct mgcp_config *cfg) return cfg->last_call_id; } -/* FIXIME/TODO: need to have a list of pending transactions and check that */ -static unsigned int generate_transaction_id() -{ - return abs(rand()); -} - /* * array of function pointers for handling various * messages. In the future this might be binary sorted -- cgit v1.2.3 From 9bdcc9ca75a55c5d5bc5b7589e410c39b714c0c3 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 31 Mar 2010 06:39:35 +0200 Subject: [mgcp] Add some parsing for RSIP messages coming in This will just call a callback and leave all the handling to the application. --- openbsc/include/openbsc/mgcp.h | 2 ++ openbsc/src/mgcp/mgcp_protocol.c | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index 6a07cd111..37194bee8 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -77,6 +77,7 @@ struct mgcp_config; typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state, int local_rtp); typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id); +typedef int (*mgcp_reset)(struct mgcp_config *cfg); struct mgcp_config { int source_port; @@ -97,6 +98,7 @@ struct mgcp_config { mgcp_change change_cb; mgcp_policy policy_cb; + mgcp_reset reset_cb; void *data; struct mgcp_endpoint *endpoints; diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index 7ad4e0a1f..b8c011e08 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -98,6 +98,7 @@ static struct msgb *handle_audit_endpoint(struct mgcp_config *cfg, struct msgb * static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg); static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg); static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg); +static struct msgb *handle_rsip(struct mgcp_config *cfg, struct msgb *msg); static int generate_call_id(struct mgcp_config *cfg) { @@ -129,6 +130,9 @@ static const struct mgcp_request mgcp_requests [] = { MGCP_REQUEST("CRCX", handle_create_con, "CreateConnection") MGCP_REQUEST("DLCX", handle_delete_con, "DeleteConnection") MGCP_REQUEST("MDCX", handle_modify_con, "ModifiyConnection") + + /* SPEC extension */ + MGCP_REQUEST("RSIP", handle_rsip, "ReSetInProgress") }; static struct msgb *mgcp_msgb_alloc(void) @@ -655,6 +659,13 @@ error3: return create_response(error_code, "DLCX", trans_id); } +static struct msgb *handle_rsip(struct mgcp_config *cfg, struct msgb *msg) +{ + if (cfg->reset_cb) + cfg->reset_cb(cfg); + return NULL; +} + struct mgcp_config *mgcp_config_alloc(void) { struct mgcp_config *cfg; -- cgit v1.2.3 From 64e4e775585db7b44c8d34f9811335316b940812 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 31 Mar 2010 07:01:35 +0200 Subject: [mgcp] Handle the RSIP with resetting all endpoints We could change that the message came from a special ip address/port to secure this service in general but we don't do that right now. --- openbsc/src/mgcp/mgcp_main.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c index 81f91280c..5e337e902 100644 --- a/openbsc/src/mgcp/mgcp_main.c +++ b/openbsc/src/mgcp/mgcp_main.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,8 @@ void subscr_put() { abort(); } static struct bsc_fd bfd; static struct mgcp_config *cfg; +static int reset_endpoints = 0; + const char *openbsc_version = "OpenBSC MGCP " PACKAGE_VERSION; const char *openbsc_copyright = "Copyright (C) 2009-2010 Holger Freyther and On-Waves\n" @@ -116,12 +119,21 @@ static void handle_options(int argc, char** argv) } } +/* simply remember this */ +static int mgcp_rsip_cb(struct mgcp_config *cfg) +{ + reset_endpoints = 1; + + return 0; +} + static int read_call_agent(struct bsc_fd *fd, unsigned int what) { struct sockaddr_in addr; socklen_t slen = sizeof(addr); struct msgb *msg; struct msgb *resp; + int i; msg = (struct msgb *) fd->data; @@ -146,6 +158,16 @@ static int read_call_agent(struct bsc_fd *fd, unsigned int what) sendto(bfd.fd, resp->l2h, msgb_l2len(resp), 0, (struct sockaddr *) &addr, sizeof(addr)); msgb_free(resp); } + + if (reset_endpoints) { + LOGP(DMGCP, LOGL_NOTICE, "Asked to reset endpoints.\n"); + reset_endpoints = 0; + + /* is checking in_addr.s_addr == INADDR_LOOPBACK making it more secure? */ + for (i = 1; i < cfg->number_endpoints; ++i) + mgcp_free_endp(&cfg->endpoints[i]); + } + return 0; } @@ -175,6 +197,8 @@ int main(int argc, char** argv) if (rc < 0) return rc; + /* set some callbacks */ + cfg->reset_cb = mgcp_rsip_cb; /* we need to bind a socket */ if (rc == 0) { -- cgit v1.2.3 From 616d2225182a3ba64d6059d52594255ee472af89 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 31 Mar 2010 09:27:04 +0200 Subject: [mgcp] Add a helper function to convert from GSM0808 ts/mux to MGCP endpoint Move the conversion of GSM0808 timeslot and multiplex from the bssap.c into the mgcp.h so it can be reused by multiple users. The weird math comes from the mapping of the MSC... --- openbsc/include/openbsc/mgcp.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index 37194bee8..c60a4550c 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -119,5 +119,13 @@ void mgcp_free_endp(struct mgcp_endpoint *endp); struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg); struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans, const char *data); +/* adc helper */ +static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot) +{ + if (timeslot == 0) + timeslot = 1; + return timeslot + (31 * multiplex); +} + #endif -- cgit v1.2.3 From b79994c95292c8dda971268e5ac46e7f47ca6266 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 31 Mar 2010 11:46:41 +0200 Subject: [mgcp] Add a new config option to set the call agent ip addr In the case of the nat we only want to communicate with one upstream call agent and this can now be configured. --- openbsc/include/openbsc/mgcp.h | 1 + openbsc/src/mgcp/mgcp_vty.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index c60a4550c..c4081b109 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -85,6 +85,7 @@ struct mgcp_config { char *source_addr; unsigned int number_endpoints; char *bts_ip; + char *call_agent_addr; struct in_addr bts_in; char *audio_name; diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c index 6773d889f..70f7528e0 100644 --- a/openbsc/src/mgcp/mgcp_vty.c +++ b/openbsc/src/mgcp/mgcp_vty.c @@ -63,6 +63,8 @@ static int config_write_mgcp(struct vty *vty) vty_out(vty, " forward audio ip %s%s", g_cfg->forward_ip, VTY_NEWLINE); if (g_cfg->forward_port != 0) vty_out(vty, " forward audio port %d%s", g_cfg->forward_port, VTY_NEWLINE); + if (g_cfg->call_agent_addr) + vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE); return CMD_SUCCESS; } @@ -237,6 +239,17 @@ DEFUN(cfg_mgcp_forward_port, return CMD_SUCCESS; } +DEFUN(cfg_mgcp_agent_addr, + cfg_mgcp_agent_addr_cmd, + "call agent ip IP", + "Set the address of the call agent.") +{ + if (g_cfg->call_agent_addr) + talloc_free(g_cfg->call_agent_addr); + g_cfg->call_agent_addr = talloc_strdup(g_cfg, argv[0]); + return CMD_SUCCESS; +} + int mgcp_vty_init(void) { install_element(VIEW_NODE, &show_mgcp_cmd); @@ -256,6 +269,7 @@ int mgcp_vty_init(void) install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd); install_element(MGCP_NODE, &cfg_mgcp_forward_ip_cmd); install_element(MGCP_NODE, &cfg_mgcp_forward_port_cmd); + install_element(MGCP_NODE, &cfg_mgcp_agent_addr_cmd); return 0; } -- cgit v1.2.3 From c77efdf057a7a80962f8989d83a149b13800280b Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 31 Mar 2010 12:31:09 +0200 Subject: [mgcp] Degrade verbosity to debug --- openbsc/src/mgcp/mgcp_protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index b8c011e08..61bc1cae5 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -710,7 +710,7 @@ int mgcp_endpoints_allocate(struct mgcp_config *cfg) void mgcp_free_endp(struct mgcp_endpoint *endp) { - LOGP(DMGCP, LOGL_NOTICE, "Deleting endpoint on: 0x%x\n", ENDPOINT_NUMBER(endp)); + LOGP(DMGCP, LOGL_DEBUG, "Deleting endpoint on: 0x%x\n", ENDPOINT_NUMBER(endp)); endp->ci= CI_UNUSED; if (endp->callid) { -- cgit v1.2.3 From f36a11a35d18903f29842f51ad0ce7ef63e2f71e Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 31 Mar 2010 13:26:46 +0200 Subject: [mgcp] Do not operate on the ->data pointer, use ->l2h instead This would have been broken once we attempt to parse encapsulated MGCP messages. --- openbsc/src/mgcp/mgcp_protocol.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index 61bc1cae5..6d9adfcae 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -202,25 +202,25 @@ struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg) int code; struct msgb *resp = NULL; - if (msg->len < 4) { + if (msgb_l2len(msg) < 4) { LOGP(DMGCP, LOGL_ERROR, "mgs too short: %d\n", msg->len); return NULL; } /* attempt to treat it as a response */ - if (sscanf((const char *)&msg->data[0], "%3d %*s", &code) == 1) { + if (sscanf((const char *)&msg->l2h[0], "%3d %*s", &code) == 1) { LOGP(DMGCP, LOGL_DEBUG, "Response: Code: %d\n", code); } else { int i, handled = 0; msg->l3h = &msg->l2h[4]; for (i = 0; i < ARRAY_SIZE(mgcp_requests); ++i) - if (strncmp(mgcp_requests[i].name, (const char *) &msg->data[0], 4) == 0) { + if (strncmp(mgcp_requests[i].name, (const char *) &msg->l2h[0], 4) == 0) { handled = 1; resp = mgcp_requests[i].handle_request(cfg, msg); break; } if (!handled) { - LOGP(DMGCP, LOGL_NOTICE, "MSG with type: '%.4s' not handled\n", &msg->data[0]); + LOGP(DMGCP, LOGL_NOTICE, "MSG with type: '%.4s' not handled\n", &msg->l2h[0]); } } -- cgit v1.2.3 From f2f1591ce7fde28d67da30c1998eaa631c2d5897 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 1 Apr 2010 03:27:04 +0200 Subject: [mgcp] Export header parsing via mgcp internal This will be used by the NAT code to implement custom protocol handling on top of that. --- openbsc/include/openbsc/mgcp_internal.h | 9 +++++++++ openbsc/src/mgcp/mgcp_protocol.c | 26 ++++++++++++-------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 10d0ca6ae..7ce1732f9 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -61,4 +61,13 @@ struct mgcp_endpoint { #define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints) +struct mgcp_msg_ptr { + unsigned int start; + unsigned int length; +}; + +int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg, + struct mgcp_msg_ptr *ptr, int size, + const char **transaction_id, struct mgcp_endpoint **endp); + #endif diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index 6d9adfcae..ba1d6d8aa 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -80,11 +80,6 @@ enum mgcp_connection_mode { } -struct mgcp_msg_ptr { - unsigned int start; - unsigned int length; -}; - struct mgcp_request { char *name; struct msgb *(*handle_request) (struct mgcp_config *cfg, struct msgb *msg); @@ -277,9 +272,9 @@ static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg, const char * return &cfg->endpoints[gw]; } -static int analyze_header(struct mgcp_config *cfg, struct msgb *msg, - struct mgcp_msg_ptr *ptr, int size, - const char **transaction_id, struct mgcp_endpoint **endp) +int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg, + struct mgcp_msg_ptr *ptr, int size, + const char **transaction_id, struct mgcp_endpoint **endp) { int found; @@ -315,8 +310,11 @@ static int analyze_header(struct mgcp_config *cfg, struct msgb *msg, } *transaction_id = (const char *)&msg->l3h[ptr[0].start]; - *endp = find_endpoint(cfg, (const char *)&msg->l3h[ptr[1].start]); - return *endp == NULL; + if (endp) { + *endp = find_endpoint(cfg, (const char *)&msg->l3h[ptr[1].start]); + return *endp == NULL; + } + return 0; } static int verify_call_id(const struct mgcp_endpoint *endp, @@ -350,7 +348,7 @@ static struct msgb *handle_audit_endpoint(struct mgcp_config *cfg, struct msgb * const char *trans_id; struct mgcp_endpoint *endp; - found = analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp); + found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp); if (found != 0) response = 500; else @@ -383,7 +381,7 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg) int error_code = 500; int port; - found = analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp); + found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp); if (found != 0) return create_response(500, "CRCX", trans_id); @@ -482,7 +480,7 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg) struct mgcp_endpoint *endp; int error_code = 500; - found = analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp); + found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp); if (found != 0) return create_response(error_code, "MDCX", trans_id); @@ -595,7 +593,7 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg) struct mgcp_endpoint *endp; int error_code = 500; - found = analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp); + found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp); if (found != 0) return create_response(error_code, "DLCX", trans_id); -- cgit v1.2.3 From 8b120f0ef9d533654c4fca98bcaed756c3a1dea2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 1 Apr 2010 07:56:04 +0200 Subject: [mgcp] Look at the bts addr set at the endpoint This will allow to discover the ports of a bts when we only know the addr and have multiple bts's to handle. --- openbsc/src/mgcp/mgcp_network.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c index 924e6fc44..592e20fff 100644 --- a/openbsc/src/mgcp/mgcp_network.c +++ b/openbsc/src/mgcp/mgcp_network.c @@ -144,7 +144,9 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what) /* We have no idea who called us, maybe it is the BTS. */ if (dest == DEST_NETWORK && (endp->bts_rtp == 0 || cfg->forward_ip)) { /* it was the BTS... */ - if (!cfg->bts_ip || memcmp(&addr.sin_addr, &cfg->bts_in, sizeof(cfg->bts_in)) == 0) { + if (!cfg->bts_ip + || memcmp(&addr.sin_addr, &cfg->bts_in, sizeof(cfg->bts_in)) == 0 + || memcmp(&addr.sin_addr, &endp->bts, sizeof(endp->bts)) == 0) { if (fd == &endp->local_rtp) { endp->bts_rtp = addr.sin_port; } else { -- cgit v1.2.3 From 58df0ea9a0b97efe98a84148a08120d3092fd1ab Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 4 Apr 2010 16:33:04 +0200 Subject: [mgcp] Fix the transaction id of the AUEP request --- openbsc/contrib/mgcp_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/contrib/mgcp_server.py b/openbsc/contrib/mgcp_server.py index cf3ef3845..88963f31b 100755 --- a/openbsc/contrib/mgcp_server.py +++ b/openbsc/contrib/mgcp_server.py @@ -45,7 +45,7 @@ def generate_tid(): i = 1 while True: send_receive(rsip_resp) - send_receive(audit_packet) + send_receive(audit_packet % generate_tid()) send_receive(crcx_packet % generate_tid() ) send_receive(mdcx_packet % (generate_tid(), i)) send_receive(dlcx_packet % (generate_tid(), i)) -- cgit v1.2.3 From e125d40f66fcf81278cd70c492706c39a98fcb96 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 4 Apr 2010 18:39:56 +0200 Subject: [mgcp] Start to look into the MGCP messages and extract the CI we will need the call identifier for the MDCX and DLCX message for now we were just assuming it would increment, use som python to extract the CI from a possible response, also switch back to a blocking read to test the BSC nat. --- openbsc/contrib/mgcp_server.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/openbsc/contrib/mgcp_server.py b/openbsc/contrib/mgcp_server.py index 88963f31b..ae8a6e277 100755 --- a/openbsc/contrib/mgcp_server.py +++ b/openbsc/contrib/mgcp_server.py @@ -25,15 +25,24 @@ def hexdump(src, length=8): server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT)) -server_socket.setblocking(0) +server_socket.setblocking(1) - -def send_receive(packet): +last_ci = 1 +def send_and_receive(packet): + global last_ci server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT)) try: data, addr = server_socket.recvfrom(4096) + + # attempt to store the CI of the response + list = data.split("\n") + for item in list: + if item.startswith("I: "): + last_ci = int(item[3:]) + print hexdump(data), addr - except socket.error: + except socket.error, e: + print e pass def generate_tid(): @@ -42,13 +51,10 @@ def generate_tid(): -i = 1 while True: - send_receive(rsip_resp) - send_receive(audit_packet % generate_tid()) - send_receive(crcx_packet % generate_tid() ) - send_receive(mdcx_packet % (generate_tid(), i)) - send_receive(dlcx_packet % (generate_tid(), i)) - i = i + 1 + send_and_receive(audit_packet % generate_tid()) + send_and_receive(crcx_packet % generate_tid() ) + send_and_receive(mdcx_packet % (generate_tid(), last_ci)) + send_and_receive(dlcx_packet % (generate_tid(), last_ci)) time.sleep(3) -- cgit v1.2.3 From 6c0729fe70db5314073ad7f90ee706d6799d045a Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 5 Apr 2010 09:00:53 +0200 Subject: [mgcp] Print the BTS IP addr of the endpoint. --- openbsc/src/mgcp/mgcp_vty.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c index 70f7528e0..c8d4b7fe6 100644 --- a/openbsc/src/mgcp/mgcp_vty.c +++ b/openbsc/src/mgcp/mgcp_vty.c @@ -77,10 +77,11 @@ DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp", vty_out(vty, "MGCP is up and running with %u endpoints:%s", g_cfg->number_endpoints - 1, VTY_NEWLINE); for (i = 1; i < g_cfg->number_endpoints; ++i) { struct mgcp_endpoint *endp = &g_cfg->endpoints[i]; - vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u%s", + vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s%s", i, endp->ci, ntohs(endp->net_rtp), ntohs(endp->net_rtcp), - ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp), VTY_NEWLINE); + ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp), + inet_ntoa(endp->bts), VTY_NEWLINE); } return CMD_SUCCESS; -- cgit v1.2.3 From ef8253c495417ed3756440b4479651389be75db8 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 5 Apr 2010 09:01:28 +0200 Subject: [mgcp] Use a different port to more easily differentiate --- openbsc/contrib/mgcp_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/contrib/mgcp_server.py b/openbsc/contrib/mgcp_server.py index ae8a6e277..05c489db5 100755 --- a/openbsc/contrib/mgcp_server.py +++ b/openbsc/contrib/mgcp_server.py @@ -10,7 +10,7 @@ rsip_resp = """200 321321332\r\n""" audit_packet = """AUEP %d 13@mgw MGCP 1.0\r\n""" crcx_packet = """CRCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n""" dlcx_packet = """DLCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\n""" -mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 4400 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n""" +mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 6666 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n""" def hexdump(src, length=8): """Recipe is from http://code.activestate.com/recipes/142812/""" -- cgit v1.2.3 From 7279d24232d000697297b1ad50da4cf012da2418 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 6 Apr 2010 11:15:50 +0200 Subject: [mgcp] Do not patch RTP payload when type is set to -1. For the nat we might or might not want to patch it, do not patch if we have no valid rtp payload type. --- openbsc/src/mgcp/mgcp_network.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c index 592e20fff..9e18937d1 100644 --- a/openbsc/src/mgcp/mgcp_network.c +++ b/openbsc/src/mgcp/mgcp_network.c @@ -90,6 +90,9 @@ static void patch_payload(int payload, char *data, int len) if (len < sizeof(*rtp_hdr)) return; + if (payload < 0) + return; + rtp_hdr = (struct rtp_hdr *) data; rtp_hdr->payload_type = payload; } -- cgit v1.2.3 From b4c7b274a1365e896affc1e1cb9a5075e3100e2a Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 6 Apr 2010 11:12:22 +0200 Subject: [mgcp] Reset the the address when freeing the endp as well --- openbsc/src/mgcp/mgcp_protocol.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index ba1d6d8aa..bbdc43e05 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -728,4 +728,6 @@ void mgcp_free_endp(struct mgcp_endpoint *endp) endp->net_rtp = endp->net_rtcp = endp->bts_rtp = endp->bts_rtcp = 0; endp->net_payload_type = endp->bts_payload_type = -1; + memset(&endp->remote, 0, sizeof(endp->remote)); + memset(&endp->bts, 0, sizeof(endp->bts)); } -- cgit v1.2.3 From 54fa7991295d64a01a39f7863f585ff8ab08ed13 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 7 Apr 2010 15:39:16 +0200 Subject: vty: Fix the byteorder... of the bound_ip We are storing the bound_ip in host byteorder but when using ntohl we need to convert it back to to network byte order. --- openbsc/src/vty_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index 897ed2f69..b5bdbc8c2 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -616,7 +616,7 @@ static void lchan_dump_vty(struct vty *vty, struct gsm_lchan *lchan) vty_out(vty, " No Subscriber%s", VTY_NEWLINE); if (is_ipaccess_bts(lchan->ts->trx->bts)) { struct in_addr ia; - ia.s_addr = lchan->abis_ip.bound_ip; + ia.s_addr = htonl(lchan->abis_ip.bound_ip); vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s", inet_ntoa(ia), lchan->abis_ip.bound_port, lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id, -- cgit v1.2.3 From b4b135efbf17f81a3faccb488ca35a5086adc618 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 7 Apr 2010 09:37:17 +0200 Subject: [mgcp] Count incoming RTP packets from the BTS and remote --- openbsc/include/openbsc/mgcp_internal.h | 4 ++++ openbsc/src/mgcp/mgcp_network.c | 6 ++++++ openbsc/src/mgcp/mgcp_protocol.c | 1 + openbsc/src/mgcp/mgcp_vty.c | 5 +++-- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 7ce1732f9..3a2832436 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -57,6 +57,10 @@ struct mgcp_endpoint { /* backpointer */ struct mgcp_config *cfg; + + /* statistics */ + unsigned int in_bts; + unsigned int in_remote; }; #define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints) diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c index 9e18937d1..a5a2481fe 100644 --- a/openbsc/src/mgcp/mgcp_network.c +++ b/openbsc/src/mgcp/mgcp_network.c @@ -162,6 +162,12 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what) } } + /* do this before the loop handling */ + if (dest == DEST_NETWORK) + ++endp->in_bts; + else + ++endp->in_remote; + /* dispatch */ if (cfg->audio_loop) dest = !dest; diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index bbdc43e05..7c8b460fa 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -728,6 +728,7 @@ void mgcp_free_endp(struct mgcp_endpoint *endp) endp->net_rtp = endp->net_rtcp = endp->bts_rtp = endp->bts_rtcp = 0; endp->net_payload_type = endp->bts_payload_type = -1; + endp->in_bts = endp->in_remote = 0; memset(&endp->remote, 0, sizeof(endp->remote)); memset(&endp->bts, 0, sizeof(endp->bts)); } diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c index c8d4b7fe6..af762c57e 100644 --- a/openbsc/src/mgcp/mgcp_vty.c +++ b/openbsc/src/mgcp/mgcp_vty.c @@ -77,11 +77,12 @@ DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp", vty_out(vty, "MGCP is up and running with %u endpoints:%s", g_cfg->number_endpoints - 1, VTY_NEWLINE); for (i = 1; i < g_cfg->number_endpoints; ++i) { struct mgcp_endpoint *endp = &g_cfg->endpoints[i]; - vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s%s", + vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s traffic in :%u/%u%s", i, endp->ci, ntohs(endp->net_rtp), ntohs(endp->net_rtcp), ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp), - inet_ntoa(endp->bts), VTY_NEWLINE); + inet_ntoa(endp->bts), endp->in_bts, endp->in_remote, + VTY_NEWLINE); } return CMD_SUCCESS; -- cgit v1.2.3 From 408cc4ace99a9163136af601549a5d1b67a168c7 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 7 Apr 2010 10:51:27 +0200 Subject: [mgcp] Add an option to allow using reallocing an endpoint For some mode of operation it can be acceptable to reallocate an already allocated endpoint. This can be the case when we only deal with one call agent that is keeping track of the endpoint but slightly confused. --- openbsc/include/openbsc/mgcp.h | 3 +++ openbsc/src/mgcp/mgcp_protocol.c | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h index c4081b109..71b7fc14e 100644 --- a/openbsc/include/openbsc/mgcp.h +++ b/openbsc/include/openbsc/mgcp.h @@ -97,6 +97,9 @@ struct mgcp_config { char *forward_ip; int forward_port; + /* spec handling */ + int force_realloc; + mgcp_change change_cb; mgcp_policy policy_cb; mgcp_reset reset_cb; diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c index 7c8b460fa..76eb7c2a0 100644 --- a/openbsc/src/mgcp/mgcp_protocol.c +++ b/openbsc/src/mgcp/mgcp_protocol.c @@ -386,8 +386,14 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg) return create_response(500, "CRCX", trans_id); if (endp->ci != CI_UNUSED) { - LOGP(DMGCP, LOGL_ERROR, "Endpoint is already used. 0x%x\n", ENDPOINT_NUMBER(endp)); - return create_response(500, "CRCX", trans_id); + if (cfg->force_realloc) { + LOGP(DMGCP, LOGL_NOTICE, "Endpoint 0x%x already allocated. Forcing realloc.\n", + ENDPOINT_NUMBER(endp)); + } else { + LOGP(DMGCP, LOGL_ERROR, "Endpoint is already used. 0x%x\n", + ENDPOINT_NUMBER(endp)); + return create_response(500, "CRCX", trans_id); + } } /* parse CallID C: and LocalParameters L: */ -- cgit v1.2.3 From 575b89585f7fa7cb4104eeb9f853561af16603d3 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 7 Apr 2010 12:55:40 +0200 Subject: [mgcp] Print the errno/strerror when we can not receive from our socket --- openbsc/src/mgcp/mgcp_network.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c index a5a2481fe..cd10d2a8c 100644 --- a/openbsc/src/mgcp/mgcp_network.c +++ b/openbsc/src/mgcp/mgcp_network.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -122,8 +123,8 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what) rc = recvfrom(fd->fd, &buf, sizeof(buf), 0, (struct sockaddr *) &addr, &slen); if (rc < 0) { - LOGP(DMGCP, LOGL_ERROR, "Failed to receive message on: 0x%x\n", - ENDPOINT_NUMBER(endp)); + LOGP(DMGCP, LOGL_ERROR, "Failed to receive message on: 0x%x errno: %d/%s\n", + ENDPOINT_NUMBER(endp), errno, strerror(errno)); return -1; } -- cgit v1.2.3 From 441273766a4c7842b457f19bad3375e9acccc842 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 6 Apr 2010 12:00:43 +0200 Subject: [mgcp] Add the logging commands for the MGCP command. --- openbsc/src/Makefile.am | 2 +- openbsc/src/mgcp/mgcp_main.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am index f4d1c01a1..2c1d37a04 100644 --- a/openbsc/src/Makefile.am +++ b/openbsc/src/Makefile.am @@ -42,7 +42,7 @@ ipaccess_config_LDADD = libbsc.a libmsc.a libbsc.a libvty.a -ldl -ldbi $(LIBCRYP isdnsync_SOURCES = isdnsync.c bsc_mgcp_SOURCES = mgcp/mgcp_main.c mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c \ - debug.c telnet_interface.c + debug.c telnet_interface.c vty_interface_cmds.c bsc_mgcp_LDADD = libvty.a ipaccess_proxy_SOURCES = ipaccess/ipaccess-proxy.c debug.c diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c index 5e337e902..80b7b543c 100644 --- a/openbsc/src/mgcp/mgcp_main.c +++ b/openbsc/src/mgcp/mgcp_main.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -255,6 +256,7 @@ int bsc_vty_init(struct gsm_network *dummy) cmd_init(1); vty_init(); + openbsc_vty_add_cmds(); mgcp_vty_init(); return 0; } -- cgit v1.2.3 From 500ff97c21c14f6c76afe902c4ceebf8bc6497d2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 7 Apr 2010 23:00:23 +0200 Subject: Fix compiler warning about void return in non void method. --- openbsc/tests/debug/debug_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openbsc/tests/debug/debug_test.c b/openbsc/tests/debug/debug_test.c index 695d65c0b..f3e483703 100644 --- a/openbsc/tests/debug/debug_test.c +++ b/openbsc/tests/debug/debug_test.c @@ -38,4 +38,6 @@ int main(int argc, char** argv) DEBUGP(DRLL, "You should see this\n"); DEBUGP(DCC, "You should see this\n"); DEBUGP(DMM, "You should not see this\n"); + + return 0; } -- cgit v1.2.3 From 1ea8dbec908f26e51a8864ba210a503be23e9005 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 5 Apr 2010 22:42:18 +0200 Subject: [mgcp] Fix navigation in the vty hierachy (make exit work) Make exit from the MGCP node work properly. --- openbsc/src/vty/command.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openbsc/src/vty/command.c b/openbsc/src/vty/command.c index 2faed35e4..a38ed0424 100644 --- a/openbsc/src/vty/command.c +++ b/openbsc/src/vty/command.c @@ -2362,6 +2362,9 @@ DEFUN(config_exit, case VTY_NODE: vty->node = CONFIG_NODE; break; + case MGCP_NODE: + vty->node = CONFIG_NODE; + vty->index = NULL; default: break; } -- cgit v1.2.3 From 19bab73d7903d0718979aca1463503fcc185166b Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 20 Nov 2009 15:14:01 +0100 Subject: [rsl] Speculative crash fix in the RSL rcv message The theory is that the BTS is almost dead and sends out a incomplete message and we crash with that. I have not been able to completely verify that. --- openbsc/src/abis_rsl.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 0e572ccce..0e385c18c 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -1652,9 +1652,21 @@ static int abis_rsl_rx_ipacc(struct msgb *msg) /* Entry-point where L2 RSL from BTS enters */ int abis_rsl_rcvmsg(struct msgb *msg) { - struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ; + struct abis_rsl_common_hdr *rslh; int rc = 0; + if (!msg) { + DEBUGP(DRSL, "Empty RSL msg?..\n"); + return -1; + } + + if (msgb_l2len(msg) < sizeof(*rslh)) { + DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg)); + return -1; + } + + rslh = msgb_l2(msg); + switch (rslh->msg_discr & 0xfe) { case ABIS_RSL_MDISC_RLL: rc = abis_rsl_rx_rll(msg); -- cgit v1.2.3 From 6c8c0ddbe21c45f16ed996a9cb38b0fb3b9bc66f Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 4 Apr 2010 18:12:37 +0200 Subject: [ipa] When including MGCP our messages might be bigger than 300 byte The length field of the IPA header allows to have 16bit numbers and I just ran into the 300 byte limit with MGCP messages. Make it three times the size and see how long this is going to be enough. --- openbsc/src/input/ipaccess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c index 323540f48..2449e261d 100644 --- a/openbsc/src/input/ipaccess.c +++ b/openbsc/src/input/ipaccess.c @@ -57,7 +57,7 @@ struct ia_e1_handle { static struct ia_e1_handle *e1h; -#define TS1_ALLOC_SIZE 300 +#define TS1_ALLOC_SIZE 900 static const u_int8_t pong[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_PONG }; static const u_int8_t id_ack[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK }; -- cgit v1.2.3 From d4e7888ae3b3b5d195b75fe317d97bfd3606e4cb Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 27 Jan 2010 09:10:05 +0100 Subject: [paging] Increase the time used to send paging messages to the BTS Send a Paging Request to the BTS every two seconds. This way it is unlikely that a phone will try to respond to two paging requests as it is currently happening. --- openbsc/src/paging.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index 7c3750d66..9c978bee6 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -160,7 +160,7 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b } while (paging_bts->available_slots > 0 && initial_request != current_request); - bsc_schedule_timer(&paging_bts->work_timer, 1, 0); + bsc_schedule_timer(&paging_bts->work_timer, 2, 0); } static void paging_worker(void *data) @@ -245,7 +245,7 @@ static int _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, llist_add_tail(&req->entry, &bts_entry->pending_requests); if (!bsc_timer_pending(&bts_entry->work_timer)) - bsc_schedule_timer(&bts_entry->work_timer, 1, 0); + bsc_schedule_timer(&bts_entry->work_timer, 2, 0); return 0; } -- cgit v1.2.3 From 07d838a3bf866692f15d6d3bbc17e91451ace216 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 8 Apr 2010 16:48:46 +0200 Subject: [paging] Do not use request after it was was destroyed.. Increment the counter before we call the remove request which is freeing the request... --- openbsc/src/paging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index 9c978bee6..3d16a21fb 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -208,11 +208,11 @@ static void paging_T3113_expired(void *data) sig_data.lchan = NULL; /* must be destroyed before calling cbfn, to prevent double free */ + counter_inc(req->bts->network->stats.paging.expired); cbfn_param = req->cbfn_param; cbfn = req->cbfn; paging_remove_request(&req->bts->paging, req); - counter_inc(req->bts->network->stats.paging.expired); dispatch_signal(SS_PAGING, S_PAGING_EXPIRED, &sig_data); if (cbfn) -- cgit v1.2.3 From aff596b8e1639213f0927bca8b54d85b6e09c146 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 9 Apr 2010 18:53:01 +0200 Subject: [mgcp] Print the IP addr of the BTS we have detected. --- openbsc/src/mgcp/mgcp_network.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c index cd10d2a8c..5a982608e 100644 --- a/openbsc/src/mgcp/mgcp_network.c +++ b/openbsc/src/mgcp/mgcp_network.c @@ -158,8 +158,9 @@ static int rtp_data_cb(struct bsc_fd *fd, unsigned int what) } endp->bts = addr.sin_addr; - LOGP(DMGCP, LOGL_NOTICE, "Found BTS for endpoint: 0x%x on port: %d/%d\n", - ENDPOINT_NUMBER(endp), ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp)); + LOGP(DMGCP, LOGL_NOTICE, "Found BTS for endpoint: 0x%x on port: %d/%d of %s\n", + ENDPOINT_NUMBER(endp), ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp), + inet_ntoa(addr.sin_addr)); } } -- cgit v1.2.3 From 5615b982c251a352e62e1332c4c3383b90905116 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 9 Apr 2010 18:53:24 +0200 Subject: [mgcp] Improve the endpoint display on the vty.. Make sure one understands the two values for number of incoming packets.. --- openbsc/src/mgcp/mgcp_vty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c index af762c57e..743f3fd07 100644 --- a/openbsc/src/mgcp/mgcp_vty.c +++ b/openbsc/src/mgcp/mgcp_vty.c @@ -77,7 +77,7 @@ DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp", vty_out(vty, "MGCP is up and running with %u endpoints:%s", g_cfg->number_endpoints - 1, VTY_NEWLINE); for (i = 1; i < g_cfg->number_endpoints; ++i) { struct mgcp_endpoint *endp = &g_cfg->endpoints[i]; - vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s traffic in :%u/%u%s", + vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u on %s traffic received bts: %u remote: %u%s", i, endp->ci, ntohs(endp->net_rtp), ntohs(endp->net_rtcp), ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp), -- cgit v1.2.3 From 19722d44116353c14de8cb1f09eb45b9f8ec8ae2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 9 Apr 2010 18:38:06 +0200 Subject: paging: Avoid integer underflow on ipaccess On the nanoBTS we do not receive any load indication for the paging channel and we just decrement our available slots and the unsigned int wraps to the maximum value. Together with a not yet understood bug this makes us go amock. For the nanoBTS and even the Siemens BS11 resetting the load to 20 after two seconds should be just fine. For the nanoBTS we would need to reset the 20 a lot more earlier but we need to take a look at how often we run low. --- openbsc/src/paging.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index 3d16a21fb..2ae3fc6bf 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -133,6 +133,20 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b return; } + /* + * In case the BTS does not provide us with load indication just fill + * up our slots for this round. We should be able to page 20 subscribers + * every two seconds. So we will just give the BTS some extra credit. + * We will have to see how often we run out of this credit, so we might + * need a low watermark and then add credit or give 20 every run when + * the bts sets an option for that. + */ + if (paging_bts->available_slots == 0) { + LOGP(DPAG, LOGL_NOTICE, "No slots available on bts nr %d\n", + paging_bts->bts->nr); + paging_bts->available_slots = 20; + } + if (!paging_bts->last_request) paging_bts->last_request = (struct gsm_paging_request *)paging_bts->pending_requests.next; -- cgit v1.2.3 From 754e801826207fb0c5ff490bbd8c36eb134aae5e Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 9 Apr 2010 21:53:35 +0200 Subject: [paging] Simplify the last request and treat llist as a queue The current code was overly complex. It tried to iterate over the list in a round robin and we had to keep track of the last element, see if we remove that one, check if the list becomes empty... This can all replaced by treating the double linked list as a queue. We take the item at the front, do something on it and then and then put it back to the list at the end. --- openbsc/include/openbsc/gsm_data.h | 1 - openbsc/src/paging.c | 43 ++++++++------------------------------ 2 files changed, 9 insertions(+), 35 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 8dfa5886b..ef0b50768 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -368,7 +368,6 @@ struct gsm_paging_request { struct gsm_bts_paging_state { /* pending requests */ struct llist_head pending_requests; - struct gsm_paging_request *last_request; struct gsm_bts *bts; struct timer_list work_timer; diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index 2ae3fc6bf..ece71ca7f 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -70,14 +70,6 @@ static unsigned int calculate_group(struct gsm_bts *bts, struct gsm_subscriber * static void paging_remove_request(struct gsm_bts_paging_state *paging_bts, struct gsm_paging_request *to_be_deleted) { - /* Update the last_request if that is necessary */ - if (to_be_deleted == paging_bts->last_request) { - paging_bts->last_request = - (struct gsm_paging_request *)paging_bts->last_request->entry.next; - if (&to_be_deleted->entry == &paging_bts->pending_requests) - paging_bts->last_request = NULL; - } - bsc_del_timer(&to_be_deleted->T3113); llist_del(&to_be_deleted->entry); subscr_put(to_be_deleted->subscr); @@ -103,14 +95,6 @@ static void page_ms(struct gsm_paging_request *request) request->chan_type); } -static void paging_move_to_next(struct gsm_bts_paging_state *paging_bts) -{ - paging_bts->last_request = - (struct gsm_paging_request *)paging_bts->last_request->entry.next; - if (&paging_bts->last_request->entry == &paging_bts->pending_requests) - paging_bts->last_request = NULL; -} - /* * This is kicked by the periodic PAGING LOAD Indicator * coming from abis_rsl.c @@ -128,7 +112,6 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b * return then. */ if (llist_empty(&paging_bts->pending_requests)) { - paging_bts->last_request = NULL; /* since the list is empty, no need to reschedule the timer */ return; } @@ -147,12 +130,8 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b paging_bts->available_slots = 20; } - if (!paging_bts->last_request) - paging_bts->last_request = - (struct gsm_paging_request *)paging_bts->pending_requests.next; - - assert(paging_bts->last_request); - initial_request = paging_bts->last_request; + initial_request = llist_entry(paging_bts->pending_requests.next, + struct gsm_paging_request, entry); current_request = initial_request; do { @@ -160,17 +139,13 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b page_ms(current_request); paging_bts->available_slots--; - /* - * move to the next item. We might wrap around - * this means last_request will be NULL and we just - * call paging_page_to_next again. It it guranteed - * that the list is not empty. - */ - paging_move_to_next(paging_bts); - if (!paging_bts->last_request) - paging_bts->last_request = - (struct gsm_paging_request *)paging_bts->pending_requests.next; - current_request = paging_bts->last_request; + /* take the current and add it to the back */ + llist_del(¤t_request->entry); + llist_add_tail(¤t_request->entry, &paging_bts->pending_requests); + + /* take the next request */ + current_request = llist_entry(paging_bts->pending_requests.next, + struct gsm_paging_request, entry); } while (paging_bts->available_slots > 0 && initial_request != current_request); -- cgit v1.2.3 From c50b83654030732416dda8dc8053efcdc3a8480c Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 9 Apr 2010 22:02:39 +0200 Subject: [paging] Move code to use LOGP and print some more information --- openbsc/src/paging.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index ece71ca7f..e0cb5313d 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -82,7 +82,7 @@ static void page_ms(struct gsm_paging_request *request) unsigned int mi_len; unsigned int page_group; - DEBUGP(DPAG, "Going to send paging commands: imsi: '%s' tmsi: '0x%x'\n", + LOGP(DPAG, LOGL_INFO, "Going to send paging commands: imsi: '%s' tmsi: '0x%x'\n", request->subscr->imsi, request->subscr->tmsi); if (request->subscr->tmsi == GSM_RESERVED_TMSI) @@ -189,7 +189,7 @@ static void paging_T3113_expired(void *data) void *cbfn_param; gsm_cbfn *cbfn; - DEBUGP(DPAG, "T3113 expired for request %p (%s)\n", + LOGP(DPAG, LOGL_INFO, "T3113 expired for request %p (%s)\n", req, req->subscr->imsi); sig_data.subscr = req->subscr; @@ -216,11 +216,11 @@ static int _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, struct gsm_paging_request *req; if (paging_pending_request(bts_entry, subscr)) { - DEBUGP(DPAG, "Paging request already pending\n"); + LOGP(DPAG, LOGL_INFO, "Paging request already pending for %s\n", subscr->imsi); return -EEXIST; } - DEBUGP(DPAG, "Start paging of subscriber %llu on bts %d.\n", + LOGP(DPAG, LOGL_DEBUG, "Start paging of subscriber %llu on bts %d.\n", subscr->id, bts->nr); req = talloc_zero(tall_paging_ctx, struct gsm_paging_request); req->subscr = subscr_get(subscr); @@ -285,11 +285,11 @@ static void _paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *sub entry) { if (req->subscr == subscr) { if (lchan && req->cbfn) { - DEBUGP(DPAG, "Stop paging on bts %d, calling cbfn.\n", bts->nr); + LOGP(DPAG, LOGL_DEBUG, "Stop paging on bts %d, calling cbfn.\n", bts->nr); req->cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_SUCCEEDED, NULL, lchan, req->cbfn_param); } else - DEBUGP(DPAG, "Stop paging on bts %d silently.\n", bts->nr); + LOGP(DPAG, LOGL_DEBUG, "Stop paging on bts %d silently.\n", bts->nr); paging_remove_request(&bts->paging, req); break; } -- cgit v1.2.3 From 1469600b0dcde77eaa4322b480b677fdf03e9cd0 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 9 Apr 2010 22:55:55 +0200 Subject: [paging] Start with a smaller paging limit... The value 20 is just a random number and it really depends on the number of TRX on a bts to be a sane or insane limit. --- openbsc/src/paging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index e0cb5313d..9a4f3657b 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -167,7 +167,7 @@ void paging_init(struct gsm_bts *bts) bts->paging.work_timer.data = &bts->paging; /* Large number, until we get a proper message */ - bts->paging.available_slots = 100; + bts->paging.available_slots = 20; } static int paging_pending_request(struct gsm_bts_paging_state *bts, -- cgit v1.2.3 From ae80f9291a8d6d4824ece720b9fecf9d669b116d Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 10 Apr 2010 00:05:16 +0200 Subject: Return anything from append_lsa_params. --- openbsc/src/rest_octets.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openbsc/src/rest_octets.c b/openbsc/src/rest_octets.c index 16996cec2..df27cf21e 100644 --- a/openbsc/src/rest_octets.c +++ b/openbsc/src/rest_octets.c @@ -133,6 +133,7 @@ static int append_lsa_params(struct bitvec *bv, const struct gsm48_lsa_params *lsa_params) { /* FIXME */ + return -1; } /* Generate SI4 Rest Octets (Chapter 10.5.2.35) */ -- cgit v1.2.3 From ef8117883b425995d5c05cecd47de4b454641e5b Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 10 Apr 2010 00:06:17 +0200 Subject: [paging] Include chan_alloc.h to silence a compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit paging.c:259: warning: implicit declaration of function ‘trx_is_usable’ --- openbsc/src/paging.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index 9a4f3657b..314d3d135 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -45,6 +45,7 @@ #include #include #include +#include void *tall_paging_ctx; -- cgit v1.2.3 From e1ffc08f724c678dc76b6c7a36dda280f065db47 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 10 Apr 2010 00:08:28 +0200 Subject: [vty] Forward declare the extra init function the base is calling --- openbsc/src/vty_interface.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index b5bdbc8c2..480b65836 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -1740,6 +1740,8 @@ DEFUN(cfg_ts_e1_subslot, return CMD_SUCCESS; } +extern int bsc_vty_init_extra(struct gsm_network *net); + int bsc_vty_init(struct gsm_network *net) { gsmnet = net; -- cgit v1.2.3 From 07ba16fe03594827e659b07fa25fb5c5c942422d Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 10 Apr 2010 00:08:59 +0200 Subject: [vty] Remove unused variables due them only being used in the layer3 I moved the extra code to the layer3 VTY implementation but didn't remove the variables while doign so, silent compiler warnings. --- openbsc/src/vty_interface.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index 480b65836..f74a041b6 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -540,10 +540,6 @@ DEFUN(show_ts, static void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr) { - int rc; - struct gsm_auth_info ainfo; - struct gsm_auth_tuple atuple; - vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id, subscr->authorized, VTY_NEWLINE); if (subscr->name) -- cgit v1.2.3 From ccfd57264786a513b81429d7d7064e216c4461af Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 9 Apr 2010 13:06:56 +0200 Subject: [rsl] Remove method that is not called by anything. --- openbsc/include/openbsc/abis_rsl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h index e6973eef0..ac0a17978 100644 --- a/openbsc/include/openbsc/abis_rsl.h +++ b/openbsc/include/openbsc/abis_rsl.h @@ -73,7 +73,6 @@ int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id); /* to be provided by external code */ int abis_rsl_sendmsg(struct msgb *msg); int rsl_deact_sacch(struct gsm_lchan *lchan); -int rsl_chan_release(struct gsm_lchan *lchan); /* BCCH related code */ int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf); -- cgit v1.2.3 From 74419497fccc93ef5acf6bc0d64f683c8bf25617 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 10 Apr 2010 00:12:31 +0200 Subject: [rsl] Introduce a method to set the state of the lchan Setting the state through a dedicated method allows us to track the state transitions and check if they are done in a proper way. --- openbsc/include/openbsc/abis_rsl.h | 2 ++ openbsc/src/abis_rsl.c | 18 ++++++++++++------ openbsc/src/handover_logic.c | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h index ac0a17978..8e6774d15 100644 --- a/openbsc/include/openbsc/abis_rsl.h +++ b/openbsc/include/openbsc/abis_rsl.h @@ -70,6 +70,8 @@ u_int64_t str_to_imsi(const char *imsi_str); u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan); int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id); +int rsl_lchan_set_state(struct gsm_lchan *lchan, int); + /* to be provided by external code */ int abis_rsl_sendmsg(struct msgb *msg); int rsl_deact_sacch(struct gsm_lchan *lchan); diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 0e385c18c..9cf34b497 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -727,7 +727,7 @@ int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id) link_id, 0); msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */ - lchan->state = LCHAN_S_REL_REQ; + rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ); /* FIXME: start some timer in case we don't receive a REL ACK ? */ msg->trx = lchan->ts->trx; @@ -735,6 +735,12 @@ int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id) return abis_rsl_sendmsg(msg); } +int rsl_lchan_set_state(struct gsm_lchan *lchan, int state) +{ + lchan->state = state; + return 0; +} + /* Chapter 8.4.2: Channel Activate Acknowledge */ static int rsl_rx_chan_act_ack(struct msgb *msg) { @@ -749,7 +755,7 @@ static int rsl_rx_chan_act_ack(struct msgb *msg) LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n", gsm_lchan_name(msg->lchan), gsm_lchans_name(msg->lchan->state)); - msg->lchan->state = LCHAN_S_ACTIVE; + rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE); dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan); @@ -775,9 +781,9 @@ static int rsl_rx_chan_act_nack(struct msgb *msg) print_rsl_cause(LOGL_ERROR, cause, TLVP_LEN(&tp, RSL_IE_CAUSE)); if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) - msg->lchan->state = LCHAN_S_NONE; + rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE); } else - msg->lchan->state = LCHAN_S_NONE; + rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE); LOGPC(DRSL, LOGL_ERROR, "\n"); @@ -981,7 +987,7 @@ static int abis_rsl_rx_dchan(struct msgb *msg) LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n", gsm_lchan_name(msg->lchan), gsm_lchans_name(msg->lchan->state)); - msg->lchan->state = LCHAN_S_NONE; + rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE); lchan_free(msg->lchan); break; case RSL_MT_MODE_MODIFY_ACK: @@ -1124,7 +1130,7 @@ static int rsl_rx_chan_rqd(struct msgb *msg) LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel " "in state %s\n", gsm_lchan_name(lchan), gsm_lchans_name(lchan->state)); - lchan->state = LCHAN_S_ACT_REQ; + rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ); ts_number = lchan->ts->nr; arfcn = lchan->ts->trx->arfcn; diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c index 7fb0b13e1..7352d6464 100644 --- a/openbsc/src/handover_logic.c +++ b/openbsc/src/handover_logic.c @@ -229,7 +229,7 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan) /* update lchan pointer of transaction */ trans_lchan_change(&ho->old_lchan->conn, &new_lchan->conn); - ho->old_lchan->state = LCHAN_S_INACTIVE; + rsl_lchan_set_state(ho->old_lchan, LCHAN_S_INACTIVE); lchan_auto_release(ho->old_lchan); /* do something to re-route the actual speech frames ! */ -- cgit v1.2.3 From 63d18b51a7fe76e05a0a3167205c5d61205fca98 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 10 Apr 2010 00:14:55 +0200 Subject: [rsl] Set the release state from within the lchan class Currently our GSM04.11 code is closing the link for SAPI=3 and this would mean that the whole channel would be scheduled for close... where we only want to close everything when freeing the lchan or handling an error. --- openbsc/src/abis_rsl.c | 1 - openbsc/src/chan_alloc.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 9cf34b497..ba1be99c8 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -727,7 +727,6 @@ int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id) link_id, 0); msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */ - rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ); /* FIXME: start some timer in case we don't receive a REL ACK ? */ msg->trx = lchan->ts->trx; diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c index cd48e4359..118deca10 100644 --- a/openbsc/src/chan_alloc.c +++ b/openbsc/src/chan_alloc.c @@ -348,6 +348,7 @@ int lchan_auto_release(struct gsm_lchan *lchan) lchan->conn.use_count); DEBUGP(DRLL, "%s Recycling Channel\n", gsm_lchan_name(lchan)); + rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ); rsl_release_request(lchan, 0); return 1; } -- cgit v1.2.3 From 5eec9d91d85edc7aac5c326f30d67036513c2dcf Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 10 Apr 2010 00:16:04 +0200 Subject: [rsl] Set the right state when asking for the activation. Set the state to activation to avoid a warning about the getting a CHAN ACK without waiting for it. We set it in the code to make sure it is set after all error checking to avoid inconsistent state as the state is only set back to NONE/ACT due replies from the BTS. --- openbsc/src/handover_logic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c index 7352d6464..b2ffe4616 100644 --- a/openbsc/src/handover_logic.c +++ b/openbsc/src/handover_logic.c @@ -134,6 +134,7 @@ int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts) return rc; } + rsl_lchan_set_state(new_lchan, LCHAN_S_ACT_REQ); llist_add(&ho->list, &bsc_handovers); /* we continue in the SS_LCHAN handler / ho_chan_activ_ack */ -- cgit v1.2.3 From 63cb447fd509954d5c32d3cf17a9f45d8ff0203e Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 11 Apr 2010 10:10:04 +0200 Subject: Revert "ipa: Reduce the throttling of the IPA msges" Reducing the throttling to this value created a regression with bringing up RSL on the nanoBTS 900. We do seem to have a bug/issue in the bsc_init code and might send a command too early without this longer wait period and then the state transition does not happen. For now it is agreed that reverting is the best thing to do. Debugged-by: Sylvain Munaut <246tnt@gmail.com> This reverts commit f5284ae1cf8babc1567b33f469e20a66a73fcd9e. --- openbsc/src/input/ipaccess.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c index 2449e261d..8722791bc 100644 --- a/openbsc/src/input/ipaccess.c +++ b/openbsc/src/input/ipaccess.c @@ -475,7 +475,9 @@ static int handle_ts1_write(struct bsc_fd *bfd) /* set tx delay timer for next event */ e1i_ts->sign.tx_timer.cb = timeout_ts1_write; e1i_ts->sign.tx_timer.data = e1i_ts; - bsc_schedule_timer(&e1i_ts->sign.tx_timer, 0, 100); + + /* Reducing this might break the nanoBTS 900 init. */ + bsc_schedule_timer(&e1i_ts->sign.tx_timer, 0, 100000); return ret; } -- cgit v1.2.3 From b998d7b219d66ab3e89e263aa345856e0bf97cbb Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Sun, 25 Oct 2009 17:48:42 +0100 Subject: abis_nm: Fix ACTIVATE SW parameters The previous code only sent the FILE_ID tag data part, but according to the GSM 12.21 spec, section 8.3.6, the full SW Description 'object' must be sent so that includes the NM_ATT_SW_DESCR tag, the whole FILE_ID and the whole FILE_VERSION (including tags & length fields). Note that functionnaly on a nanoBTS 139 I couldn't see any difference ... whatever I send in there it works ... Signed-off-by: Sylvain Munaut --- openbsc/src/abis_nm.c | 61 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c index 5e6e8196c..c78ee5699 100644 --- a/openbsc/src/abis_nm.c +++ b/openbsc/src/abis_nm.c @@ -822,15 +822,56 @@ static int ipacc_sw_activate(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i return abis_nm_sendmsg(bts, msg); } +static int abis_nm_parse_sw_descr(const u_int8_t *sw_descr, int sw_descr_len) +{ + static const struct tlv_definition sw_descr_def = { + .def = { + [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V, }, + [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V, }, + }, + }; + + u_int8_t tag; + u_int16_t tag_len; + const u_int8_t *val; + int ofs = 0, len; + + /* Classic TLV parsing doesn't work well with SW_DESCR because of it's + * nested nature and the fact you have to assume it contains only two sub + * tags NM_ATT_FILE_VERSION & NM_ATT_FILE_ID to parse it */ + + if (sw_descr[0] != NM_ATT_SW_DESCR) { + DEBUGP(DNM, "SW_DESCR attribute identifier not found!\n"); + return -1; + } + ofs += 1; + + len = tlv_parse_one(&tag, &tag_len, &val, + &sw_descr_def, &sw_descr[ofs], sw_descr_len-ofs); + if (len < 0 || (tag != NM_ATT_FILE_ID)) { + DEBUGP(DNM, "FILE_ID attribute identifier not found!\n"); + return -2; + } + ofs += len; + + len = tlv_parse_one(&tag, &tag_len, &val, + &sw_descr_def, &sw_descr[ofs], sw_descr_len-ofs); + if (len < 0 || (tag != NM_ATT_FILE_VERSION)) { + DEBUGP(DNM, "FILE_VERSION attribute identifier not found!\n"); + return -3; + } + ofs += len; + + return ofs; +} + static int abis_nm_rx_sw_act_req(struct msgb *mb) { struct abis_om_hdr *oh = msgb_l2(mb); struct abis_om_fom_hdr *foh = msgb_l3(mb); struct tlv_parsed tp; const u_int8_t *sw_config; - int sw_config_len; - int file_id_len; - int ret; + int ret, sw_config_len, sw_descr_len; debugp_foh(foh); @@ -854,20 +895,16 @@ static int abis_nm_rx_sw_act_req(struct msgb *mb) DEBUGP(DNM, "Found SW config: %s\n", hexdump(sw_config, sw_config_len)); } - if (sw_config[0] != NM_ATT_SW_DESCR) - DEBUGP(DNM, "SW_DESCR attribute identifier not found!\n"); - if (sw_config[1] != NM_ATT_FILE_ID) - DEBUGP(DNM, "FILE_ID attribute identifier not found!\n"); - file_id_len = sw_config[2] * 256 + sw_config[3]; + /* Use the first SW_DESCR present in SW config */ + sw_descr_len = abis_nm_parse_sw_descr(sw_config, sw_config_len); + if (sw_descr_len < 0) + return -EINVAL; - /* Assumes first SW file in list is the one to be activated */ - /* sw_config + 4 to skip over 2 attribute ID bytes and 16-bit length field */ return ipacc_sw_activate(mb->trx->bts, foh->obj_class, foh->obj_inst.bts_nr, foh->obj_inst.trx_nr, foh->obj_inst.ts_nr, - sw_config + 4, - file_id_len); + sw_config, sw_descr_len); } /* Receive a CHANGE_ADM_STATE_ACK, parse the TLV and update local state */ -- cgit v1.2.3 From b54dda4cefe89665d98074cf3767858fa6ecdb6e Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Sun, 20 Dec 2009 22:06:40 +0100 Subject: ipaccess: Send RTP Payload IE for CRCX & MDCX For GSM V1 FR, the payload type is fixed to 3 in the RFC. But for the other codecs, the payload type is dynamically assigned between 96 and 127. Here, we use a static mapping internal to OpenBSC. This patch is needed to make a rather old 139 unit (with sw version 120a002_v149b42d0) work with something else than FR codec. I also tested this patch on a newer 139 (with sw version 120a352_v267b22d0) to make sure it didn't add a regression. More testing with newer EDGE units should be done by whoever has some of theses. Signed-off-by: Sylvain Munaut --- openbsc/include/openbsc/gsm_data.h | 1 + openbsc/include/openbsc/rtp_proxy.h | 6 +++++ openbsc/src/abis_rsl.c | 54 +++++++++++++++++++++++++++++++++---- openbsc/src/rtp_proxy.c | 3 --- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index ef0b50768..68d3deebf 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -250,6 +250,7 @@ struct gsm_lchan { u_int16_t bound_port; u_int16_t connect_port; u_int16_t conn_id; + u_int8_t rtp_payload; u_int8_t rtp_payload2; u_int8_t speech_mode; struct rtp_socket *rtp_socket; diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h index f82711a8e..65b1a5fac 100644 --- a/openbsc/include/openbsc/rtp_proxy.h +++ b/openbsc/include/openbsc/rtp_proxy.h @@ -28,6 +28,12 @@ #include #include +#define RTP_PT_GSM_FULL 3 +#define RTP_PT_GSM_HALF 96 +#define RTP_PT_GSM_EFR 97 +#define RTP_PT_AMR_FULL 98 +#define RTP_PT_AMR_HALF 99 + enum rtp_rx_action { RTP_NONE, RTP_PROXY, diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index ba1be99c8..343347aa5 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -1368,6 +1368,44 @@ static u_int8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan) return 0; } +static u_int8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan) +{ + switch (lchan->tch_mode) { + case GSM48_CMODE_SPEECH_V1: + switch (lchan->type) { + case GSM_LCHAN_TCH_F: + return RTP_PT_GSM_FULL; + case GSM_LCHAN_TCH_H: + return RTP_PT_GSM_HALF; + default: + break; + } + case GSM48_CMODE_SPEECH_EFR: + switch (lchan->type) { + case GSM_LCHAN_TCH_F: + return RTP_PT_GSM_EFR; + /* there's no half-rate EFR */ + default: + break; + } + case GSM48_CMODE_SPEECH_AMR: + switch (lchan->type) { + case GSM_LCHAN_TCH_F: + return RTP_PT_AMR_FULL; + case GSM_LCHAN_TCH_H: + return RTP_PT_AMR_HALF; + default: + break; + } + default: + break; + } + LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for " + "tch_mode == 0x%02x\n & lchan_type == %d", + lchan->tch_mode, lchan->type); + return 0; +} + /* ip.access specific RSL extensions */ static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv) { @@ -1434,10 +1472,13 @@ int rsl_ipacc_crcx(struct gsm_lchan *lchan) /* 0x1- == receive-only, 0x-1 == EFR codec */ lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan); + lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan); msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode); + msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload); - DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x\n", - gsm_lchan_name(lchan), lchan->abis_ip.speech_mode); + DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n", + gsm_lchan_name(lchan), lchan->abis_ip.speech_mode, + lchan->abis_ip.rtp_payload); msg->trx = lchan->ts->trx; @@ -1464,11 +1505,13 @@ int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port, /* 0x0- == both directions, 0x-1 == EFR codec */ lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan); + lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan); ia.s_addr = htonl(ip); - DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d " - "speech_mode=0x%02x\n", gsm_lchan_name(lchan), inet_ntoa(ia), port, - rtp_payload2, lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode); + DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d " + "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan), + inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2, + lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode); msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id); msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP); @@ -1476,6 +1519,7 @@ int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port, *att_ip = ia.s_addr; msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port); msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode); + msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload); if (rtp_payload2) msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2); diff --git a/openbsc/src/rtp_proxy.c b/openbsc/src/rtp_proxy.c index 375204e97..924173dd2 100644 --- a/openbsc/src/rtp_proxy.c +++ b/openbsc/src/rtp_proxy.c @@ -91,9 +91,6 @@ struct rtp_x_hdr { #define RTP_VERSION 2 -#define RTP_PT_GSM_FULL 3 -#define RTP_PT_GSM_EFR 97 - /* decode an rtp frame and create a new buffer with payload */ static int rtp_decode(struct msgb *msg, u_int32_t callref, struct msgb **data) { -- cgit v1.2.3 From 70402a4e4ddc0f7ee584445c9c3ac7dc91fe374b Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 15 Apr 2010 11:17:24 +0200 Subject: [ipa] Handle losing the RSL/OML connection.. This is addressing multiple issues regarding the loss of the OML/RSL link to the BTS. 1.) When we lose the OML link, close down all RSL connections on all TRXs (only tested with one TRX) and free the e1inp_line allocated for the OML connection. 2.) When we lose the RSL link on any TRX and we know to which lines this connection belongs, we will close down the OML connection as we have a problem to just reactivate one RSL link. 3.) When we lose the RSL link on any TRX and we do not know where it belongs to we will free the bfd we have allocated in the rsl listen/accept method and we properly close the socket (i could not test this one properly). This is made under the assumption the BTS has not responded to the ID request. 4.) When we already have a bts->oml_link we will throw it away and use the new link (it should not happen) and the same applies to the rsl link. --- openbsc/include/openbsc/ipaccess.h | 2 + openbsc/src/input/ipaccess.c | 147 ++++++++++++++++++++++++++++++------- 2 files changed, 123 insertions(+), 26 deletions(-) diff --git a/openbsc/include/openbsc/ipaccess.h b/openbsc/include/openbsc/ipaccess.h index 86248aae5..f8ddfd467 100644 --- a/openbsc/include/openbsc/ipaccess.h +++ b/openbsc/include/openbsc/ipaccess.h @@ -53,6 +53,8 @@ int ipaccess_send_id_req(int fd); int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len); +int ipaccess_drop_oml(struct gsm_bts *bts); +int ipaccess_drop_rsl(struct gsm_bts_trx *trx); /* * Firmware specific header diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c index 8722791bc..8fb9d3a8e 100644 --- a/openbsc/src/input/ipaccess.c +++ b/openbsc/src/input/ipaccess.c @@ -1,6 +1,8 @@ /* OpenBSC Abis input driver for ip.access */ /* (C) 2009 by Harald Welte + * (C) 2010 by Holger Hans Peter Freyther + * (C) 2010 by On-Waves * * All Rights Reserved * @@ -234,6 +236,8 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg, } DEBUGP(DINP, "Identified BTS %u/%u/%u\n", site_id, bts_id, trx_id); if (bfd->priv_nr == PRIV_OML) { + /* drop any old oml connection */ + ipaccess_drop_oml(bts); bts->oml_link = e1inp_sign_link_create(&line->ts[PRIV_OML - 1], E1INP_SIGN_OML, bts->c0, bts->oml_tei, 0); @@ -241,7 +245,18 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg, struct e1inp_ts *e1i_ts; struct bsc_fd *newbfd; struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_id); - + + /* drop any old rsl connection */ + ipaccess_drop_rsl(trx); + + if (!bts->oml_link) { + bsc_unregister_fd(bfd); + close(bfd->fd); + bfd->fd = -1; + talloc_free(bfd); + return 0; + } + bfd->data = line = bts->oml_link->ts->line; e1i_ts = &line->ts[PRIV_RSL + trx_id - 1]; newbfd = &e1i_ts->driver.ipaccess.fd; @@ -251,19 +266,13 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg, E1INP_SIGN_RSL, trx, trx->rsl_tei, 0); - if (newbfd->fd >= 0) { - LOGP(DINP, LOGL_ERROR, "BTS is still registered. Closing old connection.\n"); - bsc_unregister_fd(newbfd); - close(newbfd->fd); - newbfd->fd = -1; - } - /* get rid of our old temporary bfd */ memcpy(newbfd, bfd, sizeof(*newbfd)); newbfd->priv_nr = PRIV_RSL + trx_id; bsc_unregister_fd(bfd); - bsc_register_fd(newbfd); + bfd->fd = -1; talloc_free(bfd); + bsc_register_fd(newbfd); } break; } @@ -328,6 +337,103 @@ struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error) return msg; } +int ipaccess_drop_oml(struct gsm_bts *bts) +{ + struct gsm_bts_trx *trx; + struct e1inp_ts *ts; + struct e1inp_line *line; + struct bsc_fd *bfd; + + if (!bts || !bts->oml_link) + return -1; + + /* send OML down */ + ts = bts->oml_link->ts; + line = ts->line; + e1inp_event(ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_OML); + + bfd = &ts->driver.ipaccess.fd; + bsc_unregister_fd(bfd); + close(bfd->fd); + bfd->fd = -1; + + /* clean up OML and RSL */ + e1inp_sign_link_destroy(bts->oml_link); + bts->oml_link = NULL; + bts->ip_access.flags = 0; + + /* drop all RSL connections too */ + llist_for_each_entry(trx, &bts->trx_list, list) + ipaccess_drop_rsl(trx); + + /* kill the E1 line now... as we have no one left to use it */ + talloc_free(line); + + return -1; +} + +static int ipaccess_drop(struct e1inp_ts *ts, struct bsc_fd *bfd) +{ + struct e1inp_sign_link *link; + int bts_nr; + + if (!ts) { + /* + * If we don't have a TS this means that this is a RSL + * connection but we are not past the authentication + * handling yet. So we can safely delete this bfd and + * wait for a reconnect. + */ + bsc_unregister_fd(bfd); + close(bfd->fd); + bfd->fd = -1; + talloc_free(bfd); + return -1; + } + + /* attempt to find a signalling link */ + if (ts->type == E1INP_TS_TYPE_SIGN) { + llist_for_each_entry(link, &ts->sign.sign_links, list) { + bts_nr = link->trx->bts->bts_nr; + /* we have issues just reconnecting RLS so we drop OML */ + ipaccess_drop_oml(link->trx->bts); + return bts_nr; + } + } + + /* error case */ + LOGP(DINP, LOGL_ERROR, "Failed to find a signalling link for ts: %p\n", ts); + bsc_unregister_fd(bfd); + close(bfd->fd); + bfd->fd = -1; + return -1; +} + +int ipaccess_drop_rsl(struct gsm_bts_trx *trx) +{ + struct bsc_fd *bfd; + struct e1inp_ts *ts; + + if (!trx || !trx->rsl_link) + return -1; + + /* send RSL down */ + ts = trx->rsl_link->ts; + e1inp_event(ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_RSL); + + /* close the socket */ + bfd = &ts->driver.ipaccess.fd; + bsc_unregister_fd(bfd); + close(bfd->fd); + bfd->fd = -1; + + /* destroy */ + e1inp_sign_link_destroy(trx->rsl_link); + trx->rsl_link = NULL; + + return -1; +} + static int handle_ts1_read(struct bsc_fd *bfd) { struct e1inp_line *line = bfd->data; @@ -341,18 +447,12 @@ static int handle_ts1_read(struct bsc_fd *bfd) msg = ipaccess_read_msg(bfd, &error); if (!msg) { if (error == 0) { - link = e1inp_lookup_sign_link(e1i_ts, IPAC_PROTO_OML, 0); - if (link) { - link->trx->bts->ip_access.flags = 0; + int ret = ipaccess_drop(e1i_ts, bfd); + if (ret >= 0) LOGP(DINP, LOGL_NOTICE, "BTS %u disappeared, dead socket\n", - link->trx->bts->nr); - } else + ret); + else LOGP(DINP, LOGL_NOTICE, "unknown BTS disappeared, dead socket\n"); - e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_RSL); - e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_OML); - bsc_unregister_fd(bfd); - close(bfd->fd); - bfd->fd = -1; } return error; } @@ -362,13 +462,8 @@ static int handle_ts1_read(struct bsc_fd *bfd) hh = (struct ipaccess_head *) msg->data; if (hh->proto == IPAC_PROTO_IPACCESS) { ret = ipaccess_rcvmsg(line, msg, bfd); - if (ret < 0) { - e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_RSL); - e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_OML); - bsc_unregister_fd(bfd); - close(bfd->fd); - bfd->fd = -1; - } + if (ret < 0) + ipaccess_drop(e1i_ts, bfd); msgb_free(msg); return ret; } -- cgit v1.2.3 From f8eff2e4b537c00cfc8a17991759df0f58a29148 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 11 Apr 2010 18:54:58 +0200 Subject: [ipa] Fix the reporting of link down... Now bsc_init.c is able to handle the link down messages. --- openbsc/src/input/ipaccess.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c index 8fb9d3a8e..8a8a1987d 100644 --- a/openbsc/src/input/ipaccess.c +++ b/openbsc/src/input/ipaccess.c @@ -350,7 +350,7 @@ int ipaccess_drop_oml(struct gsm_bts *bts) /* send OML down */ ts = bts->oml_link->ts; line = ts->line; - e1inp_event(ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_OML); + e1inp_event(ts, EVT_E1_TEI_DN, bts->oml_link->tei, bts->oml_link->sapi); bfd = &ts->driver.ipaccess.fd; bsc_unregister_fd(bfd); @@ -419,7 +419,7 @@ int ipaccess_drop_rsl(struct gsm_bts_trx *trx) /* send RSL down */ ts = trx->rsl_link->ts; - e1inp_event(ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_RSL); + e1inp_event(ts, EVT_E1_TEI_DN, trx->rsl_link->tei, trx->rsl_link->sapi); /* close the socket */ bfd = &ts->driver.ipaccess.fd; -- cgit v1.2.3 From 135f797a3711d317a9aef43f0efa9fb8764a0d10 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 15 Apr 2010 11:21:02 +0200 Subject: [bsc_init] When the RSL/OML connection drops, free all lchans Free all allocated channels on the TRX that failed, go through lchan_free to signal higher layers and then force a reset of the channel. Make the TRX and TS unusable by setting the operational set to 0 (not really defined) which should be reset once the RSL is coming up again. --- openbsc/include/openbsc/chan_alloc.h | 1 + openbsc/src/bsc_init.c | 29 +++++++++++++++++++++++++++-- openbsc/src/chan_alloc.c | 14 ++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h index f564e9e4d..d4f5858b7 100644 --- a/openbsc/include/openbsc/chan_alloc.h +++ b/openbsc/include/openbsc/chan_alloc.h @@ -45,6 +45,7 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type); /* Free a logical channel (SDCCH, TCH, ...) */ void lchan_free(struct gsm_lchan *lchan); +void lchan_reset(struct gsm_lchan *lchan); /* Consider releasing the channel */ int lchan_auto_release(struct gsm_lchan *lchan); diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c index f3436621f..fccdb0cd8 100644 --- a/openbsc/src/bsc_init.c +++ b/openbsc/src/bsc_init.c @@ -31,6 +31,7 @@ #include #include #include +#include #include /* global pointer to the gsm network data structure */ @@ -899,6 +900,8 @@ static void bootstrap_rsl(struct gsm_bts_trx *trx) void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx) { + int ts_no, lchan_no; + switch (event) { case EVT_E1_TEI_UP: switch (type) { @@ -913,8 +916,30 @@ void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx) } break; case EVT_E1_TEI_DN: - LOGP(DMI, LOGL_NOTICE, "Lost some E1 TEI link\n"); - /* FIXME: deal with TEI or L1 link loss */ + LOGP(DMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", type, trx); + + /* + * free all allocated channels. change the nm_state so the + * trx and trx_ts becomes unusable and chan_alloc.c can not + * allocate from it. + */ + for (ts_no = 0; ts_no < ARRAY_SIZE(trx->ts); ++ts_no) { + struct gsm_bts_trx_ts *ts = &trx->ts[ts_no]; + + for (lchan_no = 0; lchan_no < ARRAY_SIZE(ts->lchan); ++lchan_no) { + if (ts->lchan[lchan_no].state != GSM_LCHAN_NONE) + lchan_free(&ts->lchan[lchan_no]); + lchan_reset(&ts->lchan[lchan_no]); + } + + ts->nm_state.operational = 0; + ts->nm_state.availability = 0; + } + + trx->nm_state.operational = 0; + trx->nm_state.availability = 0; + trx->bb_transc.nm_state.operational = 0; + trx->bb_transc.nm_state.availability = 0; break; default: break; diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c index 118deca10..107abdc92 100644 --- a/openbsc/src/chan_alloc.c +++ b/openbsc/src/chan_alloc.c @@ -330,6 +330,20 @@ void lchan_free(struct gsm_lchan *lchan) * channel using it */ } +/* + * There was an error with the TRX and we need to forget + * any state so that a lchan can be allocated again after + * the trx is fully usable. + */ +void lchan_reset(struct gsm_lchan *lchan) +{ + bsc_del_timer(&lchan->T3101); + + lchan->type = GSM_LCHAN_NONE; + lchan->state = LCHAN_S_NONE; +} + + /* Consider releasing the channel now */ int lchan_auto_release(struct gsm_lchan *lchan) { -- cgit v1.2.3 From 2d425059af3339a86aea70857997ccb43dc1a908 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 13 Apr 2010 09:28:40 +0200 Subject: [mgcp] Only write audio_name/payload when it is actually set. --- openbsc/src/mgcp/mgcp_vty.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c index 743f3fd07..6bfb28784 100644 --- a/openbsc/src/mgcp/mgcp_vty.c +++ b/openbsc/src/mgcp/mgcp_vty.c @@ -55,8 +55,10 @@ static int config_write_mgcp(struct vty *vty) vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE); vty_out(vty, " bind early %u%s", !!g_cfg->early_bind, VTY_NEWLINE); vty_out(vty, " rtp base %u%s", g_cfg->rtp_base_port, VTY_NEWLINE); - vty_out(vty, " sdp audio payload number %u%s", g_cfg->audio_payload, VTY_NEWLINE); - vty_out(vty, " sdp audio payload name %s%s", g_cfg->audio_name, VTY_NEWLINE); + if (g_cfg->audio_payload != -1) + vty_out(vty, " sdp audio payload number %d%s", g_cfg->audio_payload, VTY_NEWLINE); + if (g_cfg->audio_name) + vty_out(vty, " sdp audio payload name %s%s", g_cfg->audio_name, VTY_NEWLINE); vty_out(vty, " loop %u%s", !!g_cfg->audio_loop, VTY_NEWLINE); vty_out(vty, " endpoints %u%s", g_cfg->number_endpoints, VTY_NEWLINE); if (g_cfg->forward_ip) -- cgit v1.2.3 From e0ec32686792bd962f4efb6122be8769b1b832b9 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 15 Apr 2010 11:28:14 +0200 Subject: [vty] Separate BSC and MSC statistics. Make it easy to print them. Move the statistics command into the MSC part and move the BSC statistics printing into a subroutine. --- openbsc/include/openbsc/vty.h | 4 ++++ openbsc/src/vty_interface.c | 41 -------------------------------------- openbsc/src/vty_interface_cmds.c | 11 ++++++++++ openbsc/src/vty_interface_layer3.c | 37 ++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 41 deletions(-) diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h index 40e219162..f1b1148ad 100644 --- a/openbsc/include/openbsc/vty.h +++ b/openbsc/include/openbsc/vty.h @@ -1,6 +1,10 @@ #ifndef OPENBSC_VTY_H #define OPENBSC_VTY_H +struct gsm_network; +struct vty; + void openbsc_vty_add_cmds(void); +void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *); #endif diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index f74a041b6..bcf4a87ff 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -875,46 +875,6 @@ DEFUN(show_paging, return CMD_SUCCESS; } -DEFUN(show_stats, - show_stats_cmd, - "show statistics", - SHOW_STR "Display network statistics\n") -{ - struct gsm_network *net = gsmnet; - - vty_out(vty, "Channel Requests : %lu total, %lu no channel%s", - counter_get(net->stats.chreq.total), - counter_get(net->stats.chreq.no_channel), VTY_NEWLINE); - vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s", - counter_get(net->stats.loc_upd_type.attach), - counter_get(net->stats.loc_upd_type.normal), - counter_get(net->stats.loc_upd_type.periodic), VTY_NEWLINE); - vty_out(vty, "IMSI Detach Indications : %lu%s", - counter_get(net->stats.loc_upd_type.detach), VTY_NEWLINE); - vty_out(vty, "Location Update Response: %lu accept, %lu reject%s", - counter_get(net->stats.loc_upd_resp.accept), - counter_get(net->stats.loc_upd_resp.reject), VTY_NEWLINE); - vty_out(vty, "Paging : %lu attempted, %lu complete, %lu expired%s", - counter_get(net->stats.paging.attempted), - counter_get(net->stats.paging.completed), - counter_get(net->stats.paging.expired), VTY_NEWLINE); - vty_out(vty, "Handover : %lu attempted, %lu no_channel, %lu timeout, " - "%lu completed, %lu failed%s", - counter_get(net->stats.handover.attempted), - counter_get(net->stats.handover.no_channel), - counter_get(net->stats.handover.timeout), - counter_get(net->stats.handover.completed), - counter_get(net->stats.handover.failed), VTY_NEWLINE); - vty_out(vty, "SMS MO : %lu submitted, %lu no receiver%s", - counter_get(net->stats.sms.submitted), - counter_get(net->stats.sms.no_receiver), VTY_NEWLINE); - vty_out(vty, "SMS MT : %lu delivered, %lu no memory, %lu other error%s", - counter_get(net->stats.sms.delivered), - counter_get(net->stats.sms.rp_err_mem), - counter_get(net->stats.sms.rp_err_other), VTY_NEWLINE); - return CMD_SUCCESS; -} - DEFUN(cfg_net, cfg_net_cmd, "network", @@ -1756,7 +1716,6 @@ int bsc_vty_init(struct gsm_network *net) install_element(VIEW_NODE, &show_e1ts_cmd); install_element(VIEW_NODE, &show_paging_cmd); - install_element(VIEW_NODE, &show_stats_cmd); openbsc_vty_add_cmds(); diff --git a/openbsc/src/vty_interface_cmds.c b/openbsc/src/vty_interface_cmds.c index d4945840e..623aa30df 100644 --- a/openbsc/src/vty_interface_cmds.c +++ b/openbsc/src/vty_interface_cmds.c @@ -228,6 +228,17 @@ DEFUN(diable_logging, return CMD_SUCCESS; } +void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net) +{ + vty_out(vty, "Channel Requests : %lu total, %lu no channel%s", + counter_get(net->stats.chreq.total), + counter_get(net->stats.chreq.no_channel), VTY_NEWLINE); + vty_out(vty, "Paging : %lu attempted, %lu complete, %lu expired%s", + counter_get(net->stats.paging.attempted), + counter_get(net->stats.paging.completed), + counter_get(net->stats.paging.expired), VTY_NEWLINE); +} + void openbsc_vty_add_cmds() { install_element(VIEW_NODE, &enable_logging_cmd); diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c index b824c3db6..5e3098289 100644 --- a/openbsc/src/vty_interface_layer3.c +++ b/openbsc/src/vty_interface_layer3.c @@ -41,6 +41,7 @@ #include #include #include +#include static struct gsm_network *gsmnet; @@ -502,6 +503,41 @@ static int scall_cbfn(unsigned int subsys, unsigned int signal, return 0; } +DEFUN(show_stats, + show_stats_cmd, + "show statistics", + SHOW_STR "Display network statistics\n") +{ + struct gsm_network *net = gsmnet; + + openbsc_vty_print_statistics(vty, net); + vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s", + counter_get(net->stats.loc_upd_type.attach), + counter_get(net->stats.loc_upd_type.normal), + counter_get(net->stats.loc_upd_type.periodic), VTY_NEWLINE); + vty_out(vty, "IMSI Detach Indications : %lu%s", + counter_get(net->stats.loc_upd_type.detach), VTY_NEWLINE); + vty_out(vty, "Location Update Response: %lu accept, %lu reject%s", + counter_get(net->stats.loc_upd_resp.accept), + counter_get(net->stats.loc_upd_resp.reject), VTY_NEWLINE); + vty_out(vty, "Handover : %lu attempted, %lu no_channel, %lu timeout, " + "%lu completed, %lu failed%s", + counter_get(net->stats.handover.attempted), + counter_get(net->stats.handover.no_channel), + counter_get(net->stats.handover.timeout), + counter_get(net->stats.handover.completed), + counter_get(net->stats.handover.failed), VTY_NEWLINE); + vty_out(vty, "SMS MO : %lu submitted, %lu no receiver%s", + counter_get(net->stats.sms.submitted), + counter_get(net->stats.sms.no_receiver), VTY_NEWLINE); + vty_out(vty, "SMS MT : %lu delivered, %lu no memory, %lu other error%s", + counter_get(net->stats.sms.delivered), + counter_get(net->stats.sms.rp_err_mem), + counter_get(net->stats.sms.rp_err_other), VTY_NEWLINE); + return CMD_SUCCESS; +} + + int bsc_vty_init_extra(struct gsm_network *net) { gsmnet = net; @@ -517,6 +553,7 @@ int bsc_vty_init_extra(struct gsm_network *net) install_element(VIEW_NODE, &subscriber_silent_sms_cmd); install_element(VIEW_NODE, &subscriber_silent_call_start_cmd); install_element(VIEW_NODE, &subscriber_silent_call_stop_cmd); + install_element(VIEW_NODE, &show_stats_cmd); install_element(CONFIG_NODE, &cfg_subscr_cmd); install_node(&subscr_node, dummy_config_write); -- cgit v1.2.3 From 2ba40afc36c1abfa4b0777fb5dc4eb6ac8179d3a Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 17 Apr 2010 06:42:07 +0200 Subject: Add rf_locked to the configuration writing. --- openbsc/src/vty_interface.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index bcf4a87ff..2f8c1b3e0 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -266,6 +266,9 @@ static void config_write_trx_single(struct vty *vty, struct gsm_bts_trx *trx) int i; vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE); + vty_out(vty, " rf_locked %u%s", + trx->nm_state.administrative == NM_STATE_LOCKED ? 1 : 0, + VTY_NEWLINE); vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE); vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE); vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE); -- cgit v1.2.3 From 8d9833ef8376a144ef384d0f47b5c67bd0a1f6e2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 16 Apr 2010 16:59:48 +0200 Subject: [mgcp] Fix vty file generation for the BSC nat and other cases The current setting was not properly written out, this commit is fixing it. This includes indention, empty bts ip, wrong command for endpoints and the wrong number (+1 as zero is allocated but unused). --- openbsc/src/mgcp/mgcp_vty.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c index 6bfb28784..bf5d15f0b 100644 --- a/openbsc/src/mgcp/mgcp_vty.c +++ b/openbsc/src/mgcp/mgcp_vty.c @@ -33,6 +33,8 @@ #include #include +#include + static struct mgcp_config *g_cfg = NULL; /* @@ -48,8 +50,8 @@ static int config_write_mgcp(struct vty *vty) { vty_out(vty, "mgcp%s", VTY_NEWLINE); if (g_cfg->local_ip) - vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE); - if (g_cfg->bts_ip) + vty_out(vty, " local ip %s%s", g_cfg->local_ip, VTY_NEWLINE); + if (g_cfg->bts_ip && strlen(g_cfg->bts_ip) != 0) vty_out(vty, " bts ip %s%s", g_cfg->bts_ip, VTY_NEWLINE); vty_out(vty, " bind ip %s%s", g_cfg->source_addr, VTY_NEWLINE); vty_out(vty, " bind port %u%s", g_cfg->source_port, VTY_NEWLINE); @@ -60,13 +62,13 @@ static int config_write_mgcp(struct vty *vty) if (g_cfg->audio_name) vty_out(vty, " sdp audio payload name %s%s", g_cfg->audio_name, VTY_NEWLINE); vty_out(vty, " loop %u%s", !!g_cfg->audio_loop, VTY_NEWLINE); - vty_out(vty, " endpoints %u%s", g_cfg->number_endpoints, VTY_NEWLINE); + vty_out(vty, " number endpoints %u%s", g_cfg->number_endpoints - 1, VTY_NEWLINE); if (g_cfg->forward_ip) - vty_out(vty, " forward audio ip %s%s", g_cfg->forward_ip, VTY_NEWLINE); + vty_out(vty, " forward audio ip %s%s", g_cfg->forward_ip, VTY_NEWLINE); if (g_cfg->forward_port != 0) - vty_out(vty, " forward audio port %d%s", g_cfg->forward_port, VTY_NEWLINE); + vty_out(vty, " forward audio port %d%s", g_cfg->forward_port, VTY_NEWLINE); if (g_cfg->call_agent_addr) - vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE); + vty_out(vty, " call agent ip %s%s", g_cfg->call_agent_addr, VTY_NEWLINE); return CMD_SUCCESS; } -- cgit v1.2.3 From 3ba36d5b57f5964b9bdc2fd1e5ee7d0d9fd398dd Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 17 Apr 2010 06:48:29 +0200 Subject: [statistics] Keep track of rf failures and rll release failures Add two new counters to count the RF Failures and the RLL Release failure and make them available via the vty interface. --- openbsc/include/openbsc/gsm_data.h | 4 ++++ openbsc/src/abis_rsl.c | 5 ++++- openbsc/src/gsm_data.c | 2 ++ openbsc/src/vty_interface_cmds.c | 3 +++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 68d3deebf..2db98de97 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -535,6 +535,10 @@ struct gsmnet_stats { struct counter *alerted; /* we alerted the other end */ struct counter *connected;/* how many calls were accepted */ } call; + struct { + struct counter *rf_fail; + struct counter *rll_err; + } chan; }; enum gsm_auth_policy { diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 343347aa5..bbce67a96 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -810,6 +810,7 @@ static int rsl_rx_conn_fail(struct msgb *msg) LOGPC(DRSL, LOGL_NOTICE, "\n"); /* FIXME: only free it after channel release ACK */ + counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail); return rsl_rf_chan_release(msg->lchan); } @@ -1245,8 +1246,10 @@ static int rsl_rx_rll_err_ind(struct msgb *msg) rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND); - if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) + if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) { + counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err); return rsl_rf_chan_release(msg->lchan); + } return 0; } diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index 176367dc7..f837c2709 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -280,6 +280,8 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c net->stats.call.dialled = counter_alloc("net.call.dialled"); net->stats.call.alerted = counter_alloc("net.call.alerted"); net->stats.call.connected = counter_alloc("net.call.connected"); + net->stats.chan.rf_fail = counter_alloc("net.chan.rf_fail"); + net->stats.chan.rll_err = counter_alloc("net.chan.rll_err"); net->mncc_recv = mncc_recv; diff --git a/openbsc/src/vty_interface_cmds.c b/openbsc/src/vty_interface_cmds.c index 623aa30df..8ade51851 100644 --- a/openbsc/src/vty_interface_cmds.c +++ b/openbsc/src/vty_interface_cmds.c @@ -233,6 +233,9 @@ void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net) vty_out(vty, "Channel Requests : %lu total, %lu no channel%s", counter_get(net->stats.chreq.total), counter_get(net->stats.chreq.no_channel), VTY_NEWLINE); + vty_out(vty, "Channel Failures : %lu rf_failures, %lu rll failures%s", + counter_get(net->stats.chan.rf_fail), + counter_get(net->stats.chan.rll_err), VTY_NEWLINE); vty_out(vty, "Paging : %lu attempted, %lu complete, %lu expired%s", counter_get(net->stats.paging.attempted), counter_get(net->stats.paging.completed), -- cgit v1.2.3 From bb110f91e8fd5c190f974ef3b9cb9a1118beb592 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 12 Apr 2010 10:45:52 +0200 Subject: [statistics] Keep track of OML/RSL failures of the BTS. --- openbsc/include/openbsc/gsm_data.h | 4 ++++ openbsc/src/bsc_init.c | 5 +++++ openbsc/src/gsm_data.c | 2 ++ openbsc/src/vty_interface_cmds.c | 3 +++ 4 files changed, 14 insertions(+) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 2db98de97..a2f0e406c 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -539,6 +539,10 @@ struct gsmnet_stats { struct counter *rf_fail; struct counter *rll_err; } chan; + struct { + struct counter *oml_fail; + struct counter *rsl_fail; + } bts; }; enum gsm_auth_policy { diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c index fccdb0cd8..94576b796 100644 --- a/openbsc/src/bsc_init.c +++ b/openbsc/src/bsc_init.c @@ -918,6 +918,11 @@ void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx) case EVT_E1_TEI_DN: LOGP(DMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", type, trx); + if (type == E1INP_SIGN_OML) + counter_inc(trx->bts->network->stats.bts.oml_fail); + else if (type == E1INP_SIGN_RSL) + counter_inc(trx->bts->network->stats.bts.rsl_fail); + /* * free all allocated channels. change the nm_state so the * trx and trx_ts becomes unusable and chan_alloc.c can not diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index f837c2709..4af46e487 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -282,6 +282,8 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c net->stats.call.connected = counter_alloc("net.call.connected"); net->stats.chan.rf_fail = counter_alloc("net.chan.rf_fail"); net->stats.chan.rll_err = counter_alloc("net.chan.rll_err"); + net->stats.bts.oml_fail = counter_alloc("net.bts.oml_fail"); + net->stats.bts.rsl_fail = counter_alloc("net.bts.rsl_fail"); net->mncc_recv = mncc_recv; diff --git a/openbsc/src/vty_interface_cmds.c b/openbsc/src/vty_interface_cmds.c index 8ade51851..671351e1c 100644 --- a/openbsc/src/vty_interface_cmds.c +++ b/openbsc/src/vty_interface_cmds.c @@ -240,6 +240,9 @@ void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net) counter_get(net->stats.paging.attempted), counter_get(net->stats.paging.completed), counter_get(net->stats.paging.expired), VTY_NEWLINE); + vty_out(vty, "BTS failures : %lu OML, %lu RSL%s", + counter_get(net->stats.bts.oml_fail), + counter_get(net->stats.bts.rsl_fail), VTY_NEWLINE); } void openbsc_vty_add_cmds() -- cgit v1.2.3 From 6ba3bcbbc69050f1a336c416db7a42d90b2948b0 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 16 Mar 2010 00:56:08 +0800 Subject: BVCI 0 is not within the permitted range --- openbsc/src/vty_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index 2f8c1b3e0..e5290c98f 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -1392,7 +1392,7 @@ DEFUN(cfg_bts_per_loc_upd, cfg_bts_per_loc_upd_cmd, } DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd, - "gprs cell bvci <0-65535>", + "gprs cell bvci <1-65535>", "GPRS BSSGP VC Identifier") { struct gsm_bts *bts = vty->index; -- cgit v1.2.3 From 57ba7e30936ccb5ea2e341113d2eb9810ce42e20 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 14:00:26 +0200 Subject: GPRS: BVCI 0 and 1 are not permitted. According to TS 08.18, BVCI=0 is for the SIGNALLING entity, and BVCI=1 is for the PTM entity. Both should not be used by the PTP entity that we're configuring here. --- openbsc/src/vty_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index e5290c98f..2f034e74a 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -1392,7 +1392,7 @@ DEFUN(cfg_bts_per_loc_upd, cfg_bts_per_loc_upd_cmd, } DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd, - "gprs cell bvci <1-65535>", + "gprs cell bvci <2-65535>", "GPRS BSSGP VC Identifier") { struct gsm_bts *bts = vty->index; -- cgit v1.2.3 From ad9f7830fbb7d7a1d5eb7810bad5d808c0856a8d Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 21:08:26 +0200 Subject: update the openbts.cfg.nanobts example --- openbsc/src/openbsc.cfg.nanobts | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/openbsc/src/openbsc.cfg.nanobts b/openbsc/src/openbsc.cfg.nanobts index a1ceaec79..4c5cf805a 100644 --- a/openbsc/src/openbsc.cfg.nanobts +++ b/openbsc/src/openbsc.cfg.nanobts @@ -1,6 +1,6 @@ ! ! OpenBSC configuration saved from vty -! +! ! password foo ! line vty @@ -11,17 +11,52 @@ network mobile network code 1 short name OpenBSC long name OpenBSC + auth policy closed + location updating reject cause 13 + encryption a5 0 + neci 0 + rrlp mode none + mm info 1 + handover 0 + handover window rxlev averaging 10 + handover window rxqual averaging 1 + handover window rxlev neighbor averaging 10 + handover power budget interval 6 + handover power budget hysteresis 3 + handover maximum distance 9999 timer t3101 10 + timer t3103 0 + timer t3105 0 + timer t3107 0 + timer t3109 0 + timer t3111 0 timer t3113 60 + timer t3115 0 + timer t3117 0 + timer t3119 0 + timer t3141 0 bts 0 type nanobts - ip.access unit_id 1801 0 - band GSM1800 + band DCS1800 + cell_identity 0 location_area_code 1 training_sequence_code 7 base_station_id_code 63 + ms max power 15 + cell reselection hysteresis 4 + rxlev access min 0 + channel allocator ascending + rach tx integer 9 + rach max transmission 7 + ip.access unit_id 1801 0 + oml ip.access stream_id 255 + gprs enabled 0 trx 0 + rf_locked 0 arfcn 514 + nominal power 23 + max_power_red 20 + rsl e1 tei 0 timeslot 0 phys_chan_config CCCH+SDCCH4 timeslot 1 -- cgit v1.2.3 From 2c57232489d8551a54741b883bcc39b527602b1b Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 21:25:18 +0200 Subject: add an example config file for nanoBTS multi-trx case --- openbsc/src/openbsc.cfg.nanobts.multitrx | 97 ++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 openbsc/src/openbsc.cfg.nanobts.multitrx diff --git a/openbsc/src/openbsc.cfg.nanobts.multitrx b/openbsc/src/openbsc.cfg.nanobts.multitrx new file mode 100644 index 000000000..2bd6e3f0b --- /dev/null +++ b/openbsc/src/openbsc.cfg.nanobts.multitrx @@ -0,0 +1,97 @@ +! +! OpenBSC configuration saved from vty +! ! +password foo +! +line vty + no login +! +network + network country code 1 + mobile network code 1 + short name OpenBSC + long name OpenBSC + auth policy closed + location updating reject cause 13 + encryption a5 0 + neci 0 + rrlp mode none + mm info 0 + handover 0 + handover window rxlev averaging 10 + handover window rxqual averaging 1 + handover window rxlev neighbor averaging 10 + handover power budget interval 6 + handover power budget hysteresis 3 + handover maximum distance 9999 + timer t3101 10 + timer t3103 0 + timer t3105 0 + timer t3107 0 + timer t3109 0 + timer t3111 0 + timer t3113 60 + timer t3115 0 + timer t3117 0 + timer t3119 0 + timer t3141 0 + bts 0 + type nanobts + band DCS1800 + cell_identity 0 + location_area_code 1 + training_sequence_code 7 + base_station_id_code 63 + ms max power 15 + cell reselection hysteresis 4 + rxlev access min 0 + channel allocator ascending + rach tx integer 9 + rach max transmission 7 + ip.access unit_id 1800 0 + oml ip.access stream_id 255 + gprs enabled 0 + trx 0 + rf_locked 0 + arfcn 871 + nominal power 23 + max_power_red 0 + rsl e1 tei 0 + timeslot 0 + phys_chan_config CCCH+SDCCH4 + timeslot 1 + phys_chan_config SDCCH8 + timeslot 2 + phys_chan_config TCH/F + timeslot 3 + phys_chan_config TCH/F + timeslot 4 + phys_chan_config TCH/F + timeslot 5 + phys_chan_config TCH/F + timeslot 6 + phys_chan_config TCH/F + timeslot 7 + phys_chan_config TCH/F + trx 1 + rf_locked 0 + arfcn 873 + nominal power 23 + max_power_red 0 + rsl e1 tei 0 + timeslot 0 + phys_chan_config CCCH+SDCCH4 + timeslot 1 + phys_chan_config SDCCH8 + timeslot 2 + phys_chan_config TCH/F + timeslot 3 + phys_chan_config TCH/F + timeslot 4 + phys_chan_config TCH/F + timeslot 5 + phys_chan_config TCH/F + timeslot 6 + phys_chan_config TCH/F + timeslot 7 + phys_chan_config TCH/F -- cgit v1.2.3 From da0586a83810f43b061f7b12ad079b264bc03781 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 14:49:05 +0200 Subject: GPRS: Add Support for the GPRS Cell Option Extension Info IE Extension Information is part of the GPRS Cell Options IE, as specified in Chapter 12.24 of TS 04.60. It is needed for indicating EDGE capabilities of the BTS to the MS. This simply adds the code to encode this IE as part of SI13, but does not actually use the code yet. --- openbsc/include/openbsc/rest_octets.h | 11 +++++++++++ openbsc/src/rest_octets.c | 27 +++++++++++++++++++++++++-- openbsc/src/system_information.c | 10 ++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h index 4e72c0f87..6d9011963 100644 --- a/openbsc/include/openbsc/rest_octets.h +++ b/openbsc/include/openbsc/rest_octets.h @@ -71,6 +71,7 @@ enum gprs_nmo { GPRS_NMO_III = 2, /* no paging coordination */ }; +/* TS 04.60 12.24 */ struct gprs_cell_options { enum gprs_nmo nmo; /* T3168: wait for packet uplink assignment message */ @@ -79,6 +80,16 @@ struct gprs_cell_options { u_int32_t t3192; /* in milliseconds */ u_int32_t drx_timer_max;/* in seconds */ u_int32_t bs_cv_max; + + u_int8_t ext_info_present; + struct { + u_int8_t egprs_supported; + u_int8_t use_egprs_p_ch_req; + u_int8_t bep_period; + u_int8_t pfc_supported; + u_int8_t dtm_supported; + u_int8_t bss_paging_coordination; + } ext_info; }; /* TS 04.60 Table 12.9.2 */ diff --git a/openbsc/src/rest_octets.c b/openbsc/src/rest_octets.c index df27cf21e..0aac8d51f 100644 --- a/openbsc/src/rest_octets.c +++ b/openbsc/src/rest_octets.c @@ -319,8 +319,31 @@ static int append_gprs_cell_opt(struct bitvec *bv, /* hard-code no PAN_{DEC,INC,MAX} */ bitvec_set_bit(bv, 0); - /* no extension information (EDGE) */ - bitvec_set_bit(bv, 0); + if (!gco->ext_info_present) { + /* no extension information */ + bitvec_set_bit(bv, 0); + } else { + /* extension information */ + bitvec_set_bit(bv, 1); + if (!gco->ext_info.egprs_supported) { + /* 6bit length of extension */ + bitvec_set_uint(bv, 1 + 3, 6); + /* EGPRS supported in the cell */ + bitvec_set_bit(bv, 0); + } else { + /* 6bit length of extension */ + bitvec_set_uint(bv, 1 + 5 + 3, 6); + /* EGPRS supported in the cell */ + bitvec_set_bit(bv, 1); + /* 1bit EGPRS PACKET CHANNEL REQUEST */ + bitvec_set_bit(bv, gco->ext_info.use_egprs_p_ch_req); + /* 4bit BEP PERIOD */ + bitvec_set_uint(bv, gco->ext_info.bep_period, 4); + } + bitvec_set_bit(bv, gco->ext_info.pfc_supported); + bitvec_set_bit(bv, gco->ext_info.dtm_supported); + bitvec_set_bit(bv, gco->ext_info.bss_paging_coordination); + } return 0; } diff --git a/openbsc/src/system_information.c b/openbsc/src/system_information.c index 3f9d60954..de0e287c9 100644 --- a/openbsc/src/system_information.c +++ b/openbsc/src/system_information.c @@ -402,6 +402,16 @@ static struct gsm48_si13_info si13_default = { .t3192 = 500, .drx_timer_max = 3, .bs_cv_max = 15, + .ext_info_present = 0, + .ext_info = { + /* The values below are just guesses ! */ + .egprs_supported = 1, + .use_egprs_p_ch_req = 1, + .bep_period = 4, + .pfc_supported = 0, + .dtm_supported = 0, + .bss_paging_coordination = 0, + }, }, .pwr_ctrl_pars = { .alpha = 10, /* a = 1.0 */ -- cgit v1.2.3 From 4511d891ddf221eeea32d33f6199fa76c17df9c3 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 15:51:20 +0200 Subject: GPRS: change 'gprs enabled <0-1>' to 'gprs mode (none|gprs|egprs)' This causes some config file breakage but sounds like a much cleaner approach than to have two separate config variables for this. --- openbsc/include/openbsc/gsm_data.h | 11 ++++++++++- openbsc/src/bsc_init.c | 8 ++++---- openbsc/src/gsm_data.c | 17 +++++++++++++++++ openbsc/src/system_information.c | 10 +++++++++- openbsc/src/vty_interface.c | 29 +++++++++++++++-------------- 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index a2f0e406c..52b82c062 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -73,6 +73,12 @@ enum gsm_paging_event { GSM_PAGING_OOM, }; +enum bts_gprs_mode { + BTS_GPRS_NONE = 0, + BTS_GPRS_GPRS = 1, + BTS_GPRS_EGPRS = 2, +}; + struct msgb; typedef int gsm_cbfn(unsigned int hooknum, unsigned int event, @@ -476,7 +482,7 @@ struct gsm_bts { /* Not entirely sure how ip.access specific this is */ struct { - int enabled; + enum bts_gprs_mode mode; struct { struct gsm_nm_state nm_state; u_int16_t nsei; @@ -705,6 +711,9 @@ const char *gsm_auth_policy_name(enum gsm_auth_policy policy); enum rrlp_mode rrlp_mode_parse(const char *arg); const char *rrlp_mode_name(enum rrlp_mode mode); +enum bts_gprs_mode bts_gprs_mode_parse(const char *arg); +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 */ diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c index 94576b796..1711aeb13 100644 --- a/openbsc/src/bsc_init.c +++ b/openbsc/src/bsc_init.c @@ -462,7 +462,7 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj, break; case NM_OC_GPRS_NSE: bts = container_of(obj, struct gsm_bts, gprs.nse); - if (!bts->gprs.enabled) + if (bts->gprs.mode == BTS_GPRS_NONE) break; if (new_state->availability == 5) { abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr, @@ -476,7 +476,7 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj, break; case NM_OC_GPRS_CELL: bts = container_of(obj, struct gsm_bts, gprs.cell); - if (!bts->gprs.enabled) + if (bts->gprs.mode == BTS_GPRS_NONE) break; if (new_state->availability == 5) { abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr, @@ -491,7 +491,7 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj, case NM_OC_GPRS_NSVC: nsvc = obj; bts = nsvc->bts; - if (!bts->gprs.enabled) + if (bts->gprs.mode == BTS_GPRS_NONE) break; /* We skip NSVC1 since we only use NSVC0 */ if (nsvc->id == 1) @@ -799,7 +799,7 @@ static int set_system_infos(struct gsm_bts_trx *trx) DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc)); rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp)); } - if (bts->gprs.enabled) { + if (bts->gprs.mode != BTS_GPRS_NONE) { i = 13; rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13); if (rc < 0) diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index 4af46e487..4d8fa1747 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -502,6 +502,23 @@ const char *rrlp_mode_name(enum rrlp_mode mode) return get_value_string(rrlp_mode_names, mode); } +static const struct value_string bts_gprs_mode_names[] = { + { BTS_GPRS_NONE, "none" }, + { BTS_GPRS_GPRS, "gprs" }, + { BTS_GPRS_EGPRS, "egprs" }, + { 0, NULL } +}; + +enum bts_gprs_mode bts_gprs_mode_parse(const char *arg) +{ + return get_string_value(bts_gprs_mode_names, arg); +} + +const char *bts_gprs_mode_name(enum bts_gprs_mode mode) +{ + return get_value_string(bts_gprs_mode_names, mode); +} + struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan) { struct gsm_meas_rep *meas_rep; diff --git a/openbsc/src/system_information.c b/openbsc/src/system_information.c index de0e287c9..8072ba2d4 100644 --- a/openbsc/src/system_information.c +++ b/openbsc/src/system_information.c @@ -458,7 +458,15 @@ static int generate_si13(u_int8_t *output, struct gsm_bts *bts) int gsm_generate_si(u_int8_t *output, struct gsm_bts *bts, int type) { - si_info.gprs_ind.present = bts->gprs.enabled; + switch (bts->gprs.mode) { + case BTS_GPRS_EGPRS: + case BTS_GPRS_GPRS: + si_info.gprs_ind.present = 1; + break; + case BTS_GPRS_NONE: + si_info.gprs_ind.present = 0; + break; + } switch (type) { case RSL_SYSTEM_INFO_1: diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index 2f034e74a..dd35372ca 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -318,8 +318,9 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) config_write_e1_link(vty, &bts->oml_e1_link, " oml "); vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE); } - vty_out(vty, " gprs enabled %u%s", bts->gprs.enabled, VTY_NEWLINE); - if (bts->gprs.enabled) { + vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode), + VTY_NEWLINE); + if (bts->gprs.mode != BTS_GPRS_NONE) { vty_out(vty, " gprs routing area %u%s", bts->gprs.rac, VTY_NEWLINE); vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci, @@ -1397,7 +1398,7 @@ DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd, { struct gsm_bts *bts = vty->index; - if (!bts->gprs.enabled) { + if (bts->gprs.mode == BTS_GPRS_NONE) { vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE); return CMD_WARNING; } @@ -1413,7 +1414,7 @@ DEFUN(cfg_bts_gprs_nsei, cfg_bts_gprs_nsei_cmd, { struct gsm_bts *bts = vty->index; - if (!bts->gprs.enabled) { + if (bts->gprs.mode == BTS_GPRS_NONE) { vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE); return CMD_WARNING; } @@ -1431,7 +1432,7 @@ DEFUN(cfg_bts_gprs_nsvci, cfg_bts_gprs_nsvci_cmd, struct gsm_bts *bts = vty->index; int idx = atoi(argv[0]); - if (!bts->gprs.enabled) { + if (bts->gprs.mode == BTS_GPRS_NONE) { vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE); return CMD_WARNING; } @@ -1448,7 +1449,7 @@ DEFUN(cfg_bts_gprs_nsvc_lport, cfg_bts_gprs_nsvc_lport_cmd, struct gsm_bts *bts = vty->index; int idx = atoi(argv[0]); - if (!bts->gprs.enabled) { + if (bts->gprs.mode == BTS_GPRS_NONE) { vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE); return CMD_WARNING; } @@ -1465,7 +1466,7 @@ DEFUN(cfg_bts_gprs_nsvc_rport, cfg_bts_gprs_nsvc_rport_cmd, struct gsm_bts *bts = vty->index; int idx = atoi(argv[0]); - if (!bts->gprs.enabled) { + if (bts->gprs.mode == BTS_GPRS_NONE) { vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE); return CMD_WARNING; } @@ -1483,7 +1484,7 @@ DEFUN(cfg_bts_gprs_nsvc_rip, cfg_bts_gprs_nsvc_rip_cmd, int idx = atoi(argv[0]); struct in_addr ia; - if (!bts->gprs.enabled) { + if (bts->gprs.mode == BTS_GPRS_NONE) { vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE); return CMD_WARNING; } @@ -1500,7 +1501,7 @@ DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd, { struct gsm_bts *bts = vty->index; - if (!bts->gprs.enabled) { + if (bts->gprs.mode == BTS_GPRS_NONE) { vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE); return CMD_WARNING; } @@ -1510,13 +1511,13 @@ DEFUN(cfg_bts_gprs_rac, cfg_bts_gprs_rac_cmd, return CMD_SUCCESS; } -DEFUN(cfg_bts_gprs_enabled, cfg_bts_gprs_enabled_cmd, - "gprs enabled <0-1>", - "GPRS Enabled on this BTS") +DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd, + "gprs mode (none|gprs|egprs)", + "GPRS Mode for this BTS") { struct gsm_bts *bts = vty->index; - bts->gprs.enabled = atoi(argv[0]); + bts->gprs.mode = bts_gprs_mode_parse(argv[0]); return CMD_SUCCESS; } @@ -1775,7 +1776,7 @@ int bsc_vty_init(struct gsm_network *net) install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd); install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd); install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd); - install_element(BTS_NODE, &cfg_bts_gprs_enabled_cmd); + install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd); install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd); install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd); install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd); -- cgit v1.2.3 From a06fea020d593f79337b4582bddebe9c9c3593cc Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 15:53:40 +0200 Subject: GPRS: actually enable indicating EDGE capability in SI13 --- openbsc/src/system_information.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openbsc/src/system_information.c b/openbsc/src/system_information.c index 8072ba2d4..3bd833a93 100644 --- a/openbsc/src/system_information.c +++ b/openbsc/src/system_information.c @@ -405,7 +405,7 @@ static struct gsm48_si13_info si13_default = { .ext_info_present = 0, .ext_info = { /* The values below are just guesses ! */ - .egprs_supported = 1, + .egprs_supported = 0, .use_egprs_p_ch_req = 1, .bep_period = 4, .pfc_supported = 0, @@ -460,6 +460,9 @@ int gsm_generate_si(u_int8_t *output, struct gsm_bts *bts, int type) { switch (bts->gprs.mode) { case BTS_GPRS_EGPRS: + si13_default.cell_opts.ext_info_present = 1; + si13_default.cell_opts.ext_info.egprs_supported = 1; + /* fallthrough */ case BTS_GPRS_GPRS: si_info.gprs_ind.present = 1; break; -- cgit v1.2.3 From 439bb828f9568bfd6272ac82b4b36b7efe55f060 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 16:50:11 +0200 Subject: GPRS: Enable EGPRS coding schemes in Cell Attributes if 'gprs mode egprs' --- openbsc/src/bsc_init.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c index 1711aeb13..a39bc198a 100644 --- a/openbsc/src/bsc_init.c +++ b/openbsc/src/bsc_init.c @@ -378,11 +378,11 @@ static unsigned char nanobts_attr_cell[] = { 4, /* N3103 */ 8, /* N3105 */ 15, /* RLC CV countdown */ - NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00, + NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00, /* CS1..CS4 */ NM_ATT_IPACC_RLC_CFG_2, 0, 5, - 0x00, 250, - 0x00, 250, - 2, /* MCS2 */ + 0x00, 250, /* T downlink TBF extension (0..500) */ + 0x00, 250, /* T uplink TBF extension (0..500) */ + 2, /* CS2 */ #if 0 /* EDGE model only, breaks older models. * Should inquire the BTS capabilities */ @@ -886,6 +886,11 @@ static void patch_nm_tables(struct gsm_bts *bts) /* patch RAC */ nanobts_attr_cell[3] = bts->gprs.rac; + if (bts->gprs.mode == BTS_GPRS_EGPRS) { + /* patch EGPRS coding schemes MCS 1..9 */ + nanobts_attr_cell[29] = 0x8f; + nanobts_attr_cell[30] = 0xff; + } } static void bootstrap_rsl(struct gsm_bts_trx *trx) -- cgit v1.2.3 From 18038180927c9ffd3f8f1da18bada698e6afcefb Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 21:33:00 +0200 Subject: update openbsc.cfg examples for new gprs syntax --- openbsc/src/openbsc.cfg.nanobts | 2 +- openbsc/src/openbsc.cfg.nanobts.multitrx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openbsc/src/openbsc.cfg.nanobts b/openbsc/src/openbsc.cfg.nanobts index 4c5cf805a..da0ba74e1 100644 --- a/openbsc/src/openbsc.cfg.nanobts +++ b/openbsc/src/openbsc.cfg.nanobts @@ -50,7 +50,7 @@ network rach max transmission 7 ip.access unit_id 1801 0 oml ip.access stream_id 255 - gprs enabled 0 + gprs mode none trx 0 rf_locked 0 arfcn 514 diff --git a/openbsc/src/openbsc.cfg.nanobts.multitrx b/openbsc/src/openbsc.cfg.nanobts.multitrx index 2bd6e3f0b..d9fb54b49 100644 --- a/openbsc/src/openbsc.cfg.nanobts.multitrx +++ b/openbsc/src/openbsc.cfg.nanobts.multitrx @@ -50,7 +50,7 @@ network rach max transmission 7 ip.access unit_id 1800 0 oml ip.access stream_id 255 - gprs enabled 0 + gprs mode none trx 0 rf_locked 0 arfcn 871 -- cgit v1.2.3 From 5fda90816f0623b32ddb60f1cf4d9d67119de811 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 22:41:01 +0200 Subject: GPRS: Indicate the SGSN is Release 99 as this is the first with EDGE --- openbsc/src/rest_octets.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openbsc/src/rest_octets.c b/openbsc/src/rest_octets.c index 0aac8d51f..fd56caf81 100644 --- a/openbsc/src/rest_octets.c +++ b/openbsc/src/rest_octets.c @@ -358,7 +358,7 @@ static void append_gprs_pwr_ctrl_pars(struct bitvec *bv, bitvec_set_uint(bv, pcp->n_avg_i, 4); } -/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */ +/* Generate SI13 Rest Octests (04.08 Chapter 10.5.2.37b) */ int rest_octets_si13(u_int8_t *data, const struct gsm48_si13_info *si13) { struct bitvec bv; @@ -414,6 +414,11 @@ int rest_octets_si13(u_int8_t *data, const struct gsm48_si13_info *si13) break; } } + /* 3GPP TS 44.018 Release 6 / 10.5.2.37b */ + bitvec_set_bit(&bv, H); /* added Release 99 */ + /* claim our SGSN is compatible with Release 99, as EDGE and EGPRS + * was only added in this Release */ + bitvec_set_bit(&bv, 1); } bitvec_spare_padding(&bv, (bv.data_len*8)-1); return bv.data_len; -- cgit v1.2.3 From 39608dc04557ac050de6a05a6d41239fc18d9eb8 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 18 Apr 2010 22:47:22 +0200 Subject: GPRS: Fix calculation of 'Extension Length' in GPRS Cell Options The actual 'Extension Length' field in the 'GPRS Cell Options' IE is coded the length - 1, not the full length. Without this fix, the code has an off-by-one error. --- openbsc/src/rest_octets.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openbsc/src/rest_octets.c b/openbsc/src/rest_octets.c index fd56caf81..039d2c83a 100644 --- a/openbsc/src/rest_octets.c +++ b/openbsc/src/rest_octets.c @@ -327,12 +327,12 @@ static int append_gprs_cell_opt(struct bitvec *bv, bitvec_set_bit(bv, 1); if (!gco->ext_info.egprs_supported) { /* 6bit length of extension */ - bitvec_set_uint(bv, 1 + 3, 6); + bitvec_set_uint(bv, (1 + 3)-1, 6); /* EGPRS supported in the cell */ bitvec_set_bit(bv, 0); } else { /* 6bit length of extension */ - bitvec_set_uint(bv, 1 + 5 + 3, 6); + bitvec_set_uint(bv, (1 + 5 + 3)-1, 6); /* EGPRS supported in the cell */ bitvec_set_bit(bv, 1); /* 1bit EGPRS PACKET CHANNEL REQUEST */ -- cgit v1.2.3 From 38e9c821143a9b86227ae02b1830de43b67facab Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 19 Apr 2010 10:24:07 +0200 Subject: RSL: inmplement ip.access paging load indication 'below threshold' This is an ip.access specific 08.58 oddity. It reports 0xffff available paging buffers if the paging load is below the 12.21 CCCH LOAD INDICATION THRESHOLD. We use 50, since that is what it reports if the threshold == 0. --- openbsc/src/abis_rsl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index bbce67a96..53b29823e 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -1187,6 +1187,10 @@ static int rsl_rx_ccch_load(struct msgb *msg) switch (rslh->data[0]) { case RSL_IE_PAGING_LOAD: pg_buf_space = rslh->data[1] << 8 | rslh->data[2]; + if (is_ipaccess_bts(msg->trx->bts) && pg_buf_space == 0xffff) { + /* paging load below configured threshold, use 50 as default */ + pg_buf_space = 50; + } paging_update_buffer_space(msg->trx->bts, pg_buf_space); break; case RSL_IE_RACH_LOAD: -- cgit v1.2.3