Esempio n. 1
0
// ------------------------------------------------------------------------------------------------
// Reception test with interrupt handling
int radio_receive_test_int(spi_parms_t *spi_parms, arguments_t *arguments)
// ------------------------------------------------------------------------------------------------
{
    uint8_t nb_rx, rx_bytes[RADIO_BUFSIZE];

    init_radio_int(spi_parms, arguments);
    PI_CC_SPIStrobe(spi_parms, PI_CCxxx0_SFRX); // Flush Rx FIFO

    verbprintf(0, "Starting...\n");

    while((arguments->repetition == 0) || (packets_received < arguments->repetition))
    {
        radio_init_rx(spi_parms, arguments); // Init for new packet to receive
        radio_turn_rx(spi_parms);            // Put back into Rx

        do
        {
            radio_wait_free(); // make sure no radio operation is in progress
            nb_rx = radio_receive_packet(spi_parms, arguments, rx_bytes);
        } while(nb_rx == 0);

        rx_bytes[nb_rx] = '\0';
        verbprintf(0,"\"%s\"\n", rx_bytes);
    }
}
Esempio n. 2
0
/* FIXME it's a dirty hack, supporting VBOs would be the real thing */
const GLubyte * glGetString( GLenum name )
{
    init();
    static const GLubyte * (*func)(GLenum) = NULL;
    if (!func)
        func = (const GLubyte * (*)(GLenum)) dlsym(RTLD_NEXT, "glGetString");

    verbprintf("glGetString( %d );\n", name);

    switch (name) {
    case GL_EXTENSIONS:
        verbprintf("\tGL_EXTENSIONS:we return \"\" instead of %s\n",
                   func(name));
        return (const GLubyte *) "";
        break;
    case GL_VENDOR:
        verbprintf("\tGL_VENDOR:we return \"\" instead of %s\n",
                   func(name));
        return (const GLubyte *) "";
        break;
    case GL_RENDERER:
        verbprintf("\tGL_RENDERER:we return \"\" instead of %s\n",
                   func(name));
        return (const GLubyte *) "";
        break;
    case GL_VERSION:
        verbprintf("\tGL_VERSION: we return \"\" instead of %s\n",
                   func(name));
        return (const GLubyte *) "1.2";
        break;
    default:
        return func(name);
    }
}
Esempio n. 3
0
static void disp_packet(struct demod_state *s, unsigned char *bp, unsigned int len)
{
        unsigned char i,j;

        if (!bp)
		return;
        if (!len) {
                verbprintf(0, "\n");
                return;
        }
        j = 0;
        while (len) {
                i = *bp++;
                if ((i >= 32) && (i < 128))
                        verbprintf(0, "%c",i);
                else if (i == 13) {
                        if (j) 
                                verbprintf(0, "\n");
                        j = 0;
                } else
                       verbprintf(0, "[0x%02X]",i);

                if (i >= 32)
                        j = 1;

                len--;
        }
        if (j)
                verbprintf(0, "\n");
}
Esempio n. 4
0
/*
 * Within the index range (into the array entries_address_ascending), find the
 * symbol with the maximal lifetime and split/truncate all symbols that overlap
 * with it (i.e. that there won't be any overlaps anymore).
 */
static int handle_overlap_region(int start_idx, int end_idx)
{
	int rc = OP_JIT_CONV_OK;
	int idx;
	struct jitentry * e;
	int cnt;
	char * name;
	int i, j;
	unsigned long long totaltime, pct;

	if (debug) {
		for (i = start_idx; i <= end_idx; i++) {
			e = entries_address_ascending[i];
			verbprintf(debug, "overlap idx=%i, name=%s, "
				   "start=%llx, end=%llx, life_start=%lli, "
				   "life_end=%lli, lifetime=%lli\n",
				   i, e->symbol_name, e->vma,
				   e->vma + e->code_size, e->life_start,
				   e->life_end, e->life_end - e->life_start);
		}
	}
	idx = select_one(start_idx, end_idx);
	// This can't happen, but we check anyway, just to silence Coverity
	if (idx == OP_JIT_CONV_FAIL) {
		rc = OP_JIT_CONV_FAIL;
		goto out;
	}
	totaltime = eliminate_overlaps(start_idx, end_idx, idx);
	if (totaltime == ULONG_MAX) {
		rc = OP_JIT_CONV_FAIL;
		goto out;
	}
	e = entries_address_ascending[idx];
	pct = (totaltime == 0) ? 100 : (e->life_end - e->life_start) * 100 / totaltime;

	cnt = 1;
	j = pct;
	while ((j = j/10))
		cnt++;

	// Mark symbol name with a %% to indicate the overlap.
	cnt += strlen(e->symbol_name) + 2 + 1;
	name = xmalloc(cnt);
	snprintf(name, cnt, "%s%%%llu", e->symbol_name, pct);
	if (e->sym_name_malloced)
		free(e->symbol_name);
	e->symbol_name = name;
	e->sym_name_malloced = 1;
	verbprintf(debug, "selected idx=%i, name=%s\n", idx, e->symbol_name);
out:
	return rc;
}
Esempio n. 5
0
/* parse all entries in the jit dump file and build jitentry_list.
 * the code needs to check always whether there is enough
 * to read remaining. this is because the file may be written to
 * concurrently. */
static int parse_entries(void const * ptr, void const * end,
			 unsigned long long end_time)
{
	int rc = OP_JIT_CONV_OK;
	struct jr_prefix const * rec = ptr;

	while ((void *)rec + sizeof(struct jr_prefix) < end) {
		if (((void *) rec + rec->total_size) > end) {
			verbprintf(debug, "record past end of file\n");
			rc = OP_JIT_CONV_FAIL;
			break;
		}

		switch (rec->id) {
		case JIT_CODE_LOAD:
			if (parse_code_load(rec, rec->total_size, end_time)) {
				rc = OP_JIT_CONV_FAIL;
				break;
			}
			break;

		case JIT_CODE_UNLOAD:
			parse_code_unload(rec, end_time);
			break;

		
		case JIT_CODE_CLOSE:
			break;

		case JIT_CODE_DEBUG_INFO:
			if (rec->total_size == 0) {
				rc = OP_JIT_CONV_FAIL;
				break;
			}

			parse_code_debug_info(rec, end, end_time);
			break;

		default:
			verbprintf(debug, "unknown record type\n");
			rc = OP_JIT_CONV_FAIL;
			break;
		}

		
		rec = (void *)rec + rec->total_size;
	}

	return rc;
}
Esempio n. 6
0
/*
 * Scans through the index range and splits/truncates entries that overlap
 * with the one indexed by keep_idx. Returns the total lifetime of the symbols
 * found to overlap.
 * Returns ULONG_MAX on error.
 */
static unsigned long long eliminate_overlaps(int start_idx, int end_idx,
					 int keep_idx)
{
	unsigned long long retval;
	struct jitentry const * keep = entries_address_ascending[keep_idx];
	struct jitentry * e;
	unsigned long long start_addr_keep = keep->vma;
	unsigned long long end_addr_keep = keep->vma + keep->code_size;
	unsigned long long start_addr_entry, end_addr_entry;
	int i;
	unsigned long long min_start = keep->life_start;
	unsigned long long max_end = keep->life_end;

	for (i = start_idx; i <= end_idx; i++) {
		if (i == keep_idx)
			continue;
		e = entries_address_ascending[i];
		start_addr_entry = e->vma;
		end_addr_entry = e->vma + e->code_size;
		if (debug) {
			if (!(start_addr_entry <= end_addr_entry)) {
				verbprintf(debug, "assert failed:"
					   " start_addr_entry <="
					   " end_addr_entry\n");
				retval = ULONG_MAX;
				goto out;
			}
			if (!(start_addr_keep <= end_addr_keep)) {
				verbprintf(debug, "assert failed: "
					   "start_addr_keep <="
					   " end_addr_keep\n");
				retval = ULONG_MAX;
				goto out;
			}
		}
		if (start_addr_entry < end_addr_keep &&
		    end_addr_entry > start_addr_keep) {
			if (e->life_start < min_start)
				min_start = e->life_start;
			if (e->life_end > max_end)
				max_end = e->life_end;
			split_entry(e, keep);
		}
	}
	retval = max_end - min_start;
out:
	return retval;
}
Esempio n. 7
0
static void opd_shutdown(struct op_buffer_head * buf, size_t size, struct op_note * nbuf, size_t nsize)
{
	ssize_t count = -1;
	ssize_t ncount = -1;

	if (fcntl(devfd, F_SETFL, fcntl(devfd, F_GETFL) | O_NONBLOCK) < 0) {
		perror("Failed to set non-blocking read for device: ");
		exit(EXIT_FAILURE);
	}

	
	while (ncount < 0)
		ncount = op_read_device(notedevfd, nbuf, nsize);

	if (ncount > 0)
		opd_do_notes(nbuf, ncount);

	while (1) {
		count = op_read_device(devfd, buf, size);
		if (count < 0 && errno == EAGAIN)
			break;
		verbprintf(vmisc, "Shutting down, state %d\n", buf->state);
		opd_do_samples(buf);
	}
}
Esempio n. 8
0
/* create nr item randomly created with nr_unique_item distinct items */
static void speed_test(int nr_item, int nr_unique_item)
{
	int i;
	double begin, end;
	odb_t hash;
	int rc;

	rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header));
	if (rc) {
		fprintf(stderr, "%s", strerror(rc));
		exit(EXIT_FAILURE);
	}
	begin = used_time();
	for (i = 0 ; i < nr_item ; ++i) {
		rc = odb_insert(&hash, (random() % nr_unique_item) + 1, 1);
		if (rc != EXIT_SUCCESS) {
			fprintf(stderr, "%s", strerror(rc));
			exit(EXIT_FAILURE);
		}
	}
	end = used_time();
	odb_close(&hash);

	remove(TEST_FILENAME);

	verbprintf("nr item: %d, unique item: %d, elapsed: %f\n",
	           nr_item, nr_unique_item, end - begin);
}
Esempio n. 9
0
static int parse_code_load(void const * ptr_arg, int size,
			   unsigned long long end_time)
{
	struct jitentry * entry;
	int rc = OP_JIT_CONV_OK;
	char const * ptr = ptr_arg;
	struct jr_code_load const * rec = ptr_arg;
	char const * end;
	size_t padding_count, rec_totalsize;
	end = rec->code_addr ? ptr + size : NULL;

	entry = xcalloc(1, sizeof(struct jitentry));

	
	entry->next = NULL;
	ptr += sizeof(*rec);
	
	entry->symbol_name = (char *)ptr;
	entry->sym_name_malloced = 0;
	ptr += strlen(ptr) + 1;
	entry->code = rec->code_addr ? ptr : NULL;
	entry->vma = rec->vma;
	entry->code_size = rec->code_size;
	entry->section = NULL;
	entry->life_start = rec->timestamp;
	
	// sampling run, this value may be overwritten by an unload record1
	
	entry->life_end = end_time;

	
	entry->next = jitentry_list;
	jitentry_list = entry;

	rec_totalsize = sizeof(*rec) + strlen(entry->symbol_name) + 1 + entry->code_size;
	padding_count = PADDING_8ALIGNED(rec_totalsize);

	verbprintf(debug, "record0: name=%s, vma=%llx, code_size=%i, "
		   "padding_count=%llu, life_start=%lli, life_end=%lli\n", entry->symbol_name,
		   entry->vma, entry->code_size, (unsigned long long)padding_count, entry->life_start,
		   entry->life_end);
	if (end && (ptr + entry->code_size + padding_count != end)) {
		verbprintf(debug, "record total size mismatch\n");
		rc = OP_JIT_CONV_FAIL;
	}
	return rc;
}
Esempio n. 10
0
unsigned char disp_parm(unsigned char *bp, unsigned char param_len)
{
        unsigned char i, len;

        len=param_len;

	while (len) {
        	i = *bp++;
		if ((i >= 32) && (i < 128)) 
                        verbprintf(0, "%c",i);
		else 
		        verbprintf(0, ".");
                len--;
	}

return param_len;
}
Esempio n. 11
0
/**
 * opd_do_samples - process a sample buffer
 * @param opd_buf  buffer to process
 *
 * Process a buffer of samples.
 * The signals specified by the global variable maskset are
 * masked.
 *
 * If the sample could be processed correctly, it is written
 * to the relevant sample file. Additionally mapping and
 * process notifications are handled here.
 */
static void opd_do_samples(struct op_buffer_head const * opd_buf)
{
	uint i;
	struct op_sample const * buffer = opd_buf->buffer; 

	opd_24_stats[OPD_DUMP_COUNT]++;

	verbprintf(vmisc, "Read buffer of %d entries for cpu %d.\n",
		   (unsigned int)opd_buf->count, opd_buf->cpu_nr);
 
	if (separate_cpu)
		cpu_number = opd_buf->cpu_nr;
	for (i = 0; i < opd_buf->count; i++) {
		verbprintf(vsamples, "%.6u: EIP: 0x%.8lx pid: %.6d\n",
			i, buffer[i].eip, buffer[i].pid);
		opd_put_sample(&buffer[i]);
	}
}
Esempio n. 12
0
static void parse_code_unload(void const * ptr, unsigned long long end_time)
{
	struct jr_code_unload const * rec = ptr;
	struct jitentry * entry;

	verbprintf(debug,"record1: vma=%llx, life_end=%lli\n",
		   rec->vma, rec->timestamp);
	if (rec->timestamp > 0 && rec->vma != 0) {
		for (entry = jitentry_list; entry; entry = entry->next) {
			if (entry->vma == rec->vma &&
			    entry->life_end == end_time) {
				entry->life_end = rec->timestamp;
				verbprintf(debug,"matching record found\n");
				break;
			}
		}
	}
}
Esempio n. 13
0
int enough_remaining(struct transient * trans, size_t size)
{
	if (trans->remaining >= size)
		return 1;

	verbprintf(vmisc, "Dangling ESCAPE_CODE.\n");
	opd_stats[OPD_DANGLING_CODE]++;
	return 0;
}
Esempio n. 14
0
glvoid glBegin( GLenum mode )
{
    init();
    static void (*func)(GLenum) = NULL;
    if (!func)
        func = (void (*)(GLenum)) dlsym(RTLD_NEXT, "glBegin");

    if (dump_count)
    {
        verbprintf("glBegin(%s);", prim_type_name[mode]);

        current_prim = new_prim(mode);

        verbprintf(" /* [%d] */\n", nPrim-1);
        dump_count--;
    }

    func(mode);
}
Esempio n. 15
0
void clip_rxbit(struct demod_state *s, int bit)
{
	s->l2.uart.rxbitstream <<= 1;
	s->l2.uart.rxbitstream |= !!bit;
	if (!s->l2.uart.rxstate) {
		switch (s->l2.uart.rxbitstream & 0x03) {
			case 0x02:	/* start bit */
				s->l2.uart.rxstate = 1;
				s->l2.uart.rxbitbuf = 0x100;
				break;
			case 0x00:	/* no start bit */
			case 0x03:	/* consecutive stop bits*/
				if ((s->l2.uart.rxptr - s->l2.uart.rxbuf) >= 1)
					clip_disp_packet(s, s->l2.uart.rxbuf, s->l2.uart.rxptr - s->l2.uart.rxbuf);
				s->l2.uart.rxptr = s->l2.uart.rxbuf;
				break;
		}
		return;
	}
	if (s->l2.uart.rxbitstream & 1)
		s->l2.uart.rxbitbuf |= 0x200;
//	verbprintf(7, "b=%c", '0'+(s->l2.uart.rxbitstream & 1));
	if (s->l2.uart.rxbitbuf & 1) {
		if (s->l2.uart.rxptr >= s->l2.uart.rxbuf+sizeof(s->l2.uart.rxbuf)) {
			s->l2.uart.rxstate = 0;
			clip_disp_packet(s, s->l2.uart.rxbuf, s->l2.uart.rxptr - s->l2.uart.rxbuf);
			verbprintf(1, "Error: packet size too large\n");
			return;
		}
                if ( !(s->l2.uart.rxbitstream & 1) ) {
			s->l2.uart.rxstate = 0;
			verbprintf(1, "Error: stop bit is 0. Bad framing\n");
			return;
		}
		*s->l2.uart.rxptr++ = s->l2.uart.rxbitbuf >> 1;
//		verbprintf(6, "B=%02X ", (s->l2.uart.rxbitbuf >> 1) & 0xff);
//		verbprintf(5, "%c", (s->l2.uart.rxbitbuf >> 1) & 0xff);
		s->l2.uart.rxbitbuf = 0x100;
		s->l2.uart.rxstate = 0;
		return;
	}
      	s->l2.uart.rxbitbuf >>= 1;
}
Esempio n. 16
0
glvoid glVertex2i( GLint x, GLint y )
{
    init();
    static void (*func)(GLint, GLint) = NULL;
    if (!func)
        func = (void (*)(GLint, GLint)) dlsym(RTLD_NEXT, "glVertex2i");

    verbprintf("glVertex2i(%d, %d);\n", x, y);

    func(x, y);
}
Esempio n. 17
0
glvoid glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w )
{
    init();
    static void (*func)(GLdouble, GLdouble, GLdouble, GLdouble) = NULL;
    if (!func)
        func = (void (*)(GLdouble, GLdouble, GLdouble, GLdouble)) dlsym(RTLD_NEXT, "glVertex4d");

    verbprintf("glVertex4d(%f, %f, %f, %f);\n", x, y, z, w);

    func(x, y, z, w);
}
Esempio n. 18
0
glvoid glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
{
    init();
    static void (*func)(GLfloat, GLfloat, GLfloat, GLfloat) = NULL;
    if (!func)
        func = (void (*)(GLfloat, GLfloat, GLfloat, GLfloat)) dlsym(RTLD_NEXT, "glVertex4f");

    verbprintf("glVertex4f(%f, %f, %f, %f);\n", x, y, z, w);

    func(x, y, z, w);
}
Esempio n. 19
0
glvoid glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w )
{
    init();
    static void (*func)(GLshort, GLshort, GLshort, GLshort) = NULL;
    if (!func)
        func = (void (*)(GLshort, GLshort, GLshort, GLshort)) dlsym(RTLD_NEXT, "glVertex4s");

    verbprintf("glVertex4s(%d, %d, %d, %d);\n", x, y, z, w);

    func(x, y, z, w);
}
Esempio n. 20
0
glvoid glVertex2fv( const GLfloat *v )
{
    init();
    static void (*func)(const GLfloat *) = NULL;
    if (!func)
        func = (void (*)(const GLfloat *)) dlsym(RTLD_NEXT, "glVertex2fv");

    verbprintf("glVertex2fv(%f, %f);\n", v[0], v[1]);

    func(v);
}
Esempio n. 21
0
glvoid glVertex4dv( const GLdouble *v )
{
    init();
    static void (*func)(const GLdouble *) = NULL;
    if (!func)
        func = (void (*)(const GLdouble *)) dlsym(RTLD_NEXT, "glVertex4dv");

    verbprintf("glVertex4dv(%f, %f, %f, %f);\n", v[0], v[1], v[2], v[4]);

    func(v);
}
Esempio n. 22
0
glvoid glVertex4sv( const GLshort *v )
{
    init();
    static void (*func)(const GLshort *) = NULL;
    if (!func)
        func = (void (*)(const GLshort *)) dlsym(RTLD_NEXT, "glVertex4sv");

    verbprintf("glVertex4sv(%d, %d, %d, %d);\n", v[0], v[1], v[2], v[4]);

    func(v);
}
Esempio n. 23
0
glvoid glNewList( GLuint list, GLenum mode )
{
    init();
    static void (*func)(GLuint, GLenum) = NULL;
    if (!func)
        func = (void (*)(GLuint, GLenum)) dlsym(RTLD_NEXT, "glNewList");

    verbprintf("glNewList(%d, %d);\n", list, mode);

    func(list, mode);
}
Esempio n. 24
0
/**
 * opd_do_samples - process a sample buffer
 * @param opd_buf  buffer to process
 *
 * Process a buffer of samples.
 *
 * If the sample could be processed correctly, it is written
 * to the relevant sample file.
 */
static void opd_do_samples(char const * opd_buf, ssize_t count)
{
	size_t num = count / kernel_pointer_size;
 
	opd_stats[OPD_DUMP_COUNT]++;

	verbprintf(vmisc, "Read buffer of %d entries.\n", (unsigned int)num);
 
	opd_process_samples(opd_buf, num);

	complete_dump();
}
Esempio n. 25
0
/* SIGCHLD received from JIT dump child process. */
static void opd_sigchild(void)
{
	int child_status;
	wait(&child_status);
	jit_conversion_running = 0;
	if (WIFEXITED(child_status) && (!WEXITSTATUS(child_status))) {
		verbprintf(vmisc, "JIT dump processing complete.\n");
	} else {
		printf("JIT dump processing exited abnormally: %d\n",
		       WEXITSTATUS(child_status));
	}

}
Esempio n. 26
0
/**
 * opd_do_read - enter processing loop
 * @param buf  buffer to read into
 * @param size  size of buffer
 *
 * Read some of a buffer from the device and process
 * the contents.
 */
static void opd_do_read(char * buf, size_t size)
{
	opd_open_pipe();

	while (1) {
		ssize_t count = -1;

		/* loop to handle EINTR */
		while (count < 0) {
			count = op_read_device(devfd, buf, size);

			/* we can lose an alarm or a hup but
			 * we don't care.
			 */
			if (signal_alarm) {
				signal_alarm = 0;
				opd_alarm();
			}

			if (signal_hup) {
				signal_hup = 0;
				opd_sighup();
			}

			if (signal_term)
				opd_sigterm();

			if (signal_child)
				opd_sigchild();

			if (signal_usr1) {
				signal_usr1 = 0;
				perfmon_start();
			}

			if (signal_usr2) {
				signal_usr2 = 0;
				perfmon_stop();
			}

			if (is_jitconv_requested()) {
				verbprintf(vmisc, "Start opjitconv was triggered\n");
				opd_do_jitdumps();
			}
		}

		opd_do_samples(buf, count);
	}
	
	opd_close_pipe();
}
Esempio n. 27
0
static int parse_header(char const ** ptr, char const * end)
{
	int rc = OP_JIT_CONV_OK;
	struct jitheader const * header;

	if (*ptr + sizeof(struct jitheader) >= end) {
		verbprintf(debug,
			   "opjitconv: EOF in jitdump file, no header\n");
		rc = OP_JIT_CONV_FAIL;
		goto out;
	}
	header = (struct jitheader *)*ptr;
	if (header->magic != JITHEADER_MAGIC) {
		verbprintf(debug, "opjitconv: Wrong jitdump file magic\n");
		rc = OP_JIT_CONV_FAIL;
		goto out;
	}
	if (header->version != JITHEADER_VERSION) {
		verbprintf(debug, "opjitconv: Wrong jitdump file version\n");
		rc = OP_JIT_CONV_FAIL;
		goto out;
	}
	if (*ptr + header->totalsize > end) {
		verbprintf(debug, "opjitconv: EOF in jitdump file, not enough "
			   "data for header\n");
		rc = OP_JIT_CONV_FAIL;
		goto out;
	}
	dump_bfd_arch = header->bfd_arch;
	dump_bfd_mach = header->bfd_mach;
	dump_bfd_target_name = header->bfd_target;
	verbprintf(debug, "header: bfd-arch=%i, bfd-mach=%i,"
		   " bfd_target_name=%s\n", dump_bfd_arch, dump_bfd_mach,
		   dump_bfd_target_name);
	*ptr = *ptr + header->totalsize;
out:
	return rc;
}
Esempio n. 28
0
// ------------------------------------------------------------------------------------------------
// Transmission test with interrupt handling
int radio_transmit_test_int(spi_parms_t *spi_parms, arguments_t *arguments)
// ------------------------------------------------------------------------------------------------
{
    init_radio_int(spi_parms, arguments);
    PI_CC_SPIStrobe(spi_parms, PI_CCxxx0_SFTX); // Flush Tx FIFO

    verbprintf(0, "Sending %d test packets of size %d\n", arguments->repetition, arguments->packet_length);

    while(packets_sent < arguments->repetition)
    {
        radio_wait_free(); // make sure no radio operation is in progress
        radio_send_packet(spi_parms, arguments, arguments->test_phrase, strlen(arguments->test_phrase));
        radio_wait_a_bit(arguments->packet_length / 4);
    }
}
Esempio n. 29
0
// ------------------------------------------------------------------------------------------------
// Check if the KISS block is a command block and interpret the command 
// Returns 1 if this is a command block
// Returns 0 it this is a data block
uint8_t kiss_command(uint8_t *block)
// ------------------------------------------------------------------------------------------------
{
    uint8_t command_code = block[1] & 0x0F;
    uint8_t kiss_port = (block[1] & 0xF0)>>4;
    uint8_t command_arg = block[2];

    verbprintf(4, "KISS: command %02X %02X\n", block[1], block[2]);

    switch (command_code)
    {
        case 0: // data block
            return 0;
        case 1: // TXDELAY
            tnc_tx_keyup_delay = command_arg * 10000; // these are tenths of ms
            break;
        case 2: // Persistence parameter
            kiss_persistence = (command_arg + 1) / 256.0;
            break;
        case 3: // Slot time
            kiss_slot_time = command_arg * 10000; // these are tenths of ms
            break;
        case 4: // Tx tail
            kiss_tx_tail = command_arg * 10000; // these are tenths of ms
            break;
        case 15:
            verbprintf(1, "KISS: received aborting command\n");
            abort();
            break;
        default:
            break;
    }

    verbprintf(1, "KISS: command received for port %d: (%d,%d)\n", kiss_port, command_code, command_arg);
    return 1;
}
void opd_parse_events(char const * events)
{
	char * ev = xstrdup(events);
	char * c;
	size_t cur = 0;

	if (cpu_type == CPU_TIMER_INT) {
		struct opd_event * event = &opd_events[0];
		event->name = xstrdup("TIMER");
		event->value = event->counter
			= event->count = event->um = 0;
		event->kernel = 1;
		event->user = 1;
		return;
	}

	if (!ev || !strlen(ev)) {
		fprintf(stderr, "oprofiled: no events passed.\n");
		exit(EXIT_FAILURE);
	}

	verbprintf(vmisc, "Events: %s\n", ev);

	c = ev;

	while (*c && cur < op_nr_counters) {
		struct opd_event * event = &opd_events[cur];

		if (!(event->name = copy_token(&c, ':')))
			malformed_events();
		event->value = copy_ulong(&c, ':');
		event->counter = copy_ulong(&c, ':');
		event->count = copy_ulong(&c, ':');
		event->um = copy_ulong(&c, ':');
		event->kernel = copy_ulong(&c, ':');
		event->user = copy_ulong(&c, ',');
		++cur;
	}

	if (*c) {
		fprintf(stderr, "oprofiled: too many events passed.\n");
		exit(EXIT_FAILURE);
	}

	free(ev);

	cpu_speed = op_cpu_frequency();
}