mncc_sock: Add new 'mncc handler' function

This adds mncc_sock_from_cc() as a handler function for CC messages
to be passed to the MNCC interface.  If there is no MNCC socket
registered, we immediately release any CC related messages.

Together with flushing all established CC transaction at MNCC socket
close time, this ensures that all resources are released and no
new resources can be established until the MNCC applicaiton has
re-attached.
This commit is contained in:
Harald Welte
2010-12-23 01:26:29 +01:00
parent 29b64e9708
commit ea057d9350
2 changed files with 39 additions and 1 deletions

View File

@@ -156,8 +156,13 @@ struct gsm_data_frame {
};
char *get_mncc_name(int value);
int int_mncc_recv(struct gsm_network *net, struct msgb *msg);
void mncc_set_cause(struct gsm_mncc *data, int loc, int val);
void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg);
/* input from CC code into mncc_builtin */
int int_mncc_recv(struct gsm_network *net, struct msgb *msg);
/* input from CC code into mncc_sock */
void mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg);
#endif

View File

@@ -32,6 +32,7 @@
#include <osmocore/talloc.h>
#include <osmocore/select.h>
#include <osmocore/protocol/gsm_04_08.h>
#include <openbsc/debug.h>
#include <openbsc/mncc.h>
@@ -46,6 +47,38 @@ struct mncc_sock_state {
/* FIXME: avoid this */
static struct mncc_sock_state *g_state;
/* input from CC code into mncc_sock */
void mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg)
{
struct gsm_mncc *mncc_in = msgb_data(msg);
int msg_type = mncc_in->msg_type;
/* Check if we currently have a MNCC handler connected */
if (g_state->conn_bfd.fd < 0) {
LOGP(DMNCC, LOGL_ERROR, "mncc_sock receives %s for external CC app "
"but socket is gone\n", get_mncc_name(msg_type));
if (msg_type != GSM_TCHF_FRAME &&
msg_type != GSM_TCHF_FRAME_EFR) {
/* release the request */
struct gsm_mncc mncc_out;
memset(&mncc_out, 0, sizeof(mncc_out));
mncc_out.callref = mncc_in->callref;
mncc_set_cause(&mncc_out, GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_TEMP_FAILURE);
mncc_tx_to_cc(net, MNCC_REL_REQ, &mncc_out);
}
/* free the original message */
msgb_free(msg);
return;
}
/* FIXME: check for some maximum queue depth? */
/* Actually enqueue the message and mark socket write need */
msgb_enqueue(&net->upqueue, msg);
g_state->conn_bfd.when |= BSC_FD_WRITE;
}
void mncc_sock_write_pending(void)
{
g_state->conn_bfd.when |= BSC_FD_WRITE;