From chester.mino at gmail.com Thu Apr 2 14:47:05 2015 From: chester.mino at gmail.com (Dominiq T) Date: Thu, 2 Apr 2015 16:47:05 +0200 Subject: OsmoBTS - OsmocomBB emulation project Message-ID: Dear Osmcom, I am working on a project, where I am connecting OsmoBTS with OsmocomBB without hardware. I am trying to remove l1 on both sides and connect OsmoBTS with BB application via simple unix sockets. Based on the further recommendations, I am using osmobts-trx branch. Currently I am able to handle messages between BTS and TRX driver on clock and control ports, and on BB side I am in state that phone wants to connect into a cell (so its waiting for BCCH) . I am now trying to find a possible way how to handle messages on data port , between BTS ? TRX ( TRX is removed, there is my application instead), and forward these messages to my customized BB l1 interface . The thing is that I need to send to BB phone (layer23) messages in structures from gsm_04_08.h (i.e. gsm48_system_information_type_3). I am not sure if I will be able to get needed from the messages coming on the data port 5702. I found, that PCU creates unix socket on ?/tmp/pcu_bts? , but only in case sysmoBTS is in use (please correct me if I am wrong), so this will be not possible due compilation errors without HW. Here I found the gsm48_system_information_type_3 messages. So basically I need somehow to get this message structures on my custom l1 BB interface. Do you have any idea how to do this ? Any advice will be highly appreciated. Many thanks you for your attention :) Best regards, Dominik Tamaskovic. -------------- next part -------------- An HTML attachment was scrubbed... URL: From holger at freyther.de Sat Apr 4 07:05:20 2015 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 4 Apr 2015 09:05:20 +0200 Subject: libosmo-abis/RSL queue and OS interaction Message-ID: <20150404070520.GA10127@xiaoyu.lan> Dear Pablo, Ciaby, from what I see we have the following OpenBSC/OS integration. * OpenBSC wants to send some RSL data and calls abis_rsl_sendmsg ** abis_rsl_sendmsg entails the msgb into a queue and informs the lower layer driver (ipa in our case) ** ipa sets the when to ~= BSC_FD_WRITE * code returns * OpenBSC runs select for all fds/timers.. * libosmocore dispatches fd's ** libosmo-abis/ipaccess.c will try to write a single message ** libosmo-abis/ipaccess.c will set the BSC_FD_WRITE again if the queue is not empty * Linux/TCP will run nagle to combine these messages * OpenBSC runs select for all fds/timers... .... The integration does work but appears to be a bit painful for busy and high latency links. E.g. OpenBSC starts timers when abis_rsl_sendmsg is invoked which might just be a little bit later. I wonder if there is a better way? For reading we could read until -EWOULDBLOCK but then this might not be too fair for the other parts of the software. For writing we might end up in the situation where a write only partially succeeds and we need to remember how much of the msgb to write next... So we would need to do ioctl's to check how much space is left in the send buffer Do you have ideas? comments? is it a non issue? is it something we can do better? Is there a TCP mode where a "write" either fully succeeds or fails with -ENOSPC or such? holger From laforge at gnumonks.org Sun Apr 5 13:46:16 2015 From: laforge at gnumonks.org (Harald Welte) Date: Sun, 5 Apr 2015 15:46:16 +0200 Subject: libosmo-abis/RSL queue and OS interaction In-Reply-To: <20150404070520.GA10127@xiaoyu.lan> References: <20150404070520.GA10127@xiaoyu.lan> Message-ID: <20150405134616.GD31452@nataraja> Hi Holger, Pablo, Ciaby, On Sat, Apr 04, 2015 at 09:05:20AM +0200, Holger Hans Peter Freyther wrote: > * Linux/TCP will run nagle to combine these messages we could easily disable nagle if that's what we want to avoid latencies [see below] > I wonder if there is a better way? For reading we could read > until -EWOULDBLOCK but then this might not be too fair for > the other parts of the software. In terms of msgb reading, I think a fixed upper limit might make sense, i.e. read up to [configurable] N messages in one BSC_FD_READ callback. > For writing we might end up in the situation where a write only > partially succeeds and we need to remember how much of the msgb to > write next... So we would need to do ioctl's to check how much space > is left in the send buffer Even if you do the ioctl(SICOUTQ) / getsockopt(SO_SNDBUF), what would you do next? i.e. if you have determined not to write the msgb due to insufficient socket buffer space. If you then leave BSC_FD_WRITE set, then your next select will immediately return, and you have a potential to busy-loop until finally the buffer space is available. In case the remote end / network link is stalled this would be quite dangerous. If you don't set BSC_FD_WRITE, then you wouldn't notice once the buffer has sufficient space again. If you did periodic checks, then the latency introduced by those checks are probably counter-productive. So I think we will have to deal with partial writes from the IPA msgb sending code, just like the IPA msgb receiving code has to deal with partial reads. > Do you have ideas? comments? is it a non issue? is it something > we can do better? It depends probably on the use case. On expensive (e.g. sat) links you probably want nagle to combine multiple packets. In all other cases disabling nagle is probably a good idea to get started. > Is there a TCP mode where a "write" either fully succeeds or fails > with -ENOSPC or such? Not to my knowledge. The proper answer would probably to use DCCP or SCTP or any other protocol that can provide reliable delivery of packets (possibly with ordering guarantees) and not abuse a stream protocol like TCP. This would of course break IPA compatibility... but it might be an interesting experiment to compare different L4 protocol performance against TCP for the given use case. -- - Harald Welte http://laforge.gnumonks.org/ ============================================================================ "Privacy in residential applications is a desirable marketing option." (ETSI EN 300 175-7 Ch. A6) From holger at freyther.de Mon Apr 6 10:08:19 2015 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 6 Apr 2015 12:08:19 +0200 Subject: recurring issue with OpenBSC In-Reply-To: <20150204091031.GA8805@xiaoyu.lan> References: <5479FD5C.3000708@autistici.org> <20141130154252.GU16131@xiaoyu.lan> <547B76C6.3080408@autistici.org> <20141202075929.GA14607@xiaoyu.lan> <20150204091031.GA8805@xiaoyu.lan> Message-ID: <20150406100819.GA13126@xiaoyu.lan> On Wed, Feb 04, 2015 at 10:10:31AM +0100, Holger Hans Peter Freyther wrote: > My current thought on this system is that we should remove > subscr_put_channel. It is based on some assumptions/goals > that does not make sense anymore. I started the removal zecke/features/no-queue... it still needs integration with the SMPP/sms_queue... and I have not used it at all yet.. From holger at freyther.de Mon Apr 6 15:17:53 2015 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 6 Apr 2015 17:17:53 +0200 Subject: recurring issue with OpenBSC In-Reply-To: <20150406100819.GA13126@xiaoyu.lan> References: <5479FD5C.3000708@autistici.org> <20141130154252.GU16131@xiaoyu.lan> <547B76C6.3080408@autistici.org> <20141202075929.GA14607@xiaoyu.lan> <20150204091031.GA8805@xiaoyu.lan> <20150406100819.GA13126@xiaoyu.lan> Message-ID: <20150406151753.GA8318@xiaoyu.lan> On Mon, Apr 06, 2015 at 12:08:19PM +0200, Holger Hans Peter Freyther wrote: > I started the removal zecke/features/no-queue... it still > needs integration with the SMPP/sms_queue... and I have not > used it at all yet.. I fixed the first round of crashes/defects. It should be feature equal to the current master branch. What I noticed is that if there is a SDCCH open and we place a call.. it is not using the same audio codec as the other leg of the call. I have to monitor the tch_mode of the logical channel. From holger at freyther.de Mon Apr 6 16:52:23 2015 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 6 Apr 2015 18:52:23 +0200 Subject: recurring issue with OpenBSC In-Reply-To: <20150406151753.GA8318@xiaoyu.lan> References: <5479FD5C.3000708@autistici.org> <20141130154252.GU16131@xiaoyu.lan> <547B76C6.3080408@autistici.org> <20141202075929.GA14607@xiaoyu.lan> <20150204091031.GA8805@xiaoyu.lan> <20150406100819.GA13126@xiaoyu.lan> <20150406151753.GA8318@xiaoyu.lan> Message-ID: <20150406165223.GE8318@xiaoyu.lan> On Mon, Apr 06, 2015 at 05:17:53PM +0200, Holger Hans Peter Freyther wrote: > I fixed the first round of crashes/defects. It should be feature > equal to the current master branch. What I noticed is that if there > is a SDCCH open and we place a call.. it is not using the same > audio codec as the other leg of the call. > > I have to monitor the tch_mode of the logical channel. Okay, we enter into the field of MNCC not being up to the job. The issue was that the channel type was compared to TCH_F and then the "TCH_H" codec was assigned... I know the whole topic of codec selection is something to look into. I have put a band-aid on it to have gsm_04_08.c and the mncc_builtin.c to behave the same. The next topic (besides more testing) is sms_queue and SMPP integration to enforce the one SMS per direction rule and have the two systems coordinate each other. From jerlbeck at sysmocom.de Tue Apr 7 15:49:47 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Apr 2015 17:49:47 +0200 Subject: [PATCH 1/4] nat: Fix timeslot range in 'show bsc mgcp' VTY command Message-ID: <1428421790-3423-1-git-send-email-jerlbeck@sysmocom.de> Currently the inner loop in show_bsc_mgcp iterates of the timeslot interval [0, 31]. Timeslot 0 is not valid, which causes mgcp_timeslot_to_endpoint to generate a corresponding warning and to return an invalid endp value. That value causes an out-of-bound read access, possibly hitting unallocated memory. This patch fixes the loop range by starting with timeslot 1. Note that this does not prevent mgcp_timeslot_to_endpoint from returning an invalid endpoint index when called with arguments not within its domain. Addresses: <000b> ../../include/openbsc/mgcp.h:250 Timeslot should not be 0 [...] vty=0xb4203db0, argc=1, argv=0xbfffebb0) at bsc_nat_vty.c:256 max = 1 con = 0xb4a004f0 i = 0 j = 0 [...] ==15700== ERROR: AddressSanitizer: heap-use-after-free on address 0xb520be4f at pc 0x8062a42 bp 0xbfffeb18 sp 0xbfffeb0c Sponsored-by: On-Waves ehf --- openbsc/src/osmo-bsc_nat/bsc_nat_vty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c index 5f4ad28..2b7db2e 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c @@ -250,7 +250,7 @@ DEFUN(show_bsc_mgcp, show_bsc_mgcp_cmd, "show bsc mgcp NR", vty_out(vty, "MGCP Status for %d%s", con->cfg->nr, VTY_NEWLINE); max = bsc_mgcp_nr_multiplexes(con->max_endpoints); for (i = 0; i < max; ++i) { - for (j = 0; j < 32; ++j) { + for (j = 1; j < 32; ++j) { endp = mgcp_timeslot_to_endpoint(i, j); vty_out(vty, " Endpoint 0x%x %s%s", endp, con->_endpoint_status[endp] == 0 -- 1.9.1 From jerlbeck at sysmocom.de Tue Apr 7 15:49:49 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Apr 2015 17:49:49 +0200 Subject: [PATCH 3/4] nitb: Check source string length before calling strncpy (Coverity) In-Reply-To: <1428421790-3423-1-git-send-email-jerlbeck@sysmocom.de> References: <1428421790-3423-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1428421790-3423-3-git-send-email-jerlbeck@sysmocom.de> Currently some VTY command do neither check the length of the source string before calling strncpy nor ensure NUL-termination afterwards. This can to destination string buffers whose contents are not NUL-teminated. This commit adds checks and corresponding warnings to the VTY commands 'subscriber TYPE ID name .NAME" and "subscriber TYPE ID extension EXTENSION". Fixes: Coverity CID 1206570, 1206569 Sponsored-by: On-Waves ehf --- openbsc/src/libmsc/vty_interface_layer3.c | 14 ++++++++++++++ openbsc/tests/vty_test_runner.py | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 68d9c44..558db5e 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -548,6 +548,13 @@ DEFUN(ena_subscr_name, return CMD_WARNING; } + if (strlen(name) > sizeof(subscr->name)-1) { + vty_out(vty, + "%% NAME is too long, max. %d characters are allowed%s", + sizeof(subscr->name)-1, VTY_NEWLINE); + return CMD_WARNING; + } + strncpy(subscr->name, name, sizeof(subscr->name)); talloc_free(name); db_sync_subscriber(subscr); @@ -574,6 +581,13 @@ DEFUN(ena_subscr_extension, return CMD_WARNING; } + if (strlen(ext) > sizeof(subscr->extension)-1) { + vty_out(vty, + "%% EXTENSION is too long, max. %d characters are allowed%s", + sizeof(subscr->extension)-1, VTY_NEWLINE); + return CMD_WARNING; + } + strncpy(subscr->extension, ext, sizeof(subscr->extension)); db_sync_subscriber(subscr); diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 2b7fd19..fb4ca7d 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -286,6 +286,32 @@ class TestVTYNITB(TestVTYGenericBSC): res = self.vty.command('show subscriber imsi '+imsi) self.assert_(res != '% No subscriber found for imsi '+imsi) + def testSubscriberSettings(self): + self.vty.enable() + + imsi = "204300854013739" + wrong_imsi = "204300999999999" + + # Lets create one + res = self.vty.command('subscriber create imsi '+imsi) + self.assert_(res.find(" IMSI: "+imsi) > 0) + + self.vty.verify('subscriber imsi '+wrong_imsi+' name wrong', ['% No subscriber found for imsi '+wrong_imsi]) + res = self.vty.command('subscriber imsi '+imsi+' name '+('X' * 160)) + self.assert_(res.find("NAME is too long") > 0) + + self.vty.verify('subscriber imsi '+imsi+' name '+('G' * 159), ['']) + + self.vty.verify('subscriber imsi '+wrong_imsi+' extension 840', ['% No subscriber found for imsi '+wrong_imsi]) + res = self.vty.command('subscriber imsi '+imsi+' extension '+('9' * 15)) + self.assert_(res.find("EXTENSION is too long") > 0) + + self.vty.verify('subscriber imsi '+imsi+' extension '+('1' * 14), ['']) + + # Delete it + res = self.vty.command('subscriber delete imsi '+imsi) + self.assert_(res != "") + def testShowPagingGroup(self): res = self.vty.command("show paging-group 255 1234567") self.assertEqual(res, "% can't find BTS 255") -- 1.9.1 From jerlbeck at sysmocom.de Tue Apr 7 15:49:48 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Apr 2015 17:49:48 +0200 Subject: [PATCH 2/4] gprs: Fix GSUP cancel_type handling (Coverity) In-Reply-To: <1428421790-3423-1-git-send-email-jerlbeck@sysmocom.de> References: <1428421790-3423-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1428421790-3423-2-git-send-email-jerlbeck@sysmocom.de> When handling an incoming GSUP cancellation request, the cancel_type if effectively ignored, such that is always handled as GPRS_GSUP_CANCEL_TYPE_UPDATE and never as WITHDRAW. This commit fixes the expression used to set the variable is_update_procedure. Fixes: Coverity CID 1267739 Sponsored-by: On-Waves ehf --- openbsc/src/gprs/gprs_subscriber.c | 3 ++- openbsc/tests/sgsn/sgsn_test.c | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 8486834..e3da0f8 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -492,7 +492,8 @@ static int gprs_subscr_handle_loc_cancel_req(struct gsm_subscriber *subscr, struct gprs_gsup_message *gsup_msg) { struct gprs_gsup_message gsup_reply = {0}; - int is_update_procedure = !gsup_msg->cancel_type || gsup_msg->cancel_type; + int is_update_procedure = !gsup_msg->cancel_type || + gsup_msg->cancel_type == GPRS_GSUP_CANCEL_TYPE_UPDATE; LOGGSUBSCRP(LOGL_INFO, subscr, "Cancelling MS subscriber (%s)\n", is_update_procedure ? diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 6fc4f99..197be9d 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -440,6 +440,12 @@ static void test_subscriber_gsup(void) 0x06, 0x01, 0x00, }; + static const uint8_t location_cancellation_req_withdraw[] = { + 0x1c, + TEST_GSUP_IMSI1_IE, + 0x06, 0x01, 0x01, + }; + static const uint8_t location_cancellation_req_other[] = { 0x1c, 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01, @@ -582,6 +588,12 @@ static void test_subscriber_gsup(void) OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED); OSMO_ASSERT(s1->sgsn_data->mm == NULL); + /* Inject LocCancelReq(withdraw) GSUP message */ + rc = rx_gsup_message(location_cancellation_req_withdraw, + sizeof(location_cancellation_req_withdraw)); + OSMO_ASSERT(rc >= 0); + OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED); + /* Inject PurgeMsRes GSUP message */ rc = rx_gsup_message(purge_ms_res, sizeof(purge_ms_res)); -- 1.9.1 From jerlbeck at sysmocom.de Tue Apr 7 15:49:50 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Apr 2015 17:49:50 +0200 Subject: [PATCH 4/4] nitb: Fix IMSI/IMEI buffer handling (Coverity) In-Reply-To: <1428421790-3423-1-git-send-email-jerlbeck@sysmocom.de> References: <1428421790-3423-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1428421790-3423-4-git-send-email-jerlbeck@sysmocom.de> Currently the handling of the buffers is not done consistently. Some code assumes that the whole buffer may be used to store the string while at other places, the last buffer byte is left untouched in the assumption that it contains a terminating NUL-character. The latter is the correct behaviour. This commit changes to code to not touch the last byte in the buffers and to rely on the last byte being NUL. So the maximum IMSI/IMEI length is GSM_IMSI_LENGTH-1/GSM_IMEI_LENGTH-1. Fixes: Coverity CID 1206568, 1206567 Sponsored-by: On-Waves ehf --- openbsc/src/libcommon/gsm_subscriber_base.c | 3 +-- openbsc/src/libmsc/db.c | 2 +- openbsc/src/osmo-bsc_nat/bsc_ussd.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/openbsc/src/libcommon/gsm_subscriber_base.c b/openbsc/src/libcommon/gsm_subscriber_base.c index 3c56101..a455824 100644 --- a/openbsc/src/libcommon/gsm_subscriber_base.c +++ b/openbsc/src/libcommon/gsm_subscriber_base.c @@ -112,8 +112,7 @@ struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp, if (!subscr) return NULL; - strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH); - subscr->imsi[GSM_IMSI_LENGTH - 1] = '\0'; + strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH-1); subscr->group = sgrp; return subscr; } diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index bdecbb4..ee678b6 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -802,7 +802,7 @@ static void db_set_from_query(struct gsm_subscriber *subscr, dbi_conn result) const char *string; string = dbi_result_get_string(result, "imsi"); if (string) - strncpy(subscr->imsi, string, GSM_IMSI_LENGTH); + strncpy(subscr->imsi, string, GSM_IMSI_LENGTH-1); string = dbi_result_get_string(result, "tmsi"); if (string) diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c index ac5a9f5..67844b8 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c +++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c @@ -399,7 +399,7 @@ int bsc_ussd_check(struct nat_sccp_connection *con, struct bsc_nat_parsed *parse if (parsed->bssap != BSSAP_MSG_DTAP) return 0; - if (strlen(con->imsi) > GSM_IMSI_LENGTH) + if (strlen(con->imsi) >= GSM_IMSI_LENGTH) return 0; hdr48 = bsc_unpack_dtap(parsed, msg, &len); -- 1.9.1 From jerlbeck at sysmocom.de Tue Apr 7 15:52:43 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Apr 2015 17:52:43 +0200 Subject: [PATCH 1/3] bssgp: Always expect dup != NULL in bssgp_tx_dl_ud (Coverity) Message-ID: <1428421965-3534-1-git-send-email-jerlbeck@sysmocom.de> Currently the implementation of bssgp_tx_dl_ud conditionally adds some optional IE if dup != NULL. Later on is dereferences dup to access qos_profile and fc, but this without checking dup in advance. This may lead to an segmentation violation fault. This commit changes the value range of the function to only accept dup != NULL. An assertion will fail otherwise. All other explicit checks for non-NULL are removed. Fixes: Coverity CID 1040673 Sponsored-by: On-Waves ehf --- src/gb/gprs_bssgp.c | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c index 2f23290..a3fd6aa 100644 --- a/src/gb/gprs_bssgp.c +++ b/src/gb/gprs_bssgp.c @@ -1092,6 +1092,8 @@ int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime, uint16_t _pdu_lifetime = htons(pdu_lifetime); /* centi-seconds */ uint16_t drx_params; + OSMO_ASSERT(dup != NULL); + /* Identifiers from UP: TLLI, BVCI, NSEI (all in msgb->cb) */ if (bvci <= BVCI_PTM ) { LOGP(DBSSGP, LOGL_ERROR, "Cannot send DL-UD to BVCI %u\n", @@ -1124,35 +1126,32 @@ int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime, /* FIXME: optional elements: Alignment, UTRAN CCO, LSA, PFI */ - if (dup) { - /* Old TLLI to help BSS map from old->new */ - if (dup->tlli) { - uint32_t tlli = htonl(*dup->tlli); - msgb_tvlv_push(msg, BSSGP_IE_TLLI, 4, (uint8_t *) &tlli); - } - - /* IMSI */ - if (dup->imsi && strlen(dup->imsi)) { - uint8_t mi[10]; - int imsi_len = gsm48_generate_mid_from_imsi(mi, dup->imsi); - if (imsi_len > 2) - msgb_tvlv_push(msg, BSSGP_IE_IMSI, - imsi_len-2, mi+2); - } + /* Old TLLI to help BSS map from old->new */ + if (dup->tlli) { + uint32_t tlli = htonl(*dup->tlli); + msgb_tvlv_push(msg, BSSGP_IE_TLLI, 4, (uint8_t *) &tlli); + } - /* DRX parameters */ - drx_params = htons(dup->drx_parms); - msgb_tvlv_push(msg, BSSGP_IE_DRX_PARAMS, 2, - (uint8_t *) &drx_params); + /* IMSI */ + if (dup->imsi && strlen(dup->imsi)) { + uint8_t mi[10]; + int imsi_len = gsm48_generate_mid_from_imsi(mi, dup->imsi); + if (imsi_len > 2) + msgb_tvlv_push(msg, BSSGP_IE_IMSI, + imsi_len-2, mi+2); + } - /* FIXME: Priority */ + /* DRX parameters */ + drx_params = htons(dup->drx_parms); + msgb_tvlv_push(msg, BSSGP_IE_DRX_PARAMS, 2, + (uint8_t *) &drx_params); - /* MS Radio Access Capability */ - if (dup->ms_ra_cap.len) - msgb_tvlv_push(msg, BSSGP_IE_MS_RADIO_ACCESS_CAP, - dup->ms_ra_cap.len, dup->ms_ra_cap.v); + /* FIXME: Priority */ - } + /* MS Radio Access Capability */ + if (dup->ms_ra_cap.len) + msgb_tvlv_push(msg, BSSGP_IE_MS_RADIO_ACCESS_CAP, + dup->ms_ra_cap.len, dup->ms_ra_cap.v); /* prepend the pdu lifetime */ msgb_tvlv_push(msg, BSSGP_IE_PDU_LIFETIME, 2, (uint8_t *)&_pdu_lifetime); -- 1.9.1 From jerlbeck at sysmocom.de Tue Apr 7 15:52:45 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Apr 2015 17:52:45 +0200 Subject: [PATCH 3/3] ns: Log when sending fails (Coverity) In-Reply-To: <1428421965-3534-1-git-send-email-jerlbeck@sysmocom.de> References: <1428421965-3534-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1428421965-3534-3-git-send-email-jerlbeck@sysmocom.de> Currently the return value of the gprs_ns_tx family of functions is often ignored. This is not a serious issue, since the successful delivery of the messages is neither guaranteed nor acknowledged by the network layer anyway. Nevertheless this commit adds logging (level INFO) to gprs_ns_tx and gprs_ns_msgb_alloc. The definition of the latter has been moved from the header file to gprs_ns.c. Fixes: Coverity CID 1040678, 1040679, 1040680, 1040681, 1040682, 1040683, 1040684, 1040686, 1040687, 1040688, 1111545, 1240203, 1240204 Sponsored-by: On-Waves ehf --- include/osmocom/gprs/gprs_ns.h | 10 ++++------ src/gb/gprs_ns.c | 19 +++++++++++++++++++ src/gb/libosmogb.map | 1 + 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/include/osmocom/gprs/gprs_ns.h b/include/osmocom/gprs/gprs_ns.h index e77ca42..d5a605d 100644 --- a/include/osmocom/gprs/gprs_ns.h +++ b/include/osmocom/gprs/gprs_ns.h @@ -23,6 +23,9 @@ "Alive Timer (Tns-alive) timeout\n" \ "Alive Timer (Tns-alive) number of retries\n" +#define NS_ALLOC_SIZE 2048 +#define NS_ALLOC_HEADROOM 20 + enum ns_timeout { NS_TOUT_TNS_BLOCK, NS_TOUT_TNS_BLOCK_RETRIES, @@ -186,12 +189,7 @@ void gprs_ns_ll_copy(struct gprs_nsvc *nsvc, struct gprs_nsvc *other); /* Clear the link layer info (will never match a real link then) */ void gprs_ns_ll_clear(struct gprs_nsvc *nsvc); -#define NS_ALLOC_SIZE 2048 -#define NS_ALLOC_HEADROOM 20 -static inline struct msgb *gprs_ns_msgb_alloc(void) -{ - return msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "GPRS/NS"); -} +struct msgb *gprs_ns_msgb_alloc(void); enum signal_ns { S_NS_RESET, diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index 27968e3..827d09d 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -131,6 +131,17 @@ static const struct rate_ctr_group_desc nsvc_ctrg_desc = { LOGP(DNS, LOGL_ERROR, "TX failed (%d) to peer %s\n", \ rc, gprs_ns_ll_str(nsvc)); +struct msgb *gprs_ns_msgb_alloc(void) +{ + struct msgb *msg = msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, + "GPRS/NS"); + if (!msg) { + LOGP(DNS, LOGL_ERROR, "Failed to allocate NS message of size %d\n", + NS_ALLOC_SIZE); + } + return msg; +} + /*! \brief Lookup struct gprs_nsvc based on NSVCI * \param[in] nsi NS instance in which to search @@ -298,9 +309,17 @@ static int gprs_ns_tx(struct gprs_nsvc *nsvc, struct msgb *msg) switch (nsvc->ll) { case GPRS_NS_LL_UDP: ret = nsip_sendmsg(nsvc, msg); + if (ret < 0) + LOGP(DNS, LOGL_INFO, + "failed to send NS message via UDP: %s\n", + strerror(-ret)); break; case GPRS_NS_LL_FR_GRE: ret = gprs_ns_frgre_sendmsg(nsvc, msg); + if (ret < 0) + LOGP(DNS, LOGL_INFO, + "failed to send NS message via FR/GRE: %s\n", + strerror(-ret)); break; default: LOGP(DNS, LOGL_ERROR, "unsupported NS linklayer %u\n", nsvc->ll); diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map index a21a7ac..43ebbf8 100644 --- a/src/gb/libosmogb.map +++ b/src/gb/libosmogb.map @@ -57,6 +57,7 @@ gprs_ns_vty_init; gprs_ns_ll_str; gprs_ns_ll_copy; gprs_ns_ll_clear; +gprs_ns_msgb_alloc; gprs_nsvc_create; gprs_nsvc_delete; -- 1.9.1 From jerlbeck at sysmocom.de Tue Apr 7 15:52:44 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 7 Apr 2015 17:52:44 +0200 Subject: [PATCH 2/3] bssgp: Ensure non-NULL bctx before calling bssgp_rx_ptp (Coverity) In-Reply-To: <1428421965-3534-1-git-send-email-jerlbeck@sysmocom.de> References: <1428421965-3534-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1428421965-3534-2-git-send-email-jerlbeck@sysmocom.de> Currently bssgp_rx_ptp might be called with bctx being NULL, when the NS BVCI is neither BVCI_SIGNALLING nor BVCI_PTM, but the message is a BVC_RESET or it contains an BVCI IE != BVCI_SIGNALLING where the BVCI is not known. This patch ensures that bssgp_rx_ptp will only be called with a non-NULL bctx. A log message will be issued, if the bctx is NULL when this was not expected. Fixes: Coverity CID 1040674 Sponsored-by: On-Waves ehf --- src/gb/gprs_bssgp.c | 7 ++++++- tests/gb/gprs_bssgp_test.c | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c index a3fd6aa..4c93b69 100644 --- a/src/gb/gprs_bssgp.c +++ b/src/gb/gprs_bssgp.c @@ -1073,8 +1073,13 @@ int bssgp_rcvmsg(struct msgb *msg) rc = bssgp_rx_sign(msg, &tp, bctx); else if (ns_bvci == BVCI_PTM) rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg); - else + else if (bctx) rc = bssgp_rx_ptp(msg, &tp, bctx); + else + LOGP(DBSSGP, LOGL_NOTICE, + "NSEI=%u/BVCI=%u Cannot handle PDU type %u for " + "unknown BVCI, NS BVCI %u\n", + msgb_nsei(msg), bvci, pdu_type, ns_bvci); return rc; } diff --git a/tests/gb/gprs_bssgp_test.c b/tests/gb/gprs_bssgp_test.c index 3d1384b..b454430 100644 --- a/tests/gb/gprs_bssgp_test.c +++ b/tests/gb/gprs_bssgp_test.c @@ -159,6 +159,22 @@ static void test_bssgp_status(void) printf("----- %s END\n", __func__); } +static void test_bssgp_bad_reset() +{ + struct msgb *msg = bssgp_msgb_alloc(); + uint16_t bvci_be = htons(2); + uint8_t cause = BSSGP_CAUSE_OML_INTERV; + + msgb_v_put(msg, BSSGP_PDUT_BVC_RESET); + msgb_tvlv_put(msg, BSSGP_IE_BVCI, sizeof(bvci_be), (uint8_t *)&bvci_be); + msgb_tvlv_put(msg, BSSGP_IE_CAUSE, sizeof(cause), &cause); + + msgb_bvci(msg) = 0xbad; + + msgb_bssgp_send_and_free(msg); +} + + static struct log_info info = {}; int main(int argc, char **argv) @@ -181,6 +197,7 @@ int main(int argc, char **argv) printf("===== BSSGP test START\n"); test_bssgp_suspend_resume(); test_bssgp_status(); + test_bssgp_bad_reset(); printf("===== BSSGP test END\n\n"); exit(EXIT_SUCCESS); -- 1.9.1 From mike.mcternan at wavemobile.com Tue Apr 7 16:10:11 2015 From: mike.mcternan at wavemobile.com (Mike McTernan (wavemobile)) Date: Tue, 7 Apr 2015 16:10:11 +0000 Subject: OsmoBTS - OsmocomBB emulation project In-Reply-To: References: Message-ID: Hi Dominiq, > I am trying to remove l1 on both sides and connect OsmoBTS with BB application via simple unix sockets. ... > Currently I am able to handle messages between BTS and TRX driver on clock and control ports ... > The thing is that I need to send to BB phone (layer23) messages in structures from gsm_04_08.h (i.e. gsm48_system_information_type_3). > I am not sure if I will be able to get needed from the messages coming on the data port 5702.? ? You are correct. The data port UDP messages carry burst data - that is data after convolutional encoding and interleaving as well as training sequence insertion, padding etc... You would have to very inefficiently decode all this again to retrieve the CSN data bits you seek, though you could then stimulate the timing advance and power control loops. >?I found, that PCU creates unix socket on ?/tmp/pcu_bts? , but only in case sysmoBTS is in use (please correct me if I am wrong), For non-sysmoBTS there is a different socket, TCP or UDP - I forget, but that's why you don't see the SEQ_PACKET Unix socket in /tmp for the other config. Check sysmo_sock.cpp vs openbts_sock.cpp. > So basically I need somehow to get this message structures on my custom l1 BB interface. > Do you have any idea how to do this ? ? I'm no expert, but depending on your ultimate goal you may have some luck pulling them out of the GSMTAP interface. You can view this using Wireshark to quickly see if it is enough. Check the docs or source on how to set this up and view it. Alternatively, using the trx branch, you could try implementing a custom l1. Check around the bts_model/l1sap code for the software interface (which is shared between the code in osmo-bts-sysmo and osmo-bts-trx). That's probably a fair bit of work but gives you a lot of flexibility. Kind Regards, Mike From holger at freyther.de Tue Apr 7 18:13:05 2015 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 7 Apr 2015 20:13:05 +0200 Subject: [PATCH 4/4] nitb: Fix IMSI/IMEI buffer handling (Coverity) In-Reply-To: <1428421790-3423-4-git-send-email-jerlbeck@sysmocom.de> References: <1428421790-3423-1-git-send-email-jerlbeck@sysmocom.de> <1428421790-3423-4-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20150407181305.GP1966@xiaoyu.lan> On Tue, Apr 07, 2015 at 05:49:50PM +0200, Jacob Erlbeck wrote: > This commit changes to code to not touch the last byte in the buffers > and to rely on the last byte being NUL. So the maximum IMSI/IMEI > length is GSM_IMSI_LENGTH-1/GSM_IMEI_LENGTH-1. For information: "rely" here means.. we assume that we allocate the structure with talloc_zero. This means we have NULed the entire imsi array and then only write sizeof - 1 characters to it. So the last byte remains NUL From jerlbeck at sysmocom.de Thu Apr 9 12:22:22 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 9 Apr 2015 14:22:22 +0200 Subject: [PATCH 2/2] gprs: Add assertion for msg != NULL to bssgp_msgb_alloc (Coverity) In-Reply-To: <1428582142-5416-1-git-send-email-jerlbeck@sysmocom.de> References: <1428582142-5416-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1428582142-5416-2-git-send-email-jerlbeck@sysmocom.de> Currently out-of-memory is not handled by bssgp_msgb_alloc, leading to SEGV failures if msgb_alloc_headroom returns NULL. This commit adds an OSMO_ASSERT to catch this case, which improves the situation only slightly. But bssgp_msgb_alloc is used in many places without checking the return value, so just adding a conditional early NULL return would not fix the issue either. Fixes: Coverity CID 1293377 Sponsored-by: On-Waves ehf --- src/gb/gprs_bssgp_util.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gb/gprs_bssgp_util.c b/src/gb/gprs_bssgp_util.c index fe66f46..3c42e4d 100644 --- a/src/gb/gprs_bssgp_util.c +++ b/src/gb/gprs_bssgp_util.c @@ -71,6 +71,10 @@ const char *bssgp_cause_str(enum gprs_bssgp_cause cause) struct msgb *bssgp_msgb_alloc(void) { struct msgb *msg = msgb_alloc_headroom(4096, 128, "BSSGP"); + + /* TODO: Add handling of msg == NULL to this function and to all callers */ + OSMO_ASSERT(msg != NULL); + msgb_bssgph(msg) = msg->data; return msg; } -- 1.9.1 From jerlbeck at sysmocom.de Thu Apr 9 12:22:21 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 9 Apr 2015 14:22:21 +0200 Subject: [PATCH 1/2] msgb: Check the return value of msgb_alloc (Coverity) Message-ID: <1428582142-5416-1-git-send-email-jerlbeck@sysmocom.de> In some places, the return value of msgb_alloc/msgb_alloc_headroom is not checked before it is dereferenced. This commit adds NULL checks to return with -ENOMEM from the calling functions if the alloc function has failed. Fixes: Coverity CID 1249692, 1293376 Sponsored-by: On-Waves ehf --- src/gsm/lapdm.c | 3 +++ src/sim/reader.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c index 698f850..54d3a0b 100644 --- a/src/gsm/lapdm.c +++ b/src/gsm/lapdm.c @@ -675,6 +675,9 @@ static int l2_ph_rach_ind(struct lapdm_entity *le, uint8_t ra, uint32_t fn, uint struct gsm_time gt; struct msgb *msg = msgb_alloc_headroom(512, 64, "RSL CHAN RQD"); + if (!msg) + return -ENOMEM; + msg->l2h = msgb_push(msg, sizeof(*ch)); ch = (struct abis_rsl_cchan_hdr *)msg->l2h; rsl_init_cchan_hdr(ch, RSL_MT_CHAN_RQD); diff --git a/src/sim/reader.c b/src/sim/reader.c index 160f175..e7169b5 100644 --- a/src/sim/reader.c +++ b/src/sim/reader.c @@ -58,6 +58,9 @@ static int transceive_apdu_t0(struct osim_card_hdl *st, struct msgb *amsg) uint16_t sw; int rc, num_resp = 0; + if (!tmsg) + return -ENOMEM; + /* create TPDU header from APDU header */ tpduh = (struct osim_apdu_cmd_hdr *) msgb_put(tmsg, sizeof(*tpduh)); memcpy(tpduh, msgb_apdu_h(amsg), sizeof(*tpduh)); -- 1.9.1 From jerlbeck at sysmocom.de Thu Apr 9 12:47:18 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 9 Apr 2015 14:47:18 +0200 Subject: [PATCH] nitb: Fix IMSI/IMEI buffer handling (Coverity) In-Reply-To: <20150407181305.GP1966@xiaoyu.lan> References: <20150407181305.GP1966@xiaoyu.lan> Message-ID: <1428583638-6126-1-git-send-email-jerlbeck@sysmocom.de> Currently the handling of the buffers is not done consistently. Some code assumes that the whole buffer may be used to store the string while at other places, the last buffer byte is left untouched in the assumption that it contains a terminating NUL-character. The latter is the correct behaviour. This commit changes to code to not touch the last byte in the buffers and to rely on the last byte being NUL. So the maximum IMSI/IMEI length is GSM_IMSI_LENGTH-1/GSM_IMEI_LENGTH-1. For information: We assume that we allocate the structure with talloc_zero. This means we have NULed the entire imsi array and then only write sizeof - 1 characters to it. So the last byte remains NUL. Fixes: Coverity CID 1206568, 1206567 Sponsored-by: On-Waves ehf --- openbsc/src/libcommon/gsm_subscriber_base.c | 3 +-- openbsc/src/libmsc/db.c | 4 ++-- openbsc/src/osmo-bsc_nat/bsc_ussd.c | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/openbsc/src/libcommon/gsm_subscriber_base.c b/openbsc/src/libcommon/gsm_subscriber_base.c index 3c56101..a455824 100644 --- a/openbsc/src/libcommon/gsm_subscriber_base.c +++ b/openbsc/src/libcommon/gsm_subscriber_base.c @@ -112,8 +112,7 @@ struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp, if (!subscr) return NULL; - strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH); - subscr->imsi[GSM_IMSI_LENGTH - 1] = '\0'; + strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH-1); subscr->group = sgrp; return subscr; } diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index bdecbb4..428f99b 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -565,7 +565,7 @@ static int get_equipment_by_subscr(struct gsm_subscriber *subscr) string = dbi_result_get_string(result, "imei"); if (string) - strncpy(equip->imei, string, sizeof(equip->imei)); + strncpy(equip->imei, string, sizeof(equip->imei)-1); string = dbi_result_get_string(result, "classmark1"); if (string) { @@ -802,7 +802,7 @@ static void db_set_from_query(struct gsm_subscriber *subscr, dbi_conn result) const char *string; string = dbi_result_get_string(result, "imsi"); if (string) - strncpy(subscr->imsi, string, GSM_IMSI_LENGTH); + strncpy(subscr->imsi, string, GSM_IMSI_LENGTH-1); string = dbi_result_get_string(result, "tmsi"); if (string) diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c index ac5a9f5..67844b8 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c +++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c @@ -399,7 +399,7 @@ int bsc_ussd_check(struct nat_sccp_connection *con, struct bsc_nat_parsed *parse if (parsed->bssap != BSSAP_MSG_DTAP) return 0; - if (strlen(con->imsi) > GSM_IMSI_LENGTH) + if (strlen(con->imsi) >= GSM_IMSI_LENGTH) return 0; hdr48 = bsc_unpack_dtap(parsed, msg, &len); -- 1.9.1 From holger at freyther.de Fri Apr 10 06:55:55 2015 From: holger at freyther.de (Holger Freyther) Date: Fri, 10 Apr 2015 08:55:55 +0200 Subject: [PATCH 3/4] sub: Remove introspection of the "channel queue" In-Reply-To: <1428648956-27615-1-git-send-email-holger@freyther.de> References: <1428648956-27615-1-git-send-email-holger@freyther.de> Message-ID: <1428648956-27615-3-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther Over the next commits the queuing of commits will be completely modified to remove the queue and move the scheduling/limits to the outer callers. --- openbsc/include/openbsc/gsm_subscriber.h | 5 -- openbsc/src/libmsc/gsm_subscriber.c | 45 ----------------- openbsc/src/libmsc/vty_interface_layer3.c | 81 ++----------------------------- 3 files changed, 4 insertions(+), 127 deletions(-) diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 290cc44..c5585ce 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -109,11 +109,6 @@ struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp, struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp, const char *imsi); -int subscr_pending_requests(struct gsm_subscriber *subscr); -int subscr_pending_clear(struct gsm_subscriber *subscr); -int subscr_pending_dump(struct gsm_subscriber *subscr, struct vty *vty); -int subscr_pending_kick(struct gsm_subscriber *subscr); - char *subscr_name(struct gsm_subscriber *subscr); int subscr_purge_inactive(struct gsm_subscriber_group *sgrp); diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c index c444fe0..9037e89 100644 --- a/openbsc/src/libmsc/gsm_subscriber.c +++ b/openbsc/src/libmsc/gsm_subscriber.c @@ -443,48 +443,3 @@ void subscr_expire(struct gsm_subscriber_group *sgrp) { db_subscriber_expire(sgrp->net, subscr_expire_callback); } - -int subscr_pending_requests(struct gsm_subscriber *sub) -{ - struct subscr_request *req; - int pending = 0; - - llist_for_each_entry(req, &sub->requests, entry) - pending += 1; - - return pending; -} - -int subscr_pending_clear(struct gsm_subscriber *sub) -{ - int deleted = 0; - struct subscr_request *req, *tmp; - - llist_for_each_entry_safe(req, tmp, &sub->requests, entry) { - subscr_put(req->subscr); - llist_del(&req->entry); - talloc_free(req); - deleted += 1; - } - - return deleted; -} - -int subscr_pending_dump(struct gsm_subscriber *sub, struct vty *vty) -{ - struct subscr_request *req; - - vty_out(vty, "Pending Requests for Subscriber %llu.%s", sub->id, VTY_NEWLINE); - llist_for_each_entry(req, &sub->requests, entry) { - vty_out(vty, "Channel type: %d State: %d Sub: %llu.%s", - req->channel_type, req->state, req->subscr->id, VTY_NEWLINE); - } - - return 0; -} - -int subscr_pending_kick(struct gsm_subscriber *sub) -{ - subscr_put_channel(sub); - return 0; -} diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 558db5e..04e65e7 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -55,7 +55,7 @@ extern struct gsm_network *gsmnet_from_vty(struct vty *v); -static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, int pending) +static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr) { int rc; struct gsm_auth_info ainfo; @@ -107,11 +107,6 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, "%a, %d %b %Y %T %z", localtime(&subscr->expire_lu)); expire_time[sizeof(expire_time) - 1] = '\0'; vty_out(vty, " Expiration Time: %s%s", expire_time, VTY_NEWLINE); - - if (pending) - vty_out(vty, " Pending: %d%s", - subscr_pending_requests(subscr), VTY_NEWLINE); - vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE); } @@ -127,7 +122,7 @@ DEFUN(show_subscr_cache, llist_for_each_entry(subscr, &active_subscribers, entry) { vty_out(vty, " Subscriber:%s", VTY_NEWLINE); - subscr_dump_full_vty(vty, subscr, 0); + subscr_dump_full_vty(vty, subscr); } return CMD_SUCCESS; @@ -215,7 +210,7 @@ DEFUN(show_subscr, return CMD_WARNING; } - subscr_dump_full_vty(vty, subscr, 1); + subscr_dump_full_vty(vty, subscr); subscr_put(subscr); @@ -241,7 +236,7 @@ DEFUN(subscriber_create, } /* Show info about the created subscriber. */ - subscr_dump_full_vty(vty, subscr, 0); + subscr_dump_full_vty(vty, subscr); subscr_put(subscr); @@ -596,71 +591,6 @@ DEFUN(ena_subscr_extension, return CMD_SUCCESS; } -DEFUN(ena_subscr_clear, - ena_subscr_clear_cmd, - "subscriber " SUBSCR_TYPES " ID clear-requests", - SUBSCR_HELP "Clear the paging requests for this subscriber\n") -{ - int del; - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct gsm_subscriber *subscr = - get_subscr_by_argv(gsmnet, argv[0], argv[1]); - - if (!subscr) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - del = subscr_pending_clear(subscr); - vty_out(vty, "Cleared %d pending requests.%s", del, VTY_NEWLINE); - subscr_put(subscr); - - return CMD_SUCCESS; -} - -DEFUN(ena_subscr_pend, - ena_subscr_pend_cmd, - "subscriber " SUBSCR_TYPES " ID show-pending", - SUBSCR_HELP "Clear the paging requests for this subscriber\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct gsm_subscriber *subscr = - get_subscr_by_argv(gsmnet, argv[0], argv[1]); - - if (!subscr) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - subscr_pending_dump(subscr, vty); - subscr_put(subscr); - - return CMD_SUCCESS; -} - -DEFUN(ena_subscr_kick, - ena_subscr_kick_cmd, - "subscriber " SUBSCR_TYPES " ID kick-pending", - SUBSCR_HELP "Clear the paging requests for this subscriber\n") -{ - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct gsm_subscriber *subscr = - get_subscr_by_argv(gsmnet, argv[0], argv[1]); - - if (!subscr) { - vty_out(vty, "%% No subscriber found for %s %s%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - subscr_pending_kick(subscr); - subscr_put(subscr); - - return CMD_SUCCESS; -} - DEFUN(ena_subscr_handover, ena_subscr_handover_cmd, "subscriber " SUBSCR_TYPES " ID handover BTS_NR", @@ -1139,9 +1069,6 @@ int bsc_vty_init_extra(void) install_element(ENABLE_NODE, &ena_subscr_extension_cmd); install_element(ENABLE_NODE, &ena_subscr_authorized_cmd); install_element(ENABLE_NODE, &ena_subscr_a3a8_cmd); - install_element(ENABLE_NODE, &ena_subscr_clear_cmd); - install_element(ENABLE_NODE, &ena_subscr_pend_cmd); - install_element(ENABLE_NODE, &ena_subscr_kick_cmd); install_element(ENABLE_NODE, &ena_subscr_handover_cmd); install_element(ENABLE_NODE, &subscriber_purge_cmd); install_element(ENABLE_NODE, &smsqueue_trigger_cmd); -- 2.1.4 From holger at freyther.de Fri Apr 10 06:55:53 2015 From: holger at freyther.de (Holger Freyther) Date: Fri, 10 Apr 2015 08:55:53 +0200 Subject: [PATCH 1/4] mncc: Select the codec similar to the modify handling Message-ID: <1428648956-27615-1-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther In case the default TCH/F codec is "EFR" and we do an early assignment from SDCCH to a TCH we would assign the TCH/H codec. This is because the lchan_type will be neither a TCH/H nor a TCH/F. At the same time the _gsm48_lchan_modify code to check for half vs. full-rate is the other way around. Align both. It is full-rate if it is not a TCH_H. This will have some other complications down the way (early assignment on cells with only TCH/H). So the mode should not depend on the _current_ channel but the kind of channel we want. --- openbsc/src/libmsc/mncc_builtin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/src/libmsc/mncc_builtin.c b/openbsc/src/libmsc/mncc_builtin.c index a5a463b..5c3461b 100644 --- a/openbsc/src/libmsc/mncc_builtin.c +++ b/openbsc/src/libmsc/mncc_builtin.c @@ -69,7 +69,7 @@ static uint8_t determine_lchan_mode(struct gsm_mncc *setup) { /* FIXME: check codec capabilities of the phone */ - if (setup->lchan_type == GSM_LCHAN_TCH_F) + if (setup->lchan_type != GSM_LCHAN_TCH_H) return mncc_int.def_codec[0]; else return mncc_int.def_codec[1]; -- 2.1.4 From holger at freyther.de Fri Apr 10 06:55:54 2015 From: holger at freyther.de (Holger Freyther) Date: Fri, 10 Apr 2015 08:55:54 +0200 Subject: [PATCH 2/4] sub: Remove paging requests before dispatching In-Reply-To: <1428648956-27615-1-git-send-email-holger@freyther.de> References: <1428648956-27615-1-git-send-email-holger@freyther.de> Message-ID: <1428648956-27615-2-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther The dispatching might lead to the removal of more paging requests and makes "request" invalid. Remove it before calling the callback. --- openbsc/src/libbsc/paging.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/openbsc/src/libbsc/paging.c b/openbsc/src/libbsc/paging.c index 2d08af7..8bc10e6 100644 --- a/openbsc/src/libbsc/paging.c +++ b/openbsc/src/libbsc/paging.c @@ -366,13 +366,19 @@ static void _paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *sub llist_for_each_entry_safe(req, req2, &bts_entry->pending_requests, entry) { if (req->subscr == subscr) { - if (conn && req->cbfn) { + gsm_cbfn *cbfn = req->cbfn; + void *param = req->cbfn_param; + + /* now give up the data structure */ + paging_remove_request(&bts->paging, req); + req = NULL; + + if (conn && cbfn) { LOGP(DPAG, LOGL_DEBUG, "Stop paging on bts %d, calling cbfn.\n", bts->nr); - req->cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_SUCCEEDED, - msg, conn, req->cbfn_param); + cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_SUCCEEDED, + msg, conn, param); } else LOGP(DPAG, LOGL_DEBUG, "Stop paging on bts %d silently.\n", bts->nr); - paging_remove_request(&bts->paging, req); break; } } -- 2.1.4 From holger at freyther.de Fri Apr 10 06:55:56 2015 From: holger at freyther.de (Holger Freyther) Date: Fri, 10 Apr 2015 08:55:56 +0200 Subject: [PATCH 4/4] sub: Remove the queue from the subscriber code In-Reply-To: <1428648956-27615-1-git-send-email-holger@freyther.de> References: <1428648956-27615-1-git-send-email-holger@freyther.de> Message-ID: <1428648956-27615-4-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther The idea of "subscriber_get_channel" was that different requests would be coordinated. At the same time we have seen that the "queue" can get stuck at both 31C3 and the rhizomatica installations. Voice calls and SMS do not need coordination. We should be able to send SMS on a voice channel and switch the MS from a SDCCH to a TCH in case we establish a voice call. The SMS code itself needs to coordinate to obey the limit of one SMS per direction but this should be enforced in the sms layer and not on the subscriber. Modify the code to have a simple paging coordination. The subscriber code will schedule the paging and register who would like to know about success/failure. This allowed to greatly simplify the paging response handling for the transaction code (and in fact we could move the transaction list into the subscriber structure now). The code gained to support to cancel the notification of a request (but not the paging itself yet). TODO: Cancel paging request in case no one cares about it anymore. --- openbsc/include/openbsc/gsm_data.h | 1 - openbsc/include/openbsc/gsm_subscriber.h | 14 ++- openbsc/include/openbsc/transaction.h | 2 +- openbsc/src/libmsc/gsm_04_08.c | 95 +++++++----------- openbsc/src/libmsc/gsm_04_11.c | 8 +- openbsc/src/libmsc/gsm_subscriber.c | 154 ++++++++---------------------- openbsc/src/libmsc/osmo_msc.c | 8 -- openbsc/src/libmsc/transaction.c | 7 +- openbsc/src/libmsc/vty_interface_layer3.c | 2 + openbsc/tests/channel/channel_test.c | 12 ++- 10 files changed, 102 insertions(+), 201 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 51d68d2..30a397c 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -119,7 +119,6 @@ struct gsm_subscriber_connection { /* Are we part of a special "silent" call */ int silent_call; - int put_channel; /* bsc structures */ struct osmo_bsc_sccp_con *sccp_con; diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index c5585ce..7d6c776 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -22,6 +22,8 @@ struct vty; struct sgsn_mm_ctx; struct sgsn_subscriber_data; +struct subscr_request; + struct gsm_subscriber_group { struct gsm_network *net; @@ -66,7 +68,7 @@ struct gsm_subscriber { struct llist_head entry; /* pending requests */ - int in_callback; + int is_paging; struct llist_head requests; /* GPRS/SGSN related fields */ @@ -101,9 +103,6 @@ struct gsm_subscriber *subscr_get_by_id(struct gsm_subscriber_group *sgrp, struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp, const char *imsi); int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason); -void subscr_put_channel(struct gsm_subscriber *subscr); -void subscr_get_channel(struct gsm_subscriber *subscr, - int type, gsm_cbfn *cbfn, void *param); struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp, uint32_t tmsi); struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp, @@ -116,6 +115,13 @@ void subscr_update_from_db(struct gsm_subscriber *subscr); void subscr_expire(struct gsm_subscriber_group *sgrp); int subscr_update_expire_lu(struct gsm_subscriber *subscr, struct gsm_bts *bts); +/* + * Paging handling with authentication + */ +struct subscr_request *subscr_request_channel(struct gsm_subscriber *subscr, + int type, gsm_cbfn *cbfn, void *param); +void subscr_remove_request(struct subscr_request *req); + /* internal */ struct gsm_subscriber *subscr_alloc(void); extern struct llist_head active_subscribers; diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h index 82891b8..6ef1612 100644 --- a/openbsc/include/openbsc/transaction.h +++ b/openbsc/include/openbsc/transaction.h @@ -36,7 +36,7 @@ struct gsm_trans { int tch_recv; /* is thats one paging? */ - struct gsm_network **paging_request; + struct subscr_request *paging_request; union { struct { diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 941090c..5609602 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1384,68 +1384,42 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg); /* call-back from paging the B-end of the connection */ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event, - struct msgb *msg, void *_conn, void *param) + struct msgb *msg, void *_conn, void *_transt) { - int found = 0; struct gsm_subscriber_connection *conn = _conn; - struct gsm_network **paging_request = param, *net; - struct gsm_trans *transt, *tmp; + struct gsm_trans *transt = _transt; - if (hooknum != GSM_HOOK_RR_PAGING) - return -EINVAL; - - net = *paging_request; - if (!net) { - DEBUGP(DCC, "Error Network not set!\n"); - return -EINVAL; - } + OSMO_ASSERT(!transt->conn); + OSMO_ASSERT(conn); /* check all tranactions (without lchan) for subscriber */ - llist_for_each_entry_safe(transt, tmp, &net->trans_list, entry) { - if (transt->paging_request != paging_request || transt->conn) - continue; - switch (event) { - case GSM_PAGING_SUCCEEDED: - if (!conn) // paranoid - break; - DEBUGP(DCC, "Paging subscr %s succeeded!\n", - transt->subscr->extension); - found = 1; - /* Assign lchan */ - if (!transt->conn) { - transt->paging_request = NULL; - transt->conn = conn; - conn->put_channel = 1; - } - /* send SETUP request to called party */ - gsm48_cc_tx_setup(transt, &transt->cc.msg); - break; - case GSM_PAGING_EXPIRED: - case GSM_PAGING_BUSY: - DEBUGP(DCC, "Paging subscr %s expired!\n", - transt->subscr->extension); - /* Temporarily out of order */ - found = 1; - mncc_release_ind(transt->net, transt, - transt->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_DEST_OOO); - transt->callref = 0; - transt->paging_request = NULL; - trans_free(transt); - break; - } + switch (event) { + case GSM_PAGING_SUCCEEDED: + DEBUGP(DCC, "Paging subscr %s succeeded!\n", transt->subscr->extension); + /* Assign lchan */ + transt->conn = conn; + /* send SETUP request to called party */ + gsm48_cc_tx_setup(transt, &transt->cc.msg); + break; + case GSM_PAGING_EXPIRED: + case GSM_PAGING_BUSY: + DEBUGP(DCC, "Paging subscr %s expired!\n", + transt->subscr->extension); + /* Temporarily out of order */ + mncc_release_ind(transt->net, transt, + transt->callref, + GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_DEST_OOO); + transt->callref = 0; + transt->paging_request = NULL; + trans_free(transt); + break; + default: + LOGP(DCC, LOGL_ERROR, "Unknown paging event %d\n", event); + break; } - talloc_free(paging_request); - - /* - * FIXME: The queue needs to be kicked. This is likely to go through a RF - * failure and then the subscr will be poke again. This needs a lot of fixing - * in the subscriber queue code. - */ - if (!found && conn) - conn->put_channel = 1; + transt->paging_request = NULL; return 0; } @@ -3124,19 +3098,16 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) /* store setup informations until paging was successfull */ memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc)); - /* Get a channel */ - trans->paging_request = talloc_zero(subscr->group->net, - struct gsm_network*); + /* Request a channel */ + trans->paging_request = subscr_request_channel(subscr, + RSL_CHANNEED_TCH_F, setup_trig_pag_evt, + trans); if (!trans->paging_request) { LOGP(DCC, LOGL_ERROR, "Failed to allocate paging token.\n"); subscr_put(subscr); trans_free(trans); return 0; } - - *trans->paging_request = subscr->group->net; - subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, setup_trig_pag_evt, trans->paging_request); - subscr_put(subscr); return 0; } diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index bcc25e4..1b2a42c 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -938,6 +938,7 @@ int gsm411_send_sms_subscr(struct gsm_subscriber *subscr, struct gsm_sms *sms) { struct gsm_subscriber_connection *conn; + void *res; /* check if we already have an open lchan to the subscriber. * if yes, send the SMS this way */ @@ -947,7 +948,12 @@ int gsm411_send_sms_subscr(struct gsm_subscriber *subscr, } /* if not, we have to start paging */ - subscr_get_channel(subscr, RSL_CHANNEED_SDCCH, paging_cb_send_sms, sms); + res = subscr_request_channel(subscr, RSL_CHANNEED_SDCCH, + paging_cb_send_sms, sms); + if (!res) { + send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, GSM_PAGING_BUSY); + sms_free(sms); + } return 0; } diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c index 9037e89..4559de5 100644 --- a/openbsc/src/libmsc/gsm_subscriber.c +++ b/openbsc/src/libmsc/gsm_subscriber.c @@ -56,28 +56,11 @@ int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq, struct subscr_request { struct llist_head entry; - /* back reference */ - struct gsm_subscriber *subscr; - - /* the requested channel type */ - int channel_type; - - /* what did we do */ - int state; - /* the callback data */ gsm_cbfn *cbfn; void *param; }; -enum { - REQ_STATE_INITIAL, - REQ_STATE_QUEUED, - REQ_STATE_PAGED, - REQ_STATE_FAILED_START, - REQ_STATE_DISPATCHED, -}; - static struct gsm_subscriber *get_subscriber(struct gsm_subscriber_group *sgrp, int type, const char *ident) { @@ -94,16 +77,14 @@ static struct gsm_subscriber *get_subscriber(struct gsm_subscriber_group *sgrp, static int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, struct msgb *msg, void *data, void *param) { - struct subscr_request *request; + struct subscr_request *request, *tmp; struct gsm_subscriber_connection *conn = data; struct gsm_subscriber *subscr = param; struct paging_signal_data sig_data; - /* There is no request anymore... */ - if (llist_empty(&subscr->requests)) - return -1; + OSMO_ASSERT(subscr->is_paging); - /* Dispatch signal */ + /* Inform parts of the system we don't know */ sig_data.subscr = subscr; sig_data.bts = conn ? conn->bts : NULL; sig_data.conn = conn; @@ -116,34 +97,22 @@ static int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, ); /* - * FIXME: What to do with paging requests coming during - * this callback? We must be sure to not start paging when - * we have an active connection to a subscriber and to make - * the subscr_put_channel work as required... + * Stop paging on all other BTS. E.g. if this is + * the first timeout on a BTS then the others will + * timeout soon as well. Let's just stop everything + * and forget we wanted to page. */ - request = (struct subscr_request *)subscr->requests.next; - request->state = REQ_STATE_DISPATCHED; - llist_del(&request->entry); - subscr->in_callback = 1; - request->cbfn(hooknum, event, msg, data, request->param); - subscr->in_callback = 0; + paging_request_stop(NULL, subscr, NULL, NULL); + subscr->is_paging = 0; - if (event != GSM_PAGING_SUCCEEDED) { - /* - * This is a workaround for a bigger issue. We have - * issued paging that might involve multiple BTSes - * and one of them have failed now. We will stop the - * other paging requests as well as the next timeout - * would work on the next paging request and the queue - * will do bad things. This should be fixed by counting - * the outstanding results. - */ - paging_request_stop(NULL, subscr, NULL, NULL); - subscr_put_channel(subscr); + llist_for_each_entry_safe(request, tmp, &subscr->requests, entry) { + llist_del(&request->entry); + request->cbfn(hooknum, event, msg, data, request->param); + talloc_free(request); } + /* balanced with the moment we start paging */ subscr_put(subscr); - talloc_free(request); return 0; } @@ -194,86 +163,43 @@ static int subscr_paging_cb(unsigned int hooknum, unsigned int event, return gsm48_secure_channel(conn, pr->key_seq, subscr_paging_sec_cb, param); } - -static void subscr_send_paging_request(struct gsm_subscriber *subscr) +struct subscr_request *subscr_request_channel(struct gsm_subscriber *subscr, + int channel_type, gsm_cbfn *cbfn, void *param) { - struct subscr_request *request; int rc; - struct gsm_network *net = subscr->group->net; - - assert(!llist_empty(&subscr->requests)); - - request = (struct subscr_request *)subscr->requests.next; - request->state = REQ_STATE_PAGED; - rc = paging_request(net, subscr, request->channel_type, - subscr_paging_cb, subscr); - - /* paging failed, quit now */ - if (rc <= 0) { - request->state = REQ_STATE_FAILED_START; - subscr_paging_cb(GSM_HOOK_RR_PAGING, GSM_PAGING_BUSY, - NULL, NULL, subscr); - } -} - -void subscr_get_channel(struct gsm_subscriber *subscr, - int type, gsm_cbfn *cbfn, void *param) -{ struct subscr_request *request; - request = talloc(tall_sub_req_ctx, struct subscr_request); - if (!request) { - if (cbfn) - cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_OOM, - NULL, NULL, param); - return; + /* Start paging.. we know it is async so we can do it before */ + if (!subscr->is_paging) { + LOGP(DMM, LOGL_DEBUG, "Subscriber %s not paged yet.\n", + subscr_name(subscr)); + rc = paging_request(subscr->group->net, subscr, channel_type, + subscr_paging_cb, subscr); + if (rc <= 0) { + LOGP(DMM, LOGL_ERROR, "Subscriber %s paging failed: %d\n", + subscr_name(subscr), rc); + return NULL; + } + /* reduced on the first paging callback */ + subscr_get(subscr); + subscr->is_paging = 1; } - memset(request, 0, sizeof(*request)); - request->subscr = subscr_get(subscr); - request->channel_type = type; + /* TODO: Stop paging in case of memory allocation failure */ + request = talloc_zero(subscr, struct subscr_request); + if (!request) + return NULL; + request->cbfn = cbfn; request->param = param; - request->state = REQ_STATE_INITIAL; - - /* - * FIXME: We might be able to assign more than one - * channel, e.g. voice and SMS submit at the same - * time. - */ - if (!subscr->in_callback && llist_empty(&subscr->requests)) { - /* add to the list, send a request */ - llist_add_tail(&request->entry, &subscr->requests); - subscr_send_paging_request(subscr); - } else { - /* this will be picked up later, from subscr_put_channel */ - llist_add_tail(&request->entry, &subscr->requests); - request->state = REQ_STATE_QUEUED; - } + llist_add_tail(&request->entry, &subscr->requests); + return request; } -void subscr_put_channel(struct gsm_subscriber *subscr) +void subscr_remove_request(struct subscr_request *request) { - /* - * FIXME: Continue with other requests now... by checking - * the gsm_subscriber inside the gsm_lchan. Drop the ref count - * of the lchan after having asked the next requestee to handle - * the channel. - */ - /* - * FIXME: is the lchan is of a different type we could still - * issue an immediate assignment for another channel and then - * close this one. - */ - /* - * Currently we will drop the last ref of the lchan which - * will result in a channel release on RSL and we will start - * the paging. This should work most of the time as the MS - * will listen to the paging requests before we timeout - */ - - if (subscr && !llist_empty(&subscr->requests)) - subscr_send_paging_request(subscr); + llist_del(&request->entry); + talloc_free(request); } struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp, diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c index f3badb7..b4facff 100644 --- a/openbsc/src/libmsc/osmo_msc.c +++ b/openbsc/src/libmsc/osmo_msc.c @@ -39,10 +39,6 @@ static void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci) static int msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause) { gsm0408_clear_request(conn, cause); - if (conn->put_channel) { - conn->put_channel = 0; - subscr_put_channel(conn->subscr); - } return 1; } @@ -173,9 +169,5 @@ void msc_release_connection(struct gsm_subscriber_connection *conn) conn->in_release = 1; gsm0808_clear(conn); - if (conn->put_channel) { - conn->put_channel = 0; - subscr_put_channel(conn->subscr); - } subscr_con_free(conn); } diff --git a/openbsc/src/libmsc/transaction.c b/openbsc/src/libmsc/transaction.c index 2101ae9..a750362 100644 --- a/openbsc/src/libmsc/transaction.c +++ b/openbsc/src/libmsc/transaction.c @@ -98,11 +98,8 @@ void trans_free(struct gsm_trans *trans) break; } - /* FIXME: implement a sane way to stop this. */ - if (!trans->conn && trans->paging_request) { - LOGP(DNM, LOGL_ERROR, - "Transaction freed while paging for sub: %llu\n", - trans->subscr->id); + if (trans->paging_request) { + subscr_remove_request(trans->paging_request); trans->paging_request = NULL; } diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 04e65e7..6cf51a3 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -107,6 +107,8 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr) "%a, %d %b %Y %T %z", localtime(&subscr->expire_lu)); expire_time[sizeof(expire_time) - 1] = '\0'; vty_out(vty, " Expiration Time: %s%s", expire_time, VTY_NEWLINE); + vty_out(vty, " Paging: %s paging%s", + subscr->is_paging ? "is" : "not", VTY_NEWLINE); vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE); } diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 2369339..cd6a1fd 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -31,6 +31,8 @@ static int s_end = 0; static struct gsm_subscriber_connection s_conn; +static void *s_data; +static gsm_cbfn *s_cbfn; /* our handler */ static int subscr_cb(unsigned int hook, unsigned int event, struct msgb *msg, void *data, void *param) @@ -48,7 +50,8 @@ static int subscr_cb(unsigned int hook, unsigned int event, struct msgb *msg, vo /* mock object for testing, directly invoke the cb... maybe later through the timer */ int paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscriber, int type, gsm_cbfn *cbfn, void *data) { - cbfn(101, 200, (void*)0x1323L, &s_conn, data); + s_data = data; + s_cbfn = cbfn; /* claim we have patched */ return 1; @@ -80,11 +83,10 @@ int main(int argc, char **argv) OSMO_ASSERT(subscr->group->net == network); /* Ask for a channel... */ - subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, subscr_cb, (void*)0x2342L); + subscr_request_channel(subscr, RSL_CHANNEED_TCH_F, subscr_cb, (void*)0x2342L); + s_cbfn(101, 200, (void*)0x1323L, &s_conn, s_data); - while (!s_end) { - osmo_select_main(0); - } + OSMO_ASSERT(s_end); return EXIT_SUCCESS; } -- 2.1.4 From mike.mcternan at wavemobile.com Fri Apr 10 17:42:32 2015 From: mike.mcternan at wavemobile.com (Mike McTernan (wavemobile)) Date: Fri, 10 Apr 2015 17:42:32 +0000 Subject: Why isn't ARFCN 0 supported? Message-ID: Good afternoon! In libbsc/bsc_init.c we have the following case: case GSM_BAND_900: if (bts->c0->arfcn < 1 || (bts->c0->arfcn > 124 && bts->c0->arfcn < 955) || bts->c0->arfcn > 1023) { LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n"); return -EINVAL; } break; 3GPP 45.005, table 2-2 gives valid channel numbers as: P-GSM900 -> 1-124, E-GSM900 -> 0-124 and 975-1023 R-GSM900 -> 0-124 and 955-1023 ER-GSM900 -> 0-124 and 940-1023 The code looks to bounds check ARFCN closest to R-GSM900, but omits ARFCN 0. Is the check "bts->c0->arfcn < 1" erroneous, or am I missing some history? Also should it really check for the R-GSM 900 range, or should it be E-GSM (more common)? The other band checks look correct. Kind Regards, Mike PS: osmo-arfcn is okay with ARFCN 0: $ ./osmo-arfcn -a 0 ARFCN 0: Uplink 890.0 MHz / Downlink 935.0 MHz From pablo at gnumonks.org Sat Apr 11 12:43:25 2015 From: pablo at gnumonks.org (Pablo Neira Ayuso) Date: Sat, 11 Apr 2015 14:43:25 +0200 Subject: libosmo-abis/RSL queue and OS interaction In-Reply-To: <20150405134616.GD31452@nataraja> References: <20150404070520.GA10127@xiaoyu.lan> <20150405134616.GD31452@nataraja> Message-ID: <20150411124325.GA3302@salvia> Hi! On Sun, Apr 05, 2015 at 03:46:16PM +0200, Harald Welte wrote: > Hi Holger, Pablo, Ciaby, > > On Sat, Apr 04, 2015 at 09:05:20AM +0200, Holger Hans Peter Freyther wrote: > > * Linux/TCP will run nagle to combine these messages > > we could easily disable nagle if that's what we want to avoid > latencies [see below] > > > I wonder if there is a better way? For reading we could read > > until -EWOULDBLOCK but then this might not be too fair for > > the other parts of the software. > > In terms of msgb reading, I think a fixed upper limit might make sense, > i.e. read up to [configurable] N messages in one BSC_FD_READ callback. I think the same, batching seems like the way to go to me. [...] > > Is there a TCP mode where a "write" either fully succeeds or fails > > with -ENOSPC or such? > > Not to my knowledge. The proper answer would probably to use DCCP or > SCTP or any other protocol that can provide reliable delivery of packets > (possibly with ordering guarantees) and not abuse a stream protocol > like TCP. This would of course break IPA compatibility... but it might > be an interesting experiment to compare different L4 protocol > performance against TCP for the given use case. Looking at the current state of art of the Linux stack, TCP is very well tuned and there are more people looking into it than those other protocols. From chester.mino at gmail.com Sat Apr 11 15:20:41 2015 From: chester.mino at gmail.com (Dominiq T) Date: Sat, 11 Apr 2015 17:20:41 +0200 Subject: OsmoBTS - OsmocomBB emulation project In-Reply-To: References: Message-ID: Hi Mike, Thanks for your advice. > For non-sysmoBTS there is a different socket, TCP or UDP - I forget, but that's why you don't see the SEQ_PACKET Unix socket in /tmp for the other config. Check sysmo_sock.cpp vs openbts_sock.cpp. - for the openbts, i found UDP channel on 5944 <--->5934 ports. But in case of the osmo-bts-trx i did not found anything. Even with openBTS i could see some "activity" of the PCU . I.e. while i started my app with OpenBTS, i could see at least: <0001> pcu_l1_if.cpp:330 BTS available <0001> pcu_l1_if.cpp:80 Sending activate request: trx=0 ts=6 <0001> pcu_l1_if.cpp:456 PDCH: trx=0 ts=6 <0001> pcu_l1_if.cpp:80 Sending activate request: trx=0 ts=7 <0001> pcu_l1_if.cpp:456 PDCH: trx=0 ts=7 but with trx no activity at all. I am doing something wrong ? Do I have change config somehow ? >I'm no expert, but depending on your ultimate goal you may have some luck pulling them out of the GSMTAP interface. You can view this using Wireshark to quickly see if it is enough. Check the docs or source on how >to set this up and view it. >Alternatively, using the trx branch, you could try implementing a custom l1. Check around the bts_model/l1sap code for the software interface (which is shared between the code in osmo-bts-sysmo and osmo-bts-trx). >That's probably a fair bit of work but gives you a lot of flexibility. - I think i can do it like this: As a "transmit" interface BTS -> osmocomBB i want to use GSMTAP feature. I thing there is suffient support of this protocol for my needs. The biggest issue i can see is, how to handle receive messages GSMTAP messages on my eBTS. I have idea to transform these messages into l1sap readable format, and send them to l1sap_up() function (which, if I am not mistaken , is a single point for trasnfer primitives from the TRX - please correct me). I have currently no idea what willl happen, and if its even possible to "jump over" the lower parts of the code... Thanks. Dominik 2015-04-07 18:10 GMT+02:00 Mike McTernan (wavemobile) < mike.mcternan at wavemobile.com>: > Hi Dominiq, > > > I am trying to remove l1 on both sides and connect OsmoBTS with BB > application via simple unix sockets. > ... > > Currently I am able to handle messages between BTS and TRX driver on > clock and control ports > ... > > The thing is that I need to send to BB phone (layer23) messages in > structures from gsm_04_08.h (i.e. gsm48_system_information_type_3). > > > I am not sure if I will be able to get needed from the messages coming > on the data port 5702. > > You are correct. The data port UDP messages carry burst data - that is > data after convolutional encoding and interleaving as well as training > sequence insertion, padding etc... You would have to very inefficiently > decode all this again to retrieve the CSN data bits you seek, though you > could then stimulate the timing advance and power control loops. > > > I found, that PCU creates unix socket on ?/tmp/pcu_bts? , but only in > case sysmoBTS is in use (please correct me if I am wrong), > > For non-sysmoBTS there is a different socket, TCP or UDP - I forget, but > that's why you don't see the SEQ_PACKET Unix socket in /tmp for the other > config. Check sysmo_sock.cpp vs openbts_sock.cpp. > > > So basically I need somehow to get this message structures on my custom > l1 BB interface. > > Do you have any idea how to do this ? > > I'm no expert, but depending on your ultimate goal you may have some luck > pulling them out of the GSMTAP interface. You can view this using > Wireshark to quickly see if it is enough. Check the docs or source on how > to set this up and view it. > > Alternatively, using the trx branch, you could try implementing a custom > l1. Check around the bts_model/l1sap code for the software interface > (which is shared between the code in osmo-bts-sysmo and osmo-bts-trx). > That's probably a fair bit of work but gives you a lot of flexibility. > > Kind Regards, > > Mike > -------------- next part -------------- An HTML attachment was scrubbed... URL: From holger at freyther.de Thu Apr 23 21:40:38 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 23 Apr 2015 17:40:38 -0400 Subject: [PATCH 3/9] gsup: Extract the new MSISDN string In-Reply-To: <1429825244-61253-1-git-send-email-holger@freyther.de> References: <1429825244-61253-1-git-send-email-holger@freyther.de> Message-ID: <1429825244-61253-3-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther --- openbsc/include/openbsc/gprs_gsup_messages.h | 4 ++++ openbsc/src/gprs/gprs_gsup_messages.c | 10 ++++++++++ openbsc/tests/gprs/gprs_test.c | 2 ++ 3 files changed, 16 insertions(+) diff --git a/openbsc/include/openbsc/gprs_gsup_messages.h b/openbsc/include/openbsc/gprs_gsup_messages.h index 9857b97..937733f 100644 --- a/openbsc/include/openbsc/gprs_gsup_messages.h +++ b/openbsc/include/openbsc/gprs_gsup_messages.h @@ -29,6 +29,7 @@ #define GPRS_GSUP_MAX_NUM_PDP_INFO 10 /* GSM 09.02 limits this to 50 */ #define GPRS_GSUP_MAX_NUM_AUTH_INFO 5 +#define GPRS_GSUP_MAX_MSISDN_LEN 9 #define GPRS_GSUP_PDP_TYPE_SIZE 2 @@ -43,6 +44,7 @@ enum gprs_gsup_iei { GPRS_GSUP_PDP_CONTEXT_ID_IE = 0x10, GPRS_GSUP_PDP_TYPE_IE = 0x11, GPRS_GSUP_ACCESS_POINT_NAME_IE = 0x12, + GPRS_GSUP_MSISDN_IE = 0x13, GPRS_GSUP_RAND_IE = 0x20, GPRS_GSUP_SRES_IE = 0x21, GPRS_GSUP_KC_IE = 0x22 @@ -102,6 +104,8 @@ struct gprs_gsup_message { size_t num_auth_tuples; struct gprs_gsup_pdp_info pdp_infos[GPRS_GSUP_MAX_NUM_PDP_INFO]; size_t num_pdp_infos; + const uint8_t *msisdn_enc; + size_t msisdn_enc_len; }; int gprs_gsup_decode(const uint8_t *data, size_t data_len, diff --git a/openbsc/src/gprs/gprs_gsup_messages.c b/openbsc/src/gprs/gprs_gsup_messages.c index 9d9b6be..be8e823 100644 --- a/openbsc/src/gprs/gprs_gsup_messages.c +++ b/openbsc/src/gprs/gprs_gsup_messages.c @@ -2,6 +2,7 @@ /* * (C) 2014 by Sysmocom s.f.m.c. GmbH + * (C) 2015 by Holger Hans Peter Freyther * All Rights Reserved * * Author: Jacob Erlbeck @@ -291,6 +292,10 @@ int gprs_gsup_decode(const uint8_t *const_data, size_t data_len, gsup_msg->auth_tuples[gsup_msg->num_auth_tuples++] = auth_info; break; + case GPRS_GSUP_MSISDN_IE: + gsup_msg->msisdn_enc = value; + gsup_msg->msisdn_enc_len = value_len; + break; default: LOGP(DGPRS, LOGL_NOTICE, "GSUP IE type %d unknown\n", iei); @@ -415,4 +420,9 @@ void gprs_gsup_encode(struct msgb *msg, const struct gprs_gsup_message *gsup_msg encode_auth_info(msg, GPRS_GSUP_AUTH_TUPLE_IE, auth_info); } + + if (gsup_msg->msisdn_enc) + msgb_tlv_put(msg, GPRS_GSUP_MSISDN_IE, + gsup_msg->msisdn_enc_len, gsup_msg->msisdn_enc); + } diff --git a/openbsc/tests/gprs/gprs_test.c b/openbsc/tests/gprs/gprs_test.c index 0ae06e7..555d657 100644 --- a/openbsc/tests/gprs/gprs_test.c +++ b/openbsc/tests/gprs/gprs_test.c @@ -452,6 +452,8 @@ static void test_gsup_messages_dec_enc(void) 0x10, 0x01, 0x02, 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n', + 0x13, 0x07, /* MSISDN of the subscriber */ + 0x91, 0x94, 0x61, 0x46, 0x32, 0x24, 0x43, }; static const uint8_t location_cancellation_req[] = { -- 2.3.5 From holger at freyther.de Thu Apr 23 21:40:41 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 23 Apr 2015 17:40:41 -0400 Subject: [PATCH 6/9] sgsn: Store subscribed QoS and attempt to use it In-Reply-To: <1429825244-61253-1-git-send-email-holger@freyther.de> References: <1429825244-61253-1-git-send-email-holger@freyther.de> Message-ID: <1429825244-61253-6-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther * Fix QoS encoding as it forgot the Allocation/Retention policy * Use the qos_req as it is the only one encoded for GTPv1 and as 7.7.34 --- openbsc/include/openbsc/gprs_sgsn.h | 2 ++ openbsc/include/openbsc/gsm_04_08_gprs.h | 1 + openbsc/src/gprs/gprs_sgsn.c | 15 +++++++++++++++ openbsc/src/gprs/gprs_subscriber.c | 9 +++++++++ openbsc/src/gprs/sgsn_libgtp.c | 18 ++++++++++++++---- 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index baa2d78..7a429cd 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -294,6 +294,8 @@ struct sgsn_subscriber_pdp_data { unsigned int context_id; uint16_t pdp_type; char apn_str[GSM_APN_LENGTH]; + uint8_t qos_subscribed[20]; + size_t qos_subscribed_len; }; struct sgsn_subscriber_data { diff --git a/openbsc/include/openbsc/gsm_04_08_gprs.h b/openbsc/include/openbsc/gsm_04_08_gprs.h index 3eec983..f35d11b 100644 --- a/openbsc/include/openbsc/gsm_04_08_gprs.h +++ b/openbsc/include/openbsc/gsm_04_08_gprs.h @@ -100,6 +100,7 @@ enum gsm48_gprs_ie_sm { * but which we use to simplify internal APIs */ OSMO_IE_GSM_REQ_QOS = 0xfd, OSMO_IE_GSM_REQ_PDP_ADDR = 0xfe, + OSMO_IE_GSM_SUB_QOS = 0xff, }; /* Chapter 9.4.15 / Table 9.4.15 */ diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 94c2b6f..711540e 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -582,6 +582,17 @@ void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx) sgsn_auth_update(mmctx); } +static void insert_qos(struct tlv_parsed *tp, struct sgsn_subscriber_pdp_data *pdp) +{ + tp->lv[OSMO_IE_GSM_SUB_QOS].len = pdp->qos_subscribed_len; + tp->lv[OSMO_IE_GSM_SUB_QOS].val = pdp->qos_subscribed; +} + +/** + * The tlv_parsed tp parameter will be modified to insert a + * OSMO_IE_GSM_SUB_QOS in case the data is available in the + * PDP context handling. + */ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, struct tlv_parsed *tp, enum gsm48_gsm_cause *gsm_cause) @@ -621,6 +632,7 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, { allow_any_apn = 1; selected_apn_str = ""; + insert_qos(tp, pdp); continue; } if (!llist_empty(&sgsn_apn_ctxts)) { @@ -629,6 +641,7 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, if (apn_ctx == NULL) continue; } + insert_qos(tp, pdp); selected_apn_str = pdp->apn_str; break; } @@ -636,11 +649,13 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx, /* Check whether the given APN is granted */ llist_for_each_entry(pdp, &mmctx->subscr->sgsn_data->pdp_list, list) { if (strcmp(pdp->apn_str, "*") == 0) { + insert_qos(tp, pdp); selected_apn_str = req_apn_str; allow_any_apn = 1; continue; } if (strcasecmp(pdp->apn_str, req_apn_str) == 0) { + insert_qos(tp, pdp); selected_apn_str = req_apn_str; break; } diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 52e7ba7..c2a3ae1 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -295,6 +295,13 @@ static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, continue; } + if (pdp_info->qos_enc_len > sizeof(pdp_data->qos_subscribed)) { + LOGGSUBSCRP(LOGL_ERROR, subscr, + "QoS info too long (%zu)\n", + pdp_info->qos_enc_len); + continue; + } + LOGGSUBSCRP(LOGL_INFO, subscr, "Will set PDP info, context id = %zu, APN = %s\n", ctx_id, osmo_hexdump(pdp_info->apn_enc, pdp_info->apn_enc_len)); @@ -310,6 +317,8 @@ static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, pdp_data->pdp_type = pdp_info->pdp_type; gprs_apn_to_str(pdp_data->apn_str, pdp_info->apn_enc, pdp_info->apn_enc_len); + memcpy(pdp_data->qos_subscribed, pdp_info->qos_enc, pdp_info->qos_enc_len); + pdp_data->qos_subscribed_len = pdp_info->qos_enc_len; } } diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 25b30d0..dd02457 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -123,6 +123,8 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, struct sgsn_pdp_ctx *pctx; struct pdp_t *pdp; uint64_t imsi_ui64; + size_t qos_len; + const uint8_t *qos; int rc; LOGP(DGPRS, LOGL_ERROR, "Create PDP Context\n"); @@ -188,12 +190,20 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, memcpy(pdp->pco_req.v, TLVP_VAL(tp, GSM48_IE_GSM_PROTO_CONF_OPT), pdp->pco_req.l); - /* QoS options from GMM */ - pdp->qos_req.l = TLVP_LEN(tp, OSMO_IE_GSM_REQ_QOS); + /* QoS options from GMM or remote */ + if (TLVP_LEN(tp, OSMO_IE_GSM_SUB_QOS) > 0) { + qos_len = TLVP_LEN(tp, OSMO_IE_GSM_SUB_QOS); + qos = TLVP_VAL(tp, OSMO_IE_GSM_SUB_QOS); + } else { + qos_len = TLVP_LEN(tp, OSMO_IE_GSM_REQ_QOS); + qos = TLVP_VAL(tp, OSMO_IE_GSM_REQ_QOS); + } + + pdp->qos_req.l = qos_len + 1; if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) pdp->qos_req.l = sizeof(pdp->qos_req.v); - memcpy(pdp->qos_req.v, TLVP_VAL(tp, OSMO_IE_GSM_REQ_QOS), - pdp->qos_req.l); + pdp->qos_req.v[0] = 0; /* Allocation/Retention policy */ + memcpy(&pdp->qos_req.v[1], qos, pdp->qos_req.l - 1); /* SGSN address for control plane */ pdp->gsnlc.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr); -- 2.3.5 From holger at freyther.de Thu Apr 23 21:40:40 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 23 Apr 2015 17:40:40 -0400 Subject: [PATCH 5/9] sgsn: Copy the msisdn to the sgsn_data and use it in PDP activation In-Reply-To: <1429825244-61253-1-git-send-email-holger@freyther.de> References: <1429825244-61253-1-git-send-email-holger@freyther.de> Message-ID: <1429825244-61253-5-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther The MSISDN should be present for "security" reasons in the first activation of a PDP context. Take the encoded MSISDN, store it for future use and then put it into the PDP activation request. --- openbsc/include/openbsc/gprs_sgsn.h | 3 +++ openbsc/src/gprs/gprs_subscriber.c | 14 ++++++++++++++ openbsc/src/gprs/sgsn_libgtp.c | 12 ++++++++++-- openbsc/tests/sgsn/sgsn_test.c | 9 +++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 2572ead..baa2d78 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -302,6 +302,9 @@ struct sgsn_subscriber_data { int auth_triplets_updated; struct llist_head pdp_list; int error_cause; + + uint8_t msisdn[9]; + size_t msisdn_len; }; #define SGSN_ERROR_CAUSE_NONE (-1) diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 60f223a..52e7ba7 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -1,6 +1,7 @@ /* MS subscriber data handling */ /* (C) 2014 by sysmocom s.f.m.c. GmbH + * (C) 2015 by Holger Hans Peter Freyther * * All Rights Reserved * @@ -259,9 +260,22 @@ static struct sgsn_subscriber_pdp_data *gprs_subscr_pdp_data_get_by_id( static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, struct gprs_gsup_message *gsup_msg) { + struct sgsn_subscriber_data *sdata = subscr->sgsn_data; unsigned idx; int rc; + if (gsup_msg->msisdn_enc) { + if (gsup_msg->msisdn_enc_len > sizeof(sdata->msisdn)) { + LOGP(DGPRS, LOGL_ERROR, "MSISDN too long (%zu)\n", + gsup_msg->msisdn_enc_len); + sdata->msisdn_len = 0; + } else { + memcpy(sdata->msisdn, gsup_msg->msisdn_enc, + gsup_msg->msisdn_enc_len); + sdata->msisdn_len = gsup_msg->msisdn_enc_len; + } + } + if (gsup_msg->pdp_info_compl) { rc = gprs_subscr_pdp_data_clear(subscr); if (rc > 0) diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 455e8af..25b30d0 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -3,6 +3,7 @@ /* (C) 2010 by Harald Welte * (C) 2010 by On-Waves + * (C) 2015 by Holger Hans Peter Freyther * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -45,6 +46,7 @@ #include #include #include +#include #include #include @@ -153,8 +155,14 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, /* IMSI, TEID/TEIC, FLLU/FLLC, TID, NSAPI set in pdp_newpdp */ - /* FIXME: MSISDN in BCD format from mmctx */ - //pdp->msisdn.l/.v + /* Put the MSISDN in case we have it */ + if (mmctx->subscr) { + pdp->msisdn.l = mmctx->subscr->sgsn_data->msisdn_len; + if (pdp->msisdn.l > sizeof(pdp->msisdn.v)) + pdp->msisdn.l = sizeof(pdp->msisdn.l); + memcpy(pdp->msisdn.v, mmctx->subscr->sgsn_data->msisdn, + pdp->msisdn.l); + } /* End User Address from GMM requested PDP address */ pdp->eua.l = TLVP_LEN(tp, OSMO_IE_GSM_REQ_PDP_ADDR); diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 197be9d..f6f8cd6 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -414,6 +414,10 @@ static void test_subscriber_gsup(void) 0x02, 0x01, 0x07 /* GPRS not allowed */ }; +#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 + + static const uint8_t s1_msisdn[] = { MSISDN }; + static const uint8_t update_location_res[] = { 0x06, TEST_GSUP_IMSI1_IE, @@ -426,8 +430,11 @@ static void test_subscriber_gsup(void) 0x10, 0x01, 0x02, 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n', + 0x13, 0x09, MSISDN, }; +#undef MSISDN + static const uint8_t update_location_err[] = { 0x05, TEST_GSUP_IMSI1_IE, @@ -534,6 +541,8 @@ static void test_subscriber_gsup(void) OSMO_ASSERT(last_updated_subscr == s1); OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE); OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE); + OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn)); + OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0); OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list)); pdpd = llist_entry(s1->sgsn_data->pdp_list.next, struct sgsn_subscriber_pdp_data, list); -- 2.3.5 From holger at freyther.de Thu Apr 23 21:40:36 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 23 Apr 2015 17:40:36 -0400 Subject: [PATCH 1/9] gsup: Document passing MSISDN as part of the response Message-ID: <1429825244-61253-1-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther --- openbsc/doc/sgsn-remote-protocol.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/openbsc/doc/sgsn-remote-protocol.txt b/openbsc/doc/sgsn-remote-protocol.txt index 3369d19..88a384e 100644 --- a/openbsc/doc/sgsn-remote-protocol.txt +++ b/openbsc/doc/sgsn-remote-protocol.txt @@ -121,6 +121,7 @@ Network peer -> SGSN 01 IMSI 4.2.9 M TLV 2-10 04 PDP info complete 4.2.8 O TLV 2 05 PDP info 4.2.3 1-10 TLV + 13 MSISDN 4.2.10 O TLV 0-9 If the PDP info complete IE is present, the old PDP info list shall be cleared. @@ -357,6 +358,7 @@ IEI that shall be used for the encoding. | 0x10 PDP context id big endian int | | 0x11 PDP type 4.2.4 | | 0x12 APN 04.08, 10.5.6.1 | + | 0x13 MSISDN ISDN-AddressString/octet | | 0x20 RAND octet string | | 0x21 SRES octet string | | 0x22 Kc octet string | @@ -397,3 +399,24 @@ The IMSI is encoded like in octet 4-N of the Called Party BCD Number defined in Note 1) Either '1 1 1 1 | Number digit N' (N odd) or 'Number digit N | Number digit N-1' (N even), where N is the number of digits. + +4.2.10. ISDN-AddressString / MSISDN /Called Party BCD Number + + +MSISDN. ISDN-AddressString in GSM 09.02 and Called Party +BCD Number in GSM 04.08. + + 8 7 6 5 4 3 2 1 + +-----------------------------------------------------+ + | | IEI | octet 1 + +-----------------------------------------------------+ + | Length of IE contents | octet 2 + +-----------------------------------------------------+ + | ext | Type of num | Numbering plan | octet 2 + +-----------------------------------------------------+ + | Number digit 2 | Number digit 1 | octet 3 + +-----------------------------------------------------+ + | Number digit 4 | Number digit 3 | octet 4 + +-----------------------------------------------------+ + : : : + +-----------------------------------------------------+ -- 2.3.5 From holger at freyther.de Thu Apr 23 21:40:44 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 23 Apr 2015 17:40:44 -0400 Subject: [PATCH 9/9] sgsn: Show the QoS that has been assigned In-Reply-To: <1429825244-61253-1-git-send-email-holger@freyther.de> References: <1429825244-61253-1-git-send-email-holger@freyther.de> Message-ID: <1429825244-61253-9-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther --- openbsc/src/gprs/sgsn_vty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 7ea8890..be575d3 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -500,8 +500,9 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, } llist_for_each_entry(pdp, &subscr->sgsn_data->pdp_list, list) { - vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s'%s", + vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s' QoS: %s%s", pdp->context_id, pdp->pdp_type, pdp->apn_str, + osmo_hexdump(pdp->qos_subscribed, pdp->qos_subscribed_len), VTY_NEWLINE); } -- 2.3.5 From holger at freyther.de Thu Apr 23 21:40:42 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 23 Apr 2015 17:40:42 -0400 Subject: [PATCH 7/9] sgsn: Handle different levels of QoS In-Reply-To: <1429825244-61253-1-git-send-email-holger@freyther.de> References: <1429825244-61253-1-git-send-email-holger@freyther.de> Message-ID: <1429825244-61253-7-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther If QoS is only three bytes it does not include the allocation/ retention policy. Otherwise it does. Copy it depending on that. We should have a macro for the clamping to reduce code duplication. The insanity does come from the MAP data and this seems to be the easiest in terms of complexity. It is an array of bytes that is transported from MAPProxy to the SGSN and then simply forwarded. --- openbsc/src/gprs/sgsn_libgtp.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index dd02457..5c0a0fd 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -199,11 +199,18 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, qos = TLVP_VAL(tp, OSMO_IE_GSM_REQ_QOS); } - pdp->qos_req.l = qos_len + 1; - if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) - pdp->qos_req.l = sizeof(pdp->qos_req.v); - pdp->qos_req.v[0] = 0; /* Allocation/Retention policy */ - memcpy(&pdp->qos_req.v[1], qos, pdp->qos_req.l - 1); + if (qos_len <= 3) { + pdp->qos_req.l = qos_len + 1; + if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) + pdp->qos_req.l = sizeof(pdp->qos_req.v); + pdp->qos_req.v[0] = 0; /* Allocation/Retention policy */ + memcpy(&pdp->qos_req.v[1], qos, pdp->qos_req.l - 1); + } else { + pdp->qos_req.l = qos_len; + if (pdp->qos_req.l > sizeof(pdp->qos_req.v)) + pdp->qos_req.l = sizeof(pdp->qos_req.v); + memcpy(&pdp->qos_req, qos, pdp->qos_req.l); + } /* SGSN address for control plane */ pdp->gsnlc.l = sizeof(sgsn->cfg.gtp_listenaddr.sin_addr); -- 2.3.5 From holger at freyther.de Thu Apr 23 21:40:43 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 23 Apr 2015 17:40:43 -0400 Subject: [PATCH 8/9] sgsn: Dump the E164 (encoded) assigned to the subscriber In-Reply-To: <1429825244-61253-1-git-send-email-holger@freyther.de> References: <1429825244-61253-1-git-send-email-holger@freyther.de> Message-ID: <1429825244-61253-8-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther --- openbsc/src/gprs/sgsn_vty.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 684204a..7ea8890 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -471,6 +471,11 @@ static void subscr_dump_full_vty(struct vty *vty, struct gsm_subscriber *subscr, if (subscr->tmsi != GSM_RESERVED_TMSI) vty_out(vty, " TMSI: %08X%s", subscr->tmsi, VTY_NEWLINE); + if (subscr->sgsn_data->msisdn_len > 0) + vty_out(vty, " MSISDN (BCD): %s%s", + osmo_hexdump(subscr->sgsn_data->msisdn, + subscr->sgsn_data->msisdn_len), + VTY_NEWLINE); if (strlen(subscr->equipment.imei) > 0) vty_out(vty, " IMEI: %s%s", subscr->equipment.imei, VTY_NEWLINE); -- 2.3.5 From holger at freyther.de Thu Apr 23 21:40:37 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 23 Apr 2015 17:40:37 -0400 Subject: [PATCH 2/9] gsup: Specify the QoS service for the PDP info In-Reply-To: <1429825244-61253-1-git-send-email-holger@freyther.de> References: <1429825244-61253-1-git-send-email-holger@freyther.de> Message-ID: <1429825244-61253-2-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther --- openbsc/doc/sgsn-remote-protocol.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/openbsc/doc/sgsn-remote-protocol.txt b/openbsc/doc/sgsn-remote-protocol.txt index 88a384e..6a93169 100644 --- a/openbsc/doc/sgsn-remote-protocol.txt +++ b/openbsc/doc/sgsn-remote-protocol.txt @@ -280,6 +280,7 @@ This is a container for information elements describing a single PDP. 10 PDP context id big endian int, 1-N C TLV 3 11 PDP type 4.2.4 C TLV 4 12 Access point name 04.08, 10.5.6.1 C TLV 3-102 + 14 Quality Of Service ?? O TLV 1-20 The conditional IE are mandantory unless mentioned otherwise. @@ -359,6 +360,7 @@ IEI that shall be used for the encoding. | 0x11 PDP type 4.2.4 | | 0x12 APN 04.08, 10.5.6.1 | | 0x13 MSISDN ISDN-AddressString/octet | + | 0x14 QoS octet string | | 0x20 RAND octet string | | 0x21 SRES octet string | | 0x22 Kc octet string | @@ -420,3 +422,19 @@ BCD Number in GSM 04.08. +-----------------------------------------------------+ : : : +-----------------------------------------------------+ + + +4.2.11 Quality of Service Subscribed Service + +QoS for the PDP context to be used by the SGSN/GGSN +communication. + + + 8 7 6 5 4 3 2 1 + +-----------------------------------------------------+ + | | IEI | octet 1 + +-----------------------------------------------------+ + | Length of IE contents | octet 2 + +-----------------------------------------------------+ + : : : + +-----------------------------------------------------+ -- 2.3.5 From holger at freyther.de Thu Apr 23 21:40:39 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 23 Apr 2015 17:40:39 -0400 Subject: [PATCH 4/9] gsup: Extract the QoS field In-Reply-To: <1429825244-61253-1-git-send-email-holger@freyther.de> References: <1429825244-61253-1-git-send-email-holger@freyther.de> Message-ID: <1429825244-61253-4-git-send-email-holger@freyther.de> From: Holger Hans Peter Freyther --- openbsc/include/openbsc/gprs_gsup_messages.h | 3 +++ openbsc/src/gprs/gprs_gsup_messages.c | 10 ++++++++++ openbsc/tests/gprs/gprs_test.c | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/openbsc/include/openbsc/gprs_gsup_messages.h b/openbsc/include/openbsc/gprs_gsup_messages.h index 937733f..701070a 100644 --- a/openbsc/include/openbsc/gprs_gsup_messages.h +++ b/openbsc/include/openbsc/gprs_gsup_messages.h @@ -45,6 +45,7 @@ enum gprs_gsup_iei { GPRS_GSUP_PDP_TYPE_IE = 0x11, GPRS_GSUP_ACCESS_POINT_NAME_IE = 0x12, GPRS_GSUP_MSISDN_IE = 0x13, + GPRS_GSUP_PDP_QOS_IE = 0x14, GPRS_GSUP_RAND_IE = 0x20, GPRS_GSUP_SRES_IE = 0x21, GPRS_GSUP_KC_IE = 0x22 @@ -91,6 +92,8 @@ struct gprs_gsup_pdp_info { uint16_t pdp_type; const uint8_t *apn_enc; size_t apn_enc_len; + const uint8_t *qos_enc; + size_t qos_enc_len; }; struct gprs_gsup_message { diff --git a/openbsc/src/gprs/gprs_gsup_messages.c b/openbsc/src/gprs/gprs_gsup_messages.c index be8e823..a4b0617 100644 --- a/openbsc/src/gprs/gprs_gsup_messages.c +++ b/openbsc/src/gprs/gprs_gsup_messages.c @@ -94,6 +94,11 @@ static int decode_pdp_info(uint8_t *data, size_t data_len, pdp_info->apn_enc_len = value_len; break; + case GPRS_GSUP_PDP_QOS_IE: + pdp_info->qos_enc = value; + pdp_info->qos_enc_len = value_len; + break; + default: LOGP(DGPRS, LOGL_ERROR, "GSUP IE type %d not expected in PDP info\n", iei); @@ -331,6 +336,11 @@ static void encode_pdp_info(struct msgb *msg, enum gprs_gsup_iei iei, pdp_info->apn_enc_len, pdp_info->apn_enc); } + if (pdp_info->qos_enc) { + msgb_tlv_put(msg, GPRS_GSUP_PDP_QOS_IE, + pdp_info->qos_enc_len, pdp_info->qos_enc); + } + /* Update length field */ *len_field = msgb_length(msg) - old_len; } diff --git a/openbsc/tests/gprs/gprs_test.c b/openbsc/tests/gprs/gprs_test.c index 555d657..ffe0220 100644 --- a/openbsc/tests/gprs/gprs_test.c +++ b/openbsc/tests/gprs/gprs_test.c @@ -444,10 +444,11 @@ static void test_gsup_messages_dec_enc(void) 0x06, TEST_IMSI_IE, 0x04, 0x00, /* PDP info complete */ - 0x05, 0x12, + 0x05, 0x15, 0x10, 0x01, 0x01, 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n', + 0x14, 0x01, 0x02, 0x05, 0x11, 0x10, 0x01, 0x02, 0x11, 0x02, 0xf1, 0x21, /* IPv4 */ -- 2.3.5 From holger at freyther.de Sun Apr 26 03:55:11 2015 From: holger at freyther.de (Holger Freyther) Date: Sat, 25 Apr 2015 23:55:11 -0400 Subject: test Message-ID: <01E4E8E7-5679-401D-A91B-D31653AC74D3@freyther.de> From holger at freyther.de Sun Apr 26 04:05:10 2015 From: holger at freyther.de (Holger Freyther) Date: Sun, 26 Apr 2015 00:05:10 -0400 Subject: test Message-ID: <9AB060F1-7544-4836-82B3-D62A1AF4D565@freyther.de> From jerlbeck at sysmocom.de Mon Apr 27 07:13:48 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 27 Apr 2015 09:13:48 +0200 Subject: [PATCH] mgcp/test: Fix mgcp-transcoding assertion (Coverity) Message-ID: <1430118828-29857-1-git-send-email-jerlbeck@sysmocom.de> In test_rtp_seq_state an assignment is accidently done within an assertion. This commit changes that into a comparison as it was intended. Fixes: Coverity CID 1295457, 1295458 Sponsored-by: On-Waves ehf --- openbsc/tests/mgcp/mgcp_transcoding_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbsc/tests/mgcp/mgcp_transcoding_test.c b/openbsc/tests/mgcp/mgcp_transcoding_test.c index 1b8001e..c5c0a0b 100644 --- a/openbsc/tests/mgcp/mgcp_transcoding_test.c +++ b/openbsc/tests/mgcp/mgcp_transcoding_test.c @@ -295,7 +295,7 @@ static void test_rtp_seq_state(void) OSMO_ASSERT(cont >= 0); OSMO_ASSERT(state->is_running); OSMO_ASSERT(state->next_seq == 2); - OSMO_ASSERT(state->next_time = 240); + OSMO_ASSERT(state->next_time == 240); /* verify that the right timestamp was written */ OSMO_ASSERT(len == audio_packets_pcma[0].len); -- 1.9.1 From mike.mcternan at wavemobile.com Tue Apr 28 10:06:49 2015 From: mike.mcternan at wavemobile.com (Mike McTernan (wavemobile)) Date: Tue, 28 Apr 2015 10:06:49 +0000 Subject: [PATCH] opensgsn: Replace some TODOs with error paths and fix compiler warning Message-ID: openggsn: Check return codes and take error paths on failure. Return early when socket() returns -1, and check return codes where indicated by some TODOs. This removes 2 TODOs and fixes a compiler warning about assignment to a variable which then isn't used. Signed-off-by: Michael McTernan Index: osmobss/openggsn/lib/tun.c =================================================================== --- osmobss.orig/openggsn/lib/tun.c 2015-04-28 10:51:37.960449539 +0100 +++ osmobss/openggsn/lib/tun.c 2015-04-28 10:54:40.301130739 +0100 @@ -117,6 +117,7 @@ int tun_sifflags(struct tun_t *this, int ifr.ifr_name[IFNAMSIZ - 1] = 0; /* Make sure to terminate */ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { SYS_ERR(DTUN, LOGL_ERROR, errno, "socket() failed"); + return -1; } if (ioctl(fd, SIOCSIFFLAGS, &ifr)) { SYS_ERR(DTUN, LOGL_ERROR, errno, @@ -318,9 +319,19 @@ int tun_addaddr(struct tun_t *this, req.n.nlmsg_seq = 0; req.n.nlmsg_flags |= NLM_F_ACK; - status = sendmsg(fd, &msg, 0); /* TODO Error check */ + status = sendmsg(fd, &msg, 0); + if (status == -1) { + SYS_ERR(DTUN, LOGL_ERROR, errno, "sendmsg() failed"); + close(fd); + return -1; + } + + status = tun_sifflags(this, IFF_UP | IFF_RUNNING); + if (status == -1) { + close(fd); + return -1; + } - tun_sifflags(this, IFF_UP | IFF_RUNNING); /* TODO */ close(fd); this->addrs++; return 0; -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: Check-and-fix-tun-setup-error-paths.patch Type: application/octet-stream Size: 1414 bytes Desc: Check-and-fix-tun-setup-error-paths.patch URL: From holger at freyther.de Tue Apr 28 10:48:57 2015 From: holger at freyther.de (Holger Freyther) Date: Tue, 28 Apr 2015 12:48:57 +0200 Subject: [PATCH] opensgsn: Replace some TODOs with error paths and fix compiler warning In-Reply-To: References: Message-ID: <32C9C3EF-CAFC-4285-A9CA-D107A290E68E@freyther.de> > On 28 Apr 2015, at 12:06, Mike McTernan (wavemobile) wrote: hi! > + status = sendmsg(fd, &msg, 0); > + if (status == -1) { this error check is not complete. sendmsg returns the number of bytes sent. This means we should check if everything we wanted to send has been sent (we were bitten by truncated LLE frames in GPRS-NS early on). Do you have time to extend this check? holger From mike.mcternan at wavemobile.com Tue Apr 28 11:59:16 2015 From: mike.mcternan at wavemobile.com (Mike McTernan (wavemobile)) Date: Tue, 28 Apr 2015 11:59:16 +0000 Subject: [PATCH] opensgsn: Replace some TODOs with error paths and fix compiler warning In-Reply-To: <32C9C3EF-CAFC-4285-A9CA-D107A290E68E@freyther.de> References: <32C9C3EF-CAFC-4285-A9CA-D107A290E68E@freyther.de> Message-ID: Hi Holger, > this error check is not complete. sendmsg returns the number of bytes sent. Whoops! > Do you have time to extend this check? Sure. I've fixed this in the attached v2 of the patch. It was tested by running the following to make sure that code path was reached and passed (which was also verified with a temporary printf): ./sgsnemu --contexts=4 -l 127.0.0.1 -r 127.0.0.2 -d --createif --net 0.0.0.0 Kind Regards, Mike -------------- next part -------------- A non-text attachment was scrubbed... Name: Check-and-fix-tun-setup-error-paths-v2.patch Type: application/octet-stream Size: 1763 bytes Desc: Check-and-fix-tun-setup-error-paths-v2.patch URL: From holger at freyther.de Wed Apr 29 12:35:36 2015 From: holger at freyther.de (Holger Freyther) Date: Wed, 29 Apr 2015 14:35:36 +0200 Subject: [PATCH] opensgsn: Replace some TODOs with error paths and fix compiler warning In-Reply-To: References: <32C9C3EF-CAFC-4285-A9CA-D107A290E68E@freyther.de> Message-ID: > On 28 Apr 2015, at 13:59, Mike McTernan (wavemobile) wrote: > > Sure. I've fixed this in the attached v2 of the patch. It was tested by running the following to make sure that code path was reached and passed (which was also verified with a temporary printf): Which version of OpenGGSN are you using? Where did you check it out? What is the last git commit? I ask because the patch does not apply and the line numbers in tun.c are quite different. I assume you are not getting it from git.osmocom.org? Do you? Where did we point to the SF repo? holger From jerlbeck at sysmocom.de Wed Apr 29 13:00:30 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 29 Apr 2015 15:00:30 +0200 Subject: [PATCH 2/2] bssgp: Fix encoding of BVC_FLOW_CONTROL In-Reply-To: <1430312430-22463-1-git-send-email-jerlbeck@sysmocom.de> References: <1430312430-22463-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1430312430-22463-2-git-send-email-jerlbeck@sysmocom.de> Currently all 2 byte IE of the message are transmitted in the little endian byte ordering. This commit adds htons to the encoding expressions. Sponsored-by: On-Waves ehf --- src/gb/gprs_bssgp_bss.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gb/gprs_bssgp_bss.c b/src/gb/gprs_bssgp_bss.c index c22a17a..5731959 100644 --- a/src/gb/gprs_bssgp_bss.c +++ b/src/gb/gprs_bssgp_bss.c @@ -325,19 +325,19 @@ int bssgp_tx_fc_bvc(struct bssgp_bvc_ctx *bctx, uint8_t tag, if ((bucket_size / 100) > 0xffff) return -EINVAL; - e_bucket_size = bucket_size / 100; + e_bucket_size = htons(bucket_size / 100); if ((bucket_leak_rate * 8 / 100) > 0xffff) return -EINVAL; - e_leak_rate = (bucket_leak_rate * 8) / 100; + e_leak_rate = htons((bucket_leak_rate * 8) / 100); if ((bmax_default_ms / 100) > 0xffff) return -EINVAL; - e_bmax_default_ms = bmax_default_ms / 100; + e_bmax_default_ms = htons(bmax_default_ms / 100); if ((r_default_ms * 8 / 100) > 0xffff) return -EINVAL; - e_r_default_ms = (r_default_ms * 8) / 100; + e_r_default_ms = htons((r_default_ms * 8) / 100); if (queue_delay_ms) { if ((*queue_delay_ms / 10) > 60000) @@ -345,7 +345,7 @@ int bssgp_tx_fc_bvc(struct bssgp_bvc_ctx *bctx, uint8_t tag, else if (*queue_delay_ms == 0xFFFFFFFF) e_queue_delay = 0xFFFF; else - e_queue_delay = *queue_delay_ms / 10; + e_queue_delay = htons(*queue_delay_ms / 10); } msg = bssgp_msgb_alloc(); -- 1.9.1 From jerlbeck at sysmocom.de Wed Apr 29 13:00:29 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 29 Apr 2015 15:00:29 +0200 Subject: [PATCH 1/2] bssgp: Fix output of the VTY 'show bssgp stats' command Message-ID: <1430312430-22463-1-git-send-email-jerlbeck@sysmocom.de> The output is terminated by a '\n' instead of VTY_NEWLINE. This is fixed by the commit. Sponsored-by: On-Waves ehf --- src/gb/gprs_bssgp_vty.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gb/gprs_bssgp_vty.c b/src/gb/gprs_bssgp_vty.c index 88ae49f..080867b 100644 --- a/src/gb/gprs_bssgp_vty.c +++ b/src/gb/gprs_bssgp_vty.c @@ -97,9 +97,10 @@ static void dump_bvc(struct vty *vty, struct bssgp_bvc_ctx *bvc, int stats) if (fc) vty_out(vty, "FC-BVC(bucket_max: %uoct, leak_rate: " "%uoct/s, cur_tokens: %uoct, max_q_d: %u, " - "cur_q_d: %u)\n", fc->bucket_size_max, + "cur_q_d: %u)%s", fc->bucket_size_max, fc->bucket_leak_rate, fc->bucket_counter, - fc->max_queue_depth, fc->queue_depth); + fc->max_queue_depth, fc->queue_depth, + VTY_NEWLINE); } } -- 1.9.1 From jerlbeck at sysmocom.de Thu Apr 30 17:28:03 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Apr 2015 19:28:03 +0200 Subject: [PATCH] bssgp: Fix call to llist_entry in fc_queue_timer_cfg Message-ID: <1430414883-25640-1-git-send-email-jerlbeck@sysmocom.de> Currently the DL sometimes hangs and sometimes a lot of messages (still not able to send PDU) are logged. This is caused by an invalid timer delay computation, setting msecs either to 0 or to some big value. This is due to an '&' operator at the wrong place, accessing some parts in fc instead of the first element of the list. This commit fixes that issue. Sponsored-by: On-Waves ehf --- src/gb/gprs_bssgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c index 4c93b69..fe4fcca 100644 --- a/src/gb/gprs_bssgp.c +++ b/src/gb/gprs_bssgp.c @@ -628,7 +628,7 @@ static int fc_queue_timer_cfg(struct bssgp_flow_control *fc) if (llist_empty(&fc->queue)) return 0; - fcqe = llist_entry(&fc->queue.next, struct bssgp_fc_queue_element, + fcqe = llist_entry(fc->queue.next, struct bssgp_fc_queue_element, list); if (fc->bucket_leak_rate != 0) { -- 1.9.1 From holger at freyther.de Thu Apr 30 18:01:24 2015 From: holger at freyther.de (Holger Freyther) Date: Thu, 30 Apr 2015 20:01:24 +0200 Subject: [PATCH] bssgp: Fix call to llist_entry in fc_queue_timer_cfg In-Reply-To: <1430414883-25640-1-git-send-email-jerlbeck@sysmocom.de> References: <1430414883-25640-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <9BBAB7D2-64C7-4643-9F47-DFD3300F54A9@freyther.de> > On 30 Apr 2015, at 19:28, Jacob Erlbeck wrote: > > Currently the DL sometimes hangs and sometimes a lot of messages > (still not able to send PDU) are logged. This is caused by an invalid > timer delay computation, setting msecs either to 0 or to some big value. > > This is due to an '&' operator at the wrong place, accessing some > parts in fc instead of the first element of the list. ouch. it appears that this is the only occurrence of this issue. How long did it take for you to find it? Did ASAN help? From jerlbeck at sysmocom.de Thu Apr 30 18:33:14 2015 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 30 Apr 2015 20:33:14 +0200 Subject: [PATCH] bssgp: Fix call to llist_entry in fc_queue_timer_cfg In-Reply-To: <9BBAB7D2-64C7-4643-9F47-DFD3300F54A9@freyther.de> References: <1430414883-25640-1-git-send-email-jerlbeck@sysmocom.de> <9BBAB7D2-64C7-4643-9F47-DFD3300F54A9@freyther.de> Message-ID: <5542756A.2080705@sysmocom.de> On 30.04.2015 20:01, Holger Freyther wrote: > >> On 30 Apr 2015, at 19:28, Jacob Erlbeck wrote: >> This is due to an '&' operator at the wrong place, accessing some >> parts in fc instead of the first element of the list. > > ouch. it appears that this is the only occurrence of this issue. How long did > it take for you to find it? Did ASAN help? > No, since the data seems to be taken from then fc struct, so the memory area is valid. ASAN was enabled and didn't complain. Logging helped instead, since the logging messages suggested, that the timer interval computation might have been broken. Jacob -- - Jacob Erlbeck http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Alt-Moabit 93 * 10559 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte