diff options
Diffstat (limited to 'src/common/cbch.c')
-rw-r--r-- | src/common/cbch.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/src/common/cbch.c b/src/common/cbch.c index 7ed11c2f..363eb672 100644 --- a/src/common/cbch.c +++ b/src/common/cbch.c @@ -12,7 +12,7 @@ * 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. + * GNU Affero 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 <http://www.gnu.org/licenses/>. @@ -38,7 +38,7 @@ struct smscb_msg { uint8_t num_segs; /* total number of segments */ }; -/* determine if current queue length differes more than permitted hysteresis from target +/* determine if current queue length differs more than permitted hysteresis from target * queue length. If it does, send CBCH LOAD IND */ static void check_and_send_cbch_load(struct gsm_bts *bts, struct bts_smscb_state *bts_ss) { @@ -139,12 +139,8 @@ static int get_smscb_block(struct bts_smscb_state *bts_ss, uint8_t *out, uint8_t block_type->seq_nr = block_nr; /* determine if this is the last block */ - if (block_nr + 1 == msg->num_segs) - block_type->lb = 1; - else - block_type->lb = 0; - - if (block_nr == 4) { + block_type->lb = (block_nr + 1 == msg->num_segs); + if (block_type->lb) { if (msg != bts_ss->default_msg) { DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n", chan_name, msg); @@ -198,7 +194,7 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ return -EINVAL; } - scm = talloc_zero_size(bts, sizeof(*scm)); + scm = talloc_zero(bts, struct smscb_msg); if (!scm) return -1; @@ -233,10 +229,10 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_RCVD_QUEUED); break; case RSL_CB_CMD_TYPE_DEFAULT: - /* old default msg will be free'd in get_smscb_block() if it is currently in transit - * and we set a new default_msg here */ + /* clear the cur_msg pointer if it is the old default message */ if (bts_ss->cur_msg && bts_ss->cur_msg == bts_ss->default_msg) - talloc_free(bts_ss->cur_msg); + bts_ss->cur_msg = NULL; + talloc_free(bts_ss->default_msg); if (cmd_type.def_bcast == RSL_CB_CMD_DEFBCAST_NORMAL) /* def_bcast == 0: normal message */ bts_ss->default_msg = scm; @@ -322,3 +318,25 @@ int bts_cbch_get(struct gsm_bts *bts, uint8_t *outbuf, struct gsm_time *g_time) return rc; } + +static void bts_smscb_state_reset(struct bts_smscb_state *bts_ss) +{ + struct smscb_msg *scm, *tmp; + llist_for_each_entry_safe(scm, tmp, &bts_ss->queue, list) { + llist_del(&scm->list); + talloc_free(scm); + } + bts_ss->queue_len = 0; + rate_ctr_group_reset(bts_ss->ctrs); + /* avoid double-free of default_msg in case cur_msg == default_msg */ + if (bts_ss->cur_msg && bts_ss->cur_msg != bts_ss->default_msg) + talloc_free(bts_ss->cur_msg); + bts_ss->cur_msg = NULL; + TALLOC_FREE(bts_ss->default_msg); +} + +void bts_cbch_reset(struct gsm_bts *bts) +{ + bts_smscb_state_reset(&bts->smscb_basic); + bts_smscb_state_reset(&bts->smscb_extended); +} |