Do not call rsl_chan_release directly but use the use_count of the lchan

Call use_lchan early in allocate_loc_updating_req, do not directly call
rsl_chan_release but go through channel alloc to take the use_count into
account.
diff --git a/include/openbsc/abis_rsl.h b/include/openbsc/abis_rsl.h
index a0e8cba..e7fea80 100644
--- a/include/openbsc/abis_rsl.h
+++ b/include/openbsc/abis_rsl.h
@@ -345,7 +345,6 @@
 		      u_int8_t ta);
 int rsl_chan_activate_tch_f(struct gsm_bts_trx_ts *ts);
 int rsl_chan_activate_sdcch(struct gsm_bts_trx_ts *ts);
-int rsl_chan_release(struct gsm_lchan *lchan);
 int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
 		   u_int8_t *ms_ident, u_int8_t chan_needed);
 int rsl_paging_cmd_imsi(struct gsm_bts *bts, u_int8_t chan_needed, const char *imsi_str);
@@ -357,6 +356,7 @@
 
 /* to be provided by external code */
 int abis_rsl_sendmsg(struct msgb *msg);
+int rsl_chan_release(struct gsm_lchan *lchan);
 
 #endif /* RSL_MT_H */
 
diff --git a/include/openbsc/chan_alloc.h b/include/openbsc/chan_alloc.h
index 0cbd03e..0c6d63e 100644
--- a/include/openbsc/chan_alloc.h
+++ b/include/openbsc/chan_alloc.h
@@ -19,4 +19,7 @@
 /* Free a logical channel (SDCCH, TCH, ...) */
 void lchan_free(struct gsm_lchan *lchan);
 
+/* Consider releasing the channel */
+int lchan_auto_release(struct gsm_lchan *lchan);
+
 #endif /* _CHAN_ALLOC_H */
diff --git a/src/chan_alloc.c b/src/chan_alloc.c
index bb71d35..98588b1 100644
--- a/src/chan_alloc.c
+++ b/src/chan_alloc.c
@@ -29,6 +29,7 @@
 #include <openbsc/gsm_data.h>
 #include <openbsc/chan_alloc.h>
 #include <openbsc/abis_nm.h>
+#include <openbsc/abis_rsl.h>
 #include <openbsc/debug.h>
 
 static void auto_release_channel(void *_lchan);
@@ -196,28 +197,29 @@
 	 * channel using it */
 }
 
-/*
- * Auto release the channel when the use count is zero
- */
-static void auto_release_channel(void *_lchan)
+/* Consider releasing the channel now */
+int lchan_auto_release(struct gsm_lchan *lchan)
 {
-	struct gsm_lchan *lchan = _lchan;
-	/*
-	 * Busy...
-	 */
 	if (lchan->use_count > 0) {
-		schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT);
-		return;
+		return 0;
 	}
 
-	/*
-	 * spoofed? message
-	 */
+	/* spoofed? message */
 	if (lchan->use_count < 0) {
 		DEBUGP(DRLL, "Channel count is negative: %d\n", lchan->use_count);
 	}
 
 	DEBUGP(DRLL, "Recylcing the channel with: %d (%x)\n", lchan->nr, lchan->nr);
 	rsl_chan_release(lchan);
+	return 1;
+}
+
+/* Auto release the channel when the use count is zero */
+static void auto_release_channel(void *_lchan)
+{
+	struct gsm_lchan *lchan = _lchan;
+
+	if (!lchan_auto_release(lchan))
+		schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT);
 }
 
diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c
index fc74579..61080b4 100644
--- a/src/gsm_04_08.c
+++ b/src/gsm_04_08.c
@@ -98,12 +98,12 @@
 
 static void allocate_loc_updating_req(struct gsm_lchan *lchan)
 {
+	use_lchan(lchan);
 	release_loc_updating_req(lchan);
 
 	lchan->loc_operation = (struct gsm_loc_updating_operation *)
 				malloc(sizeof(*lchan->loc_operation));
 	memset(lchan->loc_operation, 0, sizeof(*lchan->loc_operation));
-	use_lchan(lchan);
 }
 
 static void parse_lai(struct gsm_lai *lai, const struct gsm48_loc_area_id *lai48)
@@ -397,7 +397,7 @@
 
 	release_loc_updating_req(lchan);
 	gsm0408_loc_upd_rej(lchan, reject_cause);
-	rsl_chan_release(lchan);
+	lchan_auto_release(lchan);
 }
 
 static void schedule_reject(struct gsm_lchan *lchan)
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index af62537..0fe1310 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -80,3 +80,4 @@
 void rsl_chan_release(void) {}
 void msgb_alloc(void) {}
 void gsm0411_send_sms(void) {}
+void lchan_auto_release(void) {}