gnb_app.c 9.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*
                                gnb_app.c
                             -------------------
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
25 26 27
  AUTHOR  : Laurent Winckel, Sebastien ROUX, Lionel GAUTHIER, Navid Nikaein, WEI-TAI CHEN
  COMPANY : EURECOM, NTUST
  EMAIL   : Lionel.Gauthier@eurecom.fr and Navid Nikaein, kroempa@gmail.com
28 29 30 31 32 33 34 35 36 37
*/

#include <string.h>
#include <stdio.h>

#include "gnb_app.h"
#include "gnb_config.h"
#include "assertions.h"
#include "common/ran_context.h"

38
#include "common/utils/LOG/log.h"
39

cig's avatar
cig committed
40
#include "x2ap_eNB.h"
41 42 43 44 45
#include "intertask_interface.h"
#include "s1ap_eNB.h"
#include "sctp_eNB_task.h"
#include "gtpv1u_eNB_task.h"
#include "PHY/INIT/phy_init.h" 
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
46

47 48 49 50
extern unsigned char NB_gNB_INST;

extern RAN_CONTEXT_t RC;

51
#define GNB_REGISTER_RETRY_DELAY 10
52 53

/*------------------------------------------------------------------------------*/
54
static void configure_nr_rrc(uint32_t gnb_id)
55 56 57 58
{
  MessageDef *msg_p = NULL;
  //  int CC_id;

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
59
  msg_p = itti_alloc_new_message (TASK_GNB_APP, NRRRC_CONFIGURATION_REQ);
60

61
  if (RC.nrrrc[gnb_id]) {
62
    RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
63 64
    

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
65 66
    LOG_I(GNB_APP,"Sending configuration message to NR_RRC task\n");
    itti_send_msg_to_task (TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
67 68

  }
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
69
  else AssertFatal(0,"NRRRC context for gNB %d not allocated\n",gnb_id);
70 71 72
}

/*------------------------------------------------------------------------------*/
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
73 74

/*
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
75
static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties)
76
{
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
77
  uint32_t         gnb_id;
78
  MessageDef      *msg_p;
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
79
  uint32_t         register_gnb_pending = 0;
80

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
81
  for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
82
    {
83
      s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse
84

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
85
      // note:  there is an implicit relationship between the data structure and the message name 
86
      msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse
87

88
      RCconfig_NR_S1(msg_p, gnb_id);
89

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
90
      if (gnb_id == 0) RCconfig_nr_gtpu();
91

92
      s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
93
      LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);
94

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
95
      LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id));
96

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
97
      itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
98

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
99
      register_gnb_pending++;
100 101 102
    }
  }

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
103
  return register_gnb_pending;
104
}
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
105
*/
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

/*------------------------------------------------------------------------------*/
static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) {
  uint32_t         gnb_id;
  MessageDef      *msg_p;
  uint32_t         register_gnb_x2_pending = 0;

  for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
    {
      msg_p = itti_alloc_new_message (TASK_GNB_APP, X2AP_REGISTER_ENB_REQ);
      LOG_I(X2AP, "GNB_ID: %d \n", gnb_id);
      RCconfig_NR_X2(msg_p, gnb_id);
      itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
      register_gnb_x2_pending++;
    }
  }

  return register_gnb_x2_pending;
}

126 127

/*------------------------------------------------------------------------------*/
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
128
void *gNB_app_task(void *args_p)
129
{
130

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
131 132 133 134
  uint32_t                        gnb_nb = RC.nb_nr_inst; 
  uint32_t                        gnb_id_start = 0;
  uint32_t                        gnb_id_end = gnb_id_start + gnb_nb;
  uint32_t                        gnb_id;
135 136
  MessageDef                      *msg_p           = NULL;
  const char                      *msg_name        = NULL;
137 138 139 140 141
  instance_t                      instance;
  int                             result;
  /* for no gcc warnings */
  (void)instance;

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
142
  itti_mark_task_ready (TASK_GNB_APP);
143

144
  LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
145

146
  RCconfig_NR_L1();
147

148
  RCconfig_nr_macrlc();
149

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
150
  LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
151

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
152
  if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n");
153

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
154 155 156
  AssertFatal (gnb_nb <= RC.nb_nr_inst,
               "Number of gNB is greater than gNB defined in configuration file (%d/%d)!",
               gnb_nb, RC.nb_nr_inst);
157

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
158
  LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst);
159

160 161
  RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
  LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
162

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
163
  for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
164 165 166 167
    RC.nrrrc[gnb_id] = (gNB_RRC_INST*)malloc(sizeof(gNB_RRC_INST));
    LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end);
    memset((void *)RC.nrrrc[gnb_id],0,sizeof(gNB_RRC_INST));
    configure_nr_rrc(gnb_id);
168 169
  }

170 171
  if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
	  LOG_I(X2AP, "X2AP enabled \n");
laurent's avatar
laurent committed
172
	  __attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
173 174
  }

175
  if (EPC_MODE_ENABLED) {
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
176
  /* Try to register each gNB */
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
177 178
  //registered_gnb = 0;
  //register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
179
  } else {
180
  /* Start L2L1 task */
181 182 183
    msg_p = itti_alloc_new_message(TASK_GNB_APP, INITIALIZE_MESSAGE);
    itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p);
  }
184 185 186

  do {
    // Wait for a message
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
187
    itti_receive_msg (TASK_GNB_APP, &msg_p);
188 189 190 191 192 193

    msg_name = ITTI_MSG_NAME (msg_p);
    instance = ITTI_MSG_INSTANCE (msg_p);

    switch (ITTI_MSG_ID(msg_p)) {
    case TERMINATE_MESSAGE:
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
194
      LOG_W(GNB_APP, " *** Exiting GNB_APP thread\n");
195 196 197 198
      itti_exit_task ();
      break;

    case MESSAGE_TEST:
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
199
      LOG_I(GNB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p));
200 201
      break;

202

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
203
/*
204
    case S1AP_REGISTER_ENB_CNF:
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
205
      LOG_I(GNB_APP, "[gNB %d] Received %s: associated MME %d\n", instance, msg_name,
206 207
            S1AP_REGISTER_ENB_CNF(msg_p).nb_mme);

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
208 209
      DevAssert(register_gnb_pending > 0);
      register_gnb_pending--;
210

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
211
      // Check if at least gNB is registered with one MME 
212
      if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) {
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
213
        registered_gnb++;
214 215
      }

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
216
      // Check if all register gNB requests have been processed 
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
217 218
      if (register_gnb_pending == 0) {
        if (registered_gnb == gnb_nb) {
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
219
          // If all gNB are registered, start L2L1 task 
220 221
          MessageDef *msg_init_p;

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
222
          msg_init_p = itti_alloc_new_message (TASK_GNB_APP, INITIALIZE_MESSAGE);
223 224 225
          itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);

        } else {
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
226
          uint32_t not_associated = gnb_nb - registered_gnb;
227

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
228 229
          LOG_W(GNB_APP, " %d gNB %s not associated with a MME, retrying registration in %d seconds ...\n",
                not_associated, not_associated > 1 ? "are" : "is", GNB_REGISTER_RETRY_DELAY);
230

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
231
          // Restart the gNB registration process in GNB_REGISTER_RETRY_DELAY seconds 
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
232 233 234
          if (timer_setup (GNB_REGISTER_RETRY_DELAY, 0, TASK_GNB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
                           NULL, &gnb_register_retry_timer_id) < 0) {
            LOG_E(GNB_APP, " Can not start gNB register retry timer, use \"sleep\" instead!\n");
235

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
236
            sleep(GNB_REGISTER_RETRY_DELAY);
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
237
            // Restart the registration process 
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
238 239
            registered_gnb = 0;
            register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
240 241 242 243 244
          }
        }
      }

      break;
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
245
*/
246
    case S1AP_DEREGISTERED_ENB_IND:
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
247
      LOG_W(GNB_APP, "[gNB %d] Received %s: associated MME %d\n", instance, msg_name,
248 249 250 251 252 253
            S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme);

      /* TODO handle recovering of registration */
      break;

    case TIMER_HAS_EXPIRED:
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
254
      LOG_I(GNB_APP, " Received %s: timer_id %ld\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);
255

WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
256
      //if (TIMER_HAS_EXPIRED (msg_p).timer_id == gnb_register_retry_timer_id) {
257
        /* Restart the registration process */
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
258 259 260
      //  registered_gnb = 0;
      //  register_gnb_pending = gNB_app_register(gnb_id_start, gnb_id_end);//, gnb_properties_p);
      //}
261 262 263 264

      break;

    default:
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
265
      LOG_E(GNB_APP, "Received unexpected message %s\n", msg_name);
266 267 268 269 270 271 272 273 274 275
      break;
    }

    result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  } while (1);


  return NULL;
}