diff --git a/channels/chan_brcm.c b/channels/chan_brcm.c
index 7a7e9fa0bd8295e0cdc1589e82fc44c6a0105506..7b92c25efbcc20dd067032de60bed3c1e452a745 100644
--- a/channels/chan_brcm.c
+++ b/channels/chan_brcm.c
@@ -189,12 +189,6 @@ static int feature_access_code_match(char *sequence);
 /*  Send dialed DTMF codes during call */
 static void send_outgoing_dtmf(struct ast_channel *owner, char dtmf_button, int frametype);
 
-/* Boolean value whether the monitoring thread shall continue. */
-static unsigned int monitor;
-static unsigned int packets;
-
-static pthread_t monitor_thread = AST_PTHREADT_NULL;
-static pthread_t packet_thread = AST_PTHREADT_NULL;
 static pthread_t ubus_thread = AST_PTHREADT_NULL;
 
 static struct ubus_context *ctx;
@@ -413,19 +407,17 @@ static uint32_t get_ubus_endpt_id(int log) {
 	return endpt_id;
 }
 
-//-------------------------------------------------------------
 // Callback for: a ubus call (invocation) has replied with some data
 static void ubus_call_answer(struct ubus_request *req, int type, struct blob_attr *msg)
 {
-	ast_debug(3, "Got answer on ubus call.\n");
+	ast_verbose("%s() from thread %d\n", __func__, ast_get_tid());
 }
 
 
-//-------------------------------------------------------------
 // Callback for: a ubus call (invocation) has finished
 static void ubus_call_complete(struct ubus_request *req, int ret)
 {
-	ast_debug(3, "Ubus call completed.\n");
+	ast_verbose("%s() from thread %d\n", __func__, ast_get_tid());
 	free(req);
 }
 
@@ -449,6 +441,7 @@ static void endpt_signal(int line, char *signal, char *state, char *data) {
 		req = calloc(1, sizeof(struct ubus_request));
 		if (!req) return;
 
+		ast_verbose("thread %d: ubus call endpt signal\n", ast_get_tid());
 		res = ubus_invoke_async(ctx, endpt_id, "signal", bb.head, req);
 
 		if(res != UBUS_STATUS_OK) {
@@ -479,6 +472,7 @@ static void endpt_connection(int line, int id, char *action) {
 
 		req = calloc(1, sizeof(struct ubus_request));
 		if (!req) return;
+		ast_verbose("thread %d: ubus call endpt connection\n", ast_get_tid());
 		res = ubus_invoke_async(ctx, endpt_id, "connection", bb.head, req);
 
 		if(res != UBUS_STATUS_OK) {
@@ -3130,30 +3124,20 @@ static int unload_module(void)
 		ast_log(LOG_WARNING, "Unable to lock the monitor\n");
 		return -1;
 	}
-	if (!ast_mutex_lock(&monlock)) {
-		ast_debug(1, "Stopping threads...\n");
-		if (monitor) {
-			monitor = 0;
-			while (pthread_kill(monitor_thread, SIGURG) == 0)
-				sched_yield();
-			pthread_join(monitor_thread, NULL);
-		}
-		monitor_thread = AST_PTHREADT_STOP;
 
-		if (packets) {
-			packets = 0;
-			while (pthread_kill(packet_thread, SIGURG) == 0)
-				sched_yield();
-			pthread_join(packet_thread, NULL);
+	if (!ast_mutex_lock(&monlock)) {
+		if (ubus_thread != AST_PTHREADT_NULL && ubus_thread != AST_PTHREADT_STOP) {
+			ast_verbose("Stopping ubus thread...\n");
+			pthread_cancel(ubus_thread);
+			pthread_join(ubus_thread, NULL);
+			ubus_thread = AST_PTHREADT_STOP;
+			ast_verbose("ubus thread is stopped\n");
 		}
-		packet_thread = AST_PTHREADT_STOP;
-
 		ast_mutex_unlock(&monlock);
 	} else {
 		ast_log(LOG_WARNING, "Unable to lock the monitor\n");
 		return -1;
 	}
-	ast_debug(1, "[%d, %d,]\n",monitor, packets);
 
 	if (!ast_mutex_lock(&iflock)) {
 		/* Destroy all the interfaces and free their memory */
@@ -3515,7 +3499,7 @@ static int endpt_get_count(void) {
 static void ubus_call_answer_rtp_stats(struct ubus_request *req, int type, struct blob_attr *msg) {
 	struct blob_attr *tb[__MAX_RTP_STATS];
 
-	ast_log(LOG_DEBUG, "Got answer from endptmngr on rtp_stats ubus call.\n");
+	ast_log(LOG_DEBUG, "thread %d: got answer from endptmngr on rtp_stats ubus call.\n", ast_get_tid());
 	blobmsg_parse(endpt_rtp_stats_policy, __MAX_RTP_STATS, tb, blob_data(msg), blob_len(msg));
 
 	if (tb[RTP_STATS_LOCAL_BURST_DENSITY])
@@ -3585,7 +3569,8 @@ static void ubus_call_answer_rtp_stats(struct ubus_request *req, int type, struc
 
 static int endpt_get_rtp_stats(int line) {
 	struct blob_buf bb;
-	int res;
+	struct ubus_request *req;
+	int res = -1;
 
 	if (endpt_id) {
 		memset(&bb, 0, sizeof(bb));
@@ -3594,9 +3579,26 @@ static int endpt_get_rtp_stats(int line) {
 		blobmsg_add_u32(&bb, "line", line);
 		blobmsg_add_u8(&bb, "reset", 1); // always reset RTP stats after get them
 
-		return (ubus_invoke(ctx, endpt_id, "rtp_stats", bb.head,
-			ubus_call_answer_rtp_stats, NULL, 2000) == UBUS_STATUS_OK ? 0 : -1);
+		req = calloc(1, sizeof(struct ubus_request));
+		if (!req) {
+			return -1;
+		}
+
+		ast_log(LOG_DEBUG, "thread %d: ubus call endpt rtp_stats \"{'line':%d,'reset':true}\"", ast_get_tid(), line);
+		if (ubus_invoke_async(ctx, endpt_id, "rtp_stats", bb.head, req) == UBUS_STATUS_OK) {
+			ast_log(LOG_DEBUG, "ubus_invoke_async() succeeded\n");
+			res = 0;
+		} else {
+			ast_log(LOG_DEBUG, "ubus_invoke_async() failed\n");
+		}
+
+		req->data_cb = ubus_call_answer_rtp_stats;
+		req->complete_cb = ubus_call_complete;
+		req->priv = NULL;
+		ubus_complete_request_async(ctx, req);
 	}
+
+	return res;
 }
 
 // Reception of RPC call
@@ -3707,9 +3709,11 @@ static int ubus_init(void) {
 static void *pe_base_run(void *unused) {
 	int delay;
 
-	for(delay = 0; delay < 5 && (!iflist || !cur_tech); delay++) sleep(1);
-
+	ast_verbose("thread %d started\n", ast_get_tid());
+	for (delay = 0; delay < 5 && (!iflist || !cur_tech); delay++)
+		sleep(1);
 	pe_base_dispatch(base);
+
 	return NULL;
 }
 
@@ -3718,6 +3722,8 @@ static int load_module(void)
 	struct ast_config *cfg;
 	int result, try;
 
+	ast_verbose("thread %d is loading the module...\n", ast_get_tid());
+
 	if (!(default_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
 		return AST_MODULE_LOAD_DECLINE;
 	}
@@ -3754,6 +3760,8 @@ static int load_module(void)
 	if (!audio_rx_bus) exit_failure("Failed to create audio_rx bus");
 	pe_bus_add_handler(audio_rx_bus, audio_packet_handler);
 
+	/* endpt_get_count() invokes synchronous ubus call and MUST be called before creating the ubus thread.
+	 * Otherwise it may cause the process crash or hang */
 	for (try = 0; try < 20 && num_endpoints == -1; try++) {
 		if(endpt_get_count()) {
 			ast_log(LOG_DEBUG, "Waiting for endptmngr...\n");
diff --git a/include/asterisk/logger.h b/include/asterisk/logger.h
index d823ed4e447ed9e72d8cde7d73c95b319e0d25c1..5deb2505dc702272cf6495b3a22a5197535d5737 100644
--- a/include/asterisk/logger.h
+++ b/include/asterisk/logger.h
@@ -947,6 +947,8 @@ unsigned long _ast_trace_dec_indent(void);
 	ast_trace(__level < 0 ? __scope_level : __level, " " __VA_ARGS__); \
 })
 
+#define CHECK_POINT() ast_log(AST_LOG_ERROR, "Check point at %s@%s:%d\n", __func__, __FILE__, __LINE__)
+
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }