static void
itti_dump_user_data_delete_function (
  void *user_data,
  void *user_state)
{
  (void)user_state;             // UNUSED

  if (user_data != NULL) {
    itti_dump_queue_item_t                 *item;
    task_id_t                               task_id;
    int                                     result;

    item = (itti_dump_queue_item_t *) user_data;

    if (item->data != NULL) {
      task_id = ITTI_MSG_ORIGIN_ID (item->data);
      result = itti_free (task_id, item->data);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    } else {
      task_id = TASK_UNKNOWN;
    }

    result = itti_free (task_id, item);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }
}
示例#2
0
void *s6a_thread(void *args)
{
    itti_mark_task_ready(TASK_S6A);

    while(1) {
        MessageDef *received_message_p = NULL;
        /* 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.
         */
        itti_receive_msg(TASK_S6A, &received_message_p);
        DevAssert(received_message_p != NULL);

        switch (ITTI_MSG_ID(received_message_p))
        {
            case S6A_UPDATE_LOCATION_REQ: {
                s6a_generate_update_location(&received_message_p->ittiMsg.s6a_update_location_req);
            } break;
            case S6A_AUTH_INFO_REQ: {
                s6a_generate_authentication_info_req(&received_message_p->ittiMsg.s6a_auth_info_req);
            } break;
            case TERMINATE_MESSAGE: {
                itti_exit_task();
            } break;
            default: {
                S6A_DEBUG("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;
}
示例#3
0
void *x2ap_task(void *arg)
{
    MessageDef *received_msg = NULL;
    int         result;

    X2AP_DEBUG("Starting X2AP layer\n");

    x2ap_prepare_internal_data();

    itti_mark_task_ready(TASK_X2AP);

    while (1) {
        itti_receive_msg(TASK_X2AP, &received_msg);

        switch (ITTI_MSG_ID(received_msg)) {
            case TERMINATE_MESSAGE:
                itti_exit_task();
                break;

            default:
                X2AP_ERROR("Received unhandled message: %d:%s\n",
                           ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
                break;
        }

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

        received_msg = NULL;
    }
    return NULL;
}
示例#4
0
/* 
 * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller 
 * and can interact with other itti tasks
*/
void *flexran_agent_task(void *args){

  //flexran_agent_instance_t         *d = (flexran_agent_instance_t *) args;
  Protocol__FlexranMessage *msg;
  void *data;
  int size;
  err_code_t err_code;
  int                   priority = 0;

  MessageDef                     *msg_p           = NULL;
  const char                     *msg_name        = NULL;
  int                             result;
  struct flexran_agent_timer_element_s * elem = NULL;

  itti_mark_task_ready(TASK_FLEXRAN_AGENT);

  do {
    // Wait for a message
    itti_receive_msg (TASK_FLEXRAN_AGENT, &msg_p);
    DevAssert(msg_p != NULL);
    msg_name = ITTI_MSG_NAME (msg_p);

    switch (ITTI_MSG_ID(msg_p)) {
    case TERMINATE_MESSAGE:
      itti_exit_task ();
      break;

    case MESSAGE_TEST:
      LOG_I(FLEXRAN_AGENT, "Received %s\n", ITTI_MSG_NAME(msg_p));
      break;
    
    case TIMER_HAS_EXPIRED:
      msg = flexran_agent_process_timeout(msg_p->ittiMsg.timer_has_expired.timer_id, msg_p->ittiMsg.timer_has_expired.arg);
      if (msg != NULL){
	data=flexran_agent_pack_message(msg,&size);
	elem = get_timer_entry(msg_p->ittiMsg.timer_has_expired.timer_id);
	if (flexran_agent_msg_send(elem->agent_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) {
	  err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
	  goto error;
	}

	LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size);
      }
      break;

    default:
      LOG_E(FLEXRAN_AGENT, "Received unexpected message %s\n", msg_name);
      break;
    }

    result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    continue;
  error:
    LOG_E(FLEXRAN_AGENT,"flexran_agent_task: error %d occured\n",err_code);
  } while (1);

  return NULL;
}
示例#5
0
static void *sctp_intertask_interface(void *args_p)
{
    itti_mark_task_ready(TASK_SCTP);
    MSC_START_USE();

    while(1) {
        MessageDef *received_message_p;
        itti_receive_msg(TASK_SCTP, &received_message_p);

        switch (ITTI_MSG_ID(received_message_p)) {
        case SCTP_INIT_MSG: {
            SCTP_DEBUG("Received SCTP_INIT_MSG\n");

            /* We received a new connection request */
            if (sctp_create_new_listener(&received_message_p->ittiMsg.sctpInit) < 0) {
                /* SCTP socket creation or bind failed... */
                SCTP_ERROR("Failed to create new SCTP listener\n");
            }
        }
        break;

        case SCTP_CLOSE_ASSOCIATION: {

        } break;

        case SCTP_DATA_REQ: {
            if (sctp_send_msg(SCTP_DATA_REQ(received_message_p).assocId,
                              SCTP_DATA_REQ(received_message_p).stream,
                              SCTP_DATA_REQ(received_message_p).buffer,
                              SCTP_DATA_REQ(received_message_p).bufLen) < 0) {
                SCTP_ERROR("Failed to send message over SCTP\n");
            }
        }
        break;

        case MESSAGE_TEST: {
            //                 int i = 10000;
            //                 while(i--);
        } break;

        case TERMINATE_MESSAGE: {
            itti_exit_task();
        }
        break;

        default: {
            SCTP_DEBUG("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;
}
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;
}
示例#7
0
static
void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind)
{
  int result;

  DevAssert(sctp_data_ind != NULL);
#if defined(TEST_S1C_MME)
  mme_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream,
          sctp_data_ind->buffer, sctp_data_ind->buffer_length);
#else
  s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
                          sctp_data_ind->buffer, sctp_data_ind->buffer_length);
#endif
  result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
  AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
int s11_sgw_handle_create_session_request(NwGtpv2cStackHandleT *stack_p,
                                          NwGtpv2cUlpApiT      *pUlpApi)
{
    NwRcT  rc = NW_OK;
    NwU8T  offendingIeType, offendingIeInstance;
    NwU16T offendingIeLength;

    SgwCreateSessionRequest *create_session_request_p;
    MessageDef              *message_p;

    NwGtpv2cMsgParserT *pMsgParser;

    DevAssert(stack_p != NULL);

    message_p = itti_alloc_new_message(TASK_S11, SGW_CREATE_SESSION_REQUEST);

    create_session_request_p = &message_p->ittiMsg.sgwCreateSessionRequest;

    /* Create a new message parser */
    rc = nwGtpv2cMsgParserNew(*stack_p, NW_GTP_CREATE_SESSION_REQ,
                              s11_ie_indication_generic,
                              NULL, &pMsgParser);
    DevAssert(NW_OK == rc);

    /* Imsi IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_IMSI,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_imsi_ie_get,
                                &create_session_request_p->imsi);
    DevAssert(NW_OK == rc);

    /* MSISDN IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_MSISDN,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_msisdn_ie_get,
                                &create_session_request_p->msisdn);
    DevAssert(NW_OK == rc);

    /* MEI IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_MEI,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_mei_ie_get,
                                &create_session_request_p->mei);
    DevAssert(NW_OK == rc);

    /* ULI IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_ULI,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_uli_ie_get,
                                &create_session_request_p->uli);
    DevAssert(NW_OK == rc);

    /* Serving Network IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_SERVING_NETWORK,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_serving_network_ie_get,
                                &create_session_request_p->serving_network);
    DevAssert(NW_OK == rc);

    /* RAT Type IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_RAT_TYPE,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_MANDATORY,
                                s11_rat_type_ie_get,
                                &create_session_request_p->rat_type);
    DevAssert(NW_OK == rc);

    /* Indication Flags IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_INDICATION,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_indication_flags_ie_get,
                                &create_session_request_p->indication_flags);
    DevAssert(NW_OK == rc);

    /* APN IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_APN,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_MANDATORY,
                                s11_apn_ie_get, &create_session_request_p->apn);
    DevAssert(NW_OK == rc);

    /* Selection Mode IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_SELECTION_MODE,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_ie_indication_generic, NULL);
    DevAssert(NW_OK == rc);

    /* PDN Type IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_PDN_TYPE,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_pdn_type_ie_get, &create_session_request_p->pdn_type);
    DevAssert(NW_OK == rc);

    /* PAA IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_PAA,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_paa_ie_get, &create_session_request_p->paa);
    DevAssert(NW_OK == rc);

    /* Sender FTEID for CP IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_FTEID,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_MANDATORY,
                                s11_fteid_ie_get,
                                &create_session_request_p->sender_fteid_for_cp);
    DevAssert(NW_OK == rc);

    /* PGW FTEID for CP IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_FTEID,
                                NW_GTPV2C_IE_INSTANCE_ONE,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_fteid_ie_get,
                                &create_session_request_p->pgw_address_for_cp);
    DevAssert(NW_OK == rc);

    /* APN Restriction IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_APN_RESTRICTION,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_ie_indication_generic, NULL);
    DevAssert(NW_OK == rc);

    /* Bearer Context IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_BEARER_CONTEXT,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_MANDATORY,
                                s11_bearer_context_ie_get,
                                &create_session_request_p->bearer_to_create);
    DevAssert(NW_OK == rc);

    /* AMBR IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_AMBR,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_ambr_ie_get,
                                &create_session_request_p->ambr);
    DevAssert(NW_OK == rc);

    /* Recovery IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_RECOVERY,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_MANDATORY,
                                s11_ie_indication_generic, NULL);
    DevAssert(NW_OK == rc);

    create_session_request_p->teid    = nwGtpv2cMsgGetTeid(pUlpApi->hMsg);
    create_session_request_p->trxn    = (void*)pUlpApi->apiInfo.initialReqIndInfo.hTrxn;
    create_session_request_p->peer_ip = pUlpApi->apiInfo.initialReqIndInfo.peerIp;

    rc = nwGtpv2cMsgParserRun(pMsgParser,
                              pUlpApi->hMsg,
                              &offendingIeType,
                              &offendingIeInstance,
                              &offendingIeLength);
    if (rc != NW_OK)
    {
        gtp_cause_t cause;

        NwGtpv2cUlpApiT     ulp_req;

        memset(&ulp_req, 0, sizeof(NwGtpv2cUlpApiT));
        memset(&cause  , 0, sizeof(gtp_cause_t));

        cause.offending_ie_type     = offendingIeType;
        cause.offending_ie_length   = offendingIeLength;
        cause.offending_ie_instance = offendingIeInstance;

        switch (rc)
        {
            case NW_GTPV2C_MANDATORY_IE_MISSING:
                S11_DEBUG("Mandatory IE type '%u' of instance '%u' missing!\n",
                          offendingIeType, offendingIeLength);
                cause.cause_value = NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING;
                break;
            default:
                S11_DEBUG("Unknown message parse error!\n");
                cause.cause_value = 0;
                break;
        }

        /*
         * Send Create session response with failure to Gtpv2c Stack Instance
         */
        ulp_req.apiType = NW_GTPV2C_ULP_API_TRIGGERED_RSP;

        ulp_req.apiInfo.triggeredRspInfo.hTrxn = pUlpApi->apiInfo.initialReqIndInfo.hTrxn;

        rc = nwGtpv2cMsgNew(*stack_p,
                             NW_TRUE,
                             NW_GTP_CREATE_SESSION_RSP,
                             0,
                             nwGtpv2cMsgGetSeqNumber(pUlpApi->hMsg),
                            &(ulp_req.hMsg));

        s11_cause_ie_set(&(ulp_req.hMsg), &cause);

        S11_DEBUG("Received NW_GTP_CREATE_SESSION_REQ, Sending NW_GTP_CREATE_SESSION_RSP!\n");
        rc = nwGtpv2cProcessUlpReq(*stack_p, &ulp_req);
        DevAssert(NW_OK == rc);

        itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
        message_p = NULL;

        rc = nwGtpv2cMsgParserDelete(*stack_p, pMsgParser);
        DevAssert(NW_OK == rc);

        rc = nwGtpv2cMsgDelete(*stack_p, (pUlpApi->hMsg));
        DevAssert(NW_OK == rc);

        return 0;
    }

    rc = nwGtpv2cMsgParserDelete(*stack_p, pMsgParser);
    DevAssert(NW_OK == rc);

    rc = nwGtpv2cMsgDelete(*stack_p, (pUlpApi->hMsg));
    DevAssert(NW_OK == rc);

    return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
}
int s11_sgw_handle_delete_session_request(NwGtpv2cStackHandleT *stack_p,
                                          NwGtpv2cUlpApiT      *pUlpApi)
{
    NwRcT  rc = NW_OK;
    NwU8T  offendingIeType, offendingIeInstance;
    NwU16T offendingIeLength;

    SgwDeleteSessionRequest *delete_session_request_p;
    MessageDef              *message_p;

    NwGtpv2cMsgParserT *pMsgParser;

    DevAssert(stack_p != NULL);

    message_p = itti_alloc_new_message(TASK_S11, SGW_DELETE_SESSION_REQUEST);

    delete_session_request_p = &message_p->ittiMsg.sgwDeleteSessionRequest;

    /* Create a new message parser */
    rc = nwGtpv2cMsgParserNew(*stack_p, NW_GTP_DELETE_SESSION_REQ,
                              s11_ie_indication_generic,
                              NULL, &pMsgParser);
    DevAssert(NW_OK == rc);

    /* MME FTEID for CP IE */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_FTEID,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_OPTIONAL,
                                s11_fteid_ie_get,
                                &delete_session_request_p->sender_fteid_for_cp);
    DevAssert(NW_OK == rc);

    /* Linked EPS Bearer Id IE
     * This information element shall not be present for TAU/RAU/Handover with
     * S-GW relocation procedures.
     */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_EBI,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_OPTIONAL,
                                s11_ebi_ie_get,
                                &delete_session_request_p->lbi);
    DevAssert(NW_OK == rc);

    /* Indication Flags IE
     * For a Delete Session Request on S11 interface,
     * only the Operation Indication flag might be present.
     */
    rc = nwGtpv2cMsgParserAddIe(pMsgParser, NW_GTPV2C_IE_INDICATION,
                                NW_GTPV2C_IE_INSTANCE_ZERO,
                                NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
                                s11_indication_flags_ie_get,
                                &delete_session_request_p->indication_flags);
    DevAssert(NW_OK == rc);

    delete_session_request_p->teid    = nwGtpv2cMsgGetTeid(pUlpApi->hMsg);
    delete_session_request_p->trxn    = (void*)pUlpApi->apiInfo.initialReqIndInfo.hTrxn;
    delete_session_request_p->peer_ip = pUlpApi->apiInfo.initialReqIndInfo.peerIp;

    rc = nwGtpv2cMsgParserRun(pMsgParser,
                              pUlpApi->hMsg,
                              &offendingIeType,
                              &offendingIeInstance,
                              &offendingIeLength);
    if (rc != NW_OK) {
        NwGtpv2cUlpApiT     ulp_req;
        gtp_cause_t         cause;

        memset(&ulp_req, 0, sizeof(NwGtpv2cUlpApiT));
        memset(&cause  , 0, sizeof(gtp_cause_t));

        cause.offending_ie_type     = offendingIeType;
        cause.offending_ie_length   = offendingIeLength;
        cause.offending_ie_instance = offendingIeInstance;

        switch (rc)
        {
            case NW_GTPV2C_MANDATORY_IE_MISSING:
                S11_DEBUG("Mandatory IE type '%u' of instance '%u' missing!\n",
                          offendingIeType, offendingIeLength);
                cause.cause_value = NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING;
                break;
            default:
                S11_DEBUG("Unknown message parse error!\n");
                cause.cause_value = 0;
                break;
        }

        /*
         * Send Create session response with failure to Gtpv2c Stack Instance
         */
        ulp_req.apiType = NW_GTPV2C_ULP_API_TRIGGERED_RSP;

        ulp_req.apiInfo.triggeredRspInfo.hTrxn = pUlpApi->apiInfo.initialReqIndInfo.hTrxn;

        rc = nwGtpv2cMsgNew(*stack_p,
                             NW_TRUE,
                             NW_GTP_DELETE_SESSION_RSP,
                             0,
                             nwGtpv2cMsgGetSeqNumber(pUlpApi->hMsg),
                            &(ulp_req.hMsg));

        /* Adding the cause */
        s11_cause_ie_set(&(ulp_req.hMsg), &cause);

        S11_DEBUG("Received NW_GTP_DELETE_SESSION_REQ, Sending NW_GTP_DELETE_SESSION_RSP!\n");
        rc = nwGtpv2cProcessUlpReq(*stack_p, &ulp_req);
        DevAssert(NW_OK == rc);

        itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
        message_p = NULL;

        rc = nwGtpv2cMsgParserDelete(*stack_p, pMsgParser);
        DevAssert(NW_OK == rc);

        rc = nwGtpv2cMsgDelete(*stack_p, (pUlpApi->hMsg));
        DevAssert(NW_OK == rc);

        return 0;
    }

    rc = nwGtpv2cMsgParserDelete(*stack_p, pMsgParser);
    DevAssert(NW_OK == rc);

    rc = nwGtpv2cMsgDelete(*stack_p, (pUlpApi->hMsg));
    DevAssert(NW_OK == rc);

    return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
}
示例#10
0
void *s1ap_eNB_task(void *arg)
{
  MessageDef *received_msg = NULL;
  int         result;

  S1AP_DEBUG("Starting S1AP layer\n");

  s1ap_eNB_prepare_internal_data();

  itti_mark_task_ready(TASK_S1AP);
  MSC_START_USE();

  while (1) {
    itti_receive_msg(TASK_S1AP, &received_msg);

    switch (ITTI_MSG_ID(received_msg)) {
    case TERMINATE_MESSAGE:
      itti_exit_task();
      break;

    case S1AP_REGISTER_ENB_REQ: {
      /* Register a new eNB.
       * in Virtual mode eNBs will be distinguished using the mod_id/
       * Each eNB has to send an S1AP_REGISTER_ENB message with its
       * own parameters.
       */
      s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                   &S1AP_REGISTER_ENB_REQ(received_msg));
    }
    break;

    case SCTP_NEW_ASSOCIATION_RESP: {
      s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                            &received_msg->ittiMsg.sctp_new_association_resp);
    }
    break;

    case SCTP_DATA_IND: {
      s1ap_eNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind);
    }
    break;

    case S1AP_NAS_FIRST_REQ: {
      s1ap_eNB_handle_nas_first_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                    &S1AP_NAS_FIRST_REQ(received_msg));
    }
    break;

    case S1AP_UPLINK_NAS: {
      s1ap_eNB_nas_uplink(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                          &S1AP_UPLINK_NAS(received_msg));
    }
    break;

    case S1AP_UE_CAPABILITIES_IND: {
      s1ap_eNB_ue_capabilities(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                               &S1AP_UE_CAPABILITIES_IND(received_msg));
    }
    break;

    case S1AP_INITIAL_CONTEXT_SETUP_RESP: {
      s1ap_eNB_initial_ctxt_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                 &S1AP_INITIAL_CONTEXT_SETUP_RESP(received_msg));
    }
    break;

    case S1AP_E_RAB_SETUP_RESP: {
      s1ap_eNB_e_rab_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
				&S1AP_E_RAB_SETUP_RESP(received_msg));
    }
    break;
      
    case S1AP_NAS_NON_DELIVERY_IND: {
      s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                    &S1AP_NAS_NON_DELIVERY_IND(received_msg));
    }
    break;

    case S1AP_UE_CONTEXT_RELEASE_COMPLETE: {
      s1ap_ue_context_release_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                       &S1AP_UE_CONTEXT_RELEASE_COMPLETE(received_msg));
    }
    break;

    case S1AP_UE_CONTEXT_RELEASE_REQ: {
      s1ap_eNB_instance_t               *s1ap_eNB_instance_p           = NULL; // test
      struct s1ap_eNB_ue_context_s      *ue_context_p                  = NULL; // test

      s1ap_ue_context_release_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                  &S1AP_UE_CONTEXT_RELEASE_REQ(received_msg));


      s1ap_eNB_instance_p = s1ap_eNB_get_instance(ITTI_MESSAGE_GET_INSTANCE(received_msg)); // test
      DevAssert(s1ap_eNB_instance_p != NULL); // test

      if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
                          S1AP_UE_CONTEXT_RELEASE_REQ(received_msg).eNB_ue_s1ap_id)) == NULL) { // test
        /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
        S1AP_ERROR("Failed to find ue context associated with eNB ue s1ap id: %u\n",
                   S1AP_UE_CONTEXT_RELEASE_REQ(received_msg).eNB_ue_s1ap_id); // test
      }  // test
    }
    break;

    default:
      S1AP_ERROR("Received unhandled message: %d:%s\n",
                 ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
      break;
    }

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

    received_msg = NULL;
  }

  return NULL;
}
/* Callback called when a gtpv1u message arrived on UDP interface */
NwGtpv1uRcT gtpv1u_process_stack_req(
  NwGtpv1uUlpHandleT hUlp,
  NwGtpv1uUlpApiT *pUlpApi)
{
  switch(pUlpApi->apiType) {
    /* Here there are two type of messages handled:
     * - T-PDU
     * - END-MARKER
     */
  case NW_GTPV1U_ULP_API_RECV_TPDU: {
    //uint8_t              buffer[4096];
    //uint32_t             buffer_len;
    MessageDef          *message_p  = NULL;
    Gtpv1uTunnelDataInd *data_ind_p = NULL;

    /* Nw-gptv1u stack has processed a PDU. we can forward it to IPV4
     * task for transmission.
     */
    /*if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
        buffer, (uint32_t *)&buffer_len)) {
        GTPU_ERROR("Error while retrieving T-PDU\n");
    }*/
    GTPU_DEBUG("Received TPDU from gtpv1u stack %u with size %d\n",
               pUlpApi->apiInfo.recvMsgInfo.teid,
               ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen);

    message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_TUNNEL_DATA_IND);

    if (message_p == NULL) {
      return -1;
    }

    data_ind_p                       = &message_p->ittiMsg.gtpv1uTunnelDataInd;
    data_ind_p->buffer               = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf;
    data_ind_p->length               = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen;
    data_ind_p->offset               = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufOffset;
    data_ind_p->local_S1u_teid       = pUlpApi->apiInfo.recvMsgInfo.teid;

    if (data_ind_p->buffer == NULL) {
      GTPU_ERROR("Failed to allocate new buffer\n");
      itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
      message_p = NULL;
    } else {
      //memcpy(data_ind_p->buffer, buffer, buffer_len);
      //data_ind_p->length = buffer_len;
      if (itti_send_msg_to_task(TASK_FW_IP, INSTANCE_DEFAULT, message_p) < 0) {
        GTPU_ERROR("Failed to send message to task\n");
        itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
        message_p = NULL;
      }
    }
  }
  break;

  case NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT: {
  }
  break;

  default: {
    GTPU_ERROR("Received undefined UlpApi (%02x) from gtpv1u stack!\n",
               pUlpApi->apiType);
  }
  }

  return NW_GTPV1U_OK;
}
static void *nas_intertask_interface(void *args_p)
{
  itti_mark_task_ready(TASK_NAS_MME);
  MSC_START_USE();

  while(1) {
    MessageDef *received_message_p;

next_message:
    itti_receive_msg(TASK_NAS_MME, &received_message_p);

    switch (ITTI_MSG_ID(received_message_p)) {
    case NAS_CONNECTION_ESTABLISHMENT_IND: {
#if defined(DISABLE_USE_NAS)
      MessageDef       *message_p;
      nas_attach_req_t *nas_req_p;
      s1ap_initial_ue_message_t *transparent;

      NAS_DEBUG("NAS abstraction: Generating NAS ATTACH REQ\n");

      message_p = itti_alloc_new_message(TASK_NAS_MME, NAS_ATTACH_REQ);

      nas_req_p = &message_p->ittiMsg.nas_attach_req;
      transparent = &message_p->ittiMsg.nas_attach_req.transparent;

      nas_req_p->initial = INITIAL_REQUEST;
      sprintf(nas_req_p->imsi, "%14llu", 20834123456789ULL);

      memcpy(transparent, &received_message_p->ittiMsg.nas_conn_est_ind.transparent,
             sizeof(s1ap_initial_ue_message_t));

      itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p);
#else
      nas_establish_ind_t *nas_est_ind_p;

      nas_est_ind_p = &received_message_p->ittiMsg.nas_conn_est_ind.nas;

      nas_proc_establish_ind(nas_est_ind_p->UEid,
                             nas_est_ind_p->tac,
                             nas_est_ind_p->initialNasMsg.data,
                             nas_est_ind_p->initialNasMsg.length);
#endif
    }
    break;

#if defined(DISABLE_USE_NAS)

    case NAS_ATTACH_ACCEPT: {
      itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, received_message_p);
      goto next_message;
    }
    break;

    case NAS_AUTHENTICATION_REQ: {
      MessageDef      *message_p;
      nas_auth_resp_t *nas_resp_p;

      NAS_DEBUG("NAS abstraction: Generating NAS AUTHENTICATION RESPONSE\n");

      message_p = itti_alloc_new_message(TASK_NAS_MME, NAS_AUTHENTICATION_RESP);

      nas_resp_p = &message_p->ittiMsg.nas_auth_resp;

      memcpy(nas_resp_p->imsi, received_message_p->ittiMsg.nas_auth_req.imsi, 16);

      itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p);
    }
    break;
#else

    case NAS_UPLINK_DATA_IND: {
      nas_proc_ul_transfer_ind(NAS_UL_DATA_IND(received_message_p).UEid,
                               NAS_UL_DATA_IND(received_message_p).nasMsg.data,
                               NAS_UL_DATA_IND(received_message_p).nasMsg.length);
    }
    break;

    case NAS_DOWNLINK_DATA_CNF: {
      nas_proc_dl_transfer_cnf(NAS_DL_DATA_CNF(received_message_p).UEid);
    } break;

    case NAS_DOWNLINK_DATA_REJ: {
      nas_proc_dl_transfer_rej(NAS_DL_DATA_REJ(received_message_p).UEid);
    } break;

    case NAS_AUTHENTICATION_PARAM_RSP: {
      nas_proc_auth_param_res(&NAS_AUTHENTICATION_PARAM_RSP(received_message_p));
    }
    break;

    case NAS_AUTHENTICATION_PARAM_FAIL: {
      nas_proc_auth_param_fail(&NAS_AUTHENTICATION_PARAM_FAIL(received_message_p));
    }
    break;
#endif

    case NAS_PDN_CONNECTIVITY_RSP: {
      nas_proc_pdn_connectivity_res(&NAS_PDN_CONNECTIVITY_RSP(received_message_p));
    }
    break;

    case NAS_PDN_CONNECTIVITY_FAIL: {
      nas_proc_pdn_connectivity_fail(&NAS_PDN_CONNECTIVITY_FAIL(received_message_p));
    }
    break;


    case TIMER_HAS_EXPIRED: {
#if !defined(DISABLE_USE_NAS)
      /* Call the NAS timer api */
      nas_timer_handle_signal_expiry(TIMER_HAS_EXPIRED(received_message_p).timer_id,
                                     TIMER_HAS_EXPIRED(received_message_p).arg);
#endif
    }
    break;

    case S1AP_ENB_DEREGISTERED_IND: {
#if !defined(DISABLE_USE_NAS)
      int i;

      for (i = 0; i < S1AP_ENB_DEREGISTERED_IND(received_message_p).nb_ue_to_deregister; i ++) {
        nas_proc_deregister_ue(S1AP_ENB_DEREGISTERED_IND(received_message_p).mme_ue_s1ap_id[i]);
      }

#endif
    }
    break;

    case S1AP_DEREGISTER_UE_REQ: {
#if !defined(DISABLE_USE_NAS)
      nas_proc_deregister_ue(S1AP_DEREGISTER_UE_REQ(received_message_p).mme_ue_s1ap_id);
#endif
    }
    break;

    case TERMINATE_MESSAGE: {
      itti_exit_task();
    }
    break;

    default: {
      NAS_DEBUG("Unkwnon message ID %d:%s from %s\n",
                ITTI_MSG_ID(received_message_p),
                ITTI_MSG_NAME(received_message_p),
                ITTI_MSG_ORIGIN_NAME(received_message_p));
    }
    break;
    }

    itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p);
    received_message_p = NULL;
  }

  return NULL;
}
示例#13
0
//-----------------------------------------------------------------------------
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 = &GTPV1U_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**)&gtpv1u_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;
}
示例#14
0
/* Callback called when a gtpv1u message arrived on UDP interface */
NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
  NwGtpv1uUlpHandleT hUlp,
  NwGtpv1uUlpApiT   *pUlpApi)
{
  boolean_t           result             = FALSE;
  teid_t              teid               = 0;
  hashtable_rc_t      hash_rc            = HASH_TABLE_KEY_NOT_EXISTS;
  gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
  protocol_ctxt_t     ctxt;

  switch(pUlpApi->apiType) {
    /* Here there are two type of messages handled:
     * - T-PDU
     * - END-MARKER
     */
  case NW_GTPV1U_ULP_API_RECV_TPDU: {
    uint8_t              buffer[4096];
    uint32_t             buffer_len;
    /* Nw-gptv1u stack has processed a PDU. we can schedule it to PDCP
     * for transmission.
     */
    teid = pUlpApi->apiInfo.recvMsgInfo.teid;

    if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
                                           buffer, &buffer_len)) {
      LOG_E(GTPU, "Error while retrieving T-PDU");
    }

    itti_free(TASK_UDP, ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf);
#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0
    gtpv1u_eNB_write_dump_socket(buffer,buffer_len);
#endif

    //-----------------------
    // GTPV1U->PDCP mapping
    //-----------------------
    hash_rc = hashtable_get(gtpv1u_data_g.teid_mapping, teid, (void**)&gtpv1u_teid_data_p);

    if (hash_rc == HASH_TABLE_OK) {
#if defined(LOG_GTPU) && LOG_GTPU > 0
      LOG_D(GTPU, "Received T-PDU from gtpv1u stack teid  %u size %d -> enb module id %u ue module id %u rab id %u\n",
            teid,
            buffer_len,
            gtpv1u_teid_data_p->enb_id,
            gtpv1u_teid_data_p->ue_id,
            gtpv1u_teid_data_p->eps_bearer_id);
#endif

//#warning "LG eps bearer mapping to DRB id to do (offset -4)"
      PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gtpv1u_teid_data_p->enb_id, ENB_FLAG_YES,  gtpv1u_teid_data_p->ue_id, 0, 0,gtpv1u_teid_data_p->enb_id);
      MSC_LOG_TX_MESSAGE(
			 MSC_GTPU_ENB,
			 MSC_PDCP_ENB,
			 NULL,0,
			 MSC_AS_TIME_FMT" DATA-REQ rb %u size %u",
			 0,0,
			 (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4,
			 buffer_len);
      
      result = pdcp_data_req(
			     &ctxt,
			     SRB_FLAG_NO,
			     (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4,
			     0, // mui
			     SDU_CONFIRM_NO, // confirm
			     buffer_len,
			     buffer,
			     PDCP_TRANSMISSION_MODE_DATA);
      
      
      if ( result == FALSE ) {
	
	if (ctxt.configured == FALSE )
	  LOG_W(GTPU, "PDCP data request failed, cause: RB is not configured!\n") ;
	else  
	  LOG_W(GTPU, "PDCP data request failed\n");
	
	return NW_GTPV1U_FAILURE;
      }
      
    } else {
      LOG_W(GTPU, "Received T-PDU from gtpv1u stack teid %u unknown size %u", teid, buffer_len);
    }
  }
    break;
    
  default: {
    LOG_E(GTPU, "Received undefined UlpApi (%02x) from gtpv1u stack!\n",
          pUlpApi->apiType);
  }
  
  } // end of switch 
  
  return NW_GTPV1U_OK;
}
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP)  //, int calibration_flag) {
{

  unsigned int nprb[MAX_NUM_CCs];
  unsigned int nCCE[MAX_NUM_CCs];
  int mbsfn_status[MAX_NUM_CCs];
  uint32_t RBalloc[MAX_NUM_CCs];
  protocol_ctxt_t   ctxt;
#ifdef EXMIMO
  int ret;
#endif
#if defined(ENABLE_ITTI)
  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
  int           result;
#endif
  DCI_PDU *DCI_pdu[MAX_NUM_CCs];
  int CC_id,i,next_i;
  UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
  rnti_t rnti;

  LOG_D(MAC,"[eNB %d] Frame %d, Subframe %d, entering MAC scheduler (UE_list->head %d)\n",module_idP, frameP, subframeP,UE_list->head);

  start_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    DCI_pdu[CC_id] = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu;
    nCCE[CC_id]=0;
    nprb[CC_id]=0;
    RBalloc[CC_id]=0;
    mbsfn_status[CC_id]=0;
  }

  // refresh UE list based on UEs dropped by PHY in previous subframe
  i = UE_list->head;

  while (i>=0) {
    rnti = UE_RNTI(module_idP, i);
    CC_id = UE_PCCID(module_idP, i);
    LOG_D(MAC,"UE %d: rnti %x (%p)\n", i, rnti,
          mac_xface->get_eNB_UE_stats(module_idP, CC_id, rnti));
    next_i= UE_list->next[i];

    if (mac_xface->get_eNB_UE_stats(module_idP, CC_id, rnti)==NULL) {
      mac_remove_ue(module_idP, i, frameP, subframeP);
    }
    i = next_i;
  }

#if defined(ENABLE_ITTI)

  do {
    // Checks if a message has been sent to MAC sub-task
    itti_poll_msg (TASK_MAC_ENB, &msg_p);

    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);

      switch (ITTI_MSG_ID(msg_p)) {
      case MESSAGE_TEST:
        LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p));
        break;

      case RRC_MAC_BCCH_DATA_REQ:
        LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
              RRC_MAC_BCCH_DATA_REQ (msg_p).frame, RRC_MAC_BCCH_DATA_REQ (msg_p).enb_index);

        // TODO process BCCH data req.
        break;

      case RRC_MAC_CCCH_DATA_REQ:
        LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
              RRC_MAC_CCCH_DATA_REQ (msg_p).frame, RRC_MAC_CCCH_DATA_REQ (msg_p).enb_index);

        // TODO process CCCH data req.
        break;

#ifdef Rel10

      case RRC_MAC_MCCH_DATA_REQ:
        LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d, mbsfn_sync_area %d\n",
              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
              RRC_MAC_MCCH_DATA_REQ (msg_p).frame, RRC_MAC_MCCH_DATA_REQ (msg_p).enb_index, RRC_MAC_MCCH_DATA_REQ (msg_p).mbsfn_sync_area);

        // TODO process MCCH data req.
        break;
#endif

      default:
        LOG_E(MAC, "Received unexpected message %s\n", msg_name);
        break;
      }

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

#endif

  // clear DCI and BCCH contents before scheduling
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    DCI_pdu[CC_id]->Num_common_dci  = 0;
    DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
    eNB_mac_inst[module_idP].common_channels[CC_id].bcch_active = 0;

#ifdef Rel10
    eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active =0;
#endif

    eNB_mac_inst[module_idP].frame    = frameP;
    eNB_mac_inst[module_idP].subframe = subframeP;
  }

  //if (subframeP%5 == 0)
  //#ifdef EXMIMO
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, 0,module_idP);
  pdcp_run(&ctxt);
  //#endif

  // check HO
  rrc_rx_tx(&ctxt,
            0, // eNB index, unused in eNB
            CC_id);

#ifdef Rel10

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    if (eNB_mac_inst[module_idP].common_channels[CC_id].MBMS_flag >0) {
      start_meas(&eNB_mac_inst[module_idP].schedule_mch);
      mbsfn_status[CC_id] = schedule_MBMS(module_idP,CC_id,frameP,subframeP);
      stop_meas(&eNB_mac_inst[module_idP].schedule_mch);
    }
  }

#endif
  // refresh UE list based on UEs dropped by PHY in previous subframe
  /*
  i=UE_list->head;
  while (i>=0) {
    next_i = UE_list->next[i];
    LOG_T(MAC,"UE %d : rnti %x, stats %p\n",i,UE_RNTI(module_idP,i),mac_xface->get_eNB_UE_stats(module_idP,0,UE_RNTI(module_idP,i)));
    if (mac_xface->get_eNB_UE_stats(module_idP,0,UE_RNTI(module_idP,i))==NULL) {
      mac_remove_ue(module_idP,i,frameP);
    }
    i=next_i;
  }
  */

  switch (subframeP) {
  case 0:

    // FDD/TDD Schedule Downlink RA transmissions (RA response, Msg4 Contention resolution)
    // Schedule ULSCH for FDD or subframeP 4 (TDD config 0,3,6)
    // Schedule Normal DLSCH

    schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE);

    if (mac_xface->lte_frame_parms->frame_type == FDD) {  //FDD
      schedule_ulsch(module_idP,frameP,cooperation_flag,0,4,nCCE);//,calibration_flag);
    } else if  ((mac_xface->lte_frame_parms->tdd_config == TDD) || //TDD
                (mac_xface->lte_frame_parms->tdd_config == 3) ||
                (mac_xface->lte_frame_parms->tdd_config == 6)) {
      //schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE);//,calibration_flag);
    }

    // schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);

    fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);

    break;

  case 1:

    // TDD, schedule UL for subframeP 7 (TDD config 0,1) / subframeP 8 (TDD Config 6)
    // FDD, schedule normal UL/DLSCH
    if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
      switch (mac_xface->lte_frame_parms->tdd_config) {
      case 0:
      case 1:
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      case 6:
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      default:
        break;
      }
    } else { //FDD
      schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
      schedule_ulsch(module_idP,frameP,cooperation_flag,1,5,nCCE);
    }

    break;

  case 2:

    // TDD, nothing
    // FDD, normal UL/DLSCH
    if (mac_xface->lte_frame_parms->frame_type == FDD) {  //FDD
      schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
      schedule_ulsch(module_idP,frameP,cooperation_flag,2,6,nCCE);
    }

    break;

  case 3:

    // TDD Config 2, ULSCH for subframeP 7
    // TDD Config 2/5 normal DLSCH
    // FDD, normal UL/DLSCH
    if (mac_xface->lte_frame_parms->frame_type == TDD) {
      switch (mac_xface->lte_frame_parms->tdd_config) {
      case 2:
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7,nCCE);

        // no break here!
      case 5:
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      default:
        break;
      }
    } else { //FDD
      schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
      schedule_ulsch(module_idP,frameP,cooperation_flag,3,7,nCCE);

    }

    break;

  case 4:

    // TDD Config 1, ULSCH for subframeP 8
    // TDD Config 1/2/4/5 DLSCH
    // FDD UL/DLSCH
    if (mac_xface->lte_frame_parms->frame_type == 1) { // TDD
      switch (mac_xface->lte_frame_parms->tdd_config) {
      case 1:
        //        schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8,nCCE);

        // no break here!
      case 2:

        // no break here!
      case 4:

        // no break here!
      case 5:
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
        break;

      default:
        break;
      }
    } else {
      if (mac_xface->lte_frame_parms->frame_type == FDD) {  //FDD
	//        schedule_RA(module_idP,frameP, subframeP, 0, nprb, nCCE);
        //  schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, nCCE);
        schedule_ue_spec(module_idP, frameP, subframeP, nprb, nCCE, mbsfn_status);
        fill_DLSCH_dci(module_idP, frameP, subframeP, RBalloc, 1, mbsfn_status);

      }
    }

    break;

  case 5:
    // TDD/FDD Schedule SI
    // TDD Config 0,6 ULSCH for subframes 9,3 resp.
    // TDD normal DLSCH
    // FDD normal UL/DLSCH
    schedule_SI(module_idP,frameP,nprb,nCCE);

    //schedule_RA(module_idP,frameP,subframeP,5,nprb,nCCE);
    if (mac_xface->lte_frame_parms->frame_type == FDD) {
      schedule_RA(module_idP,frameP,subframeP,1,nprb,nCCE);
      //      schedule_ulsch(module_idP,frameP,cooperation_flag,5,9,nCCE);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);

    } else if ((mac_xface->lte_frame_parms->tdd_config == 0) || // TDD Config 0
               (mac_xface->lte_frame_parms->tdd_config == 6)) { // TDD Config 6
      //schedule_ulsch(module_idP,cooperation_flag,subframeP,nCCE);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
    } else {
      //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
    }

    break;

  case 6:

    // TDD Config 0,1,6 ULSCH for subframes 2,3
    // TDD Config 3,4,5 Normal DLSCH
    // FDD normal ULSCH/DLSCH
    if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
      switch (mac_xface->lte_frame_parms->tdd_config) {
      case 0:
        break;

      case 1:
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
        //  schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      case 6:
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
        //  schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      case 5:
        schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE);
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
        break;

      case 3:
      case 4:
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      default:
        break;
      }
    } else { //FDD
      //      schedule_ulsch(module_idP,frameP,cooperation_flag,6,0,nCCE);
      schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
    }

    break;

  case 7:

    // TDD Config 3,4,5 Normal DLSCH
    // FDD Normal UL/DLSCH
    if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
      switch (mac_xface->lte_frame_parms->tdd_config) {
      case 3:
      case 4:
        schedule_RA(module_idP,frameP,subframeP,3,nprb,nCCE);  // 3 = Msg3 subframeP, not
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
        break;

      case 5:
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      default:
        break;
      }
    } else { //FDD
      //schedule_ulsch(module_idP,frameP,cooperation_flag,7,1,nCCE);
      schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
    }

    break;

  case 8:

    // TDD Config 2,3,4,5 ULSCH for subframeP 2
    //
    // FDD Normal UL/DLSCH
    if (mac_xface->lte_frame_parms->frame_type == TDD) { // TDD
      switch (mac_xface->lte_frame_parms->tdd_config) {
      case 2:
      case 3:
      case 4:
      case 5:

        //  schedule_RA(module_idP,subframeP,nprb,nCCE);
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE);
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      default:
        break;
      }
    } else { //FDD
      //schedule_ulsch(module_idP,frameP,cooperation_flag,8,2,nCCE);
      schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
    }

    break;

  case 9:

    // TDD Config 1,3,4,6 ULSCH for subframes 3,3,3,4
    if (mac_xface->lte_frame_parms->frame_type == TDD) {
      switch (mac_xface->lte_frame_parms->tdd_config) {
      case 1:
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
        schedule_RA(module_idP,frameP,subframeP,7,nprb,nCCE);  // 7 = Msg3 subframeP, not
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status);
        break;

      case 3:
      case 4:
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE);
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      case 6:
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE);
        //schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      case 2:
      case 5:
        //schedule_RA(module_idP,frameP,subframeP,nprb,nCCE);
        schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
        break;

      default:
        break;
      }
    } else { //FDD
      //     schedule_ulsch(module_idP,frameP,cooperation_flag,9,3,nCCE);
      schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status);
    }

    break;

  }

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    DCI_pdu[CC_id]->nCCE = nCCE[CC_id];
  }

  LOG_D(MAC,"frameP %d, subframeP %d nCCE %d\n",frameP,subframeP,nCCE[0]);

  stop_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);

}
static void *s11_sgw_thread(void *args)
{
  itti_mark_task_ready(TASK_S11);

  while(1) {
    MessageDef *received_message_p = NULL;
    itti_receive_msg(TASK_S11, &received_message_p);
    assert(received_message_p != NULL);

    switch (ITTI_MSG_ID(received_message_p)) {
    case UDP_DATA_IND: {
      /* We received new data to handle from the UDP layer */
      NwRcT rc;
      udp_data_ind_t *udp_data_ind;

      udp_data_ind = &received_message_p->ittiMsg.udp_data_ind;

      S11_DEBUG("Processing new data indication from UDP\n");

      rc = nwGtpv2cProcessUdpReq(s11_sgw_stack_handle,
                                 udp_data_ind->buffer,
                                 udp_data_ind->buffer_length,
                                 udp_data_ind->peer_port,
                                 udp_data_ind->peer_address);

      DevAssert(rc == NW_OK);
    }
    break;

    case SGW_CREATE_SESSION_RESPONSE: {
      S11_DEBUG("Received create session response from S-PGW APP\n");
      s11_sgw_handle_create_session_response(
        &s11_sgw_stack_handle,
        &received_message_p->ittiMsg.sgwCreateSessionResponse);
    }
    break;

    case SGW_MODIFY_BEARER_RESPONSE: {
      S11_DEBUG("Received modify bearer response from S-PGW APP\n");
      s11_sgw_handle_modify_bearer_response(
        &s11_sgw_stack_handle,
        &received_message_p->ittiMsg.sgwModifyBearerResponse);
    }
    break;

    case SGW_DELETE_SESSION_RESPONSE: {
      S11_DEBUG("Received delete session response from S-PGW APP\n");
      s11_sgw_handle_delete_session_response(
        &s11_sgw_stack_handle,
        &received_message_p->ittiMsg.sgwDeleteSessionResponse);
    }
    break;

    case TIMER_HAS_EXPIRED: {
      S11_DEBUG("Processing timeout for timer_id 0x%lx and arg %p\n",
                received_message_p->ittiMsg.timer_has_expired.timer_id,
                received_message_p->ittiMsg.timer_has_expired.arg);
      DevAssert(nwGtpv2cProcessTimeout(received_message_p->ittiMsg.timer_has_expired.arg) == NW_OK);
    }
    break;

    default: {
      S11_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;
}
//------------------------------------------------------------------------------
static void *eNB_app_task(void *args_p)
//------------------------------------------------------------------------------
{
  const Enb_properties_array_t   *enb_properties_p  = NULL;
  uint32_t                        enb_nb = 1; /* Default number of eNB is 1 */
  uint32_t                        enb_id_start = 0;
  uint32_t                        enb_id_end = enb_id_start + enb_nb;
  uint32_t                        register_enb_pending;
  uint32_t                        registered_enb;
  long                            enb_register_retry_timer_id;
  MessageDef                     *msg_p           = NULL;
  const char                     *msg_name        = NULL;
  instance_t                      instance;
  int                             result;

  itti_mark_task_ready (TASK_ENB_APP);

  enb_properties_p = enb_config_get();

  AssertFatal (enb_nb <= enb_properties_p->number,
               "Number of eNB is greater than eNB defined in configuration file (%d/%d)!",
               enb_nb, enb_properties_p->number);


  /* Try to register each eNB */
  registered_enb = 0;
  register_enb_pending = eNB_app_register (enb_id_start, enb_id_end, enb_properties_p);

  do {
    // Wait for a message
    itti_receive_msg (TASK_ENB_APP, &msg_p);

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

    switch (ITTI_MSG_ID(msg_p)) {
    case TERMINATE_MESSAGE:
      itti_exit_task ();
      break;

    case MESSAGE_TEST:
      LOG_I(ENB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p));
      break;


    case S1AP_REGISTER_ENB_CNF:
      LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
            S1AP_REGISTER_ENB_CNF(msg_p).nb_mme);

      DevAssert(register_enb_pending > 0);
      register_enb_pending--;

      /* Check if at least eNB is registered with one MME */
      if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) {
        registered_enb++;
      }

      /* Check if all register eNB requests have been processed */
      if (register_enb_pending == 0) {
        if (registered_enb == enb_nb) {
          mme_test_s1_start_test(instance);


        } else {
          uint32_t not_associated = enb_nb - registered_enb;

          LOG_W(ENB_APP, " %d eNB %s not associated with a MME, retrying registration in %d seconds ...\n",
                not_associated, not_associated > 1 ? "are" : "is", ENB_REGISTER_RETRY_DELAY);

          /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */
          if (timer_setup (ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
                           NULL, &enb_register_retry_timer_id) < 0) {
            LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n");

            sleep(ENB_REGISTER_RETRY_DELAY);
            /* Restart the registration process */
            registered_enb = 0;
            register_enb_pending = eNB_app_register (enb_id_start, enb_id_end, enb_properties_p);
          }
        }
      }

      break;

    case S1AP_DEREGISTERED_ENB_IND:
      LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
            S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme);

      /* TODO handle recovering of registration */
      break;

    case TIMER_HAS_EXPIRED:
      LOG_I(ENB_APP, " Received %s: timer_id %d\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);

      if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) {
        /* Restart the registration process */
        registered_enb = 0;
        register_enb_pending = eNB_app_register (enb_id_start, enb_id_end, enb_properties_p);
      }

      break;

    default:
      LOG_E(ENB_APP, "Received unexpected message %s\n", msg_name);
      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;
}
示例#18
0
void *nas_ue_task(void *args_p) {
  int                   nb_events;
  struct epoll_event   *events;
  MessageDef           *msg_p;
  const char           *msg_name;
  instance_t            instance;
  unsigned int          Mod_id;
  int                   result;

  itti_mark_task_ready (TASK_NAS_UE);

  /* Initialize UE NAS (EURECOM-NAS) */
  {
    /* Initialize user interface (to exchange AT commands with user process) */
    {
      if (user_api_initialize (NAS_PARSER_DEFAULT_USER_HOSTNAME, NAS_PARSER_DEFAULT_USER_PORT_NUMBER, NULL,
                               NULL) != RETURNok) {
        LOG_E(NAS, "[UE] user interface initialization failed!");
        exit (EXIT_FAILURE);
      }
      user_fd = user_api_get_fd ();
      itti_subscribe_event_fd (TASK_NAS_UE, user_fd);
    }

    /* Initialize NAS user */
    nas_user_initialize (&user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION);
  }

  /* Set UE activation state */
  for (instance = NB_eNB_INST; instance < (NB_eNB_INST + NB_UE_INST); instance++)
  {
      MessageDef *message_p;

      message_p = itti_alloc_new_message(TASK_NAS_UE, DEACTIVATE_MESSAGE);
      itti_send_msg_to_task(TASK_L2L1, instance, message_p);
  }

  while(1) {
    // Wait for a message or an event
    itti_receive_msg (TASK_NAS_UE, &msg_p);

    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
      Mod_id = instance - NB_eNB_INST;

      switch (ITTI_MSG_ID(msg_p)) {
        case INITIALIZE_MESSAGE:
          LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, msg_name);
#if (NAS_UE_AUTOSTART != 0)
          {
            /* Send an activate modem command to NAS like UserProcess should do it */
            char *user_data = "at+cfun=1\r";

            nas_user_receive_and_process (&user_fd, user_data);
          }
#endif
          break;

        case TERMINATE_MESSAGE:
          itti_exit_task ();
          break;

        case MESSAGE_TEST:
          LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, msg_name);
          break;

        case NAS_CELL_SELECTION_CNF:
          LOG_I(NAS, "[UE %d] Received %s: errCode %u, cellID %u, tac %u\n", Mod_id, msg_name,
                NAS_CELL_SELECTION_CNF (msg_p).errCode, NAS_CELL_SELECTION_CNF (msg_p).cellID, NAS_CELL_SELECTION_CNF (msg_p).tac);

          {
            int cell_found = (NAS_CELL_SELECTION_CNF (msg_p).errCode == AS_SUCCESS);

            nas_proc_cell_info (cell_found, NAS_CELL_SELECTION_CNF (msg_p).tac,
                                NAS_CELL_SELECTION_CNF (msg_p).cellID, NAS_CELL_SELECTION_CNF (msg_p).rat,
                                NAS_CELL_SELECTION_CNF (msg_p).rsrq, NAS_CELL_SELECTION_CNF (msg_p).rsrp);
          }
          break;

        case NAS_CELL_SELECTION_IND:
          LOG_I(NAS, "[UE %d] Received %s: cellID %u, tac %u\n", Mod_id, msg_name,
                NAS_CELL_SELECTION_IND (msg_p).cellID, NAS_CELL_SELECTION_IND (msg_p).tac);

          /* TODO not processed by NAS currently */
          break;

        case NAS_PAGING_IND:
          LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, msg_name,
                NAS_PAGING_IND (msg_p).cause);

          /* TODO not processed by NAS currently */
          break;

        case NAS_CONN_ESTABLI_CNF:
          LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id, msg_name,
                NAS_CONN_ESTABLI_CNF (msg_p).errCode, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);

          if ((NAS_CONN_ESTABLI_CNF (msg_p).errCode == AS_SUCCESS)
              || (NAS_CONN_ESTABLI_CNF (msg_p).errCode == AS_TERMINATED_NAS)) {
            nas_proc_establish_cnf(NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.data, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);

            /* TODO checks if NAS will free the nas message, better to do it there anyway! */
            // result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data);
            // AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
          }
          break;

        case NAS_CONN_RELEASE_IND:
          LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, msg_name,
                NAS_CONN_RELEASE_IND (msg_p).cause);

          nas_proc_release_ind (NAS_CONN_RELEASE_IND (msg_p).cause);
          break;

        case NAS_UPLINK_DATA_CNF:
          LOG_I(NAS, "[UE %d] Received %s: UEid %u, errCode %u\n", Mod_id, msg_name,
                NAS_UPLINK_DATA_CNF (msg_p).UEid, NAS_UPLINK_DATA_CNF (msg_p).errCode);

          if (NAS_UPLINK_DATA_CNF (msg_p).errCode == AS_SUCCESS) {
            nas_proc_ul_transfer_cnf ();
          } else {
            nas_proc_ul_transfer_rej ();
          }
          break;

        case NAS_DOWNLINK_DATA_IND:
          LOG_I(NAS, "[UE %d] Received %s: UEid %u, length %u\n", Mod_id, msg_name,
                NAS_DOWNLINK_DATA_IND (msg_p).UEid, NAS_DOWNLINK_DATA_IND (msg_p).nasMsg.length);

          nas_proc_dl_transfer_ind (NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length);

          if (0) {
          /* TODO checks if NAS will free the nas message, better to do it there anyway! */
          result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data);
          AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
          }
          break;

        default:
          LOG_E(NAS, "[UE %d] Received unexpected message %s\n", Mod_id, msg_name);
          break;
      }

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

    nb_events = itti_get_events(TASK_NAS_UE, &events);
    if ((nb_events > 0) && (events != NULL)) {
      if (nas_ue_process_events(events, nb_events) == TRUE) {
        LOG_E(NAS, "[UE] Received exit loop\n");
      }
    }
  }
}