diff --git a/Makefile b/Makefile
index eed819c01426f0766c06fd8dbcc84ed1f931f0a1..0e6a2432c9e82a4fec042303f262b7c1c3600523 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ CFLAGS += -I./ -Ilibvoice/
 
 
 OBJS := $(SRCS:.c=.o)
-LIBS += -lubox -lubus -lpthread -lpicoevent -luci -L./libvoice -lvoice
+LIBS += -lubox -lubus -lpthread -lpicoevent -luci -L./libvoice -lvoice -lblobmsg_json
 
 all: debug $(VOICEMNGR)
 
diff --git a/docs/api/endpt.md b/docs/api/endpt.md
old mode 100755
new mode 100644
index dbab2cc093c5c3d97257e60334ea5adfe367c562..468c64d10cb22dfff0866861ff00c6e3b3d3f44e
--- a/docs/api/endpt.md
+++ b/docs/api/endpt.md
@@ -1,7 +1,7 @@
 # endpt Schema
 
 ```
-https://www.iopsys.eu/asterisk.json
+https://www.iopsys.eu/endpt.json
 ```
 
 | Custom Properties | Additional Properties |
@@ -13,6 +13,7 @@ https://www.iopsys.eu/asterisk.json
 | List of Methods           |
 | ------------------------- |
 | [call](#call)             | Method | endpt (this schema) |
+| [codecs](#codecs)         | Method | endpt (this schema) |
 | [connection](#connection) | Method | endpt (this schema) |
 | [count](#count)           | Method | endpt (this schema) |
 | [rtp_stats](#rtp_stats)   | Method | endpt (this schema) |
@@ -53,6 +54,7 @@ https://www.iopsys.eu/asterisk.json
 | ---------- | ------- | ------------ |
 | `add`      | integer | **Required** |
 | `cid`      | string  | Optional     |
+| `pcm_id`   | integer | **Required** |
 | `terminal` | integer | **Required** |
 
 #### add
@@ -87,6 +89,20 @@ https://www.iopsys.eu/asterisk.json
 ^[0-9]*#
 ```
 
+#### pcm_id
+
+`pcm_id`
+
+- is **required**
+- type: `integer`
+
+##### pcm_id Type
+
+`integer`
+
+- minimum value: `0`
+- maximum value: `5`
+
 #### terminal
 
 `terminal`
@@ -108,6 +124,7 @@ https://www.iopsys.eu/asterisk.json
 | Property   | Type    | Required     |
 | ---------- | ------- | ------------ |
 | `cid`      | string  | Optional     |
+| `pcm_id`   | integer | **Required** |
 | `release`  | integer | **Required** |
 | `terminal` | integer | **Required** |
 
@@ -129,6 +146,20 @@ https://www.iopsys.eu/asterisk.json
 ^[0-9]*#
 ```
 
+#### pcm_id
+
+`pcm_id`
+
+- is **required**
+- type: `integer`
+
+##### pcm_id Type
+
+`integer`
+
+- minimum value: `0`
+- maximum value: `5`
+
 #### release
 
 `release`
@@ -160,7 +191,7 @@ https://www.iopsys.eu/asterisk.json
 ### Ubus CLI Example
 
 ```
-ubus call endpt call {"terminal":4,"release":1,"cid":"329337#"}
+ubus call endpt call {"terminal":6,"add":1,"pcm_id":0,"cid":"018#"}
 ```
 
 ### JSONRPC Example
@@ -170,7 +201,7 @@ ubus call endpt call {"terminal":4,"release":1,"cid":"329337#"}
   "jsonrpc": "2.0",
   "id": 0,
   "method": "call",
-  "params": ["<SID>", "endpt", "call", { "terminal": 4, "release": 1, "cid": "329337#" }]
+  "params": ["<SID>", "endpt", "call", { "terminal": 6, "add": 1, "pcm_id": 0, "cid": "018#" }]
 }
 ```
 
@@ -227,7 +258,200 @@ ubus call endpt call {"terminal":4,"release":1,"cid":"329337#"}
 ### Output Example
 
 ```json
-{ "terminal": 95818467, "pcm": -54557753, "errno": 49583331 }
+{ "terminal": 73262276, "pcm": -31145049, "errno": -61339135 }
+```
+
+## codecs
+
+`codecs`
+
+- type: `Method`
+
+### codecs Type
+
+`object` with following properties:
+
+| Property | Type   | Required     |
+| -------- | ------ | ------------ |
+| `input`  | object | Optional     |
+| `output` | object | **Required** |
+
+#### input
+
+`input`
+
+- is optional
+- type: `object`
+
+##### input Type
+
+`object` with following properties:
+
+| Property | Type | Required |
+| -------- | ---- | -------- |
+| None     | None | None     |
+
+### Ubus CLI Example
+
+```
+ubus call endpt codecs {}
+```
+
+### JSONRPC Example
+
+```json
+{ "jsonrpc": "2.0", "id": 0, "method": "call", "params": ["<SID>", "endpt", "codecs", {}] }
+```
+
+#### output
+
+`output`
+
+- is **Required**
+- type: `object`
+
+##### output Type
+
+`object` with following properties:
+
+| Property    | Type   | Required     |
+| ----------- | ------ | ------------ |
+| `codec_key` | object | **Required** |
+
+#### codec_key
+
+`codec_key`
+
+- is **Required**
+- type: `object`
+
+##### codec_key Type
+
+`object` with following properties:
+
+| Property          | Type    | Required     |
+| ----------------- | ------- | ------------ |
+| `bitrate`         | number  | **Required** |
+| `name`            | string  | **Required** |
+| `ptime_default`   | integer | **Required** |
+| `ptime_increment` | integer | **Required** |
+| `ptime_max`       | integer | **Required** |
+| `ptime_min`       | integer | **Required** |
+
+#### bitrate
+
+`bitrate`
+
+- is **required**
+- type: `number`
+
+##### bitrate Type
+
+`number`
+
+- minimum value: `0`
+- maximum value: `100`
+
+#### name
+
+`name`
+
+- is **required**
+- type: `enum`
+
+##### name Type
+
+`string`
+
+The value of this property **must** be equal to one of the [known values below](#codecs-known-values).
+
+##### name Known Values
+
+| Value      |
+| ---------- |
+| G.711MuLaw |
+| G.711ALaw  |
+| G.729a     |
+| G.723.1    |
+| G.726      |
+| G.728      |
+| G.729      |
+| G.729e     |
+| GSM-FR     |
+| GSM-EFR    |
+| GSM-HR     |
+| GSM-AMR    |
+| iLBC       |
+
+#### ptime_default
+
+`ptime_default`
+
+- is **required**
+- type: `integer`
+
+##### ptime_default Type
+
+`integer`
+
+- minimum value: `0`
+- maximum value: `50`
+
+#### ptime_increment
+
+`ptime_increment`
+
+- is **required**
+- type: `integer`
+
+##### ptime_increment Type
+
+`integer`
+
+- minimum value: `0`
+- maximum value: `50`
+
+#### ptime_max
+
+`ptime_max`
+
+- is **required**
+- type: `integer`
+
+##### ptime_max Type
+
+`integer`
+
+- minimum value: `0`
+- maximum value: `300`
+
+#### ptime_min
+
+`ptime_min`
+
+- is **required**
+- type: `integer`
+
+##### ptime_min Type
+
+`integer`
+
+- minimum value: `0`
+- maximum value: `50`
+
+### Output Example
+
+```json
+{
+  "codec_key": {
+    "name": "G.729e",
+    "ptime_min": 44,
+    "ptime_max": 36,
+    "ptime_default": 12,
+    "ptime_increment": 38,
+    "bitrate": 12.60194806517081
+  }
+}
 ```
 
 ## connection
@@ -314,7 +538,7 @@ The value of this property **must** be equal to one of the [known values below](
 ### Ubus CLI Example
 
 ```
-ubus call endpt connection {"line":1,"id":80045812,"action":"stop_conference"}
+ubus call endpt connection {"line":3,"id":4989534,"action":"start_conference"}
 ```
 
 ### JSONRPC Example
@@ -324,7 +548,7 @@ ubus call endpt connection {"line":1,"id":80045812,"action":"stop_conference"}
   "jsonrpc": "2.0",
   "id": 0,
   "method": "call",
-  "params": ["<SID>", "endpt", "connection", { "line": 1, "id": 80045812, "action": "stop_conference" }]
+  "params": ["<SID>", "endpt", "connection", { "line": 3, "id": 4989534, "action": "start_conference" }]
 }
 ```
 
@@ -476,10 +700,10 @@ ubus call endpt count {"effective":true}
 
 ```json
 {
-  "num_endpoints": 33328553,
-  "num_fxo_endpoints": 50973699,
-  "num_fxs_endpoints": 25375525,
-  "num_dect_endpoints": 17497288
+  "num_endpoints": 28959373,
+  "num_fxo_endpoints": 16921710,
+  "num_fxs_endpoints": 5497405,
+  "num_dect_endpoints": 2393708
 }
 ```
 
@@ -542,7 +766,7 @@ ubus call endpt count {"effective":true}
 ### Ubus CLI Example
 
 ```
-ubus call endpt rtp_stats {"line":1,"reset":false}
+ubus call endpt rtp_stats {"line":0,"reset":true}
 ```
 
 ### JSONRPC Example
@@ -552,7 +776,7 @@ ubus call endpt rtp_stats {"line":1,"reset":false}
   "jsonrpc": "2.0",
   "id": 0,
   "method": "call",
-  "params": ["<SID>", "endpt", "rtp_stats", { "line": 1, "reset": false }]
+  "params": ["<SID>", "endpt", "rtp_stats", { "line": 0, "reset": true }]
 }
 ```
 
@@ -939,32 +1163,32 @@ ubus call endpt rtp_stats {"line":1,"reset":false}
 
 ```json
 {
-  "lineId": 0,
-  "localBurstDensity": 55283780,
-  "remoteBurstDensity": 62068585,
-  "localBurstDuration": 94260800,
-  "remoteBurstDuration": 99693375,
-  "localGapDensity": 71402386,
-  "remoteGapDensity": 47162230,
-  "localGapDuration": 7583318,
-  "remoteGapDuration": 6863264,
-  "localJbRate": 87945882,
-  "remoteJbRate": 14582824,
-  "localJbMax": 22999542,
-  "remoteJbMax": 29034128,
-  "localJbNominal": 15578543,
-  "remoteJbNominal": 31528270,
-  "localJbAbsMax": 9399794,
-  "remoteJbAbsMax": 29508034,
-  "discarded": 54075545,
-  "lost": 70983167,
-  "rxpkts": 17096099,
-  "txpkts": 59756075,
-  "jbAvg": 97568226,
-  "jitter": 56764254,
-  "uLossRate": 11873018,
-  "maxJitter": 95833762,
-  "averageRoundTripDelay": 82416645
+  "lineId": 3,
+  "localBurstDensity": 72187314,
+  "remoteBurstDensity": 57272242,
+  "localBurstDuration": 550512,
+  "remoteBurstDuration": 9577445,
+  "localGapDensity": 31746248,
+  "remoteGapDensity": 5373655,
+  "localGapDuration": 93046060,
+  "remoteGapDuration": 6028757,
+  "localJbRate": 48187376,
+  "remoteJbRate": 42684338,
+  "localJbMax": 4617104,
+  "remoteJbMax": 68868842,
+  "localJbNominal": 97005535,
+  "remoteJbNominal": 37554392,
+  "localJbAbsMax": 15660701,
+  "remoteJbAbsMax": 15370482,
+  "discarded": 38026287,
+  "lost": 73256347,
+  "rxpkts": 77415865,
+  "txpkts": 30316611,
+  "jbAvg": 16648797,
+  "jitter": 12286104,
+  "uLossRate": 44899753,
+  "maxJitter": 68636630,
+  "averageRoundTripDelay": 25815554
 }
 ```
 
@@ -1090,7 +1314,7 @@ The value of this property **must** be equal to one of the [known values below](
 ### Ubus CLI Example
 
 ```
-ubus call endpt signal {"line":2,"signal":"dtmf8","state":"on","data":"exercitation do voluptate ut Ut"}
+ubus call endpt signal {"line":0,"signal":"busy","state":"on","data":"dolor"}
 ```
 
 ### JSONRPC Example
@@ -1100,12 +1324,7 @@ ubus call endpt signal {"line":2,"signal":"dtmf8","state":"on","data":"exercitat
   "jsonrpc": "2.0",
   "id": 0,
   "method": "call",
-  "params": [
-    "<SID>",
-    "endpt",
-    "signal",
-    { "line": 2, "signal": "dtmf8", "state": "on", "data": "exercitation do voluptate ut Ut" }
-  ]
+  "params": ["<SID>", "endpt", "signal", { "line": 0, "signal": "busy", "state": "on", "data": "dolor" }]
 }
 ```
 
@@ -1177,13 +1396,13 @@ ubus call endpt signal {"line":2,"signal":"dtmf8","state":"on","data":"exercitat
 ### Ubus CLI Example
 
 ```
-ubus call endpt status {"line":4}
+ubus call endpt status {"line":1}
 ```
 
 ### JSONRPC Example
 
 ```json
-{ "jsonrpc": "2.0", "id": 0, "method": "call", "params": ["<SID>", "endpt", "status", { "line": 4 }] }
+{ "jsonrpc": "2.0", "id": 0, "method": "call", "params": ["<SID>", "endpt", "status", { "line": 1 }] }
 ```
 
 #### output
@@ -1239,5 +1458,5 @@ The value of this property **must** be equal to one of the [known values below](
 ### Output Example
 
 ```json
-{ "line": 3, "offhook": 0 }
+{ "line": 3, "offhook": 1 }
 ```
diff --git a/docs/functionspec.md b/docs/functionspec.md
index a8a992aa9c8b7beed1e7191ad6eb8631b5b6026f..0fb26b05e52e3c4581f670a408a7ff579e243b2b 100644
--- a/docs/functionspec.md
+++ b/docs/functionspec.md
@@ -8,8 +8,9 @@
 	"signal":{"line":"Integer","signal":"String","state":"String","data":"String"}
 	"connection":{"line":"Integer","id":"Integer","action":"String"}
 	"status":{"line":"Integer"}
-	"call":{"terminal":"Integer","add":"Integer","release":"Integer","cid":"String"}
-	"rtp_stats":{"line":"Integer","reset":"Boolean"}```
+	"call":{"terminal":"Integer","add":"Integer","release":"Integer","cid":"String","pcm_id":"Integer"}
+	"rtp_stats":{"line":"Integer","reset":"Boolean"}
+	"codecs":{}
 ```
 
 # Contents
@@ -27,8 +28,9 @@
 | [signal](#signal)         | Start/stop call progress tone or signals on a terminal, e.g. dial tone, ring signal, and etc. This is called by asterisk. |
 | [connection](#connection) | Create/destroy a connection for a terminal. This is called by asterisk. |
 | [status](#status)         | Get the hook status of a terminal. This is called by asterisk. |
-| [call](#call)             | Establish/release a call on a terminal. This is called both by asterisk and by dectmngr. |
+| [call](#call)             | Establish/release a call on a terminal. This is called by dectmngr. |
 | [rtp_stats](#rtp_stats)   | Get the RTP statistics of a terminal. This is called by asterisk. |
+| [codecs](#codecs)   | Get the hardware specific codec capability. This is called by "voice.asterisk codecs". |
 
 
 #### Methods
@@ -58,3 +60,7 @@ Methods descriptions of the `endpt` object.
 ##### rtp_stats
 
 [rtp_stats documentation](./api/endpt.md#rtp_stats)
+
+##### codecs
+
+[codecs documentation](./api/endpt.md#codecs)
diff --git a/libvoice/common.c b/libvoice/common.c
index acd1ab72c0947e03671e3a85b77392d7df2fd779..32fa3df81a85d7381e17b80cf306682ca5d37078 100644
--- a/libvoice/common.c
+++ b/libvoice/common.c
@@ -72,6 +72,7 @@ const struct voice_signal_t signal_map[] = { // List of signals requested by Ast
 	{ .name = "dtmfC",          .signal = VOICE_SIG_DTMFC },
 	{ .name = "dtmfD",          .signal = VOICE_SIG_DTMFD },
 	{ .name = "keypad",         .signal = VOICE_SIG_INGRESS_DTMF },
+	{ .name = "answer", 	    .signal = VOICE_SIG_ANSWER },
 	{ .name = "",               .signal = VOICE_SIG_LAST },
 };
 
@@ -119,8 +120,8 @@ int voice_line_preinit(void) {
 	}
 	for(i = 0; i < terminal_info.num_voice_ports; i++) {
 		lines[i].type = VOICE_LINE_UNKNOWN;
-		lines[i].pcm_state[PCM_0] = LINE_PCM_STATE_NOT_USED;
-		lines[i].pcm_state[PCM_1] = LINE_PCM_STATE_NOT_USED;
+		lines[i].pcm_callid[PCM_0] = CALLID_INVALID;
+		lines[i].pcm_callid[PCM_1] = CALLID_INVALID;
 	}
 
 	return 0;
diff --git a/libvoice/libvoice.h b/libvoice/libvoice.h
index 19b8271e2bd2cc8293d446a18695c7568f9febce..c344235fac49cbbb2210b3dbae30b06864b6dac9 100644
--- a/libvoice/libvoice.h
+++ b/libvoice/libvoice.h
@@ -13,6 +13,8 @@
 
 #define MAX_CALLER_ID_LEN  120 // Max length of caller id string we accept
 #define MAX_KEYPAD_DIGITS  100 // Max number of simulated keypad presses we accept
+#define MAX_CODECS         20
+#define MAX_CODEC_NAMELEN  20
 
 #define DEBUG_LOOPBACK       0 // Debug - feed received audio back to transmitter
 
@@ -53,7 +55,6 @@ enum VOICE_EVENT
 };
 
 enum DECT_EVENT {
-	DECT_EVT_START,
 	DECT_EVT_SWITCH,
 	DECT_EVT_JOIN,
 	DECT_EVT_RELEASE,
@@ -88,20 +89,21 @@ enum VOICE_SIGNAL {
 	VOICE_SIG_DTMFC,
 	VOICE_SIG_DTMFD,
 	VOICE_SIG_INGRESS_DTMF, // Simulate phone keypad button pressing
+	VOICE_SIG_ANSWER,
 	VOICE_SIG_LAST
 };
 
-enum LINE_PCM_ID {
+typedef enum callid_state {
+	CALLID_INVALID = -1,
+	CALLID_OBTAINING = 0,
+	CALLID_ESTABLISHED = 1
+} callid_state;
+
+enum pcm_id {
 	PCM_0,
 	PCM_1
 };
 
-enum LINE_PCM_STATE {
-	LINE_PCM_STATE_NOT_USED  = -1,
-	LINE_PCM_STATE_RINGING   =  0,
-	LINE_PCM_STATE_CONNECTED =  1
-};
-
 enum VOICE_LINE_TYPE {
 	VOICE_LINE_UNKNOWN,  // Invalid type
 	VOICE_LINE_FXS,
@@ -135,7 +137,7 @@ struct line_t {
 	uint32_t simulated_busy_peer_id;  // ID of remote who gets the above busy message
 	uint16_t signaled_call_waiting;   // True if Call waiting has already been signaled to DECT
 	uint16_t conference_started;      // True if conference has just been setup by DECT handset
-	enum LINE_PCM_STATE pcm_state[2]; // PCM call states on the line
+	int pcm_callid[2];	  // -1: Invalid, 0: Obtaining, >0: Established
 	pe_list_t *pending_digits;        // List of keypad digits waiting to be sent
 
 	void *priv;                       // Platform dependent data
@@ -198,6 +200,19 @@ struct rtp_stats_t {
 	uint32_t avg_round_trip_delay;
 };
 
+struct codec_capability {
+	int num_codecs;
+	struct {
+		char uciName[MAX_CODEC_NAMELEN];
+		char codec[MAX_CODEC_NAMELEN];
+		int ptimeMin;
+		int ptimeMax;
+		int ptimeDefault;
+		int ptimeIncrement;
+		float bitRate;
+	} codecs[MAX_CODECS];
+};
+
 #define ENABLE_VOICE_DEBUG    0 // Enable/disable voice debug
 #if ENABLE_VOICE_DEBUG
 // log to file
@@ -263,6 +278,7 @@ int voice_get_max_rx_gain(void);
 int voice_get_terminal_info(const struct terminal_info_t *voice_port_cfg, struct terminal_info_t *terminal_info);
 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_egress_media(void (*cb_egress_media)(const struct media_packet_t *packet, int size));
diff --git a/line-dect.c b/line-dect.c
index 27075c9009111b20bb999a7cd454a7d9acf30a83..d505734f5668f87988a391cc02247a4ab5bfc36c 100644
--- a/line-dect.c
+++ b/line-dect.c
@@ -53,8 +53,8 @@ int ubus_process_queued_reqs_to_dectmngr(void) {
 		return 0;
 
 	ENDPT_DBG("%s: Poped DECT req %p from list, action: %d pcmId: %d\n", __func__, req, req->action, req->pcm_id);
-	ENDPT_DBG("%s: lines[%d].pcm_state[%d]: %d, lines[%d].pcm_state[%d]: %d\n", __func__, req->line, PCM_0,
-			lines[req->line].pcm_state[PCM_0], req->line, PCM_1, lines[req->line].pcm_state[PCM_1]);
+	pcm_states_dump(__func__, req->line);
+
 	switch (req->action) {
 		case ACTION_CONN_CREATE:
 		case ACTION_SIG_RING:
@@ -69,6 +69,12 @@ int ubus_process_queued_reqs_to_dectmngr(void) {
 				return -1;
 			}
 			break;
+		case ACTION_SIG_ANSWERED:
+			if(ubus_call_dectmngr(voicemngr_line_to_dectmngr_line(req->line), 2, 0, req->caller_id, req->pcm_id, req)) {
+				free(req);
+				return -1;
+			}
+			break;
 		default:
 			break;
 	}
@@ -127,8 +133,7 @@ int ubus_cb_dectmngr_replied(struct line_req_t *req, enum ubus_msg_status reply_
 
 	ENDPT_DBG("%s got answer req %p from dectmngr, action: %d, line: %d, pcmId: %d, conId: %d\n", __func__,
 		req, req->action, req->line, req->pcm_id, req->connection_id);
-	ENDPT_DBG("%s lines[%d].pcm_state[%d]: %d, lines[%d].pcm_state[%d]: %d\n", __func__, req->line, PCM_0,
-			lines[req->line].pcm_state[PCM_0], req->line, PCM_1, lines[req->line].pcm_state[PCM_1]);
+	pcm_states_dump(__func__, req->line);
 
 	switch (req->action) {
 		case ACTION_CONN_CREATE:
@@ -137,22 +142,18 @@ int ubus_cb_dectmngr_replied(struct line_req_t *req, enum ubus_msg_status reply_
 			}
 			break;
 		case ACTION_CONN_CLOSE:
-			lines[req->line].pcm_state[req->pcm_id] = LINE_PCM_STATE_NOT_USED;
-			ENDPT_DBG("%s changing value of lines[%d].pcm_state[%d] to %d\n", __func__, req->line, req->pcm_id,
-					lines[req->line].pcm_state[req->pcm_id]);
-			if (lines[req->line].pcm_state[PCM_0] > LINE_PCM_STATE_RINGING ||
-					lines[req->line].pcm_state[PCM_1] > LINE_PCM_STATE_RINGING)
+			lines[req->line].pcm_callid[req->pcm_id] = CALLID_INVALID;
+			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 && lines[req->line].pcm_state[PCM_1] == LINE_PCM_STATE_RINGING) ||
-					(req->pcm_id == PCM_1 && lines[req->line].pcm_state[PCM_0] == LINE_PCM_STATE_RINGING))
+			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;
-			lines[req->line].pcm_state[req->pcm_id] = LINE_PCM_STATE_RINGING;
-			ENDPT_DBG("%s changing value of lines[%d].pcm_state[%d] to %d\n", __func__, req->line, req->pcm_id,
-					lines[req->line].pcm_state[req->pcm_id]);
+			lines[req->line].pcm_callid[req->pcm_id] = CALLID_OBTAINING;
 			break;
 		default:
 			break;
diff --git a/line.c b/line.c
index 7545ad65c88eb5c0c4650b83dc3db953a2bb1414..5df9d2f7719494f37bc2794921b4853511f89e77 100644
--- a/line.c
+++ b/line.c
@@ -17,17 +17,32 @@
 #include "main.h"
 #include "ubus.h"
 
-enum {
-	STATE_OFF = 0,
-	STATE_ON,
-	STATE_LAST,
-};
-
-enum {
-	ACTION_CREATE,
-	ACTION_DESTROY,
-	ACTION_LAST,
-};
+
+static char *pcmState2Str(callid_state state)
+{
+	if (state <= CALLID_INVALID)
+		return "Invalid";
+	else if (state == CALLID_OBTAINING)
+		return "Obtaining";
+	else
+		return "Established";
+}
+
+void pcm_states_dump(const char *func, int line)
+{
+	ENDPT_DBG("%s line: %d pcm_callid[%d]: \'%s\', pcm_callid[%d]: \'%s\'\n", func, line, PCM_0, pcmState2Str(lines[line].pcm_callid[PCM_0]),
+		PCM_1, pcmState2Str(lines[line].pcm_callid[PCM_1]));
+}
+
+// Get call_id state (-1, 0, 1)
+callid_state get_callid_state(int call_id) {
+	if (call_id <= CALLID_INVALID)
+		return CALLID_INVALID;
+	else if (call_id == CALLID_OBTAINING)
+		return CALLID_OBTAINING;
+	else
+		return CALLID_ESTABLISHED;
+}
 
 static int send_dect_event_to_asterisk(int line, struct dect_event_t dectEvnt) {
 	struct line_event_t *msg;
@@ -86,8 +101,7 @@ static int line_signal_ring(int line, int pcm, enum VOICE_SIGNAL signal, const c
 	int start_ring = data && strcmp(data, "0") != 0;
 
 	ENDPT_DBG("%s: line %d pcm: %d data: %s\n", __func__, line, pcm, data);
-	ENDPT_DBG("%s: pcm_state[%d]: %d, pcm_state[%d]: %d\n", __func__, PCM_0, lines[line].pcm_state[PCM_0],
-			PCM_1, lines[line].pcm_state[PCM_1]);
+	pcm_states_dump(__func__, line);
 
 	// Relay the request to dectmngr if the line is DECT
 	if(lines[line].type == VOICE_LINE_DECT) {
@@ -159,6 +173,34 @@ static int line_signal_ring(int line, int pcm, enum VOICE_SIGNAL signal, const c
 	return 0;
 }
 
+//-------------------------------------------------------------
+// Reception of a answer connection request from Asterisk. If
+// line type is Dect we need to relay the requets to the Dectmngr.
+static int line_signal_answer(int line, int pcm, const char *data, struct voice_ubus_req_t *ubus_req) {
+	struct line_req_t *line_req = NULL;
+
+	ENDPT_DBG("%s() line %d pcm: %d data: %s\n", __func__, line, pcm, data);
+	pcm_states_dump(__func__, line);
+
+	assert(ubus_req);
+	line_req = calloc(1, sizeof(struct line_req_t));
+	if(!line_req) return -1;
+	line_req->line = line;
+	line_req->connection_id = -1;
+	line_req->pcm_id = pcm;
+	line_req->action = ACTION_SIG_ANSWERED;
+	memcpy(&line_req->ubus, ubus_req, sizeof(struct voice_ubus_req_t));
+
+	assert(line_req);
+
+	if(ubus_queue_req_to_dectmngr(line_req) || ubus_process_queued_reqs_to_dectmngr())
+		return -1;
+	ubus_defer_request(line_req->ubus.ctx, line_req->ubus.reqIn, &line_req->ubus.reqOut);
+	line_req->ubus.reqIn = NULL;
+
+	return 0;
+}
+
 //-------------------------------------------------------------
 // Generate a signal to the phone, such as DTMF tones or ringing
 int line_signal(int line, const char *signame, const char *data, struct voice_ubus_req_t *ubus_req) {
@@ -183,12 +225,12 @@ int line_signal(int line, const char *signame, const char *data, struct voice_ub
 		case VOICE_SIG_CALLID:
 		case VOICE_SIG_RINGING:
 			if(atoi(data) == 0) {
-				res = line_signal_ring(line, lines[line].pcm_state[PCM_0] ==
-						LINE_PCM_STATE_RINGING ? PCM_0 : PCM_1, sig->signal, data, ubus_req);
+				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);
 				lines[line].signaled_call_waiting = 0;
 			} else {
-				res = line_signal_ring(line, lines[line].pcm_state[PCM_0] ==
-						LINE_PCM_STATE_NOT_USED ? PCM_0 : PCM_1, sig->signal, data, ubus_req);
+				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);
 			}
 			break;
 
@@ -201,13 +243,13 @@ int line_signal(int line, const char *signame, const char *data, struct voice_ub
 				ENDPT_DBG("lines[%d].signaled_call_waiting: %d\n", line, lines[line].signaled_call_waiting);
 				if((data[0] == '1') && (lines[line].signaled_call_waiting == 0)) {
 					// start call waiting
-					res = line_signal_ring(line, lines[line].pcm_state[PCM_1] ==
-							LINE_PCM_STATE_NOT_USED ? PCM_1 : PCM_0, VOICE_SIG_RINGING, data, ubus_req);
+					res = line_signal_ring(line, get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_INVALID ?
+							PCM_1 : PCM_0, VOICE_SIG_RINGING, data, ubus_req);
 					lines[line].signaled_call_waiting = 1;
 				} else if((data[0] == '0')) {
 					// stop call waiting
-					res = line_signal_ring(line, lines[line].pcm_state[PCM_1] ==
-							LINE_PCM_STATE_RINGING ? PCM_1 : PCM_0, VOICE_SIG_RINGING, data, ubus_req);
+					res = line_signal_ring(line, get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING ?
+							PCM_1 : PCM_0, VOICE_SIG_RINGING, data, ubus_req);
 					lines[line].signaled_call_waiting = 0;
 				}
 			} else {
@@ -232,6 +274,15 @@ int line_signal(int line, const char *signame, const char *data, struct voice_ub
 			}
 			break;
 
+		case VOICE_SIG_ANSWER:
+			if ((lines[line].type == VOICE_LINE_DECT) && (data[0] == '1')) {
+				res = line_signal_answer(line, get_callid_state(lines[line].pcm_callid[PCM_1]) >= CALLID_OBTAINING ?
+						PCM_1 : PCM_0, data, ubus_req);
+			} else {
+				res = 0;
+			}
+			break;
+
 		default:
 			res = voice_line_signal(line, -1, sig->signal, atoi(data), NULL);
 			break;
@@ -257,18 +308,12 @@ int line_new_connection_by_asterisk(int line, int connection, struct voice_ubus_
 		return -1;
 
 	ENDPT_DBG("%s line: %d, connection: %d\n", __func__, line, connection);
-	ENDPT_DBG("%s lines[%d].pcm_state[%d]: %d, lines[%d].pcm_state[%d]: %d\n", __func__, line, PCM_0,
-		lines[line].pcm_state[PCM_0], line, PCM_1, lines[line].pcm_state[PCM_1]);
-
-	if (lines[line].pcm_state[PCM_0] == LINE_PCM_STATE_RINGING) {
-		lines[line].pcm_state[PCM_0] = connection;
-		ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_0] to %d\n", __func__, line,
-			lines[line].pcm_state[PCM_0]);
-	} else if (lines[line].pcm_state[PCM_1] == LINE_PCM_STATE_RINGING) {
-		lines[line].pcm_state[PCM_1] = connection;
-		ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_1] to %d\n", __func__, line,
-			lines[line].pcm_state[PCM_1]);
-	}
+	pcm_states_dump(__func__, line);
+
+	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)
+		lines[line].pcm_callid[PCM_1] = connection;
 
 	if (lines[line].type == VOICE_LINE_DECT) {
 		if (voice_line_is_offhook(line) || voice_line_get_connection_count(line) > 0) {
@@ -284,7 +329,7 @@ int line_new_connection_by_asterisk(int line, int connection, struct voice_ubus_
 			}
 			line_req->line = line;
 			line_req->connection_id = line;
-			line_req->pcm_id = lines[line].pcm_state[PCM_0] == connection ? PCM_0 : PCM_1;
+			line_req->pcm_id = lines[line].pcm_callid[PCM_0] == connection ? PCM_0 : PCM_1;
 			line_req->action = ACTION_CONN_CREATE;
 			memcpy(&line_req->ubus, ubus_req, sizeof(struct voice_ubus_req_t));
 			if (ubus_queue_req_to_dectmngr(line_req) || ubus_process_queued_reqs_to_dectmngr())
@@ -309,11 +354,10 @@ int line_close_connection_by_asterisk(int line, int connection, struct voice_ubu
 		return -1;
 
 	ENDPT_DBG("%s line: %d, connection: %d\n", __func__, line, connection);
-	ENDPT_DBG("%s lines[%d].pcm_state[%d]: %d, lines[%d].pcm_state[%d]: %d\n", __func__, line, PCM_0,
-		lines[line].pcm_state[PCM_0], line, PCM_1, lines[line].pcm_state[PCM_1]);
+	pcm_states_dump(__func__, line);
 
-	if (lines[line].pcm_state[PCM_0] == LINE_PCM_STATE_NOT_USED &&
-		lines[line].pcm_state[PCM_1] == LINE_PCM_STATE_NOT_USED) {
+	if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_INVALID &&
+		get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_INVALID) {
 		return voice_connection_close(line, line);
 	}
 
@@ -325,18 +369,14 @@ int line_close_connection_by_asterisk(int line, int connection, struct voice_ubu
 			if(!line_req) return -1;
 			line_req->line = line;
 			line_req->connection_id = line;
-			if (lines[line].pcm_state[PCM_0] >= LINE_PCM_STATE_CONNECTED &&
-				lines[line].pcm_state[PCM_1] == LINE_PCM_STATE_NOT_USED) {
+			if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_ESTABLISHED &&
+				get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_INVALID) {
 				line_req->pcm_id = PCM_0;
-				lines[line].pcm_state[PCM_0] = LINE_PCM_STATE_NOT_USED;
-				ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_0] to %d\n", __func__,
-					line, lines[line].pcm_state[PCM_0]);
-			} else if (lines[line].pcm_state[PCM_1] >= LINE_PCM_STATE_CONNECTED &&
-				lines[line].pcm_state[PCM_0] == LINE_PCM_STATE_NOT_USED) {
+				lines[line].pcm_callid[PCM_0] = CALLID_INVALID;
+			} 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_state[PCM_1] = LINE_PCM_STATE_NOT_USED;
-				ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_1] to %d\n", __func__,
-					line, lines[line].pcm_state[PCM_1]);
+				lines[line].pcm_callid[PCM_1] = CALLID_INVALID;
 			}
 			line_req->action = ACTION_CONN_CLOSE;
 			memcpy(&line_req->ubus, ubus_req, sizeof(struct voice_ubus_req_t));
@@ -347,13 +387,11 @@ int line_close_connection_by_asterisk(int line, int connection, struct voice_ubu
 			break;
 
 		default:
-			if (lines[line].pcm_state[PCM_0] >= LINE_PCM_STATE_CONNECTED) {
-				lines[line].pcm_state[PCM_0] = LINE_PCM_STATE_NOT_USED;
-				ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_0] to %d\n", line, lines[line].pcm_state[PCM_0]);
-			} else if (lines[line].pcm_state[PCM_1] >= LINE_PCM_STATE_CONNECTED) {
-				lines[line].pcm_state[PCM_1] = LINE_PCM_STATE_NOT_USED;
-				ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_1] to %d\n", line, lines[line].pcm_state[PCM_1]);
-			}
+			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)
+				lines[line].pcm_callid[PCM_1] = CALLID_INVALID;
+
 			return voice_connection_close(line, line);
 	}
 
@@ -367,8 +405,7 @@ int line_release_connection_by_asterisk(int line, int connection, struct voice_u
 		return -1;
 
 	ENDPT_DBG("%s line: %d connection: %d\n", __func__, line, connection);
-	ENDPT_DBG("%s lines[%d].pcm_state[%d]: %d, lines[%d].pcm_state[%d]: %d\n", __func__,
-		line, PCM_0, lines[line].pcm_state[PCM_0], line, PCM_1, lines[line].pcm_state[PCM_1]);
+	pcm_states_dump(__func__, line);
 
 	// during start of call conference asterisk removes 1 of connection, we skip
 	// it because voicemngr<->dectmngr needs to keep it active
@@ -377,11 +414,12 @@ int line_release_connection_by_asterisk(int line, int connection, struct voice_u
 		return 0;
 	}
 
-	if (lines[line].pcm_state[PCM_0] < LINE_PCM_STATE_CONNECTED && lines[line].pcm_state[PCM_1] < LINE_PCM_STATE_CONNECTED) {
+	if (get_callid_state(lines[line].pcm_callid[PCM_0]) < CALLID_ESTABLISHED &&
+		get_callid_state(lines[line].pcm_callid[PCM_1]) < CALLID_ESTABLISHED) {
 		return 0;
 	}
 
-	if (lines[line].pcm_state[PCM_0] != connection && lines[line].pcm_state[PCM_1] != connection) {
+	if (lines[line].pcm_callid[PCM_0] != connection && lines[line].pcm_callid[PCM_1] != connection) {
 		return 0;
 	}
 
@@ -393,16 +431,12 @@ int line_release_connection_by_asterisk(int line, int connection, struct voice_u
 			if(!line_req) return -1;
 			line_req->line = line;
 			line_req->connection_id = line;
-			if (lines[line].pcm_state[PCM_0] == connection) {
+			if (lines[line].pcm_callid[PCM_0] == connection) {
 				line_req->pcm_id = PCM_0;
-				lines[line].pcm_state[PCM_0] = LINE_PCM_STATE_NOT_USED;
-				ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_0] to %d\n", __func__,
-					line, lines[line].pcm_state[PCM_0]);
-			} else if (lines[line].pcm_state[PCM_1] == connection) {
+				lines[line].pcm_callid[PCM_0] = CALLID_INVALID;
+			} else if (lines[line].pcm_callid[PCM_1] == connection) {
 				line_req->pcm_id = PCM_1;
-				lines[line].pcm_state[PCM_1] = LINE_PCM_STATE_NOT_USED;
-				ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_1] to %d\n", __func__,
-					line, lines[line].pcm_state[PCM_1]);
+				lines[line].pcm_callid[PCM_1] = CALLID_INVALID;
 			}
 			line_req->action = ACTION_CONN_CLOSE;
 			memcpy(&line_req->ubus, ubus_req, sizeof(struct voice_ubus_req_t));
@@ -413,40 +447,32 @@ int line_release_connection_by_asterisk(int line, int connection, struct voice_u
 			break;
 
 		default:
-			if (lines[line].pcm_state[PCM_0] == connection) {
-				lines[line].pcm_state[PCM_0] = LINE_PCM_STATE_NOT_USED;
-				ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_0] to %d\n", __func__,
-					line, lines[line].pcm_state[PCM_0]);
-			} else if (lines[line].pcm_state[PCM_1] == connection) {
-				lines[line].pcm_state[PCM_1] = LINE_PCM_STATE_NOT_USED;
-				ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_1] to %d\n", __func__,
-					line, lines[line].pcm_state[PCM_1]);
-			}
+			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)
+				lines[line].pcm_callid[PCM_1] = CALLID_INVALID;
+
 			return voice_connection_close(line, line);
 	}
 
 	return 0;
 }
 
-int line_update_connection_by_pbx(int line, int pcm_state) {
+int line_update_connection_by_pbx(int line, int pcm_callid) {
 	if (!voice_line_is_ready(line))
 		return -1;
 
-	ENDPT_DBG("%s Received update connection for line: %d with pcm_state: %d\n",
-		__func__, line, pcm_state);
-	ENDPT_DBG("%s lines[%d].pcm_state[%d]: %d, lines[%d].pcm_state[%d]: %d\n", __func__,
-		line, PCM_0, lines[line].pcm_state[PCM_0], line, PCM_1, lines[line].pcm_state[PCM_1]);
+	ENDPT_DBG("%s Received update connection for line: %d with pcm_callid: %d\n",
+		__func__, line, pcm_callid);
+	pcm_states_dump(__func__, line);
 
 	if(lines[line].type != VOICE_LINE_DECT)
 		return 0;
 
-	if (lines[line].pcm_state[PCM_0] == LINE_PCM_STATE_RINGING) {
-		lines[line].pcm_state[PCM_0] = pcm_state;
-		ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_0] to %d\n", __func__, line, lines[line].pcm_state[PCM_0]);
-	} else if(lines[line].pcm_state[PCM_1] == LINE_PCM_STATE_RINGING) {
-		lines[line].pcm_state[PCM_1] = pcm_state;
-		ENDPT_DBG("%s changing value of lines[%d].pcm_state[PCM_1] to %d\n", __func__, line, lines[line].pcm_state[PCM_1]);
-	}
+	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)
+		lines[line].pcm_callid[PCM_1] = pcm_callid;
 
 	return 0;
 }
@@ -465,14 +491,11 @@ int line_new_connection_by_dect(int line, const char *cid, int pcm, struct voice
 		return -1;
 
 	ENDPT_DBG("%s line: %d, pcm: %d, cid: %s\n", __func__, line, pcm, cid);
-	ENDPT_DBG("%s lines[%d].pcm_state[%d]: %d, lines[%d].pcm_state[%d]: %d\n", __func__,
-		line, PCM_0, lines[line].pcm_state[PCM_0], line, PCM_1, lines[line].pcm_state[PCM_1]);
+	pcm_states_dump(__func__, line);
 
 	if(pcm <= PCM_1) {
-		lines[line].pcm_state[pcm] = LINE_PCM_STATE_RINGING;
+		lines[line].pcm_callid[pcm] = CALLID_OBTAINING;
 		lines[line].signaled_call_waiting = 0;
-		ENDPT_DBG("%s changing value of lines[%d].pcm_state[%d] to %d\n", __func__,
-			line, pcm, lines[line].pcm_state[pcm]);
 	}
 
 	if(!voice_line_is_offhook(line) && voice_line_simulate_hook(line, VOICE_EVT_OFFHOOK))
@@ -537,8 +560,7 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub
 		return -1;
 	}
 	ENDPT_DBG("%s() for line %d, pcm: %d\n", __func__, line, pcm);
-	ENDPT_DBG("%s lines[%d].pcm_state[%d]: %d, lines[%d].pcm_state[%d]: %d\n", __func__, line, PCM_0, lines[line].pcm_state[PCM_0],
-		line, PCM_1, lines[line].pcm_state[PCM_1]);
+	pcm_states_dump(__func__, line);
 
 	if (pcm == CALL_DECT_UNAVAILABLE) {
 		struct line_event_t *msg;
@@ -558,33 +580,43 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub
 			pcm, UBUS_STATUS_OK);
 	}
 
-	 if (lines[line].pcm_state[pcm] == LINE_PCM_STATE_RINGING) {
-		struct line_event_t *msg;
+	if ((pcm & 0xFFFF) == CALL_REJECT && ((pcm >> 16) == CALL_DEFAULT0 || (pcm >> 16) == CALL_DEFAULT1)) {
+		if (get_callid_state(lines[line].pcm_callid[(pcm >> 16)]) == CALLID_OBTAINING) {
+			struct line_event_t *msg;
 
-		ENDPT_DBG("%s: DECT handsets may have not answered the call yet. "
-			"Send CALL_REJECT event to Asterisk\n", __func__);
+			ENDPT_DBG("%s: DECT handsets may have not answered the call yet. "
+				"Send CALL_REJECT event to Asterisk\n", __func__);
 
-		msg = malloc(sizeof(struct line_event_t));
-		if (msg) {
-			msg->name = "CALL_REJECT";
-			msg->data = 0;
-			msg->line = line;
-			send_event_main(msg, EVENT_MAIN_LINE);
-		}
+			msg = malloc(sizeof(struct line_event_t));
+			if (msg) {
+				msg->name = "CALL_REJECT";
+				msg->data = 0;
+				msg->line = line;
+				send_event_main(msg, EVENT_MAIN_LINE);
+			}
 
-		return send_reply_dectmngr(ubus_req, line + 1, // +1 Dectmngr lines starting from 1
-			pcm, UBUS_STATUS_OK);
+			return send_reply_dectmngr(ubus_req, line + 1, // +1 Dectmngr lines starting from 1
+				pcm, UBUS_STATUS_OK);
+		} else {
+			pcm = pcm >> 16;
+		}
 	}
 
-	if(lines[line].pcm_state[PCM_0] <= LINE_PCM_STATE_RINGING ||
-		lines[line].pcm_state[PCM_1] <= LINE_PCM_STATE_RINGING) {
+	if(get_callid_state(lines[line].pcm_callid[PCM_0]) <= CALLID_OBTAINING ||
+		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;
+			if (get_callid_state(lines[line].pcm_callid[1-pcm]) == CALLID_OBTAINING) {
+				lines[line].pcm_callid[1-pcm] = CALLID_INVALID;
+			}
+		}
 		voice_line_simulate_hook(line, VOICE_EVT_ONHOOK);
 		return -1;
 	}
 
-	lines[line].pcm_state[pcm] = LINE_PCM_STATE_NOT_USED;
-	ENDPT_DBG("%s changing value of lines[%d].pcm_state[%d] to %d\n", __func__,
-		line, pcm, lines[line].pcm_state[pcm]);
+	if(pcm == CALL_DEFAULT0 || pcm == CALL_DEFAULT1)
+		lines[line].pcm_callid[pcm] = CALLID_INVALID;
+
 	if(send_dect_event_to_asterisk(line, dect_event_map[DECT_EVT_RELEASE]))
 		return -1;
 
diff --git a/line.h b/line.h
index 0da3741c233c8c9a1204b28a511a9a2ee109286f..8a420ba7c284e49bf03dba0ee90324836e8dfc0a 100644
--- a/line.h
+++ b/line.h
@@ -10,6 +10,7 @@ enum line_action_t {
 	ACTION_CONN_CREATE,
 	ACTION_CONN_CLOSE,
 	ACTION_SIG_RING,
+	ACTION_SIG_ANSWERED,
 };
 
 // In UBUS request to voicemngr we need to define what this request is about
@@ -20,6 +21,7 @@ enum call_action {
 	CALL_TOGGLE,            // Switch in Call Waiting
 	CALL_CONFERENCE,        // Join - start Call Conference
 	CALL_DECT_UNAVAILABLE,  // No DECT handset available for call
+	CALL_REJECT,            // indicate for call_reject event, upper 16 bits for pcm_id when using
 	CALL_LAST
 };
 
@@ -52,9 +54,11 @@ int find_endpt_from_asterisk_id(int line);
 int line_new_connection_by_asterisk(int line, int connection, struct voice_ubus_req_t *ubus_req);
 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_state);
+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_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);
 
 #endif
diff --git a/schemas/ubus/endpt.json b/schemas/ubus/endpt.json
index 457d9ab7ac1b5895c3192f9fed08a979c26c3fe6..0366b62edc27e18a7f0c0ad4240bc30624dd9a67 100644
--- a/schemas/ubus/endpt.json
+++ b/schemas/ubus/endpt.json
@@ -139,20 +139,22 @@
                     "oneOf": [
                         {
                             "type": "object",
-                            "required": [ "terminal", "add" ],
+                            "required": [ "terminal", "add", "pcm_id" ],
                             "properties": {
                                 "terminal": { "type": "integer", "minimum": 1, "maximum": 6 },
                                 "add": { "type": "integer", "minimum": 0, "maximum": 5 },
-                                "cid": { "type": "string", "minLength": 0, "maxLength": 32, "pattern": "^[0-9]*#" }
+                                "cid": { "type": "string", "minLength": 0, "maxLength": 32, "pattern": "^[0-9]*#" },
+                                "pcm_id": { "type": "integer", "minimum": 0, "maximum": 5 }
                             }
                         },
                         {
                             "type": "object",
-                            "required": [ "terminal", "release" ],
+                            "required": [ "terminal", "release", "pcm_id" ],
                             "properties": {
                                 "terminal": { "type": "integer", "minimum": 1, "maximum": 6 },
                                 "release": { "type": "integer", "minimum": 0, "maximum": 5 },
-                                "cid": { "type": "string", "minLength": 0, "maxLength": 32, "pattern": "^[0-9]*#" }
+                                "cid": { "type": "string", "minLength": 0, "maxLength": 32, "pattern": "^[0-9]*#" },
+                                "pcm_id": { "type": "integer", "minimum": 0, "maximum": 5 }
                             }
                         }
                     ]
@@ -240,6 +242,78 @@
                     }
                 }
             }
+        },
+        "codecs": {
+            "type": "object",
+            "required": [ "output" ],
+            "properties": {
+                "input": {
+                    "type": "object",
+                    "properties": {}
+                },
+                "output": {
+                    "type": "object",
+                    "required": [ "codec_key" ],
+                    "properties": {
+                        "codec_key": {
+                            "type": "object",
+                            "required": [
+                                "name",
+                                "ptime_min",
+                                "ptime_max",
+                                "ptime_default",
+                                "ptime_increment",
+                                "bitrate"
+                            ],
+                            "properties": {
+                                "name": {
+                                    "type": "string",
+                                    "enum": [
+                                        "G.711MuLaw",
+                                        "G.711ALaw",
+                                        "G.729a",
+                                        "G.723.1",
+                                        "G.726",
+                                        "G.728",
+                                        "G.729",
+                                        "G.729e",
+                                        "GSM-FR",
+                                        "GSM-EFR",
+                                        "GSM-HR",
+                                        "GSM-AMR",
+                                        "iLBC"
+                                    ]
+                                },
+                                "ptime_min": {
+                                    "type": "integer",
+                                    "minimum": 0,
+                                    "maximum": 50
+                                },
+                                "ptime_max": {
+                                    "type": "integer",
+                                    "minimum": 0,
+                                    "maximum": 300
+                                },
+                                "ptime_default": {
+                                    "type": "integer",
+                                    "minimum": 0,
+                                    "maximum": 50
+                                },
+                                "ptime_increment": {
+                                    "type": "integer",
+                                    "minimum": 0,
+                                    "maximum": 50
+                                },
+                                "bitrate": {
+                                    "type": "number",
+                                    "minimum": 0,
+                                    "maximum": 100
+                                }
+                            }
+                        }
+                    }
+                }
+            }
         }
     }
 }
diff --git a/ubus.c b/ubus.c
index 2962fa27662599cd12bff5568930359a1dd6a792..65e55c249c9c9d21c4189d7fed06a7af5368ca27 100644
--- a/ubus.c
+++ b/ubus.c
@@ -110,6 +110,9 @@ static int ubus_request_call(struct ubus_context *uctx, struct ubus_object *obj
 static int ubus_request_rtp_stats(struct ubus_context *uctx, struct ubus_object *obj __attribute__((unused)),
 	struct ubus_request_data *req, const char *method __attribute__((unused)),
 	struct blob_attr *msg);
+static int ubus_request_codec_capability(struct ubus_context *uctx, struct ubus_object *obj __attribute__((unused)),
+	struct ubus_request_data *req, const char *method __attribute__((unused)),
+	struct blob_attr *msg __attribute__((unused)));
 
 
 const char uciStrConfig[] = "asterisk";							// UCI package name
@@ -180,6 +183,7 @@ static struct ubus_method rpc_methods[] = {
 	UBUS_METHOD("status", ubus_request_status, request_status_policy),
 	UBUS_METHOD("call", ubus_request_call, request_call_policy),
 	UBUS_METHOD("rtp_stats", ubus_request_rtp_stats, request_rtp_stats_policy),
+	UBUS_METHOD_NOARG("codecs", ubus_request_codec_capability),
 };
 
 static struct ubus_object_type rpc_obj_type =
@@ -457,7 +461,8 @@ static int ubus_request_count(struct ubus_context *uctx, struct ubus_object *obj
 	int32_t dectEndpoints, totEndpoints;
 	struct blob_buf bb;
 
-	if(blobmsg_parse(request_count_policy, ARRAY_SIZE(request_count_policy), keys, blob_data(msg), blob_len(msg))) {
+	if(blobmsg_parse(request_count_policy, ARRAY_SIZE(request_count_policy),
+		keys, blob_data(msg), blob_len(msg)) && blob_len(msg)) {
 		return UBUS_STATUS_INVALID_ARGUMENT;
 	}
 
@@ -624,7 +629,7 @@ static int ubus_request_status(struct ubus_context *uctx, struct ubus_object *ob
 	int line, unpopulatedDectEndpoints, totEndpoints;
 
 	if(blobmsg_parse(request_status_policy, ARRAY_SIZE(request_status_policy),
-			keys, blob_data(msg), blob_len(msg))) {
+			keys, blob_data(msg), blob_len(msg)) && blob_len(msg)) {
 		return UBUS_STATUS_INVALID_ARGUMENT;
 	}
 
@@ -756,6 +761,51 @@ static int ubus_request_rtp_stats(struct ubus_context *uctx, struct ubus_object
 	return UBUS_STATUS_OK;
 }
 
+// RPC handler for ubus call endpt codecs : Provides list of supported codecs and parameters
+static int ubus_request_codec_capability(struct ubus_context *uctx, struct ubus_object *obj __attribute__((unused)),
+			  struct ubus_request_data *req, const char *method __attribute__((unused)),
+			  struct blob_attr *msg __attribute__((unused)))
+{
+	struct codec_capability codecs_list = {0};
+	struct blob_buf blob;
+	memset(&blob, 0, sizeof(blob));
+
+	if(blob_buf_init(&blob, 0))
+		return UBUS_STATUS_UNKNOWN_ERROR;
+
+	int status = voice_get_codec_capability(&codecs_list);
+	if(!status)
+	{
+		for(int count = 0 ; count < codecs_list.num_codecs; count++)
+		{
+			void *table;
+			table = blobmsg_open_table(&blob, codecs_list.codecs[count].uciName);
+			blobmsg_add_string(&blob, "name", codecs_list.codecs[count].codec);
+			blobmsg_add_u32(&blob, "ptime_min", codecs_list.codecs[count].ptimeMin);
+			blobmsg_add_u32(&blob, "ptime_max", codecs_list.codecs[count].ptimeMax);
+			blobmsg_add_u32(&blob, "ptime_default", codecs_list.codecs[count].ptimeDefault);
+			blobmsg_add_u32(&blob, "ptime_increment", codecs_list.codecs[count].ptimeIncrement);
+			blobmsg_add_double(&blob, "bitrate", codecs_list.codecs[count].bitRate);
+			blobmsg_close_table(&blob, table);
+		}
+	}
+	else
+	{
+		// Read the /lib/voice/codecs.json file
+		static const char *codecfile = "/lib/voice/codecs.json";
+		ENDPT_DBG("Display codecs from file codecs.json !!\n");
+		int res = blobmsg_add_json_from_file(&blob, codecfile);
+		if(!res)
+		{
+			ENDPT_DBG("brcm capability query returned with error %d and Json file is missing/invalid \n", status);
+			return UBUS_STATUS_UNKNOWN_ERROR;
+		}
+	}
+	ubus_send_reply(uctx, req, blob.head);
+	blob_buf_free(&blob);
+	return UBUS_STATUS_OK;
+}
+
 // RPC handler for ubus call endpt call '{ "terminal": x, "add": x }'
 static int ubus_request_call(struct ubus_context *uctx, struct ubus_object *obj __attribute__((unused)),
 		struct ubus_request_data *req, const char *method __attribute__((unused)),
@@ -803,7 +853,7 @@ static int ubus_request_call(struct ubus_context *uctx, struct ubus_object *obj
 		ENDPT_DBG("pcmId %d\n", pcmId);
 	}
 
-	if(pcmId < CALL_DEFAULT0 || pcmId >= CALL_LAST || (!add && !release)) {
+	if((pcmId & 0xFFFF) < CALL_DEFAULT0 || (pcmId & 0xFFFF) >= CALL_LAST || (!add && !release)) {
 		return UBUS_STATUS_INVALID_ARGUMENT;
 	}