Compare commits

...

16 Commits

Author SHA1 Message Date
Holger Hans Peter Freyther
8c3694a282 Bump the version for the BSC. 2010-04-08 10:09:49 +02:00
Holger Hans Peter Freyther
191d23a889 nat: Rename bsc_write to bsc_send_data 2010-04-08 09:20:48 +02:00
Holger Hans Peter Freyther
a5963097ac bssap: Comment and code cleanup 2010-04-07 20:35:59 +02:00
Holger Hans Peter Freyther
221fb37518 bssap: Switch to use LOGP and pick some debug categories 2010-04-07 20:35:02 +02:00
Holger Hans Peter Freyther
4ec8a390cc bssap: Another possible null derference on the code.
We do not want to send a msg over the NULL lchan. Let us
return fast from here.
2010-04-07 20:22:21 +02:00
Holger Hans Peter Freyther
cf3f1c8b3d 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.
2010-04-07 15:39:16 +02:00
Holger Hans Peter Freyther
984f3b8047 bssap: Speculative crash fix. 2010-04-07 15:37:33 +02:00
Holger Hans Peter Freyther
ec1f15d513 [mgcp] Print the errno/strerror when we can not receive from our socket 2010-04-07 12:55:40 +02:00
Holger Hans Peter Freyther
b76cd5ed7e nat: Send the reset after we have received the init ack
Sending the reset right away will upset the MSC and we
need to wait for the first contact.
2010-04-07 11:20:36 +02:00
Holger Hans Peter Freyther
1592550d98 nat: Fix the reset message and prepend the IPA header 2010-04-07 11:11:11 +02:00
Holger Hans Peter Freyther
5cdf42b1a4 nat: Allow to realloc already allocated endpoints
E.g. when the MGCP on the BSS is not responding we could block
all of our endpoints. As we are mostly in the middle and forward
bits we will happily reallocate the endpoints.
2010-04-07 10:52:48 +02:00
Holger Hans Peter Freyther
3a6b1a41fb [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.
2010-04-07 10:51:27 +02:00
Holger Hans Peter Freyther
1b5b3bbfdb nat: Send a GSM0808 message to the MSC when we are reconnecting
The rest of the code should filter the reset ack msg. This should
make the MSC give up all resources it had allocated for us.
2010-04-07 10:46:30 +02:00
Holger Hans Peter Freyther
3a67035411 nat: Attempt to make MGCP forwarding more robust
When not being able to allocate the msgb for the forwarded data
there is no point in keeping and preparing the transaction. So
we can move the msg creation a bit up and only do the allocations
after having done the msgb allocation.

When receiving a DLCX we will now delete the endpoint right away. This
means when a BSS does not respond to the DLCX our endpoint will not
be blocked. E.g. this could happen when the MGCP is restarting or
in similiar conditions. When the BSS is not responding we move the
burden up the chain to the CallAgent. We have to still keep track
of the transaction id and the bsc pointer to keep the mgcp forward
routine working.
2010-04-07 09:53:54 +02:00
Holger Hans Peter Freyther
cb1937a4c5 [mgcp] Count incoming RTP packets from the BTS and remote 2010-04-07 09:37:17 +02:00
Holger Hans Peter Freyther
3cfd5d6a02 bsc_msc_ip.c: Fix the -e command line option 2010-04-07 08:41:01 +02:00
12 changed files with 160 additions and 94 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.92onwaves)
AM_INIT_AUTOMAKE(openbsc, 0.3.93onwaves)
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])

View File

@@ -158,6 +158,9 @@ struct bsc_nat {
u_int8_t mgcp_msg[4096];
int mgcp_length;
/* msc things */
int first_contact;
struct bsc_endpoint *bsc_endpoints;
};

View File

@@ -104,6 +104,9 @@ struct mgcp_config {
unsigned int number_endpoints;
struct mgcp_endpoint *endpoints;
/* spec handling */
int force_realloc;
/* callback functionality */
mgcp_change change_cb;
mgcp_policy policy_cb;

View File

@@ -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)

View File

@@ -900,7 +900,7 @@ static void handle_options(int argc, char** argv)
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hd:sTPc:m:l:",
c = getopt_long(argc, argv, "hd:sTPc:m:l:e:",
long_options, &option_index);
if (c == -1)
break;

View File

@@ -85,13 +85,13 @@ 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)
{
DEBUGP(DMSC, "Paging is complete.\n");
LOGP(DMSC, LOGL_DEBUG, "Paging is complete.\n");
return 0;
}
static int bssmap_handle_reset_ack(struct gsm_network *net, struct msgb *msg, unsigned int length)
{
DEBUGP(DMSC, "Reset ACK from MSC\n");
LOGP(DMSC, LOGL_NOTICE, "Reset ACK from MSC\n");
return 0;
}
@@ -112,15 +112,15 @@ static int bssmap_handle_paging(struct gsm_network *net, struct msgb *msg, unsig
tlv_parse(&tp, &bss_att_tlvdef, msg->l4h + 1, payload_length - 1, 0, 0);
if (!TLVP_PRESENT(&tp, GSM0808_IE_IMSI)) {
DEBUGP(DMSC, "Mandantory IMSI not present.\n");
LOGP(DMSC, LOGL_ERROR, "Mandantory IMSI not present.\n");
return -1;
} else if ((TLVP_VAL(&tp, GSM0808_IE_IMSI)[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_IMSI) {
DEBUGP(DMSC, "Wrong content in the IMSI\n");
LOGP(DMSC, LOGL_ERROR, "Wrong content in the IMSI\n");
return -1;
}
if (!TLVP_PRESENT(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST)) {
DEBUGP(DMSC, "Mandantory CELL IDENTIFIER LIST not present.\n");
LOGP(DMSC, LOGL_ERROR, "Mandantory CELL IDENTIFIER LIST not present.\n");
return -1;
}
@@ -150,7 +150,7 @@ static int bssmap_handle_paging(struct gsm_network *net, struct msgb *msg, unsig
unsigned int *_lac = (unsigned int *)&data[1];
lac = ntohs(*_lac);
} else if (data_length > 1 || (data[0] & 0x0f) != CELL_IDENT_BSS) {
DEBUGPC(DMSC, "Unsupported Cell Identifier List: %s\n", hexdump(data, data_length));
LOGP(DMSC, LOGL_ERROR, "Unsupported Cell Identifier List: %s\n", hexdump(data, data_length));
return -1;
}
@@ -158,10 +158,10 @@ static int bssmap_handle_paging(struct gsm_network *net, struct msgb *msg, unsig
chan_needed = TLVP_VAL(&tp, GSM0808_IE_CHANNEL_NEEDED)[0] & 0x03;
if (TLVP_PRESENT(&tp, GSM0808_IE_EMLPP_PRIORITY)) {
DEBUGP(DMSC, "eMLPP is not handled\n");
LOGP(DMSC, LOGL_ERROR, "eMLPP is not handled\n");
}
DEBUGP(DMSC, "Paging request from MSC IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x\n", mi_string, tmsi, tmsi, lac);
LOGP(DMSC, LOGL_DEBUG, "Paging request from MSC IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x\n", mi_string, tmsi, tmsi, lac);
subscr = subscr_get_or_create(net, mi_string);
if (!subscr)
return -1;
@@ -170,7 +170,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);
DEBUGP(DMSC, "Paged IMSI: '%s' TMSI: '0x%x/%u' LAC: 0x%x on #bts: %d\n", mi_string, tmsi, tmsi, lac, paged);
LOGP(DMSC, 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;
@@ -185,7 +185,7 @@ static int bssmap_handle_clear_command(struct sccp_connection *conn,
/* TODO: handle the cause of this package */
if (msg->lchan) {
DEBUGP(DMSC, "Releasing all transactions on %p\n", conn);
LOGP(DMSC, LOGL_DEBUG, "Releasing all transactions on %p\n", conn);
bsc_del_timer(&msg->lchan->msc_data->T10);
msg->lchan->msc_data->lchan = NULL;
@@ -200,7 +200,7 @@ static int bssmap_handle_clear_command(struct sccp_connection *conn,
/* send the clear complete message */
resp = bssmap_create_clear_complete();
if (!resp) {
DEBUGP(DMSC, "Sending clear complete failed.\n");
LOGP(DMSC, LOGL_ERROR, "Sending clear complete failed.\n");
return -1;
}
@@ -227,14 +227,13 @@ static int bssmap_handle_cipher_mode(struct sccp_connection *conn,
int reject_cause = -1;
int include_imeisv = 1;
/* HACK: Sending A5/0 to the MS */
if (!msg->lchan || !msg->lchan->msc_data) {
DEBUGP(DMSC, "No lchan/msc_data in cipher mode command.\n");
LOGP(DMSC, LOGL_ERROR, "No lchan/msc_data in cipher mode command.\n");
goto reject;
}
if (msg->lchan->msc_data->ciphering_handled) {
DEBUGP(DMSC, "Already seen ciphering command. Protocol Error.\n");
LOGP(DMSC, LOGL_ERROR, "Already seen ciphering command. Protocol Error.\n");
goto reject;
}
@@ -243,7 +242,7 @@ static int bssmap_handle_cipher_mode(struct sccp_connection *conn,
tlv_parse(&tp, &bss_att_tlvdef, msg->l4h + 1, payload_length - 1, 0, 0);
if (!TLVP_PRESENT(&tp, GSM0808_IE_ENCRYPTION_INFORMATION)) {
DEBUGP(DMSC, "IE Encryption Information missing.\n");
LOGP(DMSC, LOGL_ERROR, "IE Encryption Information missing.\n");
goto reject;
}
@@ -255,7 +254,7 @@ static int bssmap_handle_cipher_mode(struct sccp_connection *conn,
*/
len = TLVP_LEN(&tp, GSM0808_IE_ENCRYPTION_INFORMATION);
if (len < 1) {
DEBUGP(DMSC, "IE Encryption Information is too short.\n");
LOGP(DMSC, LOGL_ERROR, "IE Encryption Information is too short.\n");
goto reject;
}
@@ -269,7 +268,7 @@ static int bssmap_handle_cipher_mode(struct sccp_connection *conn,
msg->lchan->encr.key_len = len - 1;
memcpy(msg->lchan->encr.key, &data[1], len - 1);
} else {
DEBUGP(DMSC, "Can not select encryption...\n");
LOGP(DMSC, LOGL_ERROR, "Can not select encryption...\n");
goto reject;
}
@@ -280,12 +279,12 @@ static int bssmap_handle_cipher_mode(struct sccp_connection *conn,
return gsm48_send_rr_ciph_mode(msg->lchan, include_imeisv);
reject:
if (msg->lchan->msc_data)
if (msg->lchan && msg->lchan->msc_data)
msg->lchan->msc_data->block_gsm = 0;
resp = bssmap_create_cipher_reject(reject_cause);
if (!resp) {
DEBUGP(DMSC, "Sending the cipher reject failed.\n");
LOGP(DMSC, LOGL_ERROR, "Sending the cipher reject failed.\n");
return -1;
}
@@ -301,11 +300,11 @@ static void bssmap_t10_fired(void *_conn)
struct sccp_connection *conn = (struct sccp_connection *) _conn;
struct msgb *resp;
DEBUGP(DMSC, "T10 fired, assignment failed: %p\n", conn);
LOGP(DMSC, LOGL_ERROR, "T10 fired, assignment failed: %p\n", conn);
resp = bssmap_create_assignment_failure(
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
if (!resp) {
DEBUGP(DMSC, "Allocation failure: %p\n", conn);
LOGP(DMSC, LOGL_ERROR, "Allocation failure: %p\n", conn);
return;
}
@@ -329,7 +328,7 @@ enum gsm0808_permitted_speech audio_support_to_gsm88(struct gsm_audio_support *a
return GSM0808_PERM_HR3;
break;
default:
DEBUGP(DMSC, "Wrong speech mode: %d\n", audio->ver);
LOGP(DMSC, LOGL_ERROR, "Wrong speech mode: %d\n", audio->ver);
return GSM0808_PERM_FR1;
}
} else {
@@ -344,8 +343,8 @@ enum gsm0808_permitted_speech audio_support_to_gsm88(struct gsm_audio_support *a
return GSM0808_PERM_FR3;
break;
default:
DEBUGP(DMSC, "Wrong speech mode: %d\n", audio->ver);
return GSM0808_PERM_HR1;
LOGP(DMSC, LOGL_ERROR, "Wrong speech mode: %d\n", audio->ver);
return GSM0808_PERM_HR1;
}
}
}
@@ -472,8 +471,8 @@ static int bssmap_handle_assignm_req(struct sccp_connection *conn,
int i, supported, port, full_rate = -1;
if (!msg->lchan || !msg->lchan->msc_data) {
DEBUGP(DMSC, "No lchan/msc_data in cipher mode command.\n");
goto reject;
LOGP(DMSC, LOGL_ERROR, "No lchan/msc_data in cipher mode command.\n");
return -1;
}
msc_data = msg->lchan->msc_data;
@@ -481,12 +480,12 @@ static int bssmap_handle_assignm_req(struct sccp_connection *conn,
tlv_parse(&tp, &bss_att_tlvdef, msg->l4h + 1, length - 1, 0, 0);
if (!TLVP_PRESENT(&tp, GSM0808_IE_CHANNEL_TYPE)) {
DEBUGP(DMSC, "Mandantory channel type not present.\n");
LOGP(DMSC, LOGL_ERROR, "Mandantory channel type not present.\n");
goto reject;
}
if (!TLVP_PRESENT(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)) {
DEBUGP(DMSC, "Identity code missing. Audio routing will not work.\n");
LOGP(DMSC, LOGL_ERROR, "Identity code missing. Audio routing will not work.\n");
goto reject;
}
@@ -500,7 +499,7 @@ static int bssmap_handle_assignm_req(struct sccp_connection *conn,
* multi-slot, limiting the channel coding, speech...
*/
if (TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE) < 3) {
DEBUGP(DMSC, "ChannelType len !=3 not supported: %d\n",
LOGP(DMSC, LOGL_ERROR, "ChannelType len !=3 not supported: %d\n",
TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE));
goto reject;
}
@@ -512,12 +511,12 @@ static int bssmap_handle_assignm_req(struct sccp_connection *conn,
data = (u_int8_t *) TLVP_VAL(&tp, GSM0808_IE_CHANNEL_TYPE);
if ((data[0] & 0xf) != 0x1) {
DEBUGP(DMSC, "ChannelType != speech: %d\n", data[0]);
LOGP(DMSC, LOGL_ERROR, "ChannelType != speech: %d\n", data[0]);
goto reject;
}
if (data[1] != GSM0808_SPEECH_FULL_PREF && data[1] != GSM0808_SPEECH_HALF_PREF) {
DEBUGP(DMSC, "ChannelType full not allowed: %d\n", data[1]);
LOGP(DMSC, LOGL_ERROR, "ChannelType full not allowed: %d\n", data[1]);
goto reject;
}
@@ -546,7 +545,7 @@ static int bssmap_handle_assignm_req(struct sccp_connection *conn,
}
if (chan_mode == GSM48_CMODE_SIGN) {
DEBUGP(DMSC, "No supported audio type found.\n");
LOGP(DMSC, LOGL_ERROR, "No supported audio type found.\n");
goto reject;
}
@@ -567,7 +566,7 @@ static int bssmap_handle_assignm_req(struct sccp_connection *conn,
else
goto reject;
} else {
DEBUGP(DMSC, "Sending ChanModify for speech on: sccp: %p mode: 0x%x on port %d %d/0x%x port: %u\n",
LOGP(DMSC, LOGL_ERROR, "Sending ChanModify for speech on: sccp: %p mode: 0x%x on port %d %d/0x%x port: %u\n",
conn, chan_mode, port, multiplex, timeslot, msc_data->rtp_port);
if (chan_mode == GSM48_CMODE_SPEECH_AMR) {
@@ -590,7 +589,7 @@ int bssmap_rcvmsg_udt(struct gsm_network *net, struct msgb *msg, unsigned int le
int ret = 0;
if (length < 1) {
DEBUGP(DMSC, "Not enough room: %d\n", length);
LOGP(DMSC, LOGL_ERROR, "Not enough room: %d\n", length);
return -1;
}
@@ -611,7 +610,7 @@ int bssmap_rcvmsg_dt1(struct sccp_connection *conn, struct msgb *msg, unsigned i
int ret = 0;
if (length < 1) {
DEBUGP(DMSC, "Not enough room: %d\n", length);
LOGP(DMSC, LOGL_ERROR, "Not enough room: %d\n", length);
return -1;
}
@@ -626,7 +625,7 @@ int bssmap_rcvmsg_dt1(struct sccp_connection *conn, struct msgb *msg, unsigned i
ret = bssmap_handle_assignm_req(conn, msg, length);
break;
default:
DEBUGP(DMSC, "Unimplemented msg type: %d\n", msg->l4h[0]);
LOGP(DMSC, LOGL_DEBUG, "Unimplemented msg type: %d\n", msg->l4h[0]);
break;
}
@@ -641,29 +640,29 @@ int dtap_rcvmsg(struct gsm_lchan *lchan, struct msgb *msg, unsigned int length)
u_int8_t link_id;
if (!lchan) {
DEBUGP(DMSC, "No lchan available\n");
LOGP(DMSC, LOGL_ERROR, "No lchan available\n");
return -1;
}
header = (struct dtap_header *) msg->l3h;
if (sizeof(*header) >= length) {
DEBUGP(DMSC, "The DTAP header does not fit. Wanted: %u got: %u\n", sizeof(*header), length);
DEBUGP(DMSC, "hex: %s\n", hexdump(msg->l3h, length));
LOGP(DMSC, LOGL_ERROR, "The DTAP header does not fit. Wanted: %u got: %u\n", sizeof(*header), length);
LOGP(DMSC, LOGL_ERROR, "hex: %s\n", hexdump(msg->l3h, length));
return -1;
}
if (header->length > length - sizeof(*header)) {
DEBUGP(DMSC, "The DTAP l4 information does not fit: header: %u length: %u\n", header->length, length);
DEBUGP(DMSC, "hex: %s\n", hexdump(msg->l3h, length));
LOGP(DMSC, LOGL_ERROR, "The DTAP l4 information does not fit: header: %u length: %u\n", header->length, length);
LOGP(DMSC, LOGL_ERROR, "hex: %s\n", hexdump(msg->l3h, length));
return -1;
}
DEBUGP(DMSC, "DTAP message: SAPI: %u CHAN: %u\n", header->link_id & 0x07, header->link_id & 0xC0);
LOGP(DMSC, LOGL_DEBUG, "DTAP message: SAPI: %u CHAN: %u\n", header->link_id & 0x07, header->link_id & 0xC0);
/* forward the data */
gsm48 = gsm48_msgb_alloc();
if (!gsm48) {
DEBUGP(DMSC, "Allocation of the message failed.\n");
LOGP(DMSC, LOGL_ERROR, "Allocation of the message failed.\n");
return -1;
}
@@ -884,7 +883,7 @@ static u_int8_t chan_mode_to_speech(struct gsm_lchan *lchan)
case GSM48_CMODE_DATA_6k0:
case GSM48_CMODE_DATA_3k6:
default:
DEBUGP(DMSC, "Using non speech mode: %d\n", mode);
LOGP(DMSC, LOGL_ERROR, "Using non speech mode: %d\n", mode);
return 0;
break;
}
@@ -937,7 +936,7 @@ static u_int8_t lchan_to_chosen_channel(struct gsm_lchan *lchan)
channel = 0x9;
break;
case GSM_LCHAN_UNKNOWN:
DEBUGP(DMSC, "Unknown lchan type: %p\n", lchan);
LOGP(DMSC, LOGL_ERROR, "Unknown lchan type: %p\n", lchan);
break;
}
@@ -1075,7 +1074,7 @@ static int bssap_handle_lchan_signal(unsigned int subsys, unsigned int signal,
msg = msgb_alloc(30, "sccp: clear request");
if (!msg) {
DEBUGP(DMSC, "Failed to allocate clear request.\n");
LOGP(DMSC, LOGL_ERROR, "Failed to allocate clear request.\n");
return 0;
}
@@ -1088,7 +1087,7 @@ static int bssap_handle_lchan_signal(unsigned int subsys, unsigned int signal,
msg->l3h[4] = 1;
msg->l3h[5] = GSM0808_CAUSE_RADIO_INTERFACE_FAILURE;
DEBUGP(DMSC, "Sending clear request on unexpected channel release.\n");
LOGP(DMSC, LOGL_NOTICE, "Sending clear request on unexpected channel release.\n");
bsc_queue_connection_write(conn, msg);
break;
case S_LCHAN_ACTIVATE_ACK:
@@ -1111,17 +1110,17 @@ void bsc_queue_connection_write(struct sccp_connection *conn, struct msgb *msg)
data = (struct bss_sccp_connection_data *)conn->data_ctx;
if (conn->connection_state > SCCP_CONNECTION_STATE_ESTABLISHED) {
DEBUGP(DMSC, "Connection closing, dropping packet on: %p\n", conn);
LOGP(DMSC, LOGL_ERROR, "Connection closing, dropping packet on: %p\n", conn);
msgb_free(msg);
} else if (conn->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED
&& data->sccp_queue_size == 0) {
sccp_connection_write(conn, msg);
msgb_free(msg);
} else if (data->sccp_queue_size > 10) {
DEBUGP(DMSC, "Dropping packet on %p due queue overflow\n", conn);
LOGP(DMSC, LOGL_ERROR, "Dropping packet on %p due queue overflow\n", conn);
msgb_free(msg);
} else {
DEBUGP(DMSC, "Queuing packet on %p. Queue size: %d\n", conn, data->sccp_queue_size);
LOGP(DMSC, LOGL_DEBUG, "Queuing packet on %p. Queue size: %d\n", conn, data->sccp_queue_size);
++data->sccp_queue_size;
msgb_enqueue(&data->sccp_queue, msg);
}
@@ -1166,13 +1165,13 @@ static void rll_ind_cb(struct gsm_lchan *lchan, u_int8_t link_id,
struct bss_sccp_connection_data *data = lchan->msc_data;
if (!data || !data->sccp) {
DEBUGP(DMSC, "Time-out/Establish after sccp release? Ind: %d lchan: %p\n",
LOGP(DMSC, LOGL_ERROR, "Time-out/Establish after sccp release? Ind: %d lchan: %p\n",
rllr_ind, lchan);
return;
}
if (memcmp(&data->sccp->source_local_reference, &ref, sizeof(ref)) != 0) {
DEBUGP(DMSC, "Wrong SCCP connection. Not handling RLL callback: %u %u\n",
LOGP(DMSC, LOGL_ERROR, "Wrong SCCP connection. Not handling RLL callback: %u %u\n",
sccp_src_ref_to_int(&ref),
sccp_src_ref_to_int(&data->sccp->source_local_reference));
return;
@@ -1192,7 +1191,7 @@ static void rll_ind_cb(struct gsm_lchan *lchan, u_int8_t link_id,
bts_free_queued(data);
sapi_reject = bssmap_create_sapi_reject(link_id);
if (!sapi_reject){
DEBUGP(DMSC, "Failed to create SAPI reject\n");
LOGP(DMSC, LOGL_ERROR, "Failed to create SAPI reject\n");
return;
}
@@ -1221,9 +1220,9 @@ void bts_queue_send(struct msgb *msg, int link_id)
(void *)sccp_src_ref_to_int(&data->sccp->source_local_reference));
}
} else if (data->gsm_queue_size == 10) {
DEBUGP(DMSC, "Queue full on %p. Dropping GSM0408.\n", data->sccp);
LOGP(DMSC, LOGL_ERROR, "Queue full on %p. Dropping GSM0408.\n", data->sccp);
} else {
DEBUGP(DMSC, "Queueing GSM0408 message on %p. Queue size: %d\n",
LOGP(DMSC, LOGL_DEBUG, "Queueing GSM0408 message on %p. Queue size: %d\n",
data->sccp, data->gsm_queue_size + 1);
msg->smsh = (unsigned char*) link_id;
@@ -1285,7 +1284,7 @@ void gsm0808_send_assignment_failure(struct gsm_lchan *lchan, u_int8_t cause, u_
bsc_del_timer(&lchan->msc_data->T10);
resp = bssmap_create_assignment_failure(cause, rr_value);
if (!resp) {
DEBUGP(DMSC, "Allocation failure: %p\n", lchan_get_sccp(lchan));
LOGP(DMSC, LOGL_ERROR, "Allocation failure: %p\n", lchan_get_sccp(lchan));
return;
}
@@ -1299,7 +1298,7 @@ void gsm0808_send_assignment_compl(struct gsm_lchan *lchan, u_int8_t rr_cause)
bsc_del_timer(&lchan->msc_data->T10);
resp = bssmap_create_assignment_completed(lchan, rr_cause);
if (!resp) {
DEBUGP(DMSC, "Creating MSC response failed: %p\n", lchan_get_sccp(lchan));
LOGP(DMSC, LOGL_ERROR, "Creating MSC response failed: %p\n", lchan_get_sccp(lchan));
return;
}

View File

@@ -25,6 +25,7 @@
#include <string.h>
#include <unistd.h>
#include <endian.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
@@ -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;
}
@@ -164,6 +165,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;

View File

@@ -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: */
@@ -728,6 +734,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));
}

View File

@@ -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;

View File

@@ -148,9 +148,18 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c
talloc_free(bsc_endp->transaction_id);
}
/* we need to generate a new and patched message */
bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length,
nat->mgcp_cfg->source_addr, mgcp_endp->rtp_port);
if (!bsc_msg) {
LOGP(DMGCP, LOGL_ERROR, "Failed to patch the msg.\n");
return MGCP_POLICY_CONT;
}
bsc_endp->transaction_id = talloc_strdup(nat, transaction_id);
bsc_endp->bsc = bsc_con;
bsc_endp->pending_delete = state == MGCP_ENDP_DLCX;
bsc_endp->pending_delete = 0;
/* we need to update some bits */
if (state == MGCP_ENDP_CRCX) {
@@ -162,14 +171,10 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c
} else {
mgcp_endp->bts = sock.sin_addr;
}
}
/* we need to generate a new and patched message */
bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length,
nat->mgcp_cfg->source_addr, mgcp_endp->rtp_port);
if (!bsc_msg) {
LOGP(DMGCP, LOGL_ERROR, "Failed to patch the msg.\n");
return MGCP_POLICY_CONT;
} else if (state == MGCP_ENDP_DLCX) {
/* we will free the endpoint now in case the BSS does not respond */
bsc_endp->pending_delete = 1;
mgcp_free_endp(mgcp_endp);
}
bsc_write_mgcp_msg(bsc_con, bsc_msg);
@@ -223,21 +228,26 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg)
return;
}
/* make it point to our endpoint if it was not deleted */
if (bsc_endp->pending_delete) {
bsc_endp->bsc = NULL;
bsc_endp->pending_delete = 0;
} else {
endp->ci = bsc_mgcp_extract_ci((const char *) msg->l2h);
}
/* free some stuff */
talloc_free(bsc_endp->transaction_id);
bsc_endp->transaction_id = NULL;
/* make it point to our endpoint */
endp->ci = bsc_mgcp_extract_ci((const char *) msg->l2h);
/*
* rewrite the information. In case the endpoint was deleted
* there should be nothing for us to rewrite so putting endp->rtp_port
* with the value of 0 should be no problem.
*/
output = bsc_mgcp_rewrite((char * ) msg->l2h, msgb_l2len(msg),
bsc->nat->mgcp_cfg->source_addr, endp->rtp_port);
if (bsc_endp->pending_delete) {
mgcp_free_endp(endp);
bsc_endp->bsc = NULL;
bsc_endp->pending_delete = 0;
}
if (!output) {
LOGP(DMGCP, LOGL_ERROR, "Failed to rewrite MGCP msg.\n");
return;
@@ -447,6 +457,7 @@ int bsc_mgcp_init(struct bsc_nat *nat)
nat->mgcp_cfg->audio_payload = -1;
nat->mgcp_cfg->data = nat;
nat->mgcp_cfg->policy_cb = bsc_mgcp_policy_cb;
nat->mgcp_cfg->force_realloc = 1;
nat->bsc_endpoints = talloc_zero_array(nat,
struct bsc_endpoint,
nat->mgcp_cfg->number_endpoints + 1);

View File

@@ -58,8 +58,9 @@ static struct bsc_fd bsc_listen;
static struct bsc_nat *nat;
static void bsc_write(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
static void bsc_send_data(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
static void remove_bsc_connection(struct bsc_connection *connection);
static void msc_send_reset(struct bsc_msc_connection *con);
struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num)
{
@@ -98,7 +99,7 @@ static void send_reset_ack(struct bsc_connection *bsc)
0x00, 0x01, 0x31,
};
bsc_write(bsc, gsm_reset_ack, sizeof(gsm_reset_ack));
bsc_send_data(bsc, gsm_reset_ack, sizeof(gsm_reset_ack));
}
static void send_id_ack(struct bsc_connection *bsc)
@@ -107,7 +108,7 @@ static void send_id_ack(struct bsc_connection *bsc)
0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK
};
bsc_write(bsc, id_ack, sizeof(id_ack));
bsc_send_data(bsc, id_ack, sizeof(id_ack));
}
static void send_id_req(struct bsc_connection *bsc)
@@ -124,7 +125,7 @@ static void send_id_req(struct bsc_connection *bsc)
0x01, IPAC_IDTAG_SERNR,
};
bsc_write(bsc, id_req, sizeof(id_req));
bsc_send_data(bsc, id_req, sizeof(id_req));
}
static void nat_send_rlsd(struct sccp_connections *conn)
@@ -169,16 +170,17 @@ static void send_mgcp_reset(struct bsc_connection *bsc)
*/
static void initialize_msc_if_needed()
{
static int init = 0;
init = 1;
if (nat->first_contact)
return;
/* do we need to send a GSM 08.08 message here? */
nat->first_contact = 1;
msc_send_reset(msc_con);
}
/*
* Currently we are lacking refcounting so we need to copy each message.
*/
static void bsc_write(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length)
static void bsc_send_data(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length)
{
struct msgb *msg;
@@ -264,7 +266,7 @@ static int forward_sccp_to_bts(struct msgb *msg)
return -1;
}
bsc_write(con->bsc, msg->data, msg->len);
bsc_send_data(con->bsc, msg->data, msg->len);
return 0;
send_to_all:
@@ -276,7 +278,7 @@ send_to_all:
if (parsed->ipa_proto == IPAC_PROTO_SCCP && parsed->gsm_type == BSS_MAP_MSG_PAGING) {
bsc = bsc_nat_find_bsc(nat, msg);
if (bsc)
bsc_write(bsc, msg->data, msg->len);
bsc_send_data(bsc, msg->data, msg->len);
else
LOGP(DNAT, LOGL_ERROR, "Could not determine BSC for paging.\n");
@@ -287,7 +289,7 @@ send_to_all:
if (!bsc->authenticated)
continue;
bsc_write(bsc, msg->data, msg->len);
bsc_send_data(bsc, msg->data, msg->len);
}
exit:
@@ -303,10 +305,39 @@ static void msc_connection_was_lost(struct bsc_msc_connection *con)
llist_for_each_entry_safe(bsc, tmp, &nat->bsc_connections, list_entry)
remove_bsc_connection(bsc);
nat->first_contact = 0;
bsc_mgcp_free_endpoints(nat);
bsc_msc_schedule_connect(con);
}
static void msc_send_reset(struct bsc_msc_connection *con)
{
static const u_int8_t reset[] = {
0x00, 0x12, 0xfd,
0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
0x01, 0x20
};
struct msgb *msg;
msg = msgb_alloc_headroom(4096, 128, "08.08 reset");
if (!msg) {
LOGP(DMSC, LOGL_ERROR, "Failed to allocate reset msg.\n");
return;
}
msg->l2h = msgb_put(msg, sizeof(reset));
memcpy(msg->l2h, reset, msgb_l2len(msg));
if (write_queue_enqueue(&con->write_queue, msg) != 0) {
LOGP(DMSC, LOGL_ERROR, "Failed to enqueue reset msg.\n");
msgb_free(msg);
}
LOGP(DMSC, LOGL_NOTICE, "Scheduled GSM0808 reset msg for the MSC.\n");
}
static int ipaccess_msc_read_cb(struct bsc_fd *bfd)
{
int error;

View File

@@ -652,7 +652,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,