Exemple #1
0
void snd_efw_stream_stop_duplex(struct snd_efw *efw)
{
	struct amdtp_stream *master, *slave;
	atomic_t *master_substreams, *slave_substreams;

	if (efw->master == &efw->rx_stream) {
		slave  = &efw->tx_stream;
		master = &efw->rx_stream;
		slave_substreams  = &efw->capture_substreams;
		master_substreams = &efw->playback_substreams;
	} else {
		slave  = &efw->rx_stream;
		master = &efw->tx_stream;
		slave_substreams  = &efw->playback_substreams;
		master_substreams = &efw->capture_substreams;
	}

	mutex_lock(&efw->mutex);

	if (atomic_read(slave_substreams) == 0) {
		stop_stream(efw, slave);

		if (atomic_read(master_substreams) == 0)
			stop_stream(efw, master);
	}

	mutex_unlock(&efw->mutex);
}
Exemple #2
0
void snd_efw_stream_update_duplex(struct snd_efw *efw)
{
	if ((cmp_connection_update(&efw->out_conn) < 0) ||
	    (cmp_connection_update(&efw->in_conn) < 0)) {
		mutex_lock(&efw->mutex);
		stop_stream(efw, &efw->rx_stream);
		stop_stream(efw, &efw->tx_stream);
		mutex_unlock(&efw->mutex);
	} else {
		amdtp_stream_update(&efw->rx_stream);
		amdtp_stream_update(&efw->tx_stream);
	}
}
void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw)
{
	stop_stream(oxfw);

	amdtp_stream_destroy(&oxfw->rx_stream);
	cmp_connection_destroy(&oxfw->in_conn);
}
void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw)
{
	if (cmp_connection_update(&oxfw->in_conn) < 0)
		stop_stream(oxfw);
	else
		amdtp_stream_update(&oxfw->rx_stream);
}
Exemple #5
0
static int
start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
	     unsigned int sampling_rate)
{
	struct cmp_connection *conn;
	unsigned int mode, pcm_channels, midi_ports;
	int err;

	err = snd_efw_get_multiplier_mode(sampling_rate, &mode);
	if (err < 0)
		goto end;
	if (stream == &efw->tx_stream) {
		conn = &efw->out_conn;
		pcm_channels = efw->pcm_capture_channels[mode];
		midi_ports = efw->midi_out_ports;
	} else {
		conn = &efw->in_conn;
		pcm_channels = efw->pcm_playback_channels[mode];
		midi_ports = efw->midi_in_ports;
	}

	amdtp_stream_set_parameters(stream, sampling_rate,
				    pcm_channels, midi_ports);

	/*  establish connection via CMP */
	err = cmp_connection_establish(conn,
				amdtp_stream_get_max_payload(stream));
	if (err < 0)
		goto end;

	/* start amdtp stream */
	err = amdtp_stream_start(stream,
				 conn->resources.channel,
				 conn->speed);
	if (err < 0) {
		stop_stream(efw, stream);
		goto end;
	}

	/* wait first callback */
	if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
		stop_stream(efw, stream);
		err = -ETIMEDOUT;
	}
end:
	return err;
}
Exemple #6
0
void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw,
				  struct amdtp_stream *stream)
{
	if (((stream == &oxfw->tx_stream) && (oxfw->capture_substreams > 0)) ||
	    ((stream == &oxfw->rx_stream) && (oxfw->playback_substreams > 0)))
		return;

	stop_stream(oxfw, stream);
}
Exemple #7
0
static void
destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream)
{
	stop_stream(efw, stream);

	amdtp_stream_destroy(stream);

	if (stream == &efw->tx_stream)
		cmp_connection_destroy(&efw->out_conn);
	else
		cmp_connection_destroy(&efw->in_conn);
}
Exemple #8
0
void irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
	
	PDEBUG("IRQ %i: got event\n", irq);

	if(jiffies - tmp_jiffie > HZ) {
		tmp_jiffie = jiffies;
		if(atomic_read(&irq_atomic_var_stream) == 0) {
			start_stream();
		} else {
			stop_stream();
		}
	}

}
int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw)
{
	int err = 0;

	if (amdtp_streaming_error(&oxfw->rx_stream))
		stop_stream(oxfw);

	if (amdtp_stream_running(&oxfw->rx_stream))
		goto end;

	err = cmp_connection_establish(&oxfw->in_conn,
			amdtp_stream_get_max_payload(&oxfw->rx_stream));
	if (err < 0)
		goto end;

	err = amdtp_stream_start(&oxfw->rx_stream,
				 oxfw->in_conn.resources.channel,
				 oxfw->in_conn.speed);
	if (err < 0)
		stop_stream(oxfw);
end:
	return err;
}
Exemple #10
0
void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw,
				    struct amdtp_stream *stream)
{
	struct cmp_connection *conn;

	if (stream == &oxfw->tx_stream)
		conn = &oxfw->out_conn;
	else
		conn = &oxfw->in_conn;

	if (cmp_connection_update(conn) < 0)
		stop_stream(oxfw, stream);
	else
		amdtp_stream_update(stream);
}
static int start_stream(enum cg2900_audio_endpoint_id ep1,
			enum cg2900_audio_endpoint_id ep2)
{
	LOG_I("Enter.");

	int error = 0;
	unsigned int data[2];
	unsigned char *buf;
	size_t len;
	ssize_t r;

	if (stream_handle != 0xffffffff) {
		LOG_I("Tear down old stream.");
		/* tear down old stream first */
		stop_stream();
	}

	len = 4 + sizeof(ep1) + sizeof(ep2);
	buf = (unsigned char *)malloc(len);
	if (!buf) {
		LOG_E("Error: Out of memory!");
		return -1;
	}
	memset(buf, 0, len);
	buf[0] = CHAR_DEV_OP_CODE_CONNECT_AND_START_STREAM;
	memcpy(buf + 4, &ep1, sizeof(ep1));
	memcpy(buf + 4 + sizeof(ep1), &ep2, sizeof(ep2));

	r = write(chardev_fd, buf, len);
	free(buf);
	if (r != (ssize_t)len) {
		LOG_E("ERROR: Start stream failed (%s)", (r < 0) ? strerror(errno) : "Internal error");
		return -1;
	}

	r = read(chardev_fd, data, sizeof(data));
	if ((unsigned int)r < sizeof(data)) {
		LOG_E("ERROR: Start stream failed (%s)!", (r < 0) ? strerror(errno) : "Internal error");
		error = -1;
	} else {
		stream_handle = data[1];
	}

	return error;
}
int BoardE1::KhompPvtISDN::doChannelAnswer(CommandRequest &cmd)
{
    try
    {
        ScopedPvtLock lock(this);

        // is this a collect call?
        bool has_recv_collect_call = _call->_collect_call;

        // do we have to drop collect calls?
        bool has_drop_collect_call = Opt::_drop_collect_call
            || _call->_flags.check(Kflags::DROP_COLLECT)
            || _call->_flags.check(Kflags::FILTER_COLLECT);

        // do we have to drop THIS call?
        bool do_drop_call = has_drop_collect_call && has_recv_collect_call;

        if(has_drop_collect_call) 
        {
            usleep(75000);

            DBG(FUNC, PVT_FMT(target(), "disconnecting collect call"));
            //TODO: Define what is SCE
            //        command(KHOMP_LOG,CM_DISCONNECT,SCE_HIDE);
            command(KHOMP_LOG,CM_DISCONNECT);

            // thou shalt not talk anymore!
            stop_listen();
            stop_stream();
            //TODO: Checar se retorna aqui
        }
    }
    catch (ScopedLockFailed & err)
    {
        K::Logger::Logg(C_ERROR, PVT_FMT(_target, "unable to lock %s!") % err._msg.c_str() );
        return ksFail;
    }

    KhompPvtE1::doChannelAnswer(cmd);
}
Exemple #13
0
int CFlowStatRuleMgr::del_stream(TrexStream * stream) {
#ifdef __DEBUG_FUNC_ENTRY__
    std::cout << __METHOD_NAME__ << " user id:" << stream->m_rx_check.m_pg_id << std::endl;
    stream_dump(stream);
#endif

    if (! stream->m_rx_check.m_enabled) {
        return 0;
    }

    if (! m_api)
        throw TrexFStatEx("Called del_stream, but no stream was added", TrexException::T_FLOW_STAT_NO_STREAMS_EXIST);

    TrexPlatformApi::driver_stat_cap_e rule_type = (TrexPlatformApi::driver_stat_cap_e)stream->m_rx_check.m_rule_type;
    switch(rule_type) {
    case TrexPlatformApi::IF_STAT_IPV4_ID:
        break;
    case TrexPlatformApi::IF_STAT_PAYLOAD:
        break;
    default:
        throw TrexFStatEx("Wrong rule_type", TrexException::T_FLOW_STAT_BAD_RULE_TYPE);
        break;
    }

    // we got del_stream command for a stream which has valid hw_id.
    // Probably someone forgot to call stop
    if(stream->m_rx_check.m_hw_id < MAX_FLOW_STATS + MAX_FLOW_STATS_PAYLOAD) {
        stop_stream(stream);
    }

    // calling del for same stream twice, or for a stream which was never "added"
    if(stream->m_rx_check.m_hw_id == HW_ID_INIT) {
        return 0;
    }
    m_user_id_map.del_stream(stream->m_rx_check.m_pg_id); // Throws exception in case of error
    stream->m_rx_check.m_hw_id = HW_ID_INIT;

    return 0;
}
Exemple #14
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;
}
bool BoardE1::KhompPvtE1::indicateBusyUnlocked(int cause, bool sent_signaling)
{
    DBG(FUNC, PVT_FMT(_target, "(E1) c"));

    if(!KhompPvt::indicateBusyUnlocked(cause, sent_signaling))
    {
        DBG(FUNC, PVT_FMT(_target, "(E1) r (false)"));
        return false;
    }

    if(call()->_flags.check(Kflags::IS_INCOMING))
    {
        if(!call()->_flags.check(Kflags::CONNECTED) && !sent_signaling)
        {
            if(!call()->_flags.check(Kflags::HAS_PRE_AUDIO))
            {
                int rb_value = callFailFromCause(call()->_hangup_cause);
                DBG(FUNC, PVT_FMT(target(), "sending the busy status"));

                if (sendRingBackStatus(rb_value) == RingbackDefs::RBST_UNSUPPORTED)
                {
                    DBG(FUNC, PVT_FMT(target(), "falling back to audio indication!"));
                    /* stop the line audio */
                    stop_stream();

                    /* just pre connect, no ringback */
                    if (!sendPreAudio())
                        DBG(FUNC, PVT_FMT(target(), "everything else failed, just sending audio indication..."));

                    /* be very specific about the situation. */
                    mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
                }
            }
            else
            {
                DBG(FUNC, PVT_FMT(target(), "going to play busy"));

                /* stop the line audio */
                stop_stream();

                /* be very specific about the situation. */
                mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);

            }
        }
        else
        {
            /* already connected or sent signaling... */
            mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
        }

    }
    else if(call()->_flags.check(Kflags::IS_OUTGOING))
    {
        /* already connected or sent signaling... */
        mixer(KHOMP_LOG, 1, kmsGenerator, kmtBusy);
    }

    DBG(FUNC,PVT_FMT(_target, "(E1) r"));
    
    return true; 
}
Exemple #16
0
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;
}
void teardown_fm_i2s(void)
{
	stop_stream();
	close_chardev();
}
void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw)
{
	stop_stream(oxfw);
}
Exemple #19
0
static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream,
			unsigned int rate, unsigned int pcm_channels)
{
	u8 **formats;
	struct cmp_connection *conn;
	struct snd_oxfw_stream_formation formation;
	unsigned int i, midi_ports;
	int err;

	if (stream == &oxfw->rx_stream) {
		formats = oxfw->rx_stream_formats;
		conn = &oxfw->in_conn;
	} else {
		formats = oxfw->tx_stream_formats;
		conn = &oxfw->out_conn;
	}

	/* Get stream format */
	for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
		if (formats[i] == NULL)
			break;

		err = snd_oxfw_stream_parse_format(formats[i], &formation);
		if (err < 0)
			goto end;
		if (rate != formation.rate)
			continue;
		if (pcm_channels == 0 ||  pcm_channels == formation.pcm)
			break;
	}
	if (i == SND_OXFW_STREAM_FORMAT_ENTRIES) {
		err = -EINVAL;
		goto end;
	}

	pcm_channels = formation.pcm;
	midi_ports = formation.midi * 8;

	/* The stream should have one pcm channels at least */
	if (pcm_channels == 0) {
		err = -EINVAL;
		goto end;
	}
	err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports,
					 false);
	if (err < 0)
		goto end;

	err = cmp_connection_establish(conn,
				       amdtp_stream_get_max_payload(stream));
	if (err < 0)
		goto end;

	err = amdtp_stream_start(stream,
				 conn->resources.channel,
				 conn->speed);
	if (err < 0) {
		cmp_connection_break(conn);
		goto end;
	}

	/* Wait first packet */
	if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
		stop_stream(oxfw, stream);
		err = -ETIMEDOUT;
	}
end:
	return err;
}
Exemple #20
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*/
}
Exemple #21
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;
}