static void *gtpv1u_thread(void *args) { itti_mark_task_ready(TASK_GTPV1_U); MSC_START_USE(); while(1) { /* Trying to fetch a message from the message queue. * If the queue is empty, this function will block till a * message is sent to the task. */ MessageDef *received_message_p = NULL; itti_receive_msg(TASK_GTPV1_U, &received_message_p); DevAssert(received_message_p != NULL); switch (ITTI_MSG_ID(received_message_p)) { case TERMINATE_MESSAGE: { itti_exit_task(); } break; // DATA COMING FROM UDP case UDP_DATA_IND: { udp_data_ind_t *udp_data_ind_p; udp_data_ind_p = &received_message_p->ittiMsg.udp_data_ind; nwGtpv1uProcessUdpReq(gtpv1u_sgw_data.gtpv1u_stack, udp_data_ind_p->buffer, udp_data_ind_p->buffer_length, udp_data_ind_p->peer_port, udp_data_ind_p->peer_address); //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer); } break; case TIMER_HAS_EXPIRED: nwGtpv1uProcessTimeout(&received_message_p->ittiMsg.timer_has_expired.arg); break; default: { GTPU_ERROR("Unkwnon message ID %d:%s\n", ITTI_MSG_ID(received_message_p), ITTI_MSG_NAME(received_message_p)); } break; } itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p); received_message_p = NULL; } return NULL; }
//----------------------------------------------------------------------------- void *gtpv1u_eNB_task(void *args) { int rc = 0; instance_t instance; //const char *msg_name_p; rc = gtpv1u_eNB_init(); AssertFatal(rc == 0, "gtpv1u_eNB_init Failed"); itti_mark_task_ready(TASK_GTPV1_U); MSC_START_USE(); while(1) { /* Trying to fetch a message from the message queue. * If the queue is empty, this function will block till a * message is sent to the task. */ MessageDef *received_message_p = NULL; itti_receive_msg(TASK_GTPV1_U, &received_message_p); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_IN); DevAssert(received_message_p != NULL); instance = ITTI_MSG_INSTANCE(received_message_p); //msg_name_p = ITTI_MSG_NAME(received_message_p); switch (ITTI_MSG_ID(received_message_p)) { case GTPV1U_ENB_DELETE_TUNNEL_REQ: { gtpv1u_delete_s1u_tunnel(instance, &received_message_p->ittiMsg.Gtpv1uDeleteTunnelReq); } break; // DATA COMING FROM UDP case UDP_DATA_IND: { udp_data_ind_t *udp_data_ind_p; udp_data_ind_p = &received_message_p->ittiMsg.udp_data_ind; nwGtpv1uProcessUdpReq(gtpv1u_data_g.gtpv1u_stack, udp_data_ind_p->buffer, udp_data_ind_p->buffer_length, udp_data_ind_p->peer_port, udp_data_ind_p->peer_address); //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer); } break; // DATA TO BE SENT TO UDP case GTPV1U_ENB_TUNNEL_DATA_REQ: { gtpv1u_enb_tunnel_data_req_t *data_req_p = NULL; NwGtpv1uUlpApiT stack_req; NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; teid_t enb_s1u_teid = 0; teid_t sgw_s1u_teid = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_IN); data_req_p = >PV1U_ENB_TUNNEL_DATA_REQ(received_message_p); //ipv4_send_data(ipv4_data_p->sd, data_ind_p->buffer, data_ind_p->length); #if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 gtpv1u_eNB_write_dump_socket(&data_req_p->buffer[data_req_p->offset],data_req_p->length); #endif memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); hash_rc = hashtable_get(gtpv1u_data_g.ue_mapping, (uint64_t)data_req_p->rnti, (void**)>pv1u_ue_data_p); if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: while getting ue rnti %x in hashtable ue_mapping\n", data_req_p->rnti); } else { if ((data_req_p->rab_id >= GTPV1U_BEARER_OFFSET) && (data_req_p->rab_id <= max_val_DRB_Identity)) { enb_s1u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_eNB; sgw_s1u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_sgw; stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU; stack_req.apiInfo.sendtoInfo.teid = sgw_s1u_teid; stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].sgw_ip_addr; rc = nwGtpv1uGpduMsgNew( gtpv1u_data_g.gtpv1u_stack, sgw_s1u_teid, NW_FALSE, gtpv1u_data_g.seq_num++, data_req_p->buffer, data_req_p->length, data_req_p->offset, &(stack_req.apiInfo.sendtoInfo.hMsg)); if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uGpduMsgNew failed: 0x%x\n", rc); MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", enb_s1u_teid,sgw_s1u_teid,data_req_p->length); (void)enb_s1u_teid; /* avoid gcc warning "set but not used" */ } else { rc = nwGtpv1uProcessUlpReq(gtpv1u_data_g.gtpv1u_stack, &stack_req); if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: 0x%x\n", rc); MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", enb_s1u_teid,sgw_s1u_teid,data_req_p->length); } else { MSC_LOG_TX_MESSAGE( MSC_GTPU_ENB, MSC_GTPU_SGW, NULL, 0, MSC_AS_TIME_FMT" G-PDU ltid %u rtid %u size %u", 0,0, enb_s1u_teid, sgw_s1u_teid, data_req_p->length); } rc = nwGtpv1uMsgDelete(gtpv1u_data_g.gtpv1u_stack, stack_req.apiInfo.sendtoInfo.hMsg); if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc); } } } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_OUT); /* Buffer still needed, do not free it */ //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer); } break; case TERMINATE_MESSAGE: { if (gtpv1u_data_g.ue_mapping != NULL) { hashtable_destroy (gtpv1u_data_g.ue_mapping); } if (gtpv1u_data_g.teid_mapping != NULL) { hashtable_destroy (gtpv1u_data_g.teid_mapping); } itti_exit_task(); } break; case TIMER_HAS_EXPIRED: nwGtpv1uProcessTimeout(&received_message_p->ittiMsg.timer_has_expired.arg); break; default: { LOG_E(GTPU, "Unkwnon message ID %d:%s\n", ITTI_MSG_ID(received_message_p), ITTI_MSG_NAME(received_message_p)); } break; } rc = itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p); AssertFatal(rc == EXIT_SUCCESS, "Failed to free memory (%d)!\n", rc); received_message_p = NULL; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_OUT); } return NULL; }