/****************************************************************************
 **                                                                        **
 ** Name:  eRALlte_NAS_send_rb_release_request()                     **
 **                                                                        **
 ** Description: Sends Radio Bearer release request to the NAS driver.     **
 **                                                                        **
 ** Inputs:  mt_ix:   Mobile Terminal index                      **
 **      ch_ix:   Radio bearer channel index                 **
 **      Others:  g_sockd_nas, nas_rg_msg, nas_rg_request    **
 **                                                                        **
 ** Outputs:   None                                                      **
 **    Return:  -1 if the request message has not been     **
 **       successfully sent to the NAS driver.       **
 **       Otherwise, the number of bytes actually    **
 **       sent to the NAS driver.                    **
 **      Others:  None                                       **
 **                                                                        **
 ***************************************************************************/
int  eRALlte_NAS_send_rb_release_request(int mt_ix, int ch_ix)
{
  int rc = eRALlte_NAS_write_rb_release_request(mt_ix, ch_ix);

  if (!rc) {
    rc = send(g_sockd_nas, nas_rg_msg, nas_rg_request->length, 0);

    if (rc < 0) {
      ERR(": failed to send NAS_RG_MSG_RB_RELEASE_REQUEST (%d)\n", errno);
#ifdef MSCGEN_PYTOOL
      NOTICE("[MSC_MSG][%s][%s][--- NAS_RG_MSG_RB_RELEASE_REQUEST ---x][nas]\n", getTimeStamp4Log(), g_link_id);
#endif
    } else {
      DEBUG (" NAS_RG_MSG_RB_RELEASE_REQUEST sent to NAS (%d)\n", nas_rg_request->length);
#ifdef MSCGEN_PYTOOL
      NOTICE("[MSC_MSG][%s][%s][--- NAS_RG_MSG_RB_RELEASE_REQUEST --->][nas]\n", getTimeStamp4Log(), g_link_id);
#endif
    }
  }

  return rc;
}
/****************************************************************************
 **                                                                        **
 ** Name:  TQAL_process_NAS_message()                                **
 **                                                                        **
 ** Description: Sends messages to the NAS sublayer.                       **
 **                                                                        **
 ** Inputs:  ioctl_obj: ioctl object identifier                    **
 **    ioctl_cmd: ioctl command identifier                   **
 **    mt_ix:   Mobile Terminal index                      **
 **    ch_ix:   Radio Bearer channel index                 **
 **      Others:  g_sockd_nas, nas_rg_msg, nas_rg_request    **
 **                                                                        **
 ** Outputs:   None                                                      **
 **    Return:  0 if the message has been successfully     **
 **       sent to the NAS driver; -1 otherwise.      **
 **      Others:  nas_rg_msg                                 **
 **                                                                        **
 ***************************************************************************/
int TQAL_process_NAS_message(int ioctl_obj, int ioctl_cmd,
                             int mt_ix, int ch_ix)
{
  int rc = -1;
  char msg_name[64];

  memset(nas_rg_msg, 0, NAS_RG_NETL_MAXLEN);

  switch (ioctl_obj) {
  case IO_OBJ_STATS:
    /*
     * Statistics command
     */
    break;

  case IO_OBJ_CNX:

    /*
     * Connexion command
     */
    switch (ioctl_cmd) {
    case IO_CMD_LIST:
      strncpy(msg_name, "NAS_RG_MSG_CNX_STATUS_REQUEST", 64);
      rc = eRALlte_NAS_write_cnx_status_request(mt_ix);
      break;

    default:
      ERR(" %s : invalid ioctl command %d for object %d\n",
          __FUNCTION__, ioctl_cmd, ioctl_obj);
      break;
    }

    break;

  case IO_OBJ_RB:

    /*
     * Radio Bearer command
     */
    switch (ioctl_cmd) {
    case IO_CMD_ADD:
      strncpy(msg_name, "NAS_RG_MSG_RB_ESTABLISH_REQUEST", 64);
      rc = eRALlte_NAS_write_rb_establish_request(mt_ix, ch_ix);
      break;

    case IO_CMD_DEL:
      strncpy(msg_name, "NAS_RG_MSG_RB_RELEASE_REQUEST", 64);
      rc = eRALlte_NAS_write_rb_release_request(mt_ix, ch_ix);
      break;

    case IO_CMD_LIST:
      strncpy(msg_name, "NAS_RG_MSG_RB_LIST_REQUEST", 64);
      rc = eRALlte_NAS_write_rb_list_request(mt_ix);
      break;

    default:
      ERR(" %s : invalid ioctl command %d for object %d\n",
          __FUNCTION__, ioctl_cmd, ioctl_obj);
      break;
    }

    break;

  case IO_OBJ_MC:

    /*
     * Multicast command
     */
    switch (ioctl_cmd) {
    case IO_CMD_ADD:
      break;

    case IO_CMD_DEL:
      break;

    default:
      ERR(" %s : invalid ioctl command %d for object %d\n",
          __FUNCTION__, ioctl_cmd, ioctl_obj);
      break;
    }

    break;

  default:
    ERR(" %s : invalid ioctl object %d\n", __FUNCTION__, ioctl_obj);
    break;
  }

  if (!rc) {
    rc = send(g_sockd_nas, nas_rg_msg, nas_rg_request->length, 0);

    if (rc < 0) {
      ERR(": failed to send %s (%d)\n", msg_name, errno);
#ifdef MSCGEN_PYTOOL
      NOTICE("[MSC_MSG][%s][%s][--- %s ---x][nas]\n",
             getTimeStamp4Log(), g_link_id, msg_name);
#endif
    } else {
      DEBUG (" %s sent to NAS (%d)\n", msg_name, nas_rg_request->length);
#ifdef MSCGEN_PYTOOL
      NOTICE("[MSC_MSG][%s][%s][--- %s --->][nas]\n",
             getTimeStamp4Log(), g_link_id, msg_name);
#endif
    }
  }

  return rc;
}
/****************************************************************************
 **                                                                        **
 ** Name:  eRALlte_NAS_process_message()                             **
 **                                                                        **
 ** Description: Processes messages received from the NAS sublayer.        **
 **                                                                        **
 ** Inputs:  None                                                      **
 **      Others:  g_sockd_nas, nas_rg_msg                    **
 **                                                                        **
 ** Outputs:   None                                                      **
 **    Return:  0 if the received message has been         **
 **       successfully processed; -1 otherwise.      **
 **      Others:                                             **
 **                                                                        **
 ***************************************************************************/
int eRALlte_NAS_process_message(void)
{
  int rc = 0;
  int n;

  n = recv(g_sockd_nas, nas_rg_msg, NAS_RG_NETL_MAXLEN, 0);

  if (n <= 0) {
    if (n < 0) {
      ERR(" %s : recv() failed (%d)\n", __FUNCTION__, errno);
    }

    rc = -1;
  } else if (n != nas_rg_reply->length) {
    ERR(" %s : invalid message length %d (should be %d)", __FUNCTION__,
        n, nas_rg_reply->length);
    rc = -1;
  }

  if (!rc) {
    rc = -1;

    switch (nas_rg_reply->type) {
      /*
       * Process Radio Bearer establish reply message
       */
    case NAS_RG_MSG_RB_ESTABLISH_REPLY:
      DEBUG(" NAS_RG_MSG_RB_ESTABLISH_REPLY received from NAS (%d)\n", nas_rg_reply->length);
#ifdef MSCGEN_PYTOOL
      NOTICE("[MSC_MSG][%s][nas][--- NAS_RG_MSG_RB_ESTABLISH_REPLY --->][%s]\n",
             getTimeStamp4Log(), g_link_id);
#endif
      rc = eRALlte_NAS_read_rb_establish_reply();
      break;

      /*
       * Process Radio Bearer release reply message
       */
    case NAS_RG_MSG_RB_RELEASE_REPLY:
      DEBUG(" NAS_RG_MSG_RB_RELEASE_REPLY received from NAS (%d)\n", nas_rg_reply->length);
#ifdef MSCGEN_PYTOOL
      NOTICE("[MSC_MSG][%s][nas][--- NAS_RG_MSG_RB_RELEASE_REPLY --->][%s]\n",
             getTimeStamp4Log(), g_link_id);
#endif
      rc = eRALlte_NAS_read_rb_release_reply();
      break;

    case NAS_RG_MSG_MT_MCAST_JOIN_REP:
      DEBUG(" NAS_RG_MSG_MT_MCAST_JOIN_REP received ");
      break;

    case NAS_RG_MSG_MT_MCAST_LEAVE_REP:
      DEBUG(" NAS_RG_MSG_MT_MCAST_LEAVE_REP received ");
      break;

      /*
       * Process connection status reply message
       */
    case NAS_RG_MSG_CNX_STATUS_REPLY:
      DEBUG(" NAS_RG_MSG_CNX_STATUS_REPLY received from NAS (%d)\n", nas_rg_reply->length);
#ifdef MSCGEN_PYTOOL
      NOTICE("[MSC_MSG][%s][nas][--- NAS_RG_MSG_CNX_STATUS_REPLY --->][%s]\n",
             getTimeStamp4Log(), g_link_id);
#endif
      rc = eRALlte_NAS_read_cnx_status_reply();
      break;

      /*
       * Process Radio Bearer list reply message
       */
    case NAS_RG_MSG_RB_LIST_REPLY:
      DEBUG(" NAS_RG_MSG_RB_LIST_REPLY received from NAS (%d)\n", nas_rg_reply->length);
#ifdef MSCGEN_PYTOOL
      NOTICE("[MSC_MSG][%s][nas][--- NAS_RG_MSG_RB_LIST_REPLY --->][%s]\n",
             getTimeStamp4Log(), g_link_id);
#endif
      rc = eRALlte_NAS_read_rb_list_reply();
      break;

    case NAS_RG_MSG_STATISTIC_REPLY:
      DEBUG(" NAS_RG_MSG_STATISTIC_REPLY received\n");
      break;

    case NAS_RG_MSG_MEASUREMENT_REPLY:
      DEBUG(" NAS_RG_MSG_MEASUREMENT_REPLY received\n");
      break;

    default:
      WARNING(" %s : invalid message Type %d\n",
              __FUNCTION__, nas_rg_reply->type);
      break;
    }

  }

  return rc;
}
Example #4
0
//---------------------------------------------------------------------------
int IAL_decode_NAS_message(void){
//---------------------------------------------------------------------------
    struct nas_ue_netl_reply *msgToRcve;
    int done=0, n, i;
    char *buffer;
    #ifdef MSCGEN_PYTOOL
    unsigned int              buffer_index;
    #endif
    n = recv(s_nas, message, NAS_UE_NETL_MAXLEN, 0);
    if (n <= 0) {
        if (n < 0) perror("RAL_process_DNAS_message : recv");
        done = 1;
    }

    if (!done) {
        DEBUG(" ");
        DEBUG("RAL_decode_NAS_message: primitive from NAS\n");
        msgToRcve = (struct nas_ue_netl_reply *) message;

        switch (msgToRcve->type) {

            case NAS_UE_MSG_CNX_ESTABLISH_REPLY:
                NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_CNX_ESTABLISH_REPLY --->][%s]\n", getTimeStamp4Log(), g_link_id);
                DEBUG("NAS_UE_MSG_CNX_ESTABLISH_REPLY received\n");
                ralpriv->pending_req_action = MIH_C_LINK_AC_TYPE_NONE;
                ralpriv->state = DISCONNECTED;
                if (msgToRcve->ialNASPrimitive.cnx_est_rep.status==0) {
                    ERR(" Connexion establishment failure: %d\n",msgToRcve->ialNASPrimitive.cnx_est_rep.status);
                    done = 1;
                    ralpriv->pending_req_status    = MIH_C_STATUS_SUCCESS;
                    ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_FAILURE;
                    //mRALu_send_link_switch_cnf();
                    //mRALte_send_link_action_confirm();
                 } else {
                    ralpriv->pending_req_status    = MIH_C_STATUS_SUCCESS;
                    ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_SUCCESS;
                    ralpriv->pending_req_flag = 1;
                    DEBUG(" Connexion establishment pending: pending_req_flag %d\n\n",ralpriv->pending_req_flag);
                }
                break;

            case NAS_UE_MSG_CNX_RELEASE_REPLY:
                NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_CNX_RELEASE_REPLY --->][%s]\n",
                       getTimeStamp4Log(),
                       g_link_id);
                DEBUG("NAS_UE_MSG_CNX_RELEASE_REPLY received\n");
                ralpriv->pending_req_action = MIH_C_LINK_AC_TYPE_NONE;
                if (msgToRcve->ialNASPrimitive.cnx_rel_rep.status>0){
                    ERR(" Connexion release failure: %d", msgToRcve->ialNASPrimitive.cnx_rel_rep.status);
                    done = 1;
                    ralpriv->pending_req_status    = MIH_C_STATUS_SUCCESS;
                    ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_FAILURE;
                } else {
                    ralpriv->pending_req_status    = MIH_C_STATUS_SUCCESS;
                    ralpriv->pending_req_ac_result = MIH_C_LINK_AC_RESULT_SUCCESS;
                    ralpriv->pending_req_flag = 1;
                    DEBUG(" Connexion establishment pending: pending_req_flag %d\n\n",ralpriv->pending_req_flag);
                }
                ralpriv->state = DISCONNECTED;
                //mRALu_send_link_switch_cnf();
                //added
                ralpriv->pending_req_flag = 0;
                ralpriv->cell_id = CONF_UNKNOWN_CELL_ID;
                break;

            case NAS_UE_MSG_CNX_LIST_REPLY:
                {
                    struct nas_ue_msg_cnx_list_reply *p;
                    NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_CNX_LIST_REPLY --->][%s]\n",
                            getTimeStamp4Log(),
                            g_link_id);
                    DEBUG("NAS_UE_MSG_CNX_LIST_REPLY received\n");
                    p = &(msgToRcve->ialNASPrimitive.cnx_list_rep);
                    DEBUG(" CellId\tIID4\tIID6\t\t\tnum_rb\tnsclass\tState\n");

                    DEBUG(" %u\t%u\t", p->cellid, p->iid4);
                    for (i=0;i<8;++i)
                    DEBUG("%02x", *((uint8_t *)p->iid6+i));
                    DEBUG("\t%u\t%u\t", p->num_rb, p->nsclassifier);
                    print_state(p->state);

                    ralpriv->nas_state = p->state ;
                    ralpriv->num_rb = p->num_rb;
                    ralpriv->cell_id = p->cellid ;
                    //IAL_return_NAS_StatAttach();
                }
                break;

           case NAS_UE_MSG_RB_LIST_REPLY:
             {
             struct nas_ue_msg_rb_list_reply *p;
             NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_RB_LIST_REPLY --->][%s]\n",
                       getTimeStamp4Log(),
                       g_link_id);
             DEBUG("NAS_UE_MSG_RB_LIST_REPLY received\n");
             p = &(msgToRcve->ialNASPrimitive.rb_list_rep);
             ralpriv->num_rb = p->num_rb;
             DEBUG("rab_id\t\tdscp\t\tQoS\t\tState\n");
             for(i=0; i<p->num_rb; i++){
               DEBUG("%u\t\t%u\t\t%u\t\t", p->RBList[i].rbId, p->RBList[i].dscp, p->RBList[i].QoSclass);
               print_state(p->RBList[i].state);
               ralpriv->rbId[i]= p->RBList[i].rbId;
               ralpriv->QoSclass[i] = p->RBList[i].QoSclass;
               ralpriv->dscp[i] = p->RBList[i].dscp;
             }
             }
             //IAL_return_NAS_StatRB();
             break;

           case NAS_UE_MSG_MEAS_REPLY:
             {
             struct nas_ue_msg_measure_reply *p;
             DEBUG("NAS_UE_MSG_MEASUREMENT_REPLY received\n");
             p = &(msgToRcve->ialNASPrimitive.meas_rep);
             #ifdef DEBUG_MRALU_MEASURES
             DEBUG("Measurement Report - Number of cells %d - Current cell %d\n", p->num_cells, ralpriv->cell_id);
             DEBUG("Cell_id\tMeasure\tProvider_id\n");
             #endif
             for (i=0;i<p->num_cells; i++){
                 #ifdef DEBUG_MRALU_MEASURES
                 DEBUG(" %d\t%d\t%d\n",p-> measures[i].cell_id,p-> measures[i].level,p-> measures[i].provider_id);
                 #endif
                 ralpriv->meas_cell_id[i] = p-> measures[i].cell_id;
                 IAL_integrate_measure(p-> measures[i].level, i);
                 ralpriv->provider_id[i] = p-> measures[i].provider_id;
             }
             #ifdef MSCGEN_PYTOOL
             memset(msc_gen_buff, 0, MSC_GEN_BUF_SIZE);
             buffer_index = 0;

             for (i=0;i<p->num_cells; i++){
                 buffer_index += sprintf(&msc_gen_buff[buffer_index], "\\nCell Id %d Level %d Provider %d",
                                        p-> measures[i].cell_id, p-> measures[i].level, p-> measures[i].provider_id);
                 ralpriv->meas_cell_id[i] = p-> measures[i].cell_id;
             }
             NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_MEASUREMENT_REPLY%s --->][%s]\n",
                getTimeStamp4Log(),
                msc_gen_buff,
                g_link_id);
             #endif
             //Temp
             #ifdef RAL_DUMMY
             ralpriv->num_measures = p->num_cells;  //TEMP- To be activated later
             #endif
             //ralpriv->meas_cell_id[0] = ralpriv->cell_id;
             }
             break;

           case NAS_UE_MSG_IMEI_REPLY:
             DEBUG("NAS_UE_MSG_IMEI_REPLY received\n");
             DEBUG("IMEI value received= %d %d\n", msgToRcve->ialNASPrimitive.l2id_rep.l2id[0], msgToRcve->ialNASPrimitive.l2id_rep.l2id[1]);
             //store the received value, to be used later
             ralpriv->ipv6_l2id[0] = msgToRcve->ialNASPrimitive.l2id_rep.l2id[0];
             ralpriv->ipv6_l2id[1] = msgToRcve->ialNASPrimitive.l2id_rep.l2id[1];
             buffer = (char *)(&ralpriv->ipv6_l2id[0]);
             DEBUG ("IMEI value: = ");
             for (i = 0; i < 8; i++) {
                 DEBUG ("-%hhx-", (unsigned char) buffer[i]);
             }
             DEBUG ("\n");
             #ifdef MSCGEN_PYTOOL
             memset(msc_gen_buff, 0, MSC_GEN_BUF_SIZE);
             buffer_index = 0;
             buffer_index = sprintf(&msc_gen_buff[buffer_index], "\\nIMEI:%hhx-%hhx-%hhx-%hhx-%hhx-%hhx-%hhx-%hhx",
                                    (unsigned char) buffer[0],(unsigned char) buffer[1],
                                    (unsigned char) buffer[2],(unsigned char) buffer[3],
                                    (unsigned char) buffer[4],(unsigned char) buffer[5],
                                    (unsigned char) buffer[6],(unsigned char) buffer[7]);
             NOTICE("[MSC_MSG][%s][nas][--- NAS_UE_MSG_IMEI_REPLY --->][%s]\n",
                       getTimeStamp4Log(),
                       g_link_id);
             #endif
             break;

           default:
             ERR("IAL_decode_NAS_message : invalid message Type %d\n",msgToRcve->type);
             done = 1;
        }
    }
    return done;
}
Example #5
0
//---------------------------------------------------------------------------
int IAL_process_DNAS_message(int ioctl_obj, int ioctl_cmd, int ioctl_cellid){
//---------------------------------------------------------------------------
  struct nas_ue_netl_request *msgToSend;
  int rc;


  msgToSend = (struct nas_ue_netl_request *) message;
  memset(message,0,NAS_UE_NETL_MAXLEN);

  NOTICE(" \n");

  switch (ioctl_obj){
      case IO_OBJ_CNX:
         switch (ioctl_cmd){
      /***/
            case IO_CMD_ADD:
              {
                NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_CNX_ESTABLISH_REQUEST --->][nas]\n",
                       getTimeStamp4Log(),
                       g_link_id);
                msgToSend->type=NAS_UE_MSG_CNX_ESTABLISH_REQUEST;
                msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request);
                msgToSend->ialNASPrimitive.cnx_req.cellid = ioctl_cellid;
                ralpriv->cell_id = ioctl_cellid;
                //
          			DEBUG("ioctl : Connection establishment requested\n");
                rc = 0;
              }
      		  break;
      /***/
            case IO_CMD_DEL:
              {

                NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_CNX_RELEASE_REQUEST --->][nas]\n",
                       getTimeStamp4Log(),
                       g_link_id);
          			msgToSend->type=NAS_UE_MSG_CNX_RELEASE_REQUEST;
                msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request);
                //
          			DEBUG("ioctl : Connexion release requested\n");
                rc = 0;
              }
      		  break;
      /***/
            case IO_CMD_LIST:
              {
                NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_CNX_LIST_REQUEST --->][nas]\n",
                       getTimeStamp4Log(),
                       g_link_id);
           			msgToSend->type=NAS_UE_MSG_CNX_LIST_REQUEST;
                msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request);
                //
          			DEBUG("ioctl : Connexion list requested\n");
                rc = 0;
              }
      		  break;
      /***/
          default:
          ERR("IAL_process_DNAS_message : invalid ioctl command %d\n",ioctl_cmd);
		      rc= -1;
      } //end switch ioctl_cmd
      break;

/***************************/
      case IO_OBJ_RB:
         switch (ioctl_cmd){
      /***/
            case IO_CMD_LIST:
              {
                NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_RB_LIST_REQUEST --->][nas]\n",
                       getTimeStamp4Log(),
                       g_link_id);
                msgToSend->type=NAS_UE_MSG_RB_LIST_REQUEST;
                msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request);
                //
          	DEBUG("ioctl : Radio bearer list requested\n");
                rc = 0;
               }
      		  break;
      /***/
            default:
            ERR("IAL_process_DNAS_message : invalid ioctl command %d\n",ioctl_cmd);
  		      rc= -1;
         } //end switch ioctl_cmd
      break;
/***************************/
      case IO_OBJ_MEAS:
        //
        {
            msgToSend->type=NAS_UE_MSG_MEAS_REQUEST;
            NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_MEAS_REQUEST --->][nas]\n",
                       getTimeStamp4Log(),
                       g_link_id);
            msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request);
           //
            DEBUG("ioctl : Measurement requested\n");
            rc = 0;
        }
      break;
/***************************/
      case IO_OBJ_IMEI:
        {
            NOTICE("[MSC_MSG][%s][%s][--- NAS_UE_MSG_IMEI_REQUEST --->][nas]\n",
                       getTimeStamp4Log(),
                       g_link_id);
      		msgToSend->type=NAS_UE_MSG_IMEI_REQUEST;
          msgToSend->length = sizeof(struct nas_ue_netl_hdr)+ sizeof(struct nas_ue_netl_request);
           //
      		DEBUG("ioctl : L2Id (IMEI) requested\n");
      		rc = 0;
        }
      break;
/***************************/
      default:
        ERR("IAL_process_DNAS_message : invalid ioctl object %d\n",ioctl_obj);
		    rc= -1;
  } //end switch ioctl_obj

  if (!rc){
    if (send(s_nas, message,msgToSend->length, 0) < 0) {
        perror("IAL_process_DNAS_message : send");
        rc= -1;
    }
    DEBUG ("message sent to NAS %d\n",msgToSend->length);
  }
	return rc;
}
Example #6
0
/****************************************************************************
 **                                                                        **
 ** Name:	 RAL_initialize()                                          **
 **                                                                        **
 ** Description: Performs overall RAL LTE initialisations:                 **
 **                  - Default value of global variables                   **
 **                  - Command line parsing                                **
 **                  - List of supported MIH actions                       **
 **                  - List of supported MIH link-events                   **
 **                  - Communication channel with the NAS driver           **
 **                  - MIH link registration                               **
 **                                                                        **
 ** Inputs:	 argc:		Number of parameters in the command line   **
 ** 	 	 argv:		Command line parameters                    **
 ** 	 	 Others:	None                                       **
 **                                                                        **
 ** Outputs:	 None                                                      **
 **		 Return:	None                                       **
 ** 	 	 Others:	g_mihf_ip_address, g_mihf_remote_port      **
 **				g_sockd_mihf, g_ral_ip_address,            **
 **				g_ral_listening_port_for_mihf              **
 **				g_link_id, g_mihf_id, g_log_output         **
 **				g_sockd_nas, ralpriv                       **
 **                                                                        **
 ***************************************************************************/
static int RAL_initialize(int argc, const char *argv[])
{
    MIH_C_TRANSACTION_ID_T           transaction_id;
    unsigned int                     t;
    struct sockaddr_un               nas_socket;

    ralpriv = &rl_priv;
    memset(ralpriv, 0, sizeof(struct ral_lte_priv));

    /*
     * Initialize defaults
     */
    g_ral_ip_address                = strdup(DEFAULT_IP_ADDRESS_RAL);
    g_ral_listening_port_for_mihf   = strdup(DEFAULT_LOCAL_PORT_RAL);
    g_mihf_remote_port              = strdup(DEFAULT_REMOTE_PORT_MIHF);
    g_mihf_ip_address               = strdup(DEFAULT_IP_ADDRESS_MIHF);
    g_sockd_mihf                    = -1;
    g_link_id                       = strdup(DEFAULT_LINK_ID);
    g_mihf_id                       = strdup(DEFAULT_MIHF_ID);
    g_log_output                    = LOG_TO_CONSOLE;

    /*
     * Parse command line parameters
     */
    if (parse_opts(argc, (char**) argv) < 0) {
        exit(0);
    }

    MIH_C_init(g_log_output);

    DEBUG(" %s -I %s -P %s -i %s -p %s -l %s -m %s\n", argv[0],
	  g_ral_ip_address, g_ral_listening_port_for_mihf,
	  g_mihf_ip_address, g_mihf_remote_port,
	  g_link_id, g_mihf_id);

    /*
     * Connect to the MIF Function
     */
    DEBUG(" Connect to the MIH-F ...\n");
    if (eRALlte_mihf_connect() < 0 ) {
        ERR(" %s : Could not connect to MIH-F...exiting\n", __FUNCTION__);
        exit(-1);
    }

    // excluded MIH_C_LINK_AC_TYPE_NONE
    // excluded MIH_C_LINK_AC_TYPE_LINK_DISCONNECT
    // excluded MIH_C_LINK_AC_TYPE_LINK_LOW_POWER
    // excluded MIH_C_LINK_AC_TYPE_LINK_POWER_DOWN
    // excluded MIH_C_LINK_AC_TYPE_LINK_POWER_UP
    ralpriv->mih_supported_link_action_list = 
	(1 << MIH_C_LINK_AC_TYPE_LINK_FLOW_ATTR)		|
	(1 << MIH_C_LINK_AC_TYPE_LINK_ACTIVATE_RESOURCES)	|
	(1 << MIH_C_LINK_AC_TYPE_LINK_DEACTIVATE_RESOURCES);

    // excluded MIH_C_BIT_LINK_DETECTED
    // excluded MIH_C_BIT_LINK_PARAMETERS_REPORT
    // excluded MIH_C_BIT_LINK_GOING_DOWN
    // excluded MIH_C_BIT_LINK_HANDOVER_IMMINENT
    // excluded MIH_C_BIT_LINK_HANDOVER_COMPLETE
    // excluded MIH_C_BIT_LINK_PDU_TRANSMIT_STATUS
    ralpriv->mih_supported_link_event_list =
	MIH_C_BIT_LINK_UP			|
	MIH_C_BIT_LINK_DOWN;

    // excluded MIH_C_BIT_LINK_GET_PARAMETERS
    // excluded MIH_C_BIT_LINK_CONFIGURE_THRESHOLDS
    ralpriv->mih_supported_link_command_list =
	MIH_C_BIT_LINK_EVENT_SUBSCRIBE		|
	MIH_C_BIT_LINK_EVENT_UNSUBSCRIBE	|
	MIH_C_BIT_LINK_ACTION;

    NOTICE("[MSC_NEW][%s][MIH-F=%s]\n", getTimeStamp4Log(), g_mihf_id);
    NOTICE("[MSC_NEW][%s][RAL=%s]\n", getTimeStamp4Log(), g_link_id);
    NOTICE("[MSC_NEW][%s][NAS=%s]\n", getTimeStamp4Log(), "nas");

    /*
     * Initialize the NAS driver communication channel
     */
    NAS_Netlink_socket_init();
    DEBUG(" Waiting for a connection from the NAS Driver ...\n");
    t = sizeof(nas_socket);
    if ((g_sockd_nas = accept(netl_s, (struct sockaddr *)&nas_socket, &t)) == -1) {
        perror("RAL_initialize : g_sockd_nas - accept() failed");
        exit(1);
    }
    DEBUG(" NAS Driver Connected.\n\n");

    /*
     * Get the interface IPv6 address
     */
#ifdef RAL_DUMMY
    get_IPv6_addr("eth0");
#else
#ifdef RAL_REALTIME
    get_IPv6_addr("graal0");
#endif
#endif

    /*
     * Get the list of MTs
     */
    eRALlte_NAS_get_MTs_list();
    DEBUG(" List of MTs initialized\n\n");

    transaction_id = (MIH_C_TRANSACTION_ID_T)0;
    eRALlte_send_link_register_indication(&transaction_id);

    return 0;
}