From c7c8057fa211943c65e11820fcd0446ab8756195 Mon Sep 17 00:00:00 2001 From: Tien-Thinh Nguyen <tien-thinh.nguyen@eurecom.fr> Date: Wed, 6 Dec 2017 23:02:39 +0100 Subject: [PATCH] integrate RRC control socket --- openair2/RRC/LITE/defs.h | 85 ++++++++++ openair2/RRC/LITE/proto.h | 6 + openair2/RRC/LITE/rrc_UE.c | 231 +++++++++++++++++++++++++++ targets/RT/USER/lte-softmodem-stub.c | 9 ++ 4 files changed, 331 insertions(+) diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index 5952a03d31d..ccea22330b5 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -47,6 +47,91 @@ #include "LAYER2/MAC/defs.h" +//TTN-for D2D +#define CONTROL_SOCKET_PORT_NO 8888 +#define DEBUG_CTRL_SOCKET +#define BUFSIZE 1024 +#define CONTROL_SOCKET_PORT_NO 8888 + +//netlink +//#define DEBUG_PDCP +#define UE_IP_PDCP_NETLINK_ID 31 +#define PDCP_PID 1 +#define NETLINK_HEADER_SIZE 16 +#define SL_DEFAULT_RAB_ID 1 +#define SLRB_ID 11 + +#define MAX_PAYLOAD 1024 /* maximum payload size*/ + +#define UE_STATE_NOTIFICATION_INTERVAL 50 + +#define IPV4_ADDR "%u.%u.%u.%u" +#define IPV4_ADDR_FORMAT(aDDRESS) \ + (uint8_t)((aDDRESS) & 0x000000ff), \ + (uint8_t)(((aDDRESS) & 0x0000ff00) >> 8 ), \ + (uint8_t)(((aDDRESS) & 0x00ff0000) >> 16), \ + (uint8_t)(((aDDRESS) & 0xff000000) >> 24) + + +//----------------------------------------------------- +// header for Control socket + +//Primitives +#define SESSION_INIT_REQ 1 +#define UE_STATUS_INFO 2 +#define GROUP_COMMUNICATION_ESTABLISH_REQ 3 +#define GROUP_COMMUNICATION_ESTABLISH_RSP 4 +#define DIRECT_COMMUNICATION_ESTABLISH_REQ 5 +#define DIRECT_COMMUNICATION_ESTABLISH_RSP 6 +#define GROUP_COMMUNICATION_RELEASE_REQ 7 +#define GROUP_COMMUNICATION_RELEASE_RSP 8 + +typedef enum { + UE_STATE_OFF_NETWORK, + UE_STATE_ON_NETWORK +} SL_UE_STATE_t; + +typedef enum { + GROUP_COMMUNICATION_RELEASE_OK = 0, + GROUP_COMMUNICATION_RELEASE_FAILURE +} Group_Communication_Status_t; + +struct GroupCommunicationEstablishReq { + uint8_t type; //0 - rx, 1 - tx + uint32_t sourceL2Id; + uint32_t groupL2Id; + uint32_t groupIpAddress; + uint8_t pppp; +}; + +struct DirectCommunicationEstablishReq { + uint32_t sourceL2Id; + uint32_t destinationL2Id; +}; + +struct sidelink_ctrl_element { + unsigned short type; + union { + struct GroupCommunicationEstablishReq group_comm_establish_req; + struct DirectCommunicationEstablishReq direct_comm_estblish_req; + Group_Communication_Status_t group_comm_release_rsp; + //struct DirectCommunicationReleaseReq direct_comm_release_req; + SL_UE_STATE_t ue_state; + int slrb_id; + + } sidelinkPrimitive; +}; + +//global variables +extern struct sockaddr_in clientaddr; +extern int slrb_id; +extern pthread_mutex_t slrb_mutex; + +//the thread function +void *send_UE_status_notification(void *); + +//end TTN + //#include "COMMON/openair_defs.h" #ifndef USER_MODE #include <rtai.h> diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h index 46ab00cbd3a..059b54c80eb 100644 --- a/openair2/RRC/LITE/proto.h +++ b/openair2/RRC/LITE/proto.h @@ -180,6 +180,12 @@ void rrc_ue_process_sidelink_radioResourceConfig( SL_CommConfig_r12_t* sl_CommConfig, SL_DiscConfig_r12_t* sl_DiscConfig); +/** \brief Init control socket to listen to incoming packets from ProSe App + * + */ +void +rrc_control_socket_init(); + // eNB/CH RRC Procedures diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 1ffed72dc5f..15ed542dc14 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -88,6 +88,15 @@ #include "SIMULATION/TOOLS/defs.h" // for taus +//TTN - for D2D +#define D2D_MODE //enable d2d +int ctrl_sock_fd; +#define BUFSIZE 1024 +struct sockaddr_in prose_app_addr; +int slrb_id; +pthread_mutex_t slrb_mutex; +static void *rrc_control_socket_thread_fct(void *arg); +//end TTN #ifdef PHY_EMUL extern EMULATION_VARS *Emul_vars; @@ -5105,3 +5114,225 @@ rrc_ue_process_sidelink_radioResourceConfig( } } } + +#ifdef D2D_MODE +//----------------------------------------------------------- +void +rrc_control_socket_init(){ + + struct sockaddr_in rrc_ctrl_socket_addr; + pthread_attr_t attr; + struct sched_param sched_param; + int optval; // flag value for setsockopt + int n; // message byte size + + //init the mutex + //pthread_mutex_init(&slrb_mutex, NULL); + + // create the control socket + ctrl_sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (ctrl_sock_fd == -1) { + LOG_E(RRC,"[rrc_control_socket_init] :Error opening socket %d (%d:%s)\n",ctrl_sock_fd,errno, strerror(errno)); + exit(EXIT_FAILURE); + } + // if (ctrl_sock_fd < 0) + // error("ERROR: Failed on opening socket"); + optval = 1; + setsockopt(ctrl_sock_fd, SOL_SOCKET, SO_REUSEADDR, + (const void *)&optval , sizeof(int)); + + //build the server's address + bzero((char *) &rrc_ctrl_socket_addr, sizeof(rrc_ctrl_socket_addr)); + rrc_ctrl_socket_addr.sin_family = AF_INET; + rrc_ctrl_socket_addr.sin_addr.s_addr = htonl(INADDR_ANY); + rrc_ctrl_socket_addr.sin_port = htons(CONTROL_SOCKET_PORT_NO); + // associate the parent socket with a port + if (bind(ctrl_sock_fd, (struct sockaddr *) &rrc_ctrl_socket_addr, + sizeof(rrc_ctrl_socket_addr)) < 0) { + LOG_E(RRC,"[rrc_control_socket_init] ERROR: Failed on binding the socket\n"); + exit(1); + } + //create thread to listen to incoming packets + if (pthread_attr_init(&attr) != 0) { + LOG_E(RRC, "[rrc_control_socket_init]Failed to initialize pthread attribute for ProSe -> RRC communication (%d:%s)\n", + errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + sched_param.sched_priority = 10; + + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setschedparam(&attr, &sched_param); + + pthread_t rrc_control_socket_thread; + + if (pthread_create(&rrc_control_socket_thread, &attr, rrc_control_socket_thread_fct, NULL) != 0) { + LOG_E(RRC, "[rrc_control_socket_init]Failed to create new thread for RRC/ProSeApp communication (%d:%s)\n", + errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + pthread_setname_np( rrc_control_socket_thread, "RRC Control Socket" ); + +} + +//-------------------------------------------------------- +static void *rrc_control_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 + struct sidelink_ctrl_element *sl_ctrl_msg_recv = NULL; + struct sidelink_ctrl_element *sl_ctrl_msg_send = NULL; + + + //from the main program, listen for the incoming messages from control socket (ProSe App) + prose_addr_len = sizeof(prose_app_addr); + int enable_notification = 1; + while (1) { + LOG_I(RRC,"[rrc_control_socket_thread_fct]: Listening to incoming connection from ProSe App \n"); + // receive a message from ProSe App + memset(receive_buf, 0, BUFSIZE); + n = recvfrom(ctrl_sock_fd, receive_buf, BUFSIZE, 0, + (struct sockaddr *) &prose_app_addr, &prose_addr_len); + if (n < 0){ + LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n"); + exit(EXIT_FAILURE); + } + //TODO: should store the address of ProSeApp [UE_rrc_inst] to be able to send UE state notification to the App + + + //sl_ctrl_msg_recv = (struct sidelink_ctrl_element *) receive_buf; + sl_ctrl_msg_recv = calloc(1, sizeof(struct sidelink_ctrl_element)); + memcpy((void *)sl_ctrl_msg_recv, (void *)receive_buf, sizeof(struct sidelink_ctrl_element)); + + //process the message + switch (sl_ctrl_msg_recv->type) { + case SESSION_INIT_REQ: +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[rrc_control_socket_thread_fct]: Received SessionInitializationRequest on socket from ProSe App (msg type: %d)\n", sl_ctrl_msg_recv->type); +#endif + //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 + + /* if (enable_notification > 0) { + //create thread to send status notification (for testing purpose, status notification will be sent e.g., every 20 seconds) + pthread_t notification_thread; + if( pthread_create( ¬ification_thread , NULL , send_UE_status_notification , (void*) &sockfd) < 0) + error("ERROR: could not create thread"); + } + enable_notification = 0; + */ + break; + + case GROUP_COMMUNICATION_ESTABLISH_REQ: +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[rrc_control_socket_thread_fct][GroupCommunicationEstablishReq] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_I(RRC,"[rrc_control_socket_thread_fct][GroupCommunicationEstablishReq] type: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.type); + LOG_I(RRC,"[rrc_control_socket_thread_fct][GroupCommunicationEstablishReq] source Id: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.sourceL2Id); + LOG_I(RRC,"[rrc_control_socket_thread_fct][GroupCommunicationEstablishReq] group Id: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupL2Id); + LOG_I(RRC,"[rrc_control_socket_thread_fct][GroupCommunicationEstablishReq] group IP Address: " IPV4_ADDR "\n",IPV4_ADDR_FORMAT(sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.groupIpAddress)); +#endif + // configure lower layers PDCP/MAC/PHY for this communication + + LOG_I(RRC,"[rrc_control_socket_thread_fct]Send GroupCommunicationEstablishResp 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 = 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) { +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[rrc_control_socket_thread_fct][GroupCommunicationEstablishReq] PPPP: %d\n",sl_ctrl_msg_recv->sidelinkPrimitive.group_comm_establish_req.pppp); +#endif + 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; + } + + 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,"[rrc_control_socket_thread_fct][GroupCommunicationEstablishResponse] msg type: %d\n",ptr_ctrl_msg->type); + LOG_I(RRC,"[rrc_control_socket_thread_fct][GroupCommunicationEstablishResponse] slrb_id: %d\n",ptr_ctrl_msg->sidelinkPrimitive.slrb_id); +#endif + break; + case GROUP_COMMUNICATION_RELEASE_REQ: + printf("-----------------------------------\n"); +#ifdef DEBUG_CTRL_SOCKET + LOG_I(RRC,"[rrc_control_socket_thread_fct][GroupCommunicationReleaseRequest] Received on socket from ProSe App (msg type: %d)\n",sl_ctrl_msg_recv->type); + LOG_I(RRC,"[rrc_control_socket_thread_fct][GroupCommunicationReleaseRequest] Slrb Id: %i\n",sl_ctrl_msg_recv->sidelinkPrimitive.slrb_id); +#endif + LOG_I(RRC,"[rrc_control_socket_thread_fct]Send GroupCommunicationReleaseResponse 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 = GROUP_COMMUNICATION_RELEASE_RSP; + //if the requested id exists -> release this ID + if (sl_ctrl_msg_recv->sidelinkPrimitive.slrb_id == slrb_id) { + sl_ctrl_msg_send->sidelinkPrimitive.group_comm_release_rsp = GROUP_COMMUNICATION_RELEASE_OK; + // pthread_mutex_lock(&slrb_mutex); + slrb_id = 0; //Reset slrb_id + //pthread_mutex_unlock(&slrb_mutex); + } else { + sl_ctrl_msg_send->sidelinkPrimitive.group_comm_release_rsp = GROUP_COMMUNICATION_RELEASE_FAILURE; + } + 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); + } + break; + + default: + break; + } + } + free (sl_ctrl_msg_recv); + return 0; +} + + +#endif diff --git a/targets/RT/USER/lte-softmodem-stub.c b/targets/RT/USER/lte-softmodem-stub.c index d9ed9f408f8..768ceaf7a0d 100644 --- a/targets/RT/USER/lte-softmodem-stub.c +++ b/targets/RT/USER/lte-softmodem-stub.c @@ -96,6 +96,8 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "UTIL/OTG/otg_vars.h" #endif +#define D2D_MODE + #if defined(ENABLE_ITTI) #include "intertask_interface_init.h" #include "create_tasks.h" @@ -1065,6 +1067,13 @@ int main( int argc, char **argv ) #endif #endif +//TTN for D2D +#ifdef D2D_MODE + printf ("RRC control socket\n"); + rrc_control_socket_init(); +#endif + + #if !defined(ENABLE_ITTI) // to make a graceful exit when ctrl-c is pressed signal(SIGSEGV, signal_handler); -- GitLab