Exemple #1
0
size_t wave_write(void *theHandler, char *theMono16BitsWaveBuffer, size_t theSize)
{
	(void)theHandler; // unused

	size_t bytes_written = 0;
	// space in ringbuffer for the sample needed: 1x mono channel but 2x for 1 stereo channel
	size_t bytes_to_write = (out_channels == 1) ? theSize : theSize*2;
	my_stream_could_start = 0;

	if (pa_stream == NULL) {
		if (0 != wave_open_sound())
			return 0;
		my_stream_could_start = 1;
	} else if (!wave_is_busy(NULL))
		my_stream_could_start = 1;
	assert(BUFFER_LENGTH >= bytes_to_write);

	if (myWrite >= myBuffer + BUFFER_LENGTH)
		myWrite = myBuffer;

	size_t aTotalFreeMem = 0;
	char *aRead;

	while (1) {
		if (my_callback_is_output_enabled && (0 == my_callback_is_output_enabled()))
			return 0;

		aRead = myRead;

		// write pointer is before read pointer?
		if (myWrite >= aRead)
			aTotalFreeMem = aRead + BUFFER_LENGTH - myWrite;
		else // read pointer is before write pointer!
			aTotalFreeMem = aRead - myWrite;

		if (aTotalFreeMem > 1) {
			// -1 because myWrite must be different of aRead
			// otherwise buffer would be considered as empty
			aTotalFreeMem -= 1;
		}

		if (aTotalFreeMem >= bytes_to_write)
			break;

		usleep(10000);
	}

	aRead = myRead;

	// write pointer is ahead the read pointer?
	if (myWrite >= aRead) {
		// determine remaining free memory to the end of the ringbuffer
		size_t aFreeMem = myBuffer + BUFFER_LENGTH - myWrite;
		// is enough linear space available (regardless 1 or 2 channels)?
		if (aFreeMem >= bytes_to_write) {
			// copy direct - no wrap around at end of ringbuffer needed
			myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer, theSize);
		} else { // not enough linear space available
			     // 2 channels (stereo)?
			if (out_channels == 2) {
				// copy with wrap around at the end of ringbuffer
				copyBuffer(myWrite, theMono16BitsWaveBuffer, aFreeMem/2);
				myWrite = myBuffer;
				myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer+aFreeMem/2, theSize - aFreeMem/2);
			} else { // 1 channel (mono)
				// copy with wrap around at the end of ringbuffer
				copyBuffer(myWrite, theMono16BitsWaveBuffer, aFreeMem);
				myWrite = myBuffer;
				myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer+aFreeMem, theSize - aFreeMem);
			}
		}
	} else // read pointer is ahead the write pointer
		myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer, theSize);

	bytes_written = bytes_to_write;
	myWritePosition += theSize/sizeof(uint16_t); // add number of samples

	if (my_stream_could_start && (get_used_mem() >= out_channels * sizeof(uint16_t) * FRAMES_PER_BUFFER))
		start_stream();

	return bytes_written;
}
Exemple #2
0
static void
doit(int f,
	struct sockaddr_storage *fromp,
	krb5_context krb_context,
	int encr_flag,
	krb5_keytab keytab)
{
	int p, t, on = 1;
	char c;
	char abuf[INET6_ADDRSTRLEN];
	struct sockaddr_in *sin;
	struct sockaddr_in6 *sin6;
	int fromplen;
	in_port_t port;
	struct termios tp;
	boolean_t bad_port;
	boolean_t no_name;
	char rhost_addra[INET6_ADDRSTRLEN];

	if (!(rlbuf = malloc(BUFSIZ))) {
		syslog(LOG_ERR, "rlbuf malloc failed\n");
		exit(EXIT_FAILURE);
	}
	(void) alarm(60);
	if (read(f, &c, 1) != 1 || c != 0) {
		syslog(LOG_ERR, "failed to receive protocol zero byte\n");
		exit(EXIT_FAILURE);
	}
	(void) alarm(0);
	if (fromp->ss_family == AF_INET) {
		sin = (struct sockaddr_in *)fromp;
		port = sin->sin_port = ntohs((ushort_t)sin->sin_port);
		fromplen = sizeof (struct sockaddr_in);

		if (!inet_ntop(AF_INET, &sin->sin_addr,
			    rhost_addra, sizeof (rhost_addra)))
			goto badconversion;
	} else if (fromp->ss_family == AF_INET6) {
		sin6 = (struct sockaddr_in6 *)fromp;
		port = sin6->sin6_port = ntohs((ushort_t)sin6->sin6_port);
		fromplen = sizeof (struct sockaddr_in6);

		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
			struct in_addr ipv4_addr;

			IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr,
					    &ipv4_addr);
			if (!inet_ntop(AF_INET, &ipv4_addr, rhost_addra,
				    sizeof (rhost_addra)))
				goto badconversion;
		} else {
			if (!inet_ntop(AF_INET6, &sin6->sin6_addr,
				    rhost_addra, sizeof (rhost_addra)))
				goto badconversion;
		}
	} else {
		syslog(LOG_ERR, "unknown address family %d\n",
		    fromp->ss_family);
		fatal(f, "Permission denied");
	}

	/*
	 * Allow connections only from the "ephemeral" reserved
	 * ports(ports 512 - 1023) by checking the remote port
	 * because other utilities(e.g. in.ftpd) can be used to
	 * allow a unprivileged user to originate a connection
	 * from a privileged port and provide untrustworthy
	 * authentication.
	 */
	bad_port = (use_auth != KRB5_RECVAUTH_V5 &&
		    (port >= (in_port_t)IPPORT_RESERVED) ||
		    (port < (in_port_t)(IPPORT_RESERVED/2)));
	no_name = getnameinfo((const struct sockaddr *) fromp,
			    fromplen, hostname, sizeof (hostname),
			    NULL, 0, 0) != 0;

	if (no_name || bad_port) {
		(void) strlcpy(abuf, rhost_addra, sizeof (abuf));
		/* If no host name, use IP address for name later on. */
		if (no_name)
			(void) strlcpy(hostname, abuf, sizeof (hostname));
	}

	if (!no_name) {
		/*
		 * Even if getnameinfo() succeeded, we still have to check
		 * for spoofing.
		 */
		check_address("rlogind", fromp, sin, sin6, rhost_addra,
		    hostname, sizeof (hostname));
	}

	if (bad_port) {
		if (no_name)
			syslog(LOG_NOTICE,
			    "connection from %s - bad port\n",
			    abuf);
		else
			syslog(LOG_NOTICE,
			    "connection from %s(%s) - bad port\n",
			    hostname, abuf);
		fatal(f, "Permission denied");
	}

	if (use_auth == KRB5_RECVAUTH_V5) {
		do_krb_login(f, rhost_addra, hostname,
			    krb_context, encr_flag, keytab);
		if (krusername != NULL && strlen(krusername)) {
			/*
			 * Kerberos Authentication succeeded,
			 * so set the proper program name to use
			 * with pam (important during 'cleanup'
			 * routine later).
			 */
			pam_prog_name = KRB5_PROG_NAME;
		}
	}

	if (write(f, "", 1) != 1) {
		syslog(LOG_NOTICE,
		    "send of the zero byte(to %s) failed:"
		    " cannot start data transfer mode\n",
		    (no_name ? abuf : hostname));
		exit(EXIT_FAILURE);
	}
	if ((p = open("/dev/ptmx", O_RDWR)) == -1)
		fatalperror(f, "cannot open /dev/ptmx");
	if (grantpt(p) == -1)
		fatal(f, "could not grant slave pty");
	if (unlockpt(p) == -1)
		fatal(f, "could not unlock slave pty");
	if ((line = ptsname(p)) == NULL)
		fatal(f, "could not enable slave pty");
	if ((t = open(line, O_RDWR)) == -1)
		fatal(f, "could not open slave pty");
	if (ioctl(t, I_PUSH, "ptem") == -1)
		fatalperror(f, "ioctl I_PUSH ptem");
	if (ioctl(t, I_PUSH, "ldterm") == -1)
		fatalperror(f, "ioctl I_PUSH ldterm");
	if (ioctl(t, I_PUSH, "ttcompat") == -1)
		fatalperror(f, "ioctl I_PUSH ttcompat");
	/*
	 * POP the sockmod and push the rlmod module.
	 *
	 * Note that sockmod has to be removed since readstream assumes
	 * a "raw" TPI endpoint(e.g. it uses getmsg).
	 */
	if (removemod(f, "sockmod") < 0)
		fatalperror(f, "couldn't remove sockmod");

	if (encr_flag) {
		if (ioctl(f, I_PUSH, "cryptmod") < 0)
		    fatalperror(f, "ioctl I_PUSH rlmod");

	}

	if (ioctl(f, I_PUSH, "rlmod") < 0)
		fatalperror(f, "ioctl I_PUSH rlmod");

	if (encr_flag) {
		/*
		 * Make sure rlmod will pass unrecognized IOCTLs to cryptmod
		 */
		uchar_t passthru = 1;
		struct strioctl rlmodctl;

		rlmodctl.ic_cmd = CRYPTPASSTHRU;
		rlmodctl.ic_timout = -1;
		rlmodctl.ic_len = sizeof (uchar_t);
		rlmodctl.ic_dp = (char *)&passthru;

		if (ioctl(f, I_STR, &rlmodctl) < 0)
			fatal(f, "ioctl CRYPTPASSTHRU failed\n");
	}

	/*
	 * readstream will do a getmsg till it receives
	 * M_PROTO type T_DATA_REQ from rloginmodopen()
	 * indicating all data on the stream prior to pushing rlmod has
	 * been drained at the stream head.
	 */
	if ((nsize = readstream(f, rlbuf, BUFSIZ)) < 0)
		fatalperror(f, "readstream failed");
	/*
	 * Make sure the pty doesn't modify the strings passed
	 * to login as part of the "rlogin protocol."  The login
	 * program should set these flags to apropriate values
	 * after it has read the strings.
	 */
	if (ioctl(t, TCGETS, &tp) == -1)
		fatalperror(f, "ioctl TCGETS");
	tp.c_lflag &= ~(ECHO|ICANON);
	tp.c_oflag &= ~(XTABS|OCRNL);
	tp.c_iflag &= ~(IGNPAR|ICRNL);
	if (ioctl(t, TCSETS, &tp) == -1)
		fatalperror(f, "ioctl TCSETS");

	/*
	 * System V ptys allow the TIOC{SG}WINSZ ioctl to be
	 * issued on the master side of the pty.  Luckily, that's
	 * the only tty ioctl we need to do do, so we can close the
	 * slave side in the parent process after the fork.
	 */
	(void) ioctl(p, TIOCSWINSZ, &win);

	pid = fork();
	if (pid < 0)
		fatalperror(f, "fork");
	if (pid == 0) {
		int tt;
		struct utmpx ut;

		/* System V login expects a utmp entry to already be there */
		(void) memset(&ut, 0, sizeof (ut));
		(void) strncpy(ut.ut_user, ".rlogin", sizeof (ut.ut_user));
		(void) strncpy(ut.ut_line, line, sizeof (ut.ut_line));
		ut.ut_pid = getpid();
		ut.ut_id[0] = 'r';
		ut.ut_id[1] = (char)SC_WILDC;
		ut.ut_id[2] = (char)SC_WILDC;
		ut.ut_id[3] = (char)SC_WILDC;
		ut.ut_type = LOGIN_PROCESS;
		ut.ut_exit.e_termination = 0;
		ut.ut_exit.e_exit = 0;
		(void) time(&ut.ut_tv.tv_sec);
		if (makeutx(&ut) == NULL)
			syslog(LOG_INFO, "in.rlogind:\tmakeutx failed");

		/* controlling tty */
		if (setsid() == -1)
			fatalperror(f, "setsid");
		if ((tt = open(line, O_RDWR)) == -1)
			fatalperror(f, "could not re-open slave pty");

		if (close(p) == -1)
			fatalperror(f, "error closing pty master");
		if (close(t) == -1)
			fatalperror(f, "error closing pty slave"
				    " opened before session established");
		/*
		 * If this fails we may or may not be able to output an
		 * error message.
		 */
		if (close(f) == -1)
			fatalperror(f, "error closing deamon stdout");
		if (dup2(tt, STDIN_FILENO) == -1 ||
		    dup2(tt, STDOUT_FILENO) == -1 ||
		    dup2(tt, STDERR_FILENO) == -1)
			exit(EXIT_FAILURE);	/* Disaster! No stderr! */

		(void) close(tt);

		if (use_auth == KRB5_RECVAUTH_V5 &&
		    krusername != NULL && strlen(krusername)) {
			(void) execl(LOGIN_PROGRAM, "login",
				    "-d", line,
				    "-r", hostname,
				    "-u", krusername, /* KRB5 principal name */
				    "-s", pam_prog_name,
				    "-t", term,	/* Remote Terminal */
				    "-U", rusername,	/* Remote User */
				    "-R", KRB5_REPOSITORY_NAME,
				    lusername,  /* local user */
				    NULL);
		} else {
			(void) execl(LOGIN_PROGRAM, "login",
				"-d", line,
				"-r", hostname,
				NULL);
		}

		fatalperror(STDERR_FILENO, "/bin/login");
		/*NOTREACHED*/
	}
	(void) close(t);
	(void) ioctl(f, FIONBIO, &on);
	(void) ioctl(p, FIONBIO, &on);

	/*
	 * Must ignore SIGTTOU, otherwise we'll stop
	 * when we try and set slave pty's window shape
	 * (our controlling tty is the master pty).
	 * Likewise, we don't want any of the tty-generated
	 * signals from chars passing through.
	 */
	(void) sigset(SIGTSTP, SIG_IGN);
	(void) sigset(SIGINT, SIG_IGN);
	(void) sigset(SIGQUIT, SIG_IGN);
	(void) sigset(SIGTTOU, SIG_IGN);
	(void) sigset(SIGTTIN, SIG_IGN);
	(void) sigset(SIGCHLD, cleanup);
	(void) setpgrp();

	if (encr_flag) {
		krb5_data ivec, *ivptr;
		uint_t ivec_usage;
		stop_stream(f, CRYPT_ENCRYPT|CRYPT_DECRYPT);

		/*
		 * Configure the STREAMS crypto module.  For now,
		 * don't use any IV parameter.  KCMDV0.2 support
		 * will require the use of Initialization Vectors
		 * for both encrypt and decrypt modes.
		 */
		if (kcmd_protocol == KCMD_OLD_PROTOCOL) {
			if (session_key->enctype == ENCTYPE_DES_CBC_CRC) {
				/*
				 * This is gross but necessary for MIT compat.
				 */
				ivec.length = session_key->length;
				ivec.data = (char *)session_key->contents;
				ivec_usage = IVEC_REUSE;
				ivptr = &ivec;
			} else {
				ivptr = NULL; /* defaults to all 0's */
				ivec_usage = IVEC_NEVER;
			}
			/*
			 * configure both sides of stream together
			 * since they share the same IV.
			 * This is what makes the OLD KCMD protocol
			 * less secure than the newer one - Bad ivecs.
			 */
			if (configure_stream(f, session_key,
				CRYPT_ENCRYPT|CRYPT_DECRYPT,
				ivptr, ivec_usage) != 0)
				fatal(f, "Cannot initialize encryption -"
					" exiting.\n");
		} else {
			size_t blocksize;
			if (session_key->enctype == ENCTYPE_ARCFOUR_HMAC ||
			    session_key->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) {
				if (configure_stream(f, session_key,
					CRYPT_ENCRYPT|CRYPT_DECRYPT,
					NULL, IVEC_NEVER) != 0)
					fatal(f,
					"Cannot initialize encryption -"
					" exiting.\n");
				goto startcrypto;
			}
			if (krb5_c_block_size(krb_context,
					    session_key->enctype,
					    &blocksize)) {
				syslog(LOG_ERR, "Cannot determine blocksize "
				    "for encryption type %d",
				    session_key->enctype);
				fatal(f, "Cannot determine blocksize "
				    "for encryption - exiting.\n");
			}
			ivec.data = (char *)malloc(blocksize);
			ivec.length = blocksize;
			if (ivec.data == NULL)
				fatal(f, "memory error - exiting\n");
			/*
			 * Following MIT convention -
			 *   encrypt IV = 0x01 x blocksize
			 *   decrypt IV = 0x00 x blocksize
			 *   ivec_usage = IVEC_ONETIME
			 *
			 * configure_stream separately for encrypt and
			 * decrypt because there are 2 different IVs.
			 *
			 * AES uses 0's for IV.
			 */
			if (session_key->enctype ==
				ENCTYPE_AES128_CTS_HMAC_SHA1_96 ||
			    session_key->enctype ==
				ENCTYPE_AES256_CTS_HMAC_SHA1_96)
				(void) memset(ivec.data, 0x00, blocksize);
			else
				(void) memset(ivec.data, 0x01, blocksize);
			if (configure_stream(f, session_key, CRYPT_ENCRYPT,
				&ivec, IVEC_ONETIME) != 0)
				fatal(f, "Cannot initialize encryption -"
					" exiting.\n");
			(void) memset(ivec.data, 0x00, blocksize);
			if (configure_stream(f, session_key, CRYPT_DECRYPT,
				&ivec, IVEC_ONETIME) != 0)
				fatal(f, "Cannot initialize encryption -"
					" exiting.\n");

			(void) free(ivec.data);
		}
startcrypto:
		start_stream(f, CRYPT_ENCRYPT);
		start_stream(f, CRYPT_DECRYPT);
	}
	protocol(f, p, encr_flag);
	cleanup(0);
	/*NOTREACHED*/

badconversion:
	fatalperror(f, "address conversion");
	/*NOTREACHED*/
}
int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate)
{
	struct amdtp_stream *master, *slave;
	atomic_t *slave_substreams;
	enum cip_flags sync_mode;
	unsigned int curr_rate;
	int err = 0;

	mutex_lock(&efw->mutex);

	/* Need no substreams */
	if ((atomic_read(&efw->playback_substreams) == 0) &&
	    (atomic_read(&efw->capture_substreams)  == 0))
		goto end;

	err = get_sync_mode(efw, &sync_mode);
	if (err < 0)
		goto end;
	if (sync_mode == CIP_SYNC_TO_DEVICE) {
		master = &efw->tx_stream;
		slave  = &efw->rx_stream;
		slave_substreams  = &efw->playback_substreams;
	} else {
		master = &efw->rx_stream;
		slave  = &efw->tx_stream;
		slave_substreams = &efw->capture_substreams;
	}

	/*
	 * Considering JACK/FFADO streaming:
	 * TODO: This can be removed hwdep functionality becomes popular.
	 */
	err = check_connection_used_by_others(efw, master);
	if (err < 0)
		goto end;

	/* packet queueing error */
	if (amdtp_streaming_error(slave))
		stop_stream(efw, slave);
	if (amdtp_streaming_error(master))
		stop_stream(efw, master);

	/* stop streams if rate is different */
	err = snd_efw_command_get_sampling_rate(efw, &curr_rate);
	if (err < 0)
		goto end;
	if (rate == 0)
		rate = curr_rate;
	if (rate != curr_rate) {
		stop_stream(efw, slave);
		stop_stream(efw, master);
	}

	/* master should be always running */
	if (!amdtp_stream_running(master)) {
		amdtp_stream_set_sync(sync_mode, master, slave);
		efw->master = master;

		err = snd_efw_command_set_sampling_rate(efw, rate);
		if (err < 0)
			goto end;

		err = start_stream(efw, master, rate);
		if (err < 0) {
			dev_err(&efw->unit->device,
				"fail to start AMDTP master stream:%d\n", err);
			goto end;
		}
	}

	/* start slave if needed */
	if (atomic_read(slave_substreams) > 0 && !amdtp_stream_running(slave)) {
		err = start_stream(efw, slave, rate);
		if (err < 0) {
			dev_err(&efw->unit->device,
				"fail to start AMDTP slave stream:%d\n", err);
			stop_stream(efw, master);
		}
	}
end:
	mutex_unlock(&efw->mutex);
	return err;
}
Exemple #4
0
int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw,
				  struct amdtp_stream *stream,
				  unsigned int rate, unsigned int pcm_channels)
{
	struct amdtp_stream *opposite;
	struct snd_oxfw_stream_formation formation;
	enum avc_general_plug_dir dir;
	unsigned int substreams, opposite_substreams;
	int err = 0;

	if (stream == &oxfw->tx_stream) {
		substreams = oxfw->capture_substreams;
		opposite = &oxfw->rx_stream;
		opposite_substreams = oxfw->playback_substreams;
		dir = AVC_GENERAL_PLUG_DIR_OUT;
	} else {
		substreams = oxfw->playback_substreams;
		opposite_substreams = oxfw->capture_substreams;

		if (oxfw->has_output)
			opposite = &oxfw->rx_stream;
		else
			opposite = NULL;

		dir = AVC_GENERAL_PLUG_DIR_IN;
	}

	if (substreams == 0)
		goto end;

	/*
	 * Considering JACK/FFADO streaming:
	 * TODO: This can be removed hwdep functionality becomes popular.
	 */
	err = check_connection_used_by_others(oxfw, stream);
	if (err < 0)
		goto end;

	/* packet queueing error */
	if (amdtp_streaming_error(stream))
		stop_stream(oxfw, stream);

	err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
	if (err < 0)
		goto end;
	if (rate == 0)
		rate = formation.rate;
	if (pcm_channels == 0)
		pcm_channels = formation.pcm;

	if ((formation.rate != rate) || (formation.pcm != pcm_channels)) {
		if (opposite != NULL) {
			err = check_connection_used_by_others(oxfw, opposite);
			if (err < 0)
				goto end;
			stop_stream(oxfw, opposite);
		}
		stop_stream(oxfw, stream);

		err = set_stream_format(oxfw, stream, rate, pcm_channels);
		if (err < 0) {
			dev_err(&oxfw->unit->device,
				"fail to set stream format: %d\n", err);
			goto end;
		}

		/* Start opposite stream if needed. */
		if (opposite && !amdtp_stream_running(opposite) &&
		    (opposite_substreams > 0)) {
			err = start_stream(oxfw, opposite, rate, 0);
			if (err < 0) {
				dev_err(&oxfw->unit->device,
					"fail to restart stream: %d\n", err);
				goto end;
			}
		}
	}

	/* Start requested stream. */
	if (!amdtp_stream_running(stream)) {
		err = start_stream(oxfw, stream, rate, pcm_channels);
		if (err < 0)
			dev_err(&oxfw->unit->device,
				"fail to start stream: %d\n", err);
	}
end:
	return err;
}
bool BoardE1::KhompPvtR2::onNewCall(K3L_EVENT *e)
{
    DBG(FUNC,PVT_FMT(_target, "(R2) c"));   

    std::string r2_categ_a;
    
    int status = Globals::k3lapi.get_param(e, "r2_categ_a", r2_categ_a);


    if (status == ksSuccess && !r2_categ_a.empty())
    {
        try
        {
            ScopedPvtLock lock(this);

            try 
            { 
                callR2()->_r2_category = Strings::toulong(r2_categ_a); 
            }
            catch (Strings::invalid_value e) 
            { 
            /* do nothing */ 
            };

            /* channel will know if is a collect call or not */
            if (callR2()->_r2_category == kg2CollectCall)
                call()->_collect_call = true;

        }
        catch(ScopedLockFailed & err)
        {
            K::Logger::Logg(C_ERROR, PVT_FMT(target(), "(R2) r (unable to lock %s!)") % err._msg.c_str() );
            return ksFail;
        }
    }

    //TODO: The variable ret 
    bool ret = KhompPvtE1::onNewCall(e);

    if(ret)
    {
        try
        {
            ScopedPvtLock lock(this);

            if (!Opt::_r2_strict_behaviour)
            {
                // any collect call ?
                //TODO: Must decide, how to configure
                //K::util::set_collectcall(pvt,NULL);

                // keeping the hardcore mode
                if (Opt::_drop_collect_call && call()->_collect_call)
                {
                    // kill, kill, kill!!!
                    sendRingBackStatus(callFailFromCause(SWITCH_CAUSE_CALL_REJECTED));
                    usleep(75000);
                }
                else
                {
                    // send ringback too! 
                    sendPreAudio(RingbackDefs::RB_SEND_DEFAULT);
                    start_stream();
                }
            }
            else
            {
                _call->_flags.set(Kflags::NEEDS_RINGBACK_CMD);
            }
        }
        catch(ScopedLockFailed & err)
        {
            K::Logger::Logg(C_ERROR, PVT_FMT(target(), "(R2) r (unable to lock %s!)") % err._msg.c_str() );
            return ksFail;
        }
    }

    DBG(FUNC,PVT_FMT(_target, "(R2) r"));   

    return ret;
}
Exemple #6
0
int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate)
{
	const struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate;
	unsigned int curr_rate;
	int err = 0;

	/* Need no substreams */
	if (bebob->substreams_counter == 0)
		goto end;

	/*
	 * Considering JACK/FFADO streaming:
	 * TODO: This can be removed hwdep functionality becomes popular.
	 */
	err = check_connection_used_by_others(bebob, &bebob->rx_stream);
	if (err < 0)
		goto end;

	/*
	 * packet queueing error or detecting discontinuity
	 *
	 * At bus reset, connections should not be broken here. So streams need
	 * to be re-started. This is a reason to use SKIP_INIT_DBC_CHECK flag.
	 */
	if (amdtp_streaming_error(&bebob->rx_stream))
		amdtp_stream_stop(&bebob->rx_stream);
	if (amdtp_streaming_error(&bebob->tx_stream))
		amdtp_stream_stop(&bebob->tx_stream);
	if (!amdtp_stream_running(&bebob->rx_stream) &&
	    !amdtp_stream_running(&bebob->tx_stream))
		break_both_connections(bebob);

	/* stop streams if rate is different */
	err = rate_spec->get(bebob, &curr_rate);
	if (err < 0) {
		dev_err(&bebob->unit->device,
			"fail to get sampling rate: %d\n", err);
		goto end;
	}
	if (rate == 0)
		rate = curr_rate;
	if (rate != curr_rate) {
		amdtp_stream_stop(&bebob->rx_stream);
		amdtp_stream_stop(&bebob->tx_stream);
		break_both_connections(bebob);
	}

	/* master should be always running */
	if (!amdtp_stream_running(&bebob->rx_stream)) {
		/*
		 * NOTE:
		 * If establishing connections at first, Yamaha GO46
		 * (and maybe Terratec X24) don't generate sound.
		 *
		 * For firmware customized by M-Audio, refer to next NOTE.
		 */
		if (bebob->maudio_special_quirk == NULL) {
			err = rate_spec->set(bebob, rate);
			if (err < 0) {
				dev_err(&bebob->unit->device,
					"fail to set sampling rate: %d\n",
					err);
				goto end;
			}
		}

		err = make_both_connections(bebob, rate);
		if (err < 0)
			goto end;

		err = start_stream(bebob, &bebob->rx_stream, rate);
		if (err < 0) {
			dev_err(&bebob->unit->device,
				"fail to run AMDTP master stream:%d\n", err);
			break_both_connections(bebob);
			goto end;
		}

		/*
		 * NOTE:
		 * The firmware customized by M-Audio uses these commands to
		 * start transmitting stream. This is not usual way.
		 */
		if (bebob->maudio_special_quirk != NULL) {
			err = rate_spec->set(bebob, rate);
			if (err < 0) {
				dev_err(&bebob->unit->device,
					"fail to ensure sampling rate: %d\n",
					err);
				amdtp_stream_stop(&bebob->rx_stream);
				break_both_connections(bebob);
				goto end;
			}
		}

		/* wait first callback */
		if (!amdtp_stream_wait_callback(&bebob->rx_stream,
						CALLBACK_TIMEOUT)) {
			amdtp_stream_stop(&bebob->rx_stream);
			break_both_connections(bebob);
			err = -ETIMEDOUT;
			goto end;
		}
	}

	/* start slave if needed */
	if (!amdtp_stream_running(&bebob->tx_stream)) {
		err = start_stream(bebob, &bebob->tx_stream, rate);
		if (err < 0) {
			dev_err(&bebob->unit->device,
				"fail to run AMDTP slave stream:%d\n", err);
			amdtp_stream_stop(&bebob->rx_stream);
			break_both_connections(bebob);
			goto end;
		}

		/* wait first callback */
		if (!amdtp_stream_wait_callback(&bebob->tx_stream,
						CALLBACK_TIMEOUT)) {
			amdtp_stream_stop(&bebob->tx_stream);
			amdtp_stream_stop(&bebob->rx_stream);
			break_both_connections(bebob);
			err = -ETIMEDOUT;
		}
	}
end:
	return err;
}
Exemple #7
0
int test_isp_init_modules()
{
  boolean rc = FALSE;
  mct_module_t *ispif_module = NULL;
  mct_module_t *isp_module = NULL;
  mct_port_t *iface_sink_port = NULL;
  mct_port_t *iface_src_port = NULL;
  mct_port_t *isp_sink_port = NULL;
  mct_list_t *srcports, *sinkports;

  mct_event_t event;
  uint32_t i = 0;

  CDBG("%s TEST_ISP: E", __func__);
  ispif_module = module_iface_init("iface");
  CDBG("%s TEST_ISP: module_iface_init = %p", __func__, ispif_module);
  if (ispif_module== NULL) {
    CDBG_ERROR("%s: ispif_module = NULL\n",  __func__);
    exit(1);
  }
  rc = ispif_module->start_session(ispif_module, session_id);
  if (rc == FALSE) {
    CDBG_ERROR("%s: TEST_ISP: ispif_module start error = %d\n",  __func__, rc);
    exit(1);
  }
  isp_module = module_isp_init("isp");
  CDBG("%s TEST_ISP: module_isp_init = %p", __func__, isp_module);
  if (isp_module== NULL) {
    CDBG_ERROR("%s: isp_module = NULL\n",  __func__);
    exit(1);
  }
  rc = isp_module->start_session(isp_module, session_id);
  if (rc == FALSE) {
    CDBG_ERROR("%s: TEST_ISP: isp_module start error = %d\n",  __func__, rc);
    exit(1);
  }
  sinkports = MCT_MODULE_SINKPORTS(ispif_module);
  CDBG("%s TEST_ISP: ispif MCT_MODULE_SINKPORTS = %p", __func__, sinkports);
  iface_sink_port = (mct_port_t *)sinkports->data;
  srcports = MCT_MODULE_SRCPORTS(ispif_module);
  CDBG("%s TEST_ISP: ispif MCT_MODULE_SRCPORTS = %p", __func__, srcports);
  iface_src_port = (mct_port_t *)srcports->data;
  sinkports = MCT_MODULE_SINKPORTS(isp_module);
  CDBG("%s TEST_ISP: isp MCT_MODULE_SRCPORTS = %p", __func__, sinkports);
  isp_sink_port = (mct_port_t *)sinkports->data;
  if (iface_sink_port == NULL || iface_sink_port->direction != MCT_PORT_SINK) {
    CDBG_ERROR("%s: no iface sink port %p\n",  __func__,  iface_sink_port);
    exit(1);
  }
  if (iface_src_port == NULL || iface_src_port->direction != MCT_PORT_SRC) {
    CDBG_ERROR("%s: no iface src port %p\n",  __func__,  iface_src_port);
    exit(1);
  }
  if (isp_sink_port == NULL || isp_sink_port->direction != MCT_PORT_SINK) {
    CDBG_ERROR("%s: no isp sink port %p\n",  __func__,  isp_sink_port);
    exit(1);
  }
  CDBG("%s TEST_ISP: reserve port", __func__);
  rc = reserve_ports(iface_sink_port, iface_src_port, isp_sink_port);
  CDBG("%s TEST_ISP: reserve port, rc = %d", __func__, rc);
  rc = config_isp(iface_sink_port, iface_src_port, isp_sink_port);
  CDBG("%s TEST_ISP: config_isp, rc = %d", __func__, rc);
  rc = start_stream(iface_sink_port, iface_src_port, isp_sink_port);
  CDBG("%s TEST_ISP: start_stream, rc = %d", __func__, rc);
  CDBG("%s TEST_ISP: X, rc = %d", __func__, rc);
  return 0;
}
Exemple #8
0
/* this function is called each time that a userland process write to the
 * /proc/gpio/cmd proc entry */
int proc_cmd_write(struct file *file, const char *buffer, unsigned long count,
			   void *data)
{
	int i;
	char *token = NULL;
	
	/* get buffer size */
	procfs_buffer_size = count;
	if (procfs_buffer_size > PROCFS_MAX_SIZE ) {
		procfs_buffer_size = PROCFS_MAX_SIZE;
	}

	// clean the kernel buffer
	for(i=0; i<PROCFS_MAX_SIZE; i++)
		 procfs_buffer[i]='\0';

	// write data from the userland buffer to the kernel buffer
	if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size) ) {
		return -EFAULT;
	}

	// in case the last char is \n convert it to \0
	if(procfs_buffer[procfs_buffer_size-1] == '\n')
		procfs_buffer[procfs_buffer_size-1] = '\0';

	if(strcmp(procfs_buffer,"start")==0) {
		start_stream();
	} else if(strcmp(procfs_buffer,"stop")==0) {
		stop_stream();
	} else if(strcmp(procfs_buffer,"modemoff")==0) {
		PDEBUG("Shutting down modem.\n");
		/* turn on gpio for 4 seconds, this shutdown the modem */
		turn_on_gpio(gpio_out_modem);
		init_timer(&jiq_timer);
		jiq_timer.function = (void*)turn_off_gpio;
		jiq_timer.data = (int)gpio_out_modem;
		jiq_timer.expires = jiffies + HZ * 5; /* 5000ms == 5 seconds */
		add_timer(&jiq_timer);
	} else if(strcmp(procfs_buffer,"modemon")==0) {
		PDEBUG("Power on modem.\n");
		/* turn on gpio for 4 seconds, this shutdown the modem */
		turn_on_gpio(gpio_out_modem);
		init_timer(&jiq_timer);
		jiq_timer.function = (void*)turn_off_gpio;
		jiq_timer.data = (int)gpio_out_modem;
		jiq_timer.expires = jiffies + HZ / 2 ; /* 500ms */
		add_timer(&jiq_timer);
	}

	token = strtok(procfs_buffer, "=");
	if(token != NULL) {
		if(strcmp(token, "ledG") == 0) {
			token = strtok(NULL, "=");
			switch(n_atoi(token)) {
				case 0: // led off
					if(atomic_read(&atomic_var_pulse) == 1) {
						del_timer(&jiq_pulse_timer);
					}
					PDEBUG("Turning green led off.\n");
					turn_on_gpio(gpio_out_green);
					break;
				case 1: // led on
					if(atomic_read(&atomic_var_pulse) == 1) {
						del_timer(&jiq_pulse_timer);
					}
					PDEBUG("Turning green led on.\n");
					turn_off_gpio(gpio_out_green);
					break;
				case 2: // led blink slow -> period: 1s; pulse duration: 0.1s; timing: 1000000000
					pulse_data.gpio = gpio_out_green;
					pulse_data.duration = HZ/10;
					pulse_data.period = HZ;
					pulse_data.num_pulses = 1;
					PDEBUG("Blinking green led slow, period: %lu, duration: %lu, num_pulses: %d.\n",pulse_data.period,pulse_data.duration,pulse_data.num_pulses);
					if(atomic_read(&atomic_var_pulse) == 1) {
						del_timer(&jiq_pulse_timer);
					}
					atomic_set(&atomic_var_pulse,1);
					pulse_led();
					break;
				case 3: // led blink fast -> period: 0.5s; pulse duration: 0.1s; timing: 10000
					pulse_data.gpio = gpio_out_green;
					pulse_data.duration = HZ/10;
					pulse_data.period = HZ/2;
					pulse_data.num_pulses = 1;
					PDEBUG("Blinking green led slow, period: %lu, duration: %lu, num_pulses: %d.\n",pulse_data.period,pulse_data.duration,pulse_data.num_pulses);
					if(atomic_read(&atomic_var_pulse) == 1) {
						del_timer(&jiq_pulse_timer);
					}
					atomic_set(&atomic_var_pulse,1);
					pulse_led();
					break;
				case 4: // led blink double pulse -> period: 1s; pulse duration: 0.1s; timing: 1010000000
					pulse_data.gpio = gpio_out_green;
					pulse_data.duration = HZ/10;
					pulse_data.period = HZ;
					pulse_data.num_pulses =  2;
					PDEBUG("Blinking green led slow, period: %lu, duration: %lu, num_pulses: %d.\n",pulse_data.period,pulse_data.duration,pulse_data.num_pulses);
					if(atomic_read(&atomic_var_pulse) == 1) {
						del_timer(&jiq_pulse_timer);
					}
					atomic_set(&atomic_var_pulse,1);
					pulse_led();
					break;
			}
		}
	}

	return procfs_buffer_size;
}