diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h
index e81e3bea64dcf672357e9fb92b593a5230d1c9a7..b43f06df80adca5861ce8e5b5efe8b63ca1fee48 100644
--- a/openair2/COMMON/platform_types.h
+++ b/openair2/COMMON/platform_types.h
@@ -158,7 +158,9 @@ typedef enum  ip_traffic_type_e {
   TRAFFIC_IPV4_TYPE_UNICAST    =  5,
   TRAFFIC_IPV4_TYPE_MULTICAST  =  6,
   TRAFFIC_IPV4_TYPE_BROADCAST  =  7,
-  TRAFFIC_IPV4_TYPE_UNKNOWN    =  8
+  TRAFFIC_IPV4_TYPE_UNKNOWN    =  8,
+  TRAFFIC_PC5S_SIGNALLING      =  9,
+  TRAFFIC_PC5S_SESSION_INIT    =  10
 } ip_traffic_type_t;
 
 //-----------------------------------------------------------------------------
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index 07aafee26b4e00e7931db94d895924f3a5f392a7..9bbb425e6a8d7b697366ed18342dcb09b0a887fc 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -387,6 +387,10 @@ typedef struct pdcp_data_req_header_s {
   sdu_size_t          data_size;
   signed int          inst;
   ip_traffic_type_t   traffic_type;
+#ifdef Rel14
+  uint32_t sourceL2Id;
+  uint32_t destinationL2Id;
+#endif
 } pdcp_data_req_header_t;
 
 typedef struct pdcp_data_ind_header_s {
@@ -394,6 +398,10 @@ typedef struct pdcp_data_ind_header_s {
   sdu_size_t          data_size;
   signed int          inst;
   ip_traffic_type_t   dummy_traffic_type;
+#ifdef Rel14
+  uint32_t sourceL2Id;
+  uint32_t destinationL2Id;
+#endif
 } pdcp_data_ind_header_t;
 
 struct pdcp_netlink_element_s {
@@ -406,49 +414,37 @@ struct pdcp_netlink_element_s {
 //TTN for D2D (PC5S)
 #ifdef Rel14
 #define PDCP_SOCKET_PORT_NO 9999 //temporary value
+#define PC5_SIGNALLING_PAYLOAD_SIZE   5  //should be updated with a correct value
 int pdcp_pc5_sockfd;
 struct sockaddr_in prose_ctrl_addr;
 struct sockaddr_in prose_pdcp_addr;
 struct sockaddr_in pdcp_sin;
 int pdcp_pc5_socket_init();
 
-typedef enum SL_PC5S_TYPES_e {
-  SL_PC5S_INIT=1,
-  SL_DIRECT_COMMUNICATION_REQUEST,
-  SL_DIRECT_COMMUNICATION_ACCEPT,
-  SL_DIRECT_COMMUNICATION_REJECT,
-  SL_DIRECT_SECURITY_MODE_COMMAND,
-  SL_DIRECT_SECURITY_MODE_COMPLETE
-} SL_PC5S_TYPES_t;
-
 typedef struct  {
-   SL_PC5S_TYPES_t   msg_type;
-   uint16_t  rb_id;
-   int32_t   data_size;
-   uint8_t   inst;
+   rb_id_t             rb_id;
+   sdu_size_t          data_size;
+   signed int          inst;
+   ip_traffic_type_t   traffic_type;
+   uint32_t sourceL2Id;
+   uint32_t destinationL2Id;
 } __attribute__((__packed__)) pdcp_data_header_t;
 
-//should be completed with other IEs (3GPP TS 24.334)
-typedef struct {
-   uint16_t sequenceNumber;
-   uint8_t ipAddressConfig;
-} __attribute__((__packed__)) PC5SDirectCommunicationRequest;
-
-typedef struct {
-   uint16_t sequenceNumber;
-   uint8_t ipAddressConfig;
-} __attribute__((__packed__)) PC5SDirectCommunicationAccept;
+//new PC5S-message
+typedef struct  {
+   unsigned char bytes[PC5_SIGNALLING_PAYLOAD_SIZE]; 
+}  __attribute__((__packed__)) PC5SignallingMessage ;
 
 //example of PC5-S messages
-typedef struct  {
+typedef struct {
    pdcp_data_header_t pdcp_data_header;
    union {
-      PC5SDirectCommunicationRequest pc5s_direct_communication_req;
-      PC5SDirectCommunicationAccept pc5s_direct_communication_accept;
       uint8_t status;
+      PC5SignallingMessage pc5_signalling_message;
    } pc5sPrimitive;
 } __attribute__((__packed__)) sidelink_pc5s_element;
 
+
 #endif
 
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 9b9bd0ed13fdf7aead4eae3cacbb2f6af5673b7c..af989b06d6753e31732c15030db7fbed6e8e1bdf 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -206,31 +206,28 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const  ctxt_pP)
 //TTN - for D2D (PC5S)
 #ifdef Rel14
       sidelink_pc5s_element *sl_pc5s_msg_recv = NULL;
-      sidelink_pc5s_element *sl_pc5s_msg_send = NULL;
       char send_buf[BUFSIZE];
 
-      if ((((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id) == 10) { //hardcoded for PC5-Signaling
+      LOG_D(PDCP, "[THINH] PDCP->IP Frame %d INST %d, rab %d, source L2ID 0x%08x, Dest L2ID  0x%08x\n",
+            ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst,
+            ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, ((pdcp_data_ind_header_t *)(sdu_p->data))->sourceL2Id, ((pdcp_data_ind_header_t *)(sdu_p->data))->destinationL2Id);
+
+     // if ((((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id) == 10) { //hardcoded for PC5-Signaling
+      if ((((pdcp_data_ind_header_t *)(sdu_p->data))->dummy_traffic_type) == TRAFFIC_PC5S_SIGNALLING) {
 
 #ifdef PDCP_DEBUG
          sl_pc5s_msg_recv = calloc(1, sizeof(sidelink_pc5s_element));
          memcpy((void*)sl_pc5s_msg_recv, (void*)(sdu_p->data+sizeof(pdcp_data_ind_header_t)), sizeof(sidelink_pc5s_element));
-
-         LOG_D(PDCP,"Received PC5S message, header msg_type: %d)\n", sl_pc5s_msg_recv->pdcp_data_header.msg_type);
+         LOG_D(PDCP,"Received PC5S message, header traffic_type: %d)\n", sl_pc5s_msg_recv->pdcp_data_header.traffic_type);
          LOG_D(PDCP,"Received PC5S message, header rb_id: %d)\n", sl_pc5s_msg_recv->pdcp_data_header.rb_id);
          LOG_D(PDCP,"Received PC5S message, header data_size: %d)\n", sl_pc5s_msg_recv->pdcp_data_header.data_size);
          LOG_D(PDCP,"Received PC5S message, header inst: %d)\n", sl_pc5s_msg_recv->pdcp_data_header.inst);
-
-         if (sl_pc5s_msg_recv->pdcp_data_header.msg_type == SL_DIRECT_COMMUNICATION_REQUEST){
-            LOG_D(PDCP,"PC5S message (SL_DIRECT_COMMUNICATION_REQUEST), seqno: %d)\n", sl_pc5s_msg_recv->pc5sPrimitive.pc5s_direct_communication_req.sequenceNumber);
-            LOG_D(PDCP,"PC5S message (SL_DIRECT_COMMUNICATION_REQUEST), ipAddressConfig: %d)\n", sl_pc5s_msg_recv->pc5sPrimitive.pc5s_direct_communication_req.ipAddressConfig);
-         }
-         //send to ProSe app
-         LOG_D(PDCP,"Send DirectCommunicationRequest to ProSe App \n");
+         LOG_D(PDCP,"Received PC5-S message, sourceL2Id: 0x%08x\n)\n", sl_pc5s_msg_recv->pdcp_data_header.sourceL2Id);
+         LOG_D(PDCP,"Received PC5-S message, destinationL1Id: 0x%08x\n)\n", sl_pc5s_msg_recv->pdcp_data_header.destinationL2Id);
+         free(sl_pc5s_msg_recv);
 #endif
          memset(send_buf, 0, BUFSIZE);
-         //memcpy((void *)send_buf, (void *)sl_pc5s_msg_recv, sizeof(sidelink_pc5s_element));
          memcpy((void *)send_buf, (void*)(sdu_p->data+sizeof(pdcp_data_ind_header_t)), sizeof(sidelink_pc5s_element));
-         //free(sl_ctrl_msg_send);
 
          int prose_addr_len = sizeof(prose_pdcp_addr);
          int n = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len);
@@ -238,7 +235,6 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const  ctxt_pP)
             LOG_E(PDCP, "ERROR: Failed to send to ProSe App\n");
             exit(EXIT_FAILURE);
          }
-
       }
 #endif
 
@@ -566,7 +562,6 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
 
 //TTN for D2D (PC5S)
 #ifdef Rel14
-  // module_id = 0 ; //hardcoded for testing only
    prose_addr_len = sizeof(prose_pdcp_addr);
    // receive a message from ProSe App
    memset(receive_buf, 0, BUFSIZE);
@@ -580,12 +575,12 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
       pdcp_data_header = calloc(1, sizeof(pdcp_data_header_t));
       memcpy((void *)pdcp_data_header, (void *)receive_buf, sizeof(pdcp_data_header_t));
 
-      if (pdcp_data_header->msg_type == SL_PC5S_INIT){
+      if (pdcp_data_header->traffic_type == TRAFFIC_PC5S_SESSION_INIT){
          //send reply to ProSe app
-         LOG_D(PDCP,"[pdcp_fifo_read_input_sdus]: Send response to ProSe App [PDCP socket]\n");
+         LOG_D(PDCP,"Received a request to open PDCP socket and establish a new PDCP session ... send response to ProSe App \n");
          memset(send_buf, 0, BUFSIZE);
          sl_pc5s_msg_send = calloc(1, sizeof(sidelink_pc5s_element));
-         sl_pc5s_msg_send->pdcp_data_header.msg_type = SL_PC5S_INIT;
+         sl_pc5s_msg_send->pdcp_data_header.traffic_type = TRAFFIC_PC5S_SESSION_INIT;
          sl_pc5s_msg_send->pc5sPrimitive.status = 1;
 
          memcpy((void *)send_buf, (void *)sl_pc5s_msg_send, sizeof(sidelink_pc5s_element));
@@ -595,19 +590,16 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
             LOG_E(PDCP, "ERROR: Failed to send to ProSe App\n");
             exit(EXIT_FAILURE);
          }
-      } else if (pdcp_data_header->msg_type > SL_PC5S_INIT) { //if containing PC5-S message -> send to other UE
+      } else if (pdcp_data_header->traffic_type == TRAFFIC_PC5S_SIGNALLING) { //if containing PC5-S message -> send to other UE
+         LOG_D(PDCP,"Received PC5-S message ... send to the other UE\n");
 #ifdef PDCP_DEBUG
-         LOG_D(PDCP,"[pdcp_fifo_read_input_sdus] Received PC5-S message, msg_type: %d)\n", pdcp_data_header->msg_type);
-         LOG_D(PDCP,"[pdcp_fifo_read_input_sdus] Received PC5-S message, rbid: %d)\n", pdcp_data_header->rb_id);
-         LOG_D(PDCP,"[pdcp_fifo_read_input_sdus] Received PC5-S message, data_size: %d)\n", pdcp_data_header->data_size);
-         LOG_D(PDCP,"[pdcp_fifo_read_input_sdus] Received PC5-S message, inst: %d)\n", pdcp_data_header->inst);
+         LOG_D(PDCP,"Received PC5-S message, traffic_type: %d)\n", pdcp_data_header->traffic_type);
+         LOG_D(PDCP,"Received PC5-S message, rbid: %d)\n", pdcp_data_header->rb_id);
+         LOG_D(PDCP,"Received PC5-S message, data_size: %d)\n", pdcp_data_header->data_size);
+         LOG_D(PDCP,"Received PC5-S message, inst: %d)\n", pdcp_data_header->inst);
+         LOG_D(PDCP,"Received PC5-S message,sourceL2Id: 0x%08x\n)\n", pdcp_data_header->sourceL2Id);
+         LOG_D(PDCP,"Received PC5-S message,destinationL1Id: 0x%08x\n)\n", pdcp_data_header->destinationL2Id);
 
-         sl_pc5s_msg_recv = calloc(1, sizeof(sidelink_pc5s_element));
-         memcpy((void *)sl_pc5s_msg_recv, (void *)receive_buf, sizeof(sidelink_pc5s_element));
-         if (pdcp_data_header->msg_type == SL_DIRECT_COMMUNICATION_REQUEST){
-            LOG_D(PDCP,"[pdcp_fifo_read_input_sdus] Received DirectCommunicationRequest (PC5-S), seqno: %d)\n", sl_pc5s_msg_recv->pc5sPrimitive.pc5s_direct_communication_req.sequenceNumber);
-            LOG_D(PDCP,"[pdcp_fifo_read_input_sdus] Received DirectCommunicationRequest (PC5-S), ipAddressConfig: %d)\n", sl_pc5s_msg_recv->pc5sPrimitive.pc5s_direct_communication_req.ipAddressConfig);
-         }
 #endif
 
 #ifdef OAI_EMU
@@ -1282,81 +1274,6 @@ pdcp_pc5_socket_init() {
 
 }
 
-
-
-//--------------------------------------------------------
-void *pdcp_pc5_socket_thread_fct(void *arg)
-{
-
-   int prose_addr_len;
-   char send_buf[BUFSIZE];
-   char receive_buf[BUFSIZE];
-   int optval; // flag value for setsockopt
-   int n; // message byte size
-   sidelink_pc5s_element *sl_pc5s_msg_recv = NULL;
-   sidelink_pc5s_element *sl_pc5s_msg_send = NULL;
-   uint32_t sourceL2Id;
-   uint32_t groupL2Id;
-   module_id_t         module_id;
-
-   module_id = 0 ; //hardcoded for testing only
-
-   LOG_I(PDCP,"*****************[pdcp_pc5_socket_thread_fct]**************\n");
-   //from the main program, listen for the incoming messages from control socket (ProSe App)
-   prose_addr_len = sizeof(prose_pdcp_addr);
-
-   while (1) {
-      LOG_I(RRC,"[pdcp_pc5_socket_thread_fct]: Listening to incoming connection from ProSe App \n");
-      // receive a message from ProSe App
-      memset(receive_buf, 0, BUFSIZE);
-      n = recvfrom(pdcp_pc5_sockfd, receive_buf, BUFSIZE, 0,
-            (struct sockaddr *) &prose_pdcp_addr, &prose_addr_len);
-      if (n < 0){
-         LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n");
-         exit(EXIT_FAILURE);
-      }
-
-      sl_pc5s_msg_recv = calloc(1, sizeof(sidelink_pc5s_element));
-      memcpy((void *)sl_pc5s_msg_recv, (void *)receive_buf, sizeof(sidelink_pc5s_element));
-
-      //process the message (in reality, we don't need to do that, thus, forward to other ue)
-
-     // LOG_I(RRC,"[pdcp_pc5_socket_thread_fct]: Received DirectCommunicationRequest (PC5-S) on socket from ProSe App (msg type: %d)\n", sl_pc5s_msg_recv->type);
-
-      //TODO: get SL_UE_STATE from lower layer
-      /*
-         LOG_I(RRC,"[rrc_control_socket_thread_fct]: Send UEStateInformation to ProSe App \n");
-         memset(send_buf, 0, BUFSIZE);
-
-         sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element));
-         sl_ctrl_msg_send->type = UE_STATUS_INFO;
-         sl_ctrl_msg_send->sidelinkPrimitive.ue_state = UE_STATE_OFF_NETWORK; //off-network
-         memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element));
-         free(sl_ctrl_msg_send);
-
-         prose_addr_len = sizeof(prose_app_addr);
-         n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len);
-         if (n < 0) {
-            LOG_E(RRC, "ERROR: Failed to send to ProSe App\n");
-            exit(EXIT_FAILURE);
-         }
-
-
-#ifdef DEBUG_CTRL_SOCKET
-         struct sidelink_ctrl_element *ptr_ctrl_msg = NULL;
-         ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf;
-         LOG_I(RRC,"[rrc_control_socket_thread_fct][UEStateInformation] msg type: %d\n",ptr_ctrl_msg->type);
-         LOG_I(RRC,"[rrc_control_socket_thread_fct][UEStateInformation] UE state: %d\n",ptr_ctrl_msg->sidelinkPrimitive.ue_state);
-#endif
-       */
-
-   }
-   free (sl_pc5s_msg_recv);
-   return 0;
-}
-
-
-
 #endif
 
 
diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c
index 99712cc5d2fc7e749109280c01a59e808b1e28e1..e8ff5fc7ac66d9917f1624e0615a5ee94899e70a 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/common.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/common.c
@@ -248,6 +248,13 @@ ue_ip_common_ip2wireless(
   //---------------------------------------------------------------------------
   struct pdcp_data_req_header_s     pdcph;
   ue_ip_priv_t                     *priv_p=netdev_priv(ue_ip_dev[instP]);
+#ifdef Rel14
+  ipversion_t         *ipv_p             = NULL;
+  unsigned int         hard_header_len   = 0;
+  unsigned char       *src_addr          = 0;
+  unsigned char       *dst_addr          = 0;
+#endif
+
 #ifdef LOOPBACK_TEST
   int i;
 #endif
@@ -278,6 +285,37 @@ ue_ip_common_ip2wireless(
 
   pdcph.inst       = instP;
 
+  //pass source/destination IP addresses to PDCP header
+  hard_header_len = ue_ip_dev[instP]->hard_header_len;
+  ipv_p = (ipversion_t *)((void *)&(skb_pP->data[hard_header_len]));
+
+  switch (ipv_p->version) {
+  case 6:
+    printk("[UE_IP_DRV][%s] receive IPv6 message\n",__FUNCTION__);
+    //TODO
+    break;
+
+  case 4:
+     src_addr = (unsigned char *)&((struct iphdr *)&skb_pP->data[hard_header_len])->saddr;
+    if (src_addr) {
+      printk("[UE_IP_DRV][%s] Source %d.%d.%d.%d\n",__FUNCTION__, src_addr[0],src_addr[1],src_addr[2],src_addr[3]);
+    }
+    dst_addr = (unsigned char *)&((struct iphdr *)&skb_pP->data[hard_header_len])->daddr;
+    if (dst_addr) {
+      printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, dst_addr[0],dst_addr[1],dst_addr[2],dst_addr[3]);
+    }
+
+    //get Ipv4 address and pass to PCDP header
+    printk("[UE_IP_DRV] source Id: 0x%08x\n",pdcph.sourceL2Id );
+    printk("[UE_IP_DRV] destinationL2Id Id: 0x%08x\n",pdcph.destinationL2Id );
+    pdcph.sourceL2Id = ntohl( ((struct iphdr *)&skb_pP->data[hard_header_len])->saddr) & 0x00FFFFFF;
+    pdcph.destinationL2Id = ntohl( ((struct iphdr *)&skb_pP->data[hard_header_len])->daddr) & 0x00FFFFFF;
+    break;
+
+  default:
+     break;
+  }
+
 
   bytes_wrote = ue_ip_netlink_send((char *)&pdcph,UE_IP_PDCPH_SIZE);
 #ifdef OAI_DRV_DEBUG_SEND
diff --git a/openair2/NETWORK_DRIVER/UE_IP/local.h b/openair2/NETWORK_DRIVER/UE_IP/local.h
index ac3b0409954daab75466448b14a1727c94d76ada..976222967d326d885dc02288b12562e7bc953665 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/local.h
+++ b/openair2/NETWORK_DRIVER/UE_IP/local.h
@@ -89,6 +89,10 @@ typedef struct pdcp_data_req_header_s {
   sdu_size_t          data_size;
   signed int          inst;
   ip_traffic_type_t   traffic_type;
+#ifdef Rel14
+  uint32_t sourceL2Id;
+  uint32_t destinationL2Id;
+#endif
 } pdcp_data_req_header_t;
 
 typedef struct pdcp_data_ind_header_s {
@@ -96,6 +100,10 @@ typedef struct pdcp_data_ind_header_s {
   sdu_size_t          data_size;
   signed int          inst;
   ip_traffic_type_t   dummy_traffic_type;
+#ifdef Rel14
+  uint32_t sourceL2Id;
+  uint32_t destinationL2Id;
+#endif
 } pdcp_data_ind_header_t;
 
 
diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h
index 7aac2e8938eab9d7206b63a0c7a624cdd9c5b75e..e5a171501cbe319065014f3e2fe139b8014e092f 100644
--- a/openair2/RRC/LITE/defs.h
+++ b/openair2/RRC/LITE/defs.h
@@ -87,7 +87,7 @@
 #define GROUP_COMMUNICATION_RELEASE_RSP     8
 #define PC5S_ESTABLISH_REQ                  9
 #define PC5S_ESTABLISH_RSP                  10
-#define PC5_DISCOVERY_MESSAGE          	    11
+#define PC5_DISCOVERY_MESSAGE          	  11
 
 
 #define PC5_DISCOVERY_PAYLOAD_SIZE	    29