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;
}
void
recv_callback (
  uint8_t * buffer,
  uint32_t length)
{
  uint8_t                                *bufferS;
  uint32_t                                len;

  s1ap_eNB_generate_initial_ue_message (&bufferS, &len);
  sctp_send_msg (assoc[0], 1, bufferS, len);
}
int s1ap_eNB_generate_s1_setup_request(struct s1ap_eNB_description_s* eNB_ref) {

    SupportedTAs_Item_t ta;
    PLMNidentity_t plmnIdentity;
    S1SetupRequestIEs_t s1SetupRequest;

    char tac[] = { 0x00, 0x01 };
    char identity[] = { 0x02, 0x08, 0x34 };
    char eNBname[150];
    int eNBnameLength = 0;
    uint8_t *buffer;
    uint32_t len;

    if (eNB_ref == NULL) return -1;

    memset((void *)&s1SetupRequest, 0, sizeof(S1SetupRequestIEs_t));
    s1SetupRequest.global_ENB_ID.eNB_ID.present = ENB_ID_PR_macroENB_ID;
    s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.buf = calloc(1,3);
    s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[0] = eNB_ref->eNB_id;
    s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.size = 3;
    s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.bits_unused = 4;
    OCTET_STRING_fromBuf(&s1SetupRequest.global_ENB_ID.pLMNidentity, identity, 3);

    eNBnameLength = sprintf(eNBname, "eNB %d Eurecom", eNB_ref->eNB_id);
    if (eNBnameLength > 0) {
        s1SetupRequest.presenceMask |= S1SETUPREQUESTIES_ENBNAME_PRESENT;
        OCTET_STRING_fromBuf(&s1SetupRequest.eNBname, eNBname, eNBnameLength);
    }

    memset((void *)&ta, 0, sizeof(SupportedTAs_Item_t));
    memset((void *)&plmnIdentity, 0, sizeof(PLMNidentity_t));
    OCTET_STRING_fromBuf(&ta.tAC, tac, 2);
    OCTET_STRING_fromBuf(&plmnIdentity, identity, 3);
    ASN_SEQUENCE_ADD(&ta.broadcastPLMNs, &plmnIdentity);
    ASN_SEQUENCE_ADD(&s1SetupRequest.supportedTAs, &ta);

    s1SetupRequest.defaultPagingDRX = PagingDRX_v64;

    if (s1ap_eNB_encode_s1_setup_request(&s1SetupRequest, &buffer, &len) < 0)
        return -1;
    eNB_ref->state |= S1AP_ENB_STATE_WAITING;
    return sctp_send_msg(eNB_ref->assocId, 0, buffer, len);
}
int
main (
  int argc,
  char *argv[])
{
  asn_enc_rval_t                          retVal;
  uint8_t                                *buffer;
  uint32_t                                len;
  SupportedTAs_Item_t                     ta;
  PLMNidentity_t                          plmnIdentity;

  asn_debug = 0;
  asn1_xer_print = 0;
  S1SetupRequestIEs                       s1SetupRequest;

  memset (&s1SetupRequest, 0, sizeof (S1SetupRequestIEs));
  s1SetupRequest.global_ENB_ID.eNB_ID.present = ENB_ID_PR_macroENB_ID;
  s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.buf = id;
  s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.size = 3;
  s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.bits_unused = 4;
  OCTET_STRING_fromBuf (&s1SetupRequest.global_ENB_ID.pLMNidentity, identity, 3);
  s1SetupRequest.presenceMask |= S1SETUPREQUESTIES_ENBNAME_PRESENT;
  OCTET_STRING_fromBuf (&s1SetupRequest.eNBname, "ENB 1 eurecom", strlen ("ENB 1 eurecom"));
  memset (&ta, 0, sizeof (SupportedTAs_Item_t));
  memset (&plmnIdentity, 0, sizeof (PLMNidentity_t));
  OCTET_STRING_fromBuf (&ta.tAC, tac, 2);
  OCTET_STRING_fromBuf (&plmnIdentity, identity, 3);
  ASN_SEQUENCE_ADD (&ta.broadcastPLMNs, &plmnIdentity);
  ASN_SEQUENCE_ADD (&s1SetupRequest.supportedTAs, &ta);
  s1SetupRequest.defaultPagingDRX = PagingDRX_v64;
  s1ap_eNB_encode_s1setuprequest (&s1SetupRequest, &buffer, &len);
  assoc[0] = sctp_connect_to_remote_host (ip_addr, 36412, &recv_callback);
  sctp_send_msg (0, 0, buffer, len);
  free (buffer);
  //     generateUplinkNASTransport(&buffer, &len);
  //     sctp_send_msg(assoc[0], 0, buffer, len);
  //     s1ap_mme_decode_pdu(buffer, len);
  pthread_join (sctp_get_receiver_thread (assoc[0]), NULL);
  return (0);
}
int s1ap_eNB_generate_initial_ue_message(struct s1ap_eNB_UE_description_s *ue_ref,
                                         uint8_t                          *nas_pdu,
                                         uint32_t                          nas_len) {
    InitialUEMessageIEs_t  initialUEmessageIEs;
    InitialUEMessageIEs_t *initialUEmessageIEs_p = &initialUEmessageIEs;
    uint8_t  *buffer;
    uint32_t  len;

    char tac[] = { 0x00, 0x01 };
    uint8_t id[] = { 0x03, 0x56, 0xf0, 0xd8 };
    char identity[] = { 0x02, 0x08, 0x34 };

    memset((void *)initialUEmessageIEs_p, 0, sizeof(InitialUEMessageIEs_t));

    initialUEmessageIEs.eNB_UE_S1AP_ID = ue_ref->eNB_UE_s1ap_id;
    initialUEmessageIEs.nas_pdu.buf = nas_pdu;
    initialUEmessageIEs.nas_pdu.size = nas_len;

    initialUEmessageIEs.tai.tAC.buf = (uint8_t*)tac;
    initialUEmessageIEs.tai.tAC.size = 2;
    initialUEmessageIEs.tai.pLMNidentity.buf = (uint8_t*)identity;
    initialUEmessageIEs.tai.pLMNidentity.size = 3;
    initialUEmessageIEs.eutran_cgi.pLMNidentity.buf = (uint8_t*)identity;
    initialUEmessageIEs.eutran_cgi.pLMNidentity.size = 3;
    initialUEmessageIEs.eutran_cgi.cell_ID.buf = (uint8_t*)id;
    initialUEmessageIEs.eutran_cgi.cell_ID.size = 4;
    initialUEmessageIEs.eutran_cgi.cell_ID.bits_unused = 4;

    initialUEmessageIEs.rrC_Establishment_Cause = RRC_Establishment_Cause_mo_Data;

    if (s1ap_eNB_encode_initial_ue_message(initialUEmessageIEs_p, &buffer, &len) < 0) {
        if (buffer != NULL) free(buffer);
        return -1;
    }
    /* Send encoded message over sctp */
    return sctp_send_msg(ue_ref->eNB->assocId, ue_ref->stream_send, buffer, len);
}