From: Jon Langseth <jon.langseth@lilug.no>
Date: Sun, 8 Jul 2012 18:19:21 +0000 (+0200)
Subject: Header-files and support-code allows for further expansion.
X-Git-Url: https://git.defcon.no/?a=commitdiff_plain;h=fa4964bb3038877f748442d91919e59fa6f7932b;p=hm-trp-tool

Header-files and support-code allows for further expansion.
I needed the set_speed tool first, so that's what goes in initial commit.
---

fa4964bb3038877f748442d91919e59fa6f7932b
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..21cc481
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# Couldn't be bothered to make a proper make-file...
+
+for i in *.c
+do 
+	gcc -c $i
+done
+
+gcc read_hm-trp.o hm-trp.o serial.o -o read_hm-trp
+gcc set_speed.o hm-trp.o serial.o -o set_speed
+
diff --git a/hm-trp.c b/hm-trp.c
new file mode 100644
index 0000000..4ca2cd3
--- /dev/null
+++ b/hm-trp.c
@@ -0,0 +1,196 @@
+#include "hm-trp.h"
+
+#include <stdio.h>
+
+#ifndef CBUFFER_SIZE
+#define CBUFFER_SIZE 32
+#endif
+
+const int count_devtype = 4;
+const char* dev_name[4] = {
+	"HM-TRP-433",
+	"HM-TRP-470",
+	"HM-TRP-868",
+	"HM-TRP-915"
+};
+
+const uint32_t freq_min[4] = {
+	414 * 1e6,
+	450 * 1e6,
+	849 * 1e6,
+	895 * 1e6
+};
+const uint32_t freq_max[4] = {
+	454 * 1e6,
+	490 * 1e6,
+	889 * 1e6,
+	935 * 1e6
+};
+const uint32_t freq_default[4] = {
+	434 * 1e6,
+	470 * 1e6,
+	869 * 1e6,
+	915 * 1e6
+};
+
+const int count_recv_bw = 12;
+// Values selected somewhat randomly...
+const int recv_bw[12] = {
+	30,
+	50,
+	75,
+	90,
+	105,
+	120,
+	150,
+	175,
+	200,
+	250,
+	300,
+	620
+};
+
+const int count_freq_dev = 10;
+// Values selected somewhat randomly...
+const int freq_dev[10] = {  // Values as kHz ..
+	10,
+	20,
+	35,
+	50,
+	55,
+	80,
+	110,
+	120,
+	145,
+	160
+};
+
+const int count_powerlevel = 8;
+const int powerlevel[8] = { 1, 2, 5, 8, 11, 14, 17, 20 };
+
+const int count_rates = 9;
+const int port_rate_value[9] = {
+	1200,
+	1800,
+	2400,
+	4800,
+	9600,
+	19200,
+	38400,
+	57600,
+	115200 
+};
+
+const int port_rates[9] = {
+	B1200,
+	B1800,
+	B2400,
+	B4800,
+	B9600,
+	B19200,
+	B38400,
+	B57600,
+	B115200 
+};
+
+const char cmd_reset[3]     = { 0xAA, 0xFA, 0xF0 };
+const char cmd_config[3]    = { 0xAA, 0xFA, 0xE1 };
+const char cmd_frequency[3] = { 0xAA, 0xFA, 0xD2 };
+const char cmd_air_rate[3]   = { 0xAA, 0xFA, 0xC3 };
+const char cmd_bw[3]        = { 0xAA, 0xFA, 0xB4 };
+const char cmd_deviation[3] = { 0xAA, 0xFA, 0xA5 };
+const char cmd_power[3]     = { 0xAA, 0xFA, 0x96 };
+const char cmd_uart_rate[3] = { 0xAA, 0xFA, 0x1E };
+const char cmd_RSSI[3]      = { 0xAA, 0xFA, 0x87 };
+const char cmd_SNR[3]       = { 0xAA, 0xFA, 0x78 };
+
+int write_uint32_t ( int f, uint32_t v )
+{
+	int i;
+	unsigned char buf[4];
+	v = __bswap_32(v);
+	for ( i = 0; i < 4; i++ )
+		buf[i] = (v>>(8*i) & 0xff );
+
+	return write( f, buf, 4 );
+}
+
+int write_uint16_t ( int f, uint16_t v )
+{
+	int i;
+	unsigned char buf[2];
+	v = __bswap_16(v);
+	for ( i = 0; i < 2; i++ )
+		buf[i] = (v>>(8*i) & 0xff );
+
+	return write( f, buf, 2 );
+}
+
+int write_uint8_t ( int f, uint8_t v )
+{
+	int i;
+	unsigned char buf[2];
+
+	//for ( i = 0; i < 2; i++ )
+	//	buf[i] = (v>>(8*i) & 0xff );
+
+	return write( f, &v, 1 );
+}
+
+int write_cmd ( int f, const char* buf )
+{
+	return write( f, buf, 3 ); 	// Send the command to the device
+}
+
+int read_config ( int fd, config_t * config )
+{
+
+	unsigned char buf[CBUFFER_SIZE];
+	int res;
+
+	res = write_cmd( fd, cmd_config ); 	// Send the command to the device
+	if ( res < 0 ) return(-1); 		// and die on failure..
+
+	int i = 0;
+	uint8_t* tmp_config = (uint8_t*)config;
+	do {
+		bzero(buf, CBUFFER_SIZE);
+		res = read( fd, buf, 1 );
+
+		if ( res )
+		{
+			*tmp_config++ = (uint8_t)buf[0];
+			// Make sure wo don't overflow the config struct.
+			if ( (void*)tmp_config > ((void*)config+sizeof(config_t)) ) return(-2);
+		}
+
+	} while ( res > 0 );
+
+	if ( res < 0 )
+	{
+		return -1;
+	}
+
+	if ( config->freq ) 
+	{
+		config->freq      = __bswap_32( config->freq );
+		config->air_rate  = __bswap_32( config->air_rate );
+		config->bw        = __bswap_16( config->bw );
+		config->uart_rate = __bswap_32( config->uart_rate );
+		return 1;
+	}
+	
+	return 0; // No errors, but no valid config
+}
+
+int read_ok ( int fd )
+{
+	unsigned char ok[5];
+	int i = 0;
+	unsigned char c;
+	bzero(ok, 5);
+
+	while( (read( fd, &c, 1 ) > 0 ) && ( i < 4) ) ok[i++] = c;
+	if ( strcmp( ok, "OK\r\n" ) == 0 ) return 1;
+	return 0;
+}
diff --git a/hm-trp.h b/hm-trp.h
new file mode 100644
index 0000000..68f106e
--- /dev/null
+++ b/hm-trp.h
@@ -0,0 +1,57 @@
+#ifndef _HM_TRP_H
+#define _HM_TRP_H
+
+#include <string.h>  /* String function definitions */
+#include <stdint.h>  /* uint*_t types */
+#include <byteswap.h> /* __bwap_{16,32} */
+#include "serial.h"
+
+typedef struct {
+	uint32_t freq;
+	uint32_t air_rate;
+	uint16_t bw;
+	uint8_t  deviation;
+	uint8_t  power;
+	uint32_t uart_rate;
+} config_t;
+
+extern const int count_devtype;
+extern const char* dev_name[4];
+
+extern const uint32_t freq_min[4];
+extern const uint32_t freq_max[4];
+extern const uint32_t freq_default[4];
+
+extern const int count_recv_bw;
+extern const int recv_bw[12];
+
+extern const int count_freq_dev;
+extern const int freq_dev[10];
+
+extern const int count_powerlevel;
+extern const int powerlevel[8];
+
+extern const int count_rates;
+extern const int port_rate_value[9];
+extern const int port_rates[9];
+
+extern const char cmd_reset[3];
+extern const char cmd_config[3];
+extern const char cmd_frequency[3];
+extern const char cmd_air_rate[3];
+extern const char cmd_bw[3];
+extern const char cmd_deviation[3];
+extern const char cmd_power[3];
+extern const char cmd_uart_rate[3];
+extern const char cmd_RSSI[3];
+extern const char cmd_SNR[3];
+
+int write_uint32_t ( int f, uint32_t v );
+int write_uint16_t ( int f, uint16_t v );
+int write_uint8_t ( int f, uint8_t v );
+int write_cmd ( int f, const char* buf );
+int read_config ( int fd, config_t * config );
+
+int read_ok( int fd );
+
+#endif /* _HM_TRP_H */
diff --git a/read_hm-trp.c b/read_hm-trp.c
new file mode 100644
index 0000000..71c5742
--- /dev/null
+++ b/read_hm-trp.c
@@ -0,0 +1,67 @@
+#include <errno.h>   /* Error number definitions */
+#include <string.h>  /* String function definitions */
+#include <stdio.h>   /* Standard I/O */
+#include <unistd.h>  /* sleep */
+#include <stdlib.h>  /* malloc, free */
+
+#include "hm-trp.h"
+#include "serial.h"
+
+#define CBUFFER_SIZE 32
+
+int main ( int argc, char** argv )
+{
+	int fd;
+	int res;
+	int r, c, f;
+	unsigned char buf[CBUFFER_SIZE];
+
+	config_t* config = malloc(sizeof(config_t));
+	bzero(config, sizeof(config_t));
+
+	if ( ! argv[1] )
+	{
+		printf("Serial port device required as argument, e.g. /dev/ttyUSB0\n");
+		return 1;
+	}
+
+
+	printf("Looking for device on port %s\n", argv[1]);
+
+	for ( r = 0; r <= count_rates; r++ )
+	{
+		fd = open_port( argv[1], port_rates[r] );
+		if ( fd < 0 )
+		{
+			perror(argv[1]); 
+			return(-1);
+		}
+
+		if ( read_config( fd, config )  == 1 )
+		{
+			printf("Found device at baud-rate %d, config:\n", port_rate_value[r] );
+			printf("Freq      %d \n", config->freq );
+			printf("Air rate  %d \n", config->air_rate );
+			printf("Deviation %d \n", config->deviation );
+			printf("TX Power  %d \n", config->power );
+			printf("BW        %d \n", config->bw );
+			printf("UART rate %d \n", config->uart_rate );
+
+
+			for ( f = 0; f < count_devtype; f++ ) 
+			{
+				if ( (config->freq >= freq_min[f]) &&
+						(config->freq <= freq_max[f]))
+				{
+					printf("Device type is %s\n", dev_name[f]);
+				}
+			}
+
+			return(0);
+		}
+		close(fd);
+	}
+	printf("Unable to find device on %s\n", argv[1]);
+	return(1);
+}
+
diff --git a/serial.c b/serial.c
new file mode 100644
index 0000000..7cb5ab0
--- /dev/null
+++ b/serial.c
@@ -0,0 +1,35 @@
+#include "serial.h"
+
+int open_port ( char* device, int rate )
+{
+	int f;
+	struct termios tio;
+
+	f = open ( device, O_RDWR | O_NOCTTY ); // Not using O_NDELAY, that caused ERR11: temp unavail.
+	if ( f < 0 )
+	{
+		return(-1);
+	}
+
+	tio.c_cflag = rate | CS8 | CLOCAL | CREAD;
+
+	// 8 bits, local mode, read enabled
+	tio.c_cflag |= CS8 | CLOCAL | CREAD;
+
+	// no flow-control,
+	tio.c_cflag &= ~CRTSCTS;
+
+	// no parity
+        tio.c_iflag = IGNPAR;
+
+        tio.c_oflag = 0;
+        tio.c_lflag = 0; // Non-canonical read, no other options.
+	tio.c_cc[VMIN] = 0; // Disable minimum characters for read
+       	tio.c_cc[VTIME] = 5; // Wait for a max of 0.5 second
+
+        tcsetattr(f,TCSANOW,&tio); // Apply this now.
+
+	tcflush(f, TCIFLUSH); //  the serial input buffer.
+
+	return f;
+}
diff --git a/serial.h b/serial.h
new file mode 100644
index 0000000..ed3db76
--- /dev/null
+++ b/serial.h
@@ -0,0 +1,10 @@
+#ifndef _SERIAL_H
+#define _SERIAL_H
+
+#include <termios.h> /* Terminal I/O support */
+#include <errno.h>   /* Error number definitions */
+#include <fcntl.h>   /* File descriptor manipulation */
+
+int open_port ( char* device, int rate );
+
+#endif /* _SERIAL_H */
diff --git a/set_speed.c b/set_speed.c
new file mode 100644
index 0000000..c29393c
--- /dev/null
+++ b/set_speed.c
@@ -0,0 +1,85 @@
+#include <errno.h>   /* Error number definitions */
+#include <string.h>  /* String function definitions */
+#include <stdio.h>   /* Standard I/O */
+#include <unistd.h>  /* sleep */
+#include <stdlib.h>  /* malloc, free */
+
+#include "hm-trp.h"
+#include "serial.h"
+
+#define CBUFFER_SIZE 32
+
+int main ( int argc, char** argv )
+{
+	int fd;
+	int res;
+	int r, c, f;
+	long rate;
+
+	unsigned char buf[CBUFFER_SIZE];
+
+	config_t* config = malloc(sizeof(config_t));
+	bzero(config, sizeof(config_t));
+
+	if ( ! argv[1] )
+	{
+		printf("Serial port device required as argument, e.g. /dev/ttyUSB0\n");
+		return 1;
+	}
+
+	if ( ! argv[2] )
+	{
+		printf("Desired bit-rate required. Use RS232 rates only.\n");
+		return 1;
+	}
+
+	rate = atol( argv[2] );
+	for ( r = 0; r <= count_rates; r++ )
+		if ( port_rate_value[r] == rate ) { rate = r; break; }
+
+	if ( r >= count_rates ) { printf("Invalid data rate requested\n"); return 1; }
+
+	printf("Looking for device on port %s\n", argv[1]);
+
+	for ( r = 0; r <= count_rates; r++ )
+	{
+		fd = open_port( argv[1], port_rates[r] );
+		if ( fd < 0 )
+		{
+			perror(argv[1]); 
+			return(-1);
+		}
+
+		if ( read_config( fd, config )  == 1 )
+		{
+			printf("Found device at baud-rate %d.\n", port_rate_value[r] );
+
+			if ( r == rate  && ( config->air_rate == config->uart_rate ) )
+			{
+				printf("Data rate is already set to %d\n", port_rate_value[r] );
+				return 0;
+			}
+
+			write_cmd( fd, cmd_air_rate );
+			write_uint32_t( fd, port_rate_value[rate] );
+
+			if ( ! read_ok( fd ) )
+			{
+				printf("Air rate NOT set\n");
+				return 1;
+			}
+
+			write_cmd( fd, cmd_uart_rate );
+			write_uint32_t( fd, port_rate_value[rate] );
+
+			read_ok( fd ); // Clear buffer.
+
+			printf("Device UART and air data rate set to %d\n", port_rate_value[rate] );
+			return(0);
+		}
+		close(fd);
+	}
+	printf("Unable to find device on %s\n", argv[1]);
+	return(1);
+}
+
diff --git a/swap.c_example b/swap.c_example
new file mode 100644
index 0000000..401f53a
--- /dev/null
+++ b/swap.c_example
@@ -0,0 +1,19 @@
+#include <bits/byteswap.h> /* __bwap_{16,32} */
+
+/*
+  Basically, does:
+uint32_t swap_uint32 ( uint32_t num )
+{
+	return  ( (num>>24) & 0x000000ff) |    // move byte 3 to byte 0
+		( (num<<8)  & 0x00ff0000) |   // move byte 1 to byte 2
+		( (num>>8)  & 0x0000ff00) |     // move byte 2 to byte 1
+		( (num<<24) & 0xff000000); // byte 0 to byte 3
+}
+
+uint16_t swap_uint16 ( uint16_t num )
+{
+	//          Move UP and mask    | Move DOWN and mask
+	return( (num<<8) & 0xff00 ) | ( (num>>8) & 0x00ff ); 
+}
+*/
+