diff --git a/libvoice/common.c b/libvoice/common.c
index f75cdd43852e439bb0e335f5ed536e6a5d40add4..210eeff0801bdcc9b91e840783232cc6c4e78225 100644
--- a/libvoice/common.c
+++ b/libvoice/common.c
@@ -52,9 +52,13 @@ const struct voice_signal_t signal_map[] = { // List of signals requested by Ast
 	{ .name = "callwt",         .signal = VOICE_SIG_CALL_WAITING },
 	{ .name = "busy",           .signal = VOICE_SIG_BUSY },
 	{ .name = "ringing",        .signal = VOICE_SIG_RINGING },
+	{ .name = "ringing_int",    .signal = VOICE_SIG_RINGING_INTERNAL },
 	{ .name = "callid_ringing", .signal = VOICE_SIG_CALLID_RINGING },
+	{ .name = "callid_ringing_int", .signal = VOICE_SIG_CALLID_RINGING_INTERNAL },
 	{ .name = "callid",         .signal = VOICE_SIG_CALLID },
 	{ .name = "congestion",     .signal = VOICE_SIG_NETBUSY },
+	{ .name = "positive",       .signal = VOICE_SIG_POSITIVE },
+	{ .name = "negative",       .signal = VOICE_SIG_NEGATIVE },
 	{ .name = "dtmf0",          .signal = VOICE_SIG_DTMF0 },
 	{ .name = "dtmf1",          .signal = VOICE_SIG_DTMF1 },
 	{ .name = "dtmf2",          .signal = VOICE_SIG_DTMF2 },
@@ -78,7 +82,7 @@ const struct voice_signal_t signal_map[] = { // List of signals requested by Ast
 };
 
 // Callback function which is invoked when an event is detected from the voice engine
-void (*voice_cb_event_report)(int line, const char *event, int data) = NULL;
+void (*voice_cb_event_report)(int line, const char *event, const char *data) = NULL;
 // Callback function which is invoked when an encoded media packet is generated by the voice engine
 void (*voice_cb_egress_media)(const struct media_packet_t *packet, int size) = NULL;
 
@@ -124,7 +128,9 @@ int voice_line_preinit(void) {
 		lines[i].type = terminal_info.voice_ports[i];
 		ENDPT_DBG("lines[%d].type=%d\n", i, lines[i].type);
 		lines[i].pcm_callid[PCM_0] = CALLID_INVALID;
+		ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", i, PCM_0, lines[i].pcm_callid[PCM_0]);
 		lines[i].pcm_callid[PCM_1] = CALLID_INVALID;
+		ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", i, PCM_1, lines[i].pcm_callid[PCM_1]);
 	}
 
 	return 0;
@@ -164,7 +170,7 @@ int voice_line_deinit(void) {
 }
 
 // Register the callback function for event report
-int voice_register_cb_event_report(void (*cb_event_report)(int line, const char *event, int data)) {
+int voice_register_cb_event_report(void (*cb_event_report)(int line, const char *event, const char *data)) {
 	voice_cb_event_report = cb_event_report;
 
 	return 0;
diff --git a/libvoice/libvoice.h b/libvoice/libvoice.h
index 3a704831573eab99a4bd2acbc3803c54115b0ce7..9f64f4828db976b3b06826282fdcda089695ecc8 100644
--- a/libvoice/libvoice.h
+++ b/libvoice/libvoice.h
@@ -13,17 +13,26 @@
 #include <libpicoevent.h>
 #include "voice-types.h"
 
-#define MAX_CALLER_ID_LEN  120 // Max length of caller id string we accept
+#define MIN_CALLER_ID_LEN  14  	// Minimum string length to be valid.
+#define MAX_CALLER_ID_LEN  (CLID_MAX_DATE + CLID_MAX_NUMBER + CLID_MAX_NAME + 3 + 5)	// Max length of caller id string
+#define CLID_TIME_DELIM    8	// String index where time record ends.
+#define CLID_NUMB_REC      (CLID_TIME_DELIM + 2)  // String index where number starts.
+
 #define MAX_KEYPAD_DIGITS  100 // Max number of simulated keypad presses we accept
 #define MAX_CODECS         20
 #define MAX_CODEC_NAMELEN  20
-#define MIN_CALLER_ID_LEN  14                   // Minimum string length to be valid.
-#define CLID_TIME_DELIM    8			// String index where time record ends.
-#define CLID_NUMB_REC      CLID_TIME_DELIM + 2  // String index where number starts.
-#define MAX_CALLER_NAME	   60 // Max length of caller's name to be displayed on the DECT handset
 
 #define DEBUG_LOOPBACK       0 // Debug - feed received audio back to transmitter
 
+enum PAGING_STATUS
+{
+	PAGING_IDLE,
+	PAGING_IN_PROGRESS,
+	PAGING_SUCCESS,
+	PAGING_NOT_IN_REACH,
+	PAGING_TIMEOUT
+};
+
 enum VOICE_EVENT
 {
 	VOICE_EVT_START,
@@ -75,7 +84,9 @@ enum VOICE_SIGNAL {
 	VOICE_SIG_CALL_WAITING,
 	VOICE_SIG_BUSY,
 	VOICE_SIG_RINGING,
+	VOICE_SIG_RINGING_INTERNAL,
 	VOICE_SIG_CALLID_RINGING,
+	VOICE_SIG_CALLID_RINGING_INTERNAL,
 	VOICE_SIG_CALLID,
 	VOICE_SIG_NETBUSY,
 	VOICE_SIG_DTMF0,
@@ -97,6 +108,8 @@ enum VOICE_SIGNAL {
 	VOICE_SIG_INGRESS_DTMF, // Simulate phone keypad button pressing
 	VOICE_SIG_ANSWER,
 	VOICE_SIG_K_BREAK,
+	VOICE_SIG_POSITIVE,
+	VOICE_SIG_NEGATIVE,
 	VOICE_SIG_LAST
 };
 
@@ -142,6 +155,10 @@ struct line_t {
 	uint16_t conference_started;      // True if conference has just been setup by DECT handset
 	int pcm_callid[2];	  // -1: Invalid, 0: Obtaining, >0: Established
 	pe_list_t *pending_digits;        // List of keypad digits waiting to be sent
+	enum PAGING_STATUS paging_status; // Line's paging status
+#define VOICEMNGR_LINE_FLAG_NARROW_BAND_ONLY    0x1
+#define VOICEMNGR_LINE_FLAG_OVERLAP_DIALING     0x2
+	uint32_t flags;
 
 	void *priv;                       // Platform dependent data
 };
@@ -212,33 +229,40 @@ struct codec_capability {
 	} codecs[MAX_CODECS];
 };
 
-#define ENABLE_VOICE_DEBUG    0 // Enable/disable voice debug
+#define ENABLE_VOICE_DEBUG    1 // Enable/disable voice debug
 #if ENABLE_VOICE_DEBUG
 // log to file
-#define ENDPT_DBG(fmt, ...) do { \
-		FILE *fp = fopen("/tmp/voicemngr.log", "a"); \
-		if (fp) { \
-			struct timeval tv_now; \
-			struct tm tm_now; \
-			gettimeofday(&tv_now, NULL); \
-			localtime_r(&tv_now.tv_sec, &tm_now); \
-			fprintf(fp, "%04d-%02d-%02d %02d:%02d:%02d.%03d %s()@%s:%d: " fmt, \
-				1900 + tm_now.tm_year, tm_now.tm_mon + 1, tm_now.tm_mday, \
-				tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec, (int)(tv_now.tv_usec / 1000), \
-				__func__, __FILE__, __LINE__, ##__VA_ARGS__); \
-			fclose(fp); \
-		} \
-		printf(fmt, ##__VA_ARGS__); \
-	} while (0)
+#define ENDPT_LOG(level, fmt, ...) do { \
+    FILE *fp = fopen("/tmp/voicemngr.log", "a"); \
+    if (fp) { \
+        struct timeval tv_now; \
+        struct tm tm_now; \
+        gettimeofday(&tv_now, NULL); \
+        localtime_r(&tv_now.tv_sec, &tm_now); \
+        fprintf(fp, "%04d-%02d-%02d %02d:%02d:%02d.%03d [%s] %s()@%s:%d: " fmt, \
+            1900 + tm_now.tm_year, tm_now.tm_mon + 1, tm_now.tm_mday, \
+            tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec, (int)(tv_now.tv_usec / 1000), \
+            level, __func__, __FILE__, __LINE__, ##__VA_ARGS__); \
+        fclose(fp); \
+    } \
+    printf(fmt, ##__VA_ARGS__); \
+} while (0)
+
+#define ENDPT_DBG(fmt, ...)   ENDPT_LOG("DEBUG", fmt, ##__VA_ARGS__)
+#define ENDPT_INFO(fmt, ...)  ENDPT_LOG("INFO ", fmt, ##__VA_ARGS__)
+#define ENDPT_WARN(fmt, ...)  ENDPT_LOG("WARN ", fmt, ##__VA_ARGS__)
+#define ENDPT_ERR(fmt, ...)   ENDPT_LOG("ERROR", fmt, ##__VA_ARGS__)
 #else
 #define ENDPT_DBG(format, ...)  voice_syslog(LOG_DEBUG, "%s:%d %s: " format, \
-		__FILE__, __LINE__, __func__, ##__VA_ARGS__)
-#endif
-#define CHECK_POINT() ENDPT_DBG("Check point at %s@%s:%d\n", __func__, __FILE__, __LINE__)
-
+               __FILE__, __LINE__, __func__, ##__VA_ARGS__)
 #define ENDPT_INFO(...) voice_syslog(LOG_INFO, __VA_ARGS__)
 #define ENDPT_WARN(...) voice_syslog(LOG_WARNING, __VA_ARGS__)
 #define ENDPT_ERR(...)  voice_syslog(LOG_ERR, __VA_ARGS__)
+#endif /* ENABLE_VOICE_DEBUG */
+
+#define CHECK_POINT() ENDPT_DBG("Check point\n")
+
+
 
 extern struct terminal_info_t terminal_info;
 extern struct line_t *lines;
@@ -248,7 +272,7 @@ extern const struct voice_event_t event_map[];
 extern const struct dect_event_t dect_event_map[];
 extern const struct voice_signal_t signal_map[];
 
-extern void (*voice_cb_event_report)(int line, const char *event, int data);
+extern void (*voice_cb_event_report)(int line, const char *event, const char *data);
 extern void (*voice_cb_egress_media)(const struct media_packet_t *packet, int size);
 
 
@@ -284,7 +308,7 @@ void voice_hook_simulation_maintain(int line);
 int voice_get_rtp_stats(int line, int connection, int reset, struct rtp_stats_t *rtp_stats);
 int voice_get_codec_capability(struct codec_capability *pcodecs);
 int voice_set_country(const char *country_code);
-int voice_register_cb_event_report(void (*voice_cb_event_report)(int line, const char *event, int data));
+int voice_register_cb_event_report(void (*voice_cb_event_report)(int line, const char *event, const char *data));
 int voice_register_cb_egress_media(void (*cb_egress_media)(const struct media_packet_t *packet, int size));
 int voice_write_media_packet(const struct media_packet_t *packet);
 
diff --git a/libvoice/voice-types.h b/libvoice/voice-types.h
index 74cfb67b65604e11ecf3359af1401ad14f665add..b278447c1a36c22fd91c034b450b2b48a4d14a8b 100644
--- a/libvoice/voice-types.h
+++ b/libvoice/voice-types.h
@@ -68,6 +68,21 @@ enum call_action {
 	CALL_LAST
 };
 
+typedef enum flash_spec {
+	FLASH_SPEC_UK = 0,
+	FLASH_SPEC_ETSI,
+} flash_spec;
+
+// The possible values of DECTMNGR_RPC_PARAM_HANGUPCAUSE
+enum hangup_cause {
+	HANGUPCAUSE_UNANSWERED = 0,
+	HANGUPCAUSE_ANSWERED_ELSEWERE,
+};
+
+#define CLID_MAX_DATE  	10
+#define CLID_MAX_NUMBER	30
+#define CLID_MAX_NAME  	60
+
 /*
  * UBUS related definitions
  */
@@ -79,5 +94,8 @@ enum call_action {
 // Parameters
 #define DECTMNGR_RPC_PARAM_EXTENSION_ID  "extension_id"
 #define DECTMNGR_RPC_PARAM_PCM_ID        "pcm_id"
+#define DECTMNGR_RPC_PARAM_HANGUPCAUSE   "hangupcause"
+// Parameter values
+#define EVENT_DATA_NARROW_BAND_ONLY      "narrow_band_only"
 
 #endif
diff --git a/line-dect.c b/line-dect.c
index af839a8939322271bda3276ff7800615d2811256..3738cc6b18c0d0bc39fcf00fcf21ee15436bccd9 100644
--- a/line-dect.c
+++ b/line-dect.c
@@ -111,7 +111,7 @@ int ubus_process_queued_reqs_to_dectmngr(void) {
 	switch (req->action) {
 		case ACTION_CONN_CREATE:
 		case ACTION_SIG_RING:
-			if(ubus_call_dectmngr(voicemngr_line_to_dectmngr_line(req->line), 1, 0, req->caller_id, req->caller_name, req->pcm_id, req)) {
+			if(ubus_call_dectmngr(voicemngr_line_to_dectmngr_line(req->line), 1, 0, req->caller_id, req->caller_name, req->sip_client_id, req->pcm_id, req)) {
 				free(req);
 				return -1;
 			}
@@ -123,7 +123,16 @@ int ubus_process_queued_reqs_to_dectmngr(void) {
 				return 0;
 			}
 			// ACTION_CONN_CLOSE: could not just skip due to compile warning is treated as error.
-			if(ubus_call_dectmngr(voicemngr_line_to_dectmngr_line(req->line), 0, 1, req->caller_id, req->caller_name, req->pcm_id, req)) {
+			if(ubus_call_dectmngr(voicemngr_line_to_dectmngr_line(req->line), 0, 1, req->caller_id, req->caller_name, req->sip_client_id, req->pcm_id, req)) {
+				free(req);
+				return -1;
+			}
+			break;
+		case ACTION_RINGING_STOP:
+			dectmngr_rpc.action = req->action;
+			dectmngr_rpc.extension_id = voicemngr_line_to_dectmngr_line(req->line);
+			dectmngr_rpc.params.hangupcause = req->hangupcause;
+			if(ubus_dectmngr_rpc(&dectmngr_rpc, req)) {
 				free(req);
 				return -1;
 			}
@@ -146,13 +155,13 @@ int ubus_process_queued_reqs_to_dectmngr(void) {
 			}
 			break;
 		case ACTION_SIG_BUSY_TONE:
-			if(ubus_call_dectmngr(voicemngr_line_to_dectmngr_line(req->line), 0, 2, req->caller_id, req->caller_name, req->pcm_id, req)) {
+			if(ubus_call_dectmngr(voicemngr_line_to_dectmngr_line(req->line), 0, 2, req->caller_id, req->caller_name, req->sip_client_id, req->pcm_id, req)) {
 				free(req);
 				return -1;
 			}
 			break;
 		case ACTION_SIG_ANSWERED:
-			if(ubus_call_dectmngr(voicemngr_line_to_dectmngr_line(req->line), 2, 0, req->caller_id, req->caller_name, req->pcm_id, req)) {
+			if(ubus_call_dectmngr(voicemngr_line_to_dectmngr_line(req->line), 2, 0, req->caller_id, req->caller_name, req->sip_client_id, req->pcm_id, req)) {
 				free(req);
 				return -1;
 			}
@@ -179,6 +188,12 @@ int simulate_digits_pressing(int line, const char *pressed_digits) {
 	if(lines[line].type != VOICE_LINE_DECT)
 		return 0;
 
+	if (!pressed_digits) {
+		ENDPT_DBG("line: %d overlap dialing\n", line);
+		lines[line].flags |= VOICEMNGR_LINE_FLAG_OVERLAP_DIALING;
+		return 0;
+	}
+
 	ENDPT_DBG("line: %d pressed_digits: %s\n", line, (pressed_digits ? pressed_digits : ""));
 
 	// Store digits in a list.
@@ -215,6 +230,8 @@ int ubus_cb_dectmngr_replied(struct line_req_t *req, enum ubus_msg_status reply_
 	if(!req)
 		return -1;
 
+	struct line_t *line = &lines[req->line];
+
 	ENDPT_DBG("got answer req %p from dectmngr, action: %d, line: %d, pcmId: %d, conId: %d\n",
 		req, req->action, req->line, req->pcm_id, req->connection_id);
 	pcm_states_dump(__func__, req->line);
@@ -225,28 +242,40 @@ int ubus_cb_dectmngr_replied(struct line_req_t *req, enum ubus_msg_status reply_
 				reply_status = UBUS_STATUS_UNKNOWN_ERROR;
 			}
 			break;
-		case ACTION_CONN_CLOSE:
 		case ACTION_RINGING_STOP:
-			if (req->pcm_id == PCM_0 || req->pcm_id == PCM_1) {
-				lines[req->line].pcm_callid[req->pcm_id] = CALLID_INVALID;
+			if (get_callid_state(line->pcm_callid[req->pcm_id]) == CALLID_ESTABLISHED)
+				break; // Don't clear if call is already established
+			// intentional fallthrough
+		case ACTION_CONN_CLOSE:
+			if (is_valid_pcm_id(req->pcm_id)) {
+				line->pcm_callid[req->pcm_id] = CALLID_INVALID;
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", req->line, req->pcm_id, line->pcm_callid[req->pcm_id]);
 			} else if (req->pcm_id == -1) {
-				// Close all calls
-				lines[req->line].pcm_callid[PCM_0] = CALLID_INVALID;
-				lines[req->line].pcm_callid[PCM_1] = CALLID_INVALID;
+				// Clear both PCM slots
+				for (int i = 0; i <= PCM_1; ++i) {
+					line->pcm_callid[i] = CALLID_INVALID;
+					ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", req->line, i, CALLID_INVALID);
+				}
+			}
+			// If no established calls left, close connection
+			if (get_callid_state(line->pcm_callid[PCM_0]) != CALLID_ESTABLISHED &&
+				get_callid_state(line->pcm_callid[PCM_1]) != CALLID_ESTABLISHED) {
+				reply_status = voice_connection_close(req->line, req->line)
+					? UBUS_STATUS_UNKNOWN_ERROR
+					: UBUS_STATUS_OK;
 			}
-			if (get_callid_state(lines[req->line].pcm_callid[PCM_0]) == CALLID_ESTABLISHED ||
-				get_callid_state(lines[req->line].pcm_callid[PCM_1]) == CALLID_ESTABLISHED)
-				break;
-			reply_status = voice_connection_close(req->line, req->line) ? // Close regardless of any dectmngr error.
-				UBUS_STATUS_UNKNOWN_ERROR : UBUS_STATUS_OK;
 			break;
 		case ACTION_SIG_RING:
-			if ((req->pcm_id == PCM_0 && get_callid_state(lines[req->line].pcm_callid[PCM_1]) == CALLID_OBTAINING) ||
-				(req->pcm_id == PCM_1 && get_callid_state(lines[req->line].pcm_callid[PCM_0]) == CALLID_OBTAINING))
-				break;
-			if (req->pcm_id == PCM_0 || req->pcm_id == PCM_1)
-				lines[req->line].pcm_callid[req->pcm_id] = CALLID_OBTAINING;
+		{
+			int other_pcm = (req->pcm_id == PCM_0) ? PCM_1 : PCM_0;
+			if (is_valid_pcm_id(req->pcm_id)) {
+				if (get_callid_state(line->pcm_callid[other_pcm]) != CALLID_OBTAINING) {
+					line->pcm_callid[req->pcm_id] = CALLID_OBTAINING;
+					ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", req->line, req->pcm_id, CALLID_OBTAINING);
+				}
+			}
 			break;
+		}
 		default:
 			break;
 	}
diff --git a/line.c b/line.c
index 5cb22034e988106582e8b5da2eb2ff2234571e3b..5d93e96f83417a66b30cfca366472010b66ef854 100644
--- a/line.c
+++ b/line.c
@@ -44,13 +44,18 @@ callid_state get_callid_state(int call_id) {
 		return CALLID_ESTABLISHED;
 }
 
+bool is_valid_pcm_id(int id)
+{
+	return id == PCM_0 || id == PCM_1;
+}
+
 static int send_dect_event_to_asterisk(int line, struct dect_event_t dectEvnt)
 {
 	struct line_event_t *msg;
 
 	msg = malloc(sizeof(struct line_event_t));
 	msg->name = dectEvnt.name;
-	msg->data = 0;
+	msg->data = NULL;
 	msg->line = line;
 
 	ubus_call_asterisk(msg);
@@ -83,7 +88,7 @@ static int perhaps_simulate_busy(int line, struct voice_ubus_req_t *ubus_req)
 	msg = malloc(sizeof(struct line_event_t));
 	if (msg) {
 		msg->name = ev->name;
-		msg->data = 0;
+		msg->data = NULL;
 		msg->line = line;
 		send_event_main(msg, EVENT_MAIN_LINE);
 	} else {
@@ -94,7 +99,7 @@ static int perhaps_simulate_busy(int line, struct voice_ubus_req_t *ubus_req)
 }
 //----------------------------------------------------------------------------------
 // DECT handset tone trigger
-static int dect_tone_play(int line, int pcm, enum VOICE_SIGNAL signal, const char *data, struct voice_ubus_req_t *ubus_req)
+/*static int dect_tone_play(int line, int pcm, enum VOICE_SIGNAL signal, const char *data, struct voice_ubus_req_t *ubus_req)
 {
 	struct line_req_t *line_req = NULL;
 	ENDPT_DBG("line=%d, pcm=%d, data=%s\n", line, pcm, data);
@@ -131,23 +136,52 @@ static int dect_tone_play(int line, int pcm, enum VOICE_SIGNAL signal, const cha
 	line_req->ubus.reqIn = NULL;
 
 	return 0;
-}
+}*/
 
-static void setCallerName(const char *data, char *callerName)
+static void setCLIDinfo(const char *data, struct line_req_t *line_req)
 {
-	char *start;
+	if (!data || !line_req) {
+		return;
+	}
 
-	if ( (start = strchr(data,'\"')) )
-	{
-		char *end;
-
-		start += 1;
-		if ( (end = strchr(start,'\"')) )
-		{
-			int len = ((end - start) < MAX_CALLER_NAME ? (end - start) : MAX_CALLER_NAME);
-			memcpy(callerName, start, len);
-			callerName[len] = '\0';
+	size_t data_len = strlen(data);
+	char cid_tmp[data_len + 1];
+
+	strcpy(cid_tmp, data);
+	char* ptr = cid_tmp;
+
+	// Initialize struct fields to empty strings
+	line_req->caller_id[0] = '\0';
+	line_req->caller_name[0] = '\0';
+
+	char *token = strtok_r(cid_tmp, ", ", &ptr);  // Skip the first field (date)
+	if (!token) return;
+
+	token = strtok_r(NULL, ", ", &ptr);  // Extract Caller ID
+	if (token) {
+		strncpy(line_req->caller_id, token, sizeof(line_req->caller_id) - 1);
+		line_req->caller_id[sizeof(line_req->caller_id) - 1] = '\0';
+	}
+
+	token = strtok_r(NULL, ",", &ptr);  // Extract Caller Name (quoted, may be empty)
+	if (token) {
+		// Check if it's enclosed in quotes
+		if (token[0] == '"') {
+			token++; // Move past opening quote
+			char *end_quote = strchr(token, '"');
+			if (end_quote) {
+				*end_quote = '\0'; // Terminate at closing quote
+			}
 		}
+		if (strlen(token) > 0) { // Only copy if non-empty
+			strncpy(line_req->caller_name, token, sizeof(line_req->caller_name) - 1);
+			line_req->caller_name[sizeof(line_req->caller_name) - 1] = '\0';
+		}
+	}
+
+	token = strtok_r(NULL, ", ", &ptr);  // Extract Line Number
+	if (token) {
+		line_req->sip_client_id = atoi(token);
 	}
 }
 
@@ -156,9 +190,9 @@ static void setCallerName(const char *data, char *callerName)
 static int line_signal_ring(int line, int pcm, enum VOICE_SIGNAL signal, const char *data, struct voice_ubus_req_t *ubus_req)
 {
 	struct line_req_t *line_req = NULL;
-	int start_ring = data && strcmp(data, "0") != 0;
+	int start_ring = data && strcmp(data, "0") != 0 && strcmp(data, "answered") != 0;
 
-	ENDPT_DBG("line=%d, pcm=%d, data=%s\n", line, pcm, data);
+	ENDPT_DBG("line=%d, pcm=%d, data=%s, start_ring: %d\n", line, pcm, data, start_ring);
 	pcm_states_dump(__func__, line);
 
 	// Relay the request to dectmngr if the line is DECT
@@ -178,13 +212,7 @@ static int line_signal_ring(int line, int pcm, enum VOICE_SIGNAL signal, const c
 		// Parse the called ID string generated by Asterisk
 		if(data && strlen(data) >= MIN_CALLER_ID_LEN && strlen(data) <= MAX_CALLER_ID_LEN &&
 			data[CLID_TIME_DELIM] == ',' && data[CLID_NUMB_REC + 1] != ',') {
-			char cid_tmp[strlen(data) + 1], *end;
-
-			strcpy(cid_tmp, data);
-			if ((end = strchr(cid_tmp + CLID_NUMB_REC, ',')) != NULL)
-				*end = '\0'; // Find comma after digits and null it
-			strcpy(line_req->caller_id, cid_tmp + CLID_NUMB_REC); // Extract the number
-			setCallerName(data, line_req->caller_name);
+			setCLIDinfo(data, line_req);
 		}
 	}
 
@@ -199,10 +227,12 @@ static int line_signal_ring(int line, int pcm, enum VOICE_SIGNAL signal, const c
 			break;
 
 		case VOICE_SIG_RINGING:
+		case VOICE_SIG_RINGING_INTERNAL:
 		case VOICE_SIG_CALLID_RINGING:
+		case VOICE_SIG_CALLID_RINGING_INTERNAL:
 			if(line_req) {
 				if(start_ring) {
-					if(signal == VOICE_SIG_CALLID_RINGING) {
+					if(signal == VOICE_SIG_CALLID_RINGING || VOICE_SIG_CALLID_RINGING_INTERNAL) {
 						// Dect ignore this enable signal
 						free(line_req);
 						return 0;
@@ -210,6 +240,10 @@ static int line_signal_ring(int line, int pcm, enum VOICE_SIGNAL signal, const c
 					line_req->action = ACTION_SIG_RING;
 				} else {
 					line_req->action = ACTION_RINGING_STOP;
+					if (strcmp(data, "answered") == 0)
+						line_req->hangupcause = HANGUPCAUSE_ANSWERED_ELSEWERE;
+					else
+						line_req->hangupcause = HANGUPCAUSE_UNANSWERED;
 				}
 				line_req->caller_id[0] = 0; // Discard enable/disable char or it will become the caller ID
 			} else {
@@ -220,6 +254,10 @@ static int line_signal_ring(int line, int pcm, enum VOICE_SIGNAL signal, const c
 			if(line_req) {
 				if(!start_ring) {
 					line_req->action = ACTION_RINGING_STOP;
+					if (strcmp(data, "answered") == 0)
+						line_req->hangupcause = HANGUPCAUSE_ANSWERED_ELSEWERE;
+					else
+						line_req->hangupcause = HANGUPCAUSE_UNANSWERED;
 				}
 				line_req->caller_id[0] = 0; // Discard enable/disable char or it will become the caller ID
 				break;
@@ -278,6 +316,7 @@ int line_signal(int line, const char *signame, const char *data, struct voice_ub
 {
 	const struct voice_signal_t *sig;
 	int res = 0;
+	int pcm = PCM_0;
 
 	ENDPT_DBG("line=%d(type:%d), signame=%s, data=%s\n", line, lines[line].type, signame, data);
 
@@ -294,15 +333,22 @@ int line_signal(int line, const char *signame, const char *data, struct voice_ub
 
 	switch(sig->signal) {
 		case VOICE_SIG_CALLID_RINGING:
+		case VOICE_SIG_CALLID_RINGING_INTERNAL:
 		case VOICE_SIG_CALLID:
 		case VOICE_SIG_RINGING:
+		case VOICE_SIG_RINGING_INTERNAL:
 			if(atoi(data) == 0) {
-				res = line_signal_ring(line, get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING ?
-						PCM_0 : PCM_1, sig->signal, data, ubus_req);
+				if ( get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING ||
+				     get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_INVALID )
+					pcm = PCM_0;
+				else
+					pcm = PCM_1;
+
+				res = line_signal_ring(line, pcm, sig->signal, data, ubus_req);
 				lines[line].signaled_call_waiting = 0;
 			} else {
-				res = line_signal_ring(line, get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_INVALID ?
-						PCM_0 : PCM_1, sig->signal, data, ubus_req);
+				pcm = get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_INVALID ? PCM_0 : PCM_1;
+				res = line_signal_ring(line, pcm, sig->signal, data, ubus_req);
 			}
 			break;
 
@@ -313,20 +359,18 @@ int line_signal(int line, const char *signame, const char *data, struct voice_ub
 		case VOICE_SIG_CALL_WAITING:
 			if (lines[line].type == VOICE_LINE_DECT) {
 				ENDPT_DBG("lines[%d].signaled_call_waiting: %d\n", line, lines[line].signaled_call_waiting);
-				if(data && strlen(data) >= MIN_CALLER_ID_LEN &&
-					strlen(data) <= MAX_CALLER_ID_LEN &&
-					data[CLID_TIME_DELIM] == ',' &&
-					data[CLID_NUMB_REC + 1] != ',' &&
+				if(data && strlen(data) >= MIN_CALLER_ID_LEN && strlen(data) <= MAX_CALLER_ID_LEN &&
+					data[CLID_TIME_DELIM] == ',' && data[CLID_NUMB_REC + 1] != ',' &&
 					lines[line].signaled_call_waiting == 0) {
 					pcm_states_dump(__func__, line);
 					// start call waiting
-					res = line_signal_ring(line, get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_INVALID ?
-							PCM_1 : PCM_0, VOICE_SIG_CALLID, data, ubus_req);
+					pcm = get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_INVALID ? PCM_1 : PCM_0;
+					res = line_signal_ring(line, pcm, VOICE_SIG_CALLID, data, ubus_req);
 					lines[line].signaled_call_waiting = 1;
-				} else if(data && (data[0] == '0')) {
+				} else if(data && ((data[0] == '0') || (strcmp(data, "answered") == 0))) {
 					// stop call waiting when accepted but not close the connection on the accepted line
-					res = line_signal_ring(line, get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING ?
-							PCM_1 : PCM_0, VOICE_SIG_CALL_WAITING, data, ubus_req);
+					pcm = get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING ? PCM_1 : PCM_0;
+					res = line_signal_ring(line, pcm, VOICE_SIG_CALL_WAITING, data, ubus_req);
 					lines[line].signaled_call_waiting = 0;
 				}
 			} else {
@@ -346,12 +390,10 @@ int line_signal(int line, const char *signame, const char *data, struct voice_ub
 		case VOICE_SIG_NETBUSY:
 			if (lines[line].type == VOICE_LINE_DECT) {
 				pcm_states_dump(__func__, line);
-				if (get_callid_state(lines[line].pcm_callid[PCM_0])==CALLID_ESTABLISHED && get_callid_state(lines[line].pcm_callid[PCM_1])==CALLID_ESTABLISHED){
+				if (get_callid_state(lines[line].pcm_callid[PCM_0])==CALLID_ESTABLISHED && get_callid_state(lines[line].pcm_callid[PCM_1])==CALLID_ESTABLISHED)
 					send_dect_event_to_asterisk(line, dect_event_map[DECT_EVT_RELEASE]);
-				} else if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_ESTABLISHED || get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_ESTABLISHED){
-				// play tone on DECT
-					res = dect_tone_play(line, get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_ESTABLISHED ? PCM_0 : PCM_1, sig->signal, data, ubus_req);
-				}
+				else
+					res = voice_line_signal(line, -1, sig->signal, atoi(data), NULL);
 			} else {
 				res = voice_line_signal(line, -1, sig->signal, atoi(data), NULL);
 			}
@@ -398,10 +440,14 @@ int line_new_connection_by_asterisk(int line, int connection, struct voice_ubus_
 	ENDPT_DBG("%s line: %d, connection: %d\n", __func__, line, connection);
 	pcm_states_dump(__func__, line);
 
-	if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING)
+	if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING) {
 		lines[line].pcm_callid[PCM_0] = connection;
-	else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING)
+		ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]);
+	}
+	else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING) {
 		lines[line].pcm_callid[PCM_1] = connection;
+		ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]);
+	}
 
 	if (lines[line].type == VOICE_LINE_DECT) {
 		if (voice_line_is_offhook(line) || voice_line_get_connection_count(line) > 0) {
@@ -477,10 +523,12 @@ int line_close_connection_by_asterisk(int line, int connection, struct voice_ubu
 				get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_INVALID) {
 				line_req->pcm_id = PCM_0;
 				lines[line].pcm_callid[PCM_0] = CALLID_INVALID;
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]);
 			} else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_ESTABLISHED &&
 				get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_INVALID) {
 				line_req->pcm_id = PCM_1;
 				lines[line].pcm_callid[PCM_1] = CALLID_INVALID;
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]);
 			}
 			line_req->action = ACTION_CONN_CLOSE;
 			if (connection == -1) {
@@ -495,10 +543,14 @@ int line_close_connection_by_asterisk(int line, int connection, struct voice_ubu
 			break;
 
 		default:
-			if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_ESTABLISHED)
+			if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_ESTABLISHED) {
 				lines[line].pcm_callid[PCM_0] = CALLID_INVALID;
-			else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_ESTABLISHED)
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]);
+			}
+			else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_ESTABLISHED) {
 				lines[line].pcm_callid[PCM_1] = CALLID_INVALID;
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]);
+			}
 
 			return voice_connection_close(line, line);
 	}
@@ -543,9 +595,11 @@ int line_release_connection_by_asterisk(int line, int connection, struct voice_u
 			if (lines[line].pcm_callid[PCM_0] == connection) {
 				line_req->pcm_id = PCM_0;
 				lines[line].pcm_callid[PCM_0] = CALLID_INVALID;
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]);
 			} else if (lines[line].pcm_callid[PCM_1] == connection) {
 				line_req->pcm_id = PCM_1;
 				lines[line].pcm_callid[PCM_1] = CALLID_INVALID;
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]);
 			}
 			line_req->action = ACTION_CONN_CLOSE;
 			memcpy(&line_req->ubus, ubus_req, sizeof(struct voice_ubus_req_t));
@@ -556,10 +610,14 @@ int line_release_connection_by_asterisk(int line, int connection, struct voice_u
 			break;
 
 		default:
-			if (lines[line].pcm_callid[PCM_0] == connection)
+			if (lines[line].pcm_callid[PCM_0] == connection) {
 				lines[line].pcm_callid[PCM_0] = CALLID_INVALID;
-			else if (lines[line].pcm_callid[PCM_1] == connection)
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]);
+			}
+			else if (lines[line].pcm_callid[PCM_1] == connection) {
 				lines[line].pcm_callid[PCM_1] = CALLID_INVALID;
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]);
+			}
 
 			return voice_connection_close(line, line);
 	}
@@ -578,10 +636,14 @@ int line_update_connection_by_pbx(int line, int pcm_callid)
 	if(lines[line].type != VOICE_LINE_DECT)
 		return 0;
 
-	if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING)
+	if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING) {
 		lines[line].pcm_callid[PCM_0] = pcm_callid;
-	else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING)
+		ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]);
+	}
+	else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING) {
 		lines[line].pcm_callid[PCM_1] = pcm_callid;
+		ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]);
+	}
 
 	return 0;
 }
@@ -590,22 +652,29 @@ int line_update_connection_by_pbx(int line, int pcm_callid)
 // Reception of a create connection request from dectmngr.
 // Generate a off-hook event and queue the request
 // until Asterisk acknowledge the offh-ook event.
-int line_new_connection_by_dect(int line, const char *cid, int pcm, struct voice_ubus_req_t *ubus_req)
+int line_new_connection_by_dect(int line, const char *cid, int pcm, const char *data, struct voice_ubus_req_t *ubus_req)
 {
 	struct line_req_t *line_req;
 
 	if (!voice_line_is_ready(line) || lines[line].type != VOICE_LINE_DECT)
 		return -1;
 
-	ENDPT_DBG("line=%d, pcm=%d, cid=%s\n", line, pcm, cid);
+	ENDPT_DBG("line=%d, pcm=%d, cid=%s, data=%s\n", line, pcm, cid, data ? data : "<null>");
 	pcm_states_dump(__func__, line);
 
-	if (pcm == PCM_0 || pcm == PCM_1) {
+	if (is_valid_pcm_id(pcm)) {
 		lines[line].pcm_callid[pcm] = CALLID_OBTAINING;
+		ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, pcm, lines[line].pcm_callid[pcm]);
 		lines[line].signaled_call_waiting = 0;
 	}
 
 	if (!voice_line_is_offhook(line)) {
+		if (data && strcmp(data, EVENT_DATA_NARROW_BAND_ONLY) == 0) {
+			lines[line].flags |= VOICEMNGR_LINE_FLAG_NARROW_BAND_ONLY;
+			ENDPT_DBG("The DECT handset which goes off hook supports narrow band only\n");
+		} else {
+			lines[line].flags &= ~VOICEMNGR_LINE_FLAG_NARROW_BAND_ONLY;
+		}
 		if (voice_line_simulate_hook(line, VOICE_EVT_OFFHOOK))
 			return -1;
 	} else {
@@ -672,7 +741,7 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub
 		msg = malloc(sizeof(struct line_event_t));
 		if (msg) {
 			msg->name = "DECT_UNAVAILABLE";
-			msg->data = 0;
+			msg->data = NULL;
 			msg->line = line;
 			send_event_main(msg, EVENT_MAIN_LINE);
 		}
@@ -691,7 +760,7 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub
 			msg = malloc(sizeof(struct line_event_t));
 			if (msg) {
 				msg->name = "CALL_REJECT";
-				msg->data = 0;
+				msg->data = NULL;
 				msg->line = line;
 				send_event_main(msg, EVENT_MAIN_LINE);
 			}
@@ -707,8 +776,10 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub
 		get_callid_state(lines[line].pcm_callid[PCM_1]) <= CALLID_OBTAINING) {
 		if(pcm == CALL_DEFAULT0 || pcm == CALL_DEFAULT1) {
 			lines[line].pcm_callid[pcm] = CALLID_INVALID;
+			ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, pcm, lines[line].pcm_callid[pcm]);
 			if (get_callid_state(lines[line].pcm_callid[1-pcm]) == CALLID_OBTAINING) {
 				lines[line].pcm_callid[1-pcm] = CALLID_INVALID;
+				ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, 1-pcm, lines[line].pcm_callid[1-pcm]);
 			}
 		}
 		voice_line_simulate_hook(line, VOICE_EVT_ONHOOK);
@@ -716,8 +787,10 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub
 			pcm, UBUS_STATUS_OK);
 	}
 
-	if(pcm == CALL_DEFAULT0 || pcm == CALL_DEFAULT1)
+	if(pcm == CALL_DEFAULT0 || pcm == CALL_DEFAULT1) {
 		lines[line].pcm_callid[pcm] = CALLID_INVALID;
+		ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, pcm, lines[line].pcm_callid[pcm]);
+	}
 
 	if(send_dect_event_to_asterisk(line, dect_event_map[DECT_EVT_RELEASE]))
 		return -1;
@@ -739,3 +812,28 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub
 
 	return 0;
 }
+
+//---------------------------------------------------------------
+// Return the paging status in string from the value of lines[line].paging_status
+char *voice_line_get_paging_status(int line)
+{
+	if (line < 0 || line >= terminal_info.num_voice_ports) {
+		ENDPT_DBG("Line number %d is out of range\n", line);
+		return "Idle";
+	}
+
+	switch(lines[line].paging_status)
+	{
+		case PAGING_IN_PROGRESS:
+			return "InProgress";
+		case PAGING_SUCCESS:
+			return "Success";
+		case PAGING_NOT_IN_REACH:
+			return "Error_Not_In_Reach";
+		case PAGING_TIMEOUT:
+			return "Error_TimeOut";
+		case PAGING_IDLE:
+		default:
+			return "Idle";
+	}
+}
diff --git a/line.h b/line.h
index 64a212d4d744c8d305d47477a5a01c7b00436484..850fc9229ef12a58e3ebc43438a36aec58545438 100644
--- a/line.h
+++ b/line.h
@@ -19,9 +19,9 @@ enum line_action_t {
 
 // Event sent with UBUS when something has happened with a phone line
 struct line_event_t {
-	const char *name; // String communicated with Asterisk
-	int data;         // True/false is a DTMF button is pressed/depressed
-	int line;         // Line number
+	const char *name;  // String communicated with Asterisk
+	const char *data;  // Event specific data
+	int line;          // Line number
 };
 
 // Deferred UBUS request
@@ -36,12 +36,14 @@ struct voice_ubus_req_t {
 struct line_req_t {
 	int line;
 	int pcm_id;
-	int connection_id;                 // Connection ID from Asterisk
-	enum line_action_t action;         // The requested action from origin
-	char caller_id[MAX_CALLER_ID_LEN]; // Caller ID
-	char caller_name[MAX_CALLER_NAME]; // Caller Name
+	int connection_id;                 	// Connection ID from Asterisk
+	enum line_action_t action;         	// The requested action from origin
+	char caller_id[CLID_MAX_NUMBER]; 	// Caller ID
+	char caller_name[CLID_MAX_NAME]; 	// Caller Name
+	int sip_client_id;              	// sip client id
 	struct voice_ubus_req_t ubus;
 	struct timespec time_stamp;
+	enum hangup_cause hangupcause;
 };
 
 struct dectmngr_rpc_t {
@@ -50,6 +52,7 @@ struct dectmngr_rpc_t {
 	int  pcm_id;
 	union {
 		// Action specific parameters will be added here
+		enum hangup_cause hangupcause;
 	} params;
 };
 
@@ -58,11 +61,13 @@ int line_new_connection_by_asterisk(int line, int connection, struct voice_ubus_
 int line_close_connection_by_asterisk(int line, int connection, struct voice_ubus_req_t *ubus_req);
 int line_release_connection_by_asterisk(int line, int connection, struct voice_ubus_req_t *ubus_req);
 int line_update_connection_by_pbx(int line, int pcm_callid);
-int line_new_connection_by_dect(int line, const char *cid, int pcm, struct voice_ubus_req_t *ubus_req);
+int line_new_connection_by_dect(int line, const char *cid, int pcm, const char *data, struct voice_ubus_req_t *ubus_req);
 int line_connection_parm_update_by_asterisk(int line, int connection, struct config_update_struct *data);
 int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ubus_req);
 int line_signal(int line, const char *signame, const char *data, struct voice_ubus_req_t *ubus_req);
 void pcm_states_dump(const char* func, int line);
 callid_state get_callid_state(int call_id);
+bool is_valid_pcm_id(int id);
+char *voice_line_get_paging_status(int line);
 
 #endif
diff --git a/main.c b/main.c
index 8635d7eeecba65bc3351bc0a127fd620f0dbde92..dd970087f233a8e1b1012328c05fc38e1a134621 100644
--- a/main.c
+++ b/main.c
@@ -19,6 +19,10 @@
 #include "main.h"
 #include "ubus.h"
 
+#ifdef INCLUDE_BREAKPAD
+#include "breakpad_wrapper.h"
+#endif
+
 #ifndef UCI_CONFIG_DIR
 #define UCI_CONFIG_DIR "/etc/config/"
 #endif
@@ -91,7 +95,7 @@ static void event_stream_handler(pe_stream_t *stream __attribute__((unused)), pe
 		case EVENT_MAIN_LINE:
 			ev = (struct line_event_t*) pe_list_get(event_list);
 			if(!ev) break;
-			ENDPT_DBG("Main event handler line %d event %s\n", ev->line, ev->name);
+			ENDPT_DBG("Main event handler line %d event %s data %s\n", ev->line, ev->name, ev->data ? ev->data : "<null>");
 			ubus_call_asterisk(ev);
 			ubus_broadcast_event(ev); // Also broadcast event to all
 			break;
@@ -172,6 +176,9 @@ static int signals_init(void) {
 	struct sigaction action;
 	unsigned int i;
 
+#ifdef INCLUDE_BREAKPAD
+	breakpad_ExceptionHandler();
+#endif
 	memset(&action, 0, sizeof(action));
 	action.sa_sigaction = signal_handler;
 	action.sa_flags = SA_SIGINFO | SA_RESTART;
@@ -191,7 +198,7 @@ static int signals_init(void) {
 	return 0;
 }
 
-static void voicemngr_event_report(int line, const char *event, int data) {
+static void voicemngr_event_report(int line, const char *event, const char *data) {
 	/* Re-send the event to the main thread, which in turn re-send
 	 * to Asterisk. We need to do this due to UBUS is not thread safe,
 	 * so all UBUS calls must be done from a single thread. */
@@ -203,8 +210,9 @@ static void voicemngr_event_report(int line, const char *event, int data) {
 			return;
 		}
 		msg->name = event;
-		msg->data = (data < 0 ? 0 : data); // Discard negative values
+		msg->data = data;
 		msg->line = line;
+		ENDPT_ERR("%s: event: %s, data: %s, line: %d\n", __func__, msg->name ? msg->name : "null", msg->data ? msg->data : "null", msg->line);
 		send_event_main(msg, EVENT_MAIN_LINE);
 	}
 }
diff --git a/ubus.c b/ubus.c
index ce4f3cf3e5723a73e8cb2bda53745f66458f0d1e..ab5a77df37b1bb9f764a92ed63658f8c08479c37 100644
--- a/ubus.c
+++ b/ubus.c
@@ -78,7 +78,9 @@ enum {
 	DECT_REL,						// Release call using PCMx
 	DECT_CID,						// Caller ID
 	DECT_CALLER_NAME,				// Caller Name
+	DECT_SIP_CLIENT_ID,
 	DECT_PCM_ID,					// PCM ID
+	DECT_DATA,						// Extra parameter which is request (call creation, release, and etc.) specific
 };
 
 // Keeping track of sent but not yet answered UBUS requests, for timeout.
@@ -136,7 +138,7 @@ static const char broadcast_path[] = "voice.endpoint";			// UBUS path name for b
 static const char uciStrComSect[] = "tel_options";				// Common endpoint section name
 static const char uciStrLineSect[] = "extension";				// Line specific section name
 static const char uciStrCountry[] = "country";					// Endpoint country
-static const char uciStrLoglevel[] = "vmloglevel";			// syslog level of voicemngr
+static const char uciStrLoglevel[] = "vmloglevel";				// syslog level of voicemngr
 static const char ubusStrObjAdd[] = "ubus.object.add";			// UBUS objects added to global context
 static const char ubusStrObjRm[] = "ubus.object.remove";		// UBUS objects added removed from global context
 
@@ -182,7 +184,9 @@ static const struct blobmsg_policy request_call_policy[] = {
 	[DECT_REL] = { .name = "release", .type = BLOBMSG_TYPE_INT32 },
 	[DECT_CID] = { .name = "cid", .type = BLOBMSG_TYPE_STRING },
 	[DECT_CALLER_NAME] = { .name = "caller_name", .type = BLOBMSG_TYPE_STRING },
+	[DECT_SIP_CLIENT_ID] =  { .name = "sip_client_id",      .type = BLOBMSG_TYPE_INT32 },
 	[DECT_PCM_ID] = { .name = "pcm_id", .type = BLOBMSG_TYPE_INT32 },
+	[DECT_DATA] = { .name = "data", .type = BLOBMSG_TYPE_STRING },
 };
 
 // Our ubus RPC methods
@@ -568,22 +572,24 @@ static int ubus_request_signal(struct ubus_context *uctx, struct ubus_object *ob
 	}
 
 	signame = blobmsg_get_string(keys[SIGNAL_TYPE]);
-	ENDPT_DBG("line=%d, signame=%s\n", line, signame);
 
 	// on or off signal?
 	enable = "0";
-	data = NULL;
 	state = blobmsg_get_string(keys[SIGNAL_STATE]);
 	if (strcmp(state, "on") == 0) {
 		enable = "1";
-		// Do we have extra data that should be passed to endpoint?
-		if (keys[SIGNAL_DATA])
-			data = blobmsg_get_string(keys[SIGNAL_DATA]);
 	} else if (strcmp(state, "off")) {
 		ENDPT_ERR("Error! invalid state %s\n", state);
 		return UBUS_STATUS_INVALID_ARGUMENT;
 	}
 
+	// Do we have extra data that should be passed to endpoint?
+	if (keys[SIGNAL_DATA])
+		data = blobmsg_get_string(keys[SIGNAL_DATA]);
+	else
+		data = NULL;
+
+	ENDPT_DBG("line=%d, signame=%s, state=%s, data=%s\n", line, signame, state, data?data:"");
 	// Prepare for possibly deferring the request
 	memset(&ubusReq, 0, sizeof(struct voice_ubus_req_t));
 	clock_gettime(CLOCK_MONOTONIC, &ubusReq.timeStamp);
@@ -727,6 +733,7 @@ static int ubus_request_status(struct ubus_context *uctx, struct ubus_object *ob
 		if (line >= 0 && line < totEndpoints) {
 			blobmsg_add_u32(&blob, "line", line);
 			blobmsg_add_u32(&blob, "offhook", voice_line_is_offhook(line + unpopulatedDectEndpoints));
+			blobmsg_add_string(&blob, "paging_status", voice_line_get_paging_status(line));
 			res = UBUS_STATUS_OK;
 		} else {
 			ENDPT_ERR("Error! No such line value: %d\n", line);
@@ -739,10 +746,9 @@ static int ubus_request_status(struct ubus_context *uctx, struct ubus_object *ob
 		for(line = 0; line < totEndpoints; line++) {
 			void  *tbl;
 			tbl = blobmsg_open_table(&blob, NULL);
-
 			blobmsg_add_u32(&blob, "line", line);
 			blobmsg_add_u32(&blob, "offhook", voice_line_is_offhook(line + unpopulatedDectEndpoints));
-
+			blobmsg_add_string(&blob, "paging_status", voice_line_get_paging_status(line));
 			blobmsg_close_table(&blob, tbl);
 		}
 
@@ -889,15 +895,9 @@ static int ubus_request_call(struct ubus_context *uctx, struct ubus_object *obj
 		struct blob_attr *msg)
 {
 	struct blob_attr *keys[ARRAY_SIZE(request_call_policy)];
-	int termId, pcmId, add, release;
+	int termId = -1, pcmId = -1, add = 0, release = 0;
 	struct voice_ubus_req_t ubusReq;
-	const char *cid;
-
-	termId = -1;
-	pcmId = -1;
-	add = 0;
-	release = 0;
-	cid = NULL;
+	const char *cid = NULL, *data = NULL;
 
 	// Tokenize message key/value paris into an array
 	if(blobmsg_parse(request_call_policy, ARRAY_SIZE(request_call_policy),
@@ -927,7 +927,12 @@ static int ubus_request_call(struct ubus_context *uctx, struct ubus_object *obj
 
 	if(keys[DECT_PCM_ID]) {
 		pcmId = blobmsg_get_u32(keys[DECT_PCM_ID]);
-		ENDPT_DBG("pcmId %d\n", pcmId);
+		ENDPT_DBG("call pcmId %d\n", pcmId);
+	}
+
+	if(keys[DECT_DATA]) {
+		data = blobmsg_get_string(keys[DECT_DATA]);
+		ENDPT_DBG("call data %s\n", data);
 	}
 
 	if((pcmId & 0xFFFF) < CALL_DEFAULT0 || (pcmId & 0xFFFF) >= CALL_LAST) {
@@ -947,7 +952,7 @@ static int ubus_request_call(struct ubus_context *uctx, struct ubus_object *obj
 			return UBUS_STATUS_UNKNOWN_ERROR;
 		}
 	} else if(add && termId >= 0) {
-		if(line_new_connection_by_dect(dectmngr_line_to_voicemngr_line(termId), cid, pcmId, &ubusReq)) {
+		if (line_new_connection_by_dect(dectmngr_line_to_voicemngr_line(termId), cid, pcmId, data, &ubusReq)) {
 			send_reply_dectmngr(&ubusReq, termId, pcmId, UBUS_STATUS_UNKNOWN_ERROR);
 			return UBUS_STATUS_UNKNOWN_ERROR;
 		}
@@ -960,7 +965,7 @@ static int ubus_request_call(struct ubus_context *uctx, struct ubus_object *obj
 		struct line_event_t *ast_msg = malloc(sizeof(struct line_event_t));
 		if (ast_msg) {
 			ast_msg->name = pcmId == CALL_MODE_MULTIPLE ? "LINE_CALL_MODE_MULTIPLE" : "LINE_CALL_MODE_SINGLE";
-			ast_msg->data = 0;
+			ast_msg->data = NULL;
 			ast_msg->line = dectmngr_line_to_voicemngr_line(termId);
 			send_event_main(ast_msg, EVENT_MAIN_LINE);
 		}
@@ -999,7 +1004,7 @@ int ubus_call_asterisk(const struct line_event_t* const ev)
 	struct blob_buf bb;
 	int res;
 
-	ENDPT_DBG("ubus call to asterisk, line:%d, event:%s, data:%d\n", ev->line, ev->name, ev->data);
+	ENDPT_DBG("ubus call to asterisk, line:%d, event:%s, data:%s\n", ev->line, ev->name, ev->data ? ev->data : "<null>");
 
 	// Do we know ubus address of Asterisk?
 	if (!asterisk_id) {
@@ -1010,7 +1015,8 @@ int ubus_call_asterisk(const struct line_event_t* const ev)
 	memset(&bb, 0, sizeof(bb));
 	if (blob_buf_init(&bb, 0)) return -1;
 	blobmsg_add_string(&bb, "event", ev->name);
-	blobmsg_add_u32(&bb, "data", ev->data);
+	if (ev->data && *ev->data)
+		blobmsg_add_string(&bb, "data", ev->data);
 	blobmsg_add_u32(&bb, "line", ev->line);
 
 	req = calloc(1, sizeof(struct ubus_request));
@@ -1045,10 +1051,6 @@ int ubus_broadcast_event(const struct line_event_t* const ev)
 	struct blob_buf blob;
 	int res = 0;
 
-	// Filter out repeated DTMF events
-	if (strncasecmp(ev->name, "DTMF", strlen("DTMF")) == 0 && ev->data == 1)
-		return 0;
-
 	memset(&blob, 0, sizeof(blob));
 	if(blob_buf_init(&blob, 0))
 		return -1;
@@ -1129,7 +1131,8 @@ static void got_dectmngr_complete(struct ubus_request *req, int ret __attribute_
 
 // Send a request to dectmngr by "ubus call dect call". Don't wait for completion. Instead, when the invocation
 // finishes, we get "called back".
-int ubus_call_dectmngr(int terminal, int add, int release, const char *cid, const char *caller_name, int pcmId, struct line_req_t *lineReq)
+int ubus_call_dectmngr(int terminal, int add, int release, const char *cid, const char *caller_name, int sip_client_id,
+		int pcmId, struct line_req_t *lineReq)
 {
 	struct ubus_request *req;
 	struct blob_buf bb;
@@ -1151,10 +1154,14 @@ int ubus_call_dectmngr(int terminal, int add, int release, const char *cid, cons
 		blobmsg_add_u32(&bb, request_call_policy[DECT_REL].name, release);
 	if(cid && *cid)
 		blobmsg_add_string(&bb, request_call_policy[DECT_CID].name, cid);
-	if(caller_name && *caller_name) blobmsg_add_string(&bb, request_call_policy[DECT_CALLER_NAME].name, caller_name);
+	if(caller_name && *caller_name)
+		blobmsg_add_string(&bb, request_call_policy[DECT_CALLER_NAME].name, caller_name);
+	if(sip_client_id >= 0)
+		blobmsg_add_u32(&bb, request_call_policy[DECT_SIP_CLIENT_ID].name, sip_client_id);
+
 	blobmsg_add_u32(&bb, request_call_policy[DECT_PCM_ID].name, pcmId);
 
-	ENDPT_DBG("Sending ubus request to dectmngr %d %d %d %s %s %d\n", terminal, add, release, cid, caller_name, pcmId);
+	ENDPT_DBG("Sending ubus request to dectmngr %d %d %d %s %s %d %d\n", terminal, add, release, cid, caller_name, sip_client_id, pcmId);
 
 	req = calloc(1, sizeof(struct ubus_request));
 	if (!req) {
@@ -1205,9 +1212,11 @@ int ubus_dectmngr_rpc(const struct dectmngr_rpc_t *dectmngr_rpc, const struct li
 	switch (dectmngr_rpc->action) {
 	case ACTION_RINGING_STOP:
 		blobmsg_add_u32(&bb, DECTMNGR_RPC_PARAM_EXTENSION_ID, dectmngr_rpc->extension_id);
+		blobmsg_add_u32(&bb, DECTMNGR_RPC_PARAM_HANGUPCAUSE, dectmngr_rpc->params.hangupcause);
 		res = ubus_invoke_async(ctx, dectmngr_rpc_id, DECTMNGR_RPC_RINGING_STOP, bb.head, req);
 		ENDPT_DBG("Invoke ubus call %s %s {'%s':%d}\n", DECTMNGR_RPC_UBUS_OBJECT, DECTMNGR_RPC_RINGING_STOP,
-				DECTMNGR_RPC_PARAM_EXTENSION_ID, dectmngr_rpc->extension_id);
+				DECTMNGR_RPC_PARAM_EXTENSION_ID, dectmngr_rpc->extension_id,
+				DECTMNGR_RPC_PARAM_HANGUPCAUSE, dectmngr_rpc->params.hangupcause);
 		break;
 
 	case ACTION_CONN_CLOSE:
diff --git a/ubus.h b/ubus.h
index 145a2ea364e9eae4054b89a430a55611125834bf..0f84b10f2a611a0760ae91fde51bb63bdeeea09f 100644
--- a/ubus.h
+++ b/ubus.h
@@ -15,7 +15,8 @@ int ubus_call_asterisk(const struct line_event_t* const ev);
 int ubus_broadcast_event(const struct line_event_t* const ev);
 int send_reply_asterisk(struct voice_ubus_req_t *req, enum ubus_msg_status ubusRet);
 int send_reply_dectmngr(struct voice_ubus_req_t *req, int terminal, int pcmId, enum ubus_msg_status ubusRet);
-int ubus_call_dectmngr(int terminal, int add, int release, const char *cid, const char *caller_name, int pcmId, struct line_req_t *lineReq);
+int ubus_call_dectmngr(int terminal, int add, int release, const char *cid, const char *caller_name, int sip_client_id,
+		int pcmId, struct line_req_t *lineReq);
 int ubus_dectmngr_rpc(const struct dectmngr_rpc_t *dectmngr_rpc, const struct line_req_t *line_req);
 int config_init(struct uci_context *context, struct uci_package *package);
 void config_syslog(struct uci_context *context, struct uci_package *package);