//-----------------------------------------------------------------------------
void MIH_C_3GPP_ADDR_load_3gpp_str_address(ral_ue_instance_t instanceP, MIH_C_3GPP_ADDR_T* _3gpp_addr_pP, u_int8_t* str_pP)
//-----------------------------------------------------------------------------
{
  int           i, l;
  u_int8_t      val_temp;
  unsigned char address_3gpp[32];
  unsigned char buf[3];
  u_int8_t      _3gpp_byte_address[8];
  module_id_t   mod_id = instanceP - NB_eNB_INST;

  strcpy((char *)address_3gpp, (char *)str_pP);

  for(l=0; l<8; l++) {
    i=l*2;
    buf[0]= address_3gpp[i];
    buf[1]= address_3gpp[i+1];
    buf[2]= '\0';
    //sscanf((const char *)buf,"%02x", &val_temp);
    sscanf((const char *)buf,"%hhx", &val_temp);
    _3gpp_byte_address[l] = val_temp;
  }

  _3gpp_byte_address[7] += mod_id;
  MIH_C_3GPP_ADDR_set(_3gpp_addr_pP, _3gpp_byte_address, 8);
}
//---------------------------------------------------------------------------------------------------------------------
void eRAL_rx_rrc_ral_connection_establishment_indication(instance_t instanceP, MessageDef *msg_pP)
//---------------------------------------------------------------------------------------------------------------------
{
    MIH_C_LINK_TUPLE_ID_T link_tuple_id;
#ifdef USE_3GPP_ADDR_AS_LINK_ADDR
    uint8_t               ue_id_array[MIH_C_3GPP_ADDR_LENGTH];
    uint8_t               mn_link_addr[MIH_C_3GPP_ADDR_LENGTH];
    uint64_t              ue_id; //EUI-64
    int                   i;
#endif
    module_id_t           mod_id = instanceP;

    // The LINK_ID contains the MN LINK_ADDR
    link_tuple_id.choice                                            = MIH_C_LINK_TUPLE_ID_CHOICE_LINK_ADDR;
    link_tuple_id.link_id.link_type                                 = MIH_C_WIRELESS_LTE;
#ifdef USE_3GPP_ADDR_AS_LINK_ADDR
    link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR;

    memset(ue_id_array, 0, MIH_C_3GPP_ADDR_LENGTH);
    ue_id = (uint64_t)RRC_RAL_CONNECTION_ESTABLISHMENT_IND(msg_pP).ue_id;
    for (i = 0; i < MIH_C_3GPP_ADDR_LENGTH; i++) {
        ue_id_array[MIH_C_3GPP_ADDR_LENGTH-1-i] = (ue_id & 0x00000000000000FF);
        ue_id = ue_id >> 8;
    }
    ueid2eui48(mn_link_addr, ue_id_array);
    MIH_C_3GPP_ADDR_set(&(link_tuple_id.link_id.link_addr._union._3gpp_addr), NULL, 8);

    // The optional LINK_ADDR contains a link address of PoA.
    eRAL_MIH_C_3GPP_ADDR_load_3gpp_str_address(mod_id, &link_tuple_id._union.link_addr._union._3gpp_addr, (uint8_t*)ENB_DEFAULT_3GPP_ADDRESS);
#else
#warning TO DO UE ID
    // preserve byte order of plmn id
    memcpy(link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val, &g_enb_ral_obj[mod_id].plmn_id, 3);
    link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id = g_enb_ral_obj[mod_id].cell_id;

    LOG_D(RAL_ENB, "PLMN ID %d.%d.%d\n",
        link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[0],
        link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[1],
        link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.plmn_id.val[2]);

    LOG_D(RAL_ENB, "CELL ID %d\n",
        link_tuple_id.link_id.link_addr._union._3gpp_3g_cell_id.cell_id);
#endif


    eRAL_send_link_up_indication(instanceP, &g_enb_ral_obj[instanceP].transaction_id,
            &link_tuple_id,
            NULL,   //MIH_C_LINK_ADDR_T       *old_arP,(Optional) Old Access Router link address.
            NULL,   //MIH_C_LINK_ADDR_T       *new_arP,(Optional) New Access Router link address.
            NULL,   //MIH_C_IP_RENEWAL_FLAG_T *flagP, (Optional) Indicates whether the MN needs to change IP Address in the new PoA.
            NULL);  //MIH_C_IP_MOB_MGMT_T     *mobil_mngtP, (Optional) Indicates the type of Mobility Management Protocol supported by the new PoA.

    g_enb_ral_obj[instanceP].transaction_id ++;

}
//---------------------------------------------------------------------------------------------------------------------
void eRAL_rx_rrc_ral_connection_reconfiguration_indication(instance_t instanceP, MessageDef *msg_pP)
//---------------------------------------------------------------------------------------------------------------------
{
  MIH_C_LINK_TUPLE_ID_T link_tuple_id;
  uint8_t               ue_id_array[MIH_C_3GPP_ADDR_LENGTH];
  uint8_t               mn_link_addr[MIH_C_3GPP_ADDR_LENGTH];
  uint64_t              ue_id; //EUI-64
  int                   i;
  module_id_t           mod_id = instanceP;

  // The LINK_ID contains the MN LINK_ADDR
  link_tuple_id.link_id.link_type                                 = MIH_C_WIRELESS_LTE;
  link_tuple_id.link_id.link_addr.choice                          = MIH_C_CHOICE_3GPP_ADDR;
  memset(ue_id_array, 0, MIH_C_3GPP_ADDR_LENGTH);
#warning "TO DO FIX UE_ID TYPE in rrc_ral_connection_establishment_ind_t"
  ue_id = (uint64_t)RRC_RAL_CONNECTION_ESTABLISHMENT_IND(msg_pP).ue_id;
  for (i = 0; i < MIH_C_3GPP_ADDR_LENGTH; i++) {
      ue_id_array[MIH_C_3GPP_ADDR_LENGTH-1-i] = (ue_id & 0x00000000000000FF);
      ue_id = ue_id >> 8;
  }
  ueid2eui48(mn_link_addr, ue_id_array);
  MIH_C_3GPP_ADDR_set(&(link_tuple_id.link_id.link_addr._union._3gpp_addr), NULL, 8);

  //The optional LINK_ADDR may contains a link address of PoA.
  link_tuple_id.choice = MIH_C_LINK_TUPLE_ID_CHOICE_NULL;

  eRAL_send_link_up_indication(instanceP, &g_enb_ral_obj[instanceP].transaction_id,
          &link_tuple_id,
          NULL,   //MIH_C_LINK_ADDR_T       *old_arP,(Optional) Old Access Router link address.
          NULL,   //MIH_C_LINK_ADDR_T       *new_arP,(Optional) New Access Router link address.
          NULL,   //MIH_C_IP_RENEWAL_FLAG_T *flagP, (Optional) Indicates whether the MN needs to change IP Address in the new PoA.
          NULL);  //MIH_C_IP_MOB_MGMT_T     *mobil_mngtP, (Optional) Indicates the type of Mobility Management Protocol supported by the new PoA.

  g_enb_ral_obj[mod_id].transaction_id ++;


}
//---------------------------------------------------------------------------
// poll for measures in NAS
void rallte_NAS_measures_polling(void){
//---------------------------------------------------------------------------
    MIH_C_LINK_GD_REASON_T      going_down_reason_code;
    MIH_C_LINK_DN_REASON_T      down_reason_code;
    MIH_C_TRANSACTION_ID_T      transaction_id;
    MIH_C_LINK_TUPLE_ID_T       link_identifier;
    MIH_C_LINK_DET_INFO_T       link_detected_info;
    MIH_C_UNSIGNED_INT2_T       time_interval;
    //MIH_C_LINK_PARAM_RPT_LIST_T link_parameters_report_list;

    IAL_process_DNAS_message(IO_OBJ_MEAS, IO_CMD_LIST, 0);

// hard-coded trigger for test
#ifdef MRALU_SIMU_LINKDOWN
    meas_counter ++;
    if (meas_counter == 4){
       ralpriv->curr_signal_level = ralpriv->curr_signal_level/10;
       IAL_integrate_measure(ralpriv->curr_signal_level, 0);
       DEBUG ("\n signal level %d , integrated new value : %d\n",ralpriv->curr_signal_level, ralpriv->integrated_meas_level[0]);
    }

    if (meas_counter == 5){
       ralpriv->curr_signal_level = 40;
       IAL_integrate_measure(ralpriv->curr_signal_level, 0);
       DEBUG ("\n signal level %d , integrated new value : %d\n",ralpriv->curr_signal_level, ralpriv->integrated_meas_level[0]);
    }
    if (meas_counter == 6){
       ralpriv->curr_signal_level = 0;
       IAL_integrate_measure(ralpriv->curr_signal_level, 0);
       DEBUG ("\n signal level %d , integrated new value : %d\n",ralpriv->curr_signal_level, ralpriv->integrated_meas_level[0]);
    }
#endif
    DEBUG ("signal level %d , integrated new value : %d , integrated old value :  (%d)\n",
              ralpriv->curr_signal_level,
              ralpriv->integrated_meas_level[0],
              ralpriv->prev_integrated_meas_level[0]);
//  condition still TBD - message dropped or level = 0
    if ((!ralpriv->curr_signal_level)  &&
        (ralpriv->link_to_be_detected == MIH_C_BOOLEAN_FALSE) &&
        (ralpriv->state != DISCONNECTED)
        ) {
        transaction_id                           = MIH_C_get_new_transaction_id();
        down_reason_code                         = MIH_C_LINK_DOWN_REASON_NO_RESOURCE;
        link_identifier.link_id.link_type        = MIH_C_WIRELESS_UMTS;
        link_identifier.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR;
        MIH_C_3GPP_ADDR_load_3gpp_str_address(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP);
        link_identifier.choice                   = MIH_C_LINK_TUPLE_ID_CHOICE_NULL;

        mRALlte_send_link_down_indication(&transaction_id,
                                          &link_identifier,
                                          NULL,
                                          &down_reason_code);

        ralpriv->link_to_be_detected = MIH_C_BOOLEAN_TRUE;
        // warning may be repeated several times
    } else if ((ralpriv->link_to_be_detected == MIH_C_BOOLEAN_FALSE) &&
               (ralpriv->curr_signal_level <= ralpriv->integrated_meas_level[0]) &&
               (ralpriv->integrated_meas_level[0] < ralpriv->prev_integrated_meas_level[0]) &&
               (ralpriv->integrated_meas_level[0] < PREDEFINED_LINK_GOING_DOWN_INDICATION_SIG_STRENGTH) &&
               (ralpriv->state != DISCONNECTED)
               ) {
        transaction_id                           = MIH_C_get_new_transaction_id();

        link_identifier.link_id.link_type        = MIH_C_WIRELESS_UMTS;
        link_identifier.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR;
        MIH_C_3GPP_ADDR_load_3gpp_str_address(&link_identifier.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP);
        link_identifier.choice                   = MIH_C_LINK_TUPLE_ID_CHOICE_NULL;

        time_interval                            = (MIH_C_UNSIGNED_INT2_T)0; // unknown

        going_down_reason_code                   = MIH_C_LINK_GOING_DOWN_REASON_LINK_PARAMETER_DEGRADING;

        mRALlte_send_link_going_down_indication(&transaction_id,
                                                &link_identifier,
                                                &time_interval,
                                                &going_down_reason_code);

    } else if ((ralpriv->link_to_be_detected == MIH_C_BOOLEAN_TRUE) && (ralpriv->curr_signal_level > PREDEFINED_LINK_DETECTED_INDICATION_SIG_STRENGTH)) {
        transaction_id                           = MIH_C_get_new_transaction_id();
        // MIH_C_LINK_TUPLE_ID_T
        link_detected_info.link_tuple_id.link_id.link_type        = MIH_C_WIRELESS_UMTS;
        link_detected_info.link_tuple_id.link_id.link_addr.choice = (MIH_C_CHOICE_T)MIH_C_CHOICE_3GPP_ADDR;
        MIH_C_3GPP_ADDR_set(&link_detected_info.link_tuple_id.link_id.link_addr._union._3gpp_addr, (u_int8_t*)DEFAULT_ADDRESS_3GPP, strlen(DEFAULT_ADDRESS_3GPP));
        link_detected_info.link_tuple_id.choice                   = MIH_C_LINK_TUPLE_ID_CHOICE_NULL;
        // MIH_C_NETWORK_ID_T
        MIH_C_NETWORK_ID_set(&link_detected_info.network_id, (u_int8_t *)PREDEFINED_MIH_NETWORK_ID, strlen(PREDEFINED_MIH_NETWORK_ID));
        // MIH_C_NET_AUX_ID_T
        MIH_C_NET_AUX_ID_set(&link_detected_info.net_aux_id, (u_int8_t *)PREDEFINED_MIH_NETAUX_ID, strlen(PREDEFINED_MIH_NETAUX_ID));
        // MIH_C_SIG_STRENGTH_T
        link_detected_info.sig_strength.choice     = MIH_C_SIG_STRENGTH_CHOICE_PERCENTAGE;
        link_detected_info.sig_strength._union.percentage = ralpriv->curr_signal_level;
        // sinr
        link_detected_info.sinr = PREDEFINED_LINK_DETECTED_INDICATION_SINR;
        // MIH_C_LINK_DATA_RATE_T
        link_detected_info.link_data_rate = PREDEFINED_LINK_DETECTED_INDICATION_LINK_DATA_RATE;
        // MIH_C_LINK_MIHCAP_FLAG
        link_detected_info.link_mihcap_flag = MIH_C_BIT_EVENT_SERVICE_SUPPORTED    |
                                              MIH_C_BIT_COMMAND_SERVICE_SUPPORTED  |
                                              MIH_C_BIT_INFORMATION_SERVICE_SUPPORTED;
        // MIH_C_NET_CAPS_T
        link_detected_info.net_caps = MIH_C_BIT_NET_CAPS_QOS_CLASS0 |
                                      MIH_C_BIT_NET_CAPS_QOS_CLASS1 |
                                      MIH_C_BIT_NET_CAPS_INTERNET_ACCESS;


        mRALlte_send_link_detected_indication(&transaction_id, &link_detected_info);
        ralpriv->link_to_be_detected = MIH_C_BOOLEAN_FALSE;
    }
    // LG: TO DO CHECK IF INDEX IS 0
    mRALlte_check_thresholds_signal_strength(ralpriv->integrated_meas_level[0], ralpriv->prev_integrated_meas_level[0]);
}