diff --git a/d2d_emulator_setup.txt b/d2d_emulator_setup.txt index 57990226af5ba04459cd17e17d69983ed66ab1a6..ef904066bc28d55eb345f9957e8751498c31e95e 100644 --- a/d2d_emulator_setup.txt +++ b/d2d_emulator_setup.txt @@ -1,7 +1,7 @@ Scenario 1 : Off-network UE2UE link SynchREF UE (UE1) -UE1(eth0 - 10.10.10.1)--------UE2(eth0 - 10.10.10.2) +UE1(eth0 - 10.10.10.1)--------UE2(eno1 - 10.10.10.2) Here's an example of /etc/network/interfaces configuration for UE1 auto eth0 @@ -36,58 +36,72 @@ OAI build/execute UE1: - sudo ifconfig oip0 10.0.0.1 - - sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.1 -j MARK --set-mark 3 + - sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3 - (if necessary) sudo route add default gw 10.10.10.1 eth0 UE2: - - sudo ifconfig oip1 10.0.0.2 - - sudo iptables -A POSTROUTING -t mangle -o oip1 -d 224.0.0.1 -j MARK --set-mark 3 - - (if necessary) sudo route add default gw 10.10.10.1 eth0 + - sudo ifconfig oip0 10.0.0.2 + - sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3 + - (if necessary) sudo route add default gw 10.10.10.1 eno1 UE1 and UE2: Get and build vencore_app from d2d-l3-stub (branch: l3_stub) - gcc -I . vencore_app.c -o vencore_app -lpthread + -------------------------------- TEST ONE-TO-MANY Run UE1 then UE2, for example: -UE1: sudo ./lte-softmodem-stub -U --emul_iface eth0 -UE2: sudo ./lte-softmodem-stub -U --emul_iface eno1 +UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0 +UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1 Test with Ping -- Sender - UE1: ping -I oip0 224.0.0.1 +- Sender - UE1: ping -I oip0 224.0.0.3 - Receiver - UE2: using wireshark Test with Iperf -- Sender - UE1: iperf -c 224.0.0.1 -u -b 0.1M --bind 10.0.0.1 -t 100 -- Receiver - UE2: sudo ./mcreceive 224.0.0.1 5001 +- Sender - UE1: iperf -c 224.0.0.3 -u -b 0.1M --bind 10.0.0.1 -t 100 +- Receiver - UE2: sudo ./mcreceive 224.0.0.3 5001 Filter the incomming packets according to GroupL2Id: receiver (one-to-many) can discard the packets if it doesn't belong to this group. For the moment, both sender and receiver use the same set of Ids (hardcoded) UE1 (sender) - - sudo ./lte-softmodem-stub -U --emul_iface eth0 + - sudo ./lte-softmodem-stub -U --emul-iface eth0 - ./vencore_app #send the sourceL2Id, groupL2Id to OAI - - ping -I oip0 224.0.0.1 + - ping -I oip0 224.0.0.3 UE2(receiver) - - sudo ./lte-softmodem-stub -U --emul_iface eno1 + - sudo ./lte-softmodem-stub -U --emul-iface eno1 #we can see the incomming packets from OAI log, however, cannot see from Wireshark -> they are discarded at MAC layer - ./vencore_app #we can see the packets appearing in Wireshark -------------------------------------- -TEST PC5-S (UE1 -sender, UE2 - receiver) +TEST PC5-S (UE1 -sender, UE2 - receiver) and PC5-U for ONE-TO-ONE scenario +Configure UE1/UE2 +UE1: + - sudo ifconfig oip0 10.0.0.1 + - sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.2 -j MARK --set-mark 3 + - sudo route add default gw 10.10.10.1 eth0 +UE2: + - sudo ifconfig oip0 10.0.0.2 + - sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.1 -j MARK --set-mark 3 + - sudo route add default gw 10.10.10.1 eno1 + step 1: -- UE1: sudo ./lte-softmodem-stub -U --emul_iface eth0 +- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0 step 2: -- UE2: sudo ./lte-softmodem-stub -U --emul_iface eno1 +- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1 - UE2: ./vencore_app -r #listen to incomming message from PC5-S step 3: - UE1: ./vencore_app -s #send a message via PC5-S (e.g., DirectCommunicationRequest) + +Generate unicast traffic +UE1: ping -I oip0 10.0.0.2 -------------------------------------- TEST PC5-D step 1: -- UE1: sudo ./lte-softmodem-stub -U --emul_iface eth0 +- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0 - UE1: ./vencore_app -d #send a PC5-Discovery-Announcement via PC5D step 2: -- UE2: sudo ./lte-softmodem-stub -U --emul_iface eno1 +- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1 - UE2: ./vencore_app -d #send a PC5-Discovery-Announcement via PC5D diff --git a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c index 1ba724976fabdd87b82c623ee50ea9b43cb8cbfb..8cf9e13212244ec7e1ab7350c1228deff9b1d5e0 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c @@ -113,7 +113,7 @@ multicast_link_init(void) if (multicast_if != NULL) { if (setsockopt(group_list[group].socket, SOL_SOCKET,SO_BINDTODEVICE, - multicast_if, 4) < 0) { + multicast_if, strlen(multicast_if)) < 0) { LOG_E(EMU, "[MULTICAST] ERROR : setsockopt:SO_BINDTODEVICE on interface %s, exiting ...\n", multicast_if); diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index bc7486b5231e60af214532ec81d9a0fca42fa588..4e772546d98775aff2b46ba4b9fcf2fa1e13699e 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -1249,6 +1249,8 @@ rrc_mac_config_req_ue( //for D2D #if defined(Rel10) || defined(Rel14) + int j = 0; + int k = 0; switch (config_action) { case CONFIG_ACTION_ADD: if (sourceL2Id){ @@ -1257,14 +1259,32 @@ rrc_mac_config_req_ue( } if (destinationL2Id) { LOG_I(MAC,"[UE %d] Configure destination L2Id 0x%08x\n", Mod_idP, *destinationL2Id ); - int j = 0; - int i = 0; - for (i=0; i< MAX_NUM_DEST; i++) { - if ((UE_mac_inst[Mod_idP].destinationList[i] == 0) && (j == 0)) j = i+1; - if (UE_mac_inst[Mod_idP].destinationList[i] == *destinationL2Id) break; //destination already exists! + for (k=0; k< MAX_NUM_DEST; k++) { + if ((UE_mac_inst[Mod_idP].destinationList[k] == 0) && (j == 0)) j = k+1; + if (UE_mac_inst[Mod_idP].destinationList[k] == *destinationL2Id) break; //destination already exists! + } + if ((k == MAX_NUM_DEST) && (j > 0)) { + UE_mac_inst[Mod_idP].destinationList[j-1] = *destinationL2Id; + // UE_mac_inst[Mod_idP].numCommFlows++; + } + for (k=0; k< MAX_NUM_DEST; k++) { + LOG_I(MAC,"[UE %d] destination %d L2Id 0x%08x\n", Mod_idP,k,UE_mac_inst[Mod_idP].destinationList[k] ); + } + } + //store list of LCIDs for SL + if (logicalChannelIdentity >0 ){ + j = 0; + for (k=0; k< MAX_NUM_LCID; k++) { + if ((UE_mac_inst[Mod_idP].SL_LCID[k] == 0) && (j == 0)) j = k+1; + if (UE_mac_inst[Mod_idP].SL_LCID[k] == logicalChannelIdentity) break; //LCID already exists! + } + if ((k == MAX_NUM_LCID) && (j > 0)) { + UE_mac_inst[Mod_idP].SL_LCID[j-1] = logicalChannelIdentity; + UE_mac_inst[Mod_idP].numCommFlows++; + } + for (k=0; k< MAX_NUM_LCID; k++) { + LOG_I(MAC,"[UE %d] logical channel %d channel id %d\n", Mod_idP,k,UE_mac_inst[Mod_idP].SL_LCID[k] ); } - if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[Mod_idP].destinationList[j-1] = *destinationL2Id; - UE_mac_inst[Mod_idP].numCommFlows++; } break; case CONFIG_ACTION_REMOVE: diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index febae955d2ca7e6f2a767d76bd82d5daf048c3a9..6d61d8e92b484d68cb8807f5bceb809659436723 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -1355,6 +1355,7 @@ typedef struct { //List of destinations uint32_t destinationList[MAX_NUM_DEST]; uint8_t numCommFlows; + uint32_t SL_LCID[MAX_NUM_LCID]; #endif /// pointer to TDD Configuration (NULL for FDD) diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 2687f6eb263bd635532899300401f556e440eb47..ee6d7a832741de8b74c6701168b5c61460c8d0f7 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -848,12 +848,17 @@ void ue_send_sl_sdu(module_id_t module_idP, //filter incoming packet based on destination address destinationL2Id = (longh->DST07<<16) | (longh->DST815 <<8) | (longh->DST1623); LOG_I( MAC, "[DestinationL2Id: 0x%08x] \n", destinationL2Id ); + //in case of 1-n communication, verify that UE belongs to that group + int i=0; + for (i=0; i< MAX_NUM_DEST; i++) + if (UE_mac_inst[module_idP].destinationList[i] == destinationL2Id) break; //match the destinationL2Id with UE L2Id or groupL2ID - if (!((destinationL2Id == UE_mac_inst[module_idP].sourceL2Id) | (destinationL2Id == UE_mac_inst[module_idP].groupL2Id))){ + if (!((destinationL2Id == UE_mac_inst[module_idP].sourceL2Id) | (i < MAX_NUM_DEST))){ LOG_I( MAC, "[Destination Id is neither matched with Source Id nor with Group Id, drop the packet!!! \n"); return; } + if (longh->F==1) { rlc_sdu_len = ((longh->L_MSB<<8)&0x7F00)|(longh->L_LSB&0xFF); rlc_sdu = sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG); @@ -3225,7 +3230,7 @@ SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_ UE_MAC_INST *ue = &UE_mac_inst[module_idP]; int rvtab[4] = {0,2,3,1}; int sdu_length; - uint8_t sl_lcids[2] = {3, 10}; //list of lcids for SL - hardcoded + //uint8_t sl_lcids[2] = {3, 10}; //list of lcids for SL - hardcoded int i = 0; // Note: this is hard-coded for now for the default SL configuration (4 SF PSCCH, 36 SF PSSCH) @@ -3235,19 +3240,21 @@ SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_ if ((absSF%40) == 0) { // fill PSCCH data later in first subframe of SL period ue->sltx_active = 0; - for (i = 0; i < 2; i++){ - for (int j = 0; j < ue->numCommFlows; j++){ - if ((ue->sourceL2Id > 0) && (ue->destinationList[j] >0) ){ - rlc_status = mac_rlc_status_ind(module_idP, 0x1234,0,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, - sl_lcids[i], 0xFFFF, ue->sourceL2Id, ue->destinationList[j]); - if (rlc_status.bytes_in_buffer > 2){ - LOG_I(MAC,"SFN.SF %d.%d: Scheduling for %d bytes in Sidelink buffer\n",frameP,subframeP,rlc_status.bytes_in_buffer); - // Fill in group id for off-network communications - ue->sltx_active = 1; - //store LCID, destinationL2Id - ue->slsch_lcid = sl_lcids[i]; - ue->destinationL2Id = ue->destinationList[j]; - break; + for (i = 0; i < MAX_NUM_LCID; i++){ + if (ue->SL_LCID[i] > 0) { + for (int j = 0; j < ue->numCommFlows; j++){ + if ((ue->sourceL2Id > 0) && (ue->destinationList[j] >0) ){ + rlc_status = mac_rlc_status_ind(module_idP, 0x1234,0,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, + ue->SL_LCID[i], 0xFFFF, ue->sourceL2Id, ue->destinationList[j]); + if (rlc_status.bytes_in_buffer > 2){ + LOG_I(MAC,"SFN.SF %d.%d: Scheduling for %d bytes in Sidelink buffer\n",frameP,subframeP,rlc_status.bytes_in_buffer); + // Fill in group id for off-network communications + ue->sltx_active = 1; + //store LCID, destinationL2Id + ue->slsch_lcid = ue->SL_LCID[i]; + ue->destinationL2Id = ue->destinationList[j]; + break; + } } } } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 61f5c5ec87f60bde92ee3917ebe230566f6d95e9..7548f1d1befca617e5b546f883caf08385e479dd 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -419,7 +419,7 @@ 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 +#define PC5_SIGNALLING_PAYLOAD_SIZE 100 //should be updated with a correct value int pdcp_pc5_sockfd; struct sockaddr_in prose_ctrl_addr; struct sockaddr_in prose_pdcp_addr; @@ -433,7 +433,7 @@ typedef struct { ip_traffic_type_t traffic_type; uint32_t sourceL2Id; uint32_t destinationL2Id; -} __attribute__((__packed__)) pdcp_data_header_t; +} __attribute__((__packed__)) pc5s_header_t; //new PC5S-message typedef struct { @@ -442,7 +442,7 @@ typedef struct { //example of PC5-S messages typedef struct { - pdcp_data_header_t pdcp_data_header; + pc5s_header_t pc5s_header; union { uint8_t status; PC5SignallingMessage pc5_signalling_message; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index abefd0b7c7e8bec56a0e2f6c080dbd62a1153d46..c0340f7bd73e6355391602d5ed972dc5f72b53f2 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -209,12 +209,12 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) #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 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); - 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); + LOG_D(PDCP,"Received PC5S message, header traffic_type: %d)\n", sl_pc5s_msg_recv->pc5s_header.traffic_type); + LOG_D(PDCP,"Received PC5S message, header rb_id: %d)\n", sl_pc5s_msg_recv->pc5s_header.rb_id); + LOG_D(PDCP,"Received PC5S message, header data_size: %d)\n", sl_pc5s_msg_recv->pc5s_header.data_size); + LOG_D(PDCP,"Received PC5S message, header inst: %d)\n", sl_pc5s_msg_recv->pc5s_header.inst); + LOG_D(PDCP,"Received PC5-S message, sourceL2Id: 0x%08x\n)\n", sl_pc5s_msg_recv->pc5s_header.sourceL2Id); + LOG_D(PDCP,"Received PC5-S message, destinationL1Id: 0x%08x\n)\n", sl_pc5s_msg_recv->pc5s_header.destinationL2Id); free(sl_pc5s_msg_recv); #endif memset(send_buf, 0, BUFSIZE); @@ -430,7 +430,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) uint32_t sourceL2Id; uint32_t groupL2Id; module_id_t module_id = 0; - pdcp_data_header_t *pdcp_data_header; + pc5s_header_t *pc5s_header; #endif # if defined(PDCP_USE_NETLINK_QUEUES) @@ -575,15 +575,15 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) // exit(EXIT_FAILURE); // } if (bytes_received > 0) { - pdcp_data_header = calloc(1, sizeof(pdcp_data_header_t)); - memcpy((void *)pdcp_data_header, (void *)receive_buf, sizeof(pdcp_data_header_t)); + pc5s_header = calloc(1, sizeof(pc5s_header_t)); + memcpy((void *)pc5s_header, (void *)receive_buf, sizeof(pc5s_header_t)); - if (pdcp_data_header->traffic_type == TRAFFIC_PC5S_SESSION_INIT){ + if (pc5s_header->traffic_type == TRAFFIC_PC5S_SESSION_INIT){ //send reply to ProSe app 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.traffic_type = TRAFFIC_PC5S_SESSION_INIT; + sl_pc5s_msg_send->pc5s_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)); @@ -593,56 +593,56 @@ 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->traffic_type == TRAFFIC_PC5S_SIGNALLING) { //if containing PC5-S message -> send to other UE + } else if (pc5s_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,"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); + LOG_D(PDCP,"Received PC5-S message, traffic_type: %d)\n", pc5s_header->traffic_type); + LOG_D(PDCP,"Received PC5-S message, rbid: %d)\n", pc5s_header->rb_id); + LOG_D(PDCP,"Received PC5-S message, data_size: %d)\n", pc5s_header->data_size); + LOG_D(PDCP,"Received PC5-S message, inst: %d)\n", pc5s_header->inst); + LOG_D(PDCP,"Received PC5-S message,sourceL2Id: 0x%08x\n)\n", pc5s_header->sourceL2Id); + LOG_D(PDCP,"Received PC5-S message,destinationL1Id: 0x%08x\n)\n", pc5s_header->destinationL2Id); #endif #ifdef OAI_EMU // overwrite function input parameters, because only one netlink socket for all instances - if (pdcp_data_header->inst < oai_emulation.info.nb_enb_local) { + if (pc5s_header->inst < oai_emulation.info.nb_enb_local) { ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ENB_FLAG_YES; - ctxt.module_id = pdcp_data_header.inst + oai_emulation.info.first_enb_local; - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_data_header->rb_id / maxDRB + oai_emulation.info.first_ue_local]; - rab_id = pdcp_data_header->rb_id % maxDRB; + ctxt.module_id = pc5s_header.inst + oai_emulation.info.first_enb_local; + ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pc5s_header->rb_id / maxDRB + oai_emulation.info.first_ue_local]; + rab_id = pc5s_header->rb_id % maxDRB; } else { ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ENB_FLAG_NO; - ctxt.module_id = pdcp_data_header->inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; + ctxt.module_id = pc5s_header->inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; - rab_id = pdcp_data_header->rb_id % maxDRB; + rab_id = pc5s_header->rb_id % maxDRB; } CHECK_CTXT_ARGS(&ctxt); AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); - /*LGpdcp_read_header.inst = (pdcp_data_header.inst >= oai_emulation.info.nb_enb_local) ? \ - pdcp_data_header.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : - pdcp_data_header.inst + oai_emulation.info.first_enb_local;*/ + /*LGpdcp_read_header.inst = (pc5s_header.inst >= oai_emulation.info.nb_enb_local) ? \ + pc5s_header.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : + pc5s_header.inst + oai_emulation.info.first_enb_local;*/ #else // OAI_EMU /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ - // pdcp_data_header.inst = 0; + // pc5s_header.inst = 0; //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ctxt_cpy.enb_flag; - LOG_I(PDCP, "[PDCP] pdcp_data_header->rb_id = %d\n", pdcp_data_header->rb_id); + LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %d\n", pc5s_header->rb_id); if (ctxt_cpy.enb_flag) { ctxt.module_id = 0; - rab_id = pdcp_data_header->rb_id % maxDRB; + rab_id = pc5s_header->rb_id % maxDRB; ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index]; } else { ctxt.module_id = 0; - rab_id = pdcp_data_header->rb_id % maxDRB; + rab_id = pc5s_header->rb_id % maxDRB; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; } #endif @@ -672,15 +672,15 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) #ifdef PDCP_DEBUG LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", ctxt.frame, - pdcp_data_header->inst, + pc5s_header->inst, bytes_received, - pdcp_data_header->rb_id); + pc5s_header->rb_id); LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", ctxt.frame, - pdcp_data_header->inst, - pdcp_data_header->rb_id, - pdcp_data_header->data_size, + pc5s_header->inst, + pc5s_header->rb_id, + pc5s_header->data_size, ctxt.module_id, ctxt.rnti, rab_id); @@ -692,10 +692,10 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) 0, MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_data_header.inst, - pdcp_data_header.rb_id, + pc5s_header.inst, + pc5s_header.rb_id, rab_id, - pdcp_data_header.data_size); + pc5s_header.data_size); pdcp_data_req( &ctxt, @@ -703,12 +703,12 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, - pdcp_data_header->data_size, + pc5s_header->data_size, (unsigned char *)receive_buf, PDCP_TRANSMISSION_MODE_DATA #ifdef Rel14 - ,&pdcp_data_header->sourceL2Id - ,&pdcp_data_header->destinationL2Id + ,&pc5s_header->sourceL2Id + ,&pc5s_header->destinationL2Id #endif ); } else { @@ -719,16 +719,16 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) 0, MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_data_header.inst, - pdcp_data_header.rb_id, + pc5s_header.inst, + pc5s_header.rb_id, rab_id, - pdcp_data_header.data_size); + pc5s_header.data_size); LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, - pdcp_data_header->inst, - pdcp_data_header->rb_id, - pdcp_data_header->data_size, + pc5s_header->inst, + pc5s_header->rb_id, + pc5s_header->data_size, ctxt.module_id, ctxt.rnti, rab_id, @@ -738,9 +738,9 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, - pdcp_data_header->inst, - pdcp_data_header->rb_id, - pdcp_data_header->data_size, + pc5s_header->inst, + pc5s_header->rb_id, + pc5s_header->data_size, ctxt.module_id, ctxt.rnti, DEFAULT_RAB_ID); @@ -750,10 +750,10 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) NULL,0, MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_data_header->inst, - pdcp_data_header->rb_id, + pc5s_header->inst, + pc5s_header->rb_id, DEFAULT_RAB_ID, - pdcp_data_header->data_size); + pc5s_header->data_size); pdcp_data_req ( &ctxt, @@ -761,12 +761,12 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) DEFAULT_RAB_ID, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, - pdcp_data_header->data_size, + pc5s_header->data_size, (unsigned char *)receive_buf, PDCP_TRANSMISSION_MODE_DATA #ifdef Rel14 - ,&pdcp_data_header->sourceL2Id - ,&pdcp_data_header->destinationL2Id + ,&pc5s_header->sourceL2Id + ,&pc5s_header->destinationL2Id #endif ); } diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 764378807873e5f731e805607fd4d7bfd7bdbf39..23fceb1e6075a6afdcc8d7c3d12f1d03c5ff6ecb 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -395,7 +395,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, rlc_mode = rlc_union_p->mode; } else { rlc_mode = RLC_MODE_NONE; - AssertFatal (0 , "RLC not configured key %ju\n", key); + //AssertFatal (0 , "RLC not configured key %ju\n", key); } if (MBMS_flagP == 0) { diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index a222ed35e6e1b8da4c4c6bb483f7abcc8f7d40b1..7354c50c02e0a374d9582a965d586a29b23f5865 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -101,7 +101,6 @@ typedef enum { } Group_Communication_Status_t; struct GroupCommunicationEstablishReq { - uint8_t type; //0 - rx, 1 - tx uint32_t sourceL2Id; uint32_t groupL2Id; uint32_t groupIpAddress; @@ -127,11 +126,12 @@ struct PC5SEstablishReq{ }; struct PC5SEstablishRsp{ - uint32_t sourceL2Id; - uint32_t destinationL2Id; - uint8_t status; + uint32_t slrbid_lcid28; + uint32_t slrbid_lcid29; + uint32_t slrbid_lcid30; }; + //PC5_DISCOVERY MESSAGE typedef struct { unsigned char payload[PC5_DISCOVERY_PAYLOAD_SIZE]; @@ -143,7 +143,7 @@ struct sidelink_ctrl_element { unsigned short type; union { struct GroupCommunicationEstablishReq group_comm_establish_req; - struct DirectCommunicationEstablishReq direct_comm_estblish_req; + struct DirectCommunicationEstablishReq direct_comm_establish_req; Group_Communication_Status_t group_comm_release_rsp; //struct DirectCommunicationReleaseReq direct_comm_release_req; SL_UE_STATE_t ue_state; diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index f44c5aa4a5660977cdfa380007c8b7ea191e4722..3db08ae79c23e85d3bd9c8ce7116f285479391c8 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -5498,6 +5498,16 @@ void *rrc_control_socket_thread_fct(void *arg) uint32_t sourceL2Id, groupL2Id, destinationL2Id; module_id_t module_id = 0; //hardcoded for testing only uint8_t type; + UE_RRC_INST *UE = NULL; + protocol_ctxt_t ctxt; + struct RLC_Config *DRB_rlc_config = NULL; + struct PDCP_Config *DRB_pdcp_config = NULL; + struct PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LogicalChannelConfig *DRB_lchan_config = NULL; + struct LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; + long *logicalchannelgroup_drb = NULL; + int j = 0; + int i = 0; //from the main program, listen for the incoming messages from control socket (ProSe App) prose_addr_len = sizeof(prose_app_addr); @@ -5566,7 +5576,6 @@ void *rrc_control_socket_thread_fct(void *arg) #ifdef DEBUG_CTRL_SOCKET LOG_I(RRC,"[GroupCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); - LOG_I(RRC,"[GroupCommunicationEstablishReq] type: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.type); LOG_I(RRC,"[GroupCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); LOG_I(RRC,"[GroupCommunicationEstablishReq] group Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); LOG_I(RRC,"[GroupCommunicationEstablishReq] group IP Address: " IPV4_ADDR "\n",IPV4_ADDR_FORMAT(sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupIpAddress)); @@ -5575,8 +5584,8 @@ void *rrc_control_socket_thread_fct(void *arg) //store sourceL2Id/groupL2Id UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; UE_rrc_inst[module_id].groupL2Id = groupL2Id; - int j = 0; - int i = 0; + j = 0; + i = 0; for (i=0; i< MAX_NUM_DEST; i++) { if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1; if (UE_rrc_inst[module_id].destinationList[i] == groupL2Id) break; //group already exists! @@ -5585,9 +5594,8 @@ void *rrc_control_socket_thread_fct(void *arg) // configure lower layers PDCP/MAC/PHY for this communication //Establish a new RBID/LCID for this communication - UE_RRC_INST *UE = &UE_rrc_inst[module_id]; // Establish a SLRB (using DRB 3 for now) - protocol_ctxt_t ctxt; + UE = &UE_rrc_inst[module_id]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); @@ -5599,34 +5607,21 @@ void *rrc_control_socket_thread_fct(void *arg) UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 - // TTN - Establish a new SLRB for PC5-S (using DRB 10 for now) - UE->DRB_config[0][1] = CALLOC(1,sizeof(struct DRB_ToAddMod)); - UE->DRB_config[0][1]->eps_BearerIdentity = CALLOC(1, sizeof(long)); - UE->DRB_config[0][1]->drb_Identity = 10; - UE->DRB_config[0][1]->eps_BearerIdentity = CALLOC(1, sizeof(long)); - // allowed value 5..15, value : x+4 - *(UE->DRB_config[0][1]->eps_BearerIdentity) = 10; - UE->DRB_config[0][1]->logicalChannelIdentity = CALLOC(1, sizeof(long)); - *(UE->DRB_config[0][1]->logicalChannelIdentity) = UE->DRB_config[0][1]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 - - struct RLC_Config *DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); - struct PDCP_Config *DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); - struct PDCP_Config__rlc_UM *PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); - struct LogicalChannelConfig *DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); - struct LogicalChannelConfig__ul_SpecificParameters - *DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); - long *logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); + DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); + PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); + DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); + DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; - UE->DRB_config[0][1]->rlc_Config = DRB_rlc_config; DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; - UE->DRB_config[0][1]->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; @@ -5640,7 +5635,6 @@ void *rrc_control_socket_thread_fct(void *arg) DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; - UE->DRB_config[0][1]->logicalChannelConfig = DRB_lchan_config; DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; @@ -5657,7 +5651,6 @@ void *rrc_control_socket_thread_fct(void *arg) UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); - ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][1]); rrc_pdcp_config_asn1_req(&ctxt, (SRB_ToAddModList_t *) NULL, @@ -5701,7 +5694,7 @@ void *rrc_control_socket_thread_fct(void *arg) #endif (MeasObjectToAddMod_t **)NULL, (MAC_MainConfig_t *)NULL, - 0, + 3, //LCID (struct LogicalChannelConfig *)NULL, (MeasGapConfig_t *)NULL, (TDD_Config_t *)NULL, @@ -5734,16 +5727,7 @@ void *rrc_control_socket_thread_fct(void *arg) memset(send_buf, 0, BUFSIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = GROUP_COMMUNICATION_ESTABLISH_RSP; - //in case of TX, assign a new SLRB and prepare for the filter - if (sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.type == 1) { - - sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = SLRB_ID; //slrb_id - //pthread_mutex_lock(&slrb_mutex); - slrb_id = SLRB_ID; - //pthread_mutex_unlock(&slrb_mutex); - } else{ //RX - sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = SL_DEFAULT_RAB_ID; - } + sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = 3; //slrb_id memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); @@ -5838,13 +5822,188 @@ void *rrc_control_socket_thread_fct(void *arg) break; + case DIRECT_COMMUNICATION_ESTABLISH_REQ: + sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.direct_comm_establish_req.sourceL2Id; + destinationL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.direct_comm_establish_req.destinationL2Id; + +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[DirectCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_I(RRC,"[DirectCommunicationEstablishReq] source Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); + LOG_I(RRC,"[DirectCommunicationEstablishReq] destination Id: 0x%08x\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); +#endif + + //store sourceL2Id/destinationL2Id + UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; + i = 0; + j = 0; + for (i=0; i< MAX_NUM_DEST; i++) { + if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1; + if (UE_rrc_inst[module_id].destinationList[i] == destinationL2Id) break; //destination already exists! + } + if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[module_id].destinationList[j-1] = destinationL2Id; + + // configure lower layers PDCP/MAC/PHY for this communication + //Establish a new RBID/LCID for this communication + // Establish a SLRB (using DRB 3 for now) + UE = &UE_rrc_inst[module_id]; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + + UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + UE->DRB_config[0][0]->drb_Identity = 3; + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + // allowed value 5..15, value : x+4 + *(UE->DRB_config[0][0]->eps_BearerIdentity) = 3; + UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 + + DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); + DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); + PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); + DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); + DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + + DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; + UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + /* avoid gcc warnings */ + (void)PDCP_rlc_UM; + + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + + UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); + ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); + + rrc_pdcp_config_asn1_req(&ctxt, + (SRB_ToAddModList_t *) NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*) NULL, + 0xff, NULL, NULL, NULL +#if defined(Rel10) || defined(Rel14) + , (PMCH_InfoList_r9_t *) NULL +#endif + ,NULL); + + + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#if defined(Rel10) || defined(Rel14) + ,(PMCH_InfoList_r9_t *)NULL + , 0, 0 +#endif + ); + + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#ifdef Rel14 + ,(PMCH_InfoList_r9_t *)NULL + , sourceL2Id, destinationL2Id +#endif + ); + + + //configure MAC with sourceL2Id/destinationL2Id + rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 + (RadioResourceConfigCommonSIB_t *)NULL, + (struct PhysicalConfigDedicated *)NULL, +#if defined(Rel10) || defined(Rel14) + (SCellToAddMod_r10_t *)NULL, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, +#endif + (MeasObjectToAddMod_t **)NULL, + (MAC_MainConfig_t *)NULL, + 3, //LCID + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *)NULL, + (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +#if defined(Rel10) || defined(Rel14) + ,0, + (MBSFN_AreaInfoList_r9_t *)NULL, + (PMCH_InfoList_r9_t *)NULL + +#endif +#ifdef CBA + , + 0, + 0 +#endif +#if defined(Rel10) || defined(Rel14) + ,CONFIG_ACTION_ADD, + &sourceL2Id, + &destinationL2Id +#endif + ); + + LOG_I(RRC,"Send DirectCommunicationEstablishResp 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 = DIRECT_COMMUNICATION_ESTABLISH_RSP; + sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = 3; //slrb_id + + 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 + ptr_ctrl_msg = (struct sidelink_ctrl_element *) send_buf; + LOG_I(RRC,"[DirectCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); + LOG_I(RRC,"[DirectCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); +#endif + break; + case PC5S_ESTABLISH_REQ: type = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type; sourceL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id; - #ifdef DEBUG_CTRL_SOCKET - LOG_I(RRC,"[PC5EstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); - LOG_I(RRC,"[PC5EstablishReq] type: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type); //RX/TX - LOG_I(RRC,"[PC5EstablishReq] source Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id); +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[PC5EstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_I(RRC,"[PC5EstablishReq] type: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.type); //RX/TX + LOG_I(RRC,"[PC5EstablishReq] source Id: 0x%08x \n",sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.sourceL2Id); #endif if (type > 0) { destinationL2Id = sl_ctrl_msg_recv->sidelinkPrimitive.pc5s_establish_req.destinationL2Id; @@ -5853,100 +6012,200 @@ void *rrc_control_socket_thread_fct(void *arg) #endif } - //store sourceL2Id, destinationL2Id + //store sourceL2Id/destinationL2Id if (type > 0) { //TX UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; - UE_rrc_inst[module_id].destinationL2Id = destinationL2Id; + j = 0; + i = 0; + for (i=0; i< MAX_NUM_DEST; i++) { + if ((UE_rrc_inst[module_id].destinationList[i] == 0) && (j == 0)) j = i+1; + if (UE_rrc_inst[module_id].destinationList[i] == destinationL2Id) break; //group already exists! + } + if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[module_id].destinationList[j-1] = destinationL2Id; + } else {//RX + UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; + } + + // configure lower layers PDCP/MAC/PHY for this communication + //Establish a new RBID/LCID for this communication + // Establish a SLRB (using DRB 10 for now) + UE = &UE_rrc_inst[module_id]; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + + UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + UE->DRB_config[0][0]->drb_Identity = 10; + UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); + // allowed value 5..15, value : x+4 + *(UE->DRB_config[0][0]->eps_BearerIdentity) = 10; + UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 + + DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); + DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); + PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); + DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); + DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + + DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; + UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + /* avoid gcc warnings */ + (void)PDCP_rlc_UM; + + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; - // configure lower layers PDCP/MAC/PHY + UE->DRB_config[0][0]->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); + ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); + + rrc_pdcp_config_asn1_req(&ctxt, + (SRB_ToAddModList_t *) NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*) NULL, + 0xff, NULL, NULL, NULL +#if defined(Rel10) || defined(Rel14) + , (PMCH_InfoList_r9_t *) NULL +#endif + ,NULL); + + + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#if defined(Rel10) || defined(Rel14) + ,(PMCH_InfoList_r9_t *)NULL + , 0, 0 +#endif + ); + + //TX + if (type > 0) { + rrc_rlc_config_asn1_req(&ctxt, + (SRB_ToAddModList_t*)NULL, + UE->DRB_configList, + (DRB_ToReleaseList_t*)NULL +#ifdef Rel14 + ,(PMCH_InfoList_r9_t *)NULL + , sourceL2Id, destinationL2Id +#endif + ); + + //configure MAC with sourceL2Id/groupL2ID rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, - #if defined(Rel10) || defined(Rel14) - (SCellToAddMod_r10_t *)NULL, - //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, - #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, - 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - #if defined(Rel10) || defined(Rel14) - ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL - - #endif - #ifdef CBA - , - 0, - 0 - #endif - #if defined(Rel10) || defined(Rel14) - ,CONFIG_ACTION_ADD, - &sourceL2Id, - &destinationL2Id - #endif - ); + (RadioResourceConfigCommonSIB_t *)NULL, + (struct PhysicalConfigDedicated *)NULL, +#if defined(Rel10) || defined(Rel14) + (SCellToAddMod_r10_t *)NULL, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, +#endif + (MeasObjectToAddMod_t **)NULL, + (MAC_MainConfig_t *)NULL, + 10, //LCID + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *)NULL, + (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +#if defined(Rel10) || defined(Rel14) + ,0, + (MBSFN_AreaInfoList_r9_t *)NULL, + (PMCH_InfoList_r9_t *)NULL +#endif +#ifdef CBA + , + 0, + 0 +#endif +#if defined(Rel10) || defined(Rel14) + ,CONFIG_ACTION_ADD, + &sourceL2Id, + &destinationL2Id +#endif + ); } else {//RX - UE_rrc_inst[module_id].sourceL2Id = sourceL2Id; - // configure lower layers PDCP/MAC/PHY - rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, - #if defined(Rel10) || defined(Rel14) - (SCellToAddMod_r10_t *)NULL, - //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, - #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, - 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - #if defined(Rel10) || defined(Rel14) - ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL - - #endif - #ifdef CBA - , - 0, - 0 - #endif - #if defined(Rel10) || defined(Rel14) - ,CONFIG_ACTION_ADD, - &sourceL2Id, - NULL - #endif - ); - } + //configure MAC with sourceL2Id/groupL2ID + rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 + (RadioResourceConfigCommonSIB_t *)NULL, + (struct PhysicalConfigDedicated *)NULL, +#if defined(Rel10) || defined(Rel14) + (SCellToAddMod_r10_t *)NULL, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, +#endif + (MeasObjectToAddMod_t **)NULL, + (MAC_MainConfig_t *)NULL, + 10, //LCID + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *)NULL, + (TDD_Config_t *)NULL, + (MobilityControlInfo_t *)NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +#if defined(Rel10) || defined(Rel14) + ,0, + (MBSFN_AreaInfoList_r9_t *)NULL, + (PMCH_InfoList_r9_t *)NULL +#endif +#ifdef CBA + , + 0, + 0 +#endif +#if defined(Rel10) || defined(Rel14) + ,CONFIG_ACTION_ADD, + &sourceL2Id, + NULL +#endif + ); + + } LOG_I(RRC,"Send PC5EstablishRsp 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 = PC5S_ESTABLISH_RSP; - sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.sourceL2Id = sourceL2Id; - sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.destinationL2Id = destinationL2Id; - sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.status = 1; + sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid28 = 10; + sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid29 = 10; + sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid30 = 10; memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); prose_addr_len = sizeof(prose_app_addr);