Exemplo n.º 1
0
// ------------------------------------------------------------------------------------------------
// Run the KISS virtual TNC
void kiss_run(serial_t *serial_parms, spi_parms_t *spi_parms, arguments_t *arguments)
// ------------------------------------------------------------------------------------------------
{
    static const size_t   bufsize = RADIO_BUFSIZE;
    uint32_t timeout_value;
    uint8_t  rx_buffer[bufsize], tx_buffer[bufsize];
    uint8_t  rtx_toggle; // 1:Tx, 0:Rx
    uint8_t  rx_trigger; 
    uint8_t  tx_trigger; 
    uint8_t  force_mode;
    int      rx_count, tx_count, byte_count, ret;
    uint64_t timestamp;
    struct timeval tp;  

    set_serial_parameters(serial_parms, arguments);
    init_radio_int(spi_parms, arguments);
    memset(rx_buffer, 0, bufsize);
    memset(tx_buffer, 0, bufsize);
    radio_flush_fifos(spi_parms);
    
    verbprintf(1, "Starting...\n");

    force_mode = 1;
    rtx_toggle = 0;
    rx_trigger = 0;
    tx_trigger = 0;
    rx_count = 0;
    tx_count = 0;
    radio_init_rx(spi_parms, arguments); // init for new packet to receive Rx
    radio_turn_rx(spi_parms);            // Turn Rx on

    while(1)
    {    
        byte_count = radio_receive_packet(spi_parms, arguments, &rx_buffer[rx_count]); // check if anything was received on radio link

        if (byte_count > 0)
        {
            rx_count += byte_count;  // Accumulate Rx
            
            gettimeofday(&tp, NULL);
            timestamp = tp.tv_sec * 1000000ULL + tp.tv_usec;
            timeout_value = arguments->tnc_radio_window;
            force_mode = (timeout_value == 0);

            if (rtx_toggle) // Tx to Rx transition
            {
                tx_trigger = 1; // Push Tx
            }
            else
            {
                tx_trigger = 0;
            }

            radio_init_rx(spi_parms, arguments); // Init for new packet to receive
            rtx_toggle = 0;
        }

        byte_count = read_serial(serial_parms, &tx_buffer[tx_count], bufsize - tx_count);

        if (byte_count > 0)
        {
            tx_count += byte_count;  // Accumulate Tx

            gettimeofday(&tp, NULL);
            timestamp = tp.tv_sec * 1000000ULL + tp.tv_usec;
            timeout_value = arguments->tnc_serial_window;
            force_mode = (timeout_value == 0);

            if (!rtx_toggle) // Rx to Tx transition
            {
                rx_trigger = 1;
            }
            else
            {
                rx_trigger = 0;
            }

            rtx_toggle = 1;
        }

        if ((rx_count > 0) && ((rx_trigger) || (force_mode))) // Send bytes received on air to serial
        {
            radio_wait_free();            // Make sure no radio operation is in progress
            radio_turn_idle(spi_parms);   // Inhibit radio operations
            verbprintf(2, "Received %d bytes\n", rx_count);
            ret = write_serial(serial_parms, rx_buffer, rx_count);
            verbprintf(2, "Sent %d bytes on serial\n", ret);
            radio_init_rx(spi_parms, arguments); // Init for new packet to receive Rx
            radio_turn_rx(spi_parms);            // Put back into Rx
            rx_count = 0;
            rx_trigger = 0;
        }

        if ((tx_count > 0) && ((tx_trigger) || (force_mode))) // Send bytes received on serial to air 
        {
            if (!kiss_command(tx_buffer))
            {
                radio_wait_free();            // Make sure no radio operation is in progress
                radio_turn_idle(spi_parms);   // Inhibit radio operations (should be superfluous since both Tx and Rx turn to IDLE after a packet has been processed)
                radio_flush_fifos(spi_parms); // Flush result of any Rx activity

                verbprintf(2, "%d bytes to send\n", tx_count);

                if (tnc_tx_keyup_delay)
                {
                    usleep(tnc_tx_keyup_delay);
                }

                radio_send_packet(spi_parms, arguments, tx_buffer, tx_count);

                radio_init_rx(spi_parms, arguments); // init for new packet to receive Rx
                radio_turn_rx(spi_parms);            // put back into Rx
            }

            tx_count = 0;
            tx_trigger = 0;            
        }

        if (!force_mode)
        {
            gettimeofday(&tp, NULL);

            if ((tp.tv_sec * 1000000ULL + tp.tv_usec) > timestamp + timeout_value)
            {
                force_mode = 1;
            }                        
        }

        radio_wait_a_bit(4);
    }
}
Exemplo n.º 2
0
Arquivo: main.c Projeto: f4exb/tnc1101
// ------------------------------------------------------------------------------------------------
int main (int argc, char **argv)
// ------------------------------------------------------------------------------------------------
{
    int i, nbytes;

    // unsolicited termination handling
    struct sigaction sa;
    // Catch all signals possible on process exit!
    for (i = 1; i < 64; i++) 
    {
        // skip SIGUSR2 for Wiring Pi
        if (i == 17)
            continue; 

        // These are uncatchable or harmless or we want a core dump (SEGV) 
        if (i != SIGKILL
            && i != SIGSEGV
            && i != SIGSTOP
            && i != SIGVTALRM
            && i != SIGWINCH
            && i != SIGPROF) 
        {
            memset(&sa, 0, sizeof(sa));
            sa.sa_handler = terminate;
            sigaction(i, &sa, NULL);
        }
    }

    // Set argument defaults
    init_args(&arguments); 

    // Parse arguments 
    argp_parse (&argp, argc, argv, 0, 0, &arguments);

    if (arguments.print_long_help)
    {
        print_long_help();
        return 0;
    }
    
    if (!arguments.usbacm_device)
    {
        arguments.usbacm_device = strdup("/dev/ttyACM2");
    }
    
    if (!arguments.serial_device)
    {
        arguments.serial_device = strdup("/var/ax25/axp2");
    }
    
    if (!arguments.bulk_filename)
    {
        arguments.bulk_filename = strdup("-");
    }

    set_serial_parameters(&serial_parms_ax25, arguments.serial_device, get_serial_speed(arguments.serial_speed, &arguments.serial_speed_n));
    set_serial_parameters(&serial_parms_usb,  arguments.usbacm_device, get_serial_speed(115200, &arguments.usb_speed_n));
    init_radio_parms(&radio_parms, &arguments);

    if (arguments.verbose_level > 0)
    {
        print_args(&arguments);
        print_radio_parms(&radio_parms);
        fprintf(stderr, "\n");
    }

    if (arguments.tnc_mode == TNC_KISS)
    {
        kiss_init(&arguments);
        kiss_run(&serial_parms_ax25, &serial_parms_usb, &radio_parms, &arguments);
    }
    else if (arguments.tnc_mode == TNC_SLIP)
    {
        arguments.slip = 1;
        kiss_init(&arguments);
        kiss_run(&serial_parms_ax25, &serial_parms_usb, &radio_parms, &arguments);
    }
    else if (arguments.tnc_mode == TNC_TEST_USB_ECHO) // This one does not need any access to the radio
    {
        usb_test_echo(&serial_parms_usb, &arguments);
    }
    else if (arguments.tnc_mode == TNC_RADIO_STATUS) 
    {
        print_radio_status(&serial_parms_usb, &arguments);
    }
    else if (arguments.tnc_mode == TNC_RADIO_INIT)
    {
        init_radio(&serial_parms_usb, &radio_parms, &arguments);

        if (nbytes < 0)
        {
            fprintf(stderr, "Error\n");
        }
    }
    else if (arguments.tnc_mode == TNC_TEST_TX)
    {
        radio_transmit_test(&serial_parms_usb, &radio_parms, &arguments);
    }
    else if (arguments.tnc_mode == TNC_TEST_RX)
    {
        radio_receive_test(&serial_parms_usb, &radio_parms, &arguments);
    }
    else if (arguments.tnc_mode == TNC_TEST_ECHO_TX)
    {
        radio_echo_test(&serial_parms_usb, &radio_parms, &arguments, 1);
    } 
    else if (arguments.tnc_mode == TNC_TEST_ECHO_RX)
    {
        radio_echo_test(&serial_parms_usb, &radio_parms, &arguments, 0);
    }
    else if (arguments.tnc_mode == TNC_TEST_TX_PACKET)
    {
        radio_packet_transmit_test(&serial_parms_usb, &radio_parms, &arguments);
    }
    else if (arguments.tnc_mode == TNC_TEST_RX_PACKET)
    {
        radio_packet_receive_test(&serial_parms_usb, &radio_parms, &arguments);
    }
    else if (arguments.tnc_mode == TNC_TEST_RX_PACKET_NON_BLOCKING)
    {
        radio_packet_receive_nb_test(&serial_parms_usb, &radio_parms, &arguments);
    }
    else if (arguments.tnc_mode == TNC_BULK_TX)
    {
        file_bulk_transmit(&serial_parms_usb, &radio_parms, &arguments);
    }
    else if (arguments.tnc_mode == TNC_BULK_RX)
    {
        file_bulk_receive(&serial_parms_usb, &radio_parms, &arguments);
    }

    close_serial(&serial_parms_usb);
    close_serial(&serial_parms_ax25);
    delete_args(&arguments);
    return 0;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
	unsigned char bytes[BLOCK_SIZE];
	int read_fd = -1;
	int c;
	bool do_not_fork = false, log_console = false, log_syslog = false;
	char *log_logfile = NULL;
	char *device = NULL;
	char *serial = NULL;
	char *bytes_file = NULL;
	bool show_bps = false;
	std::string username, password;
	std::vector<std::string> hosts;
	int log_level = LOG_INFO;

	fprintf(stderr, "%s, (C) 2009-2015 by [email protected]\n", server_type);

	while((c = getopt(argc, argv, "hSX:P:o:p:I:d:L:l:sn")) != -1)
	{
		switch(c)
		{
			case 'S':
				show_bps = true;
				break;

			case 'X':
				get_auth_from_file(optarg, username, password);
				break;

			case 'P':
				pid_file = optarg;
				break;

			case 'o':
				bytes_file = optarg;
				break;

			case 'p':
				serial = optarg;
				break;

			case 'I':
				hosts.push_back(optarg);
				break;

			case 'd':
				device = optarg;
				break;

			case 's':
				log_syslog = true;
				break;

			case 'L':
				log_level = atoi(optarg);
				break;

			case 'l':
				log_logfile = optarg;
				break;

			case 'n':
				do_not_fork = true;
				log_console = true;
				break;

			case 'h':
				help();
				return 0;

			default:
				help();
				return 1;
		}
	}

	if (!hosts.empty() && (username.length() == 0 || password.length() == 0))
		error_exit("please select a file with authentication parameters (username + password) using the -X switch");

	if (hosts.empty() && !bytes_file)
		error_exit("no host to connect to or file to write to given");

	set_logging_parameters(log_console, log_logfile, log_syslog, log_level);

	if (device)
		read_fd = open(device, O_RDONLY);
	if (read_fd == -1)
		error_exit("error opening %s", device);

	if (serial)
		set_serial_parameters(read_fd, serial);

	(void)umask(0177);
	no_core();
	lock_mem(bytes, sizeof bytes);

	if (!do_not_fork)
	{
		if (daemon(0, 0) == -1)
			error_exit("fork failed");
	}

	protocol *p = NULL;
	if (!hosts.empty())
		p = new protocol(&hosts, username, password, true, server_type, DEFAULT_COMM_TO);

	write_pid(pid_file);

	signal(SIGPIPE, SIG_IGN);
	signal(SIGTERM, sig_handler);
	signal(SIGINT , sig_handler);
	signal(SIGQUIT, sig_handler);

	init_showbps();
	set_showbps_start_ts();
	for(;!do_exit;)
	{
		if (READ(read_fd, bytes, BLOCK_SIZE, &do_exit) != BLOCK_SIZE)
			error_exit("error reading from input");

		if (show_bps)
			update_showbps(BLOCK_SIZE);

		if (bytes_file)
			emit_buffer_to_file(bytes_file, bytes, BLOCK_SIZE);

		if (p && p -> message_transmit_entropy_data(bytes, BLOCK_SIZE, &do_exit) == -1)
		{
			dolog(LOG_INFO, "connection closed");
			p -> drop();
		}

		set_showbps_start_ts();
	}

	memset(bytes, 0x00, sizeof bytes);
	unlink(pid_file);

	delete p;

	return 0;
}