[PATCH] bsc/ussd: Send faked CM Service Accept before sending USSD
The MS do not show the USSD messages yet. This patch modifies the implementation to insert a CM Service Accept before the ussdNotify to finish the establishment of the MM connection according to 3GPP TS 04.10/3.2.1. This fix has been tested with a Blackberry phone that has shown an ussd_grace_txt after rf_locked has been set to '1'. Without this patch, that message wasn't shown. The phone has sent a CC Setup and other messages before processing the channel release message sent by the BSC, but these messages have not been forwarded to the MSC (as expected). Ticket: OW#957 Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gsm_04_08.h | 3 +++ openbsc/src/libmsc/gsm_04_08.c | 4 ++-- openbsc/src/osmo-bsc/Makefile.am | 6 ++++-- openbsc/src/osmo-bsc/osmo_bsc_api.c | 17 +++++++++++------ 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 2f5aaa9..8df7b73 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -39,6 +39,9 @@ void gsm_net_update_ctype(struct gsm_network *net); int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn); int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand, int key_seq); int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn); +int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn); +int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, + enum gsm48_reject_value value); int gsm48_send_rr_release(struct gsm_lchan *lchan); int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv); int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_id, diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c41443e..df985ca 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -804,14 +804,14 @@ int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn) return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_AUTH_REJ); } -static int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) +int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) { DEBUGP(DMM, "-> CM SERVICE ACK\n"); return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_ACC); } /* 9.2.6 CM service reject */ -static int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, +int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, enum gsm48_reject_value value) { struct msgb *msg; diff --git a/openbsc/src/osmo-bsc/Makefile.am b/openbsc/src/osmo-bsc/Makefile.am index 63972c8..9c091af 100644 --- a/openbsc/src/osmo-bsc/Makefile.am +++ b/openbsc/src/osmo-bsc/Makefile.am @@ -16,5 +16,7 @@ osmo_bsc_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libcommon/libcommon.a \ $(top_builddir)/src/libctrl/libctrl.a \ $(top_builddir)/src/libcommon/libcommon.a \ - $(LIBOSMOSCCP_LIBS) $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS) $(LIBOSMOABIS_LIBS) + -ldbi -ldl $(LIBOSMOSCCP_LIBS) \ + $(LIBSMPP34_LIBS) $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS) \ + $(LIBOSMOABIS_LIBS) diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c index 675bbb2..8288d3b 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_api.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c @@ -87,8 +87,8 @@ static void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, queue_msg_or_return(resp); } -static void bsc_send_ussd_notification(struct gsm_subscriber_connection *conn, - struct msgb *msg, const char *text) +static void bsc_send_ussd_no_srv(struct gsm_subscriber_connection *conn, + struct msgb *msg, const char *text) { struct gsm48_hdr *gh; int8_t pdisc; @@ -119,10 +119,14 @@ static void bsc_send_ussd_notification(struct gsm_subscriber_connection *conn, } if (drop_message) { - LOGP(DMSC, LOGL_DEBUG, "Skipping (not sending) USSD message: '%s'\n", text); + LOGP(DMSC, LOGL_DEBUG, "Skipping (not sending) USSD message: '%s'\n", + text); return; } + LOGP(DMSC, LOGL_INFO, "Sending CM Service Accept\n"); + gsm48_tx_mm_serv_ack(conn); + LOGP(DMSC, LOGL_INFO, "Sending USSD message: '%s'\n", text); gsm0480_send_ussdNotify(conn, 1, text); gsm0480_send_releaseComplete(conn); @@ -143,7 +147,8 @@ static int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg msc = bsc_find_msc(conn, msg); if (!msc) { LOGP(DMSC, LOGL_ERROR, "Failed to find a MSC for a connection.\n"); - bsc_send_ussd_notification(conn, msg, conn->bts->network->bsc_data->ussd_no_msc_txt); + bsc_send_ussd_no_srv(conn, msg, + conn->bts->network->bsc_data->ussd_no_msc_txt); return -1; } @@ -164,9 +169,9 @@ static int complete_layer3(struct gsm_subscriber_connection *conn, if (ret != BSC_CON_SUCCESS) { /* allocation has failed */ if (ret == BSC_CON_REJECT_NO_LINK) - bsc_send_ussd_notification(conn, msg, msc->ussd_msc_lost_txt); + bsc_send_ussd_no_srv(conn, msg, msc->ussd_msc_lost_txt); else if (ret == BSC_CON_REJECT_RF_GRACE) - bsc_send_ussd_notification(conn, msg, msc->ussd_grace_txt); + bsc_send_ussd_no_srv(conn, msg, msc->ussd_grace_txt); return BSC_API_CONN_POL_REJECT; } -- 1.7.9.5
On Thu, Oct 31, 2013 at 10:47:02AM +0100, Jacob Erlbeck wrote: haha, you got me. I have pushed and reverted your patch.
--- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -804,14 +804,14 @@ int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn) return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_AUTH_REJ); }
-static int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) +int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) { DEBUGP(DMM, "-> CM SERVICE ACK\n"); return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_ACC); }
/* 9.2.6 CM service reject */ -static int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, +int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, enum gsm48_reject_value value)
no. You need to move this code to the gsm_04_08_utils.c of libbsc.
+ -ldbi -ldl $(LIBOSMOSCCP_LIBS) \ + $(LIBSMPP34_LIBS) $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS) \ + $(LIBOSMOABIS_LIBS)
eeeek. There is no reason that the BSC should link to libsmpp34 and dbi and dl.. When moving the above code to gsm_04_08_utils.c no Makefile.am change is necessary.
+ LOGP(DMSC, LOGL_INFO, "Sending CM Service Accept\n"); + gsm48_tx_mm_serv_ack(conn);
I would prefer if this is the only change your patch is doing inside the BSC. This will ease chery-picking. Feel free to do the renaming of the method after. holger
These functions are currently located in libmsc/gsm_04_08.c together with other symbols that (transitively) depend on many external symbols (and thus libraries) that aren't otherwise needed by e.g. osmo-bsc. Since gsm48_tx_mm_serv_ack() will be needed by osmo-bsc, these functions are moved to avoid the dependency on gsm_04_08.o. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gsm_04_08.h | 3 +++ openbsc/src/libbsc/gsm_04_08_utils.c | 34 ++++++++++++++++++++++++++++++++++ openbsc/src/libmsc/gsm_04_08.c | 23 ----------------------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 2f5aaa9..8df7b73 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -39,6 +39,9 @@ void gsm_net_update_ctype(struct gsm_network *net); int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn); int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand, int key_seq); int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn); +int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn); +int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, + enum gsm48_reject_value value); int gsm48_send_rr_release(struct gsm_lchan *lchan); int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv); int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_id, diff --git a/openbsc/src/libbsc/gsm_04_08_utils.c b/openbsc/src/libbsc/gsm_04_08_utils.c index 8ccefd7..a0e7e5d 100644 --- a/openbsc/src/libbsc/gsm_04_08_utils.c +++ b/openbsc/src/libbsc/gsm_04_08_utils.c @@ -36,6 +36,7 @@ #include <openbsc/transaction.h> #include <openbsc/paging.h> #include <openbsc/signal.h> +#include <openbsc/bsc_api.h> /* should ip.access BTS use direct RTP streams between each other (1), * or should OpenBSC always act as RTP relay/proxy in between (0) ? */ @@ -649,3 +650,36 @@ struct msgb *gsm48_create_loc_upd_rej(uint8_t cause) gh->data[0] = cause; return msg; } + +/* 9.2.5 CM service accept */ +int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) +{ + struct msgb *msg = gsm48_msgb_alloc(); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + + msg->lchan = conn->lchan; + + gh->proto_discr = GSM48_PDISC_MM; + gh->msg_type = GSM48_MT_MM_CM_SERV_ACC; + + DEBUGP(DMM, "-> CM SERVICE ACK\n"); + + return gsm0808_submit_dtap(conn, msg, 0, 0); +} + +/* 9.2.6 CM service reject */ +int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, + enum gsm48_reject_value value) +{ + struct msgb *msg; + + msg = gsm48_create_mm_serv_rej(value); + if (!msg) { + LOGP(DMM, LOGL_ERROR, "Failed to allocate CM Service Reject.\n"); + return -1; + } + + DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value); + + return gsm0808_submit_dtap(conn, msg, 0, 0); +} diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index c41443e..3cfc455 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -804,29 +804,6 @@ int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn) return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_AUTH_REJ); } -static int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) -{ - DEBUGP(DMM, "-> CM SERVICE ACK\n"); - return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_ACC); -} - -/* 9.2.6 CM service reject */ -static int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, - enum gsm48_reject_value value) -{ - struct msgb *msg; - - msg = gsm48_create_mm_serv_rej(value); - if (!msg) { - LOGP(DMM, LOGL_ERROR, "Failed to allocate CM Service Reject.\n"); - return -1; - } - - DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value); - msg->lchan = conn->lchan; - return gsm48_conn_sendmsg(msg, conn, NULL); -} - static int _gsm48_rx_mm_serv_req_sec_cb( unsigned int hooknum, unsigned int event, struct msgb *msg, void *data, void *param) -- 1.7.9.5
The MS do not show the USSD messages yet. This patch modifies the implementation to insert a CM Service Accept to finish the establishment of the MM connection according to 3GPP TS 04.10/3.2.1 before the USSD notification is sent. This fix has been tested with a Blackberry phone that has shown an ussd_grace_txt after rf_locked has been set to '1'. Without this patch, that message wasn't shown. The phone has sent a CC Setup and other messages before processing the channel release message sent by the BSC, but these messages have not been forwarded to the MSC (as expected). Ticket: OW#957 Sponsored-by: On-Waves ehf --- openbsc/src/osmo-bsc/osmo_bsc_api.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c index 675bbb2..eca2535 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_api.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c @@ -123,6 +123,9 @@ static void bsc_send_ussd_notification(struct gsm_subscriber_connection *conn, return; } + LOGP(DMSC, LOGL_INFO, "Sending CM Service Accept\n"); + gsm48_tx_mm_serv_ack(conn); + LOGP(DMSC, LOGL_INFO, "Sending USSD message: '%s'\n", text); gsm0480_send_ussdNotify(conn, 1, text); gsm0480_send_releaseComplete(conn); -- 1.7.9.5
Rename this function to bsc_send_ussd_no_srv() since it's a rather specialised function and not a generic USSD notification function. Sponsored-by: On-Waves ehf --- openbsc/src/osmo-bsc/osmo_bsc_api.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c index eca2535..1751df7 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_api.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c @@ -87,8 +87,8 @@ static void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, queue_msg_or_return(resp); } -static void bsc_send_ussd_notification(struct gsm_subscriber_connection *conn, - struct msgb *msg, const char *text) +static void bsc_send_ussd_no_srv(struct gsm_subscriber_connection *conn, + struct msgb *msg, const char *text) { struct gsm48_hdr *gh; int8_t pdisc; @@ -146,7 +146,8 @@ static int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg msc = bsc_find_msc(conn, msg); if (!msc) { LOGP(DMSC, LOGL_ERROR, "Failed to find a MSC for a connection.\n"); - bsc_send_ussd_notification(conn, msg, conn->bts->network->bsc_data->ussd_no_msc_txt); + bsc_send_ussd_no_srv(conn, msg, + conn->bts->network->bsc_data->ussd_no_msc_txt); return -1; } @@ -167,9 +168,9 @@ static int complete_layer3(struct gsm_subscriber_connection *conn, if (ret != BSC_CON_SUCCESS) { /* allocation has failed */ if (ret == BSC_CON_REJECT_NO_LINK) - bsc_send_ussd_notification(conn, msg, msc->ussd_msc_lost_txt); + bsc_send_ussd_no_srv(conn, msg, msc->ussd_msc_lost_txt); else if (ret == BSC_CON_REJECT_RF_GRACE) - bsc_send_ussd_notification(conn, msg, msc->ussd_grace_txt); + bsc_send_ussd_no_srv(conn, msg, msc->ussd_grace_txt); return BSC_API_CONN_POL_REJECT; } -- 1.7.9.5
participants (2)
-
Holger Hans Peter Freyther -
Jacob Erlbeck