示例#1
0
static void
sound_nas_finish(ad_device_data *data)
{
	sound_nas_data_t *snd = data;

	NAS_DEBUG("finishing NAS\n");

	if (snd->aud) {
		NAS_DEBUG("closing 0x%x\n", (unsigned int)snd->aud);
		AuCloseServer(snd->aud);
	}
	snd->aud = NULL;

	NAS_DEBUG("audio-device finished.\n");

	return;
}
int nas_init(mme_config_t *mme_config_p)
{
  NAS_DEBUG("Initializing NAS task interface\n");

#if !defined(DISABLE_USE_NAS)
  nas_log_init(0x3F);
  nas_network_initialize(mme_config_p);
#endif

  if (itti_create_task(TASK_NAS_MME, &nas_intertask_interface,
                       NULL) < 0) {
    NAS_ERROR("Create task failed");
    NAS_DEBUG("Initializing NAS task interface: FAILED\n");
    return -1;
  }

  NAS_DEBUG("Initializing NAS task interface: DONE\n");
  return 0;
}
示例#3
0
static ad_device_data *
sound_nas_create(Lisp_Object nas_options)
{
	sound_nas_data_t *snd;
	char *server[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
	int i, server_cnt = 0;
	AuServer *aud = NULL;
	Lisp_Object opt_server = Qnil;

	/* parse options */
	opt_server = Fplist_get(nas_options, intern(":server"), Qnil);
	if (!NILP(opt_server) && !STRINGP(opt_server) && !DEVICEP(opt_server)) {
		wrong_type_argument(Qstringp, opt_server);
		return NULL;
	}

	if (NILP(opt_server))
		nas_setup_defaults(server, &server_cnt);
	else if (STRINGP(opt_server))
		server[server_cnt++] = (char*)XSTRING_DATA(opt_server);
#ifdef HAVE_X_WINDOWS
	else if (DEVICEP(opt_server) && DEVICE_X_P(XDEVICE(opt_server)))
		server[server_cnt++] =
			(char*)XSTRING_DATA(
				DEVICE_CONNECTION(XDEVICE(opt_server)));
#endif

	NAS_DEBUG("trying %d connections\n", server_cnt);
	for (i = 0; i<server_cnt; i++)
		if ((aud = nas_try_connection(server[i])))
			break;

	if (!aud) {
		NAS_DEBUG_C("cannot contact any NAS server\n");
		warn_when_safe(Qnas, Qwarning,
			       GETTEXT("No NAS servers in sight.\n"));
		return NULL; /* Could not contact NAS server */
	}


	/* -- initialise -- */
	snd = xnew_and_zero(sound_nas_data_t);
	snd->aud = aud;

	/* round up SOUND_MAX_AUDIO_FRAME_SIZE to multiple of NAS_FRAG_SIZE
	 * divide by 3 first because of 2:1 split */
	snd->proposed_buffer_size =
		(SOUND_MAX_AUDIO_FRAME_SIZE/3 + NAS_FRAG_SIZE-1)
		& ~(NAS_FRAG_SIZE-1);
	NAS_DEBUG_C("proposed buffer size: %u\n", snd->proposed_buffer_size);

	NAS_DEBUG_C("created: 0x%x\n", (unsigned int)snd);

	return snd;
}
示例#4
0
static void
nas_setup_defaults(char **server, int *cnt)
{
	int i;
	Lisp_Object tmp;

	/* considering some defaults */
	NAS_DEBUG("trying to find some defaults\n");

#ifdef HAVE_X_WINDOWS
	/* check for the device connection of the currently active frame */
	tmp = Fselected_device(Qnil);
	if (DEVICEP(tmp) && DEVICE_X_P(XDEVICE(tmp)))
		server[(*cnt)++] =
			(char*)XSTRING_DATA(
				DEVICE_CONNECTION(XDEVICE(tmp)));

	/* tbd: check for conn of the initial frame */
#endif

	/* try to look for $AUDIOSERVER */
	if ((server[(*cnt)] = getenv("AUDIOSERVER"))) {
		/* only add the stuff, if not already in the try queue */
		for (i=0; i < (*cnt); i++)
			if (strcmp(server[i], server[(*cnt)]) == 0)
				break;
		if (i == (*cnt))
			(*cnt)++;
	}
	/* try to look for $DISPLAY */
	if ((server[(*cnt)] = getenv("DISPLAY"))){
		/* only add the stuff, if not already in the try queue */
		for (i=0; i < (*cnt); i++)
			if (strcmp(server[i], server[(*cnt)]) == 0)
				break;
		if (i == (*cnt))
			(*cnt)++;
	}

	/* oh, let's try localhost:0.0, if not already there of course */
	for (i=0; i < (*cnt); i++)
		if (strcmp(server[i], "localhost:0.0") == 0)
			break;
	if (i == (*cnt))
		server[(*cnt)++] = "localhost:0.0";

	/* finally we try NULL, too */
	server[(*cnt)++] = NULL;

	return;
}
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;
}
示例#6
0
static int
sound_nas_play(audio_job_t aj)
{
	/* stream stuff */
	Lisp_Media_Stream *ms;
	media_substream *mss;
	/* thread stuff */
	media_thread_play_state mtp;
	/* device stuff */
	Lisp_Object device;
	Lisp_Audio_Device *lad = NULL;
	sound_nas_data_t *snd = NULL;
	/* nas stuff */
	AuElement elms[3];
	AuStatus as;
	int bsize = 0;
	/* subthread stuff */
	sound_nas_aj_data_t _snsd, *snsd = &_snsd;
	sxe_mse_volume_args _volargs, *volargs = &_volargs;
	sxe_mse_rerate_args _rrargs, *rrargs = &_rrargs;
	/* cache stuff */
	int alloced_myself = 0;

	SOUND_UNPACK_MT(aj, device, ms, mss, lad, snd, snsd->mtap);

	/* refuse to do anything if the AuServer pointer is not set */
	if (snd->aud == NULL) {
		NAS_DEBUG_C("b0rked connection, gute Nacht!\n");
		return 0;
	}

	/* install error handlers before anything else */
	AuSetErrorHandler(snd->aud, nas_error_handler);
	AuSetIOErrorHandler(snd->aud, nas_IOerror_handler);

	/* find physical output device */
	snsd->dev = nas_find_device(snd->aud, snsd->mtap->channels);

	if (snsd->dev == AuNone ||
	    !(snsd->flow = AuCreateFlow(snd->aud, NULL))) {
		/* No physical output device found or flow creation failed. */
		NAS_DEBUG_C("no physical devices for this stream\n");
		return 0;
	}

	/* A system call interrupted with a SIGALRM or SIGIO
	   comes back here */
	if (SETJMP(nas_server_sig)) {
		NAS_CRITICAL("Caught the lethal signal.\n");
		snd->aud = NULL;
		sound_nas_finish(snd);
		goto uhoh;
	}

	/* init the snsd */
	snsd->samplerate = 0;
	snsd->framesize = (snsd->channels = snsd->mtap->channels)
		* sizeof(int16_t);
	snsd->msf = MEDIA_SAMPLE_FORMAT(sxe_msf_S16);
	snsd->coe_ch_cnt = 0;
	snsd->resolution =
		(snsd->mtap->samplerate * MTPSTATE_REACT_TIME) / 1000000;
	bsize = (snsd->resolution + NAS_FRAG_SIZE - 1) & ~(NAS_FRAG_SIZE-1);

	snsd->snd = snd;
	snsd->buffer_size = bsize;
	snsd->writepos = snsd->readpos = 0;
	snsd->overfill = snsd->underrun = 0;

	/* set up flow */
	AuMakeElementImportClient(elms+0, snsd->mtap->samplerate,
				  AuFormatLinearSigned16LSB,
				  snsd->mtap->channels,
				  AuTrue,
				  bsize, bsize / 2,
				  0, NULL);
	snsd->gain = AuFixedPointFromFraction(1, 1);
	AuMakeElementMultiplyConstant(elms+1, 0, snsd->gain);
	AuMakeElementExportDevice(elms+2, 0, snsd->dev,
				  snsd->mtap->samplerate,
				  AuUnlimitedSamples, 0, NULL);
	AuSetElements(snd->aud, snsd->flow, AuTrue, 3, elms, &as);

	if (as != AuSuccess) {
		NAS_DEBUG_C("play(): AuSetElements failed\n");
		return 0;
	}

#if 0				/* atm we insist on having stereo access */
	/* the channel effect */
	ADD_MEDIA_SAMPLE_EFFECT(
		snsd->coe_chain, snsd->coe_ch_cnt,
		MEDIA_SAMPLE_EFFECT(sxe_mse_2ch_to_1ch), NULL);
#endif

	/* the volume effect */
	ADD_MEDIA_SAMPLE_EFFECT(
		snsd->coe_chain, snsd->coe_ch_cnt,
		MEDIA_SAMPLE_EFFECT(sxe_mse_volume), volargs);
	volargs->num_channels = snsd->channels;
	snsd->volargs = volargs;

	/* the rerate effect */
	ADD_MEDIA_SAMPLE_EFFECT(
		snsd->coe_chain, snsd->coe_ch_cnt,
		MEDIA_SAMPLE_EFFECT(sxe_mse_rerate), rrargs);
	rrargs->num_channels = snsd->channels;
	rrargs->srcrate = rrargs->tgtrate = 1;
	snsd->rrargs = rrargs;

	AuRegisterEventHandler(snd->aud, AuEventHandlerIDMask |
			       AuEventHandlerTypeMask,
			       AuEventTypeElementNotify, snsd->flow,
			       nas_event_handler, (AuPointer)aj);

	/* rewind the stream */
	media_stream_meth(ms, rewind)(mss);

	/* play chunks of the stream */
	SXE_MUTEX_LOCK(&aj->mtx);
	if (aj->buffer_alloc_size < SOUND_MAX_AUDIO_FRAME_SIZE) {
		alloced_myself = 1;
		aj->buffer = xmalloc_atomic(SOUND_MAX_AUDIO_FRAME_SIZE);
		aj->buffer_alloc_size = SOUND_MAX_AUDIO_FRAME_SIZE;
	}
	SXE_MUTEX_UNLOCK(&aj->mtx);
	snsd->mtp = MTPSTATE_STOP;
	snsd->volume = -1;
	audio_job_device_data(aj) = snsd;

	/* prefill the buffer */
	NAS_DEBUG_S("prefill the buffer: %d\n", 4*bsize);
	if (!nas_fill(aj, 4*bsize))
		goto uhoh;

	while (aj->play_state != MTPSTATE_STOP) {

#if 0
		if (aj->volume != snsd->volume) {
			AuElementParameters aep;
			NAS_DEBUG_S("Setting volume.\n");
			snsd->volume = aj->volume;
			snsd->gain = AU_FIXED_POINT_SCALE*(snsd->volume)/127;
			aep.parameters[AuParmsMultiplyConstantConstant] =
				snsd->gain;
			aep.flow = snd->flow;
			aep.element_num = 1;
			aep.num_parameters = AuParmsMultiplyConstant;

			AuSetElementParameters(snd->aud, 1, &aep, &as);
			if (as != AuSuccess) {
				NAS_DEBUG_S("Setting volume failed.\n");
			}
		}
#endif

#ifdef EF_USE_ASYNEQ
		/* events for me audio-job? */
		if (audio_job_queue(aj)) {
			sound_nas_handle_aj_events(aj);
		}
#endif

		SXE_MUTEX_LOCK(&aj->mtx);
		mtp = aj->play_state;
		SXE_MUTEX_UNLOCK(&aj->mtx);
		switch (mtp) {
		case MTPSTATE_RUN:
			if (snsd->mtp != mtp) {
				NAS_DEBUG("ah, gotta work again\n");
				AuStartFlow(snd->aud, snsd->flow, &as);
				if (as != AuSuccess) {
					NAS_DEBUG_C("play(): "
						    "AuStartFlow failed\n");
					aj->play_state = MTPSTATE_STOP;
				}
			}
			nas_empty_event_queue(snsd);
			usleep(snsd->resolution);
			break;
		case MTPSTATE_PAUSE:
			if (snsd->mtp != mtp) {
				NAS_DEBUG("sleeping for %d\n",
					  snsd->resolution);
				AuStopFlow(snd->aud, snsd->flow, &as);
			}
			usleep(snsd->resolution);
			break;

		case MTPSTATE_UNKNOWN:
		case MTPSTATE_STOP:
		case NUMBER_OF_MEDIA_THREAD_PLAY_STATES:
		default:
			NAS_DEBUG("ACK, quit\n");
			AuStopFlow(snd->aud, snsd->flow, &as);
			SXE_MUTEX_LOCK(&aj->mtx);
			aj->play_state = MTPSTATE_STOP;
			SXE_MUTEX_UNLOCK(&aj->mtx);
			break;
		}
		snsd->mtp = mtp;
	}

uhoh:
	/* -- Close and shutdown -- */
	SXE_MUTEX_LOCK(&aj->mtx);
	if (alloced_myself && aj->buffer) {
		xfree(aj->buffer);
	}
	aj->buffer = NULL;
	aj->buffer_alloc_size = 0;
	SXE_MUTEX_UNLOCK(&aj->mtx);

	return 1;
}