Compare commits

...

27 Commits

Author SHA1 Message Date
Holger Hans Peter Freyther
6d17dd1314 Increase the version. 2010-04-19 17:06:17 +08:00
Holger Hans Peter Freyther
7cb6867ea3 [vty] Count pending paging requests for the vty
Implement a method to count the number of pending paging requests
per bts and print it on the VTY. This helps to see how big the
backlog of requests is for a given BTS.
2010-04-19 16:20:28 +08:00
Holger Hans Peter Freyther
d8138c43a1 nat: Make sccp/bsc show connections more Cisco like...
Second attempt to use a syntax more comparable to 'Cisco',
I have never used such a system... let us see how this is
going.
2010-04-19 16:06:43 +08:00
Holger Hans Peter Freyther
46d9b94477 [vty] Allow to allocate TCH/H and TCH/F too for testing purposes. 2010-04-19 16:01:14 +08:00
Holger Hans Peter Freyther
4f705b9f99 [vty] Add a test command to allocate all SDCCH 2010-04-19 16:01:14 +08:00
Holger Hans Peter Freyther
c592e697ce [alloc] Assign a TCH for LU when all SDCCHs are occupied.
When the cell becomes visible we will be bombed with location
updating requests and to reduce the load on the network we should
assign as many channels for it as possible. During load peek it
is even more important than to have a spare voice channel and in
general the LU procedure is pretty fast.
2010-04-19 16:01:07 +08:00
Holger Hans Peter Freyther
ebb6b99c63 nat: Do not use 0/0 for mux/timeslot by default
0 is a valid timeslot and we should not use it... use
a negative value to be save.
2010-04-18 03:07:22 +08:00
Holger Hans Peter Freyther
e08253a3f7 nat: Clear the connection on a DLCX
We can forget about the timeslot/multiplex when getting
the DLCX. This way we make room for the next connection
that might need to reuse this address.
2010-04-18 03:05:27 +08:00
Holger Hans Peter Freyther
5e86095364 nat: Always initialize the out pointer...
Always initialize the pointer to a invalid value in case
we encounter a parsing error or such.
2010-04-18 02:41:20 +08:00
Holger Hans Peter Freyther
a7c144888d nat: Fix the test case by allocating a config.
For the statistics we do need to have an allocated config,
otherwise we will nicely crash.
2010-04-18 02:40:33 +08:00
Holger Hans Peter Freyther
7897c4446b nat: Return the SCCP Connection again...
We will reset the multiplex in a DLCX message and then
we can reset the multiplex as well...even if the MGCP
connection is staying open. or at least this is a theory.

The MSC likes to leave a connection open during CallControl
when hanging up early enough in the process.
2010-04-18 02:40:33 +08:00
Holger Hans Peter Freyther
ff9e09b2bc nat: Return the newest SCCP connection...
In case we have a stale SCCP connection with an Endpoint that
we want to reassign...use the newest (last) occurence of that
as it is most likely the one we want to handle.
2010-04-18 02:40:32 +08:00
Holger Hans Peter Freyther
ecf5cc294d bsc_msc_ip: Print a small status on active connections
This needs to be improved to print TS of the lchan, when
the connection was created, when we received the last IT.
2010-04-18 02:40:32 +08:00
Holger Hans Peter Freyther
82126763a7 nat: Increase the right counter on calls. 2010-04-18 02:40:31 +08:00
Holger Hans Peter Freyther
a380c89a9c nat: Add new connections to the end of the list
By adding them to the end the VTY interface will only append
connections and not change the order on each invocation.
2010-04-18 02:40:31 +08:00
Holger Hans Peter Freyther
bedaf5da64 bssap: Move parsing of paging into the paging section... 2010-04-18 02:40:30 +08:00
Holger Freyther
2b08aa35a6 nat: Remove the SHOW_STR from none show commands. 2010-04-18 02:40:30 +08:00
Holger Hans Peter Freyther
c24632930a bsc_msc_ip: Allow to put the MSC address into the network config 2010-04-17 09:07:24 +02:00
Holger Hans Peter Freyther
f140348eff nat: Print the LAC that was searched for and not found. 2010-04-17 08:07:19 +02:00
Holger Hans Peter Freyther
b5de1b0781 nat: Mention when we do not find a BSC for a given token.
This might help to identify what is wrong with the config
of the BSC. Also using the result of TLVP_VAL as a char
pointer looks suspicious...
2010-04-17 08:07:03 +02:00
Holger Hans Peter Freyther
b022cc3b8e nat: Print the IP address of the BSC that does not respond to the query. 2010-04-17 07:58:17 +02:00
Holger Hans Peter Freyther
e8396c9663 nat: Make the MSC configurable. 2010-04-17 07:48:45 +02:00
Holger Hans Peter Freyther
941839b300 nat: Move MSC ip address into the config..
The address can still be specified on the cli and it will
overwrite the config in the config file.
2010-04-17 07:31:08 +02:00
Holger Hans Peter Freyther
23a0e46f11 Add rf_locked to the configuration writing. 2010-04-17 07:31:08 +02:00
Holger Hans Peter Freyther
cb8fd6e99e Use osmocore tlv definition for GSM0808. 2010-04-17 07:31:03 +02:00
Holger Hans Peter Freyther
e66bea8ad7 [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).
2010-04-16 16:59:48 +02:00
Holger Hans Peter Freyther
e8a9f471ef nat: Two fixes for the write memory case...
Add new BSCs to the tail so we keep the sort order when writing
them out to the vty, fix the LAC command.
2010-04-16 16:52:20 +02:00
23 changed files with 264 additions and 100 deletions

View File

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

View File

@@ -204,6 +204,8 @@ struct bsc_nat {
int mgcp_length;
/* msc things */
char *msc_ip;
int msc_port;
int first_contact;
struct bsc_endpoint *bsc_endpoints;
@@ -223,6 +225,7 @@ struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token, unsi
struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num);
struct bsc_nat *bsc_nat_alloc(void);
struct bsc_connection *bsc_connection_alloc(struct bsc_nat *nat);
void bsc_nat_set_msc_ip(struct bsc_nat *bsc, const char *ip);
void sccp_connection_destroy(struct sccp_connections *);
@@ -236,7 +239,7 @@ struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
*/
int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed);
int bsc_nat_vty_init(struct bsc_nat *nat);
struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg);
struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg, int *_lac);
/**
* SCCP patching and handling
@@ -257,7 +260,7 @@ void bsc_mgcp_free_endpoint(struct bsc_nat *nat, int);
void bsc_mgcp_free_endpoints(struct bsc_nat *nat);
int bsc_mgcp_init(struct bsc_nat *nat);
struct bsc_connection *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
struct sccp_connections *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port);
void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);

View File

@@ -330,6 +330,4 @@ void bts_send_queued(struct bss_sccp_connection_data*);
void bts_free_queued(struct bss_sccp_connection_data*);
void bts_unblock_queue(struct bss_sccp_connection_data*);
const struct tlv_definition *gsm0808_att_tlvdef();
#endif

View File

@@ -63,7 +63,7 @@ struct gsm_lchan *lchan_find(struct gsm_bts *bts, struct gsm_subscriber *subscr)
struct gsm_lchan *lchan_for_subscr(struct gsm_subscriber *subscr);
/* Allocate a logical channel (SDCCH, TCH, ...) */
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type, int allow_bigger);
/* Free a logical channel (SDCCH, TCH, ...) */
void lchan_free(struct gsm_lchan *lchan);

View File

@@ -661,6 +661,8 @@ struct gsm_network {
/* a simple token for this network... */
char *bsc_token;
char *msc_ip;
int msc_port;
};
#define SMS_HDR_SIZE 128

View File

@@ -43,4 +43,7 @@ void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr,
/* update paging load */
void paging_update_buffer_space(struct gsm_bts *bts, u_int16_t);
/* pending paging requests */
unsigned int paging_pending_requests_nr(struct gsm_bts *bts);
#endif

View File

@@ -1140,6 +1140,7 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
struct gsm_lchan *lchan;
u_int8_t rqd_ta;
int ret;
int is_lu;
u_int16_t arfcn;
u_int8_t ts_number, subch;
@@ -1162,8 +1163,14 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
counter_inc(bts->network->stats.chreq.total);
/*
* We want LOCATION UPDATES to succeed and will assign a TCH
* if we have no SDCCH available.
*/
is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
/* check availability / allocate channel */
lchan = lchan_alloc(bts, lctype);
lchan = lchan_alloc(bts, lctype, is_lu);
if (!lchan) {
LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);

View File

@@ -7,6 +7,7 @@ line vty
no login
!
nat
msc ip 10.0.0.23
bsc 0
token zecke
location_area_code 3

View File

@@ -59,7 +59,7 @@
static struct log_target *stderr_target;
struct gsm_network *bsc_gsmnet = 0;
static const char *config_file = "openbsc.cfg";
static char *msc_address = "127.0.0.1";
static char *msc_address = NULL;
static struct bsc_msc_connection *msc_con;
static struct in_addr local_addr;
static LLIST_HEAD(active_connections);
@@ -70,6 +70,12 @@ extern int ipacc_rtp_direct;
extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, int, void *), const char *cfg_file);
extern int bsc_shutdown_net(struct gsm_network *net);
struct llist_head *bsc_sccp_connections()
{
return &active_connections;
}
struct bss_sccp_connection_data *bss_sccp_create_data()
{
struct bss_sccp_connection_data *data;
@@ -938,7 +944,7 @@ static void handle_options(int argc, char** argv)
ipacc_rtp_direct = 0;
break;
case 'm':
msc_address = strdup(optarg);
msc_address = optarg;
break;
case 'l':
inet_aton(optarg, &local_addr);
@@ -1030,6 +1036,7 @@ extern int bts_model_nanobts_init(void);
int main(int argc, char **argv)
{
char *msc;
int rc;
log_init(&log_info);
@@ -1070,20 +1077,6 @@ int main(int argc, char **argv)
/* initialize ipaccess handling */
register_signal_handler(SS_ABISIP, handle_abisip_signal, NULL);
/* setup MSC Connection handling */
msc_con = bsc_msc_create(msc_address, 5000);
if (!msc_con) {
fprintf(stderr, "Creating a bsc_msc_connection failed.\n");
exit(1);
}
msc_con->connection_loss = msc_connection_was_lost;
msc_con->write_queue.read_cb = ipaccess_a_fd_cb;
msc_con->write_queue.write_cb = msc_sccp_do_write;
bsc_msc_connect(msc_con);
fprintf(stderr, "Bootstraping the network. Sending GSM08.08 reset.\n");
rc = bsc_bootstrap_network(NULL, config_file);
if (rc < 0) {
@@ -1100,6 +1093,24 @@ int main(int argc, char **argv)
}
}
/* setup MSC Connection handling */
msc = bsc_gsmnet->msc_ip;
if (msc_address)
msc = msc_address;
msc_con = bsc_msc_create(msc, bsc_gsmnet->msc_port);
if (!msc_con) {
fprintf(stderr, "Creating a bsc_msc_connection failed.\n");
exit(1);
}
msc_con->connection_loss = msc_connection_was_lost;
msc_con->write_queue.read_cb = ipaccess_a_fd_cb;
msc_con->write_queue.write_cb = msc_sccp_do_write;
bsc_msc_connect(msc_con);
while (1) {
bsc_select_main(0);
}

View File

@@ -29,7 +29,7 @@
#include <openbsc/paging.h>
#include <openbsc/chan_alloc.h>
#include <osmocore/tlv.h>
#include <osmocore/gsm0808.h>
#include <sccp/sccp.h>
@@ -44,34 +44,6 @@ static void bts_queue_send(struct msgb *msg, int link_id);
static void bssmap_free_secondary(struct bss_sccp_connection_data *data);
static const struct tlv_definition bss_att_tlvdef = {
.def = {
[GSM0808_IE_IMSI] = { TLV_TYPE_TLV },
[GSM0808_IE_TMSI] = { TLV_TYPE_TLV },
[GSM0808_IE_CELL_IDENTIFIER_LIST] = { TLV_TYPE_TLV },
[GSM0808_IE_CHANNEL_NEEDED] = { TLV_TYPE_TV },
[GSM0808_IE_EMLPP_PRIORITY] = { TLV_TYPE_TV },
[GSM0808_IE_CHANNEL_TYPE] = { TLV_TYPE_TLV },
[GSM0808_IE_PRIORITY] = { TLV_TYPE_TLV },
[GSM0808_IE_CIRCUIT_IDENTITY_CODE] = { TLV_TYPE_TV },
[GSM0808_IE_DOWNLINK_DTX_FLAG] = { TLV_TYPE_TV },
[GSM0808_IE_INTERFERENCE_BAND_TO_USE] = { TLV_TYPE_TV },
[GSM0808_IE_CLASSMARK_INFORMATION_T2] = { TLV_TYPE_TLV },
[GSM0808_IE_GROUP_CALL_REFERENCE] = { TLV_TYPE_TLV },
[GSM0808_IE_TALKER_FLAG] = { TLV_TYPE_T },
[GSM0808_IE_CONFIG_EVO_INDI] = { TLV_TYPE_TV },
[GSM0808_IE_LSA_ACCESS_CTRL_SUPPR] = { TLV_TYPE_TV },
[GSM0808_IE_SERVICE_HANDOVER] = { TLV_TYPE_TV},
[GSM0808_IE_ENCRYPTION_INFORMATION] = { TLV_TYPE_TLV },
[GSM0808_IE_CIPHER_RESPONSE_MODE] = { TLV_TYPE_TV },
},
};
const struct tlv_definition *gsm0808_att_tlvdef()
{
return &bss_att_tlvdef;
}
static u_int16_t get_network_code_for_msc(struct gsm_network *net)
{
if (net->core_network_code > 0)
@@ -88,7 +60,7 @@ static u_int16_t get_country_code_for_msc(struct gsm_network *net)
static int bssmap_paging_cb(unsigned int hooknum, unsigned int event, struct msgb *msg, void *data, void *param)
{
LOGP(DMSC, LOGL_DEBUG, "Paging is complete.\n");
LOGP(DPAG, LOGL_DEBUG, "Paging is complete.\n");
return 0;
}
@@ -112,7 +84,7 @@ static int bssmap_handle_paging(struct gsm_network *net, struct msgb *msg, unsig
u_int8_t chan_needed = RSL_CHANNEED_ANY;
int paged;
tlv_parse(&tp, &bss_att_tlvdef, msg->l4h + 1, payload_length - 1, 0, 0);
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, payload_length - 1, 0, 0);
if (!TLVP_PRESENT(&tp, GSM0808_IE_IMSI)) {
LOGP(DMSC, LOGL_ERROR, "Mandantory IMSI not present.\n");
@@ -173,7 +145,7 @@ static int bssmap_handle_paging(struct gsm_network *net, struct msgb *msg, unsig
subscr->tmsi = tmsi;
subscr->lac = lac;
paged = paging_request(net, subscr, chan_needed, bssmap_paging_cb, subscr);
LOGP(DMSC, LOGL_DEBUG, "Paged IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x on #bts: %d\n", mi_string, tmsi, tmsi, lac, paged);
LOGP(DPAG, LOGL_DEBUG, "Paged IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x on #bts: %d\n", mi_string, tmsi, tmsi, lac, paged);
subscr_put(subscr);
return -1;
@@ -242,7 +214,7 @@ static int bssmap_handle_cipher_mode(struct sccp_connection *conn,
msg->lchan->msc_data->ciphering_handled = 1;
msg->lchan->msc_data->block_gsm = 1;
tlv_parse(&tp, &bss_att_tlvdef, msg->l4h + 1, payload_length - 1, 0, 0);
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, payload_length - 1, 0, 0);
if (!TLVP_PRESENT(&tp, GSM0808_IE_ENCRYPTION_INFORMATION)) {
LOGP(DMSC, LOGL_ERROR, "IE Encryption Information missing.\n");
goto reject;
@@ -431,7 +403,7 @@ static int handle_new_assignment(struct msgb *msg, int full_rate, int chan_mode)
bts = msg->lchan->ts->trx->bts;
chan_type = full_rate ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H;
new_lchan = lchan_alloc(bts, chan_type);
new_lchan = lchan_alloc(bts, chan_type, 0);
if (!new_lchan) {
LOGP(DMSC, LOGL_NOTICE, "No free channel.\n");
@@ -515,7 +487,7 @@ static int bssmap_handle_assignm_req(struct sccp_connection *conn,
msc_data = msg->lchan->msc_data;
network = msg->lchan->ts->trx->bts->network;
tlv_parse(&tp, &bss_att_tlvdef, msg->l4h + 1, length - 1, 0, 0);
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, length - 1, 0, 0);
if (!TLVP_PRESENT(&tp, GSM0808_IE_CHANNEL_TYPE)) {
LOGP(DMSC, LOGL_ERROR, "Mandantory channel type not present.\n");

View File

@@ -223,7 +223,8 @@ _lc_find_bts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
}
/* Allocate a logical channel */
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type)
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type,
int allow_bigger)
{
struct gsm_lchan *lchan = NULL;
enum gsm_phys_chan_config first, second;
@@ -241,6 +242,19 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type)
lchan = _lc_find_bts(bts, first);
if (lchan == NULL)
lchan = _lc_find_bts(bts, second);
/* allow to assign bigger channels */
if (allow_bigger) {
if (lchan == NULL) {
lchan = _lc_find_bts(bts, GSM_PCHAN_TCH_H);
type = GSM_LCHAN_TCH_H;
}
if (lchan == NULL) {
lchan = _lc_find_bts(bts, GSM_PCHAN_TCH_F);
type = GSM_LCHAN_TCH_F;
}
}
break;
case GSM_LCHAN_TCH_F:
lchan = _lc_find_bts(bts, GSM_PCHAN_TCH_F);

View File

@@ -294,6 +294,9 @@ struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_c
net->core_network_code = -1;
net->rtp_base_port = 4000;
net->msc_ip = talloc_strdup(net, "127.0.0.1");
net->msc_port = 5000;
return net;
}

View File

@@ -99,7 +99,7 @@ int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts)
counter_inc(bts->network->stats.handover.attempted);
new_lchan = lchan_alloc(bts, old_lchan->type);
new_lchan = lchan_alloc(bts, old_lchan->type, 0);
if (!new_lchan) {
LOGP(DHO, LOGL_NOTICE, "No free channel\n");
counter_inc(bts->network->stats.handover.no_channel);

View File

@@ -33,6 +33,8 @@
#include <vty/command.h>
#include <vty/vty.h>
#include <string.h>
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;
}

View File

@@ -27,6 +27,7 @@
#include <openbsc/mgcp_internal.h>
#include <osmocore/talloc.h>
#include <osmocore/gsm0808.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -91,8 +92,9 @@ void bsc_mgcp_free_endpoints(struct bsc_nat *nat)
bsc_mgcp_free_endpoint(nat, i);
}
struct bsc_connection *bsc_mgcp_find_con(struct bsc_nat *nat, int endpoint)
struct sccp_connections *bsc_mgcp_find_con(struct bsc_nat *nat, int endpoint)
{
struct sccp_connections *con = NULL;
struct sccp_connections *sccp;
llist_for_each_entry(sccp, &nat->sccp_connections, list_entry) {
@@ -101,9 +103,12 @@ struct bsc_connection *bsc_mgcp_find_con(struct bsc_nat *nat, int endpoint)
if (mgcp_timeslot_to_endpoint(0, sccp->msc_timeslot) != endpoint)
continue;
return sccp->bsc;
con = sccp;
}
if (con)
return con;
LOGP(DMGCP, LOGL_ERROR, "Failed to find the connection.\n");
return NULL;
}
@@ -112,7 +117,7 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c
{
struct bsc_nat *nat;
struct bsc_endpoint *bsc_endp;
struct bsc_connection *bsc_con;
struct sccp_connections *sccp;
struct mgcp_endpoint *mgcp_endp;
struct msgb *bsc_msg;
@@ -120,9 +125,9 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c
bsc_endp = &nat->bsc_endpoints[endpoint];
mgcp_endp = &nat->mgcp_cfg->endpoints[endpoint];
bsc_con = bsc_mgcp_find_con(nat, endpoint);
sccp = bsc_mgcp_find_con(nat, endpoint);
if (!bsc_con) {
if (!sccp) {
LOGP(DMGCP, LOGL_ERROR, "Did not find BSC for a new connection on 0x%x for %d\n", endpoint, state);
switch (state) {
@@ -158,14 +163,14 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c
bsc_endp->transaction_id = talloc_strdup(nat, transaction_id);
bsc_endp->bsc = bsc_con;
bsc_endp->bsc = sccp->bsc;
bsc_endp->pending_delete = 0;
/* we need to update some bits */
if (state == MGCP_ENDP_CRCX) {
struct sockaddr_in sock;
socklen_t len = sizeof(sock);
if (getpeername(bsc_con->write_queue.bfd.fd, (struct sockaddr *) &sock, &len) != 0) {
if (getpeername(sccp->bsc->write_queue.bfd.fd, (struct sockaddr *) &sock, &len) != 0) {
LOGP(DMGCP, LOGL_ERROR, "Can not get the peername...%d/%s\n",
errno, strerror(errno));
} else {
@@ -173,11 +178,12 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c
}
} else if (state == MGCP_ENDP_DLCX) {
/* we will free the endpoint now in case the BSS does not respond */
bsc_mgcp_clear(sccp);
bsc_endp->pending_delete = 1;
mgcp_free_endp(mgcp_endp);
}
bsc_write(bsc_con, bsc_msg, NAT_IPAC_PROTO_MGCP);
bsc_write(sccp->bsc, bsc_msg, NAT_IPAC_PROTO_MGCP);
return MGCP_POLICY_DEFER;
}

View File

@@ -51,10 +51,10 @@
struct log_target *stderr_target;
static const char *config_file = "bsc-nat.cfg";
static char *msc_address = "127.0.0.1";
static struct in_addr local_addr;
static struct bsc_msc_connection *msc_con;
static struct bsc_fd bsc_listen;
static const char *msc_ip = NULL;
static struct bsc_nat *nat;
@@ -261,7 +261,7 @@ static int forward_sccp_to_bts(struct msgb *msg)
counter_inc(nat->stats.sccp.calls);
if (con) {
counter_inc(con->bsc->cfg->stats.sccp.conn);
counter_inc(con->bsc->cfg->stats.sccp.calls);
if (bsc_mgcp_assign(con, msg) != 0)
LOGP(DNAT, LOGL_ERROR, "Failed to assign...\n");
} else
@@ -309,11 +309,13 @@ send_to_all:
* message and then send it to the authenticated messages...
*/
if (parsed->ipa_proto == IPAC_PROTO_SCCP && parsed->gsm_type == BSS_MAP_MSG_PAGING) {
bsc = bsc_nat_find_bsc(nat, msg);
int lac;
bsc = bsc_nat_find_bsc(nat, msg, &lac);
if (bsc)
bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), parsed->ipa_proto);
else
LOGP(DNAT, LOGL_ERROR, "Could not determine BSC for paging.\n");
LOGP(DNAT, LOGL_ERROR, "Could not determine BSC for paging on lac: %d/0x%x\n",
lac, lac);
goto exit;
}
@@ -458,9 +460,14 @@ static void remove_bsc_connection(struct bsc_connection *connection)
static void ipaccess_close_bsc(void *data)
{
struct sockaddr_in sock;
socklen_t len = sizeof(sock);
struct bsc_connection *conn = data;
LOGP(DNAT, LOGL_ERROR, "BSC didn't respond to identity request. Closing.\n");
getpeername(conn->write_queue.bfd.fd, (struct sockaddr *) &sock, &len);
LOGP(DNAT, LOGL_ERROR, "BSC on %s didn't respond to identity request. Closing.\n",
inet_ntoa(sock.sin_addr));
remove_bsc_connection(conn);
}
@@ -476,9 +483,11 @@ static void ipaccess_auth_bsc(struct tlv_parsed *tvp, struct bsc_connection *bsc
bsc->cfg = conf;
bsc_del_timer(&bsc->id_timeout);
LOGP(DNAT, LOGL_NOTICE, "Authenticated bsc nr: %d lac: %d\n", conf->nr, conf->lac);
break;
return;
}
}
LOGP(DNAT, LOGL_ERROR, "No bsc found for token %s.\n", token);
}
static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg)
@@ -782,7 +791,7 @@ static void handle_options(int argc, char** argv)
log_set_print_timestamp(stderr_target, 1);
break;
case 'm':
msc_address = strdup(optarg);
msc_ip = optarg;
break;
case 'l':
inet_aton(optarg, &local_addr);
@@ -815,10 +824,6 @@ int main(int argc, char** argv)
log_add_target(stderr_target);
log_set_all_filter(stderr_target, 1);
/* parse options */
local_addr.s_addr = INADDR_ANY;
handle_options(argc, argv);
nat = bsc_nat_alloc();
if (!nat) {
fprintf(stderr, "Failed to allocate the BSC nat.\n");
@@ -826,6 +831,14 @@ int main(int argc, char** argv)
}
nat->mgcp_cfg = talloc_zero(nat, struct mgcp_config);
if (!nat->mgcp_cfg) {
fprintf(stderr, "Failed to allocate MGCP cfg.\n");
return -5;
}
/* parse options */
local_addr.s_addr = INADDR_ANY;
handle_options(argc, argv);
/* init vty and parse */
bsc_nat_vty_init(nat);
@@ -835,6 +848,10 @@ int main(int argc, char** argv)
return -3;
}
/* over rule the VTY config */
if (msc_ip)
bsc_nat_set_msc_ip(nat, msc_ip);
/* seed the PRNG */
srand(time(NULL));
@@ -845,7 +862,7 @@ int main(int argc, char** argv)
return -4;
/* connect to the MSC */
msc_con = bsc_msc_create(msc_address, 5000);
msc_con = bsc_msc_create(nat->msc_ip, nat->msc_port);
if (!msc_con) {
fprintf(stderr, "Creating a bsc_msc_connection failed.\n");
exit(1);

View File

@@ -30,6 +30,7 @@
#include <osmocore/linuxlist.h>
#include <osmocore/talloc.h>
#include <osmocore/gsm0808.h>
#include <sccp/sccp.h>
@@ -50,9 +51,18 @@ struct bsc_nat *bsc_nat_alloc(void)
nat->stats.bsc.reconn = counter_alloc("nat.bsc.conn");
nat->stats.bsc.auth_fail = counter_alloc("nat.bsc.auth_fail");
nat->stats.msc.reconn = counter_alloc("nat.msc.conn");
nat->msc_ip = talloc_strdup(nat, "127.0.0.1");
nat->msc_port = 5000;
return nat;
}
void bsc_nat_set_msc_ip(struct bsc_nat *nat, const char *ip)
{
if (nat->msc_ip)
talloc_free(nat->msc_ip);
nat->msc_ip = talloc_strdup(nat, ip);
}
struct bsc_connection *bsc_connection_alloc(struct bsc_nat *nat)
{
struct bsc_connection *con = talloc_zero(nat, struct bsc_connection);
@@ -74,7 +84,7 @@ struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token, unsi
conf->nr = nat->num_bsc;
conf->nat = nat;
llist_add(&conf->entry, &nat->bsc_configs);
llist_add_tail(&conf->entry, &nat->bsc_configs);
++nat->num_bsc;
conf->stats.sccp.conn = counter_alloc("nat.bsc.sccp.conn");
@@ -94,7 +104,7 @@ void sccp_connection_destroy(struct sccp_connections *conn)
talloc_free(conn);
}
struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg)
struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg, int *lac_out)
{
struct bsc_connection *bsc;
int data_length;
@@ -102,6 +112,8 @@ struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg)
struct tlv_parsed tp;
int i = 0;
*lac_out = -1;
if (!msg->l3h || msgb_l3len(msg) < 3) {
LOGP(DNAT, LOGL_ERROR, "Paging message is too short.\n");
return NULL;
@@ -123,6 +135,7 @@ struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg)
/* Currently we only handle one BSC */
for (i = 1; i < data_length - 1; i += 2) {
unsigned int _lac = ntohs(*(unsigned int *) &data[i]);
*lac_out = _lac;
llist_for_each_entry(bsc, &nat->bsc_connections, list_entry) {
if (!bsc->cfg)
continue;

View File

@@ -55,6 +55,8 @@ static int config_write_nat(struct vty *vty)
vty_out(vty, " imsi allow %s%s", _nat->imsi_allow, VTY_NEWLINE);
if (_nat->imsi_deny)
vty_out(vty, " insi deny %s%s", _nat->imsi_deny, VTY_NEWLINE);
vty_out(vty, " msc ip %s%s", _nat->msc_ip, VTY_NEWLINE);
vty_out(vty, " msc port %d%s", _nat->msc_port, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -62,7 +64,7 @@ static void config_write_bsc_single(struct vty *vty, struct bsc_config *bsc)
{
vty_out(vty, " bsc %u%s", bsc->nr, VTY_NEWLINE);
vty_out(vty, " token %s%s", bsc->token, VTY_NEWLINE);
vty_out(vty, " lac %u%s", bsc->lac, VTY_NEWLINE);
vty_out(vty, " location_area_code %u%s", bsc->lac, VTY_NEWLINE);
if (bsc->imsi_allow)
vty_out(vty, " imsi allow %s%s", bsc->imsi_allow, VTY_NEWLINE);
if (bsc->imsi_deny)
@@ -79,7 +81,7 @@ static int config_write_bsc(struct vty *vty)
}
DEFUN(show_sccp, show_sccp_cmd, "sccp connections show",
DEFUN(show_sccp, show_sccp_cmd, "show sccp connections",
SHOW_STR "Display information about current SCCP connections")
{
struct sccp_connections *con;
@@ -96,7 +98,7 @@ DEFUN(show_sccp, show_sccp_cmd, "sccp connections show",
return CMD_SUCCESS;
}
DEFUN(show_bsc, show_bsc_cmd, "bsc connections show",
DEFUN(show_bsc, show_bsc_cmd, "show bsc connections",
SHOW_STR "Display information about current BSCs")
{
struct bsc_connection *con;
@@ -116,7 +118,7 @@ DEFUN(show_bsc, show_bsc_cmd, "bsc connections show",
}
DEFUN(show_bsc_cfg, show_bsc_cfg_cmd, "bsc config show",
SHOW_STR "Display information about known BSC configs")
"Display information about known BSC configs")
{
struct bsc_config *conf;
llist_for_each_entry(conf, &_nat->bsc_configs, entry) {
@@ -203,6 +205,24 @@ DEFUN(cfg_nat_imsi_deny,
return CMD_SUCCESS;
}
DEFUN(cfg_nat_msc_ip,
cfg_nat_msc_ip_cmd,
"msc ip IP",
"Set the IP address of the MSC.")
{
bsc_nat_set_msc_ip(_nat, argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_nat_msc_port,
cfg_nat_msc_port_cmd,
"msc port <1-65500>",
"Set the port of the MSC.")
{
_nat->msc_port = atoi(argv[0]);
return CMD_SUCCESS;
}
/* per BSC configuration */
DEFUN(cfg_bsc, cfg_bsc_cmd, "bsc BSC_NR", "Select a BSC to configure\n")
{
@@ -316,6 +336,8 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
install_default(NAT_NODE);
install_element(NAT_NODE, &cfg_nat_imsi_allow_cmd);
install_element(NAT_NODE, &cfg_nat_imsi_deny_cmd);
install_element(NAT_NODE, &cfg_nat_msc_ip_cmd);
install_element(NAT_NODE, &cfg_nat_msc_port_cmd);
/* BSC subgroups */
install_element(NAT_NODE, &cfg_bsc_cmd);

View File

@@ -99,7 +99,8 @@ int create_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc
return -1;
}
llist_add(&conn->list_entry, &bsc->nat->sccp_connections);
bsc_mgcp_clear(conn);
llist_add_tail(&conn->list_entry, &bsc->nat->sccp_connections);
counter_inc(bsc->cfg->stats.sccp.conn);
counter_inc(bsc->cfg->nat->stats.sccp.conn);

View File

@@ -326,3 +326,15 @@ void paging_update_buffer_space(struct gsm_bts *bts, u_int16_t free_slots)
{
bts->paging.available_slots = free_slots;
}
unsigned int paging_pending_requests_nr(struct gsm_bts *bts)
{
unsigned int requests = 0;
struct gsm_paging_request *req;
llist_for_each_entry(req, &bts->paging.pending_requests, entry)
++requests;
return requests;
}

View File

@@ -40,6 +40,7 @@
#include <openbsc/telnet_interface.h>
#include <openbsc/vty.h>
#include <openbsc/ipaccess.h>
#include <openbsc/paging.h>
static struct gsm_network *gsmnet;
@@ -196,7 +197,8 @@ static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
net_dump_nmstate(vty, &bts->nm_state);
vty_out(vty, " Site Mgr NM State: ");
net_dump_nmstate(vty, &bts->site_mgr.nm_state);
vty_out(vty, " Paging: FIXME pending requests, %u free slots%s",
vty_out(vty, " Paging: %u pending requests, %u free slots%s",
paging_pending_requests_nr(bts),
bts->paging.available_slots, VTY_NEWLINE);
if (!is_ipaccess_bts(bts)) {
vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
@@ -234,6 +236,36 @@ DEFUN(show_bts, show_bts_cmd, "show bts [number]",
return CMD_SUCCESS;
}
DEFUN(test_bts_lchan_alloc, test_bts_lchan_alloc_cmd, "test bts alloc (sdcch|tch_h|tch_f)",
"Test command to allocate all channels. You will need to restart. To free these channels.\n")
{
struct gsm_network *net = gsmnet;
int bts_nr;
enum gsm_chan_t type = GSM_LCHAN_NONE;
if (strcmp("sdcch", argv[0]) == 0)
type = GSM_LCHAN_SDCCH;
else if (strcmp("tch_h", argv[0]) == 0)
type = GSM_LCHAN_TCH_H;
else if (strcmp("tch_f", argv[0]) == 0)
type = GSM_LCHAN_TCH_F;
else {
vty_out(vty, "Unknown mode for allocation.%s", VTY_NEWLINE);
}
for (bts_nr = 0; bts_nr < net->num_bts; ++bts_nr) {
struct gsm_bts *bts = gsm_bts_num(net, bts_nr);
struct gsm_lchan *lchan;
/* alloc the channel */
while ((lchan = lchan_alloc(bts, type, 0)) != NULL)
rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
}
return CMD_SUCCESS;
}
/* utility functions */
static void parse_e1_link(struct gsm_e1_subslot *e1_link, const char *line,
const char *ts, const char *ss)
@@ -276,6 +308,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);
@@ -430,6 +465,8 @@ static int config_write_net(struct vty *vty)
if (gsmnet->bsc_token)
vty_out(vty, " bsc_token %s%s", gsmnet->bsc_token, VTY_NEWLINE);
vty_out(vty, " msc ip %s%s", gsmnet->msc_ip, VTY_NEWLINE);
vty_out(vty, " msc port %d%s", gsmnet->msc_port, VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1269,6 +1306,27 @@ DEFUN(cfg_net_pag_any_tch,
return CMD_SUCCESS;
}
DEFUN(cfg_net_msc_ip,
cfg_net_msc_ip_cmd,
"msc ip IP",
"Set the MSC/MUX IP address.")
{
if (gsmnet->msc_ip)
talloc_free(gsmnet->msc_ip);
gsmnet->msc_ip = talloc_strdup(gsmnet, argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_net_msc_port,
cfg_net_msc_port_cmd,
"msc port <1-65000>",
"Set the MSC/MUX port.")
{
gsmnet->msc_port = atoi(argv[0]);
return CMD_SUCCESS;
}
#define DECLARE_TIMER(number, doc) \
DEFUN(cfg_net_T##number, \
cfg_net_T##number##_cmd, \
@@ -1927,6 +1985,7 @@ int bsc_vty_init(struct gsm_network *net)
install_element(VIEW_NODE, &show_paging_cmd);
install_element(VIEW_NODE, &drop_bts_cmd);
install_element(VIEW_NODE, &test_bts_lchan_alloc_cmd);
openbsc_vty_add_cmds();
@@ -1968,6 +2027,8 @@ int bsc_vty_init(struct gsm_network *net)
install_element(GSMNET_NODE, &cfg_net_T3141_cmd);
install_element(GSMNET_NODE, &cfg_net_bsc_token_cmd);
install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
install_element(GSMNET_NODE, &cfg_net_msc_ip_cmd);
install_element(GSMNET_NODE, &cfg_net_msc_port_cmd);
install_element(GSMNET_NODE, &cfg_bts_cmd);
install_node(&bts_node, config_write_bts);

View File

@@ -29,12 +29,26 @@
#include <openbsc/gsm_data.h>
#include <openbsc/vty.h>
#include <sccp/sccp.h>
static struct gsm_network *gsmnet = NULL;
extern struct llist_head *bsc_sccp_connections();
DEFUN(show_bsc, show_bsc_cmd, "show bsc",
SHOW_STR "Display information about the BSC\n")
{
vty_out(vty, "BSC... not implemented yet%s", VTY_NEWLINE);
struct bss_sccp_connection_data *con;
vty_out(vty, "BSC Information%s", VTY_NEWLINE);
llist_for_each_entry(con, bsc_sccp_connections(), active_connections) {
vty_out(vty, " Connection: LCHAN: %p sec LCHAN: %p SCCP src: %d dest: %d%s",
con->lchan, con->secondary_lchan,
con->sccp ? (int) sccp_src_ref_to_int(&con->sccp->source_local_reference) : -1,
con->sccp ? (int) sccp_src_ref_to_int(&con->sccp->destination_local_reference) : -1,
VTY_NEWLINE);
}
return CMD_SUCCESS;
}

View File

@@ -242,6 +242,7 @@ static void test_contrack()
fprintf(stderr, "Testing connection tracking.\n");
nat = bsc_nat_alloc();
con = bsc_connection_alloc(nat);
con->cfg = bsc_config_alloc(nat, "foo", 23);
msg = msgb_alloc(4096, "test");
/* 1.) create a connection */
@@ -329,6 +330,7 @@ static void test_contrack()
static void test_paging(void)
{
int lac;
struct bsc_nat *nat;
struct bsc_connection *con;
struct bsc_nat_parsed *parsed;
@@ -347,7 +349,7 @@ static void test_paging(void)
/* Test completely bad input */
copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
if (bsc_nat_find_bsc(nat, msg) != 0) {
if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
fprintf(stderr, "Should have not found anything.\n");
abort();
}
@@ -355,7 +357,7 @@ static void test_paging(void)
/* Test it by not finding it */
copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
parsed = bsc_nat_parse(msg);
if (bsc_nat_find_bsc(nat, msg) != 0) {
if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
fprintf(stderr, "Should have not found aynthing.\n");
abort();
}
@@ -365,7 +367,7 @@ static void test_paging(void)
cfg.lac = 8213;
copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
parsed = bsc_nat_parse(msg);
if (bsc_nat_find_bsc(nat, msg) != con) {
if (bsc_nat_find_bsc(nat, msg, &lac) != con) {
fprintf(stderr, "Should have found it.\n");
abort();
}
@@ -431,14 +433,14 @@ static void test_mgcp_find(void)
abort();
}
if (bsc_mgcp_find_con(nat, 12) != con) {
if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
fprintf(stderr, "Didn't find the connection\n");
abort();
}
sccp_con->msc_timeslot = 0;
sccp_con->bsc_timeslot = 0;
if (bsc_mgcp_find_con(nat, 1) != con) {
if (bsc_mgcp_find_con(nat, 1) != sccp_con) {
fprintf(stderr, "Didn't find the connection\n");
abort();
}