aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/cbch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/cbch.c')
-rw-r--r--src/common/cbch.c42
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);
+}