From 510087752e46489b7ea61d72b3ab39540ce0d908 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 29 Dec 2009 11:49:12 +0100 Subject: introduce and implement silent_call_reroute() and silent_call_rx() Thise two functions are interfacing with the 04.08 layer 3 to determine if a particular message should be handled inside the OpenBSC layer 3, or if it should be handled in the silent call handler. --- openbsc/include/openbsc/silent_call.h | 2 ++ openbsc/src/gsm_04_08.c | 4 ++++ openbsc/src/silent_call.c | 44 +++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/openbsc/include/openbsc/silent_call.h b/openbsc/include/openbsc/silent_call.h index 53ed4e248..b5bc5c035 100644 --- a/openbsc/include/openbsc/silent_call.h +++ b/openbsc/include/openbsc/silent_call.h @@ -3,5 +3,7 @@ extern int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data); extern int gsm_silent_call_stop(struct gsm_subscriber *subscr); +extern int silent_call_rx(struct msgb *msg); +extern int silent_call_reroute(struct msgb *msg); #endif /* _SILENT_CALL_H */ diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 6eeddbf90..cd66d255f 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -50,6 +50,7 @@ #include #include #include +#include #define GSM_MAX_FACILITY 128 #define GSM_MAX_SSVERSION 128 @@ -3500,6 +3501,9 @@ int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id) struct gsm48_hdr *gh = msgb_l3(msg); u_int8_t pdisc = gh->proto_discr & 0x0f; int rc = 0; + + if (silent_call_reroute(msg)) + return silent_call_rx(msg); switch (pdisc) { case GSM48_PDISC_CC: diff --git a/openbsc/src/silent_call.c b/openbsc/src/silent_call.c index 500d1873d..2679db7a9 100644 --- a/openbsc/src/silent_call.c +++ b/openbsc/src/silent_call.c @@ -34,6 +34,7 @@ #include #include +/* paging of the requested subscriber has completed */ static int paging_cb_silent(unsigned int hooknum, unsigned int event, struct msgb *msg, void *_lchan, void *_data) { @@ -70,6 +71,48 @@ static int paging_cb_silent(unsigned int hooknum, unsigned int event, return rc; } +/* receive a layer 3 message from a silent call */ +int silent_call_rx(struct msgb *msg) +{ + /* FIXME: do something like sending it through a UDP port */ + return 0; +} + +struct msg_match { + u_int8_t pdisc; + u_int8_t msg_type; +}; + +/* list of messages that are handled inside OpenBSC, even in a silent call */ +static const struct msg_match silent_call_accept[] = { + { GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST }, + { GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_REQ }, +}; + +/* decide if we need to reroute a message as part of a silent call */ +int silent_call_reroute(struct msgb *msg) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + u_int8_t pdisc = gh->proto_discr & 0x0f; + int i; + + /* if we're not part of a silent call, never reroute */ + if (!msg->lchan->silent_call) + return 0; + + /* check if we are a special message that is handled in openbsc */ + for (i = 0; i < ARRAY_SIZE(silent_call_accept); i++) { + if (silent_call_accept[i].pdisc == pdisc && + silent_call_accept[i].msg_type == gh->msg_type) + return 0; + } + + /* otherwise, reroute */ + return 1; +} + + +/* initiate a silent call with a given subscriber */ int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data) { int rc; @@ -79,6 +122,7 @@ int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data) return rc; } +/* end a silent call with a given subscriber */ int gsm_silent_call_stop(struct gsm_subscriber *subscr) { struct gsm_lchan *lchan; -- cgit v1.2.3