From Ivan.Kluchnikov at fairwaves.ru Tue Feb 11 07:13:35 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Tue, 11 Feb 2014 11:13:35 +0400 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: <20130910125028.GF31205@xiaoyu.lan> References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> Message-ID: Hi all, The attached patches for openbsc and osmo-bts finally fix issues which were discussed above. There are two parts: 1. Implementation of sending rsl Delete_Ind message (on bts side) and handling it (on bsc side). Bts should send rsl Delete Ind message to bsc, if there is no space in agch queue and bts can not send current imm assign message. When bsc receives Delete_Ind message from bts, bsc should release allocated channel, which was specified in dropped imm_assign message. 2. Implemented calculation of agch queue length. Bts should calculate allowed length of agch queue, because bts should send imm assign message before immediate assignment procedure will be aborted by MS. Imm assign message can be queued no longer than T3126, so agch queue length should be equal (T3126 / 51 ) * bs_ag_blks_res. These patches fix critical issues and prevent network failures under heavy load, so it makes sense to merge them asap. 2013-09-10 16:50 GMT+04:00 Holger Hans Peter Freyther : > On Tue, Sep 10, 2013 at 02:24:38PM +0400, Alexander Chemeris wrote: >> >> If Andreas don't implement the calculation, we'll go with a manually >> configured limit. Should be fine for most use cases. > > come on, please don't be so lazy. > -- Regards, Ivan Kluchnikov. http://fairwaves.ru -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-rsl-Implement-handling-of-rsl-Delete-Ind-message.patch Type: text/x-diff Size: 1750 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-rsl-Send-rsl-Delete-Ind-message-to-bsc-if-there-is-n.patch Type: text/x-diff Size: 1505 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-bts-Calculate-length-of-agch-queue.patch Type: text/x-diff Size: 2819 bytes Desc: not available URL: From holger at freyther.de Tue Feb 11 10:14:01 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 11 Feb 2014 11:14:01 +0100 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> Message-ID: <20140211101401.GL21724@xiaoyu.lan> On Tue, Feb 11, 2014 at 11:13:35AM +0400, Ivan Kluchnikov wrote: Good Morning, > The attached patches for openbsc and osmo-bts finally fix issues which > were discussed above. what a surprise. Jacob has started implementing AGCH queue handling as well. So I will let him comment on the BTS part. OpenBSC: > + > + /* bts didn't send IMM_ASSIGN, so we should release allocated channel */ > + ia = (struct gsm48_imm_ass *) (rqd_hdr->data + 2); Please add a size check that the mandatory element actually fits and use early returns. > + if (ia->msg_type == GSM48_MT_RR_IMM_ASS) { > + chan_nr = ia->chan_desc.chan_nr; > + lchan = lchan_lookup(trx, chan_nr); same thing for the lchan. Verify it was found and that the state is actually the right one. > + rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE); Maybe use rsl_direct_rf_release. By definition there is no one listening on the SACCH. So there is not point in going through the normal release procedure. > +/* 8.5.4 DELETE INDICATION */ > +int rsl_tx_delete_ind(struct gsm_bts *bts, uint8_t len, uint8_t *val) > +{ > + struct msgb *msg; > + > + msg = rsl_msgb_alloc(sizeof(struct abis_rsl_cchan_hdr)); > + if (!msg) > + return -ENOMEM; > + rsl_cch_push_hdr(msg, RSL_MT_DELETE_IND, RSL_CHAN_PCH_AGCH); > + msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, len, val); > + msg->trx = bts->c0; Have you manually tested this with multi-trx support and the channel being on the second trx? The lchan_lookup in OpenBSC will be done using the "bts->c0"? > - msgb_free(msg); > + rsl_tx_delete_ind(trx->bts, msg->len, msg->data); > + return -ENOMEM; Does it leak now? or was it a double free before? From Ivan.Kluchnikov at fairwaves.ru Thu Feb 13 12:53:27 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Thu, 13 Feb 2014 16:53:27 +0400 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: <20140211101401.GL21724@xiaoyu.lan> References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <20140211101401.GL21724@xiaoyu.lan> Message-ID: Hi Holger, Thank you for review, I will fix my patches today or tomorrow and send you new version asap. 2014-02-11 14:14 GMT+04:00 Holger Hans Peter Freyther : > On Tue, Feb 11, 2014 at 11:13:35AM +0400, Ivan Kluchnikov wrote: > > Good Morning, > >> The attached patches for openbsc and osmo-bts finally fix issues which >> were discussed above. > > what a surprise. Jacob has started implementing AGCH queue handling > as well. So I will let him comment on the BTS part. > > > > OpenBSC: >> + >> + /* bts didn't send IMM_ASSIGN, so we should release allocated channel */ >> + ia = (struct gsm48_imm_ass *) (rqd_hdr->data + 2); > > Please add a size check that the mandatory element actually fits > and use early returns. > >> + if (ia->msg_type == GSM48_MT_RR_IMM_ASS) { >> + chan_nr = ia->chan_desc.chan_nr; >> + lchan = lchan_lookup(trx, chan_nr); > > same thing for the lchan. Verify it was found and that the state > is actually the right one. > > >> + rsl_rf_chan_release(lchan, 1, SACCH_DEACTIVATE); > > Maybe use rsl_direct_rf_release. By definition there is no one listening > on the SACCH. So there is not point in going through the normal release > procedure. > > >> +/* 8.5.4 DELETE INDICATION */ >> +int rsl_tx_delete_ind(struct gsm_bts *bts, uint8_t len, uint8_t *val) >> +{ >> + struct msgb *msg; >> + >> + msg = rsl_msgb_alloc(sizeof(struct abis_rsl_cchan_hdr)); >> + if (!msg) >> + return -ENOMEM; >> + rsl_cch_push_hdr(msg, RSL_MT_DELETE_IND, RSL_CHAN_PCH_AGCH); >> + msgb_tlv_put(msg, RSL_IE_FULL_IMM_ASS_INFO, len, val); >> + msg->trx = bts->c0; > > Have you manually tested this with multi-trx support and the channel > being on the second trx? The lchan_lookup in OpenBSC will be done using > the "bts->c0"? > > >> - msgb_free(msg); >> + rsl_tx_delete_ind(trx->bts, msg->len, msg->data); >> + return -ENOMEM; > > Does it leak now? or was it a double free before? > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From holger at freyther.de Thu Feb 13 13:25:46 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 13 Feb 2014 14:25:46 +0100 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <20140211101401.GL21724@xiaoyu.lan> Message-ID: <20140213132546.GZ21724@xiaoyu.lan> On Thu, Feb 13, 2014 at 04:53:27PM +0400, Ivan Kluchnikov wrote: Dear Ivan, > Thank you for review, I will fix my patches today or tomorrow and send > you new version asap. can you please confirm/reject my statements from below. Does the code have the defect for multi-trx that I lined out? holger From Ivan.Kluchnikov at fairwaves.ru Mon Feb 17 14:03:28 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Mon, 17 Feb 2014 18:03:28 +0400 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: <20140213132546.GZ21724@xiaoyu.lan> References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <20140211101401.GL21724@xiaoyu.lan> <20140213132546.GZ21724@xiaoyu.lan> Message-ID: Hi Holger, Yes, you are right, the code had the defect for multi-trx. We should use arfcn value from immediate assignment message to determine trx. I sent new version of the patch to openbsc mailing list, please check it. I also added checks for size and lchan. 2014-02-13 17:25 GMT+04:00 Holger Hans Peter Freyther : > On Thu, Feb 13, 2014 at 04:53:27PM +0400, Ivan Kluchnikov wrote: > > Dear Ivan, > >> Thank you for review, I will fix my patches today or tomorrow and send >> you new version asap. > > can you please confirm/reject my statements from below. Does the code > have the defect for multi-trx that I lined out? > > holger > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From jerlbeck at sysmocom.de Tue Feb 11 14:07:13 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 11 Feb 2014 15:07:13 +0100 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> Message-ID: <52FA2E91.1090605@sysmocom.de> Dear Ivan, since I've been investigating this topic for some days now, I would like to share my thoughts about your approach, so that we can resolve this issue quickly together. On 11.02.2014 08:13, Ivan Kluchnikov wrote: > 1. Implementation of sending rsl Delete_Ind message (on bts side) and > handling it (on bsc side). > Bts should send rsl Delete Ind message to bsc, if there is no space in > agch queue and bts can not send current imm assign message. > When bsc receives Delete_Ind message from bts, bsc should release > allocated channel, which was specified in dropped imm_assign message. As far as I understand it is not important to send such messages to IMMEDIATE ASSIGNMENT REJECT messages. But I like this idea to shorten the timeout. > 2. Implemented calculation of agch queue length. > Bts should calculate allowed length of agch queue, because bts should > send imm assign message before immediate assignment procedure will be > aborted by MS. > Imm assign message can be queued no longer than T3126, so agch queue > length should be equal (T3126 / 51 ) * bs_ag_blks_res. I'm not sure about the correctness of the max length calculation because of a) There are other timers/conditions that are influenced by the queue delay: - T3101 limits channel reservation on the network side. - Only the last 3 CHANNEL REQUEST messages are matched by the MS against incoming IMMEDIATE ASSIGNMENT messages. b) If the queue has the length limited by a) we know that at least the last (if not every) element of the queue will be delivered too late. Since your patch isn't using T3126 but min(T3126) which is based on T + 2*S, and since this reflects the 3 CHAN-REQ restriction, this is already solved (T3101 is probably larger that min(T3126)). I'll use maxL = (min(T3126) / 51 ) * bs_ag_blks_res below. The b) issue is another thing. Because of additional round-trip delays (DSP queues, BSC<->BTS delay) it might be sensible to reduce the max queue length by another factor. But AFAICS the main problem with dropping packets at the queue's input is, that you maintain a queue with stale messages while throwing away the fresh ones. So under heavy load, latency increases which is especially bad with IMMEDIATE ASSIGNMENT messages. I've two slightly different proposals to fix this: (1) If the queue is full (e.g. at 0.8 * maxL), flush all IMMEDIATE ASSIGNMENT REJECT messages. Don't notify the BSC about those. If there are still too many messages left afterwards one might also drop an IMMEDIATE ASSIGNMENT (perhaps from the queues input) and notify the BSC like in your patch. (2) When taking message from the queue, throw them away if they are IMMEDIATE ASSIGNMENT REJECTs and the queue is too long (e.g. > maxL/2) and try the next message until that condition fails (or some low water mark is reached). A variant would be to drop IA REJECTs based on a queue usage dependant probability (e.g. p(L) = L / maxL). I'm not sure, which approach would perform better considering different scenarios like burst-like accesses and high packet loss. I've done hand simulations for a single burst case (10 MS compete simultaneously for 4 channels) and both approaches worked well (much better than the current master). (2) is probably easier to implement. What do you think about that? > > These patches fix critical issues and prevent network failures under > heavy load, I'm not convinced that this approach will work reliably under overload (see above). It just guarantees a maximum queue length. > so it makes sense to merge them asap. What about rebasing on on origin/master? I think that would speed this up a lot. Is there something missing from jolly's branch beside queue length accounting? > @@ -50,6 +50,7 @@ struct gsm_bts_role_bts { > uint8_t max_ta; > struct llist_head agch_queue; > int agch_queue_count; I'd rather not use this name, but agch_queue_length instead. I think 'length' more precise than 'size' or 'count' when asking for the number of elements of a list or a queue. 'count' makes me think about the number of queues. Quite a few libraries have chosen 'size' instead, but it's ambiguous, whether this refers to memory size or to the number of elements. > + uint8_t agch_queue_len; What about agch_max_queue_length or agch_queue_length_limit? > int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) > { > struct gsm_bts_role_bts *btsb = bts_role_bts(bts); > + struct gsm48_system_information_type_3 *si3; > + uint8_t T, S, agch_num, i; > + uint8_t T_group = 0; > + uint8_t ccch_comb = 0; > + > + /* calculate length of agch queue > + agch_queue_len = ( min( T3126 ) / 51 ) * bs_ag_blks_res > + min(T3126) = T + 2*S defined in 04.08 11.1.1 Are you sure? Isn't it min(T3126) = (T + 2*S) / (RACH slots per second) ? > + S and T are defined in 04.08 3.3.1.1.2 */ > + > + si3 = GSM_BTS_SI(bts, SYSINFO_TYPE_3); > + T = si3->rach_control.tx_integer; > + for (i = 0; i < 15; i++) { > + if (tx_integer[i] == T) { > + T_group = i % 5; > + break; > + } > + } > + if (si3->control_channel_desc.ccch_conf == 1) { > + ccch_comb = 1; > + } > + S = s_values[T_group][ccch_comb]; > + agch_num = si3->control_channel_desc.bs_ag_blks_res; > > - if (btsb->agch_queue_count >= 30) > + btsb->agch_queue_len = ((T + 2 * S) / 51) * agch_num; This might lead to smaller values than neccessary due to rounding errors. Why not using agch_queue_len = (??? * agch_num) / 51? But I think, the max length computation does not yield correct results anyway because of the number of RACH slots is not taken into account. I'd rather put the above into an own function (bts_agch_update_max_queue_length?) that is only called after config/bs_ag_blks_res is changed/set. Best wishes Jacob From jerlbeck at sysmocom.de Thu Feb 13 11:07:43 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 13 Feb 2014 12:07:43 +0100 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: <52FA2E91.1090605@sysmocom.de> References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> Message-ID: <52FCA77F.9060808@sysmocom.de> Hi, On 11.02.2014 15:07, Jacob Erlbeck wrote: >> 2. Implemented calculation of agch queue length. >> Bts should calculate allowed length of agch queue, because bts should >> send imm assign message before immediate assignment procedure will be >> aborted by MS. >> Imm assign message can be queued no longer than T3126, so agch queue >> length should be equal (T3126 / 51 ) * bs_ag_blks_res. My understanding of GSM 05.02 3.3.2.3, 6.5.1 v), and clause 7 table 5 was, that bs_ag_blks_res defines the number of blocks _reserved_ for AGCH an SI messages per 51-multiframe, but does not _limit_ it. Is this correct? If yes, is there a reason why the implementations (master and jolly/trx) do not use PCH blocks when needed? > > I'm not sure about the correctness of the max length calculation because of > a) There are other timers/conditions that are influenced by the queue delay: > - T3101 limits channel reservation on the network side. > - Only the last 3 CHANNEL REQUEST messages are matched by the MS > against incoming IMMEDIATE ASSIGNMENT messages. More precisely, this limits the allowable delay to 3*(S+T/2) while CHANNEL REQUESTs are being sent. After the last one, T3126 is relevant. At least, this is my understanding of GSM 04.08, 3.3.1.1.2. So I'd rather drop that requirement, since 3S+1.5T > 2S+T. Jacob From Ivan.Kluchnikov at fairwaves.ru Thu Feb 13 12:48:47 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Thu, 13 Feb 2014 16:48:47 +0400 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: <52FCA77F.9060808@sysmocom.de> References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> Message-ID: Hi Jacob, Thank you for your comments and ideas! First I want to summarize you previous ideas, which I think we should implement: 1. we shouldn't send Delete Ind message for IMMEDIATE ASSIGNMENT REJECT messages 2. Just drop IA REJECTs, if L > maxL/2 (am I right?) 3. Use agch_queue_length and agch_max_queue_length names 4. Implement function bts_agch_update_max_queue_length, that is only called after config/bs_ag_blks_res is changed/set (do you know places where bs_ag_blks_res is changed/set?) 5. Yes, you are right, we can use PCH blocks when needed, it is good question, why (master and jolly/trx) do not use PCH blocks when needed. Actually we already have function for that: int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data, uint8_t len); Moreover we should also determine when we should start to use PCH for imm assign messages and what we should do with agch_max_queue_length in this case, what do you think about it? 6. What do you finally think about calculating agch_max_queue_length? What is the right way to calculate it from your point of view? 2014-02-13 15:07 GMT+04:00 Jacob Erlbeck : > Hi, > > On 11.02.2014 15:07, Jacob Erlbeck wrote: >>> 2. Implemented calculation of agch queue length. >>> Bts should calculate allowed length of agch queue, because bts should >>> send imm assign message before immediate assignment procedure will be >>> aborted by MS. >>> Imm assign message can be queued no longer than T3126, so agch queue >>> length should be equal (T3126 / 51 ) * bs_ag_blks_res. > > My understanding of GSM 05.02 3.3.2.3, 6.5.1 v), and clause 7 table 5 > was, that bs_ag_blks_res defines the number of blocks _reserved_ for > AGCH an SI messages per 51-multiframe, but does not _limit_ it. > Is this correct? If yes, is there a reason why the implementations > (master and jolly/trx) do not use PCH blocks when needed? > >> >> I'm not sure about the correctness of the max length calculation because of >> a) There are other timers/conditions that are influenced by the queue delay: >> - T3101 limits channel reservation on the network side. >> - Only the last 3 CHANNEL REQUEST messages are matched by the MS >> against incoming IMMEDIATE ASSIGNMENT messages. > > More precisely, this limits the allowable delay to 3*(S+T/2) while > CHANNEL REQUESTs are being sent. After the last one, T3126 is relevant. > At least, this is my understanding of GSM 04.08, 3.3.1.1.2. So I'd > rather drop that requirement, since 3S+1.5T > 2S+T. > > Jacob > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From alexander.chemeris at gmail.com Thu Feb 13 13:01:10 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Thu, 13 Feb 2014 15:01:10 +0200 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> Message-ID: On Thu, Feb 13, 2014 at 2:48 PM, Ivan Kluchnikov wrote: > 5. Yes, you are right, we can use PCH blocks when needed, it is good > question, why (master and jolly/trx) do not use PCH blocks when > needed. > Actually we already have function for that: > int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data, > uint8_t len); > Moreover we should also determine when we should start to use PCH for > imm assign messages and what we should do with agch_max_queue_length > in this case, what do you think about it? I believe that we should start using PCH for IMM.ASS as soon as we exhaust capacity of the AGCH. Imho, IMM.ASS has higher priority than PCH, as paging will lead to IMM.ASS anyway, and if AGCH is congested, there is no point in sending any more paging. > 6. What do you finally think about calculating agch_max_queue_length? > What is the right way to calculate it from your point of view? You could also consider another approach. Instead of limiting the queue length - limit the age of IMM.ASS in the queue. I'm not sure about the current implementation, but in general you should be able to predict when an IMM.ASS is sent out and thus you could predict whether the phone will receive it or not. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From jerlbeck at sysmocom.de Fri Feb 14 10:22:39 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 14 Feb 2014 11:22:39 +0100 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> Message-ID: <52FDEE6F.7090704@sysmocom.de> On 13.02.2014 14:01, Alexander Chemeris wrote: > I believe that we should start using PCH for IMM.ASS as soon as we > exhaust capacity of the AGCH. > > Imho, IMM.ASS has higher priority than PCH, as paging will lead to > IMM.ASS anyway, and if AGCH is congested, there is no point in sending > any more paging. I'm not so comfortable with that. We would then have a decreasing probability within a 51-multiframe of having a PCH message being cannibalized by a AGCH message. That in turn would IMO lead to unfair treatment of MS because of the paging group they belong to (AFAI understand GSM 05.02, 6.5.1 vi and 6.5.2). In addition, I didn't understand the 'extended paging' (see GSM 04.08, 3.3.2.1.1 b) well enough, to estimate the implications here. I'd rather prioritize paging messages over IMM.ASS.* to stay on the safe side until we have measurements or simulations that suggest otherwise. > >> 6. What do you finally think about calculating agch_max_queue_length? >> What is the right way to calculate it from your point of view? > > You could also consider another approach. Instead of limiting the > queue length - limit the age of IMM.ASS in the queue. Yes, this was my first approach, too. But it is more complex and we still need to determine max-age which suffers from the same difficulties like the max-queue-length computation. I also thought about having to queues: - One for non-reject messages (IMM.ASS.CMD and IMM.ASS.EXT) that is unlimited and has a high prio - Another for the reject messages only with a lower prio, where messages older that 3(S+T/2) RACH slots are silently dropped But I have the impression, that a simpler solution (like those I stated in the other mail) will take us far enough with much less efforts. Jacob From alexander.chemeris at gmail.com Sun Feb 16 11:20:24 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Feb 2014 15:20:24 +0400 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: <52FDEE6F.7090704@sysmocom.de> References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> <52FDEE6F.7090704@sysmocom.de> Message-ID: Jacob, On Fri, Feb 14, 2014 at 12:22 PM, Jacob Erlbeck wrote: > On 13.02.2014 14:01, Alexander Chemeris wrote: >> I believe that we should start using PCH for IMM.ASS as soon as we >> exhaust capacity of the AGCH. >> >> Imho, IMM.ASS has higher priority than PCH, as paging will lead to >> IMM.ASS anyway, and if AGCH is congested, there is no point in sending >> any more paging. > > I'm not so comfortable with that. We would then have a decreasing > probability within a 51-multiframe of having a PCH message being > cannibalized by a AGCH message. That in turn would IMO lead to unfair > treatment of MS because of the paging group they belong to (AFAI > understand GSM 05.02, 6.5.1 vi and 6.5.2). In addition, I didn't > understand the 'extended paging' (see GSM 04.08, 3.3.2.1.1 b) well > enough, to estimate the implications here. > > I'd rather prioritize paging messages over IMM.ASS.* to stay on the safe > side until we have measurements or simulations that suggest otherwise. Sending more paging messages only increases a number of IMM.ASS messages being sent out. Thus it doesn't make sense to prioritize PCH over AGCH. Another question is how do we schedule IMM.ASS in case we cannibalize PCH. IIRC, an MS could be sleeping during paging groups it doesn't belong to and thus might miss the IMM.ASS we're sending. We have to check this against the standard. >>> 6. What do you finally think about calculating agch_max_queue_length? >>> What is the right way to calculate it from your point of view? >> >> You could also consider another approach. Instead of limiting the >> queue length - limit the age of IMM.ASS in the queue. > > Yes, this was my first approach, too. But it is more complex and we > still need to determine max-age which suffers from the same difficulties > like the max-queue-length computation. I was thinking about scheduling IMM.ASS and at the time of its arrival. May be even replacing a queue with a fixed-size round-robin "map". In this case there should be no issues with understanding if IMM.ASS is too late, as we'll know when exactly it's to be sent. This changes the current code structure, though, and I haven't estimated the effort required to do that. > But I have the impression, that a simpler solution (like those I stated > in the other mail) will take us far enough with much less efforts. Which solution are you referring to? -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From jerlbeck at sysmocom.de Mon Feb 17 09:59:37 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 17 Feb 2014 10:59:37 +0100 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> <52FDEE6F.7090704@sysmocom.de> Message-ID: <5301DD89.6050400@sysmocom.de> Hello On 16.02.2014 12:20, Alexander Chemeris wrote: > On Fri, Feb 14, 2014 at 12:22 PM, Jacob Erlbeck wrote: >> On 13.02.2014 14:01, Alexander Chemeris wrote: >> I'd rather prioritize paging messages over IMM.ASS.* to stay on the safe >> side until we have measurements or simulations that suggest otherwise. > > Sending more paging messages only increases a number of IMM.ASS > messages being sent out. Thus it doesn't make sense to prioritize PCH > over AGCH. That might be true for many cases, but there might be other cases like issuing a paging request at the end of a short term AGCH overload where it would make sense, to not drop it but some IMM.ASS.REJ instead. Another case: all IMM.ASS.* messages are about TCH's and the paging request is for SDCCH (or vice versa). So until there are simulations covering all sensible combinations and all of them suggest that always prioritizing AGCH over PCH is really worth the drawbacks, I won't do that. It is not required by the spec either, which provides AG block reservation to cope with frequent PCH overloads instead. There might be reasons, why they didn't suggest this kind of prioritization and I'd rather be careful until I know that these are not technical ones. So I've implemented the usage of _free_ PCH blocks for IMM.ASS which is IMO a big improvement over the current situation and without any drawback I know of. In addition, I've added dropping of IMM.ASS.REJ based on AGCH queue length, to further increase the AGCH queue's drain rate. This is beyond the spec too, but doesn't touch another procedure at least. I suggest to gather real live experiences with these changes and implement more sophisticated solutions when need arises. > > Another question is how do we schedule IMM.ASS in case we cannibalize > PCH. IIRC, an MS could be sleeping during paging groups it doesn't > belong to and thus might miss the IMM.ASS we're sending. We have to > check this against the standard. Paging groups are not relevant for the RR connection establishment procedure (AFAICS). According to GSM 04.08 3.3.1.1.3.1 and .2 IMM.ASS.* is only restricted to the "same CCCH timeslot" where the CHANNEL REQUEST has been sent, "there is no further restriction on what part of the downlink CCCH" the IMM.ASS.* is sent. > >> But I have the impression, that a simpler solution (like those I stated >> in the other mail) will take us far enough with much less efforts. > > Which solution are you referring to? > See <52FA2E91.1090605 at sysmocom.de> (1) and (2) and above. Jacob From Ivan.Kluchnikov at fairwaves.ru Tue Feb 18 10:58:31 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Tue, 18 Feb 2014 14:58:31 +0400 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: <5301DD89.6050400@sysmocom.de> References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> <52FDEE6F.7090704@sysmocom.de> <5301DD89.6050400@sysmocom.de> Message-ID: Jacob, Your implementation (jerbeck/agch-queue branch) looks reasonable. But from my point of view we should add sending rsl Delete Ind message to bsc and implement final check (in bts_agch_dequeue function) that immediate assignment message is still valid for ms. My plan is to test your code and add sending rsl Delete Ind message to bsc. After that we can try to implement lifetime parameter for immediate assignment message. 2014-02-17 13:59 GMT+04:00 Jacob Erlbeck : > Hello > > On 16.02.2014 12:20, Alexander Chemeris wrote: >> On Fri, Feb 14, 2014 at 12:22 PM, Jacob Erlbeck wrote: >>> On 13.02.2014 14:01, Alexander Chemeris wrote: > >>> I'd rather prioritize paging messages over IMM.ASS.* to stay on the safe >>> side until we have measurements or simulations that suggest otherwise. >> >> Sending more paging messages only increases a number of IMM.ASS >> messages being sent out. Thus it doesn't make sense to prioritize PCH >> over AGCH. > > That might be true for many cases, but there might be other cases like > issuing a paging request at the end of a short term AGCH overload where > it would make sense, to not drop it but some IMM.ASS.REJ instead. > Another case: all IMM.ASS.* messages are about TCH's and the paging > request is for SDCCH (or vice versa). So until there are simulations > covering all sensible combinations and all of them suggest that always > prioritizing AGCH over PCH is really worth the drawbacks, I won't do > that. It is not required by the spec either, which provides AG block > reservation to cope with frequent PCH overloads instead. There might be > reasons, why they didn't suggest this kind of prioritization and I'd > rather be careful until I know that these are not technical ones. > > So I've implemented the usage of _free_ PCH blocks for IMM.ASS which is > IMO a big improvement over the current situation and without any > drawback I know of. In addition, I've added dropping of IMM.ASS.REJ > based on AGCH queue length, to further increase the AGCH queue's drain > rate. This is beyond the spec too, but doesn't touch another procedure > at least. > > I suggest to gather real live experiences with these changes and > implement more sophisticated solutions when need arises. > >> >> Another question is how do we schedule IMM.ASS in case we cannibalize >> PCH. IIRC, an MS could be sleeping during paging groups it doesn't >> belong to and thus might miss the IMM.ASS we're sending. We have to >> check this against the standard. > > Paging groups are not relevant for the RR connection establishment > procedure (AFAICS). According to GSM 04.08 3.3.1.1.3.1 and .2 IMM.ASS.* > is only restricted to the "same CCCH timeslot" where the CHANNEL REQUEST > has been sent, "there is no further restriction on what part of the > downlink CCCH" the IMM.ASS.* is sent. > >> >>> But I have the impression, that a simpler solution (like those I stated >>> in the other mail) will take us far enough with much less efforts. >> >> Which solution are you referring to? >> > > See <52FA2E91.1090605 at sysmocom.de> (1) and (2) and above. > > Jacob > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From jerlbeck at sysmocom.de Tue Feb 18 11:39:07 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Tue, 18 Feb 2014 12:39:07 +0100 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> <52FDEE6F.7090704@sysmocom.de> <5301DD89.6050400@sysmocom.de> Message-ID: <5303465B.6080102@sysmocom.de> Dear Ivan, On 18.02.2014 11:58, Ivan Kluchnikov wrote: > Your implementation (jerbeck/agch-queue branch) looks reasonable. But it isn't ;-) It's just a snapshot and not yet finished. > But from my point of view we should add sending rsl Delete Ind message > to bsc and implement final check (in bts_agch_dequeue function) that > immediate assignment message is still valid for ms. I thought that your Delete Ind patches could be added as next step, since they are orthogonal to the queue handling itself. > My plan is to test your code and add sending rsl Delete Ind message to bsc. Please wait with testing, the current branch just segfaults and I'll fix (and rebase) it soon. > After that we can try to implement lifetime parameter for immediate > assignment message. What do you mean exactly? Cheers Jacob From Ivan.Kluchnikov at fairwaves.ru Tue Feb 18 18:36:58 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Tue, 18 Feb 2014 22:36:58 +0400 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: <5303465B.6080102@sysmocom.de> References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> <52FDEE6F.7090704@sysmocom.de> <5301DD89.6050400@sysmocom.de> <5303465B.6080102@sysmocom.de> Message-ID: >> Your implementation (jerbeck/agch-queue branch) looks reasonable. > But it isn't ;-) It's just a snapshot and not yet finished. > Ok, I understand, actually my main goal is to test bts_update_agch_max_queue_length and compact_agch_queue functions. >> But from my point of view we should add sending rsl Delete Ind message >> to bsc and implement final check (in bts_agch_dequeue function) that >> immediate assignment message is still valid for ms. > > I thought that your Delete Ind patches could be added as next step, > since they are orthogonal to the queue handling itself. Yes. >> My plan is to test your code and add sending rsl Delete Ind message to bsc. > > Please wait with testing, the current branch just segfaults and I'll fix > (and rebase) it soon. Ok. >> After that we can try to implement lifetime parameter for immediate >> assignment message. > What do you mean exactly? The idea is to save gsm_time for each imm assign message, when we add this message to agch queue. After that when we are ready to send this message and dequeue it, we are able to calculate how long this message was in agch queue and finally decide what to do, send or drop this imm assign message. -- Regards, Ivan Kluchnikov. http://fairwaves.ru From alexander.chemeris at gmail.com Tue Feb 18 20:01:26 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Wed, 19 Feb 2014 00:01:26 +0400 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> <52FDEE6F.7090704@sysmocom.de> <5301DD89.6050400@sysmocom.de> <5303465B.6080102@sysmocom.de> Message-ID: On Tue, Feb 18, 2014 at 10:36 PM, Ivan Kluchnikov wrote: >>> After that we can try to implement lifetime parameter for immediate >>> assignment message. >> What do you mean exactly? > > The idea is to save gsm_time for each imm assign message, when we add > this message to agch queue. After that when we are ready to send this > message and dequeue it, we are able to calculate how long this message > was in agch queue and finally decide what to do, send or drop this imm > assign message. Are you sure that we could rely on the IMM.ASS timestamp to do the final judgement? From our discussions I was under impression that we should measure time difference from the original RACH burst, as that's what MS is measuring. Do I understand the procedure incorrectly? -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From jerlbeck at sysmocom.de Thu Feb 13 13:53:25 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 13 Feb 2014 14:53:25 +0100 Subject: Unbounded AGCH queue in OsmoBTS In-Reply-To: References: <20130910092158.GD31205@xiaoyu.lan> <20130910100515.GE31205@xiaoyu.lan> <20130910125028.GF31205@xiaoyu.lan> <52FA2E91.1090605@sysmocom.de> <52FCA77F.9060808@sysmocom.de> Message-ID: <52FCCE55.9020601@sysmocom.de> Hi Ivan, On 13.02.2014 13:48, Ivan Kluchnikov wrote: > First I want to summarize you previous ideas, which I think we should implement: > 1. we shouldn't send Delete Ind message for IMMEDIATE ASSIGNMENT REJECT messages > 2. Just drop IA REJECTs, if L > maxL/2 (am I right?) I'm not sure about which factor to use, especially if maxL is very low. But I think it's a good start. Maybe we need some simulations to fine-tune. In addition, we should add stat counters for that. > 3. Use agch_queue_length and agch_max_queue_length names > 4. Implement function bts_agch_update_max_queue_length, that is only > called after config/bs_ag_blks_res is changed/set (do you know places > where bs_ag_blks_res is changed/set?) We've to check. If any of the input values changes, we have to update. But let's put that call into agch_enqueue initially. Moving this to other places is just an optimization and I would like to defer it, until the rest has proved to work. > 5. Yes, you are right, we can use PCH blocks when needed, it is good > question, why (master and jolly/trx) do not use PCH blocks when > needed. I've just set up a test case with NITB and two phones, and modified code where only the PCH blocks are used for AGCH and PCH and it worked pretty well. > Actually we already have function for that: > int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data, > uint8_t len); > Moreover we should also determine when we should start to use PCH for > imm assign messages and what we should do with agch_max_queue_length > in this case, what do you think about it? I would use PCH for AGCH messages, when there is not pending paging message. And I wouldn't use paging_add_imm_ass() but just call bts_agch_dequeue() when there is no paging message. I wouldn't do this in paging_gen_message() but outside of it, since it is no paging message. agch_max_queue_length should be based on ag_blks_res + gsm0502_get_n_pag_blocks() (or something delivering the same result) then. > 6. What do you finally think about calculating agch_max_queue_length? > What is the right way to calculate it from your point of view? I'm not sure yet. Since there is a direct relationship between number of RACH bursts and CCCH blocks per multiframe, there could be a way to simplify the calculation. One have to adjust it, if there are optional CCCH blocks that are not AGCH/PCH (like CBCH), but even if that is not taken into account, the error might be tolerable. Jacob From holger at freyther.de Sat Feb 8 14:42:18 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 8 Feb 2014 15:42:18 +0100 Subject: [PATCH 3/5] sms: Add a function to update DB scheme v3 to v4. In-Reply-To: <20131008100155.GD6194@xiaoyu.lan> References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-4-git-send-email-Alexander.Chemeris@gmail.com> <20131008100155.GD6194@xiaoyu.lan> Message-ID: <20140208144218.GB14201@xiaoyu.lan> On Tue, Oct 08, 2013 at 12:01:55PM +0200, Holger Hans Peter Freyther wrote: Hi Alexander, I would like to get this patchset included and I noticed that you have never followed up on this comment. > > +#define SMS_TABLE_CREATE_STMT \ > > Can you propose an alternative to move this out of the array? Couldn't you use ALTER TABLE from within a transaction? kind regards holger From alexander.chemeris at gmail.com Sat Feb 8 17:02:46 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Feb 2014 21:02:46 +0400 Subject: [PATCH 3/5] sms: Add a function to update DB scheme v3 to v4. In-Reply-To: <20140208144218.GB14201@xiaoyu.lan> References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-4-git-send-email-Alexander.Chemeris@gmail.com> <20131008100155.GD6194@xiaoyu.lan> <20140208144218.GB14201@xiaoyu.lan> Message-ID: Hi Holger, On Sat, Feb 8, 2014 at 6:42 PM, Holger Hans Peter Freyther wrote: > On Tue, Oct 08, 2013 at 12:01:55PM +0200, Holger Hans Peter Freyther wrote: > I would like to get this patchset included and I noticed that you > have never followed up on this comment. The code for the DB conversion doesn't work in the submitted form. I fixed this, but I haven't had enough time to port the patch to master. I could submit it, if someone wants to port it before I find the time to do this myself. So far we've been working with jolly-branches, as only they support OsmoTRX and thus UmTRX. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From holger at freyther.de Sun Feb 9 07:25:43 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Feb 2014 08:25:43 +0100 Subject: [PATCH 3/5] sms: Add a function to update DB scheme v3 to v4. In-Reply-To: References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-4-git-send-email-Alexander.Chemeris@gmail.com> <20131008100155.GD6194@xiaoyu.lan> <20140208144218.GB14201@xiaoyu.lan> Message-ID: <20140209072543.GC14419@xiaoyu.lan> On Sat, Feb 08, 2014 at 09:02:46PM +0400, Alexander Chemeris wrote: Dear Alexander, > The code for the DB conversion doesn't work in the submitted form. I > fixed this, but I haven't had enough time to port the patch to master. > I could submit it, if someone wants to port it before I find the time > to do this myself. So far we've been working with jolly-branches, as > only they support OsmoTRX and thus UmTRX. That is very sad to hear. I encourage you to finish your patch and the total number of patches of yours would raise to eight. Please try to contribute and finish this patch or at least just make your modification available to the community. holger From alexander.chemeris at gmail.com Sun Feb 9 09:28:05 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Feb 2014 13:28:05 +0400 Subject: [PATCH 3/5] sms: Add a function to update DB scheme v3 to v4. In-Reply-To: <20140209072543.GC14419@xiaoyu.lan> References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-4-git-send-email-Alexander.Chemeris@gmail.com> <20131008100155.GD6194@xiaoyu.lan> <20140208144218.GB14201@xiaoyu.lan> <20140209072543.GC14419@xiaoyu.lan> Message-ID: Hi Holger, On Sun, Feb 9, 2014 at 11:25 AM, Holger Hans Peter Freyther wrote: > On Sat, Feb 08, 2014 at 09:02:46PM +0400, Alexander Chemeris wrote: >> The code for the DB conversion doesn't work in the submitted form. I >> fixed this, but I haven't had enough time to port the patch to master. >> I could submit it, if someone wants to port it before I find the time >> to do this myself. So far we've been working with jolly-branches, as >> only they support OsmoTRX and thus UmTRX. > > That is very sad to hear. I'm glad that you share my sadness that jolly branches are not yet merged. I hope you'll find some time to continue reviewing the patchset for L1 parts, which jolly submitted quite a while ago. > I encourage you to finish your patch and > the total number of patches of yours would raise to eight. Thank you for beancounting for me :) In Russia we say "Never count money in someone's else pocket", I think s/money/patches/ and s/pocket/contribution/ would make a great saying for open-source world. As much as I love programming and contributing, at this moment I have to focus on enabling other people to contribute. I hope that one day I could give up my management tasks and dive deep into writing lots of code again. That said, I'm happy that Fairwaves is funding substantial amount of work on Osmocom, including OsmoPCU, OsmoTRX, UmTRX and a bit of OsmoBTS and OsmoNITB. And we're only increasing amounts of this funding, as well as attracting more community members. > Please try to contribute and finish this patch or at least just make > your modification available to the community. I realized, that this is actually the final working version of the patch. I took you so long to get back to it, so I was thinking it's the original patch which was broken. Feel free to merge this into master. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From holger at freyther.de Sun Feb 9 09:48:11 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Feb 2014 10:48:11 +0100 Subject: [PATCH 3/5] sms: Add a function to update DB scheme v3 to v4. In-Reply-To: References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-4-git-send-email-Alexander.Chemeris@gmail.com> <20131008100155.GD6194@xiaoyu.lan> <20140208144218.GB14201@xiaoyu.lan> <20140209072543.GC14419@xiaoyu.lan> Message-ID: <20140209094811.GF14419@xiaoyu.lan> On Sun, Feb 09, 2014 at 01:28:05PM +0400, Alexander Chemeris wrote: Hi, > I'm glad that you share my sadness that jolly branches are not yet > merged. I hope you'll find some time to continue reviewing the > patchset for L1 parts, which jolly submitted quite a while ago. but as you pointed out in the other SMS email, he needs to add tests and things like (errno == 111) is an obvious no go. > As much as I love programming and contributing, at this moment I have > to focus on enabling other people to contribute. I hope that one day I > could give up my management tasks and dive deep into writing lots of > code again. That said, I'm happy that Fairwaves is funding substantial > amount of work on Osmocom, including OsmoPCU, OsmoTRX, UmTRX and a bit > of OsmoBTS and OsmoNITB. And we're only increasing amounts of this > funding, as well as attracting more community members. Please stop the marketing here. But if you really want to help, maybe mentor Andreas and review his patches before it goes to the mailinglist. I have spent way too much time on this already, it is not economic for me to do his QA. I have cats to feed! > > Please try to contribute and finish this patch or at least just make > > your modification available to the community. > > I realized, that this is actually the final working version of the > patch. I took you so long to get back to it, so I was thinking it's > the original patch which was broken. Feel free to merge this into > master. It lacks a test case and the doubt if it works or not doesn't help either. But sure it is easy to demand things from others. ;) holger From alexander.chemeris at gmail.com Sun Feb 9 10:13:38 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Feb 2014 14:13:38 +0400 Subject: [PATCH 3/5] sms: Add a function to update DB scheme v3 to v4. In-Reply-To: <20140209094811.GF14419@xiaoyu.lan> References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-4-git-send-email-Alexander.Chemeris@gmail.com> <20131008100155.GD6194@xiaoyu.lan> <20140208144218.GB14201@xiaoyu.lan> <20140209072543.GC14419@xiaoyu.lan> <20140209094811.GF14419@xiaoyu.lan> Message-ID: On Sun, Feb 9, 2014 at 1:48 PM, Holger Hans Peter Freyther wrote: > On Sun, Feb 09, 2014 at 01:28:05PM +0400, Alexander Chemeris wrote: >> > Please try to contribute and finish this patch or at least just make >> > your modification available to the community. >> >> I realized, that this is actually the final working version of the >> patch. I took you so long to get back to it, so I was thinking it's >> the original patch which was broken. Feel free to merge this into >> master. > > It lacks a test case and the doubt if it works or not doesn't help > either. I doubt a unit-test is needed in this case, given the purpose of this code and that this code is more or less self-contained. If you want, you could try it yourself, but I have tested it on pretty large DB full of SMS messages. > But sure it is easy to demand things from others. ;) I propose this to be the Rule #1 for this mailing list :) "Don't demand others to do work for you." -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From holger at freyther.de Sun Feb 9 16:24:43 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Feb 2014 17:24:43 +0100 Subject: [PATCH 3/5] sms: Add a function to update DB scheme v3 to v4. In-Reply-To: References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-4-git-send-email-Alexander.Chemeris@gmail.com> <20131008100155.GD6194@xiaoyu.lan> <20140208144218.GB14201@xiaoyu.lan> <20140209072543.GC14419@xiaoyu.lan> <20140209094811.GF14419@xiaoyu.lan> Message-ID: <20140209162443.GA24178@xiaoyu.lan> On Sun, Feb 09, 2014 at 02:13:38PM +0400, Alexander Chemeris wrote: > > But sure it is easy to demand things from others. ;) > > I propose this to be the Rule #1 for this mailing list :) > "Don't demand others to do work for you." If it makes you happy. But remember how this request started. ;) From alexander.chemeris at gmail.com Sun Feb 9 09:14:23 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Feb 2014 13:14:23 +0400 Subject: [PATCH 3/5] sms: Add a function to update DB scheme v3 to v4. In-Reply-To: <20140208144218.GB14201@xiaoyu.lan> References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-4-git-send-email-Alexander.Chemeris@gmail.com> <20131008100155.GD6194@xiaoyu.lan> <20140208144218.GB14201@xiaoyu.lan> Message-ID: Hi Holger, On Sat, Feb 8, 2014 at 6:42 PM, Holger Hans Peter Freyther wrote: > On Tue, Oct 08, 2013 at 12:01:55PM +0200, Holger Hans Peter Freyther wrote: > > Hi Alexander, > > I would like to get this patchset included and I noticed that you > have never followed up on this comment. > >> > +#define SMS_TABLE_CREATE_STMT \ > >> >> Can you propose an alternative to move this out of the array? > > Couldn't you use ALTER TABLE from within a transaction? No, ALTER TABLE can't be used, because it can only add column in SQLIte and can't remove them. The whole twist with this code is to workaround this limitation. It was discussed a while ago in the original topic. Actually, I would propose to move all other statements in that array to #define's as well to make the code more readable. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From alexander.chemeris at gmail.com Sun Feb 9 09:15:45 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Feb 2014 13:15:45 +0400 Subject: [PATCH 3/5] sms: Add a function to update DB scheme v3 to v4. In-Reply-To: References: <1381195053-10325-1-git-send-email-Alexander.Chemeris@gmail.com> <1381195053-10325-4-git-send-email-Alexander.Chemeris@gmail.com> <20131008100155.GD6194@xiaoyu.lan> <20140208144218.GB14201@xiaoyu.lan> Message-ID: On Sun, Feb 9, 2014 at 1:14 PM, Alexander Chemeris wrote: > Hi Holger, > > On Sat, Feb 8, 2014 at 6:42 PM, Holger Hans Peter Freyther > wrote: >> On Tue, Oct 08, 2013 at 12:01:55PM +0200, Holger Hans Peter Freyther wrote: >> >> Hi Alexander, >> >> I would like to get this patchset included and I noticed that you >> have never followed up on this comment. >> >>> > +#define SMS_TABLE_CREATE_STMT \ >> >>> >>> Can you propose an alternative to move this out of the array? >> >> Couldn't you use ALTER TABLE from within a transaction? > > No, ALTER TABLE can't be used, because it can only add column in > SQLIte and can't remove them. The whole twist with this code is to > workaround this limitation. It was discussed a while ago in the > original topic. > > Actually, I would propose to move all other statements in that array > to #define's as well to make the code more readable. Btw, I did reply to this question earlier in the thread. :) My original reply was: Frankly speaking, I would move _all_ these statements to separate #defines, to make the code clearer. And no, I don't see a better way to do that. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From andreas at eversberg.eu Sat Feb 1 11:31:10 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sat, 01 Feb 2014 12:31:10 +0100 Subject: [PATCH 6/9] Adding traffic forwarding via RTP to remote application In-Reply-To: <20140129100407.GA29223@xiaoyu.lan> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-6-git-send-email-jolly@eversberg.eu> <20140129100407.GA29223@xiaoyu.lan> Message-ID: <52ECDAFE.2020302@eversberg.eu> Holger Hans Peter Freyther wrote: hi holger, >> +#define MNCC_RTP_CREATE 0x0204 >> +#define MNCC_RTP_CONNECT 0x0205 >> +#define MNCC_RTP_FREE 0x0206 > Increase the version. We have a uint32_t for the version number and > it will take a while to overflow it. i already did it. but thanks for reminding me, so i did it also for the attached patch: 0001-Complete-definitions-for-all-speech-traffic-frames-a.patch >> + RTP_PROXY, /* forward from BTS to BTS */ >> + RTP_RECV_UPSTREAM, /* forward to L4 application */ >> + RTP_RECV_L4, /* receive RTP frames from L4 application */ > L4? is that the best name you can think off? for signalling messages (mncc application) it makes sense. for rtp it might lead to misunderstanding i changed that in the attached patch: 0006-Adding-traffic-forwarding-via-RTP-to-remote-applicat.patch > There are already methods for "is IP based BTS", "is E1 based BTS". Couldn't > you use them here? makes sense. i updated the patch above using this is_e1_bts() macro. >> + /* L4 uses RTP for this transaction, we send our data via RTP, >> + * otherwise we send it through MNCC interface */ >> + if (msg_type == GSM_TCHF_FRAME >> + || msg_type == GSM_TCHF_FRAME_EFR >> + || msg_type == GSM_TCHH_FRAME >> + || msg_type == GSM_TCH_FRAME_AMR >> + || msg_type == GSM_BAD_FRAME) { > > I have seen lchan->type checks and message type checks like these as well. > Could you create a predicate function that check mncc_is_audio_message(), or > lchan_voice_chan? this was already done mncc_is_data_frame() check in a later patch of jolly/testing branch. i rebased my testing branch, so the patch is prior the other patches now: (see 0002-Use-helper-function-to-check-if-an-MNCC-frame-is-dat.patch). the other patches changed a bit, due to rebase and some other improvements. i do not want to post them again, so please refer to jolly/testing branch. if wanted, i will post them. best regards, andreas From holger at freyther.de Sun Feb 9 09:31:15 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Feb 2014 10:31:15 +0100 Subject: [PATCH 6/9] Adding traffic forwarding via RTP to remote application In-Reply-To: <52ECDAFE.2020302@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-6-git-send-email-jolly@eversberg.eu> <20140129100407.GA29223@xiaoyu.lan> <52ECDAFE.2020302@eversberg.eu> Message-ID: <20140209093115.GD14419@xiaoyu.lan> On Sat, Feb 01, 2014 at 12:31:10PM +0100, Andreas Eversberg wrote: Dear Andreas, it is difficult to pick the patches from the right reply. Please re-base your branch and send the current patches you think are ready again. thanks holger From andreas at eversberg.eu Sat Feb 15 15:39:40 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sat, 15 Feb 2014 16:39:40 +0100 Subject: [PATCH 6/9] Adding traffic forwarding via RTP to remote application In-Reply-To: <20140209093115.GD14419@xiaoyu.lan> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-6-git-send-email-jolly@eversberg.eu> <20140129100407.GA29223@xiaoyu.lan> <52ECDAFE.2020302@eversberg.eu> <20140209093115.GD14419@xiaoyu.lan> Message-ID: <52FF8A3C.8020804@eversberg.eu> Holger Hans Peter Freyther wrote: > it is difficult to pick the patches from the right reply. Please > re-base your branch and send the current patches you think are > ready again. hi holger, i rebased my patches, but the "make distcheck" fails: make[3]: Entering directory `/files/projects/gsm/openbsc/openbsc/tests/mgcp' CC mgcp_test.o CCLD mgcp_test mgcp_test.o: In function `test_packet_error_detection': /files/projects/gsm/openbsc/openbsc/tests/mgcp/mgcp_test.c:804: undefined reference to `llround' i see that at Makefile.am the "-lm" is used to link math library. any idea? best regards, andreas From andreas at eversberg.eu Sun Feb 2 12:09:15 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sun, 02 Feb 2014 13:09:15 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <52EAAF51.9020203@sysmocom.de> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> <20140122102150.3862.qmail@stuge.se> <52E0F4C3.6070106@eversberg.eu> <52EA306F.4000002@sysmocom.de> <20140130154305.22908.qmail@stuge.se> <52EAAF51.9020203@sysmocom.de> Message-ID: <52EE356B.60201@eversberg.eu> Jacob Erlbeck wrote: dear jacob, > void tv_add_us(tv, usec) { > struct timeval foo; > foo.tv_sec = usec / 1000000; > foo.tv_usec = usec % 1000000; > > timeradd(tv, &foo, tv); > } > Which I then would write as > > tv_add_us(&rs->transmit.last_tv, USEC_20MS); > tv_add_us(&rs->transmit.last_tv, sample_diff_excess * USEC_SAMPLE); > > And thanks to inlining the div/mod would vanish completely in the first > case and would be without extra cost in the second. So no performance > penalty but much better readability. this makes sense. it simplifies things. i implemented it. by getting rid of negative usecs, there is no more issue about correctly decrementing the timeval. > And did you understand the second application of tv_add() at first > sight? It is correct but that is not obvious IMO. the first implementation increments last_tv by the duration of one frame. (20ms) if too much time have been elapsed since when the last frame has been processed, the last_tv is additionally incremented by the duration of frames that have been missed since then. also the RTP timestamp and sequence number is incremented accordingly. holger mentioned that you also had a problem with speech frames in conjunction with ipaccess BTS. was it a similar problem? how did you solve this? best regards, andreas From jerlbeck at sysmocom.de Mon Feb 10 09:22:47 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 10 Feb 2014 10:22:47 +0100 Subject: [PATCH 8/9] Fixed (nanoBTS) delay problems, if RTP stream jitters too much In-Reply-To: <52EE356B.60201@eversberg.eu> References: <1390381558-20914-1-git-send-email-jolly@eversberg.eu> <1390381558-20914-8-git-send-email-jolly@eversberg.eu> <20140122102150.3862.qmail@stuge.se> <52E0F4C3.6070106@eversberg.eu> <52EA306F.4000002@sysmocom.de> <20140130154305.22908.qmail@stuge.se> <52EAAF51.9020203@sysmocom.de> <52EE356B.60201@eversberg.eu> Message-ID: <52F89A67.9070700@sysmocom.de> Dear Andreas, On 02.02.2014 13:09, Andreas Eversberg wrote: > > holger mentioned that you also had a problem with speech frames in > conjunction with ipaccess BTS. was it a similar problem? how did you > solve this? that BTS silently drops frames that do not have a RTP timestamp of T0 + 160 * k, where T0 is the first timestamp (I ignore the modulo here). In addition it ceases to transmit audio from RTP if there is a pause (e.g. no RTP for >1s) but the timestamps are not incremented accordingly (probably because they've been considered to be too late). In short: that BTS expects proper timestamps. I've solved this by optionally allowing the MGCP daemon to enforce the 160*k requirement by rounding the timestamp towards the next valid one. In addition, when SSRCs are patched, the new timestamp offset is calculated based on (monotonic) system time that has passed between the last packet of the old SSRC and the first of the new. Since the RTP timestamp problems only happened when the network side switched streams (and thus luckily SSRCs), this was sufficient. In theory, the BTS should be able to detect SSRC changes and reset its timing accordingly. But since this is not the case with that BTS, those workarounds are neccessary :-( Cheers Jacob From holger at freyther.de Mon Feb 3 07:14:23 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 3 Feb 2014 08:14:23 +0100 Subject: LAPDm code issues (ladpm.c) In-Reply-To: <52E7BB6A.6060708@sysmocom.de> References: <52E7BB6A.6060708@sysmocom.de> Message-ID: <20140203071423.GF17408@xiaoyu.lan> On Tue, Jan 28, 2014 at 03:15:06PM +0100, Jacob Erlbeck wrote: Dear Andras, could you please have a look at the code, the branch by Jacob and the outstanding issues. > The initial SABM message (not the retransmitted one after T200) has a > non-zero length and ends with 3 bytes that have been taken from the end > of the RSL EST REQ message. The MS does not answer to this. > Interestingly the second SABM message that gets sent after T200 (2s) has > a length field of 0 and no trailing garbage. This is a very subtle bug. In the end SMS transfer works but it needed one timeout/retransmission cycle for it to work. It was also non obvious to find as lapd_core/lapdm use two/three different ways to describe the payload size (it is the kind of problems I want to avoid with the trx_id in libosmo-abis). Jacob will be out of office this week but you might catch up with him next week to resolve the defects/invariant violations. cheers holger From andreas at eversberg.eu Mon Feb 3 08:53:23 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Mon, 03 Feb 2014 09:53:23 +0100 Subject: LAPDm code issues (ladpm.c) In-Reply-To: <20140203071423.GF17408@xiaoyu.lan> References: <52E7BB6A.6060708@sysmocom.de> <20140203071423.GF17408@xiaoyu.lan> Message-ID: <52EF5903.6020105@eversberg.eu> Holger Hans Peter Freyther wrote: > could you please have a look at the code, the branch by Jacob and > the outstanding issues. > > >> >The initial SABM message (not the retransmitted one after T200) has a >> >non-zero length and ends with 3 bytes that have been taken from the end >> >of the RSL EST REQ message. The MS does not answer to this. >> >Interestingly the second SABM message that gets sent after T200 (2s) has >> >a length field of 0 and no trailing garbage. > This is a very subtle bug. In the end SMS transfer works but it > needed one timeout/retransmission cycle for it to work. It was also > non obvious to find as lapd_core/lapdm use two/three different ways > to describe the payload size (it is the kind of problems I want to > avoid with the trx_id in libosmo-abis). dear holger, dear jacob, i 'wiresharked' this bug. there is actually 3 bytes of payload within the first SABM message. with the jerlbeck/fixes/ladp-sms branch, the message is correct and accepted by the phone. (no retransmission) it is clear to me that removing everything in front of the l3h (msg) must be performed. we can't just remove data between l2h and l3h and assume that there is nothing in front of the l2h. so i agree with the patch in that branch. best regards, andreas From jerlbeck at sysmocom.de Wed Feb 12 11:40:07 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Wed, 12 Feb 2014 12:40:07 +0100 Subject: LAPDm code issues (ladpm.c) In-Reply-To: <52E7BB6A.6060708@sysmocom.de> References: <52E7BB6A.6060708@sysmocom.de> Message-ID: <52FB5D97.8050109@sysmocom.de> Dear Andreas, what do you think about the other issues? My patch has not fixed all possible problems that could arise from additional l1 headers (see below). On 28.01.2014 15:15, Jacob Erlbeck wrote: > > But AFAICS there is still something to do: > > - The remaining msgb_pull() need to be checked (at least the one in > l2_ph_data_ind() looks suspicious to me. > - L3 length computation should be done with the macros, how it is done > in lapdm_send_ph_data_req() is broken. > - Why does lapd_msg_ctx have a length field that is not used? > - ladp_test.c should be extended to check other execution paths, too. > I've tried it for dummy packets and I didn't get it working without > failing assertions (see below) The following applies to most sub-projects, but I find it hard to diagnose and use function calls if their API is not documented beyond parameter names and types. Especially when passing a msgb to a function it would really help if there was some documentation telling about which parts of the msgb are used (as in "l2 is expected to point to the start of the XYZ message"): > - How l2/data/.. in a msg are expected to be used/set should be > documented somewhere. Best wishes Jacob > > ====== > > The following patch still breaks the assertions, at least changing the > l3len computation in lapdm_send_ph_data_req() influences but doesn't fix > it. > > --- a/tests/lapd/lapd_test.c > +++ b/tests/lapd/lapd_test.c > @@ -123,8 +123,10 @@ static struct msgb *create_empty_msg(void) > static struct msgb *create_dummy_data_req(void) > { > struct msgb *msg; > + const int dummy_l1len = 3; > > msg = msgb_from_array(dummy1, sizeof(dummy1)); > + msgb_push(msg, dummy_l1len); > rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1); > return msg; > } > > > > > > > From andreas at eversberg.eu Sat Feb 15 09:25:56 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Sat, 15 Feb 2014 10:25:56 +0100 Subject: LAPDm code issues (ladpm.c) In-Reply-To: <52FB5D97.8050109@sysmocom.de> References: <52E7BB6A.6060708@sysmocom.de> <52FB5D97.8050109@sysmocom.de> Message-ID: <52FF32A4.6040808@eversberg.eu> hi jacob, Jacob Erlbeck wrote: > - The remaining msgb_pull() need to be checked (at least the one in > l2_ph_data_ind() looks suspicious to me. the msgb_pull() should actually pull the space between data and l2h (after adding 2), but it assumes that there is no l1 header in front. i suggest to remove the pull: - msgb_pull(msg, 2); msg->l2h += 2; no pull, because the space between data and l3h is removed afterwards in the same function. > - L3 length computation should be done with the macros, how it is done > in lapdm_send_ph_data_req() is broken. what is actually broken? i see that l3_len is the complete msgb space between data and tail. > - Why does lapd_msg_ctx have a length field that is not used? i guess it was used in early code (when osmocombb project started), but it is actually not required. > - ladp_test.c should be extended to check other execution paths, too. > I've tried it for dummy packets and I didn't get it working without > failing assertions (see below) > The following applies to most sub-projects, but I find it hard to > diagnose and use function calls if their API is not documented beyond > parameter names and types. Especially when passing a msgb to a function > it would really help if there was some documentation telling about which > parts of the msgb are used (as in "l2 is expected to point to the start > of the XYZ message"): >> - How l2/data/.. in a msg are expected to be used/set should be >> documented somewhere. each msg has l1h, l2h and l3h pointers. the logical way is (even if it is currently not implemented correctly): frames that are received from lower layer 1 should have l2h set and may have l1 header or not. (layer 2 is not responsible of l1 header, so we should ignore it.) l3h must not be set, since layer 1 does not know about any l3 header start. the l2_ph_data_ind() function should parse the l2h, set l3h and remove everything up to l3h. frames that are sent to lower layer 1 should have l2h and l3h set before sending to layer 1. see lapdm_send_ph_data_req(). > The following patch still breaks the assertions, at least changing the > l3len computation in lapdm_send_ph_data_req() influences but doesn't fix > it. > > --- a/tests/lapd/lapd_test.c > +++ b/tests/lapd/lapd_test.c > @@ -123,8 +123,10 @@ static struct msgb *create_empty_msg(void) > static struct msgb *create_dummy_data_req(void) > { > struct msgb *msg; > + const int dummy_l1len = 3; > > msg = msgb_from_array(dummy1, sizeof(dummy1)); > + msgb_push(msg, dummy_l1len); > rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1); > return msg; > } push the dummy_l1 header after pushing RLL header: msg = msgb_from_array(dummy1, sizeof(dummy1)); rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1); + msgb_push(msg, dummy_l1len); - first the msg is allocated and filled with array. l3h is set. - rsl_rll_push_l3 pushes the layer 3 information element and the RLL header in front of the msg and sets l2h. - at least msgb_push adds the dummy_l1 header in front of everything. l1h is not set, but it is not relevant, since l1 header is ignored by lapdm. best regards, andreas From jerlbeck at sysmocom.de Fri Feb 21 09:12:03 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 21 Feb 2014 10:12:03 +0100 Subject: LAPDm code issues (ladpm.c) In-Reply-To: <52FF32A4.6040808@eversberg.eu> References: <52E7BB6A.6060708@sysmocom.de> <52FB5D97.8050109@sysmocom.de> <52FF32A4.6040808@eversberg.eu> Message-ID: <53071863.5030503@sysmocom.de> Hello Andreas On 15.02.2014 10:25, Andreas Eversberg wrote: > > Jacob Erlbeck wrote: > >> - L3 length computation should be done with the macros, how it is done >> in lapdm_send_ph_data_req() is broken. > what is actually broken? i see that l3_len is the complete msgb space > between data and tail. The line uint8_t l3_len = msg->tail - msg->data; delivers the correct result, that's not the point. But here are 2 different things being mixed: - the l3 length definition: l3_len = msg->tail - msg->l3h (AKA msgb_l3len()) - the assumption that msg->data == msg->l3h Mixing things this way is IMO conceptually broken and hard to maintain. According to your statement below ("frames that are sent to lower layer 1 should have l2h and l3h set [...]"), l3h must have been set when lapdm_send_ph_data_req() is entered. The requirement data == l3h on the other hand is more than requested in general, and it would be helpful if it was documented and/or asserted. >> - Why does lapd_msg_ctx have a length field that is not used? > i guess it was used in early code (when osmocombb project started), but > it is actually not required. So it can be removed completely? >>> - How l2/data/.. in a msg are expected to be used/set should be >>> documented somewhere. > each msg has l1h, l2h and l3h pointers. the logical way is (even if it > is currently not implemented correctly): > > frames that are received from lower layer 1 should have l2h set and may > have l1 header or not. (layer 2 is not responsible of l1 header, so we > should ignore it.) l3h must not be set, since layer 1 does not know > about any l3 header start. the l2_ph_data_ind() function should parse > the l2h, set l3h and remove everything up to l3h. > > frames that are sent to lower layer 1 should have l2h and l3h set before > sending to layer 1. see lapdm_send_ph_data_req(). What about putting such definitions somewhere central (e.g. wiki or top of msgb.h)? > push the dummy_l1 header after pushing RLL header: > > msg = msgb_from_array(dummy1, sizeof(dummy1)); > rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, 0, 0, 1); > + msgb_push(msg, dummy_l1len); > > > - first the msg is allocated and filled with array. l3h is set. > - rsl_rll_push_l3 pushes the layer 3 information element and the RLL > header in front of the msg and sets l2h. > - at least msgb_push adds the dummy_l1 header in front of everything. > l1h is not set, but it is not relevant, since l1 header is ignored by > lapdm. Thank you, that makes sense. Jacob From holger at freyther.de Mon Feb 3 08:13:36 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 3 Feb 2014 09:13:36 +0100 Subject: [PATCH 2/5] mgcp/test: Fake wallclock for RTP timing/stats tests In-Reply-To: <1391112096-4059-2-git-send-email-jerlbeck@sysmocom.de> References: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> <1391112096-4059-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140203081336.GH17408@xiaoyu.lan> On Thu, Jan 30, 2014 at 09:01:33PM +0100, Jacob Erlbeck wrote: Good Morning Jacob, > Currently the stats (jitter, transit) cannot be checked properly, > since they depend on the wallclock time. there is an issue on AMD64. Please have a look. I am not sure where the difference of one would come from. The build failed on the OBS but also on the AMD64 machine in the office. @@ -90,28 +90,28 @@ Stats: Jitter = 0, Transit = 0 In TS: 160, dTS: 160, Seq: 1 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 8, Transit = 4294967155 +Stats: Jitter = 8, Transit = 4294967156 In TS: 320, dTS: 160, Seq: 2 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 -Stats: Jitter = 17, Transit = 4294967015 +Stats: Jitter = 16, Transit = 4294967016 From holger at freyther.de Mon Feb 3 08:17:09 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 3 Feb 2014 09:17:09 +0100 Subject: [PATCH 2/5] mgcp/test: Fake wallclock for RTP timing/stats tests In-Reply-To: <20140203081336.GH17408@xiaoyu.lan> References: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> <1391112096-4059-2-git-send-email-jerlbeck@sysmocom.de> <20140203081336.GH17408@xiaoyu.lan> Message-ID: <20140203081709.GI17408@xiaoyu.lan> On Mon, Feb 03, 2014 at 09:13:36AM +0100, Holger Hans Peter Freyther wrote: > On Thu, Jan 30, 2014 at 09:01:33PM +0100, Jacob Erlbeck wrote: > > Good Morning Jacob, > > > > Currently the stats (jitter, transit) cannot be checked properly, > > since they depend on the wallclock time. > > there is an issue on AMD64. Please have a look. I am not sure where > the difference of one would come from. The build failed on the OBS > but also on the AMD64 machine in the office. int32_t transit is printed with %u and GCC gives no compiler warning about this. :} From jerlbeck at sysmocom.de Mon Feb 10 10:20:56 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 10 Feb 2014 11:20:56 +0100 Subject: [PATCH 2/5] mgcp/test: Fake wallclock for RTP timing/stats tests In-Reply-To: <20140203081336.GH17408@xiaoyu.lan> References: <1391112096-4059-1-git-send-email-jerlbeck@sysmocom.de> <1391112096-4059-2-git-send-email-jerlbeck@sysmocom.de> <20140203081336.GH17408@xiaoyu.lan> Message-ID: <52F8A808.1060200@sysmocom.de> Hi Holger, On 03.02.2014 09:13, Holger Hans Peter Freyther wrote: > there is an issue on AMD64. Please have a look. I am not sure where > the difference of one would come from. The build failed on the OBS > but also on the AMD64 machine in the office. Thanks a lot for looking into and fixing that in cdfc2061bb et al. Jacob From holger at freyther.de Mon Feb 3 06:53:03 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Mon, 3 Feb 2014 07:53:03 +0100 Subject: osmoSGSN In-Reply-To: References: Message-ID: <20140203065303.GD17408@xiaoyu.lan> On Fri, Jan 31, 2014 at 04:10:50PM +0100, Michal Grzn?r wrote: Good Morning, > Hi, I am trying to use osmoSGSN in topology with openGGSN and sim-bss, > which is simulator of BSS made by company Alcatel-Lucent. I have a problem > that my osmoSGSN can not communicate with sim-BSS and it can not connect > correctly. It is caused by non function bssgp. I would like to ask you, how > can I configure bssgp on osmoSGSN? I can configure ns states also from vty > on osmoSGSN but I can not bssgp states such as bvci etc...Please could you > help me? I hope you will reply me soon. can you provide access to that BSS simulator. Have you taken a packet trace and looked at what the system actually sent? Please share a PCAP file. holger From mihal.grznar at gmail.com Mon Feb 10 23:37:19 2014 From: mihal.grznar at gmail.com (=?ISO-8859-1?Q?Michal_Grzn=E1r?=) Date: Tue, 11 Feb 2014 00:37:19 +0100 Subject: osmoSGSN In-Reply-To: <20140203065303.GD17408@xiaoyu.lan> References: <20140203065303.GD17408@xiaoyu.lan> Message-ID: I share the pcap file from communication, IP address of BSS is 74.33.6.1 and IP address of osmo-sgsn is 74.33.9.1...The first problem was, that sgsn didn?t create funcional NS-VC but after a configuration from vty this was solved, but NS-VC seems to become blocked after BVC-reset message from bss....I can not share binary files of sim-bss cause it is out of my possibilities... Michal 2014-02-03 7:53 GMT+01:00 Holger Hans Peter Freyther : > On Fri, Jan 31, 2014 at 04:10:50PM +0100, Michal Grzn?r wrote: > > Good Morning, > > > Hi, I am trying to use osmoSGSN in topology with openGGSN and sim-bss, > > which is simulator of BSS made by company Alcatel-Lucent. I have a > problem > > that my osmoSGSN can not communicate with sim-BSS and it can not connect > > correctly. It is caused by non function bssgp. I would like to ask you, > how > > can I configure bssgp on osmoSGSN? I can configure ns states also from > vty > > on osmoSGSN but I can not bssgp states such as bvci etc...Please could > you > > help me? I hope you will reply me soon. > > can you provide access to that BSS simulator. Have you taken a packet > trace and looked at what the system actually sent? Please share a PCAP > file. > > holger > > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: osmo.pcap Type: application/octet-stream Size: 411 bytes Desc: not available URL: From mihal.grznar at gmail.com Wed Feb 12 00:57:27 2014 From: mihal.grznar at gmail.com (=?ISO-8859-1?Q?Michal_Grzn=E1r?=) Date: Wed, 12 Feb 2014 01:57:27 +0100 Subject: osmoSGSN In-Reply-To: References: <20140203065303.GD17408@xiaoyu.lan> Message-ID: and in osmoSGSN vty there is <0010> gprs_ns.c: 193 NSVCI=12345 Creating NS-VC <0010> gprs_ns.c: 378 NSEI=65534 Tx NS STATUS (NSVCI=12345, cause=NS-VC blocked) anybody, who could know what can be the problem there please? thanks a lot Michal 2014-02-11 0:37 GMT+01:00 Michal Grzn?r : > I share the pcap file from communication, IP address of BSS is 74.33.6.1 > and IP address of osmo-sgsn is 74.33.9.1...The first problem was, that sgsn > didn?t create funcional NS-VC but after a configuration from vty this was > solved, but NS-VC seems to become blocked after BVC-reset message from > bss....I can not share binary files of sim-bss cause it is out of my > possibilities... > > Michal > > > 2014-02-03 7:53 GMT+01:00 Holger Hans Peter Freyther : > > On Fri, Jan 31, 2014 at 04:10:50PM +0100, Michal Grzn?r wrote: >> >> Good Morning, >> >> > Hi, I am trying to use osmoSGSN in topology with openGGSN and sim-bss, >> > which is simulator of BSS made by company Alcatel-Lucent. I have a >> problem >> > that my osmoSGSN can not communicate with sim-BSS and it can not connect >> > correctly. It is caused by non function bssgp. I would like to ask you, >> how >> > can I configure bssgp on osmoSGSN? I can configure ns states also from >> vty >> > on osmoSGSN but I can not bssgp states such as bvci etc...Please could >> you >> > help me? I hope you will reply me soon. >> >> can you provide access to that BSS simulator. Have you taken a packet >> trace and looked at what the system actually sent? Please share a PCAP >> file. >> >> holger >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ralph at schmid.xxx Mon Feb 3 12:06:10 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Mon, 3 Feb 2014 13:06:10 +0100 Subject: GPRS vs. voice with openbsc Message-ID: <00f401cf20d8$53b688d0$fb239a70$@schmid.xxx> Hi out there, I am using OpenBTS with an USRP1, so not absolutely on-topic here, but I have here some effects with GPRS that are a bit annoying, and I would like to ask if something similar is known with the openbsc familiy when using GPRS. GPRS works, but with a reduced operating distance. While voice and SMS work over 200m (USRP1, WBX, small omni antennae) GPRS stops after 20-25 m, when downlink level is around -70dBm. Digging a bit deeper showed me that GPRS uses a somehow strange power control model, not a closed loop but a kind of dedicated guess, derived from the downlink RSSI at the ME. Setting the corresponding gamma value has a strong influence, but even with its lowest value I do not reach more than those 25m, and I can reduce the operating range to 2m with it. Playing with rxgain and other parameters did not really improve things. Is similar behavior known with the openbsc familiy GSM systems? I even know similar effects from commercial operators (O2 Germany with EDGE), not knowing if it is the same issue or something completely different. A first glance at some documents showed me that this power level calculation seems to be normal - is there really no closed loop for GPRS available? With best regards Ralph. From andreas at eversberg.eu Mon Feb 3 12:42:07 2014 From: andreas at eversberg.eu (Andreas Eversberg) Date: Mon, 03 Feb 2014 13:42:07 +0100 Subject: GPRS vs. voice with openbsc In-Reply-To: <00f401cf20d8$53b688d0$fb239a70$@schmid.xxx> References: <00f401cf20d8$53b688d0$fb239a70$@schmid.xxx> Message-ID: <52EF8E9F.2040105@eversberg.eu> Ralph A. Schmid, dk5ras wrote: > Digging a bit deeper showed me that GPRS uses a somehow strange power > control model, not a closed loop but a kind of dedicated guess, derived from > the downlink RSSI at the ME. Setting the corresponding gamma value has a > strong influence, but even with its lowest value I do not reach more than > those 25m, and I can reduce the operating range to 2m with it. Playing with > rxgain and other parameters did not really improve things. hi ralph, maybe try this: use a gamma of 0. (this means that the maximum power of your phone is not reduced.) use an alpha of 0. (this means no reduction depending on the downlink RSSI.) also be sure to set MS_TXPWR_MAX_CCH to 33dbm, so the maximum allowed output power of the mobile is 2w, if supported. (at openbsc the parameter is "ms max power 33") best regards, andreas From ralph at schmid.xxx Mon Feb 3 15:35:28 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Mon, 3 Feb 2014 16:35:28 +0100 Subject: GPRS vs. voice with openbsc In-Reply-To: <52EF8E9F.2040105@eversberg.eu> References: <00f401cf20d8$53b688d0$fb239a70$@schmid.xxx> <52EF8E9F.2040105@eversberg.eu> Message-ID: <000101cf20f5$911ce4e0$b356aea0$@schmid.xxx> > maybe try this: > use a gamma of 0. (this means that the maximum power of your phone is not This I already am using, with only partial success, reaching about 10% coverage, compared to voice. > reduced.) use an alpha of 0. (this means no reduction depending on the With the alpha I did not yet play very much, has to be tested this evening :) > downlink RSSI.) also be sure to set MS_TXPWR_MAX_CCH to 33dbm, so the > maximum allowed output power of the mobile is 2w, if supported. (at > openbsc the parameter is "ms max power 33") My license allows only 100mW :) Anyway, this leads to jamming the receiver when nearby subscribers drive the AGC (?) into limiting the signal, and not recovering fast enough to decode the next (weaker) timeslot. > best regards, > > andreas Ralph. From alexander.chemeris at gmail.com Mon Feb 3 13:04:19 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 3 Feb 2014 17:04:19 +0400 Subject: GPRS vs. voice with openbsc In-Reply-To: <00f401cf20d8$53b688d0$fb239a70$@schmid.xxx> References: <00f401cf20d8$53b688d0$fb239a70$@schmid.xxx> Message-ID: Ralph, On Mon, Feb 3, 2014 at 4:06 PM, Ralph A. Schmid, dk5ras wrote: > Digging a bit deeper showed me that GPRS uses a somehow strange power > control model, not a closed loop but a kind of dedicated guess, derived from > the downlink RSSI at the ME. GPRS has two modes of operation - closed loop and open loop. What you're describing here and what is implemented in both OpenBTS and OsmoPCU. I'm pretty sure that commercial networks use closed loop control nowadays, and it's a TBD item in OsmoPCU. > Is similar behavior known with the openbsc familiy GSM systems? I even know > similar effects from commercial operators (O2 Germany with EDGE), not > knowing if it is the same issue or something completely different. It's a different issue with EDGE. EDGE uses 8-PSK modulation scheme, which is a bit more more sensitive to noise than GMSK and thus may not work at the edge of coverage. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From ralph at schmid.xxx Mon Feb 3 15:31:47 2014 From: ralph at schmid.xxx (Ralph A. Schmid, dk5ras) Date: Mon, 3 Feb 2014 16:31:47 +0100 Subject: GPRS vs. voice with openbsc In-Reply-To: References: <00f401cf20d8$53b688d0$fb239a70$@schmid.xxx> Message-ID: <000001cf20f5$0d5bcc70$28136550$@schmid.xxx> Hi, > GPRS has two modes of operation - closed loop and open loop. What you're > describing here and what is implemented in both OpenBTS and OsmoPCU. > I'm pretty sure that commercial networks use closed loop control nowadays, > and it's a TBD item in OsmoPCU. OK, I understand. > It's a different issue with EDGE. > EDGE uses 8-PSK modulation scheme, which is a bit more more sensitive to > noise than GMSK and thus may not work at the edge of coverage. Well, it is only with one operator, and the problem came up when they implemented EDGE, it only worked when you could see the BTS. Others have EDGE running until the end of coverage without any problems :) > -- > Regards, > Alexander Chemeris. Ralph. From diegoferalonso at gmail.com Mon Feb 3 12:31:44 2014 From: diegoferalonso at gmail.com (Diego Fernandez Alonso) Date: Mon, 3 Feb 2014 13:31:44 +0100 Subject: Calls from BTS to PTSN planification doubts Message-ID: Hello, my name is Diego. I've a configurated sysmoBTS in OpenBSC network-in-the-box (NITB) mode, and the osmo-nitb is working fine, doing and receiving calls and messages between the phones connected to the sysmoBTS network. At this point I would need to call outside the OpenBSC, and I would be very gratefull if someone could help me with some doubts I have. I'm new in this. For the isdn card capable of NT-mode, I've seen the "OpenVox B200P 2-port ISDN BRI PCI" card for buying, but: 1-An "OpenVox B100P ISDN BRI PCI" card, with only one RJ45 female connector, could be used correctly, working together with an already installed PCI Ethernet Controller card? Or, is it better an isdn card with two RJ45 connectors in the same card? One for connecting the BTS to the computer, and the another for connecting the computer to a LAN through a router or switch? I would like to avoid to cut cables as the LCR guide says, http://isdn.eversberg.eu/download/doc-1.4/linux-call-router-1.4_1.pdf, and the problems with the cross over and not crossed cables. 2-The "Howto OpenBSC with Asterisk and LCR" guide, http://openbsc.osmocom.org/trac/wiki/OpenBSC_LCR, indicates that it's necessary compile and install LibOsmocore and OpenBSC, but the OpenBSC/OsmoNITB inside the sysmoBTS is working, so I'm not sure about this step. If the solution is to build, configure and run OpenBSC/OsmoNITB + OsmoSGSN + OpenGGSN on a PC and configure the sysmoBTS to connect to this, should I change the image of the BTS and its whole configuration? 3-Although I don't have the isdn card yet, for testing some configurations in the PC I followed the "Building and Running OpenBSC with Asterisk" Pierre Kim guide, that I believe is newer than the "How to OpenBSC with Asterisk and LCR", and I haven't problems with the installations. So if I run the lcr: # lcr start ** LCR Version 1.14 LCR 1.14 started, waiting for calls... and running the osmo-nitb: # ./osmo-nitb -m -P DB: Database initialized. DB: Database prepared. My question in this point, is it only necessary to connect the BTS to the isdn card with the right OpenBSC to finish the system configuration? Many thanks for your time and for your work. Kindest regards, Diego. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.chemeris at gmail.com Mon Feb 3 13:22:13 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Mon, 3 Feb 2014 17:22:13 +0400 Subject: Calls from BTS to PTSN planification doubts In-Reply-To: References: Message-ID: Diego, On Mon, Feb 3, 2014 at 4:31 PM, Diego Fernandez Alonso wrote: > 3-Although I don?t have the isdn card yet, for testing some configurations > in the PC I followed the ?Building and Running OpenBSC with Asterisk? Pierre > Kim guide, that I believe is newer than the ?How to OpenBSC with Asterisk > and LCR?, and I haven?t problems with the installations. So if I run the > lcr: > [....] > My question in this point, is it only necessary to connect the BTS to the > isdn card with the right OpenBSC to finish the system configuration? If you want to have calls being routed through SIP, you don't need an ISDN card. Your steps are: 1. Configure OsmoNITB with "-m" command line parameter to enable MNCC call routing. 2. Compile LCR with SIP support and without Asterisk support. 3. Configure LCR to run in a "bridge" mode between the GSM and SIP interfaces. 4. Run LCR on the _same_ machine as your OsmoNITB. 5. If you correctly configured LCR's SIP interface, all calls will be routed through your Asterisk/Freeswitch. Looks for more details here: https://openbsc.osmocom.org/trac/wiki/network_from_scratch -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From holger at freyther.de Wed Feb 5 08:27:06 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Wed, 5 Feb 2014 09:27:06 +0100 Subject: SMS RP-Data spec violation. Somebody wants to fix it? Message-ID: <20140205082706.GA25381@xiaoyu.lan> Hi, I just looked at a trace and saw that the RP-MessageReference we assign is hardcoded to 42. It should be a sequence number going from 0 to 255. It is somehow idiotic as there can only be one SMS per direction and there is the transaction identifier as well. I would propose a patch that does: Change gsm411_send_sms to ask the subscriber connection/transaction code for a message reference. For added bonus also "put" the number so we could verify to not re-use the number too early. anyones wants to come up with a fix? holger From holger at freyther.de Sat Feb 8 14:18:54 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 8 Feb 2014 15:18:54 +0100 Subject: SMS RP-Data spec violation. Somebody wants to fix it? In-Reply-To: <20140205082706.GA25381@xiaoyu.lan> References: <20140205082706.GA25381@xiaoyu.lan> Message-ID: <20140208141854.GA14201@xiaoyu.lan> On Wed, Feb 05, 2014 at 09:27:06AM +0100, Holger Hans Peter Freyther wrote: > anyones wants to come up with a fix? No one? Fairwaves? Somebody at least want to try the below code and see if SMS can still be sent? diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 41fe328..404dfe4 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -106,6 +106,8 @@ struct gsm_subscriber_connection { /* LU expiration handling */ uint8_t expire_timer_stopped; + /* SMS helpers for libmsc */ + uint8_t next_rp_ref; /* * Operations that have a state and might be pending diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c index 97a67ee..433951a 100644 --- a/openbsc/src/libmsc/gsm_04_11.c +++ b/openbsc/src/libmsc/gsm_04_11.c @@ -64,6 +64,18 @@ extern int smpp_try_deliver(struct gsm_sms *sms, void *tall_gsms_ctx; static uint32_t new_callref = 0x40000001; +uint8_t sms_next_rp_msg_ref(struct gsm_subscriber_connection *conn) +{ + const uint8_t rp_msg_ref = conn->next_rp_ref; + /* + * This should wrap as the valid range is 0 to 255. We only + * transfer one SMS at a time so we don't need to check if + * the id has been already assigned. + */ + conn->next_rp_ref += 1; + + return rp_msg_ref; +} struct gsm_sms *sms_alloc(void) { @@ -450,7 +462,7 @@ static int gsm411_rp_sendmsg(struct gsm411_smr_inst *inst, struct msgb *msg, rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp)); rp->len = len + 2; rp->msg_type = rp_msg_type; - rp->msg_ref = rp_msg_ref; /* FIXME: Choose randomly */ + rp->msg_ref = rp_msg_ref; return gsm411_smr_send(inst, rl_msg_type, msg); } @@ -836,7 +848,7 @@ int gsm411_send_sms(struct gsm_subscriber_connection *conn, struct gsm_sms *sms) struct msgb *msg = gsm411_msgb_alloc(); struct gsm_trans *trans; uint8_t *data, *rp_ud_len; - uint8_t msg_ref = 42; + uint8_t msg_ref = sms_next_rp_msg_ref(conn); int transaction_id; int rc; From alexander.chemeris at gmail.com Sat Feb 8 17:04:21 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 8 Feb 2014 21:04:21 +0400 Subject: SMS RP-Data spec violation. Somebody wants to fix it? In-Reply-To: <20140208141854.GA14201@xiaoyu.lan> References: <20140205082706.GA25381@xiaoyu.lan> <20140208141854.GA14201@xiaoyu.lan> Message-ID: On Sat, Feb 8, 2014 at 6:18 PM, Holger Hans Peter Freyther wrote: > On Wed, Feb 05, 2014 at 09:27:06AM +0100, Holger Hans Peter Freyther wrote: > >> anyones wants to come up with a fix? > > No one? Fairwaves? Somebody at least want to try the below code and > see if SMS can still be sent? I think it would be better if you just write a unit test for this issue. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From holger at freyther.de Sun Feb 9 06:51:47 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Feb 2014 07:51:47 +0100 Subject: SMS RP-Data spec violation. Somebody wants to fix it? In-Reply-To: References: <20140205082706.GA25381@xiaoyu.lan> <20140208141854.GA14201@xiaoyu.lan> Message-ID: <20140209065147.GA14419@xiaoyu.lan> On Sat, Feb 08, 2014 at 09:04:21PM +0400, Alexander Chemeris wrote: Hi, > > No one? Fairwaves? Somebody at least want to try the below code and > > see if SMS can still be sent? > > I think it would be better if you just write a unit test for this issue. I just remembered that you said you work on SMS issues and I wanted to give you an opportunity to contribute to OpenBSC. Sure you are not required to contribute. ;) holger From alexander.chemeris at gmail.com Sun Feb 9 09:35:46 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 9 Feb 2014 13:35:46 +0400 Subject: SMS RP-Data spec violation. Somebody wants to fix it? In-Reply-To: <20140209065147.GA14419@xiaoyu.lan> References: <20140205082706.GA25381@xiaoyu.lan> <20140208141854.GA14201@xiaoyu.lan> <20140209065147.GA14419@xiaoyu.lan> Message-ID: Hi Holger, On Sun, Feb 9, 2014 at 10:51 AM, Holger Hans Peter Freyther wrote: > On Sat, Feb 08, 2014 at 09:04:21PM +0400, Alexander Chemeris wrote: >> > No one? Fairwaves? Somebody at least want to try the below code and >> > see if SMS can still be sent? >> >> I think it would be better if you just write a unit test for this issue. > > I just remembered that you said you work on SMS issues and I wanted > to give you an opportunity to contribute to OpenBSC. Sure you are not > required to contribute. ;) May be it's just me, but I find it impolite to ask someone to test a patch, just because you don't bother to test it yourself. Moreover when there it no a unit-test for the change - at least to make sure that the next_rp_ref doesn't overflow. We would be happy to test the patch in production environment, once it's at least initially tested and merged to mainline. So far we're busy with our own set of issues to be fixed, which are more severe than this one. Patches to be contributed soon. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From holger at freyther.de Sun Feb 9 16:30:48 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sun, 9 Feb 2014 17:30:48 +0100 Subject: SMS RP-Data spec violation. Somebody wants to fix it? In-Reply-To: References: <20140205082706.GA25381@xiaoyu.lan> <20140208141854.GA14201@xiaoyu.lan> <20140209065147.GA14419@xiaoyu.lan> Message-ID: <20140209163048.GB24178@xiaoyu.lan> On Sun, Feb 09, 2014 at 01:35:46PM +0400, Alexander Chemeris wrote: Alexander, > May be it's just me, but I find it impolite to ask someone to test a > patch, just because you don't bother to test it yourself. Moreover > when there it no a unit-test for the change - at least to make sure > that the next_rp_ref doesn't overflow. next_rp_ref and the message reference are of the same range. So it is intended to overlflow and I skipped the % UINT8_MAX. > We would be happy to test the patch in production environment, once > it's at least initially tested and merged to mainline. So far we're > busy with our own set of issues to be fixed, which are more severe > than this one. Patches to be contributed soon. In German we say "lieber den spatz in der hand, als die taube auf dem dach". We prepfer a little spaze over promises. I have seen your marketing about the contributions of Fairwaves, I have seen the promises of fixes coming. I just thought I could motivate you guys to actually fix something easy. I was wrong and there is no point in replying to this email. ;) holger From 246tnt at gmail.com Wed Feb 5 10:01:35 2014 From: 246tnt at gmail.com (Sylvain Munaut) Date: Wed, 5 Feb 2014 11:01:35 +0100 Subject: OsmoDevCon 2014: CFP Message-ID: Dear all, Time has come to fill out the "Talks/Discussions/Workshop / Hacking" section of the wiki page. If you have something you'd like to present, talk about or hack on, add it there. A simple descriptive title along with an estimated duration is enough. I guess we'll collect those for 2/3 weeks and then start making the schedule. Cheers, Sylvain From jim.forster at rangenetworks.com Wed Feb 5 11:56:19 2014 From: jim.forster at rangenetworks.com (Jim Forster) Date: Wed, 5 Feb 2014 11:56:19 +0000 Subject: Fwd: [dispatch] SIP and GSM/UMTS with OpenBTS References: <040E1A40-BC55-4CFC-834A-FC958DEFDE25@rangenetworks.com> Message-ID: Dear list members, I posted the following message to the IETF DISPATCH mailing list earlier today. It's got a bit of a lengthy intro, as that community is not familiar with OpenBTS (and probably not OpenBSC either), and in preliminary discussions with them it was clear that it needed a good explanation. I invite you all to join the IETF DISPATCH list, and participate in the discussion. Tim Panton has already raised some good points. See http://trac.tools.ietf.org/wg/dispatch/trac/wiki for info about the DISPATCH group and https://www.ietf.org/mailman/listinfo/dispatch to join the list. -- Jim Range Networks Begin forwarded message: > From: Jim Forster > Subject: [dispatch] SIP and GSM/UMTS with OpenBTS > Date: February 5, 2014 at 12:09:45 PM GMT+5:30 > To: "dispatch at ietf.org" > > Dear DISPATCH group, > > OpenBTS and OpenBSC are projects are combining GSM phones and SIP in new and interesting ways. I think there is some value to the community in discussing these in the DISPATCH mailing list and having an related meeting at the London IETF. There is both some short-term, relatively straightforward work to be done to agree on the usage of SIP in these existing implementations. There may also be some very interesting work to be done on more advanced approaches. > > First, some background: OpenBTS is an open source project started by the founders of Range Networks to make a 'GSM system in a box', by implementing a system which supports the air interface for GSM phones (Um) using a Software Defined Radio (SDR) for the RF. While the GSM & 3GPP defined air interface to the phones is supported, OpenBTS diverges from these standards by immediately gatewaying the call to SIP. Each GSM or UMTS phone can then appear on the Internet as a SIP endpoint. A local SIP switching decision is made to route the call; Asterix, Freeswitch, Yate have been. The call is then sent to another local connected phone or to some other SIP service point on the Internet. > > With this in place, because the air interface to the phones is supported with no changes, standard GSM/UMTS phones can make calls to other phones on the same OpenBTS system or to any SIP endpoint on the Internet, and thence to the PSTN via any of the many SIP-PSTN gateways in operation. > > A fair question would be "Why do all this? What's wrong with GSM & 3GPP systems?". One reason is that the OpenBTS approach allows very small, stand alone systems, which efficiently connect GSM and UMTS phones to the Internet based SIP systems with a minimum of other systems. Certainly GSM/3GPP based micro cells exist, but are tied to the 3GPP 'Core' which is usually beyond the means of smaller users. OpenBTS aspires to be the simplest way for a GSM/UMTS phone to make phone calls to the SIP & PSTN world. > > At least several hundred, and likely several thousand of these systems are deployed already. Many are in labs, but others are production usage on all continents. Universities find these systems very attractive for teaching and researching: all the code from RF to Signaling is visible and may be changed as desired. > > Furthermore, additional SDRs are popping up all the time. There are 3-4 separate SDR based systems that run OpenBTS and more are coming. Right now they range from $2000 up, but it's easy to see them dropping to $500 or so this year; even Kickstarter campaigns are funding some of them. There's no natural floor below that; adding GSM/UMTS to a home router and making it a micro-cell running SIP to the Internet could conceivably be a $10 HW delta and some more SW. Secondly, there are several countries that have unlicensed GSM band (Sweden, Netherlands, UK?) so some efforts are underway to do exactly that. > > When facing the Internet, OpenBTS is simply a SIP client. However, to assure interoperability, there may be value in standardized behavior, including these issues: > > * Which elements of SIP are needed for this operation? > * Should these be documented in a profile of SIP usage to be OpenBTS Ready? > * Should ICE be recommended or possibly be required for operation behind NATs? > * What about BTS-BTS neighbor discovery > * Use of SIP Re-invite for hand-over when a mobile phone moves from one BTS to a neighbor > * For somewhat different use cases: one could separate signaling from media transport and thus might support WebRTC or other such systems. E.164 addresses are used in phones, but temporary numbers can be assigned as needed (as done in Roaming) and not surfaced to the WebRTC level. > * What Changes required for IPv6? > * Required and recommended security provisions > * Is IETF an appropriate forum for this, or should it be in 3GPP, or Sipforum.org, or a separate industry group formed? > > I look forward to discussion on the mailing list, and hopefully meeting and discussing in London. > > Yours, > > Jim Forster > Range Networks > _______________________________________________ > dispatch mailing list > dispatch at ietf.org > https://www.ietf.org/mailman/listinfo/dispatch -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From ciaby at autistici.org Thu Feb 6 21:50:48 2014 From: ciaby at autistici.org (Ciaby) Date: Thu, 06 Feb 2014 15:50:48 -0600 Subject: possible bug in OpenBSC Message-ID: <52F403B8.7030608@autistici.org> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Hi all, we are currently experiencing some issues with OpenBSC paired with a sysmobts-2050. SDCCH channels are getting stick into BROKEN/UNUSABLE state, and they don't get released. This accumulates over time and reaches a point where we have to manually restart osmo-nitb because there are no channels availables and the whole network breaks down. Is it a know issue or only us? :) This is the "show lchan" output: BTS 0, TRX 0, Timeslot 0, Lchan 0: Type SDCCH Connection: 0, State: BROKEN UNUSABLE BS Power: 37 dBm, MS Power: 39 dBm No Subscriber Bound IP: 0.0.0.0 Port 0 RTP_TYPE2=0 CONN_ID=0 Measurement Report: Flags: DLinval RXL-FULL-ul: -87 dBm, RXL-SUB-ul: -47 dBm RXQ-FULL-ul: 0, RXQ-SUB-ul: 0 BTS 1, TRX 0, Timeslot 0, Lchan 2: Type NONE Connection: 0, State: BROKEN UNUSABLE BS Power: 37 dBm, MS Power: 39 dBm No Subscriber Bound IP: 0.0.0.0 Port 0 RTP_TYPE2=0 CONN_ID=0 Measurement Report: Flags: DLinval RXL-FULL-ul: -110 dBm, RXL-SUB-ul: -110 dBm RXQ-FULL-ul: 0, RXQ-SUB-ul: 0 BTS 1, TRX 0, Timeslot 0, Lchan 3: Type NONE Connection: 0, State: BROKEN UNUSABLE BS Power: 37 dBm, MS Power: 39 dBm No Subscriber Bound IP: 0.0.0.0 Port 0 RTP_TYPE2=0 CONN_ID=0 Measurement Report: Flags: DLinval RXL-FULL-ul: -110 dBm, RXL-SUB-ul: -110 dBm RXQ-FULL-ul: 0, RXQ-SUB-ul: 0 Timeslot 0 is configured as CCCH+SDCCH4. Cheers Ciaby -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREKAAYFAlL0A7MACgkQC30ZhxNccpEr7QD/WugVMQo5LW1u2RVNeK6TL6Rx hNl/h7f2UB/3lhedCTIBALcMXoglpdx/CLIo5nrZVQqoVVRCTD8Jd6UzQFtbejx+ =l7KL -----END PGP SIGNATURE----- From holger at freyther.de Fri Feb 7 17:06:20 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 7 Feb 2014 18:06:20 +0100 Subject: possible bug in OpenBSC In-Reply-To: <52F403B8.7030608@autistici.org> References: <52F403B8.7030608@autistici.org> Message-ID: <20140207170620.GQ22661@xiaoyu.lan> On Thu, Feb 06, 2014 at 03:50:48PM -0600, Ciaby wrote: Hi, I am currently traveling and will only give a short reply. > we are currently experiencing some issues with OpenBSC paired with a > sysmobts-2050. SDCCH channels are getting stick into BROKEN/UNUSABLE > state, and they don't get released. This accumulates over time and > reaches a point where we have to manually restart osmo-nitb because > there are no channels availables and the whole network breaks down. > Is it a know issue or only us? :) The timeout I picked before a channel is marked as broken (e.g. no response received) was a random value. What is the current timeout you are using? The other part is, did you have a look at the sysmobts manual to tune the system for heavy load? There is a dedicated section in the sysmocom manual for that. From alvaroneay at gmail.com Tue Feb 11 14:44:21 2014 From: alvaroneay at gmail.com (Alvaro Neira) Date: Tue, 11 Feb 2014 15:44:21 +0100 Subject: [PATCH] src/serial.c: Add serial helper read and write function Message-ID: <20140211144421.25041.43842.stgit@Ph0enix> From: ?lvaro Neira Ayuso This patch provide two new functions for reading and writing from the serial interface. I think this two functions makes it easy reading and writing from the serial interface. Signed-off-by: Alvaro Neira Ayuso --- include/osmocom/core/serial.h | 4 ++++ src/serial.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/osmocom/core/serial.h b/include/osmocom/core/serial.h index 1640a6d..056010b 100644 --- a/include/osmocom/core/serial.h +++ b/include/osmocom/core/serial.h @@ -33,10 +33,14 @@ #include +struct msgb; + int osmo_serial_init(const char *dev, speed_t baudrate); int osmo_serial_set_baudrate(int fd, speed_t baudrate); int osmo_serial_set_custom_baudrate(int fd, int baudrate); int osmo_serial_clear_custom_baudrate(int fd); +int osmo_serial_write(int fd, struct msgb *msg); +int osmo_serial_read(int fd, struct msgb *msg, int numbytes); /*! @} */ diff --git a/src/serial.c b/src/serial.c index 66ee756..818426a 100644 --- a/src/serial.c +++ b/src/serial.c @@ -43,6 +43,7 @@ #endif #include +#include #if 0 @@ -226,4 +227,36 @@ osmo_serial_clear_custom_baudrate(int fd) return 0; } +int +osmo_serial_read(int fd, struct msgb *msg, int numbytes) +{ + int rc, bread = 0; + + while (bread < numbytes) { + rc = read(fd, msg->tail, numbytes - bread); + if (rc < 0) { + msgb_free(msg); + return -1; + } + bread += rc; + msgb_put(msg, rc); + } + + return bread; +} + +int +osmo_serial_write(int fd, struct msgb *msg) +{ + int bwritten = 0, ret = 0; + + bwritten = write(fd, msg->data, msg->len); + if (bwritten < 0 || bwritten < msg->len) { + msgb_free(msg); + ret = -1; + } + + return ret; +} + /*! @} */ From Max.Suraev at fairwaves.ru Tue Feb 11 15:06:14 2014 From: Max.Suraev at fairwaves.ru (=?UTF-8?B?4piO?=) Date: Tue, 11 Feb 2014 16:06:14 +0100 Subject: [PATCH] src/serial.c: Add serial helper read and write function In-Reply-To: <20140211144421.25041.43842.stgit@Ph0enix> References: <20140211144421.25041.43842.stgit@Ph0enix> Message-ID: <52FA3C66.7040704@fairwaves.ru> Shouldn't this be in libosmocore? 11.02.2014 15:44, Alvaro Neira ?????: > From: ?lvaro Neira Ayuso > > This patch provide two new functions for reading and writing > from the serial interface. I think this two functions makes it > easy reading and writing from the serial interface. > > Signed-off-by: Alvaro Neira Ayuso > --- > include/osmocom/core/serial.h | 4 ++++ > src/serial.c | 33 +++++++++++++++++++++++++++++++++ > 2 files changed, 37 insertions(+) > > diff --git a/include/osmocom/core/serial.h b/include/osmocom/core/serial.h > index 1640a6d..056010b 100644 > --- a/include/osmocom/core/serial.h > +++ b/include/osmocom/core/serial.h > @@ -33,10 +33,14 @@ > > #include > > +struct msgb; > + > int osmo_serial_init(const char *dev, speed_t baudrate); > int osmo_serial_set_baudrate(int fd, speed_t baudrate); > int osmo_serial_set_custom_baudrate(int fd, int baudrate); > int osmo_serial_clear_custom_baudrate(int fd); > +int osmo_serial_write(int fd, struct msgb *msg); > +int osmo_serial_read(int fd, struct msgb *msg, int numbytes); > > /*! @} */ > > diff --git a/src/serial.c b/src/serial.c > index 66ee756..818426a 100644 > --- a/src/serial.c > +++ b/src/serial.c > @@ -43,6 +43,7 @@ > #endif > > #include > +#include > > > #if 0 > @@ -226,4 +227,36 @@ osmo_serial_clear_custom_baudrate(int fd) > return 0; > } > > +int > +osmo_serial_read(int fd, struct msgb *msg, int numbytes) > +{ > + int rc, bread = 0; > + > + while (bread < numbytes) { > + rc = read(fd, msg->tail, numbytes - bread); > + if (rc < 0) { > + msgb_free(msg); > + return -1; > + } > + bread += rc; > + msgb_put(msg, rc); > + } > + > + return bread; > +} > + > +int > +osmo_serial_write(int fd, struct msgb *msg) > +{ > + int bwritten = 0, ret = 0; > + > + bwritten = write(fd, msg->data, msg->len); > + if (bwritten < 0 || bwritten < msg->len) { > + msgb_free(msg); > + ret = -1; > + } > + > + return ret; > +} > + > /*! @} */ > > -- best regards, Max, http://fairwaves.ru From alvaroneay at gmail.com Tue Feb 11 15:23:28 2014 From: alvaroneay at gmail.com (=?UTF-8?B?w4FsdmFybyBOZWlyYSBBeXVzbw==?=) Date: Tue, 11 Feb 2014 16:23:28 +0100 Subject: [PATCH] src/serial.c: Add serial helper read and write function In-Reply-To: <52FA3C66.7040704@fairwaves.ru> References: <20140211144421.25041.43842.stgit@Ph0enix> <52FA3C66.7040704@fairwaves.ru> Message-ID: <52FA4070.5030303@gmail.com> El 11/02/14 16:06, ? escribi?: > Shouldn't this be in libosmocore? Yes sorry, i have forgot to put it. Thanks Max > > 11.02.2014 15:44, Alvaro Neira ?????: >> From: ?lvaro Neira Ayuso >> >> This patch provide two new functions for reading and writing >> from the serial interface. I think this two functions makes it >> easy reading and writing from the serial interface. >> >> Signed-off-by: Alvaro Neira Ayuso >> --- >> include/osmocom/core/serial.h | 4 ++++ >> src/serial.c | 33 +++++++++++++++++++++++++++++++++ >> 2 files changed, 37 insertions(+) >> >> diff --git a/include/osmocom/core/serial.h b/include/osmocom/core/serial.h >> index 1640a6d..056010b 100644 >> --- a/include/osmocom/core/serial.h >> +++ b/include/osmocom/core/serial.h >> @@ -33,10 +33,14 @@ >> >> #include >> >> +struct msgb; >> + >> int osmo_serial_init(const char *dev, speed_t baudrate); >> int osmo_serial_set_baudrate(int fd, speed_t baudrate); >> int osmo_serial_set_custom_baudrate(int fd, int baudrate); >> int osmo_serial_clear_custom_baudrate(int fd); >> +int osmo_serial_write(int fd, struct msgb *msg); >> +int osmo_serial_read(int fd, struct msgb *msg, int numbytes); >> >> /*! @} */ >> >> diff --git a/src/serial.c b/src/serial.c >> index 66ee756..818426a 100644 >> --- a/src/serial.c >> +++ b/src/serial.c >> @@ -43,6 +43,7 @@ >> #endif >> >> #include >> +#include >> >> >> #if 0 >> @@ -226,4 +227,36 @@ osmo_serial_clear_custom_baudrate(int fd) >> return 0; >> } >> >> +int >> +osmo_serial_read(int fd, struct msgb *msg, int numbytes) >> +{ >> + int rc, bread = 0; >> + >> + while (bread < numbytes) { >> + rc = read(fd, msg->tail, numbytes - bread); >> + if (rc < 0) { >> + msgb_free(msg); >> + return -1; >> + } >> + bread += rc; >> + msgb_put(msg, rc); >> + } >> + >> + return bread; >> +} >> + >> +int >> +osmo_serial_write(int fd, struct msgb *msg) >> +{ >> + int bwritten = 0, ret = 0; >> + >> + bwritten = write(fd, msg->data, msg->len); >> + if (bwritten < 0 || bwritten < msg->len) { >> + msgb_free(msg); >> + ret = -1; >> + } >> + >> + return ret; >> +} >> + >> /*! @} */ >> >> > > From peter at stuge.se Tue Feb 11 17:57:51 2014 From: peter at stuge.se (Peter Stuge) Date: Tue, 11 Feb 2014 18:57:51 +0100 Subject: [PATCH] src/serial.c: Add serial helper read and write function In-Reply-To: <20140211144421.25041.43842.stgit@Ph0enix> References: <20140211144421.25041.43842.stgit@Ph0enix> Message-ID: <20140211175751.19445.qmail@stuge.se> Alvaro Neira wrote: > +++ b/src/serial.c . > +int > +osmo_serial_read(int fd, struct msgb *msg, int numbytes) > +{ > + int rc, bread = 0; This is a nice place to add a bounds check.. > + while (bread < numbytes) { > + rc = read(fd, msg->tail, numbytes - bread); ..so that there is guaranteed room in the msgb for the requested number of bytes. > + if (rc < 0) { > + msgb_free(msg); > + return -1; > + } Are you sure that these functions should destroy the msgb on errors? Also: What about the bytes which have already been read, in case of error? The proposed code discards those bytes. Is that OK? (I don't know the answer to this; that's why I'm asking.) > +int > +osmo_serial_write(int fd, struct msgb *msg) > +{ > + int bwritten = 0, ret = 0; > + > + bwritten = write(fd, msg->data, msg->len); > + if (bwritten < 0 || bwritten < msg->len) { This is incorrect. Both read() and write() may return less than 'count' bytes. You'll need to loop here too to ensure that all data has been written to the port. > + msgb_free(msg); Same question as with the _read function - should this function destroy the msgb on errors? > + ret = -1; I would like the functions to use similar flow. My personal preference for how to handle the return value is the way you use return in the _read function, I find that much nicer than the ret variable in the _write function. But more importantly I think the two should be consistent where possible. //Peter From anayuso at sysmocom.de Wed Feb 12 10:35:48 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Wed, 12 Feb 2014 11:35:48 +0100 Subject: [libosmocore PATCH v2] src/serial.c: Add serial helper read and write function Message-ID: <20140212103234.13283.73323.stgit@Ph0enix> From: ?lvaro Neira Ayuso This patch provide two new functions for reading and writing from the serial interface. I think this two functions makes it easy reading and writing from the serial interface. Signed-off-by: Alvaro Neira Ayuso --- v2: Fixed the write function for don't supposing that i will write all the msg in one time. I have studied the limit in the read function and i have used the -errno like the other functions inside serial.c for having consistency. The previous version, i have supposed that we need to liberate the info in case of error, now if we have a error we can check the info that we have received or we must to send again. include/osmocom/core/serial.h | 4 +++ src/serial.c | 51 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/include/osmocom/core/serial.h b/include/osmocom/core/serial.h index 1640a6d..056010b 100644 --- a/include/osmocom/core/serial.h +++ b/include/osmocom/core/serial.h @@ -33,10 +33,14 @@ #include +struct msgb; + int osmo_serial_init(const char *dev, speed_t baudrate); int osmo_serial_set_baudrate(int fd, speed_t baudrate); int osmo_serial_set_custom_baudrate(int fd, int baudrate); int osmo_serial_clear_custom_baudrate(int fd); +int osmo_serial_write(int fd, struct msgb *msg); +int osmo_serial_read(int fd, struct msgb *msg, int numbytes); /*! @} */ diff --git a/src/serial.c b/src/serial.c index 66ee756..c71ee6a 100644 --- a/src/serial.c +++ b/src/serial.c @@ -43,6 +43,7 @@ #endif #include +#include #if 0 @@ -226,4 +227,54 @@ osmo_serial_clear_custom_baudrate(int fd) return 0; } +/*! \brief Read datas from Serial interface + * \param[in] fd File descriptor of the open device + * \param[in] msg Struct where we save the info + * \param[in] numbytes Number of bytes that we want read + * \returns 0 for success or negative errno. + */ +int +osmo_serial_read(int fd, struct msgb *msg, int numbytes) +{ + int rc, bread = 0; + + if (numbytes > msg->data_len) + return -errno; + + while (bread < numbytes) { + rc = read(fd, msg->tail, numbytes - bread); + if (rc < 0) + return -errno; + + bread += rc; + msgb_put(msg, rc); + } + + return bread; +} + +/*! \brief Write datas to Serial interface + * \param[in] fd File descriptor of the open device + * \param[in] msg Struct where we have the info for writing + * \returns 0 for success or negative errno. + * + * The msgb->data pointer is updated when consuming this message + */ +int +osmo_serial_write(int fd, struct msgb *msg) +{ + int rc, bwritten = 0; + + while (msg->len > 0) { + rc = write(fd, msg->data, msg->len); + if (rc == -1) + return -errno; + + msgb_pull(msg, rc); + bwritten += rc; + } + + return bwritten; +} + /*! @} */ From peter at stuge.se Wed Feb 12 18:01:19 2014 From: peter at stuge.se (Peter Stuge) Date: Wed, 12 Feb 2014 19:01:19 +0100 Subject: [libosmocore PATCH v2] src/serial.c: Add serial helper read and write function In-Reply-To: <20140212103234.13283.73323.stgit@Ph0enix> References: <20140212103234.13283.73323.stgit@Ph0enix> Message-ID: <20140212180119.29203.qmail@stuge.se> Alvaro Neira wrote: > +++ b/src/serial.c .. > +/*! \brief Read datas from Serial interface Minor language comment: "datum" is singular, "data" is plural > +int > +osmo_serial_read(int fd, struct msgb *msg, int numbytes) > +{ > + int rc, bread = 0; > + > + if (numbytes > msg->data_len) > + return -errno; This is a pretty serious bug. What is the value of errno here? > + while (bread < numbytes) { > + rc = read(fd, msg->tail, numbytes - bread); > + if (rc < 0) > + return -errno; Please confirm that any already-received bytes should indeed be discarded by this function if an error occurs? It may be useful to document that data loss is intentional in that case. And what about when read() returns 0, indicating end of file? (See: man 2 read) Oh, and one more thing: Shouldn't msg->len be updated? > +/*! \brief Write datas to Serial interface Same minor comment on "data" > +int > +osmo_serial_write(int fd, struct msgb *msg) > +{ > + int rc, bwritten = 0; > + > + while (msg->len > 0) { > + rc = write(fd, msg->data, msg->len); > + if (rc == -1) > + return -errno; Another small thing but I think it would be nice if the code is as consistent as possible between the _read and _write functions, so rather than _read checking rc < 0 and _write checking rc == -1 have the code check for errors exactly the same way in both places. //Peter From anayuso at sysmocom.de Thu Feb 13 11:48:54 2014 From: anayuso at sysmocom.de (Alvaro Neira Ayuso) Date: Thu, 13 Feb 2014 12:48:54 +0100 Subject: [libosmocore PATCH v2] src/serial.c: Add serial helper read and write function In-Reply-To: <20140212180119.29203.qmail@stuge.se> References: <20140212103234.13283.73323.stgit@Ph0enix> <20140212180119.29203.qmail@stuge.se> Message-ID: <20140213114854.GA5796@Ph0enix> On Wed, Feb 12, 2014 at 07:01:19PM +0100, Peter Stuge wrote: > Alvaro Neira wrote: > > +++ b/src/serial.c > .. > > +/*! \brief Read datas from Serial interface > > Minor language comment: "datum" is singular, "data" is plural > > > > +int > > +osmo_serial_read(int fd, struct msgb *msg, int numbytes) > > +{ > > + int rc, bread = 0; > > + > > + if (numbytes > msg->data_len) > > + return -errno; > > This is a pretty serious bug. What is the value of errno here? Yes, errno don't return anything here. I'm going to change that with -ENOSPC > > > > + while (bread < numbytes) { > > + rc = read(fd, msg->tail, numbytes - bread); > > + if (rc < 0) > > + return -errno; > > > Please confirm that any already-received bytes should indeed be > discarded by this function if an error occurs? It may be useful > to document that data loss is intentional in that case. We don't lose any data that we have readed. In all the iteration, with the function msg_put we add inside of msg the interval of data that we have readed and we update the msg->len. > > And what about when read() returns 0, indicating end of file? > (See: man 2 read) > > Oh, and one more thing: Shouldn't msg->len be updated? > > > > +/*! \brief Write datas to Serial interface > > Same minor comment on "data" > > > > +int > > +osmo_serial_write(int fd, struct msgb *msg) > > +{ > > + int rc, bwritten = 0; > > + > > + while (msg->len > 0) { > > + rc = write(fd, msg->data, msg->len); > > + if (rc == -1) > > + return -errno; > > Another small thing but I think it would be nice if the code is as > consistent as possible between the _read and _write functions, so > rather than _read checking rc < 0 and _write checking rc == -1 have > the code check for errors exactly the same way in both places. Yes, i'm going to fix that. Thanks for all Peter. I'm going to send a new version. From jhlistserv at gmail.com Wed Feb 12 21:59:36 2014 From: jhlistserv at gmail.com (j h) Date: Wed, 12 Feb 2014 16:59:36 -0500 Subject: Force Channel Release after abrupt call end (aka battery pull of mobile device) Message-ID: I've come across an issue where any channel that are active do not release in the case of an abrupt end from the mobile (such as battery being pulled). I attempting to go in programmatically and send a CC Disconnect and a CC Release to the BSC however this doesn't solve my issue. Any thoughts of how to remedy this programatically? From holger at freyther.de Thu Feb 13 10:29:40 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 13 Feb 2014 11:29:40 +0100 Subject: Force Channel Release after abrupt call end (aka battery pull of mobile device) In-Reply-To: References: Message-ID: <20140213102940.GY21724@xiaoyu.lan> On Wed, Feb 12, 2014 at 04:59:36PM -0500, j h wrote: > I've come across an issue where any channel that are active do not > release in the case of an abrupt end from the mobile (such as battery > being pulled). I attempting to go in programmatically and send a CC > Disconnect and a CC Release to the BSC however this doesn't solve my > issue. Any thoughts of how to remedy this programatically? There should be a link timeout that will be indicated from the BTS to the BSC and this will lead to the abormal release of the radio channels. holger From anayuso at sysmocom.de Thu Feb 13 12:10:37 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Thu, 13 Feb 2014 13:10:37 +0100 Subject: [libosmocore PATCH v3] src/serial.c: Add serial helper read and write function Message-ID: <20140213120812.9264.85726.stgit@Ph0enix> From: ?lvaro Neira Ayuso This patch provide two new functions for reading and writing from the serial interface. I think this two functions makes it easy reading and writing from the serial interface. Signed-off-by: Alvaro Neira Ayuso --- v3: Fixed the bug that i send errno when in this case errno don't return anything. Fixed some format error for having consistency with the others function and now, I control when read function return the value 0 for saying the end of the file. v2: Fixed the write function for don't supposing that i will write all the msg in one time. I have studied the limit in the read function and i have used the -errno like the other functions inside serial.c for having consistency. The previous version, i have supposed that we need to liberate the info in case of error, now if we have a error we can check the info that we have received or we must to send again. include/osmocom/core/serial.h | 4 +++ src/serial.c | 53 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/include/osmocom/core/serial.h b/include/osmocom/core/serial.h index 1640a6d..056010b 100644 --- a/include/osmocom/core/serial.h +++ b/include/osmocom/core/serial.h @@ -33,10 +33,14 @@ #include +struct msgb; + int osmo_serial_init(const char *dev, speed_t baudrate); int osmo_serial_set_baudrate(int fd, speed_t baudrate); int osmo_serial_set_custom_baudrate(int fd, int baudrate); int osmo_serial_clear_custom_baudrate(int fd); +int osmo_serial_write(int fd, struct msgb *msg); +int osmo_serial_read(int fd, struct msgb *msg, int numbytes); /*! @} */ diff --git a/src/serial.c b/src/serial.c index 66ee756..8c28e7a 100644 --- a/src/serial.c +++ b/src/serial.c @@ -43,6 +43,7 @@ #endif #include +#include #if 0 @@ -226,4 +227,56 @@ osmo_serial_clear_custom_baudrate(int fd) return 0; } +/*! \brief Read data from Serial interface + * \param[in] fd File descriptor of the open device + * \param[in] msg Struct where we save the info + * \param[in] numbytes Number of bytes that we want read + * \returns 0 for success or negative errno. + */ +int +osmo_serial_read(int fd, struct msgb *msg, int numbytes) +{ + int rc, bread = 0; + + if (numbytes > msg->data_len) + return -ENOSPC; + + while (bread < numbytes) { + rc = read(fd, msg->tail, numbytes - bread); + if (rc < 0) + return -errno; + if (rc == 0) + break; + + bread += rc; + msgb_put(msg, rc); + } + + return bread; +} + +/*! \brief Write data to Serial interface + * \param[in] fd File descriptor of the open device + * \param[in] msg Struct where we have the info for writing + * \returns 0 for success or negative errno. + * + * The msgb->data pointer is updated when consuming this message + */ +int +osmo_serial_write(int fd, struct msgb *msg) +{ + int rc, bwritten = 0; + + while (msg->len > 0) { + rc = write(fd, msg->data, msg->len); + if (rc < 0) + return -errno; + + msgb_pull(msg, rc); + bwritten += rc; + } + + return bwritten; +} + /*! @} */ From jerlbeck at sysmocom.de Fri Feb 14 21:28:59 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 14 Feb 2014 22:28:59 +0100 Subject: [PATCH] rsl/si: Fix resetting bits in bts->si_valid Message-ID: <1392413339-28716-1-git-send-email-jerlbeck@sysmocom.de> Use 'var &= ~(1 << x)' to reset bits instead of 'var &= (1 << x)'. Sponsored-by: On-Waves ehf --- src/common/rsl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/rsl.c b/src/common/rsl.c index 8b7702b..b7dc2b5 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -331,7 +331,7 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg) LOGP(DRSL, LOGL_INFO, " Rx RSL BCCH INFO (SI%s)\n", get_value_string(osmo_sitype_strs, osmo_si)); } else { - bts->si_valid &= (1 << osmo_si); + bts->si_valid &= ~(1 << osmo_si); LOGP(DRSL, LOGL_INFO, " RX RSL Disabling BCCH INFO (SI%s)\n", get_value_string(osmo_sitype_strs, osmo_si)); } @@ -445,7 +445,7 @@ static int rsl_rx_sacch_fill(struct gsm_bts_trx *trx, struct msgb *msg) LOGP(DRSL, LOGL_INFO, " Rx RSL SACCH FILLING (SI%s)\n", get_value_string(osmo_sitype_strs, osmo_si)); } else { - bts->si_valid &= (1 << osmo_si); + bts->si_valid &= ~(1 << osmo_si); LOGP(DRSL, LOGL_INFO, " Rx RSL Disabling SACCH FILLING (SI%s)\n", get_value_string(osmo_sitype_strs, osmo_si)); } -- 1.7.9.5 From holger at freyther.de Fri Feb 14 23:44:43 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 15 Feb 2014 00:44:43 +0100 Subject: [PATCH] rsl/si: Fix resetting bits in bts->si_valid In-Reply-To: <1392413339-28716-1-git-send-email-jerlbeck@sysmocom.de> References: <1392413339-28716-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140214234443.GB11435@xiaoyu.lan> On Fri, Feb 14, 2014 at 10:28:59PM +0100, Jacob Erlbeck wrote: > Use 'var &= ~(1 << x)' to reset bits instead of 'var &= (1 << x)'. oops. How did you find it? For how many different SI has rsl_rx_bcch_info be called? Which SI were invalid even if they should have been valid? From holger at freyther.de Sat Feb 15 16:44:37 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 15 Feb 2014 17:44:37 +0100 Subject: [PATCH] rsl/si: Fix resetting bits in bts->si_valid In-Reply-To: <20140214234443.GB11435@xiaoyu.lan> References: <1392413339-28716-1-git-send-email-jerlbeck@sysmocom.de> <20140214234443.GB11435@xiaoyu.lan> Message-ID: <20140215164437.GB6248@xiaoyu.lan> On Sat, Feb 15, 2014 at 12:44:43AM +0100, Holger Hans Peter Freyther wrote: > On Fri, Feb 14, 2014 at 10:28:59PM +0100, Jacob Erlbeck wrote: > > Use 'var &= ~(1 << x)' to reset bits instead of 'var &= (1 << x)'. > > oops. How did you find it? For how many different SI has rsl_rx_bcch_info > be called? Which SI were invalid even if they should have been valid? Ah nevermind. I didn't realize it applies to the osmo-bts. So "canceling" a SI would cause this grave defect to occurr but from what I see we don't do that. > > From shamrin at gmail.com Sun Feb 16 16:12:25 2014 From: shamrin at gmail.com (Alexey Shamrin) Date: Sun, 16 Feb 2014 20:12:25 +0400 Subject: Docker container for OpenBSC in NITB mode Message-ID: Hi all, I've recently played with Docker [1] and OpenBSC (osmo-nitb). The result is osmonitb-docker: https://github.com/shamrin/osmonitb-docker What you can do with it? You can use it to hack on OpenBSC under Mac or even Windows (there's Vagrant+VirtualBox config). Or you can try to streamline deployment and testing on production hardware. I've tested it under Mac working together with Fairwaves UmSITE hardware (running OsmoBTS). SMS and phone calls all work. Does it make sense to submit osmonitb-docker as a patch to OpenBSC? Quick start, under real or virtual Ubuntu 12.04, with Docker installed: git clone https://github.com/shamrin/osmonitb-docker.git cd osmonitb-docker docker build -rm -t shamrin/osmonitb . docker run -v $HOME/db:/var/db -i -t -p 3002:3002 -p 3003:3003 -p 30000:30000/udp -p 30001:30001/udp -p 30002:30002/udp -p 30003:30003/udp -p 30004:30004/udp -p 30005:30005/udp -p 30006:30006/udp shamrin/osmonitb start-nitb -i 10.0.0.10 GSM1800 10 20 (replace last 4 arguments as necessary) [1]: https://www.docker.io/ Alexey From alexander.chemeris at gmail.com Sun Feb 16 19:00:24 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sun, 16 Feb 2014 23:00:24 +0400 Subject: Docker container for OpenBSC in NITB mode In-Reply-To: References: Message-ID: Hi Alexey, On Sun, Feb 16, 2014 at 8:12 PM, Alexey Shamrin wrote: > Does it make sense to submit osmonitb-docker as a patch to OpenBSC? Good stuff. It would be great to have this documented at the Osmocom wiki at least. You could request a login from Harald Welte to edit the wiki. > Quick start, under real or virtual Ubuntu 12.04, with Docker installed: How big is the resulting docker file? -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From shamrin at gmail.com Sun Feb 16 22:46:59 2014 From: shamrin at gmail.com (Alexey Shamrin) Date: Mon, 17 Feb 2014 02:46:59 +0400 Subject: Docker container for OpenBSC in NITB mode In-Reply-To: References: Message-ID: Hi Alexander, On Sun, Feb 16, 2014 at 11:00 PM, Alexander Chemeris wrote: > How big is the resulting docker file? `docker images` reports 467.8 Mb virtual size. But I have spent zero time optimizing it, because Docker is usually smart about sending only changed parts when updating the image. No need to transfer basic Ubuntu image bytes. Still, it could be made much lower. [0] E.g., Docker people managed to shrink PostgreSQL image into less than 20 Mb. [1] [0]: With one caveat. Starter script currently patches openbsc and recompiles it before running. So it currently requires full build environment in the image. The proper solution is to add a config setting for an external OpenBSC IP address, because Docker put its VMs behind the NAT by default. Here's starter script: https://github.com/shamrin/osmonitb-docker/blob/master/start-nitb [1]: http://www.slideshare.net/jerome42/create-lightweight-docker-containers-with-buildroot Alexey From peter at stuge.se Mon Feb 17 14:23:07 2014 From: peter at stuge.se (Peter Stuge) Date: Mon, 17 Feb 2014 15:23:07 +0100 Subject: Docker container for OpenBSC in NITB mode In-Reply-To: References: Message-ID: <20140217142307.25167.qmail@stuge.se> Alexey Shamrin wrote: > The proper solution is to add a config setting for an external > OpenBSC IP address, because Docker put its VMs behind the NAT by > default. Ha, no, I don't think that's a proper solution. Why don't you just configure the virtual network without NAT? //Peter From shamrin at gmail.com Mon Feb 17 17:22:01 2014 From: shamrin at gmail.com (Alexey Shamrin) Date: Mon, 17 Feb 2014 21:22:01 +0400 Subject: Docker container for OpenBSC in NITB mode In-Reply-To: <20140217142307.25167.qmail@stuge.se> References: <20140217142307.25167.qmail@stuge.se> Message-ID: On Mon, Feb 17, 2014 at 6:23 PM, Peter Stuge wrote: >> The proper solution is to add a config setting for an external >> OpenBSC IP address, because Docker put its VMs behind the NAT by >> default. > Ha, no, I don't think that's a proper solution. > Why don't you just configure the virtual network without NAT? My OpenBSC container has to be available to OsmoBTS running on a another physical PC (Fairwaves UmSITE). As far as I can tell, Docker doesn't yet support connecting containers to a physical network interface. There's separate script that could probably help, but I haven't yet tried it: https://github.com/jpetazzo/pipework#connect-a-container-to-a-local-physical-interface Alexey From kluchnikovi at gmail.com Mon Feb 17 12:50:42 2014 From: kluchnikovi at gmail.com (Ivan Kluchnikov) Date: Mon, 17 Feb 2014 16:50:42 +0400 Subject: [PATCH] rsl: Implement handling of rsl Delete Ind message Message-ID: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> If bsc receives Delete_Ind message from bts, bsc should release allocated channel, which was specified in dropped imm_assign message. --- openbsc/src/libbsc/abis_rsl.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index f53ba84..ed6d8cd 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -1539,6 +1539,41 @@ static int rsl_rx_ccch_load(struct msgb *msg) return 0; } +/* CCCH overloaded, IMM_ASSIGN was dropped */ +static int rsl_rx_delete_ind(struct gsm_bts_trx *trx, struct msgb *msg) +{ + struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg); + struct gsm48_imm_ass *ia; + struct gsm_lchan *lchan; + struct gsm_bts_trx *cur_trx; + uint8_t chan_nr; + uint16_t arfcn; + + /* bts didn't send IMM_ASSIGN, so we should release allocated channel */ + if (msgb_l2len(msg) != MACBLOCK_SIZE + 6) + return -EIO; + + ia = (struct gsm48_imm_ass *) (rqd_hdr->data + 2); + + if (ia->msg_type == GSM48_MT_RR_IMM_ASS) { + chan_nr = ia->chan_desc.chan_nr; + arfcn = ia->chan_desc.h0.arfcn_high; + arfcn = (arfcn << 8) | ia->chan_desc.h0.arfcn_low; + llist_for_each_entry(cur_trx, &trx->bts->trx_list, list) { + if (cur_trx->arfcn == arfcn) { + lchan = lchan_lookup(cur_trx, chan_nr); + if (!lchan) + return -EINVAL; + if (lchan->state != LCHAN_S_ACTIVE) + return -EINVAL; + rsl_direct_rf_release(lchan); + } + } + } + + return 0; +} + static int abis_rsl_rx_cchan(struct msgb *msg) { struct e1inp_sign_link *sign_link = msg->dst; @@ -1558,6 +1593,8 @@ static int abis_rsl_rx_cchan(struct msgb *msg) break; case RSL_MT_DELETE_IND: /* CCCH overloaded, IMM_ASSIGN was dropped */ + rc = rsl_rx_delete_ind(sign_link->trx, msg); + break; case RSL_MT_CBCH_LOAD_IND: /* current load on the CBCH */ LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message " -- 1.7.9.5 From holger at freyther.de Tue Feb 18 07:00:04 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 18 Feb 2014 08:00:04 +0100 Subject: [PATCH] rsl: Implement handling of rsl Delete Ind message In-Reply-To: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> References: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> Message-ID: <20140218070004.GJ6248@xiaoyu.lan> On Mon, Feb 17, 2014 at 04:50:42PM +0400, Ivan Kluchnikov wrote: Good Morning, > + llist_for_each_entry(cur_trx, &trx->bts->trx_list, list) { > + if (cur_trx->arfcn == arfcn) { I wondered if we want to compare the access reference as well? We do not enforce that the ARFCNs of a TRX are distinct. And besides that I would like you to move the look-up code to a separate function. That way we can at least write a unit test in the future. From Ivan.Kluchnikov at fairwaves.ru Tue Feb 18 08:34:26 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Tue, 18 Feb 2014 12:34:26 +0400 Subject: [PATCH] rsl: Implement handling of rsl Delete Ind message In-Reply-To: <20140218070004.GJ6248@xiaoyu.lan> References: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> <20140218070004.GJ6248@xiaoyu.lan> Message-ID: > I wondered if we want to compare the access reference as well? We do not > enforce that the ARFCNs of a TRX are distinct. It seems, I don't understand what do you mean. What access reference we should compare? As I understand, each trx has one arfcn, so we can find trx by arfcn. And besides that I would > like you to move the look-up code to a separate function. That way we can > at least write a unit test in the future. Ok, I can move this code to "gsm_bts_trx_by_arfcn" function. -- Regards, Ivan Kluchnikov. http://fairwaves.ru From holger at freyther.de Tue Feb 18 08:42:16 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 18 Feb 2014 09:42:16 +0100 Subject: [PATCH] rsl: Implement handling of rsl Delete Ind message In-Reply-To: References: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> <20140218070004.GJ6248@xiaoyu.lan> Message-ID: <20140218084216.GS6248@xiaoyu.lan> On Tue, Feb 18, 2014 at 12:34:26PM +0400, Ivan Kluchnikov wrote: > It seems, I don't understand what do you mean. > What access reference we should compare? > As I understand, each trx has one arfcn, so we can find trx by arfcn. bts 0 trx 0 arfcn 123 trx 1 arfcn 123 it is a config not rejected by OpenBSC. Maybe we should reject it, or we should make the deletion code more robust. I was referring to the request reference (10.5.2.30) of GSM 04.08. > > And besides that I would > > like you to move the look-up code to a separate function. That way we can > > at least write a unit test in the future. > > Ok, I can move this code to "gsm_bts_trx_by_arfcn" function. exactly From Ivan.Kluchnikov at fairwaves.ru Tue Feb 18 15:03:50 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Tue, 18 Feb 2014 19:03:50 +0400 Subject: [PATCH] rsl: Implement handling of rsl Delete Ind message In-Reply-To: <20140218084216.GS6248@xiaoyu.lan> References: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> <20140218070004.GJ6248@xiaoyu.lan> <20140218084216.GS6248@xiaoyu.lan> Message-ID: > bts 0 > trx 0 > arfcn 123 > trx 1 > arfcn 123 > > it is a config not rejected by OpenBSC. Ok, now I understand. But I think the right way is to check duplicate arfcns in bootstrap_bts function, because it allows us to detect this problem earlier. -- Regards, Ivan Kluchnikov. http://fairwaves.ru From holger at freyther.de Tue Feb 18 18:21:12 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Tue, 18 Feb 2014 19:21:12 +0100 Subject: [PATCH] rsl: Implement handling of rsl Delete Ind message In-Reply-To: References: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> <20140218070004.GJ6248@xiaoyu.lan> <20140218084216.GS6248@xiaoyu.lan> Message-ID: <20140218182112.GH6756@xiaoyu.lan> On Tue, Feb 18, 2014 at 07:03:50PM +0400, Ivan Kluchnikov wrote: > Ok, now I understand. > But I think the right way is to check duplicate arfcns in > bootstrap_bts function, because it allows us to detect this problem > earlier. Sure, I just highlighted that your code makes an assumption that is not true. I can't think of a valid use-case for re-using the ARFCN across a BTS. We can forbid this kind of configuration and see if somebody complains. From alexander.chemeris at gmail.com Tue Feb 18 08:41:58 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Tue, 18 Feb 2014 12:41:58 +0400 Subject: [PATCH] rsl: Implement handling of rsl Delete Ind message In-Reply-To: <20140218070004.GJ6248@xiaoyu.lan> References: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> <20140218070004.GJ6248@xiaoyu.lan> Message-ID: 18 ????. 2014 ?. 11:02 ???????????? "Holger Hans Peter Freyther" < holger at freyther.de> ???????: > > On Mon, Feb 17, 2014 at 04:50:42PM +0400, Ivan Kluchnikov wrote: > > Good Morning, > > > + llist_for_each_entry(cur_trx, &trx->bts->trx_list, list) { > > + if (cur_trx->arfcn == arfcn) { > > I wondered if we want to compare the access reference as well? We do not > enforce that the ARFCNs of a TRX are distinct. Actually I think we should rather start enforcing that. Or do you know situations when both TRX's could run on the same ARFCN? > And besides that I would > like you to move the look-up code to a separate function. That way we can > at least write a unit test in the future. +1 Please excuse typos. Written with a touchscreen keyboard. -- Regards, Alexander Chemeris CEO/Founder Fairwaves LLC http://fairwaves.ru -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander.chemeris at gmail.com Tue Feb 18 08:42:20 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Tue, 18 Feb 2014 12:42:20 +0400 Subject: [PATCH] rsl: Implement handling of rsl Delete Ind message In-Reply-To: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> References: <1392641442-21738-1-git-send-email-kluchnikovi@gmail.com> Message-ID: 17 ????. 2014 ?. 16:54 ???????????? "Ivan Kluchnikov" ???????: > > +/* CCCH overloaded, IMM_ASSIGN was dropped */ You're missing "is" before "overloaded", if I remember English grammar correctly. :) Please excuse typos. Written with a touchscreen keyboard. -- Regards, Alexander Chemeris CEO/Founder Fairwaves LLC http://fairwaves.ru -------------- next part -------------- An HTML attachment was scrubbed... URL: From ciaby at autistici.org Mon Feb 17 21:07:15 2014 From: ciaby at autistici.org (Ciaby) Date: Mon, 17 Feb 2014 15:07:15 -0600 Subject: OsmoDevCon participation Message-ID: <53027A03.8040702@autistici.org> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Hi everybody, I know that's a bit late, but... I'm part of the Rhizomatica project, we're currently building a GSM/SIP hybrid network in Mexico. I'll be around Europe at the time of the conference, and I was wondering if there is still space available to attend. I'm not a developer of Osmocom, but we're patching OpenBSC here and there to make it fit our platform. I could come and present what is the current status, the code we wrote to manage the network from a user perspective, and where we're going in the near future. Could that be of any interest to the Osmocom crew? Cheers Ciaby -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREKAAYFAlMCef8ACgkQC30ZhxNccpHkggD+M4Sn1Zakc+1oDilvm0dkfY3P 2LidV/BIiTM7P/rgXmEA/29U6I+BhvqIyFcj0ICdZkJoB66aYc70Zk5VOhtv/92f =tvJk -----END PGP SIGNATURE----- From jolly at eversberg.eu Wed Feb 19 06:57:50 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 19 Feb 2014 07:57:50 +0100 Subject: [PATCH 1/9] Complete definitions for all speech traffic frames at MNCC interface Message-ID: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> The new definitions are: half rate and AMR Change of definition name for bad frame, because it applies to all types of traffic, not only TCH/F. Increase MNCC interface version to 4. --- openbsc/include/openbsc/mncc.h | 6 ++++-- openbsc/src/libmsc/mncc.c | 6 +++++- openbsc/src/libtrau/trau_mux.c | 2 +- openbsc/tests/trau/trau_test.c | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index ffc247b..c61f6b8 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -95,7 +95,9 @@ struct gsm_call { #define GSM_TCHF_FRAME 0x0300 #define GSM_TCHF_FRAME_EFR 0x0301 -#define GSM_TCHF_BAD_FRAME 0x03ff +#define GSM_TCHH_FRAME 0x0302 +#define GSM_TCH_FRAME_AMR 0x0303 +#define GSM_BAD_FRAME 0x03ff #define MNCC_SOCKET_HELLO 0x0400 @@ -161,7 +163,7 @@ struct gsm_data_frame { unsigned char data[0]; }; -#define MNCC_SOCK_VERSION 2 +#define MNCC_SOCK_VERSION 4 struct gsm_mncc_hello { uint32_t msg_type; uint32_t version; diff --git a/openbsc/src/libmsc/mncc.c b/openbsc/src/libmsc/mncc.c index b484772..73db5f0 100644 --- a/openbsc/src/libmsc/mncc.c +++ b/openbsc/src/libmsc/mncc.c @@ -84,7 +84,11 @@ static struct mncc_names { {"MNCC_FRAME_DROP", 0x0202}, {"MNCC_LCHAN_MODIFY", 0x0203}, - {"GSM_TCH_FRAME", 0x0300}, + {"GSM_TCHF_FRAME", 0x0300}, + {"GSM_TCHF_FRAME_EFR", 0x0301}, + {"GSM_TCHH_FRAME", 0x0302}, + {"GSM_TCH_FRAME_AMR", 0x0303}, + {"GSM_BAD_FRAME", 0x03ff}, {NULL, 0} }; diff --git a/openbsc/src/libtrau/trau_mux.c b/openbsc/src/libtrau/trau_mux.c index 7b9bac0..fd1895f 100644 --- a/openbsc/src/libtrau/trau_mux.c +++ b/openbsc/src/libtrau/trau_mux.c @@ -314,7 +314,7 @@ struct msgb *trau_decode_efr(uint32_t callref, return msg; bad_frame: - frame->msg_type = GSM_TCHF_BAD_FRAME; + frame->msg_type = GSM_BAD_FRAME; return msg; } diff --git a/openbsc/tests/trau/trau_test.c b/openbsc/tests/trau/trau_test.c index f8a48db..b95f1e8 100644 --- a/openbsc/tests/trau/trau_test.c +++ b/openbsc/tests/trau/trau_test.c @@ -57,7 +57,7 @@ void test_trau_fr_efr(unsigned char *data) msg = trau_decode_efr(1, &tf); OSMO_ASSERT(msg != NULL); frame = (struct gsm_data_frame *)msg->data; - OSMO_ASSERT(frame->msg_type == GSM_TCHF_BAD_FRAME); + OSMO_ASSERT(frame->msg_type == GSM_BAD_FRAME); msgb_free(msg); } -- 1.8.1.5 From jolly at eversberg.eu Wed Feb 19 06:57:51 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 19 Feb 2014 07:57:51 +0100 Subject: [PATCH 2/9] Use helper function to check if an MNCC frame is data (speech/traffic) In-Reply-To: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> Message-ID: <1392793078-30854-2-git-send-email-jolly@eversberg.eu> Rename method mncc_rcv_tchf() to mncc_rcv_data(), because the check applies to all types of data frames, not only TCH/F data. --- openbsc/include/openbsc/mncc.h | 8 ++++++++ openbsc/src/libmsc/mncc_builtin.c | 22 ++++++++-------------- openbsc/src/libmsc/mncc_sock.c | 3 +-- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index c61f6b8..ffac7fd 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -191,4 +191,12 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg); int mncc_sock_init(struct gsm_network *gsmnet); +#define mncc_is_data_frame(msg_type) \ + (msg_type == GSM_TCHF_FRAME \ + || msg_type == GSM_TCHF_FRAME_EFR \ + || msg_type == GSM_TCHH_FRAME \ + || msg_type == GSM_TCH_FRAME_AMR \ + || msg_type == GSM_BAD_FRAME) + + #endif diff --git a/openbsc/src/libmsc/mncc_builtin.c b/openbsc/src/libmsc/mncc_builtin.c index be35454..a5a463b 100644 --- a/openbsc/src/libmsc/mncc_builtin.c +++ b/openbsc/src/libmsc/mncc_builtin.c @@ -273,8 +273,8 @@ static int mncc_rel_cnf(struct gsm_call *call, int msg_type, struct gsm_mncc *re return 0; } -/* receiving a TCH/F frame from the BSC code */ -static int mncc_rcv_tchf(struct gsm_call *call, int msg_type, +/* receiving a (speech) traffic frame from the BSC code */ +static int mncc_rcv_data(struct gsm_call *call, int msg_type, struct gsm_data_frame *dfr) { struct gsm_trans *remote_trans; @@ -339,16 +339,14 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) DEBUGP(DMNCC, "(call %x) Call created.\n", call->callref); } - switch (msg_type) { - case GSM_TCHF_FRAME: - case GSM_TCHF_FRAME_EFR: - break; - default: - DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref, - get_mncc_name(msg_type)); - break; + if (mncc_is_data_frame(msg_type)) { + rc = mncc_rcv_data(call, msg_type, arg); + goto out_free; } + DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref, + get_mncc_name(msg_type)); + switch(msg_type) { case MNCC_SETUP_IND: rc = mncc_setup_ind(call, msg_type, arg); @@ -408,10 +406,6 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) call->callref, data->cause.value); rc = mncc_tx_to_cc(net, MNCC_RETRIEVE_REJ, data); break; - case GSM_TCHF_FRAME: - case GSM_TCHF_FRAME_EFR: - rc = mncc_rcv_tchf(call, msg_type, arg); - break; default: LOGP(DMNCC, LOGL_NOTICE, "(call %x) Message unhandled\n", callref); break; diff --git a/openbsc/src/libmsc/mncc_sock.c b/openbsc/src/libmsc/mncc_sock.c index cf4bca8..dd0a44f 100644 --- a/openbsc/src/libmsc/mncc_sock.c +++ b/openbsc/src/libmsc/mncc_sock.c @@ -54,8 +54,7 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg) if (net->mncc_state->conn_bfd.fd < 0) { LOGP(DMNCC, LOGL_ERROR, "mncc_sock receives %s for external CC app " "but socket is gone\n", get_mncc_name(msg_type)); - if (msg_type != GSM_TCHF_FRAME && - msg_type != GSM_TCHF_FRAME_EFR) { + if (!mncc_is_data_frame(msg_type)) { /* release the request */ struct gsm_mncc mncc_out; memset(&mncc_out, 0, sizeof(mncc_out)); -- 1.8.1.5 From jolly at eversberg.eu Wed Feb 19 06:57:52 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 19 Feb 2014 07:57:52 +0100 Subject: [PATCH 3/9] Add support for half rate V1 frames to MNCC/RTP interface In-Reply-To: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> Message-ID: <1392793078-30854-3-git-send-email-jolly@eversberg.eu> --- openbsc/src/libmsc/gsm_04_08.c | 6 ++++-- openbsc/src/libtrau/rtp_proxy.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index cd2a0b5..df93433 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -2952,6 +2952,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) return tch_recv_mncc(net, data->callref, 1); case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: + case GSM_TCHH_FRAME: /* Find callref */ trans = trans_find_by_callref(net, data->callref); if (!trans) { @@ -2963,11 +2964,12 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without conn\n"); return 0; } - if (trans->conn->lchan->type != GSM_LCHAN_TCH_F) { + if (trans->conn->lchan->type != GSM_LCHAN_TCH_F + && trans->conn->lchan->type != GSM_LCHAN_TCH_H) { /* This should be LOGL_ERROR or NOTICE, but * unfortuantely it happens for a couple of frames at * the beginning of every RTP connection */ - LOGP(DMNCC, LOGL_DEBUG, "TCH frame for lchan != TCH_F\n"); + LOGP(DMNCC, LOGL_DEBUG, "TCH frame for lchan != TCH_F/TCH_H\n"); return 0; } bts = trans->conn->lchan->ts->trx->bts; diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 94a5b2f..143bfa0 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -183,6 +183,15 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; + case RTP_PT_GSM_HALF: + msg_type = GSM_TCHH_FRAME; + if (payload_len != RTP_LEN_GSM_HALF) { + DEBUGPC(DLMUX, "received RTP half rate frame with " + "payload length != %d (len = %d)\n", + RTP_LEN_GSM_HALF, payload_len); + return -EINVAL; + } + break; default: DEBUGPC(DLMUX, "received RTP frame with unknown payload " "type %d\n", rtph->payload_type); @@ -250,6 +259,11 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) payload_len = RTP_LEN_GSM_EFR; duration = RTP_GSM_DURATION; break; + case GSM_TCHH_FRAME: + payload_type = RTP_PT_GSM_HALF; + payload_len = RTP_LEN_GSM_HALF; + duration = RTP_GSM_DURATION; + break; default: DEBUGPC(DLMUX, "unsupported message type %d\n", frame->msg_type); -- 1.8.1.5 From jolly at eversberg.eu Wed Feb 19 06:57:53 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 19 Feb 2014 07:57:53 +0100 Subject: [PATCH 4/9] Add support for AMR frames to MNCC/RTP interface In-Reply-To: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> Message-ID: <1392793078-30854-4-git-send-email-jolly@eversberg.eu> AMR rate is currently fixed to 5.9k. --- openbsc/src/libmsc/gsm_04_08.c | 1 + openbsc/src/libtrau/rtp_proxy.c | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index df93433..a0650ab 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -2953,6 +2953,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: case GSM_TCHH_FRAME: + case GSM_TCH_FRAME_AMR: /* Find callref */ trans = trans_find_by_callref(net, data->callref); if (!trans) { diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 143bfa0..9c16a95 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -116,6 +116,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) int payload_len; int msg_type; int x_len; + int is_amr = 0; if (msg->len < 12) { DEBUGPC(DLMUX, "received RTP frame too short (len = %d)\n", @@ -192,21 +193,26 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; + case RTP_PT_AMR: + is_amr = 1; + break; default: DEBUGPC(DLMUX, "received RTP frame with unknown payload " "type %d\n", rtph->payload_type); return -EINVAL; } - new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len, - "GSM-DATA"); + new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len + + is_amr, "GSM-DATA"); if (!new_msg) return -ENOMEM; frame = (struct gsm_data_frame *)(new_msg->data); frame->msg_type = msg_type; frame->callref = callref; - memcpy(frame->data, payload, payload_len); - msgb_put(new_msg, sizeof(struct gsm_data_frame) + payload_len); + if (is_amr) + frame->data[0] = payload_len; + memcpy(frame->data + is_amr, payload, payload_len); + msgb_put(new_msg, sizeof(struct gsm_data_frame) + is_amr + payload_len); *data = new_msg; return 0; @@ -239,6 +245,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) int payload_type; int payload_len; int duration; /* in samples */ + int is_amr = 0; if (rs->tx_action != RTP_SEND_DOWNSTREAM) { /* initialize sequences */ @@ -264,6 +271,12 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) payload_len = RTP_LEN_GSM_HALF; duration = RTP_GSM_DURATION; break; + case GSM_TCH_FRAME_AMR: + payload_type = RTP_PT_AMR; + payload_len = frame->data[0]; + duration = RTP_GSM_DURATION; + is_amr = 1; + break; default: DEBUGPC(DLMUX, "unsupported message type %d\n", frame->msg_type); @@ -305,7 +318,8 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) rtph->timestamp = htonl(rs->transmit.timestamp); rs->transmit.timestamp += duration; rtph->ssrc = htonl(rs->transmit.ssrc); - memcpy(msg->data + sizeof(struct rtp_hdr), frame->data, payload_len); + memcpy(msg->data + sizeof(struct rtp_hdr), frame->data + is_amr, + payload_len); msgb_put(msg, sizeof(struct rtp_hdr) + payload_len); msgb_enqueue(&rss->tx_queue, msg); rss->bfd.when |= BSC_FD_WRITE; -- 1.8.1.5 From jolly at eversberg.eu Wed Feb 19 06:57:54 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 19 Feb 2014 07:57:54 +0100 Subject: [PATCH 5/9] Add handling of BFI (Bad Frame Indicatior) of received TRAU frames In-Reply-To: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> Message-ID: <1392793078-30854-5-git-send-email-jolly@eversberg.eu> If a bad TRAU frame is received, it is forwarded to MNCC application as GSM_BAD_FRAME. The application can now handle the GAP of missing audio. (e.g. by extrapolation) If TRAU frames are forwarded via RTP, bad frames are dropped, but frame counter and timestamp of RTP sender state is incremented. --- openbsc/src/libtrau/rtp_proxy.c | 15 ++++++++++++++- openbsc/src/libtrau/trau_mux.c | 5 ++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 9c16a95..22d135c 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -245,7 +245,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) int payload_type; int payload_len; int duration; /* in samples */ - int is_amr = 0; + int is_amr = 0, is_bfi = 0; if (rs->tx_action != RTP_SEND_DOWNSTREAM) { /* initialize sequences */ @@ -277,6 +277,12 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) duration = RTP_GSM_DURATION; is_amr = 1; break; + case GSM_BAD_FRAME: + payload_type = 0; + payload_len = 0; + duration = RTP_GSM_DURATION; + is_bfi = 1; + break; default: DEBUGPC(DLMUX, "unsupported message type %d\n", frame->msg_type); @@ -304,6 +310,13 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) } } + if (is_bfi) { + /* In case of a bad frame, just count and drop packt. */ + rs->transmit.timestamp += duration; + rs->transmit.sequence++; + return 0; + } + msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len, "RTP-GSM-FULL"); if (!msg) return -ENOMEM; diff --git a/openbsc/src/libtrau/trau_mux.c b/openbsc/src/libtrau/trau_mux.c index fd1895f..bb513cc 100644 --- a/openbsc/src/libtrau/trau_mux.c +++ b/openbsc/src/libtrau/trau_mux.c @@ -242,7 +242,10 @@ struct msgb *trau_decode_fr(uint32_t callref, i++; j++; } - frame->msg_type = GSM_TCHF_FRAME; + if (tf->c_bits[11]) /* BFI */ + frame->msg_type = GSM_BAD_FRAME; + else + frame->msg_type = GSM_TCHF_FRAME; frame->callref = callref; msgb_put(msg, sizeof(struct gsm_data_frame) + 33); -- 1.8.1.5 From jolly at eversberg.eu Wed Feb 19 06:57:55 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 19 Feb 2014 07:57:55 +0100 Subject: [PATCH 6/9] Add traffic forwarding via RTP to remote application In-Reply-To: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> Message-ID: <1392793078-30854-6-git-send-email-jolly@eversberg.eu> Instead of forwarding traffic through MNCC interface, traffic can be forwarded to a given RTP peer directly. A special MNCC message is used to control the peer's destination. The traffic can still be forwarded through MNCC interface when this special MNCC message is not used. It also works with E1 based BTSs. In conjunction with LCR's "rtp-bridge" feature, the RTP traffic can be directly exchanged with a remote SIP endpoint, so that the traffic is not forwarded by LCR itself. This way the performance of handling traffic only depends on OpenBSC and the remote SIP endpoint. Also the traffic is exchanged with the SIP endpoint without transcoding, to have maximum performance. Increment MNCC version to 5. --- openbsc/include/openbsc/gsm_04_08.h | 3 + openbsc/include/openbsc/mncc.h | 12 +- openbsc/include/openbsc/rtp_proxy.h | 5 +- openbsc/include/openbsc/transaction.h | 2 + openbsc/src/ipaccess/ipaccess-config.c | 6 + openbsc/src/libbsc/bsc_api.c | 1 + openbsc/src/libbsc/handover_logic.c | 1 + openbsc/src/libmsc/gsm_04_08.c | 199 ++++++++++++++++++++++++++------- openbsc/src/libmsc/mncc_sock.c | 14 +++ openbsc/src/libmsc/transaction.c | 1 + openbsc/src/libtrau/rtp_proxy.c | 20 +++- openbsc/src/libtrau/trau_mux.c | 14 ++- openbsc/src/utils/bs11_config.c | 6 + openbsc/tests/abis/abis_test.c | 6 + openbsc/tests/gbproxy/gbproxy_test.c | 6 + 15 files changed, 253 insertions(+), 43 deletions(-) diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 8df7b73..93348d1 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -6,6 +6,7 @@ #include #include +#include struct msgb; struct gsm_bts; @@ -75,4 +76,6 @@ void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd, void release_security_operation(struct gsm_subscriber_connection *conn); void allocate_security_operation(struct gsm_subscriber_connection *conn); +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data); + #endif diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index ffac7fd..32a60e9 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -92,6 +92,9 @@ struct gsm_call { #define MNCC_FRAME_RECV 0x0201 #define MNCC_FRAME_DROP 0x0202 #define MNCC_LCHAN_MODIFY 0x0203 +#define MNCC_RTP_CREATE 0x0204 +#define MNCC_RTP_CONNECT 0x0205 +#define MNCC_RTP_FREE 0x0206 #define GSM_TCHF_FRAME 0x0300 #define GSM_TCHF_FRAME_EFR 0x0301 @@ -163,7 +166,7 @@ struct gsm_data_frame { unsigned char data[0]; }; -#define MNCC_SOCK_VERSION 4 +#define MNCC_SOCK_VERSION 5 struct gsm_mncc_hello { uint32_t msg_type; uint32_t version; @@ -179,6 +182,13 @@ struct gsm_mncc_hello { uint32_t lchan_type_offset; }; +struct gsm_mncc_rtp { + uint32_t msg_type; + uint32_t callref; + uint32_t ip; + uint16_t port; +}; + char *get_mncc_name(int value); void mncc_set_cause(struct gsm_mncc *data, int loc, int val); void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg); diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h index 52ffefd..a5f6a2b 100644 --- a/openbsc/include/openbsc/rtp_proxy.h +++ b/openbsc/include/openbsc/rtp_proxy.h @@ -40,8 +40,9 @@ enum rtp_rx_action { RTP_NONE, - RTP_PROXY, - RTP_RECV_UPSTREAM, + RTP_PROXY, /* forward from BTS to BTS */ + RTP_RECV_UPSTREAM, /* forward to application */ + RTP_RECV_APP, /* receive RTP frames from application */ }; enum rtp_tx_action { diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h index b6c859c..db3a5cf 100644 --- a/openbsc/include/openbsc/transaction.h +++ b/openbsc/include/openbsc/transaction.h @@ -28,6 +28,7 @@ struct gsm_trans { /* reference from MNCC or other application */ uint32_t callref; + uint32_t callref_keep; /* to remember callref, even if it is removed */ /* if traffic channel receive was requested */ int tch_recv; @@ -46,6 +47,7 @@ struct gsm_trans { int T308_second; /* used to send release again */ struct osmo_timer_list timer; struct gsm_mncc msg; /* stores setup/disconnect/release message */ + struct rtp_socket *rs; /* application traffic via RTP */ } cc; struct { struct gsm411_smc_inst smc_inst; diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c index c42c7bb..68b9131 100644 --- a/openbsc/src/ipaccess/ipaccess-config.c +++ b/openbsc/src/ipaccess/ipaccess-config.c @@ -87,6 +87,12 @@ static uint8_t prim_oml_attr[] = { 0x95, 0x00, 7, 0x88, 192, 168, 100, 11, 0x00, static uint8_t unit_id_attr[] = { 0x91, 0x00, 9, '2', '3', '4', '2', '/' , '0', '/', '0', 0x00 }; */ +/* dummy function to keep rtp_proxy.c happy */ +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data) +{ + return 0; +} + extern int ipaccess_fd_cb(struct osmo_fd *bfd, unsigned int what); extern struct e1inp_line_ops ipaccess_e1inp_line_ops; diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index e567038..e6629ff 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/openbsc/src/libbsc/handover_logic.c b/openbsc/src/libbsc/handover_logic.c index 36a758b..e20d8f7 100644 --- a/openbsc/src/libbsc/handover_logic.c +++ b/openbsc/src/libbsc/handover_logic.c @@ -39,6 +39,7 @@ #include #include #include +#include #include struct bsc_handover { diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index a0650ab..ed3785d 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1359,8 +1359,15 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans) } if (trans->cc.state != GSM_CSTATE_NULL) new_cc_state(trans, GSM_CSTATE_NULL); + /* Be sure to unmap upstream traffic for our callref only. */ if (trans->conn) - trau_mux_unmap(&trans->conn->lchan->ts->e1_link, trans->callref); + trau_mux_unmap(&trans->conn->lchan->ts->e1_link, trans->callref_keep); + + /* free application RTP socket */ + if (trans->cc.rs) { + rtp_socket_free(trans->cc.rs); + trans->cc.rs = NULL; + } } static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg); @@ -1478,6 +1485,7 @@ static int switch_for_handover(struct gsm_lchan *old_lchan, new_rs->receive = old_rs->receive; break; case RTP_NONE: + case RTP_RECV_APP: break; } @@ -1702,6 +1710,153 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable) return 0; } +static int mncc_rtp_create(struct gsm_network *net, uint32_t callref, + struct gsm_trans *trans, struct rtp_socket *rs, + struct gsm_mncc_rtp *mncc) +{ + /* use RTP instead of MNCC socket, for traffic + * open application RTP socket */ + if (rs) { + LOGP(DCC, LOGL_ERROR, "RTP already created.\n"); + return -EIO; + } + rs = trans->cc.rs = rtp_socket_create(); + if (!rs) { + LOGP(DCC, LOGL_ERROR, "RTP socket creation failed.\n"); + /* reply with IP/port = 0 */ + mncc->ip = 0; + mncc->port = 0; + mncc_recvmsg(net, trans, MNCC_RTP_CREATE, + (struct gsm_mncc *)mncc); + return -EIO; + } + rs->rx_action = RTP_RECV_APP; + rs->receive.net = net; + rs->receive.callref = callref; + /* reply with bound IP/port */ + mncc->ip = ntohl(rs->rtp.sin_local.sin_addr.s_addr); + mncc->port = ntohs(rs->rtp.sin_local.sin_port); + mncc_recvmsg(net, trans, MNCC_RTP_CREATE, (struct gsm_mncc *)mncc); + + return 0; +} + +static int mncc_rtp_connect(struct gsm_network *net, struct gsm_trans *trans, + struct rtp_socket *rs, struct gsm_mncc_rtp *mncc) +{ + int rc; + + if (!rs) { + LOGP(DCC, LOGL_ERROR, "RTP not created.\n"); + return -EIO; + } + rc = rtp_socket_connect(trans->cc.rs, mncc->ip, mncc->port); + if (rc < 0) { + LOGP(DCC, LOGL_ERROR, "RTP socket connect failed.\n"); + /* reply with IP/port = 0 */ + mncc->ip = 0; + mncc->port = 0; + mncc_recvmsg(net, trans, MNCC_RTP_CONNECT, + (struct gsm_mncc *)mncc); + return -EIO; + } + /* reply with local IP/port */ + mncc->ip = ntohl(rs->rtp.sin_local.sin_addr.s_addr); + mncc->port = ntohs(rs->rtp.sin_local.sin_port); + mncc_recvmsg(net, trans, MNCC_RTP_CONNECT, (struct gsm_mncc *)mncc); + + return 0; +} + +static int mncc_rtp_free(struct gsm_network *net, struct gsm_trans *trans, + struct rtp_socket *rs, struct gsm_mncc_rtp *mncc) +{ + if (!rs) { + LOGP(DCC, LOGL_ERROR, "RTP not created.\n"); + return -EIO; + } + rtp_socket_free(trans->cc.rs); + trans->cc.rs = NULL; + /* reply */ + mncc_recvmsg(net, trans, MNCC_RTP_FREE, (struct gsm_mncc *)mncc); + + return 0; +} + +/* handle RTP requests of application */ +static int mncc_rtp(struct gsm_network *net, uint32_t callref, + struct gsm_mncc_rtp *mncc) +{ + struct rtp_socket *rs; + struct gsm_trans *trans; + int rc = -EINVAL; + + /* Find callref */ + trans = trans_find_by_callref(net, callref); + if (!trans) { + LOGP(DCC, LOGL_ERROR, "Unknown transaction for callref=%d\n", + callref); + return -EINVAL; + } + + rs = trans->cc.rs; + + switch (mncc->msg_type) { + case MNCC_RTP_CREATE: + rc = mncc_rtp_create(net, callref, trans, rs, mncc); + break; + case MNCC_RTP_CONNECT: + rc = mncc_rtp_connect(net, trans, rs, mncc); + break; + case MNCC_RTP_FREE: + rc = mncc_rtp_free(net, trans, rs, mncc); + break; + } + + return rc; +} + +/* handle tch frame from application */ +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data) +{ + struct gsm_trans *trans; + struct gsm_bts *bts; + + /* Find callref */ + trans = trans_find_by_callref(net, data->callref); + if (!trans) { + LOGP(DMNCC, LOGL_ERROR, "TCH frame for non-existing trans\n"); + return -EIO; + } + if (!trans->conn) { + LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without conn\n"); + return 0; + } + if (trans->conn->lchan->type != GSM_LCHAN_TCH_F + && trans->conn->lchan->type != GSM_LCHAN_TCH_H) { + /* This should be LOGL_ERROR or NOTICE, but + * unfortuantely it happens for a couple of frames at + * the beginning of every RTP connection */ + LOGP(DMNCC, LOGL_DEBUG, "TCH frame for lchan != TCH_F/TCH_H\n"); + return 0; + } + bts = trans->conn->lchan->ts->trx->bts; + if (!is_e1_bts(bts)) { + if (!trans->conn->lchan->abis_ip.rtp_socket) { + DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); + return 0; + } + if (trans->conn->lchan->abis_ip.rtp_socket->receive.callref != callref) { + /* Drop frame, if not our callref. This happens, if + * the call is on hold or retrieved by another + * transaction. */ + return 0; + } + return rtp_send_frame(trans->conn->lchan->abis_ip.rtp_socket, data); + } else + return trau_send_frame(trans->conn->lchan, data); +} + static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg) { DEBUGP(DCC, "-> STATUS ENQ\n"); @@ -2937,7 +3092,6 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) int i, rc = 0; struct gsm_trans *trans = NULL, *transt; struct gsm_subscriber_connection *conn = NULL; - struct gsm_bts *bts = NULL; struct gsm_mncc *data = arg, rel; DEBUGP(DMNCC, "receive message %s\n", get_mncc_name(msg_type)); @@ -2950,46 +3104,15 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) return tch_recv_mncc(net, data->callref, 0); case MNCC_FRAME_RECV: return tch_recv_mncc(net, data->callref, 1); + case MNCC_RTP_CREATE: + case MNCC_RTP_CONNECT: + case MNCC_RTP_FREE: + return mncc_rtp(net, data->callref, (struct gsm_mncc_rtp *) arg); case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: case GSM_TCHH_FRAME: case GSM_TCH_FRAME_AMR: - /* Find callref */ - trans = trans_find_by_callref(net, data->callref); - if (!trans) { - LOGP(DMNCC, LOGL_ERROR, "TCH frame for non-existing trans\n"); - return -EIO; - } - log_set_context(BSC_CTX_SUBSCR, trans->subscr); - if (!trans->conn) { - LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without conn\n"); - return 0; - } - if (trans->conn->lchan->type != GSM_LCHAN_TCH_F - && trans->conn->lchan->type != GSM_LCHAN_TCH_H) { - /* This should be LOGL_ERROR or NOTICE, but - * unfortuantely it happens for a couple of frames at - * the beginning of every RTP connection */ - LOGP(DMNCC, LOGL_DEBUG, "TCH frame for lchan != TCH_F/TCH_H\n"); - return 0; - } - bts = trans->conn->lchan->ts->trx->bts; - switch (bts->type) { - case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMO_SYSMO: - if (!trans->conn->lchan->abis_ip.rtp_socket) { - DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); - return 0; - } - return rtp_send_frame(trans->conn->lchan->abis_ip.rtp_socket, arg); - case GSM_BTS_TYPE_BS11: - case GSM_BTS_TYPE_RBS2000: - case GSM_BTS_TYPE_NOKIA_SITE: - return trau_send_frame(trans->conn->lchan, arg); - default: - LOGP(DCC, LOGL_ERROR, "Unknown BTS type %u\n", bts->type); - } - return -EINVAL; + return tch_frame_down(net, data->callref, (struct gsm_data_frame *) arg); } memset(&rel, 0, sizeof(struct gsm_mncc)); diff --git a/openbsc/src/libmsc/mncc_sock.c b/openbsc/src/libmsc/mncc_sock.c index dd0a44f..adb56fc 100644 --- a/openbsc/src/libmsc/mncc_sock.c +++ b/openbsc/src/libmsc/mncc_sock.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include struct mncc_sock_state { struct gsm_network *net; @@ -50,6 +52,18 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg) struct gsm_mncc *mncc_in = (struct gsm_mncc *) msgb_data(msg); int msg_type = mncc_in->msg_type; + /* application uses RTP for this transaction, we send our data via RTP, + * otherwise we send it through MNCC interface */ + if (mncc_is_data_frame(msg_type)) { + struct gsm_trans *trans = trans_find_by_callref(net, mncc_in->callref); + + if (trans && trans->cc.rs) { + rtp_send_frame(trans->cc.rs, (struct gsm_data_frame *) mncc_in); + msgb_free(msg); + return 0; + } + } + /* Check if we currently have a MNCC handler connected */ if (net->mncc_state->conn_bfd.fd < 0) { LOGP(DMNCC, LOGL_ERROR, "mncc_sock receives %s for external CC app " diff --git a/openbsc/src/libmsc/transaction.c b/openbsc/src/libmsc/transaction.c index e425e67..bdd3d8e 100644 --- a/openbsc/src/libmsc/transaction.c +++ b/openbsc/src/libmsc/transaction.c @@ -78,6 +78,7 @@ struct gsm_trans *trans_alloc(struct gsm_subscriber *subscr, trans->protocol = protocol; trans->transaction_id = trans_id; trans->callref = callref; + trans->callref_keep = callref; llist_add_tail(&trans->entry, &subscr->net->trans_list); diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index 22d135c..d2bf88d 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -473,7 +473,7 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) other_rss->bfd.when |= BSC_FD_WRITE; break; - case RTP_RECV_UPSTREAM: + case RTP_RECV_UPSTREAM: /* from BTS to application */ if (!rs->receive.callref || !rs->receive.net) { rc = -EIO; goto out_free; @@ -502,6 +502,24 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) trau_tx_to_mncc(rs->receive.net, new_msg); break; + case RTP_RECV_APP: /* from remote application */ + if (!rs->receive.callref || !rs->receive.net) { + rc = -EIO; + goto out_free; + } + if (rss->bfd.priv_nr != RTP_PRIV_RTP) { + rc = ENOTSUP; + goto out_free; + } + rc = rtp_decode(msg, rs->receive.callref, &new_msg); + if (rc < 0) + goto out_free; + msgb_free(msg); + tch_frame_down(rs->receive.net, rs->receive.callref, + (struct gsm_data_frame *) new_msg->data); + msgb_free(new_msg); + break; + case RTP_NONE: /* if socket exists, but disabled by app */ msgb_free(msg); break; diff --git a/openbsc/src/libtrau/trau_mux.c b/openbsc/src/libtrau/trau_mux.c index bb513cc..15a84b0 100644 --- a/openbsc/src/libtrau/trau_mux.c +++ b/openbsc/src/libtrau/trau_mux.c @@ -171,7 +171,9 @@ int trau_mux_unmap(const struct gsm_e1_subslot *ss, uint32_t callref) llist_del(&ue->list); return 0; } - if (ss && !memcmp(&ue->src, ss, sizeof(*ss))) { + /* Only release, if no callref is given. We must ensure that + * only the transaction's upstream is removed, if exists. */ + if (ss && !callref && !memcmp(&ue->src, ss, sizeof(*ss))) { llist_del(&ue->list); return 0; } @@ -497,11 +499,21 @@ int trau_send_frame(struct gsm_lchan *lchan, struct gsm_data_frame *frame) uint8_t trau_bits_out[TRAU_FRAME_BITS]; struct gsm_e1_subslot *dst_e1_ss = &lchan->ts->e1_link; struct subch_mux *mx; + struct upqueue_entry *ue; struct decoded_trau_frame tf; mx = e1inp_get_mux(dst_e1_ss->e1_nr, dst_e1_ss->e1_ts); if (!mx) return -EINVAL; + if (!(ue = lookup_trau_upqueue(dst_e1_ss))) { + /* Call might be on hold, so we drop frames. */ + return 0; + } + if (ue->callref != frame->callref) { + /* Slot has different transaction, due to + * another call. (Ours is on hold.) */ + return 0; + } switch (frame->msg_type) { case GSM_TCHF_FRAME: diff --git a/openbsc/src/utils/bs11_config.c b/openbsc/src/utils/bs11_config.c index e8acb46..f459744 100644 --- a/openbsc/src/utils/bs11_config.c +++ b/openbsc/src/utils/bs11_config.c @@ -83,6 +83,12 @@ struct osmo_counter *osmo_counter_alloc(const char *name) return NULL; } +/* dummy function to keep rtp_proxy.c happy */ +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data) +{ + return 0; +} + int handle_serial_msg(struct msgb *rx_msg); /* create all objects for an initial configuration */ diff --git a/openbsc/tests/abis/abis_test.c b/openbsc/tests/abis/abis_test.c index e7e78d2..6bb84cc 100644 --- a/openbsc/tests/abis/abis_test.c +++ b/openbsc/tests/abis/abis_test.c @@ -27,6 +27,12 @@ #include #include +/* dummy function to keep rtp_proxy.c happy */ +int tch_frame_down(struct gsm_network *net, uint32_t callref, struct gsm_data_frame *data) +{ + return 0; +} + static const uint8_t simple_config[] = { /*0, 13, */ 66, 18, 0, 3, 1, 2, 3, 19, 0, 3, 3, 4, 5, diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c index d32ac83..69ce58a 100644 --- a/openbsc/tests/gbproxy/gbproxy_test.c +++ b/openbsc/tests/gbproxy/gbproxy_test.c @@ -34,6 +34,12 @@ #define SGSN_NSEI 0x0100 +/* dummy function to keep rtp_proxy.c happy */ +int tch_frame_down() +{ + return 0; +} + struct gbproxy_config gbcfg; static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, -- 1.8.1.5 From jolly at eversberg.eu Wed Feb 19 06:57:56 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 19 Feb 2014 07:57:56 +0100 Subject: [PATCH 7/9] Allow dynamic RTP payload types between application and MNCC interface In-Reply-To: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> Message-ID: <1392793078-30854-7-git-send-email-jolly@eversberg.eu> Since EFR/AMR/HR codecs use dynamic RTP payload, the payload type can be set. If it is set, the frame type must be set also, so OpenBSC knows what frame types are received via RTP. This modification only affects traffic beween application and MNCC interface, not the RTP traffic between OpenBSC and BTS. --- openbsc/include/openbsc/mncc.h | 2 ++ openbsc/include/openbsc/rtp_proxy.h | 2 ++ openbsc/src/libmsc/gsm_04_08.c | 2 ++ openbsc/src/libtrau/rtp_proxy.c | 57 ++++++++++++++++++++++++++----------- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h index 32a60e9..46ba237 100644 --- a/openbsc/include/openbsc/mncc.h +++ b/openbsc/include/openbsc/mncc.h @@ -187,6 +187,8 @@ struct gsm_mncc_rtp { uint32_t callref; uint32_t ip; uint16_t port; + uint32_t payload_type; + uint32_t payload_msg_type; }; char *get_mncc_name(int value); diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h index a5f6a2b..61ad325 100644 --- a/openbsc/include/openbsc/rtp_proxy.h +++ b/openbsc/include/openbsc/rtp_proxy.h @@ -74,6 +74,8 @@ struct rtp_socket { struct { struct gsm_network *net; uint32_t callref; + uint8_t payload_type; /* dynamic PT */ + int msg_type; /* message type for dynamic PT */ } receive; }; enum rtp_tx_action tx_action; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index ed3785d..663d855 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1760,6 +1760,8 @@ static int mncc_rtp_connect(struct gsm_network *net, struct gsm_trans *trans, (struct gsm_mncc *)mncc); return -EIO; } + rs->receive.msg_type = mncc->payload_msg_type; + rs->receive.payload_type = mncc->payload_type; /* reply with local IP/port */ mncc->ip = ntohl(rs->rtp.sin_local.sin_addr.s_addr); mncc->port = ntohs(rs->rtp.sin_local.sin_port); diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index d2bf88d..d4dbe02 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -106,7 +106,7 @@ struct rtp_x_hdr { #define RTP_VERSION 2 /* decode an rtp frame and create a new buffer with payload */ -static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) +static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, int msg_type) { struct msgb *new_msg; struct gsm_data_frame *frame; @@ -114,7 +114,6 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) struct rtp_x_hdr *rtpxh; uint8_t *payload; int payload_len; - int msg_type; int x_len; int is_amr = 0; @@ -165,9 +164,31 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) } } - switch (rtph->payload_type) { - case RTP_PT_GSM_FULL: - msg_type = GSM_TCHF_FRAME; + /* If no explicit frame type is given, select frame type from + * payload type. */ + if (!msg_type) { + switch (rtph->payload_type) { + case RTP_PT_GSM_FULL: + msg_type = GSM_TCHF_FRAME; + break; + case RTP_PT_GSM_EFR: + msg_type = GSM_TCHF_FRAME_EFR; + break; + case RTP_PT_GSM_HALF: + msg_type = GSM_TCHH_FRAME; + break; + case RTP_PT_AMR: + msg_type = GSM_TCH_FRAME_AMR; + break; + default: + DEBUGPC(DLMUX, "received RTP frame with unknown " + "payload type %d\n", rtph->payload_type); + return -EINVAL; + } + } + + switch (msg_type) { + case GSM_TCHF_FRAME: if (payload_len != RTP_LEN_GSM_FULL) { DEBUGPC(DLMUX, "received RTP full rate frame with " "payload length != %d (len = %d)\n", @@ -175,8 +196,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; - case RTP_PT_GSM_EFR: - msg_type = GSM_TCHF_FRAME_EFR; + case GSM_TCHF_FRAME_EFR: if (payload_len != RTP_LEN_GSM_EFR) { DEBUGPC(DLMUX, "received RTP extended full rate frame " "with payload length != %d (len = %d)\n", @@ -184,8 +204,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; - case RTP_PT_GSM_HALF: - msg_type = GSM_TCHH_FRAME; + case GSM_TCHH_FRAME: if (payload_len != RTP_LEN_GSM_HALF) { DEBUGPC(DLMUX, "received RTP half rate frame with " "payload length != %d (len = %d)\n", @@ -193,12 +212,11 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data) return -EINVAL; } break; - case RTP_PT_AMR: + case GSM_TCH_FRAME_AMR: is_amr = 1; break; default: - DEBUGPC(DLMUX, "received RTP frame with unknown payload " - "type %d\n", rtph->payload_type); + DEBUGPC(DLMUX, "Forced message type %x unknown\n", msg_type); return -EINVAL; } @@ -246,6 +264,10 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) int payload_len; int duration; /* in samples */ int is_amr = 0, is_bfi = 0; + uint8_t dynamic_pt = 0; + + if (rs->rx_action == RTP_RECV_APP) + dynamic_pt = rs->receive.payload_type; if (rs->tx_action != RTP_SEND_DOWNSTREAM) { /* initialize sequences */ @@ -262,17 +284,17 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) duration = RTP_GSM_DURATION; break; case GSM_TCHF_FRAME_EFR: - payload_type = RTP_PT_GSM_EFR; + payload_type = (dynamic_pt) ? : RTP_PT_GSM_EFR; payload_len = RTP_LEN_GSM_EFR; duration = RTP_GSM_DURATION; break; case GSM_TCHH_FRAME: - payload_type = RTP_PT_GSM_HALF; + payload_type = (dynamic_pt) ? : RTP_PT_GSM_HALF; payload_len = RTP_LEN_GSM_HALF; duration = RTP_GSM_DURATION; break; case GSM_TCH_FRAME_AMR: - payload_type = RTP_PT_AMR; + payload_type = (dynamic_pt) ? : RTP_PT_AMR; payload_len = frame->data[0]; duration = RTP_GSM_DURATION; is_amr = 1; @@ -495,7 +517,7 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) rc = -EINVAL; goto out_free; } - rc = rtp_decode(msg, rs->receive.callref, &new_msg); + rc = rtp_decode(msg, rs->receive.callref, &new_msg, 0); if (rc < 0) goto out_free; msgb_free(msg); @@ -511,7 +533,8 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) rc = ENOTSUP; goto out_free; } - rc = rtp_decode(msg, rs->receive.callref, &new_msg); + rc = rtp_decode(msg, rs->receive.callref, &new_msg, + rs->receive.msg_type); if (rc < 0) goto out_free; msgb_free(msg); -- 1.8.1.5 From jolly at eversberg.eu Wed Feb 19 06:57:57 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 19 Feb 2014 07:57:57 +0100 Subject: [PATCH 8/9] Fixed (ipaccess BTS) delay/silence problems, if RTP stream jitters too much In-Reply-To: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> Message-ID: <1392793078-30854-8-git-send-email-jolly@eversberg.eu> After OpenBSC stalled for some reason (e.g. CPU overload or database access) or after speech frames have been lost (MNCC application problems / hold/retrieve call), the timestamp and the sequence number of the RTP socket state must be corrected. The amount of incrmentation is calculated from the elapsed time. Not incrementing timestamp and sequence number would cause all frames to be dropped by ipaccess BTS, because the BTS expects frames with more recent timestamps. If speech frames are received too fast, they must be dropped. The timestamp and sequence number of the RTP socket state are not changed in this case. Incmenetating timestamp and sequence number would causes high delay at ipaccess BTS, because the BTS would queue the frames until the timestamp matches the current time. There is a simple test case: Make a call between two phones and check the delay. (When using LCR, make a call to the echo test.) The press CTRL+z to suspend OpenBSC process for a few seconds and enter "fg" to continue OpenBSC process. There shall be no change in the delay, even after repeating this test many times. --- openbsc/src/libtrau/rtp_proxy.c | 89 +++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index d4dbe02..ad3dbb6 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -236,19 +236,65 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, in return 0; } -/* "to - from" */ -static void tv_difference(struct timeval *diff, const struct timeval *from, - const struct timeval *__to) +#define USEC_1S 1000000 +#define USEC_10MS 10000 +#define USEC_20MS 20000 +#define SAMPLES_1S 8000 +#define USEC_SAMPLE 125 + +/* add usec to tv */ +static void tv_add_usec(struct timeval *tv, long int usec) { - struct timeval _to = *__to, *to = &_to; + struct timeval tv_add; - if (to->tv_usec < from->tv_usec) { - to->tv_sec -= 1; - to->tv_usec += 1000000; + tv_add.tv_sec = usec / USEC_1S; + tv_add.tv_usec = usec % USEC_1S; + timeradd(tv, &tv_add, tv); +} + +static int correct_timestamp(struct rtp_socket *rs, int duration) +{ + struct timeval tv, tv_diff; + long int usec_diff, frame_diff; + int usec_duration = duration * USEC_SAMPLE; + + gettimeofday(&tv, NULL); + timersub(&tv, &rs->transmit.last_tv, &tv_diff); + + usec_diff = tv_diff.tv_sec * USEC_1S + tv_diff.tv_usec; + frame_diff = (usec_diff + (usec_duration >> 1)) / usec_duration; /* round */ + + /* Drop frame, if current time to too much in advance of the last_tv. + * < 0 means that the time difference in frames must be at lease 2 + * frames below the expected difference of 1. + */ + if (frame_diff < 0) + return -1; + + /* Increment last_tv by the duration of one frame. */ + tv_add_usec(&rs->transmit.last_tv, usec_duration); + + /* Increment last_tv, if the current time is too much afterwards. + * Also increment timestamp and sequence number of RTP socket state. + * > 2 means that the time difference in frames must be at least 2 + * frames above the expected difference of 1. + */ + if (frame_diff > 2) { + long int frame_diff_excess = frame_diff - 1; + long int sample_diff_excess = frame_diff_excess * duration; + + /* correct last_tv */ + tv_add_usec(&rs->transmit.last_tv, + sample_diff_excess * USEC_SAMPLE); + LOGP(DLMUX, LOGL_NOTICE, + "Correcting timestamp difference of %ld frames " + "(to %s)\n", frame_diff_excess, + (rs->rx_action == RTP_RECV_APP) ? "app" : "BTS"); + rs->transmit.sequence += frame_diff_excess; + rs->transmit.timestamp += sample_diff_excess; } - diff->tv_usec = to->tv_usec - from->tv_usec; - diff->tv_sec = to->tv_sec - from->tv_sec; + return 0; } /*! \brief encode and send a rtp frame @@ -265,6 +311,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) int duration; /* in samples */ int is_amr = 0, is_bfi = 0; uint8_t dynamic_pt = 0; + int rc; if (rs->rx_action == RTP_RECV_APP) dynamic_pt = rs->receive.payload_type; @@ -275,6 +322,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) rs->transmit.ssrc = rand(); rs->transmit.sequence = random(); rs->transmit.timestamp = random(); + gettimeofday(&rs->transmit.last_tv, NULL); } switch (frame->msg_type) { @@ -311,26 +359,9 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame) return -EINVAL; } - { - struct timeval tv, tv_diff; - long int usec_diff, frame_diff; - - gettimeofday(&tv, NULL); - tv_difference(&tv_diff, &rs->transmit.last_tv, &tv); - rs->transmit.last_tv = tv; - - usec_diff = tv_diff.tv_sec * 1000000 + tv_diff.tv_usec; - frame_diff = (usec_diff / 20000); - - if (abs(frame_diff) > 1) { - long int frame_diff_excess = frame_diff - 1; - - LOGP(DLMUX, LOGL_NOTICE, - "Correcting frame difference of %ld frames\n", frame_diff_excess); - rs->transmit.sequence += frame_diff_excess; - rs->transmit.timestamp += frame_diff_excess * duration; - } - } + rc = correct_timestamp(rs, duration); + if (rc) + return 0; if (is_bfi) { /* In case of a bad frame, just count and drop packt. */ -- 1.8.1.5 From jolly at eversberg.eu Wed Feb 19 06:57:58 2014 From: jolly at eversberg.eu (Andreas Eversberg) Date: Wed, 19 Feb 2014 07:57:58 +0100 Subject: [PATCH 9/9] Fixed problem of mute audio on some calls In-Reply-To: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> Message-ID: <1392793078-30854-9-git-send-email-jolly@eversberg.eu> When reading from RTP socket, the first read() may fail right after connecting to remote socket. Subsequent read() will work as it should. If the remote socket does not open fast enough, the transmitted RTP payload can cause an ICMP (connection refused) packet reply. This causes the read to fail with errno=111. In all other error cases, the errno is logged at debug level. In all error cases, reading is not disabled. --- openbsc/src/libtrau/rtp_proxy.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c index ad3dbb6..52abad0 100644 --- a/openbsc/src/libtrau/rtp_proxy.c +++ b/openbsc/src/libtrau/rtp_proxy.c @@ -497,9 +497,16 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) return -ENOMEM; rc = read(rss->bfd.fd, msg->data, RTP_ALLOC_SIZE); - if (rc <= 0) { - rss->bfd.when &= ~BSC_FD_READ; - return rc; + if (rc == 0) + goto out_free; + if (rc < 0) { + /* Ignore "connection refused". this happens, If we open the + * socket faster than the remove side. */ + if (errno == ECONNREFUSED) + goto out_free; + DEBUGPC(DLMUX, "Read of RTP socket (%p) failed (errno %d, " + "%s)\n", rs, errno, strerror(errno)); + goto out_free; } msgb_put(msg, rc); -- 1.8.1.5 From shamrin at gmail.com Wed Feb 19 10:51:40 2014 From: shamrin at gmail.com (Alexey Shamrin) Date: Wed, 19 Feb 2014 14:51:40 +0400 Subject: [PATCH 9/9] Fixed problem of mute audio on some calls In-Reply-To: <1392793078-30854-9-git-send-email-jolly@eversberg.eu> References: <1392793078-30854-1-git-send-email-jolly@eversberg.eu> <1392793078-30854-9-git-send-email-jolly@eversberg.eu> Message-ID: Hi Andreas, 19.02.2014, ? 10:57, Andreas Eversberg ???????(?): > When reading from RTP socket, the first read() may fail right after > connecting to remote socket. Subsequent read() will work as it should. > > If the remote socket does not open fast enough, the transmitted RTP > payload can cause an ICMP (connection refused) packet reply. This causes > the read to fail with errno=111. In all other error cases, the errno is > logged at debug level. In all error cases, reading is not disabled. > --- > openbsc/src/libtrau/rtp_proxy.c | 13 ++++++++++--- > 1 file changed, 10 insertions(+), 3 deletions(-) > > diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c > index ad3dbb6..52abad0 100644 > --- a/openbsc/src/libtrau/rtp_proxy.c > +++ b/openbsc/src/libtrau/rtp_proxy.c > @@ -497,9 +497,16 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss) > return -ENOMEM; > > rc = read(rss->bfd.fd, msg->data, RTP_ALLOC_SIZE); > - if (rc <= 0) { > - rss->bfd.when &= ~BSC_FD_READ; > - return rc; > + if (rc == 0) > + goto out_free; > + if (rc < 0) { > + /* Ignore "connection refused". this happens, If we open the > + * socket faster than the remove side. */ Typo? s/remove/remote/ > + if (errno == ECONNREFUSED) > + goto out_free; > + DEBUGPC(DLMUX, "Read of RTP socket (%p) failed (errno %d, " > + "%s)\n", rs, errno, strerror(errno)); > + goto out_free; > } > > msgb_put(msg, rc); > -- > 1.8.1.5 > > From kluchnikovi at gmail.com Thu Feb 20 07:28:22 2014 From: kluchnikovi at gmail.com (Ivan Kluchnikov) Date: Thu, 20 Feb 2014 11:28:22 +0400 Subject: [PATCH 1/3] bsc_init: Check BTS configuration, BTS should not use duplicate ARFCNs Message-ID: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> --- openbsc/src/libbsc/bsc_init.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c index 8fd72cf..cd5ee58 100644 --- a/openbsc/src/libbsc/bsc_init.c +++ b/openbsc/src/libbsc/bsc_init.c @@ -351,6 +351,8 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal, static int bootstrap_bts(struct gsm_bts *bts) { int i, n; + struct gsm_bts_trx *cur_trx; + struct gsm_bts_trx *trx; if (bts->model->start && !bts->model->started) { int ret = bts->model->start(bts->network); @@ -394,6 +396,17 @@ static int bootstrap_bts(struct gsm_bts *bts) return -EINVAL; } + llist_for_each_entry(cur_trx, &bts->trx_list, list) { + llist_for_each_entry(trx, &bts->trx_list, list) { + if ((cur_trx->arfcn == trx->arfcn) && (cur_trx->nr != trx->nr)) { + LOGP(DNM, LOGL_ERROR, "BTS should not use duplicate ARFCNs. " + "Duplicate ARFCN = %d BTS = %d TRX = %d TRX = %d\n", + trx->arfcn, bts->nr, cur_trx->nr, trx->nr); + return -EINVAL; + } + } + } + if (bts->network->auth_policy == GSM_AUTH_POLICY_ACCEPT_ALL && !bts->si_common.rach_control.cell_bar) LOGP(DNM, LOGL_ERROR, "\nWARNING: You are running an 'accept-all' " -- 1.7.9.5 From kluchnikovi at gmail.com Thu Feb 20 07:28:23 2014 From: kluchnikovi at gmail.com (Ivan Kluchnikov) Date: Thu, 20 Feb 2014 11:28:23 +0400 Subject: [PATCH 2/3] gsm_data: Add search for TRX by ARFCN In-Reply-To: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> Message-ID: <1392881304-10753-2-git-send-email-kluchnikovi@gmail.com> --- openbsc/include/openbsc/gsm_data.h | 1 + openbsc/src/libcommon/gsm_data.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 41fe328..d6a107f 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -424,6 +424,7 @@ void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr, void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked); int gsm_bts_has_feature(struct gsm_bts *bts, enum gsm_bts_features feat); struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr); +struct gsm_bts_trx *gsm_bts_trx_by_arfcn(struct gsm_bts *bts, int arfcn); /* generic E1 line operations for all ISDN-based BTS. */ extern struct e1inp_line_ops bts_isdn_e1inp_line_ops; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 5f7e32e..9e3d360 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -225,6 +225,17 @@ struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr) return NULL; } +struct gsm_bts_trx *gsm_bts_trx_by_arfcn(struct gsm_bts *bts, int arfcn) +{ + struct gsm_bts_trx *trx; + + llist_for_each_entry(trx, &bts->trx_list, list) { + if (trx->arfcn == arfcn) + return trx; + } + return NULL; +} + /* Search for a BTS in the given Location Area; optionally start searching * with start_bts (for continuing to search after the first result) */ struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac, -- 1.7.9.5 From 246tnt at gmail.com Thu Feb 20 14:44:46 2014 From: 246tnt at gmail.com (Sylvain Munaut) Date: Thu, 20 Feb 2014 15:44:46 +0100 Subject: [PATCH 2/3] gsm_data: Add search for TRX by ARFCN In-Reply-To: <1392881304-10753-2-git-send-email-kluchnikovi@gmail.com> References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> <1392881304-10753-2-git-send-email-kluchnikovi@gmail.com> Message-ID: Hi, > +struct gsm_bts_trx *gsm_bts_trx_by_arfcn(struct gsm_bts *bts, int arfcn) The arfcn should be a uint16_t like is it in the structure. Please try to be consitent in the usage of types. Cheers, Sylvain From Ivan.Kluchnikov at fairwaves.ru Fri Feb 21 06:35:22 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Fri, 21 Feb 2014 10:35:22 +0400 Subject: [PATCH 2/3] gsm_data: Add search for TRX by ARFCN In-Reply-To: References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> <1392881304-10753-2-git-send-email-kluchnikovi@gmail.com> Message-ID: Hi Sylvain, > The arfcn should be a uint16_t like is it in the structure. Please try > to be consitent in the usage of types. Thank you for review. I just noticed that function gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr) has the same problem. So I think, I will fix both functions in a separate commit. -- Regards, Ivan Kluchnikov. http://fairwaves.ru From kluchnikovi at gmail.com Thu Feb 20 07:28:24 2014 From: kluchnikovi at gmail.com (Ivan Kluchnikov) Date: Thu, 20 Feb 2014 11:28:24 +0400 Subject: [PATCH 3/3] rsl: Implement handling of rsl Delete Ind message In-Reply-To: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> Message-ID: <1392881304-10753-3-git-send-email-kluchnikovi@gmail.com> If bsc receives Delete_Ind message from bts, bsc should release allocated channel, which was specified in dropped imm_assign message. --- openbsc/src/libbsc/abis_rsl.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index f53ba84..773090a 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -1539,6 +1539,40 @@ static int rsl_rx_ccch_load(struct msgb *msg) return 0; } +/* CCCH is overloaded, IMM_ASSIGN was dropped */ +static int rsl_rx_delete_ind(struct gsm_bts_trx *trx, struct msgb *msg) +{ + struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg); + struct gsm48_imm_ass *ia; + struct gsm_lchan *lchan; + struct gsm_bts_trx *cur_trx; + uint8_t chan_nr; + uint16_t arfcn; + + /* bts didn't send IMM_ASSIGN, so we should release allocated channel */ + if (msgb_l2len(msg) != MACBLOCK_SIZE + 6) + return -EIO; + + ia = (struct gsm48_imm_ass *) (rqd_hdr->data + 2); + + if (ia->msg_type == GSM48_MT_RR_IMM_ASS) { + chan_nr = ia->chan_desc.chan_nr; + arfcn = ia->chan_desc.h0.arfcn_high; + arfcn = (arfcn << 8) | ia->chan_desc.h0.arfcn_low; + cur_trx = gsm_bts_trx_by_arfcn(trx->bts, arfcn); + if (!cur_trx) + return -EINVAL; + lchan = lchan_lookup(cur_trx, chan_nr); + if (!lchan) + return -EINVAL; + if (lchan->state != LCHAN_S_ACTIVE) + return -EINVAL; + rsl_direct_rf_release(lchan); + } + + return 0; +} + static int abis_rsl_rx_cchan(struct msgb *msg) { struct e1inp_sign_link *sign_link = msg->dst; @@ -1557,7 +1591,9 @@ static int abis_rsl_rx_cchan(struct msgb *msg) rc = rsl_rx_ccch_load(msg); break; case RSL_MT_DELETE_IND: - /* CCCH overloaded, IMM_ASSIGN was dropped */ + /* CCCH is overloaded, IMM_ASSIGN was dropped */ + rc = rsl_rx_delete_ind(sign_link->trx, msg); + break; case RSL_MT_CBCH_LOAD_IND: /* current load on the CBCH */ LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message " -- 1.7.9.5 From jerlbeck at sysmocom.de Thu Feb 20 09:24:46 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Thu, 20 Feb 2014 10:24:46 +0100 Subject: [PATCH 3/3] rsl: Implement handling of rsl Delete Ind message In-Reply-To: <1392881304-10753-3-git-send-email-kluchnikovi@gmail.com> References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> <1392881304-10753-3-git-send-email-kluchnikovi@gmail.com> Message-ID: <5305C9DE.3090205@sysmocom.de> On 20.02.2014 08:28, Ivan Kluchnikov wrote: > If bsc receives Delete_Ind message from bts, bsc should release allocated channel, which was specified in dropped imm_assign message. > +/* CCCH is overloaded, IMM_ASSIGN was dropped */ > +static int rsl_rx_delete_ind(struct gsm_bts_trx *trx, struct msgb *msg) > +{ [...] > + > + if (ia->msg_type == GSM48_MT_RR_IMM_ASS) { Why are you not checking again != GSM48_MT_RR_IMM_ASS_REJ? What's with the IMM.ASS.EXT messages? Jacob From Ivan.Kluchnikov at fairwaves.ru Thu Feb 20 10:11:03 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Thu, 20 Feb 2014 14:11:03 +0400 Subject: [PATCH 3/3] rsl: Implement handling of rsl Delete Ind message In-Reply-To: <5305C9DE.3090205@sysmocom.de> References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> <1392881304-10753-3-git-send-email-kluchnikovi@gmail.com> <5305C9DE.3090205@sysmocom.de> Message-ID: Hi Jacob, There are two reasons, why I use == GSM48_MT_RR_IMM_ASS: - currently IMM.ASS.EXT messages are not used in openbsc - this code can handle only IMM.ASS messages, because IMM.ASS.EXT message allocates two channels and we should release these two channels in this case. 2014-02-20 13:24 GMT+04:00 Jacob Erlbeck : > On 20.02.2014 08:28, Ivan Kluchnikov wrote: >> If bsc receives Delete_Ind message from bts, bsc should release allocated channel, which was specified in dropped imm_assign message. >> +/* CCCH is overloaded, IMM_ASSIGN was dropped */ >> +static int rsl_rx_delete_ind(struct gsm_bts_trx *trx, struct msgb *msg) >> +{ > [...] >> + >> + if (ia->msg_type == GSM48_MT_RR_IMM_ASS) { > > Why are you not checking again != GSM48_MT_RR_IMM_ASS_REJ? What's with > the IMM.ASS.EXT messages? > > Jacob > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From holger at freyther.de Thu Feb 20 15:19:02 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Thu, 20 Feb 2014 16:19:02 +0100 Subject: [PATCH 3/3] rsl: Implement handling of rsl Delete Ind message In-Reply-To: References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> <1392881304-10753-3-git-send-email-kluchnikovi@gmail.com> <5305C9DE.3090205@sysmocom.de> Message-ID: <20140220151902.GF3486@xiaoyu.lan> On Thu, Feb 20, 2014 at 02:11:03PM +0400, Ivan Kluchnikov wrote: > Hi Jacob, > > There are two reasons, why I use == GSM48_MT_RR_IMM_ASS: > - currently IMM.ASS.EXT messages are not used in openbsc > - this code can handle only IMM.ASS messages, because IMM.ASS.EXT IMM.ASS.EXT may be created by the BTS. So the argument above is based on a wrong assumption of yours. From Ivan.Kluchnikov at fairwaves.ru Fri Feb 21 06:10:22 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Fri, 21 Feb 2014 10:10:22 +0400 Subject: [PATCH 3/3] rsl: Implement handling of rsl Delete Ind message In-Reply-To: <20140220151902.GF3486@xiaoyu.lan> References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> <1392881304-10753-3-git-send-email-kluchnikovi@gmail.com> <5305C9DE.3090205@sysmocom.de> <20140220151902.GF3486@xiaoyu.lan> Message-ID: 2014-02-20 19:19 GMT+04:00 Holger Hans Peter Freyther : > > IMM.ASS.EXT may be created by the BTS. So the argument above is > based on a wrong assumption of yours. Ok, actually my argument is based on assumption that currently IMM.ASS.EXT messages are not used in openbsc and osmo-bts. And I think, it is true. As I know, IMM.ASS.EXT messages are not created by osmo-bts. Do you know BTSs, which support creating IMM.ASS.EXT or it is just theoretical assumption? -- Regards, Ivan Kluchnikov. http://fairwaves.ru From alexander.chemeris at gmail.com Fri Feb 21 06:17:01 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 21 Feb 2014 10:17:01 +0400 Subject: [PATCH 3/3] rsl: Implement handling of rsl Delete Ind message In-Reply-To: References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> <1392881304-10753-3-git-send-email-kluchnikovi@gmail.com> <5305C9DE.3090205@sysmocom.de> <20140220151902.GF3486@xiaoyu.lan> Message-ID: On Fri, Feb 21, 2014 at 10:10 AM, Ivan Kluchnikov wrote: > 2014-02-20 19:19 GMT+04:00 Holger Hans Peter Freyther : >> >> IMM.ASS.EXT may be created by the BTS. So the argument above is >> based on a wrong assumption of yours. > > Ok, actually my argument is based on assumption that currently > IMM.ASS.EXT messages are not used in openbsc and osmo-bts. And I > think, it is true. > As I know, IMM.ASS.EXT messages are not created by osmo-bts. > Do you know BTSs, which support creating IMM.ASS.EXT or it is just > theoretical assumption? The idea is that OsmoBTS may start supporting this message, while being used with the current version of OpenBSC. Their codebase is not linked together. And thus we should handle this situation. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From Ivan.Kluchnikov at fairwaves.ru Fri Feb 21 06:46:08 2014 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Fri, 21 Feb 2014 10:46:08 +0400 Subject: [PATCH 3/3] rsl: Implement handling of rsl Delete Ind message In-Reply-To: References: <1392881304-10753-1-git-send-email-kluchnikovi@gmail.com> <1392881304-10753-3-git-send-email-kluchnikovi@gmail.com> <5305C9DE.3090205@sysmocom.de> <20140220151902.GF3486@xiaoyu.lan> Message-ID: 2014-02-21 10:17 GMT+04:00 Alexander Chemeris : > The idea is that OsmoBTS may start supporting this message, while > being used with the current version of OpenBSC. Their codebase is not > linked together. And thus we should handle this situation. In this case, it is not a problem to enhance my code in future. But now openbsc just ignores IMM.ASS.EXT messages, like IMM.ASS.REJ messages. -- Regards, Ivan Kluchnikov. http://fairwaves.ru From shamrin at gmail.com Thu Feb 20 22:00:01 2014 From: shamrin at gmail.com (Alexey Shamrin) Date: Fri, 21 Feb 2014 02:00:01 +0400 Subject: [PATCH] db: use WAL journaling mode for higher concurrency Message-ID: <1392933601-19486-1-git-send-email-shamrin@gmail.com> SQLite uses DELETE journaling mode by default. It became a problem on a real-world, actively used network (several hundred subscribers, several thousands SMS per day). Some location updates and SMS delivery marks were not getting written because database file was locked: 2013-12-13_07:26:10.10665 <0002> gsm_subscriber.c:362 Subscriber 334020422525672 ATTACHED LAC=3 2013-12-13_07:26:10.10668 <000d> db.c:170 DBI: 5: database is locked 2013-12-13_07:26:10.10865 <000d> db.c:969 Failed to update Subscriber (by IMSI). Switching to WAL mode fixed the problem. WAL journaling mode is persistent; it stays in effect after closing and reopening the database. WAL mode database requires SQLite >= 3.7.0. All credit belongs Ivan Kluchnikov who diagnosed and fixed this issue. --- openbsc/src/libmsc/db.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index e720c78..3a989d4 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -232,11 +232,18 @@ static int db_configure(void) dbi_result result; result = dbi_conn_query(conn, + "PRAGMA journal_mode = WAL"); + if (!result) + LOGP(DDB, LOGL_NOTICE, "Warning: failed to set journal_mode = WAL.\n"); + else + dbi_result_free(result); + + result = dbi_conn_query(conn, "PRAGMA synchronous = FULL"); if (!result) return -EINVAL; - dbi_result_free(result); + return 0; } -- 1.7.7.5 (Apple Git-26) From peter at stuge.se Thu Feb 20 22:05:11 2014 From: peter at stuge.se (Peter Stuge) Date: Thu, 20 Feb 2014 23:05:11 +0100 Subject: [PATCH] db: use WAL journaling mode for higher concurrency In-Reply-To: <1392933601-19486-1-git-send-email-shamrin@gmail.com> References: <1392933601-19486-1-git-send-email-shamrin@gmail.com> Message-ID: <20140220220511.23639.qmail@stuge.se> Alexey Shamrin wrote: > WAL journaling mode is persistent; it stays in effect after closing and > reopening the database. WAL mode database requires SQLite >= 3.7.0. Think about this some more. It's not enough to state dependencies in a commit message, you need to put them in the build system. A patch to do this will need to touch configure.ac, and I think it would be wise to make the requirement optional. > All credit belongs Ivan Kluchnikov who diagnosed and fixed this issue. Then the commit should list him as author, right? //Peter From shamrin at gmail.com Thu Feb 20 23:04:53 2014 From: shamrin at gmail.com (Alexey Shamrin) Date: Fri, 21 Feb 2014 03:04:53 +0400 Subject: [PATCH] db: use WAL journaling mode for higher concurrency In-Reply-To: <20140220220511.23639.qmail@stuge.se> References: <1392933601-19486-1-git-send-email-shamrin@gmail.com> <20140220220511.23639.qmail@stuge.se> Message-ID: Peter, thank you for your comments! On Fri, Feb 21, 2014 at 2:05 AM, Peter Stuge wrote: > > WAL journaling mode is persistent; it stays in effect after closing and > > reopening the database. WAL mode database requires SQLite >= 3.7.0. > Think about this some more. It's not enough to state dependencies in > a commit message, you need to put them in the build system. A patch > to do this will need to touch configure.ac, and I think it would be > wise to make the requirement optional. Is it really needed in this particular case? OpenBSC would continue working with SQLite < 3.7.0. It would just ignore `journal_mode = WAL` and keep using `DELETE` mode. The only thing that won't work is downgrading from newer SQLite to older while keeping the same database file. Older SQLite would refuse to open the database that was once opened in WAL mode. The file could be downgraded by changing journal_mode on it. But only newer SQLite could do it. Do you think something must be done about it? > > All credit belongs Ivan Kluchnikov who diagnosed and fixed this issue. > Then the commit should list him as author, right? As far as I understand, Ivan noticed the problem, opened the database with sqlite3 command, entered `PRAGMA journal_mode = WAL` and noticed the problem was now gone. Then he told me about it and suggested to write a patch. I found where to put this command in OpenBSC source, tested that it indeed persists WAL mode in the file, wrote the commit message and sent it to mailing list. I don't know what this means about the commit authorship. I can do it either way. Alexey From peter at stuge.se Thu Feb 20 23:52:08 2014 From: peter at stuge.se (Peter Stuge) Date: Fri, 21 Feb 2014 00:52:08 +0100 Subject: [PATCH] db: use WAL journaling mode for higher concurrency In-Reply-To: References: <1392933601-19486-1-git-send-email-shamrin@gmail.com> <20140220220511.23639.qmail@stuge.se> Message-ID: <20140220235208.30940.qmail@stuge.se> Alexey Shamrin wrote: > > > WAL journaling mode is persistent; it stays in effect after closing and > > > reopening the database. WAL mode database requires SQLite >= 3.7.0. > > Think about this some more. It's not enough to state dependencies in > > a commit message, you need to put them in the build system. A patch > > to do this will need to touch configure.ac, and I think it would be > > wise to make the requirement optional. > > Is it really needed in this particular case? OpenBSC would continue > working with SQLite < 3.7.0. It would just ignore `journal_mode = WAL` > and keep using `DELETE` mode. The only thing that won't work is > downgrading from newer SQLite to older while keeping the same database > file. Older SQLite would refuse to open the database that was once > opened in WAL mode. The file could be downgraded by changing > journal_mode on it. But only newer SQLite could do it. Do you think > something must be done about it? Thanks for explaining in more detail! I do think something more needs to be done but I'm no longer so sure what I'd prefer.. I think it would be good to have a build-time (configure) option to explicitly enable WAL journalling and thus also require the newer SQLite version. I also think that a version of OpenBSC built without WAL enabled has to be able to recognize databases created by OpenBSC built *with* WAL enabled, and tell the user what needs to be done to make the database work. Finally, maybe the database version number should also be bumped, to allow OpenBSC using >=3.7 to know whether a database needs WAL or not. > > > All credit belongs Ivan Kluchnikov who diagnosed and fixed this issue. > > Then the commit should list him as author, right? > > As far as I understand, Ivan noticed the problem, opened the database > with sqlite3 command, entered `PRAGMA journal_mode = WAL` and noticed > the problem was now gone. Then he told me about it and suggested to > write a patch. I found where to put this command in OpenBSC source, > tested that it indeed persists WAL mode in the file, wrote the commit > message and sent it to mailing list. Oh ok, yes, then I think you should be the author and actually some more of the above explanation could easily be in the commit message. :) //Peter From alexander.chemeris at gmail.com Fri Feb 21 06:15:22 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Fri, 21 Feb 2014 10:15:22 +0400 Subject: [PATCH] db: use WAL journaling mode for higher concurrency In-Reply-To: <20140220235208.30940.qmail@stuge.se> References: <1392933601-19486-1-git-send-email-shamrin@gmail.com> <20140220220511.23639.qmail@stuge.se> <20140220235208.30940.qmail@stuge.se> Message-ID: On Fri, Feb 21, 2014 at 3:52 AM, Peter Stuge wrote: > Alexey Shamrin wrote: > > > > WAL journaling mode is persistent; it stays in effect after closing and > > > > reopening the database. WAL mode database requires SQLite >= 3.7.0. > > > Think about this some more. It's not enough to state dependencies in > > > a commit message, you need to put them in the build system. A patch > > > to do this will need to touch configure.ac, and I think it would be > > > wise to make the requirement optional. > > > > Is it really needed in this particular case? OpenBSC would continue > > working with SQLite < 3.7.0. It would just ignore `journal_mode = WAL` > > and keep using `DELETE` mode. The only thing that won't work is > > downgrading from newer SQLite to older while keeping the same database > > file. Older SQLite would refuse to open the database that was once > > opened in WAL mode. The file could be downgraded by changing > > journal_mode on it. But only newer SQLite could do it. Do you think > > something must be done about it? > > Thanks for explaining in more detail! I do think something more needs > to be done but I'm no longer so sure what I'd prefer.. > > I think it would be good to have a build-time (configure) option to > explicitly enable WAL journalling and thus also require the newer > SQLite version. I don't think we need configure check - see my explanation below. > I also think that a version of OpenBSC built without WAL enabled > has to be able to recognize databases created by OpenBSC built *with* > WAL enabled, and tell the user what needs to be done to make the > database work. > > Finally, maybe the database version number should also be bumped, to > allow OpenBSC using >=3.7 to know whether a database needs WAL or not. I'm not sure about the DB version bump, as it doesn't touch DB structure. OTOH I think we should have a code which enables WAL in old DBs, and then it's reasonable to do in the section where we upgrade DBs. OTOH, an OpenBSC with SQLite < 3.7 should be able to jump onto a potential next DB revision without jumping over this "pseudo-revison". Otherwise it would be meaningless - DB version won't tell us whether we have WAL or not. After all, I think the proper way is as follows: 1. OpenBSC should try to set WAL pragma on every start, unless a --no-wal command line option is specified: 2. OpenBSC should check SQLite version on startup and if it's <3.7 - print a warning to log that WAL can't be enabled and we recommend upgrading. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From holger at freyther.de Fri Feb 21 12:53:02 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Fri, 21 Feb 2014 13:53:02 +0100 Subject: [PATCH] db: use WAL journaling mode for higher concurrency In-Reply-To: <1392933601-19486-1-git-send-email-shamrin@gmail.com> References: <1392933601-19486-1-git-send-email-shamrin@gmail.com> Message-ID: <20140221125302.GC16725@xiaoyu.lan> On Fri, Feb 21, 2014 at 02:00:01AM +0400, Alexey Shamrin wrote: Hi, > SQLite uses DELETE journaling mode by default. It became a problem on a > real-world, actively used network (several hundred subscribers, several > thousands SMS per day). Some location updates and SMS delivery marks > were not getting written because database file was locked: > > 2013-12-13_07:26:10.10665 <0002> gsm_subscriber.c:362 Subscriber 334020422525672 ATTACHED LAC=3 > 2013-12-13_07:26:10.10668 <000d> db.c:170 DBI: 5: database is locked > 2013-12-13_07:26:10.10865 <000d> db.c:969 Failed to update Subscriber (by IMSI). the answer right now is really not to access the database/tables from outside. So the "fix" is really just a workaround and WAL does not come for free either. In case you want to improve the database code please have a look here[1]. In the long run our interface should be async, we should use the DB APIs directly, use prepared statements, etc. holger [1] http://openbsc.osmocom.org/trac/wiki/Tasks/NITBAsyncDatabase From shamrin at gmail.com Sat Feb 22 08:19:09 2014 From: shamrin at gmail.com (Alexey Shamrin) Date: Sat, 22 Feb 2014 12:19:09 +0400 Subject: [PATCH] db: use WAL journaling mode for higher concurrency In-Reply-To: <20140221125302.GC16725@xiaoyu.lan> References: <1392933601-19486-1-git-send-email-shamrin@gmail.com> <20140221125302.GC16725@xiaoyu.lan> Message-ID: Hi Holger, On Fri, Feb 21, 2014 at 4:53 PM, Holger Hans Peter Freyther wrote: > the answer right now is really not to access the database/tables from outside. Thank you! I was under impression that OpenBSC was locking *itself* from database file. But this is obviously wrong, OpenBSC is single-threaded. I now know there was another script periodically querying SQLite file. That said, it's not practical to never touch DB from outside and use only OpenBSC VTY interface. The latter doesn't allow custom SQL queries. Fortunately, the workaround is simple: issue `PRAGMA journal_mode = WAL` from `sqlite3` command once, when deploying OpenBSC. > So the "fix" is really just a workaround and WAL does not come for free either. As far as I can tell, most disadvantages of WAL [1] don't concern OpenBSC. Possibly except the need to have write privileges to DB directory in order to read from WAL database. > In case you want to improve the database code please have > a look here[1]. In the long run our interface should be async, we should > use the DB APIs directly, use prepared statements, etc. > [1] http://openbsc.osmocom.org/trac/wiki/Tasks/NITBAsyncDatabase Yes, but switching the async interface alone won't fix the 'database is locked' problem. Only if we also switch to MySQL/Postgres. What do you mean by "use the DB APIs directly"? [1]: https://www.sqlite.org/draft/wal.htm Alexey From holger at freyther.de Sat Feb 22 08:48:39 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 22 Feb 2014 09:48:39 +0100 Subject: [PATCH] db: use WAL journaling mode for higher concurrency In-Reply-To: References: <1392933601-19486-1-git-send-email-shamrin@gmail.com> <20140221125302.GC16725@xiaoyu.lan> Message-ID: <20140222084839.GI7741@xiaoyu.lan> On Sat, Feb 22, 2014 at 12:19:09PM +0400, Alexey Shamrin wrote: Hi, > That said, it's not practical to never touch DB from outside and use > only OpenBSC VTY interface. The latter doesn't allow custom SQL > queries. Fortunately, the workaround is simple: issue `PRAGMA > journal_mode = WAL` from `sqlite3` command once, when deploying > OpenBSC. To ask the other way around. Which queries do yo run? Do you UPDATE subscriber structures too? > Yes, but switching the async interface alone won't fix the 'database > is locked' problem. Only if we also switch to MySQL/Postgres. What do > you mean by "use the DB APIs directly"? My understanding is that real and bigger deployments should use a database server like Postgres. Currently we are using the libdbi and it doesn't really work well with SQLite[1]. For every column we SELECT libdbi will issue a PRAGMA to determine the type every time we query. What I say is we need fixes and not work-arounds. The first step is making the code aware that a database lookup can take time. holger [1] http://comments.gmane.org/gmane.comp.db.libdbi.drivers/498 From alexander.chemeris at gmail.com Sat Feb 22 08:58:33 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 22 Feb 2014 12:58:33 +0400 Subject: [PATCH] db: use WAL journaling mode for higher concurrency In-Reply-To: <20140222084839.GI7741@xiaoyu.lan> References: <1392933601-19486-1-git-send-email-shamrin@gmail.com> <20140221125302.GC16725@xiaoyu.lan> <20140222084839.GI7741@xiaoyu.lan> Message-ID: On Sat, Feb 22, 2014 at 12:48 PM, Holger Hans Peter Freyther wrote: > On Sat, Feb 22, 2014 at 12:19:09PM +0400, Alexey Shamrin wrote: >> That said, it's not practical to never touch DB from outside and use >> only OpenBSC VTY interface. The latter doesn't allow custom SQL >> queries. Fortunately, the workaround is simple: issue `PRAGMA >> journal_mode = WAL` from `sqlite3` command once, when deploying >> OpenBSC. > > To ask the other way around. Which queries do yo run? Do you UPDATE > subscriber structures too? SELECT only so far. We do not use UPDATE and INSERT or do this very rarely. > What I say is we need fixes and not work-arounds. The first step is > making the code aware that a database lookup can take time. I tend to agree that making WAL into the OpenBSC code doesn't worth the effort, which would be better spent on actually fixing the issue. It's easier to enable WAL from a script when we need to do so. -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From jerlbeck at sysmocom.de Fri Feb 21 14:09:11 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 21 Feb 2014 15:09:11 +0100 Subject: [PATCH 1/5] bts/vty: Use new vty_install_default() function, adjust prompts Message-ID: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> This patch removes the local 'end' and 'exit' implementations (which aren't used anyway) and uses the generic ones provided by libosmocore instead, which are enabled automatically when vty_install_default() is used. The prompt strings are modified to match those in libosmocore/openbsc. Ticket: OW#952 Sponsored-by: On-Waves ehf --- src/common/vty.c | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/src/common/vty.c b/src/common/vty.c index 5eddc8d..d818f3f 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -71,37 +71,6 @@ int bts_vty_is_config_node(struct vty *vty, int node) } } -gDEFUN(ournode_exit, ournode_exit_cmd, "exit", - "Exit current node, go down to provious node") -{ - switch (vty->node) { - case TRX_NODE: - vty->node = BTS_NODE; - { - struct gsm_bts_trx *trx = vty->index; - vty->index = trx->bts; - } - break; - default: - break; - } - return CMD_SUCCESS; -} - -gDEFUN(ournode_end, ournode_end_cmd, "end", - "End current mode and change to enable mode") -{ - switch (vty->node) { - default: - vty_config_unlock(vty); - vty->node = ENABLE_NODE; - vty->index = NULL; - vty->index_sub = NULL; - break; - } - return CMD_SUCCESS; -} - static const char osmobts_copyright[] = "Copyright (C) 2010, 2011 by Harald Welte, Andreas Eversberg and On-Waves\r\n" "License AGPLv3+: GNU AGPL version 3 or later \r\n" @@ -140,13 +109,13 @@ struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num) static struct cmd_node bts_node = { BTS_NODE, - "%s(bts)#", + "%s(config-bts)# ", 1, }; static struct cmd_node trx_node = { TRX_NODE, - "%s(trx)#", + "%s(config-bts-trx)# ", 1, }; @@ -509,7 +478,7 @@ int bts_vty_init(const struct log_info *cat) install_node(&bts_node, config_write_bts); install_element(CONFIG_NODE, &cfg_bts_cmd); - install_default(BTS_NODE); + vty_install_default(BTS_NODE); install_element(BTS_NODE, &cfg_bts_unit_id_cmd); install_element(BTS_NODE, &cfg_bts_oml_ip_cmd); install_element(BTS_NODE, &cfg_bts_rtp_bind_ip_cmd); @@ -523,7 +492,7 @@ int bts_vty_init(const struct log_info *cat) /* add and link to TRX config node */ install_element(BTS_NODE, &cfg_bts_trx_cmd); install_node(&trx_node, config_write_dummy); - install_default(TRX_NODE); + vty_install_default(TRX_NODE); install_element(ENABLE_NODE, &bts_t_t_l_jitter_buf_cmd); -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 14:09:12 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 21 Feb 2014 15:09:12 +0100 Subject: [PATCH 2/5] agch/rsl: Fix msgb handling for IMMEDIATE ASSIGN In-Reply-To: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> References: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1392991755-3107-2-git-send-email-jerlbeck@sysmocom.de> Currently, the msg->data pointer is just set to the IMMEDIATE ASSIGN message and the len is adjusted accordingly. Unfortunately, this leaves l2h (pointing to the RSL header) and l3h (pointing to the FULL_IMM_ASS_INFO IE) in an undefined state (outside of [data, tail]). The code in bts.c accesses the message via msg->data. This patch sets l3h and l2h correctly. msgb_l3() will point to the start of the IMM ASS message and should be used instead of msg->data. Sponsored-by: On-Waves ehf --- src/common/rsl.c | 4 +++- src/osmo-bts-sysmo/l1_if.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common/rsl.c b/src/common/rsl.c index 6a54612..821b1be 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -466,7 +466,9 @@ static int rsl_rx_imm_ass(struct gsm_bts_trx *trx, struct msgb *msg) return rsl_tx_error_report(trx, RSL_ERR_MAND_IE_ERROR); /* cut down msg to the 04.08 RR part */ - msg->data = (uint8_t *) TLVP_VAL(&tp, RSL_IE_FULL_IMM_ASS_INFO); + msg->l3h = (uint8_t *) TLVP_VAL(&tp, RSL_IE_FULL_IMM_ASS_INFO); + msg->data = msg->l3h; + msg->l2h = NULL; msg->len = TLVP_LEN(&tp, RSL_IE_FULL_IMM_ASS_INFO); /* put into the AGCH queue of the BTS */ diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 3cd3be5..39c020b 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -519,7 +519,7 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, if (!msg) memcpy(msu_param->u8Buffer, fill_frame, GSM_MACBLOCK_LEN); else { - memcpy(msu_param->u8Buffer, msg->data, msg->len); + memcpy(msu_param->u8Buffer, msgb_l3(msg), msgb_l3len(msg)); msgb_free(msg); } } -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 14:09:13 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 21 Feb 2014 15:09:13 +0100 Subject: [PATCH 3/5] agch: Log error if BS_AG_BLKS_RES is != 1 in SI3 In-Reply-To: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> References: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1392991755-3107-3-git-send-email-jerlbeck@sysmocom.de> Currently, the DSP is always configured with u8NbrOfAgch = 1 before SYSINFO type 3 is received. Thus using a different value for BS_AG_BLKS_RES may lead to inconsistencies and MS failing to receive paging messages properly. This patch adds a warning and error logging and should be reverted when initialisation is done in proper order. Sponsored-by: On-Waves ehf --- src/common/paging.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/common/paging.c b/src/common/paging.c index cd1c370..7c71c6f 100644 --- a/src/common/paging.c +++ b/src/common/paging.c @@ -535,6 +535,12 @@ static int paging_signal_cbfn(unsigned int subsys, unsigned int signal, void *hd struct paging_state *ps = btsb->paging_state; struct gsm48_system_information_type_3 *si3 = (void *) bts->si_buf[SYSINFO_TYPE_3]; +#warning "TODO: Remove this when setting u8NbrOfAgch is implemented properly" + if (si3->control_channel_desc.bs_ag_blks_res != 1) + LOGP(DPAG, LOGL_ERROR, + "Paging: BS_AG_BLKS_RES = %d != 1 not fully supported\n", + si3->control_channel_desc.bs_ag_blks_res); + paging_si_update(ps, &si3->control_channel_desc); } return 0; -- 1.7.9.5 From holger at freyther.de Sat Feb 22 07:44:23 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 22 Feb 2014 08:44:23 +0100 Subject: [PATCH 3/5] agch: Log error if BS_AG_BLKS_RES is != 1 in SI3 In-Reply-To: <1392991755-3107-3-git-send-email-jerlbeck@sysmocom.de> References: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> <1392991755-3107-3-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140222074423.GE7741@xiaoyu.lan> On Fri, Feb 21, 2014 at 03:09:13PM +0100, Jacob Erlbeck wrote: Dear Jacob, > Currently, the DSP is always configured with u8NbrOfAgch = 1 before > SYSINFO type 3 is received. Thus using a different value for > BS_AG_BLKS_RES may lead to inconsistencies and MS failing to receive > paging messages properly. thanks for finding and pointing out this inconsistency! I think the log message will not help much as not many people will look at the log output and specially not during the bring-up of the BTS. I think we should/could do: * Add this check to OpenBSC for the sysmoBTS bts type. * Document this in our manual as a known issue. * Create a backlog item to resolve this issue. holger From jerlbeck at sysmocom.de Fri Feb 21 14:09:14 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 21 Feb 2014 15:09:14 +0100 Subject: [PATCH 4/5] agch: Keep track of AGCH queue length In-Reply-To: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> References: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1392991755-3107-4-git-send-email-jerlbeck@sysmocom.de> This patch adds and updates btsb->agch_queue_length to keep track of the queue length. Sponsored-by: On-Waves ehf --- include/osmo-bts/gsm_data.h | 1 + src/common/bts.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index c6cd7e4..aee56a9 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -49,6 +49,7 @@ struct gsm_bts_role_bts { uint8_t ny1; uint8_t max_ta; struct llist_head agch_queue; + int agch_queue_length; struct paging_state *paging_state; char *bsc_oml_host; unsigned int rtp_jitter_buf_ms; diff --git a/src/common/bts.c b/src/common/bts.c index 2ac411d..35fc302 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -65,6 +65,7 @@ int bts_init(struct gsm_bts *bts) bts->role = btsb = talloc_zero(bts, struct gsm_bts_role_bts); INIT_LLIST_HEAD(&btsb->agch_queue); + btsb->agch_queue_length = 0; /* configurable via VTY */ btsb->paging_state = paging_init(btsb, 200, 0); @@ -214,6 +215,7 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) /* FIXME: implement max queue length */ msgb_enqueue(&btsb->agch_queue, msg); + btsb->agch_queue_length++; return 0; } @@ -221,8 +223,12 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) struct msgb *bts_agch_dequeue(struct gsm_bts *bts) { struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + struct msgb *msg = msgb_dequeue(&btsb->agch_queue); + if (!msg) + return NULL; - return msgb_dequeue(&btsb->agch_queue); + btsb->agch_queue_length--; + return msg; } int bts_supports_cipher(struct gsm_bts_role_bts *bts, int rsl_cipher) -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 14:09:15 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 21 Feb 2014 15:09:15 +0100 Subject: [PATCH 5/5] agch/pch: Put CCCH message generation into common In-Reply-To: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> References: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1392991755-3107-5-git-send-email-jerlbeck@sysmocom.de> This patch adds a common function bts_ccch_copy_msg() that provides and schedules AGCH and PCH messages. It is basically a frontend to paging_gen_msg() and bts_agch_dequeue() and contains refactored code from l1_if.c. Sponsored-by: On-Waves ehf --- include/osmo-bts/bts.h | 2 ++ src/common/bts.c | 22 ++++++++++++++++++++++ src/osmo-bts-sysmo/l1_if.c | 17 ++++------------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index e202035..49ef617 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -26,6 +26,8 @@ void bts_setup_slot(struct gsm_bts_trx_ts *slot, uint8_t comb); int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg); struct msgb *bts_agch_dequeue(struct gsm_bts *bts); +int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, + int is_ag_res); uint8_t *bts_sysinfo_get(struct gsm_bts *bts, struct gsm_time *g_time); uint8_t *lchan_sacch_get(struct gsm_lchan *lchan, struct gsm_time *g_time); diff --git a/src/common/bts.c b/src/common/bts.c index 35fc302..e17428d 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -231,6 +231,28 @@ struct msgb *bts_agch_dequeue(struct gsm_bts *bts) return msg; } +int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, + int is_ag_res) +{ + struct msgb *msg; + struct gsm_bts_role_bts *btsb = bts->role; + int rc; + + if (!is_ag_res) + return paging_gen_msg(btsb->paging_state, out_buf, gt); + + /* special queue of messages from IMM ASS CMD */ + msg = bts_agch_dequeue(bts); + if (!msg) + return 0; + + memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg)); + rc = msg->len; + msgb_free(msg); + + return rc; +} + int bts_supports_cipher(struct gsm_bts_role_bts *bts, int rsl_cipher) { int sup; diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 39c020b..ba34c69 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -373,7 +373,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, { struct gsm_bts_trx *trx = fl1->priv; struct gsm_bts *bts = trx->bts; - struct gsm_bts_role_bts *btsb = bts->role; struct msgb *resp_msg; GsmL1_PhDataReq_t *data_req; GsmL1_MsgUnitParam_t *msu_param; @@ -513,19 +512,11 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, } break; case GsmL1_Sapi_Agch: - /* special queue of messages from IMM ASS CMD */ - { - struct msgb *msg = bts_agch_dequeue(bts); - if (!msg) - memcpy(msu_param->u8Buffer, fill_frame, GSM_MACBLOCK_LEN); - else { - memcpy(msu_param->u8Buffer, msgb_l3(msg), msgb_l3len(msg)); - msgb_free(msg); - } - } - break; case GsmL1_Sapi_Pch: - rc = paging_gen_msg(btsb->paging_state, msu_param->u8Buffer, &g_time); + rc = bts_ccch_copy_msg(bts, msu_param->u8Buffer, &g_time, + rts_ind->sapi == GsmL1_Sapi_Agch); + if (rc <= 0) + memcpy(msu_param->u8Buffer, fill_frame, GSM_MACBLOCK_LEN); break; case GsmL1_Sapi_TchF: case GsmL1_Sapi_TchH: -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 17:06:30 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 21 Feb 2014 18:06:30 +0100 Subject: [PATCH 5/5] agch/pch: Put CCCH message generation into common In-Reply-To: <1392991755-3107-5-git-send-email-jerlbeck@sysmocom.de> References: <1392991755-3107-1-git-send-email-jerlbeck@sysmocom.de> <1392991755-3107-5-git-send-email-jerlbeck@sysmocom.de> Message-ID: <53078796.7000306@sysmocom.de> Hi Holger, in case you merge, please fix the length computation below: On 21.02.2014 15:09, Jacob Erlbeck wrote: > --- a/src/common/bts.c > +++ b/src/common/bts.c > +int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, > + int is_ag_res) > +{ > + > + memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg)); > + rc = msg->len; It's rc = msgb_l3len(msg); which accidentally delivers the same value. Thanks, Jacob From jerlbeck at sysmocom.de Fri Feb 21 19:56:16 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 21 Feb 2014 20:56:16 +0100 Subject: [PATCH] agch/pch: Put CCCH message generation into common In-Reply-To: <1392991755-3107-5-git-send-email-jerlbeck@sysmocom.de> References: <1392991755-3107-5-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393012576-13888-1-git-send-email-jerlbeck@sysmocom.de> This patch adds a common function bts_ccch_copy_msg() that provides and schedules AGCH and PCH messages. It is basically a frontend to paging_gen_msg() and bts_agch_dequeue() and contains refactored code from l1_if.c. Sponsored-by: On-Waves ehf --- include/osmo-bts/bts.h | 2 ++ src/common/bts.c | 22 ++++++++++++++++++++++ src/osmo-bts-sysmo/l1_if.c | 17 ++++------------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index e202035..49ef617 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -26,6 +26,8 @@ void bts_setup_slot(struct gsm_bts_trx_ts *slot, uint8_t comb); int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg); struct msgb *bts_agch_dequeue(struct gsm_bts *bts); +int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, + int is_ag_res); uint8_t *bts_sysinfo_get(struct gsm_bts *bts, struct gsm_time *g_time); uint8_t *lchan_sacch_get(struct gsm_lchan *lchan, struct gsm_time *g_time); diff --git a/src/common/bts.c b/src/common/bts.c index 35fc302..7bbf587 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -231,6 +231,28 @@ struct msgb *bts_agch_dequeue(struct gsm_bts *bts) return msg; } +int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, + int is_ag_res) +{ + struct msgb *msg; + struct gsm_bts_role_bts *btsb = bts->role; + int rc; + + if (!is_ag_res) + return paging_gen_msg(btsb->paging_state, out_buf, gt); + + /* special queue of messages from IMM ASS CMD */ + msg = bts_agch_dequeue(bts); + if (!msg) + return 0; + + memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg)); + rc = msgb_l3len(msg); + msgb_free(msg); + + return rc; +} + int bts_supports_cipher(struct gsm_bts_role_bts *bts, int rsl_cipher) { int sup; diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 39c020b..ba34c69 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -373,7 +373,6 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, { struct gsm_bts_trx *trx = fl1->priv; struct gsm_bts *bts = trx->bts; - struct gsm_bts_role_bts *btsb = bts->role; struct msgb *resp_msg; GsmL1_PhDataReq_t *data_req; GsmL1_MsgUnitParam_t *msu_param; @@ -513,19 +512,11 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, } break; case GsmL1_Sapi_Agch: - /* special queue of messages from IMM ASS CMD */ - { - struct msgb *msg = bts_agch_dequeue(bts); - if (!msg) - memcpy(msu_param->u8Buffer, fill_frame, GSM_MACBLOCK_LEN); - else { - memcpy(msu_param->u8Buffer, msgb_l3(msg), msgb_l3len(msg)); - msgb_free(msg); - } - } - break; case GsmL1_Sapi_Pch: - rc = paging_gen_msg(btsb->paging_state, msu_param->u8Buffer, &g_time); + rc = bts_ccch_copy_msg(bts, msu_param->u8Buffer, &g_time, + rts_ind->sapi == GsmL1_Sapi_Agch); + if (rc <= 0) + memcpy(msu_param->u8Buffer, fill_frame, GSM_MACBLOCK_LEN); break; case GsmL1_Sapi_TchF: case GsmL1_Sapi_TchH: -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 23:36:02 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Sat, 22 Feb 2014 00:36:02 +0100 Subject: [PATCH 1/8] agch: Recalculate length limit of AGCH queue Message-ID: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> This patch adds a function bts_update_agch_max_queue_length() to compute a limit of the AGCH queue. This is based on the idea, that the AGCH queue has a limited drain rate and that CHANNEL REQUESTs must be answered within a certain time frame, given by the minimum value of T3126 (see GSM 04.08). When the AGCH queue reaches that limit, the last message would be delivered in time if there were no other delays involved (which is not the case). The calculation is based on the ratio of the number RACH slots and CCCH blocks per time: Lmax = (T + 2*S) / R_RACH * R_CCCH where T3126_min = (T + 2*S) / R_RACH R_RACH is the RACH slot rate (e.g. RACHs per multiframe) R_CCCH is the CCCH block rate (same time base like R_RACH) The value depends control_channel_desc.ccch_conf and rach_control.tx_integer (both from SYSINFO_TYPE_3) and should therefore by called at least each time after one of these is changed. For this reason, a signal callback is registered under SS_GLOBAL/S_NEW_SYSINFO which invokes bts_update_agch_max_queue_length(). Based-On: "bts: Calculate length of agch queue" by Ivan Kluchnikov --- include/osmo-bts/bts.h | 1 + include/osmo-bts/gsm_data.h | 1 + src/common/bts.c | 86 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index 49ef617..ec061e8 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -26,6 +26,7 @@ void bts_setup_slot(struct gsm_bts_trx_ts *slot, uint8_t comb); int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg); struct msgb *bts_agch_dequeue(struct gsm_bts *bts); +void bts_update_agch_max_queue_length(struct gsm_bts *bts); int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, int is_ag_res); diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index aee56a9..ea3fa5e 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -50,6 +50,7 @@ struct gsm_bts_role_bts { uint8_t max_ta; struct llist_head agch_queue; int agch_queue_length; + int agch_max_queue_length; struct paging_state *paging_state; char *bsc_oml_host; unsigned int rtp_jitter_buf_ms; diff --git a/src/common/bts.c b/src/common/bts.c index 7bbf587..2a6c1bd 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -42,6 +42,7 @@ #include #include #include +#include struct gsm_network bts_gsmnet = { @@ -51,11 +52,32 @@ struct gsm_network bts_gsmnet = { void *tall_bts_ctx; +/* Table 3.1 TS 04.08: Values of parameter S */ +static const uint8_t tx_integer[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 25, 32, 50, +}; + +static const uint8_t s_values[][2] = { + { 55, 41 }, { 76, 52 }, { 109, 58 }, { 163, 86 }, { 217, 115 }, +}; + +static int bts_signal_cbfn(unsigned int subsys, unsigned int signal, + void *hdlr_data, void *signal_data) +{ + if (subsys == SS_GLOBAL && signal == S_NEW_SYSINFO) { + struct gsm_bts *bts = signal_data; + + bts_update_agch_max_queue_length(bts); + } + return 0; +} + int bts_init(struct gsm_bts *bts) { struct gsm_bts_role_bts *btsb; struct gsm_bts_trx *trx; int rc; + static int initialized = 0; /* add to list of BTSs */ llist_add_tail(&bts->list, &bts_gsmnet.bts_list); @@ -110,6 +132,11 @@ int bts_init(struct gsm_bts *bts) bts_gsmnet.num_bts++; + if (!initialized) { + osmo_signal_register_handler(SS_GLOBAL, bts_signal_cbfn, NULL); + initialized = 1; + } + return rc; } @@ -209,11 +236,68 @@ int lchan_init_lapdm(struct gsm_lchan *lchan) return 0; } +#define CCCH_RACH_RATIO_COMBINED256 (256*1/9) +#define CCCH_RACH_RATIO_SEPARATE256 (256*10/55) + +void bts_update_agch_max_queue_length(struct gsm_bts *bts) +{ + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + struct gsm48_system_information_type_3 *si3; + int T, S, ccch_rach_ratio256, i; + int T_group = 0; + int ccch_comb = 0; + int old_max_length = btsb->agch_max_queue_length; + + if (!(bts->si_valid & (1<control_channel_desc.ccch_conf == 1) + ccch_comb = 1; + + /* + * The calculation is based on the ratio of the number RACH slots and + * CCCH blocks per time: + * Lmax = (T + 2*S) / R_RACH * R_CCCH + * where + * T3126_min = (T + 2*S) / R_RACH, as defined in GSM 04.08, 11.1.1 + * R_RACH is the RACH slot rate (e.g. RACHs per multiframe) + * R_CCCH is the CCCH block rate (same time base like R_RACH) + * S and T are defined in GSM 04.08, 3.3.1.1.2 + * The ratio is mainly influenced by the downlink only channels + * (BCCH, FCCH, SCH, CBCH) that can not used for CCCH. + * An estimation with an error of < 10% is used: + * ~ 1/9 if CCCH is combined with SDCCH, and + * ~ 1/5.5 otherwise. + */ + ccch_rach_ratio256 = ccch_comb ? + CCCH_RACH_RATIO_COMBINED256 : + CCCH_RACH_RATIO_SEPARATE256; + + T = si3->rach_control.tx_integer; + for (i = 0; i < 15; i++) { + if (tx_integer[i] == T) { + T_group = i % 5; + break; + } + } + S = s_values[T_group][ccch_comb]; + + btsb->agch_max_queue_length = (T + 2 * S) * ccch_rach_ratio256 / 256; + + if (btsb->agch_max_queue_length != old_max_length) + LOGP(DRSL, LOGL_INFO, "Updated AGCH max queue length to %d, " + "T = %d, S = %d, CCCH/RACH = %d%%, AG_BLK_RES = %d\n", + btsb->agch_max_queue_length, + T, S, ccch_rach_ratio256 * 100 / 256, + si3->control_channel_desc.bs_ag_blks_res); +} + int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) { struct gsm_bts_role_bts *btsb = bts_role_bts(bts); - /* FIXME: implement max queue length */ msgb_enqueue(&btsb->agch_queue, msg); btsb->agch_queue_length++; -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 23:36:03 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Sat, 22 Feb 2014 00:36:03 +0100 Subject: [PATCH 2/8] agch: Added queue operation logging (DEBUG) In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393025770-14352-2-git-send-email-jerlbeck@sysmocom.de> This adds debug logging to the AGCH queue operations. Sponsored-by: On-Waves ehf --- src/common/bts.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/common/bts.c b/src/common/bts.c index 2a6c1bd..c834786 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -301,6 +301,12 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) msgb_enqueue(&btsb->agch_queue, msg); btsb->agch_queue_length++; + LOGP(DSUM, LOGL_DEBUG, + "AGCH: enqueued message type 0x%02x, length = %d/%d, msg = %s\n", + ((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type, + btsb->agch_queue_length, btsb->agch_max_queue_length, + osmo_hexdump(msgb_l3(msg), msgb_l3len(msg))); + return 0; } @@ -312,6 +318,10 @@ struct msgb *bts_agch_dequeue(struct gsm_bts *bts) return NULL; btsb->agch_queue_length--; + LOGP(DSUM, LOGL_DEBUG, + "AGCH: dequeued message type 0x%02x, length = %d/%d\n", + ((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type, + btsb->agch_queue_length, btsb->agch_max_queue_length); return msg; } @@ -332,6 +342,10 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg)); rc = msgb_l3len(msg); + LOGP(DSUM, LOGL_DEBUG, + "AGCH: copied message type 0x%02x to %s block\n", + ((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type, + is_ag_res ? "AGCH" : "PCH"); msgb_free(msg); return rc; -- 1.7.9.5 From holger at freyther.de Sat Feb 22 07:58:32 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 22 Feb 2014 08:58:32 +0100 Subject: [PATCH 2/8] agch: Added queue operation logging (DEBUG) In-Reply-To: <1393025770-14352-2-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> <1393025770-14352-2-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140222075832.GG7741@xiaoyu.lan> On Sat, Feb 22, 2014 at 12:36:03AM +0100, Jacob Erlbeck wrote: Dear Jacob, > This adds debug logging to the AGCH queue operations. I'm a bit reluctant to add more logging. In the past I have thrown out a lot of log messages. Do we need these messages? What kind of issues can we diagnose that we can't get through observing statistics and/or the A-link to the BSC/NITB? kind regards holger From alexander.chemeris at gmail.com Sat Feb 22 08:10:11 2014 From: alexander.chemeris at gmail.com (Alexander Chemeris) Date: Sat, 22 Feb 2014 12:10:11 +0400 Subject: [PATCH 2/8] agch: Added queue operation logging (DEBUG) In-Reply-To: <20140222075832.GG7741@xiaoyu.lan> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> <1393025770-14352-2-git-send-email-jerlbeck@sysmocom.de> <20140222075832.GG7741@xiaoyu.lan> Message-ID: On Sat, Feb 22, 2014 at 11:58 AM, Holger Hans Peter Freyther wrote: > > On Sat, Feb 22, 2014 at 12:36:03AM +0100, Jacob Erlbeck wrote: > > This adds debug logging to the AGCH queue operations. > > I'm a bit reluctant to add more logging. In the past I have thrown out > a lot of log messages. Do we need these messages? What kind of issues > can we diagnose that we can't get through observing statistics and/or the > A-link to the BSC/NITB? At DEBUG level this should not harm much. Benefits of logs that it's easier to correlate with other events logged at the same place. And that you could use them retrospectively (given you have the proper debugging level enabled). On most machines overhead of running full logging is minimal, while it makes actual debugging much easier. If you worry about performance drop just because of the check, I think it make sense to have a special macro for DEBUG level, which will turn into a NOP in case of NDEBUG. What do you think? -- Regards, Alexander Chemeris. CEO, Fairwaves LLC / ??? ??????? http://fairwaves.ru From jerlbeck at sysmocom.de Fri Feb 21 23:36:04 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Sat, 22 Feb 2014 00:36:04 +0100 Subject: [PATCH 3/8] agch: Add simple counters In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393025770-14352-3-git-send-email-jerlbeck@sysmocom.de> Counters are added for the following events (use VTY show to query): - Dropped IMMEDIATE ASSIGN REJECT messages - Merged IMMEDIATE ASSIGN REJECT messages - Rejected AGCH messages - Use of PCH (non-reserved) for AGCH messages - Use of AGCH (reserved) for AGCH messages Sponsored-by: On-Waves ehf --- include/osmo-bts/gsm_data.h | 10 ++++++++++ src/common/bts.c | 1 + src/common/vty.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index ea3fa5e..b139903 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -48,9 +48,19 @@ struct gsm_bts_role_bts { } load; uint8_t ny1; uint8_t max_ta; + + /* AGCH queuing */ struct llist_head agch_queue; int agch_queue_length; int agch_max_queue_length; + + /* TODO: Use a rate counter group instead */ + uint64_t agch_queue_dropped_msgs; + uint64_t agch_queue_merged_msgs; + uint64_t agch_queue_rejected_msgs; + uint64_t agch_queue_agch_msgs; + uint64_t agch_queue_pch_msgs; + struct paging_state *paging_state; char *bsc_oml_host; unsigned int rtp_jitter_buf_ms; diff --git a/src/common/bts.c b/src/common/bts.c index c834786..508d562 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -347,6 +347,7 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt ((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type, is_ag_res ? "AGCH" : "PCH"); msgb_free(msg); + btsb->agch_queue_agch_msgs++; return rc; } diff --git a/src/common/vty.c b/src/common/vty.c index d818f3f..d2aeed0 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -359,6 +359,14 @@ static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts) vty_out(vty, " Paging: Queue size %u, occupied %u, lifetime %us%s", paging_get_queue_max(btsb->paging_state), paging_queue_length(btsb->paging_state), paging_get_lifetime(btsb->paging_state), VTY_NEWLINE); + vty_out(vty, " AGCH: Queue limit %u, occupied %d, " + "dropped %llu, merged %llu, rejected %llu, " + "ag-res %llu, non-res %llu%s", + btsb->agch_max_queue_length, btsb->agch_queue_length, + btsb->agch_queue_dropped_msgs, btsb->agch_queue_merged_msgs, + btsb->agch_queue_rejected_msgs, btsb->agch_queue_agch_msgs, + btsb->agch_queue_pch_msgs, + VTY_NEWLINE); #if 0 vty_out(vty, " Paging: %u pending requests, %u free slots%s", paging_pending_requests_nr(bts), -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 23:36:05 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Sat, 22 Feb 2014 00:36:05 +0100 Subject: [PATCH 4/8] agch/test: Add test for AGCH queue handling In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393025770-14352-4-git-send-email-jerlbeck@sysmocom.de> This test fills the queue by calling bts_agch_enqueue() with a mix of IMM.ASS and IMM.ASS.REJ. Then it drains the queue by calling bts_ccch_copy_msg(). After each of both steps, statistics are printed out. Sponsored-by: On-Waves ehf --- configure.ac | 1 + tests/Makefile.am | 2 +- tests/agch/Makefile.am | 8 ++ tests/agch/agch_test.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++ tests/agch/agch_test.ok | 4 + tests/testsuite.at | 6 ++ 6 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 tests/agch/Makefile.am create mode 100644 tests/agch/agch_test.c create mode 100644 tests/agch/agch_test.ok diff --git a/configure.ac b/configure.ac index 3411017..ff46b5a 100644 --- a/configure.ac +++ b/configure.ac @@ -59,6 +59,7 @@ AC_OUTPUT( include/osmo-bts/Makefile tests/Makefile tests/paging/Makefile + tests/agch/Makefile tests/cipher/Makefile tests/sysmobts/Makefile Makefile) diff --git a/tests/Makefile.am b/tests/Makefile.am index 5fb128f..b32241b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = paging cipher sysmobts +SUBDIRS = paging cipher sysmobts agch # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/agch/Makefile.am b/tests/agch/Makefile.am new file mode 100644 index 0000000..a0c5eed --- /dev/null +++ b/tests/agch/Makefile.am @@ -0,0 +1,8 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) -lortp +noinst_PROGRAMS = agch_test +EXTRA_DIST = agch_test.ok + +agch_test_SOURCES = agch_test.c $(srcdir)/../stubs.c +agch_test_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD) diff --git a/tests/agch/agch_test.c b/tests/agch/agch_test.c new file mode 100644 index 0000000..7e87bcf --- /dev/null +++ b/tests/agch/agch_test.c @@ -0,0 +1,220 @@ +/* testing the agch code */ + +/* (C) 2011 by Holger Hans Peter Freyther + * (C) 2014 by Sysmocom sfmc GmbH + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +#include + +#include +#include +#include + +#include + +static struct gsm_bts *bts; +static struct gsm_bts_role_bts *btsb; +int pcu_direct = 0; + +static const uint8_t static_ilv[] = { + 0x08, 0x59, 0x51, 0x30, 0x99, 0x00, 0x00, 0x00, 0x19 +}; + +#define ASSERT_TRUE(rc) \ + if (!(rc)) { \ + printf("Assert failed in %s:%d.\n", \ + __FILE__, __LINE__); \ + abort(); \ + } + +static int count_imm_ass_rej_refs(struct gsm48_imm_ass_rej *rej) +{ + int count = 0; + count++; + + if (memcmp(&rej->req_ref1, &rej->req_ref2, sizeof(rej->req_ref2))) { + count++; + } + + if (memcmp(&rej->req_ref1, &rej->req_ref3, sizeof(rej->req_ref3)) + && memcmp(&rej->req_ref2, &rej->req_ref3, sizeof(rej->req_ref3))) { + count++; + } + + if (memcmp(&rej->req_ref1, &rej->req_ref4, sizeof(rej->req_ref4)) + && memcmp(&rej->req_ref2, &rej->req_ref4, sizeof(rej->req_ref4)) + && memcmp(&rej->req_ref3, &rej->req_ref4, sizeof(rej->req_ref4))) { + count++; + } + + return count; +} + +static void put_imm_ass_rej(struct msgb *msg, int idx, uint8_t wait_ind) +{ + /* GSM CCCH - Immediate Assignment Reject */ + static const unsigned char gsm_a_ccch_data[23] = { + 0x4d, 0x06, 0x3a, 0x03, 0x25, 0x00, 0x00, 0x0a, + 0x25, 0x00, 0x00, 0x0a, 0x25, 0x00, 0x00, 0x0a, + 0x25, 0x00, 0x00, 0x0a, 0x2b, 0x2b, 0x2b + }; + + struct gsm48_imm_ass_rej *rej; + msg->l3h = msgb_put(msg, sizeof(gsm_a_ccch_data)); + rej = (struct gsm48_imm_ass_rej *)msg->l3h; + memmove(msg->l3h, gsm_a_ccch_data, sizeof(gsm_a_ccch_data)); + + rej->req_ref1.t1 = idx; + rej->wait_ind1 = wait_ind; + + rej->req_ref2.t1 = idx; + rej->req_ref3.t1 = idx; + rej->req_ref4.t1 = idx; +} + +static void put_imm_ass(struct msgb *msg, int idx) +{ + /* GSM CCCH - Immediate Assignment */ + static const unsigned char gsm_a_ccch_data[23] = { + 0x2d, 0x06, 0x3f, 0x03, 0x0c, 0xe3, 0x69, 0x25, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b + }; + + struct gsm48_imm_ass *ima; + msg->l3h = msgb_put(msg, sizeof(gsm_a_ccch_data)); + ima = (struct gsm48_imm_ass *)msg->l3h; + memmove(msg->l3h, gsm_a_ccch_data, sizeof(gsm_a_ccch_data)); + + ima->req_ref.t1 = idx; +} + +static void test_agch_queue(void) +{ + int rc; + uint8_t out_buf[GSM_MACBLOCK_LEN]; + struct gsm_time g_time; + const int num_rounds = 40; + const int num_ima_per_round = 2; + const int num_rej_per_round = 16; + + int round, idx; + int count = 0; + struct msgb *msg = NULL; + int multiframes = 0; + int imm_ass_count = 0; + int imm_ass_rej_count = 0; + int imm_ass_rej_ref_count = 0; + + g_time.fn = 0; + g_time.t1 = 0; + g_time.t2 = 0; + g_time.t3 = 6; + + printf("Testing AGCH messages queue handling.\n"); + btsb->agch_max_queue_length = 32; + + for (round = 1; round <= num_rounds; round++) { + for (idx = 0; idx < num_ima_per_round; idx++) { + msg = msgb_alloc(GSM_MACBLOCK_LEN, __FUNCTION__); + put_imm_ass(msg, ++count); + bts_agch_enqueue(bts, msg); + imm_ass_count++; + } + for (idx = 0; idx < num_rej_per_round; idx++) { + msg = msgb_alloc(GSM_MACBLOCK_LEN, __FUNCTION__); + put_imm_ass_rej(msg, ++count, 10); + bts_agch_enqueue(bts, msg); + imm_ass_rej_count++; + imm_ass_rej_ref_count++; + } + } + + printf("AGCH filled: count %u, imm.ass %d, imm.ass.rej %d (refs %d), " + "queue limit %u, occupied %d, " + "dropped %llu, merged %llu, rejected %llu, " + "ag-res %llu, non-res %llu\n", + count, imm_ass_count, imm_ass_rej_count, imm_ass_rej_ref_count, + btsb->agch_max_queue_length, btsb->agch_queue_length, + btsb->agch_queue_dropped_msgs, btsb->agch_queue_merged_msgs, + btsb->agch_queue_rejected_msgs, btsb->agch_queue_agch_msgs, + btsb->agch_queue_pch_msgs); + + imm_ass_count = 0; + imm_ass_rej_count = 0; + imm_ass_rej_ref_count = 0; + + for (idx = 0; 1; idx++) { + struct gsm48_imm_ass *ima; + int is_agch = (idx % 3) == 0; /* 1 AG reserved, 2 PCH */ + if (is_agch) + multiframes++; + + rc = bts_ccch_copy_msg(bts, out_buf, &g_time, is_agch); + ima = (struct gsm48_imm_ass *)out_buf; + switch (ima->msg_type) { + case GSM48_MT_RR_IMM_ASS: + imm_ass_count++; + break; + case GSM48_MT_RR_IMM_ASS_REJ: + imm_ass_rej_count++; + imm_ass_rej_ref_count += + count_imm_ass_rej_refs((struct gsm48_imm_ass_rej *)ima); + break; + default: + break; + } + if (is_agch && rc <= 0) + break; + + } + + printf("AGCH drained: multiframes %u, imm.ass %d, imm.ass.rej %d (refs %d), " + "queue limit %u, occupied %d, " + "dropped %llu, merged %llu, rejected %llu, " + "ag-res %llu, non-res %llu\n", + multiframes, imm_ass_count, imm_ass_rej_count, imm_ass_rej_ref_count, + btsb->agch_max_queue_length, btsb->agch_queue_length, + btsb->agch_queue_dropped_msgs, btsb->agch_queue_merged_msgs, + btsb->agch_queue_rejected_msgs, btsb->agch_queue_agch_msgs, + btsb->agch_queue_pch_msgs); +} + +int main(int argc, char **argv) +{ + void *tall_msgb_ctx; + + tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context"); + tall_msgb_ctx = talloc_named_const(tall_bts_ctx, 1, "msgb"); + msgb_set_talloc_ctx(tall_msgb_ctx); + + bts_log_init(NULL); + + bts = gsm_bts_alloc(tall_bts_ctx); + if (bts_init(bts) < 0) { + fprintf(stderr, "unable to open bts\n"); + exit(1); + } + + btsb = bts_role_bts(bts); + test_agch_queue(); + printf("Success\n"); + + return 0; +} + diff --git a/tests/agch/agch_test.ok b/tests/agch/agch_test.ok new file mode 100644 index 0000000..8442f07 --- /dev/null +++ b/tests/agch/agch_test.ok @@ -0,0 +1,4 @@ +Testing AGCH messages queue handling. +AGCH filled: count 720, imm.ass 80, imm.ass.rej 640 (refs 640), queue limit 32, occupied 720, dropped 0, merged 0, rejected 0, ag-res 0, non-res 0 +AGCH drained: multiframes 721, imm.ass 80, imm.ass.rej 640 (refs 640), queue limit 32, occupied 0, dropped 0, merged 0, rejected 0, ag-res 720, non-res 0 +Success diff --git a/tests/testsuite.at b/tests/testsuite.at index 1297421..ec3021f 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -7,6 +7,12 @@ cat $abs_srcdir/paging/paging_test.ok > expout AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/paging/paging_test], [], [expout], [ignore]) AT_CLEANUP +AT_SETUP([agch]) +AT_KEYWORDS([agch]) +cat $abs_srcdir/agch/agch_test.ok > expout +AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/agch/agch_test], [], [expout], [ignore]) +AT_CLEANUP + AT_SETUP([cipher]) AT_KEYWORDS([cipher]) cat $abs_srcdir/cipher/cipher_test.ok > expout -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 23:36:06 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Sat, 22 Feb 2014 00:36:06 +0100 Subject: [PATCH 5/8] agch/pch: Use PCH for AGCH msgs In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393025770-14352-5-git-send-email-jerlbeck@sysmocom.de> This patch extends paging_gen_msg() by adding an output parameter is_empty that is true, if only a paging message with dummy entries has been placed into buffer. This feature is then used by bts_ccch_copy_msg() to insert an AGCH message if is_empty is true and there are more entries in the AGCH queue than fit into the reserved blocks. Ticket: #224 Sponsored-by: On-Waves ehf --- include/osmo-bts/paging.h | 3 ++- src/common/bts.c | 19 ++++++++++++++++--- src/common/paging.c | 5 ++++- tests/agch/agch_test.ok | 2 +- tests/paging/paging_test.c | 8 ++++++-- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/include/osmo-bts/paging.h b/include/osmo-bts/paging.h index d31f5c1..38accd7 100644 --- a/include/osmo-bts/paging.h +++ b/include/osmo-bts/paging.h @@ -40,7 +40,8 @@ int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data, uint8_t len); /* generate paging message for given gsm time */ -int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt); +int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt, + int *is_empty); /* inspection methods below */ diff --git a/src/common/bts.c b/src/common/bts.c index 508d562..4ba2ec7 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -331,9 +331,18 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt struct msgb *msg; struct gsm_bts_role_bts *btsb = bts->role; int rc; + int is_empty = 1; + struct gsm48_system_information_type_3 *si3 = + GSM_BTS_SI(bts, SYSINFO_TYPE_3); + int bs_ag_blks_res = si3->control_channel_desc.bs_ag_blks_res; + int agch_res_full = btsb->agch_queue_length > bs_ag_blks_res; - if (!is_ag_res) - return paging_gen_msg(btsb->paging_state, out_buf, gt); + if (!is_ag_res) { + rc = paging_gen_msg(btsb->paging_state, out_buf, gt, &is_empty); + + if (!is_empty || !agch_res_full) + return rc; + } /* special queue of messages from IMM ASS CMD */ msg = bts_agch_dequeue(bts); @@ -347,7 +356,11 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt ((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type, is_ag_res ? "AGCH" : "PCH"); msgb_free(msg); - btsb->agch_queue_agch_msgs++; + + if (is_ag_res) + btsb->agch_queue_agch_msgs++; + else + btsb->agch_queue_pch_msgs++; return rc; } diff --git a/src/common/paging.c b/src/common/paging.c index 7c71c6f..f75f12d 100644 --- a/src/common/paging.c +++ b/src/common/paging.c @@ -377,12 +377,14 @@ static void sort_pr_tmsi_imsi(struct paging_record *pr[], unsigned int n) } /* generate paging message for given gsm time */ -int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt) +int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt, + int *is_empty) { struct llist_head *group_q; int group; int len; + *is_empty = 0; ps->btsb->load.ccch.pch_total += 1; group = get_pag_subch_nr(ps, gt); @@ -400,6 +402,7 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g //DEBUGP(DPAG, "Tx PAGING TYPE 1 (empty)\n"); len = fill_paging_type_1(out_buf, empty_id_lv, 0, NULL, 0); + *is_empty = 1; } else { struct paging_record *pr[4]; unsigned int num_pr = 0, imm_ass = 0; diff --git a/tests/agch/agch_test.ok b/tests/agch/agch_test.ok index 8442f07..70a9797 100644 --- a/tests/agch/agch_test.ok +++ b/tests/agch/agch_test.ok @@ -1,4 +1,4 @@ Testing AGCH messages queue handling. AGCH filled: count 720, imm.ass 80, imm.ass.rej 640 (refs 640), queue limit 32, occupied 720, dropped 0, merged 0, rejected 0, ag-res 0, non-res 0 -AGCH drained: multiframes 721, imm.ass 80, imm.ass.rej 640 (refs 640), queue limit 32, occupied 0, dropped 0, merged 0, rejected 0, ag-res 720, non-res 0 +AGCH drained: multiframes 241, imm.ass 80, imm.ass.rej 641 (refs 641), queue limit 32, occupied 0, dropped 0, merged 0, rejected 0, ag-res 240, non-res 480 Success diff --git a/tests/paging/paging_test.c b/tests/paging/paging_test.c index 95f1eba..57da0de 100644 --- a/tests/paging/paging_test.c +++ b/tests/paging/paging_test.c @@ -47,6 +47,7 @@ static void test_paging_smoke(void) int rc; uint8_t out_buf[GSM_MACBLOCK_LEN]; struct gsm_time g_time; + int is_empty = -1; printf("Testing that paging messages expire.\n"); /* add paging entry */ @@ -59,8 +60,9 @@ static void test_paging_smoke(void) g_time.t1 = 0; g_time.t2 = 0; g_time.t3 = 6; - rc = paging_gen_msg(btsb->paging_state, out_buf, &g_time); + rc = paging_gen_msg(btsb->paging_state, out_buf, &g_time, &is_empty); ASSERT_TRUE(rc == 13); + ASSERT_TRUE(!is_empty); ASSERT_TRUE(paging_group_queue_empty(btsb->paging_state, 0)); ASSERT_TRUE(paging_queue_length(btsb->paging_state) == 0); @@ -76,6 +78,7 @@ static void test_paging_sleep(void) int rc; uint8_t out_buf[GSM_MACBLOCK_LEN]; struct gsm_time g_time; + int is_empty = -1; printf("Testing that paging messages expire with sleep.\n"); /* add paging entry */ @@ -91,8 +94,9 @@ static void test_paging_sleep(void) g_time.t1 = 0; g_time.t2 = 0; g_time.t3 = 6; - rc = paging_gen_msg(btsb->paging_state, out_buf, &g_time); + rc = paging_gen_msg(btsb->paging_state, out_buf, &g_time, &is_empty); ASSERT_TRUE(rc == 13); + ASSERT_TRUE(!is_empty); ASSERT_TRUE(paging_group_queue_empty(btsb->paging_state, 0)); ASSERT_TRUE(paging_queue_length(btsb->paging_state) == 0); -- 1.7.9.5 From holger at freyther.de Sat Feb 22 08:08:58 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 22 Feb 2014 09:08:58 +0100 Subject: [PATCH 5/8] agch/pch: Use PCH for AGCH msgs In-Reply-To: <1393025770-14352-5-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> <1393025770-14352-5-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140222080858.GH7741@xiaoyu.lan> On Sat, Feb 22, 2014 at 12:36:06AM +0100, Jacob Erlbeck wrote: > This patch extends paging_gen_msg() by adding an output parameter > is_empty that is true, if only a paging message with dummy entries > has been placed into buffer. This feature is then used by > bts_ccch_copy_msg() to insert an AGCH message if is_empty is true > and there are more entries in the AGCH queue than fit into the > reserved blocks. > + struct gsm48_system_information_type_3 *si3 = > + GSM_BTS_SI(bts, SYSINFO_TYPE_3); > + int bs_ag_blks_res = si3->control_channel_desc.bs_ag_blks_res; it is the third place we access bs_ag_blks_res and it will not be the last one (src/osmo-bts-sysmo/oml.c). Here we don't check if the SI3 is valid or not. What do you think of creating an accessor method in common instead that will return a default value? This way even the paging code could initialize the bs_ag_blks_res to the default? > + int agch_res_full = btsb->agch_queue_length > bs_ag_blks_res; > > - if (!is_ag_res) > - return paging_gen_msg(btsb->paging_state, out_buf, gt); > + if (!is_ag_res) { > + rc = paging_gen_msg(btsb->paging_state, out_buf, gt, &is_empty); > + > + if (!is_empty || !agch_res_full) > + return rc; > + } If I understand that correctly. In case we generated an empty paging message and we have fewer AGCH messages in the queue than reserved blocks, we do send an empty paging message. What is the reason for that? It seems to complicate the code, is it a spec requirement? From jerlbeck at sysmocom.de Mon Feb 24 09:38:14 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 24 Feb 2014 10:38:14 +0100 Subject: [PATCH 5/8] agch/pch: Use PCH for AGCH msgs In-Reply-To: <20140222080858.GH7741@xiaoyu.lan> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> <1393025770-14352-5-git-send-email-jerlbeck@sysmocom.de> <20140222080858.GH7741@xiaoyu.lan> Message-ID: <530B1306.7050200@sysmocom.de> Hi On 22.02.2014 09:08, Holger Hans Peter Freyther wrote: > On Sat, Feb 22, 2014 at 12:36:06AM +0100, Jacob Erlbeck wrote: >> This patch extends paging_gen_msg() by adding an output parameter >> is_empty that is true, if only a paging message with dummy entries >> has been placed into buffer. I also would like to remove the paging_add_imm_ass() because IMO it doesn't make much sense any longer. >> This feature is then used by >> bts_ccch_copy_msg() to insert an AGCH message if is_empty is true >> and there are more entries in the AGCH queue than fit into the >> reserved blocks. > >> + struct gsm48_system_information_type_3 *si3 = >> + GSM_BTS_SI(bts, SYSINFO_TYPE_3); >> + int bs_ag_blks_res = si3->control_channel_desc.bs_ag_blks_res; > > it is the third place we access bs_ag_blks_res and it will not be the > last one (src/osmo-bts-sysmo/oml.c). Here we don't check if the SI3 is > valid or not. What do you think of creating an accessor method in common > instead that will return a default value? I'm note sure, whether a default value would make any sense here, because is has the match the SI3 that is transmitted over they air anyway. Does it make sense to have a complete default SI3 that can be transmitted _before_ a valid SI3 has been received via RSL? But an accessor function would be a good thing anyway. This way even the paging code > could initialize the bs_ag_blks_res to the default? > > If I understand that correctly. In case we generated an empty paging > message and we have fewer AGCH messages in the queue than reserved blocks, > we do send an empty paging message. What is the reason for that? It > seems to complicate the code, is it a spec requirement? No it's not a spec requirement. It's just a minimal change in comparison to the old behaviour. Let's remove it. > Jacob From jerlbeck at sysmocom.de Mon Feb 24 10:27:48 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Mon, 24 Feb 2014 11:27:48 +0100 Subject: [PATCH 5/8] agch/pch: Use PCH for AGCH msgs In-Reply-To: <530B1306.7050200@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> <1393025770-14352-5-git-send-email-jerlbeck@sysmocom.de> <20140222080858.GH7741@xiaoyu.lan> <530B1306.7050200@sysmocom.de> Message-ID: <530B1EA4.3070101@sysmocom.de> On 24.02.2014 10:38, Jacob Erlbeck wrote: > On 22.02.2014 09:08, Holger Hans Peter Freyther wrote: >> On Sat, Feb 22, 2014 at 12:36:06AM +0100, Jacob Erlbeck wrote: >>> This patch extends paging_gen_msg() by adding an output parameter >>> is_empty that is true, if only a paging message with dummy entries >>> has been placed into buffer. > > I also would like to remove the paging_add_imm_ass() because IMO it > doesn't make much sense any longer. It's still needed in pcu_rx_data_req() (pcu_sock.c): === case PCU_IF_SAPI_PCH: if (msg_type == PCU_IF_MSG_PAG_REQ) { /* FIXME: Add function to schedule paging request. * This might not be required, if PCU_IF_MSG_DATA_REQ * is used instead. */ } else { struct gsm_bts_role_bts *btsb = bts->role; paging_add_imm_ass(btsb->paging_state, data_req->data, data_req->len); } break; === But I don't understand why it is done this way. Jacob From jerlbeck at sysmocom.de Fri Feb 21 23:36:07 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Sat, 22 Feb 2014 00:36:07 +0100 Subject: [PATCH 6/8] agch: Manage AGCH queue length In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393025770-14352-6-git-send-email-jerlbeck@sysmocom.de> Currently, the AGCH queue length is not limited. This can lead to large delays and network malfunction if there are many IMM.ASS.REJ messages. This patch adds two features: - Don't accept msgs from the RSL layer when the queue is way too full (safety measure, mainly if bts_ccch_copy_msg() is not being called by the L1 layer, currently hard coded to 1000 messages) - Selectively drop IMM.ASS.REJ from the queue output depending on the queue length Ticket: #224 Sponsored-by: On-Waves ehf --- include/osmo-bts/gsm_data.h | 9 ++++ src/common/bts.c | 123 ++++++++++++++++++++++++++++++++++++++----- tests/agch/agch_test.c | 4 ++ tests/agch/agch_test.ok | 2 +- 4 files changed, 125 insertions(+), 13 deletions(-) diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index b139903..c7a0fc6 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -7,6 +7,11 @@ #include +#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT 41 +#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE 999999 +#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41 +#define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91 + struct pcu_sock_state; struct gsm_network { @@ -54,6 +59,10 @@ struct gsm_bts_role_bts { int agch_queue_length; int agch_max_queue_length; + int agch_queue_thresh_level; /* Cleanup threshold in percent of max len */ + int agch_queue_low_level; /* Low water mark in percent of max len */ + int agch_queue_high_level; /* High water mark in percent of max len */ + /* TODO: Use a rate counter group instead */ uint64_t agch_queue_dropped_msgs; uint64_t agch_queue_merged_msgs; diff --git a/src/common/bts.c b/src/common/bts.c index 4ba2ec7..0b14020 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -89,6 +89,14 @@ int bts_init(struct gsm_bts *bts) INIT_LLIST_HEAD(&btsb->agch_queue); btsb->agch_queue_length = 0; + /* enable management with default levels, + * raise threshold to GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE to + * disable this feature. + */ + btsb->agch_queue_low_level = GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT; + btsb->agch_queue_high_level = GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT; + btsb->agch_queue_thresh_level = GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT; + /* configurable via VTY */ btsb->paging_state = paging_init(btsb, 200, 0); @@ -297,6 +305,18 @@ void bts_update_agch_max_queue_length(struct gsm_bts *bts) int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) { struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + int hard_limit = 1000; + + if (btsb->agch_queue_length > hard_limit) { + LOGP(DSUM, LOGL_ERROR, + "AGCH: too many messages in queue, " + "refusing message type 0x%02x, length = %d/%d\n", + ((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type, + btsb->agch_queue_length, btsb->agch_max_queue_length); + + btsb->agch_queue_rejected_msgs++; + return -ENOMEM; + } msgb_enqueue(&btsb->agch_queue, msg); btsb->agch_queue_length++; @@ -325,30 +345,109 @@ struct msgb *bts_agch_dequeue(struct gsm_bts *bts) return msg; } +/* Remove lower prio messages if the queue has grown to long. + * + * \return 0 iff the number of messages in the queue would fit into the AGCH + * reserved part of the CCCH. + */ +static int compact_agch_queue(struct gsm_bts *bts) +{ + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + struct msgb *msg, *msg2; + int max_len, slope, offs; + int level_low = btsb->agch_queue_low_level; + int level_high = btsb->agch_queue_high_level; + int level_thres = btsb->agch_queue_thresh_level; + struct gsm48_system_information_type_3 *si3 = GSM_BTS_SI(bts, SYSINFO_TYPE_3); + int bs_ag_blks_res = si3->control_channel_desc.bs_ag_blks_res; + + max_len = btsb->agch_max_queue_length; + + if (max_len == 0) + max_len = 1; + + /* TODO: Make the constants configurable */ + if (btsb->agch_queue_length < max_len * level_thres / 100) + goto out; + + /* p^ + * 1+ /''''' + * | / + * | / + * 0+---/--+----+--> Q length + * low high max_len + */ + + offs = max_len * level_low / 100; + if (level_high > level_low) + slope = 0x10000 * 100 / (level_high - level_low); + else + slope = 0x10000 * max_len; /* p_drop >= 1 if len > offs */ + + llist_for_each_entry_safe(msg, msg2, &btsb->agch_queue, list) { + struct gsm48_imm_ass *imm_ass_cmd = msgb_l3(msg); + int p_drop; + LOGP(DSUM, LOGL_DEBUG, + "AGCH: head is message type 0x%02x, length = %d/%d\n", + imm_ass_cmd->msg_type, + btsb->agch_queue_length, btsb->agch_max_queue_length); + + if (imm_ass_cmd->msg_type != GSM48_MT_RR_IMM_ASS_REJ) + goto out; + + /* IMMEDIATE ASSIGN REJECT */ + + p_drop = (btsb->agch_queue_length - offs) * slope / max_len; + + if ((random() & 0xffff) >= p_drop) + goto out; + + LOGP(DSUM, LOGL_DEBUG, + "AGCH: dropping message type 0x%02x, length = %d/%d, " + "p = %f\n", + imm_ass_cmd->msg_type, + btsb->agch_queue_length, btsb->agch_max_queue_length, + p_drop / 65536.0); + + llist_del(&msg->list); + btsb->agch_queue_length--; + msgb_free(msg); + + btsb->agch_queue_dropped_msgs++; + } +out: + return btsb->agch_queue_length > bs_ag_blks_res; +} + int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, int is_ag_res) { - struct msgb *msg; + struct msgb *msg = NULL; struct gsm_bts_role_bts *btsb = bts->role; - int rc; + int rc = 0; int is_empty = 1; - struct gsm48_system_information_type_3 *si3 = - GSM_BTS_SI(bts, SYSINFO_TYPE_3); - int bs_ag_blks_res = si3->control_channel_desc.bs_ag_blks_res; - int agch_res_full = btsb->agch_queue_length > bs_ag_blks_res; + int agch_res_full; + + /* Do queue house keeping. + * This needs to be done every time a CCCH message is requested, since + * the queue max length is calculated based on the CCCH block rate and + * PCH messages also reduce the drain of the AGCH queue. + */ + agch_res_full = compact_agch_queue(bts); - if (!is_ag_res) { + /* Check for paging messages first if this is PCH */ + if (!is_ag_res) rc = paging_gen_msg(btsb->paging_state, out_buf, gt, &is_empty); - if (!is_empty || !agch_res_full) - return rc; - } + /* Check whether the block may be overwritten */ + if (!is_empty || (!is_ag_res && !agch_res_full)) + return rc; - /* special queue of messages from IMM ASS CMD */ msg = bts_agch_dequeue(bts); if (!msg) - return 0; + return rc; + /* Copy AGCH message */ memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg)); rc = msgb_l3len(msg); LOGP(DSUM, LOGL_DEBUG, diff --git a/tests/agch/agch_test.c b/tests/agch/agch_test.c index 7e87bcf..a3868c1 100644 --- a/tests/agch/agch_test.c +++ b/tests/agch/agch_test.c @@ -129,6 +129,10 @@ static void test_agch_queue(void) printf("Testing AGCH messages queue handling.\n"); btsb->agch_max_queue_length = 32; + btsb->agch_queue_low_level = 30; + btsb->agch_queue_high_level = 30; + btsb->agch_queue_thresh_level = 60; + for (round = 1; round <= num_rounds; round++) { for (idx = 0; idx < num_ima_per_round; idx++) { msg = msgb_alloc(GSM_MACBLOCK_LEN, __FUNCTION__); diff --git a/tests/agch/agch_test.ok b/tests/agch/agch_test.ok index 70a9797..57439ed 100644 --- a/tests/agch/agch_test.ok +++ b/tests/agch/agch_test.ok @@ -1,4 +1,4 @@ Testing AGCH messages queue handling. AGCH filled: count 720, imm.ass 80, imm.ass.rej 640 (refs 640), queue limit 32, occupied 720, dropped 0, merged 0, rejected 0, ag-res 0, non-res 0 -AGCH drained: multiframes 241, imm.ass 80, imm.ass.rej 641 (refs 641), queue limit 32, occupied 0, dropped 0, merged 0, rejected 0, ag-res 240, non-res 480 +AGCH drained: multiframes 33, imm.ass 80, imm.ass.rej 17 (refs 17), queue limit 32, occupied 0, dropped 624, merged 0, rejected 0, ag-res 32, non-res 64 Success -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 23:36:08 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Sat, 22 Feb 2014 00:36:08 +0100 Subject: [PATCH 7/8] agch: Add VTY queue management configuration In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393025770-14352-7-git-send-email-jerlbeck@sysmocom.de> This patch adds the following VTY commands to tune AGCH queue handling: agch-queue-management no agch-queue-management agch-queue-management threshold THRES low LOW high HIGH Examples: agch-queue-management Enable queue management with default parameters (default, recommended) no agch-queue-management Disable it completely agch-queue-management threshold 0 low 25 high 75 Start dropping at 25%, drop all messages above 75% queue length (relative to max queue length corresponding to T3126). Between low and high, drop with a probability interpolated linearly between 0 (low) and 1 (high). agch-queue-management threshold 50 low 0 high 0 Start dropping at 50% and continue until all IMM.ASS.REJ have been removed from the front (output) of the queue Sponsored-by: On-Waves ehf --- src/common/vty.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/common/vty.c b/src/common/vty.c index d2aeed0..f7a04d6 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -158,6 +158,16 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) VTY_NEWLINE); vty_out(vty, " paging lifetime %u%s", paging_get_lifetime(btsb->paging_state), VTY_NEWLINE); + if (btsb->agch_queue_thres_level == GSM_BTS_AGCH_QUEUE_THRES_LEVEL_DISABLE) + vty_out(vty, " no agch-queue-mgmt%s", VTY_NEWLINE); + else if (btsb->agch_queue_thres_level == GSM_BTS_AGCH_QUEUE_THRES_LEVEL_DEFAULT + && btsb->agch_queue_low_level == GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT + && btsb->agch_queue_high_level == GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT) + vty_out(vty, " agch-queue-mgmt%s", VTY_NEWLINE); + else + vty_out(vty, " agch-queue-mgmt threshold %d low %d high %d%s", + btsb->agch_queue_thres_level, btsb->agch_queue_low_level, + btsb->agch_queue_high_level, VTY_NEWLINE); bts_model_config_write_bts(vty, bts); @@ -324,6 +334,56 @@ DEFUN(cfg_bts_paging_lifetime, return CMD_SUCCESS; } +#define AGCH_QUEUE_STR "AGCH queue mgmt\n" + +DEFUN(cfg_bts_agch_queue_mgmt_params, + cfg_bts_agch_queue_mgmt_params_cmd, + "agch-queue-mgmt threshold <0-100> low <0-100> high <0-100000>", + AGCH_QUEUE_STR + "Threshold to start cleanup\nin %% of the maximum queue length\n" + "Low water mark for cleanup\nin %% of the maximum queue length\n" + "High water mark for cleanup\nin %% of the maximum queue length\n") +{ + struct gsm_bts *bts = vty->index; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + btsb->agch_queue_thres_level = atoi(argv[0]); + btsb->agch_queue_low_level = atoi(argv[1]); + btsb->agch_queue_high_level = atoi(argv[2]); + + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_agch_queue_mgmt, + cfg_bts_agch_queue_mgmt_cmd, + "agch-queue-mgmt", + AGCH_QUEUE_STR) +{ + struct gsm_bts *bts = vty->index; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + btsb->agch_queue_thres_level = GSM_BTS_AGCH_QUEUE_THRES_LEVEL_DEFAULT; + btsb->agch_queue_low_level = GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT; + btsb->agch_queue_high_level = GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT; + + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_agch_queue_mgmt, + cfg_bts_no_agch_queue_mgmt_cmd, + "no agch-queue-mgmt", + NO_STR AGCH_QUEUE_STR) +{ + struct gsm_bts *bts = vty->index; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + btsb->agch_queue_thres_level = GSM_BTS_AGCH_QUEUE_THRES_LEVEL_DISABLE; + btsb->agch_queue_low_level = 0; + btsb->agch_queue_high_level = 0; + + return CMD_SUCCESS; +} + /* ====================================================================== @@ -496,6 +556,9 @@ int bts_vty_init(const struct log_info *cat) install_element(BTS_NODE, &cfg_no_description_cmd); install_element(BTS_NODE, &cfg_bts_paging_queue_size_cmd); install_element(BTS_NODE, &cfg_bts_paging_lifetime_cmd); + install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_cmd); + install_element(BTS_NODE, &cfg_bts_no_agch_queue_mgmt_cmd); + install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_params_cmd); /* add and link to TRX config node */ install_element(BTS_NODE, &cfg_bts_trx_cmd); -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 21 23:36:09 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Sat, 22 Feb 2014 00:36:09 +0100 Subject: [PATCH 8/8] agch: Merge IMM.ASS.REJ if possible when enqueueing In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393025770-14352-8-git-send-email-jerlbeck@sysmocom.de> This patch implements merging of IMMEDIATE ASSIGN REJECT messages as sugegsted in GSM 08.58, 5.7. When a new IMM.ASS.REJ is to be appended to the AGCH queue and the last message in that queue is of the same type, the individual entries (up to 4 per message) of both messages are extracted, combined and stored back. If there are less than 5 entries all entries fit into the old message and the new one is discarded. Otherwise, the old message will contain 4 entries and the remaining ones are stored into the new one which is then appended to the queue. Ticket: #224 Sponsored-by: On-Waves ehf --- src/common/bts.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++ src/common/vty.c | 12 ++-- tests/agch/agch_test.ok | 4 +- 3 files changed, 154 insertions(+), 8 deletions(-) diff --git a/src/common/bts.c b/src/common/bts.c index 0b14020..566cadb 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -302,10 +302,138 @@ void bts_update_agch_max_queue_length(struct gsm_bts *bts) si3->control_channel_desc.bs_ag_blks_res); } +#define REQ_REFS_PER_IMM_ASS_REJ 4 +static int store_imm_ass_rej_refs(struct gsm48_imm_ass_rej *rej, + struct gsm48_req_ref *req_refs, + uint8_t *wait_inds, + int count) +{ + switch (count) { + case 0: + /* TODO: Warning ? */ + return 0; + default: + count = 4; + rej->req_ref4 = req_refs[3]; + rej->wait_ind4 = wait_inds[3]; + /* no break */ + case 3: + rej->req_ref3 = req_refs[2]; + rej->wait_ind3 = wait_inds[2]; + /* no break */ + case 2: + rej->req_ref2 = req_refs[1]; + rej->wait_ind2 = wait_inds[1]; + /* no break */ + case 1: + rej->req_ref1 = req_refs[0]; + rej->wait_ind1 = wait_inds[0]; + break; + } + + switch (count) { + case 1: + rej->req_ref2 = req_refs[0]; + rej->wait_ind2 = wait_inds[0]; + /* no break */ + case 2: + rej->req_ref3 = req_refs[0]; + rej->wait_ind3 = wait_inds[0]; + /* no break */ + case 3: + rej->req_ref4 = req_refs[0]; + rej->wait_ind4 = wait_inds[0]; + /* no break */ + default: + break; + } + + return count; +} + +static int extract_imm_ass_rej_refs(struct gsm48_imm_ass_rej *rej, + struct gsm48_req_ref *req_refs, + uint8_t *wait_inds) +{ + int count = 0; + req_refs[count] = rej->req_ref1; + wait_inds[count] = rej->wait_ind1; + count++; + + if (memcmp(&rej->req_ref1, &rej->req_ref2, sizeof(rej->req_ref2))) { + req_refs[count] = rej->req_ref2; + wait_inds[count] = rej->wait_ind2; + count++; + } + + if (memcmp(&rej->req_ref1, &rej->req_ref3, sizeof(rej->req_ref3)) + && memcmp(&rej->req_ref2, &rej->req_ref3, sizeof(rej->req_ref3))) { + req_refs[count] = rej->req_ref3; + wait_inds[count] = rej->wait_ind3; + count++; + } + + if (memcmp(&rej->req_ref1, &rej->req_ref4, sizeof(rej->req_ref4)) + && memcmp(&rej->req_ref2, &rej->req_ref4, sizeof(rej->req_ref4)) + && memcmp(&rej->req_ref3, &rej->req_ref4, sizeof(rej->req_ref4))) { + req_refs[count] = rej->req_ref4; + wait_inds[count] = rej->wait_ind4; + count++; + } + + return count; +} + +static int try_merge_imm_ass_rej(struct gsm48_imm_ass_rej *old_rej, + struct gsm48_imm_ass_rej *new_rej) +{ + struct gsm48_req_ref req_refs[2 * REQ_REFS_PER_IMM_ASS_REJ]; + uint8_t wait_inds[2 * REQ_REFS_PER_IMM_ASS_REJ]; + int count = 0; + int stored = 0; + + if (new_rej->msg_type != GSM48_MT_RR_IMM_ASS_REJ) + return 0; + if (old_rej->msg_type != GSM48_MT_RR_IMM_ASS_REJ) + return 0; + + /* GSM 08.58, 5.7 + * -> The BTS may combine serveral IMM.ASS.REJ messages + * -> Identical request refs in one message may be squeezed + * + * GSM 04.08, 9.1.20.2 + * -> Request ref and wait ind are duplicated to fill the message + */ + + /* Extract all entries */ + count = extract_imm_ass_rej_refs(old_rej, + &req_refs[count], &wait_inds[count]); + if (count == REQ_REFS_PER_IMM_ASS_REJ) + return 0; + + count += extract_imm_ass_rej_refs(new_rej, + &req_refs[count], &wait_inds[count]); + + /* Store entries into old message */ + stored = store_imm_ass_rej_refs(old_rej, + &req_refs[stored], &wait_inds[stored], + count); + count -= stored; + if (count == 0) + return 1; + + /* Store remaining entries into new message */ + stored += store_imm_ass_rej_refs(new_rej, + &req_refs[stored], &wait_inds[stored], + count); + return 0; +} + int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) { struct gsm_bts_role_bts *btsb = bts_role_bts(bts); int hard_limit = 1000; + struct gsm48_imm_ass_rej *imm_ass_cmd = msgb_l3(msg); if (btsb->agch_queue_length > hard_limit) { LOGP(DSUM, LOGL_ERROR, @@ -318,6 +446,24 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) return -ENOMEM; } + if (btsb->agch_queue_length > 0) { + struct msgb *last_msg = + llist_entry(btsb->agch_queue.prev, struct msgb, list); + struct gsm48_imm_ass_rej *last_imm_ass_rej = msgb_l3(last_msg); + + if (try_merge_imm_ass_rej(last_imm_ass_rej, imm_ass_cmd)) { + LOGP(DSUM, LOGL_DEBUG, + "AGCH: merged message type 0x%02x, length = %d/%d, " + "msg = %s\n", + last_imm_ass_rej->msg_type, + btsb->agch_queue_length, btsb->agch_max_queue_length, + osmo_hexdump(msgb_l3(last_msg), msgb_l3len(last_msg))); + + btsb->agch_queue_merged_msgs++; + return 0; + } + } + msgb_enqueue(&btsb->agch_queue, msg); btsb->agch_queue_length++; diff --git a/src/common/vty.c b/src/common/vty.c index f7a04d6..b59cc9b 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -158,15 +158,15 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) VTY_NEWLINE); vty_out(vty, " paging lifetime %u%s", paging_get_lifetime(btsb->paging_state), VTY_NEWLINE); - if (btsb->agch_queue_thres_level == GSM_BTS_AGCH_QUEUE_THRES_LEVEL_DISABLE) + if (btsb->agch_queue_thresh_level == GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE) vty_out(vty, " no agch-queue-mgmt%s", VTY_NEWLINE); - else if (btsb->agch_queue_thres_level == GSM_BTS_AGCH_QUEUE_THRES_LEVEL_DEFAULT + else if (btsb->agch_queue_thresh_level == GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT && btsb->agch_queue_low_level == GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT && btsb->agch_queue_high_level == GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT) vty_out(vty, " agch-queue-mgmt%s", VTY_NEWLINE); else vty_out(vty, " agch-queue-mgmt threshold %d low %d high %d%s", - btsb->agch_queue_thres_level, btsb->agch_queue_low_level, + btsb->agch_queue_thresh_level, btsb->agch_queue_low_level, btsb->agch_queue_high_level, VTY_NEWLINE); bts_model_config_write_bts(vty, bts); @@ -347,7 +347,7 @@ DEFUN(cfg_bts_agch_queue_mgmt_params, struct gsm_bts *bts = vty->index; struct gsm_bts_role_bts *btsb = bts_role_bts(bts); - btsb->agch_queue_thres_level = atoi(argv[0]); + btsb->agch_queue_thresh_level = atoi(argv[0]); btsb->agch_queue_low_level = atoi(argv[1]); btsb->agch_queue_high_level = atoi(argv[2]); @@ -362,7 +362,7 @@ DEFUN(cfg_bts_agch_queue_mgmt, struct gsm_bts *bts = vty->index; struct gsm_bts_role_bts *btsb = bts_role_bts(bts); - btsb->agch_queue_thres_level = GSM_BTS_AGCH_QUEUE_THRES_LEVEL_DEFAULT; + btsb->agch_queue_thresh_level = GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT; btsb->agch_queue_low_level = GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT; btsb->agch_queue_high_level = GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT; @@ -377,7 +377,7 @@ DEFUN(cfg_bts_no_agch_queue_mgmt, struct gsm_bts *bts = vty->index; struct gsm_bts_role_bts *btsb = bts_role_bts(bts); - btsb->agch_queue_thres_level = GSM_BTS_AGCH_QUEUE_THRES_LEVEL_DISABLE; + btsb->agch_queue_thresh_level = GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE; btsb->agch_queue_low_level = 0; btsb->agch_queue_high_level = 0; diff --git a/tests/agch/agch_test.ok b/tests/agch/agch_test.ok index 57439ed..f31676a 100644 --- a/tests/agch/agch_test.ok +++ b/tests/agch/agch_test.ok @@ -1,4 +1,4 @@ Testing AGCH messages queue handling. -AGCH filled: count 720, imm.ass 80, imm.ass.rej 640 (refs 640), queue limit 32, occupied 720, dropped 0, merged 0, rejected 0, ag-res 0, non-res 0 -AGCH drained: multiframes 33, imm.ass 80, imm.ass.rej 17 (refs 17), queue limit 32, occupied 0, dropped 624, merged 0, rejected 0, ag-res 32, non-res 64 +AGCH filled: count 720, imm.ass 80, imm.ass.rej 640 (refs 640), queue limit 32, occupied 240, dropped 0, merged 480, rejected 0, ag-res 0, non-res 0 +AGCH drained: multiframes 32, imm.ass 80, imm.ass.rej 12 (refs 48), queue limit 32, occupied 0, dropped 148, merged 480, rejected 0, ag-res 31, non-res 61 Success -- 1.7.9.5 From holger at freyther.de Sat Feb 22 07:52:01 2014 From: holger at freyther.de (Holger Hans Peter Freyther) Date: Sat, 22 Feb 2014 08:52:01 +0100 Subject: [PATCH 1/8] agch: Recalculate length limit of AGCH queue In-Reply-To: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> References: <1393025770-14352-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <20140222075201.GF7741@xiaoyu.lan> On Sat, Feb 22, 2014 at 12:36:02AM +0100, Jacob Erlbeck wrote: > + * The ratio is mainly influenced by the downlink only channels > + * (BCCH, FCCH, SCH, CBCH) that can not used for CCCH. be? > + for (i = 0; i < 15; i++) { ARRAY_SIZE(tx_integer[i])? From zero-kelvin at gmx.de Tue Feb 25 20:37:56 2014 From: zero-kelvin at gmx.de (dexter) Date: Tue, 25 Feb 2014 21:37:56 +0100 Subject: TOMORROW: Osmocom Berlin User Group meeting Message-ID: <530CFF24.9000509@gmx.de> Hi All. It's time Again! This is the announcement for the next Osmocom Berlin meeting. Tomorrow, 8pm @ CCC Berlin, Marienstr. 11, 10117 Berlin There is no formal presentation scheduled for this meeting. If you are interested to show up, feel free to do so. There is no registration required. The meeting is free as in "free beer", despite no actual free beer being around. I am looking forward to see you there! regards. Philipp From anayuso at sysmocom.de Thu Feb 27 11:16:27 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Thu, 27 Feb 2014 12:16:27 +0100 Subject: [libosmocore PATCH] src/socket: Added support for using socket unix Message-ID: <20140227111627.14179.94135.stgit@Ph0enix> From: ?lvaro Neira Ayuso Added some function for adding socket unix support. Signed-off-by: Alvaro Neira Ayuso --- include/osmocom/core/socket.h | 6 +++ src/socket.c | 92 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index f15a03a..cb1b7a8 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -30,6 +30,12 @@ int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type, int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen); +int osmo_sock_unix_init(uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags); + +int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags); + /*! @} */ #endif /* _OSMOCORE_SOCKET_H */ diff --git a/src/socket.c b/src/socket.c index 6ff00f0..6d4eddf 100644 --- a/src/socket.c +++ b/src/socket.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -257,6 +258,97 @@ int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen) return 0; } +/*! \brief Initialize a socket unix(including bind/connect) + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] socket_path path to identify the socket + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * + * This function creates a new socket unix, \a + * type and \a proto and optionally binds or connects it, depending on + * the value of \a flags parameter. + */ +int osmo_sock_unix_init(uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags) +{ + struct sockaddr_un addr; + int sfd, rc, on = 1; + + if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == + (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) + return -EINVAL; + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1); + + if (type == SOCK_RAW) { + sfd = socket(AF_UNIX, SOCK_DGRAM, 0); + } else { + sfd = socket(AF_UNIX, type, proto); + } + + if (sfd < 0) + return -1; + + if (flags & OSMO_SOCK_F_NONBLOCK) { + if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { + perror("cannot set this socket unblocking"); + close(sfd); + return -EINVAL; + } + } + if (flags & OSMO_SOCK_F_CONNECT) { + rc = connect(sfd, (struct sockaddr*)&addr, sizeof(addr)); + if (rc < 0) { + close(sfd); + return -1; + } + } else { + rc = bind(sfd, (struct sockaddr*)&addr, sizeof(addr)); + if (rc < 0) { + close(sfd); + return -1; + } + } + + if (flags & OSMO_SOCK_F_BIND) + listen(sfd, 10); + + return sfd; +} + +/*! \brief Initialize a socket unix and fill \ref osmo_fd + * \param[out] ofd file descriptor (will be filled in) + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] socket_path path to identify the socket + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * + * This function creates (and optionall binds/connects) a socket using + * \ref osmo_sock_unix_init, but also fills the \a ofd structure. + */ +int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags) +{ + int sfd, rc; + + sfd = osmo_sock_unix_init(type, proto, socket_path, flags); + if (sfd < 0) + return sfd; + + ofd->fd = sfd; + ofd->when = BSC_FD_READ; + + rc = osmo_fd_register(ofd); + if (rc < 0) { + close(sfd); + return rc; + } + + return sfd; +} + #endif /* HAVE_SYS_SOCKET_H */ /*! @} */ From anayuso at sysmocom.de Thu Feb 27 11:30:16 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Thu, 27 Feb 2014 12:30:16 +0100 Subject: [osmo-bts PATCH 1/3] src/misc/sysmobts_misc: Fixed wrong TEMP_PATH Message-ID: <20140227113016.15224.25190.stgit@Ph0enix> From: ?lvaro Neira Ayuso Before, this patch the program try to catch the info of the temperature sensor in a wrong ubication file. Signed-off-by: Alvaro Neira Ayuso --- src/osmo-bts-sysmo/misc/sysmobts_misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index 74414d0..c043045 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -45,7 +45,7 @@ * Temperature handling *********************************************************************/ -#define TEMP_PATH "/sys/class/hwmon/hwmon0/device%u_%s" +#define TEMP_PATH "/sys/class/hwmon/hwmon0/device/temp%u_%s" static const char *temp_type_str[_NUM_TEMP_TYPES] = { [SYSMOBTS_TEMP_INPUT] = "input", From anayuso at sysmocom.de Thu Feb 27 11:30:21 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Thu, 27 Feb 2014 12:30:21 +0100 Subject: [osmo-bts PATCH 2/3] misc/sysmobts_misc.c: Read temperature from microcontroller In-Reply-To: <20140227113016.15224.25190.stgit@Ph0enix> References: <20140227113016.15224.25190.stgit@Ph0enix> Message-ID: <20140227113021.15224.69836.stgit@Ph0enix> From: ?lvaro Neira Ayuso Add function for requesting the temperature information to the microcontroller. I have added a function that we can extend for requesting more information but in this case we only need to know the temperature. I have added to a microcontroller temperature handling function in the manager for monitoring this information. Signed-off-by: Alvaro Neira Ayuso --- src/osmo-bts-sysmo/misc/sysmobts_mgr.c | 29 +++++ src/osmo-bts-sysmo/misc/sysmobts_misc.c | 167 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 22 ++++ 3 files changed, 218 insertions(+) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 171f79b..71b889e 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -53,6 +53,31 @@ void *tall_mgr_ctx; /* every 1 hours means 365*24 = 8760 EEprom writes per year (max) */ #define HOURS_TIMER_SECS (1 * 3600) +static struct osmo_timer_list temp_uc_timer; +static void check_uctemp_timer_cb(void *unused) +{ + struct uc ucontrol0 = { + .id = 0, + .path = "/dev/ttyS0" + }; + int val; + + if (sysmobts_par_get_int(SYSMOBTS_PAR_MODEL_NR, &val) < 0) + return; + + if (val == 2050) { + if (sysmobts_par_get_int(SYSMOBTS_PAR_TRX_NR, &val) < 0) + return; + + if (val == 0) + sbts2050_uc_check_temp(ucontrol0); + } + + osmo_timer_schedule(&temp_uc_timer, TEMP_TIMER_SECS, 0); + + +} + static struct osmo_timer_list temp_timer; static void check_temp_timer_cb(void *unused) { @@ -305,6 +330,10 @@ int main(int argc, char **argv) temp_timer.cb = check_temp_timer_cb; check_temp_timer_cb(NULL); + /* start uc temperature check timer */ + temp_uc_timer.cb = check_uctemp_timer_cb; + check_uctemp_timer_cb(NULL); + /* start operational hours timer */ hours_timer.cb = hours_timer_cb; hours_timer_cb(NULL); diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index c043045..aee892d 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -32,6 +32,8 @@ #include #include +#include +#include #include #include #include @@ -39,7 +41,172 @@ #include "sysmobts_misc.h" #include "sysmobts_par.h" #include "sysmobts_mgr.h" +#include "sbts2050_header.h" +#define SERIAL_ALLOC_SIZE 300 +#define SIZE_HEADER_RSP 5 +#define SIZE_HEADER_CMD 4 + +/********************************************************************** + * Functions read/write from serial interface + *********************************************************************/ +int hand_serial_read(int fd, struct msgb *msg, int numbytes) +{ + int rc, bread = 0; + + if (numbytes > msg->data_len) + return -ENOSPC; + + while (bread < numbytes) { + rc = read(fd, msg->tail, numbytes - bread); + if (rc < 0) + return -1; + if (rc == 0) + break; + + bread += rc; + msgb_put(msg, rc); + } + + return bread; +} + +int hand_serial_write(int fd, struct msgb *msg) +{ + int rc, bwritten = 0; + + while (msg->len > 0) { + rc = write(fd, msg->data, msg->len); + if (rc < 0) + return -1; + + msgb_pull(msg, rc); + bwritten += rc; + } + + return bwritten; +} + +/********************************************************************** + * Functions request information to Microcontroller + *********************************************************************/ +static void add_parity(cmdpkt_t *command) +{ + int n; + uint8_t parity = 0x00; + for (n = 0; n < SIZE_HEADER_CMD+command->u8Len; n++) + parity ^= ((uint8_t *)command)[n]; + + command->cmd.raw[command->u8Len] = parity; +} + +struct msgb *sbts2050_ucinfo_get(struct uc ucontrol, struct ucinfo info) +{ + int fd, num, rc; + cmdpkt_t *command; + rsppkt_t *response; + struct msgb *msg; + fd_set fdread; + struct timeval tout = { + .tv_sec = 10, + }; + + switch (info.id) { + case SBTS2050_TEMP_RQT: + num = sizeof(command->cmd.tempGet); + break; + default: + return NULL; + } + num = num + SIZE_HEADER_CMD+1; + + msg = msgb_alloc(SERIAL_ALLOC_SIZE, "Message Microcontroller"); + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error creating msg\n"); + return NULL; + } + command = (cmdpkt_t *) msgb_put(msg, num); + + command->u16Magic = 0xCAFE; + switch (info.id) { + case SBTS2050_TEMP_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.tempGet); + break; + default: + goto err_free; + } + + add_parity(command); + + fd = osmo_serial_init(ucontrol.path, 115200); + if (fd < 0) + goto err_free; + + if (hand_serial_write(fd, msg) < 0) + goto err; + + msgb_reset(msg); + + FD_ZERO(&fdread); + FD_SET(fd, &fdread); + + num = SIZE_HEADER_RSP; + while (1) { + rc = select(fd+1, &fdread, NULL, NULL, &tout); + if (rc > 0) { + if (hand_serial_read(fd, msg, num) < 0) + goto err; + + response = (rsppkt_t *)msg->data; + + if (response->u8Id != info.id || msg->len <= 0 || + response->i8Error != RQT_SUCCESS) + goto err; + + if (msg->len == SIZE_HEADER_RSP + response->u8Len + 1) + break; + + num = response->u8Len + 1; + } else + goto err; + } + close(fd); + + return msg; + +err: + close(fd); +err_free: + msgb_free(msg); + return NULL; +} + +/********************************************************************** + * Uc temperature handling + *********************************************************************/ +void sbts2050_uc_check_temp(struct uc ucontrol) +{ + rsppkt_t *response; + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_TEMP_RQT, + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error reading temperature\n"); + return; + } + + response = (rsppkt_t *)msg->data; + + LOGP(DTEMP, LOGL_DEBUG, "Temperature Board: %+3d C\n" + "Tempeture PA: %+3d C\n", + response->rsp.tempGet.i8BrdTemp, + response->rsp.tempGet.i8PaTemp); +} /********************************************************************* * Temperature handling diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index 8f7da47..f80df16 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -1,6 +1,8 @@ #ifndef _SYSMOBTS_MISC_H #define _SYSMOBTS_MISC_H +#define RQT_SUCCESS 0 + enum sysmobts_temp_sensor { SYSMOBTS_TEMP_DIGITAL = 1, SYSMOBTS_TEMP_RF = 2, @@ -13,11 +15,31 @@ enum sysmobts_temp_type { _NUM_TEMP_TYPES }; +enum sbts2050_ids_request { + SBTS2050_TEMP_RQT = 0x10 +}; + +struct uc { + int id; + const char *path; +}; + +struct ucinfo { + uint16_t id; + int master; + int slave; + int pa; +}; + int sysmobts_temp_get(enum sysmobts_temp_sensor sensor, enum sysmobts_temp_type type); void sysmobts_check_temp(int no_eeprom_write); +struct msgb *sbts2050_ucinfo_get(struct uc ucontrol, struct ucinfo info); + +void sbts2050_uc_check_temp(struct uc ucontrol); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { From anayuso at sysmocom.de Thu Feb 27 11:30:27 2014 From: anayuso at sysmocom.de (Alvaro Neira) Date: Thu, 27 Feb 2014 12:30:27 +0100 Subject: [osmo-bts PATCH 3/3] misc/sysmobts_misc: function for switching off/on In-Reply-To: <20140227113016.15224.25190.stgit@Ph0enix> References: <20140227113016.15224.25190.stgit@Ph0enix> Message-ID: <20140227113027.15224.35042.stgit@Ph0enix> From: ?lvaro Neira Ayuso and requesting status power I have extended the principal function that we use for requesting information to the microcontroller for switching off/on the board and the PA. And i have extended too with a function for requesting the power status information of the board and the PA. Signed-off-by: Alvaro Neira Ayuso --- src/osmo-bts-sysmo/misc/sysmobts_misc.c | 78 +++++++++++++++++++++++++++++++ src/osmo-bts-sysmo/misc/sysmobts_misc.h | 12 +++++ 2 files changed, 90 insertions(+) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index aee892d..4737ff1 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -115,6 +115,12 @@ struct msgb *sbts2050_ucinfo_get(struct uc ucontrol, struct ucinfo info) case SBTS2050_TEMP_RQT: num = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + num = sizeof(command->cmd.pwrSetState); + break; + case SBTS2050_PWR_STATUS: + num = sizeof(command->cmd.pwrGetStatus); + break; default: return NULL; } @@ -133,6 +139,17 @@ struct msgb *sbts2050_ucinfo_get(struct uc ucontrol, struct ucinfo info) command->u8Id = info.id; command->u8Len = sizeof(command->cmd.tempGet); break; + case SBTS2050_PWR_RQT: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrSetState); + command->cmd.pwrSetState.u1MasterEn = !!info.master; + command->cmd.pwrSetState.u1SlaveEn = !!info.slave; + command->cmd.pwrSetState.u1PwrAmpEn = !!info.pa; + break; + case SBTS2050_PWR_STATUS: + command->u8Id = info.id; + command->u8Len = sizeof(command->cmd.pwrGetStatus); + break; default: goto err_free; } @@ -183,6 +200,67 @@ err_free: } /********************************************************************** + * Get power status function + *********************************************************************/ +int sbts2050_uc_status(struct uc ucontrol, enum sbts2050_status_rqt status) +{ + struct msgb *msg; + struct ucinfo info = { + .id = SBTS2050_PWR_STATUS, + }; + rsppkt_t *response; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return -1; + } + + response = (rsppkt_t *)msg->data; + + switch (status) { + case SBTS2050_STATUS_MASTER: + return response->rsp.pwrGetStatus.u1MasterEn; + case SBTS2050_STATUS_SLAVE: + return response->rsp.pwrGetStatus.u1SlaveEn; + case SBTS2050_STATUS_PA: + return response->rsp.pwrGetStatus.u1PwrAmpEn; + default: + return -1; + } +} + +/********************************************************************** + * Uc Power Switching handling + *********************************************************************/ +void sbts2050_uc_power(struct uc ucontrol, int pmaster, int pslave, int ppa) +{ + struct msgb *msg; + struct ucinfo info = { + .id = 0x00, + .master = pmaster, + .slave = pslave, + .pa = ppa + }; + + msg = sbts2050_ucinfo_get(ucontrol, info); + + if (msg == NULL) { + LOGP(DTEMP, LOGL_ERROR, "Error switching off some unit"); + return; + } + + LOGP(DTEMP, LOGL_DEBUG, "Switch off/on success:\n" + "MASTER %s\n" + "SLAVE %s\n" + "PA %s\n", + pmaster ? "ON" : "OFF", + pslave ? "ON" : "OFF", + ppa ? "ON" : "OFF"); +} + +/********************************************************************** * Uc temperature handling *********************************************************************/ void sbts2050_uc_check_temp(struct uc ucontrol) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h index f80df16..3d74a12 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h @@ -16,9 +16,17 @@ enum sysmobts_temp_type { }; enum sbts2050_ids_request { + SBTS2050_PWR_RQT = 0x00, + SBTS2050_PWR_STATUS = 0x01, SBTS2050_TEMP_RQT = 0x10 }; +enum sbts2050_status_rqt { + SBTS2050_STATUS_MASTER, + SBTS2050_STATUS_SLAVE, + SBTS2050_STATUS_PA +}; + struct uc { int id; const char *path; @@ -40,6 +48,10 @@ struct msgb *sbts2050_ucinfo_get(struct uc ucontrol, struct ucinfo info); void sbts2050_uc_check_temp(struct uc ucontrol); +void sbts2050_uc_power(struct uc ucontrol, int pmaster, int pslave, int ppa); + +int sbts2050_uc_status(struct uc ucontrol, enum sbts2050_status_rqt status); + int sysmobts_update_hours(int no_epprom_write); enum sysmobts_firmware_type { From jerlbeck at sysmocom.de Fri Feb 28 19:47:45 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 28 Feb 2014 20:47:45 +0100 Subject: [PATCH 1/2] msgb: Add msgb_hexdump() function Message-ID: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> This function works like osmo_hexdump() and return a static buffer containing hex bytes along with markes for the layers. Sponsored-by: On-Waves ehf --- include/osmocom/core/msgb.h | 1 + src/msgb.c | 48 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index c4be0c3..33e8081 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -73,6 +73,7 @@ extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg); extern struct msgb *msgb_dequeue(struct llist_head *queue); extern void msgb_reset(struct msgb *m); uint16_t msgb_length(const struct msgb *msg); +extern const char *msgb_hexdump(const struct msgb *msg); #ifdef MSGB_DEBUG #include diff --git a/src/msgb.c b/src/msgb.c index 359a545..98c7d79 100644 --- a/src/msgb.c +++ b/src/msgb.c @@ -153,4 +153,52 @@ void msgb_set_talloc_ctx(void *ctx) tall_msgb_ctx = ctx; } +/*! \brief Return (static) buffer containing a hexdump of the msg + * \param[in] msg message buffer + * \returns a pointer to a static char array + */ +const char *msgb_hexdump(const struct msgb *msg) +{ + static char buf[4100]; + int buf_offs = 0; + int nchars; + const unsigned char *start = msg->data; + const unsigned char *lxhs[4]; + int i; + + lxhs[0] = msg->l1h; + lxhs[1] = msg->l2h; + lxhs[2] = msg->l3h; + lxhs[3] = msg->l4h; + + for (i = 0; i < ARRAY_SIZE(lxhs); i++) { + if (lxhs[i]) { + if (lxhs[i] < msg->data) + goto out_of_range; + if (lxhs[i] > msg->tail) + goto out_of_range; + nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs, + "%s[L%d]> ", + osmo_hexdump(start, lxhs[i] - start), + i+1); + if (nchars < 0 || nchars + buf_offs >= sizeof(buf)) + return "ERROR"; + + buf_offs += nchars; + start = lxhs[i]; + } + } + nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs, + "%s", osmo_hexdump(start, msg->tail - start)); + if (nchars < 0 || nchars + buf_offs >= sizeof(buf)) + return "ERROR"; + + return buf; + +out_of_range: + nchars = snprintf(buf, sizeof(buf) - buf_offs, + "!!! L%d out of range", i+1); + return buf; +} + /*! @} */ -- 1.7.9.5 From jerlbeck at sysmocom.de Fri Feb 28 19:47:46 2014 From: jerlbeck at sysmocom.de (Jacob Erlbeck) Date: Fri, 28 Feb 2014 20:47:46 +0100 Subject: [PATCH 2/2] msgb: Optionally declare some msgb struct fields as const In-Reply-To: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> References: <1393616866-18629-1-git-send-email-jerlbeck@sysmocom.de> Message-ID: <1393616866-18629-2-git-send-email-jerlbeck@sysmocom.de> Writing directly to following struct fields may cause inconsistencies that hard to debug: data_len, len, head, tail, data In general, the available macros and functions should be used to modify them instead. This patch declares these fields as const if MSGB_DISABLE_DIRECT_WRITE is defined. Doing so may lead to warnings and errors, therefore this macro is only defined for libosmocore yet, where at least the errors are also fixed by this patch. The main purpose is to maintain consistency, so only modifing the fields themselves is restricted. It's still possible to modify the data the pointers refer to. Sponsored-by: On-Waves ehf --- Doxyfile.core.in | 2 +- Makefile.am | 3 +- include/osmocom/core/msgb.h | 69 ++++++++++++++++++++++++++++++------------ src/msgb.c | 20 ++++++------ tests/gsm0808/gsm0808_test.c | 3 +- 5 files changed, 63 insertions(+), 34 deletions(-) diff --git a/Doxyfile.core.in b/Doxyfile.core.in index 71843cc..eecd123 100644 --- a/Doxyfile.core.in +++ b/Doxyfile.core.in @@ -1447,7 +1447,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/Makefile.am b/Makefile.am index a77bd8f..cb194dc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ ACLOCAL_AMFLAGS = -I m4 -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +export AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -DMSGB_DISABLE_DIRECT_WRITE + SUBDIRS = include src src/vty src/codec src/gsm src/gb tests utils pkgconfigdir = $(libdir)/pkgconfig diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 33e8081..f627164 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -38,6 +38,12 @@ #define MSGB_DEBUG +#ifdef MSGB_DISABLE_DIRECT_WRITE +# define MSGB_CONST const +#else +# define MSGB_CONST +#endif + /*! \brief Osmocom message buffer */ struct msgb { struct llist_head list; /*!< \brief linked list header */ @@ -58,12 +64,35 @@ struct msgb { unsigned long cb[5]; /*!< \brief control buffer */ - uint16_t data_len; /*!< \brief length of underlying data array */ - uint16_t len; /*!< \brief length of bytes used in msgb */ +#ifdef DOXYGEN + const uint16_t data_len; /*!< \brief length of underlying data array */ + const uint16_t len; /*!< \brief length of bytes used in msgb */ + unsigned char const *head; /*!< \brief start of underlying memory buffer */ + unsigned char const *tail; /*!< \brief end of message in buffer */ + unsigned char const *data; /*!< \brief start of message in buffer */ +#else + union { + MSGB_CONST uint16_t data_len; + uint16_t __data_len; + }; + union { + MSGB_CONST uint16_t len; + uint16_t __len; + }; + union { + unsigned char * MSGB_CONST head; + unsigned char *__head; + }; + union { + unsigned char * MSGB_CONST tail; + unsigned char *__tail; + }; + union { + unsigned char * MSGB_CONST data; + unsigned char *__data; + }; +#endif - unsigned char *head; /*!< \brief start of underlying memory buffer */ - unsigned char *tail; /*!< \brief end of message in buffer */ - unsigned char *data; /*!< \brief start of message in buffer */ unsigned char _data[0]; /*!< \brief optional immediate data array */ }; @@ -179,12 +208,12 @@ static inline int msgb_headroom(const struct msgb *msgb) */ static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len) { - unsigned char *tmp = msgb->tail; + unsigned char *tmp = msgb->__tail; if (msgb_tailroom(msgb) < (int) len) MSGB_ABORT(msgb, "Not enough tailroom msgb_push (%u < %u)\n", msgb_tailroom(msgb), len); - msgb->tail += len; - msgb->len += len; + msgb->__tail += len; + msgb->__len += len; return tmp; } @@ -228,12 +257,12 @@ static inline void msgb_put_u32(struct msgb *msgb, uint32_t word) */ static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len) { - unsigned char *tmp = msgb->data - len; + unsigned char *tmp = msgb->__data - len; if (msgb_length(msgb) < len) MSGB_ABORT(msgb, "msgb too small to get %u (len %u)\n", len, msgb_length(msgb)); - msgb->tail -= len; - msgb->len -= len; + msgb->__tail -= len; + msgb->__len -= len; return tmp; } /*! \brief remove uint8 from end of message @@ -281,9 +310,9 @@ static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len) if (msgb_headroom(msgb) < (int) len) MSGB_ABORT(msgb, "Not enough headroom msgb_push (%u < %u)\n", msgb_headroom(msgb), len); - msgb->data -= len; - msgb->len += len; - return msgb->data; + msgb->__data -= len; + msgb->__len += len; + return msgb->__data; } /*! \brief remove (pull) a header from the front of the message buffer * \param[in] msgb message buffer @@ -296,8 +325,8 @@ static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len) */ static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len) { - msgb->len -= len; - return msgb->data += len; + msgb->__len -= len; + return msgb->__data += len; } /*! \brief remove (pull) all headers in front of l3h from the message buffer. @@ -356,8 +385,8 @@ static inline uint32_t msgb_pull_u32(struct msgb *msgb) */ static inline void msgb_reserve(struct msgb *msg, int len) { - msg->data += len; - msg->tail += len; + msg->__data += len; + msg->__tail += len; } /*! \brief Trim the msgb to a given absolute length @@ -370,8 +399,8 @@ static inline int msgb_trim(struct msgb *msg, int len) if (len > msg->data_len) return -1; - msg->len = len; - msg->tail = msg->data + len; + msg->__len = len; + msg->__tail = msg->__data + len; return 0; } diff --git a/src/msgb.c b/src/msgb.c index 98c7d79..a3a48d9 100644 --- a/src/msgb.c +++ b/src/msgb.c @@ -55,11 +55,11 @@ struct msgb *msgb_alloc(uint16_t size, const char *name) return NULL; } - msg->data_len = size; - msg->len = 0; - msg->data = msg->_data; - msg->head = msg->_data; - msg->tail = msg->_data; + msg->__data_len = size; + msg->__len = 0; + msg->__data = msg->_data; + msg->__head = msg->_data; + msg->__tail = msg->_data; return msg; } @@ -113,10 +113,10 @@ struct msgb *msgb_dequeue(struct llist_head *queue) */ void msgb_reset(struct msgb *msg) { - msg->len = 0; - msg->data = msg->_data; - msg->head = msg->_data; - msg->tail = msg->_data; + msg->__len = 0; + msg->__data = msg->_data; + msg->__head = msg->_data; + msg->__tail = msg->_data; msg->trx = NULL; msg->lchan = NULL; @@ -133,7 +133,7 @@ void msgb_reset(struct msgb *msg) */ uint8_t *msgb_data(const struct msgb *msg) { - return msg->data; + return msg->__data; } /*! \brief get length of message buffer diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index 7e5e97b..1ce6ef9 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -108,8 +108,7 @@ static void test_create_cipher_complete() msgb_free(msg); /* with l3 data but short */ - l3->len -= 1; - l3->tail -= 1; + msgb_trim(l3, l3->len - 1); msg = gsm0808_create_cipher_complete(l3, 4); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); -- 1.7.9.5