mirror of
				https://github.com/brmlab/osmo-tetra.git
				synced 2025-10-30 23:14:00 +01:00 
			
		
		
		
	sniffer (audio and pcap) patch
This commit is contained in:
		
							parent
							
								
									a562b0e9a2
								
							
						
					
					
						commit
						bffab641ae
					
				
					 5 changed files with 204 additions and 11 deletions
				
			
		|  | @ -39,6 +39,9 @@ | ||||||
| #include "tetra_upper_mac.h" | #include "tetra_upper_mac.h" | ||||||
| #include <lower_mac/viterbi.h> | #include <lower_mac/viterbi.h> | ||||||
| 
 | 
 | ||||||
|  | extern int ssi; | ||||||
|  | extern int tsn; | ||||||
|  | 
 | ||||||
| struct tetra_blk_param { | struct tetra_blk_param { | ||||||
| 	const char *name; | 	const char *name; | ||||||
| 	uint16_t type345_bits; | 	uint16_t type345_bits; | ||||||
|  | @ -184,6 +187,57 @@ void tp_sap_udata_ind(enum tp_sap_data_type type, const uint8_t *bits, unsigned | ||||||
| 	DEBUGP("%s %s type4: %s\n", tbp->name, time_str, | 	DEBUGP("%s %s type4: %s\n", tbp->name, time_str, | ||||||
| 		osmo_ubit_dump(type4, tbp->type345_bits)); | 		osmo_ubit_dump(type4, tbp->type345_bits)); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /*  ###### Begin traffic dump patch ###### */ | ||||||
|  | 
 | ||||||
|  | 	extern char *dumpdir; | ||||||
|  | 	if ((type == TPSAP_T_SCH_F) && (tms->cur_burst.is_traffic) && dumpdir) { | ||||||
|  | 		printf("SAVING FRAME\n"); | ||||||
|  | 		char fname[200]; | ||||||
|  | 		int16_t block[690]; | ||||||
|  | 		FILE *f; | ||||||
|  | 		int i; | ||||||
|  | 
 | ||||||
|  | 		/* Open target file */ | ||||||
|  | 		//snprintf(fname, 100, "traffic_%d_%d.out", tcd->time.tn, tms->cur_burst.is_traffic);
 | ||||||
|  | 		//snprintf(fname, 100, "traffic_%d.out", tcd->time.tn);
 | ||||||
|  | 		snprintf(fname, 199, "%s/traffic_%d_%d.out", dumpdir, tms->cur_burst.is_traffic, tsn); | ||||||
|  | 		f = fopen(fname, "ab"); | ||||||
|  | 
 | ||||||
|  | 		/* Generate a block */ | ||||||
|  | 		memset(block, 0x00, sizeof(int16_t) * 690); | ||||||
|  | 		for (i=0; i<6; i++) | ||||||
|  | 		block[115*i] = 0x6b21 + i; | ||||||
|  | 
 | ||||||
|  | 		for (i=0; i<114; i++) | ||||||
|  | 		block[ 1+i] = type4[ i] ? -127 : 127; | ||||||
|  | 
 | ||||||
|  | 		for (i=0; i<114; i++) | ||||||
|  | 		block[116+i] = type4[114+i] ? -127 : 127; | ||||||
|  | 
 | ||||||
|  | 		for (i=0; i<114; i++) | ||||||
|  | 		block[231+i] = type4[228+i] ? -127 : 127; | ||||||
|  | 
 | ||||||
|  | 		for (i=0; i<90; i++) | ||||||
|  | 		block[346+i] = type4[342+i] ? -127 : 127; | ||||||
|  | 
 | ||||||
|  | 		/* Write it */ | ||||||
|  | 		fwrite(block, sizeof(int16_t), 690, f); | ||||||
|  | 
 | ||||||
|  | 		/* Close */ | ||||||
|  | 		fclose(f); | ||||||
|  | 		memset(fname, 0x0, sizeof(char)*200); | ||||||
|  | 		snprintf(fname, 199, "%s/traffic_%d_%d.txt", dumpdir, tms->cur_burst.is_traffic, tsn); | ||||||
|  | 		/* Write used ssi */ | ||||||
|  | 		f=fopen(fname, "a"); | ||||||
|  | 		memset(fname, 0x0, sizeof(char)*200); | ||||||
|  | 		snprintf(fname, 199, "%d\n", ssi); | ||||||
|  | 		fwrite(fname, sizeof(char), strlen(fname), f); | ||||||
|  | 		fclose(f); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* end traffic dump patch */ | ||||||
|  | 
 | ||||||
| 	if (tbp->interleave_a) { | 	if (tbp->interleave_a) { | ||||||
| 		/* Run block deinterleaving: type-3 bits */ | 		/* Run block deinterleaving: type-3 bits */ | ||||||
| 		block_deinterleave(tbp->type345_bits, tbp->interleave_a, type4, type3); | 		block_deinterleave(tbp->type345_bits, tbp->interleave_a, type4, type3); | ||||||
|  |  | ||||||
							
								
								
									
										50
									
								
								src/pcap.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/pcap.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | ||||||
|  | #ifndef PCAP_H | ||||||
|  | #define PCAP_H | ||||||
|  | #include <inttypes.h> | ||||||
|  | 
 | ||||||
|  | typedef uint32_t guint32; | ||||||
|  | typedef uint16_t guint16; | ||||||
|  | typedef int32_t gint32; | ||||||
|  | 
 | ||||||
|  | typedef struct __attribute__ ((__packed__)) pcap_hdr_s { | ||||||
|  |         guint32 magic_number;   /* magic number */ | ||||||
|  |         guint16 version_major;  /* major version number */ | ||||||
|  |         guint16 version_minor;  /* minor version number */ | ||||||
|  |         gint32  thiszone;       /* GMT to local correction */ | ||||||
|  |         guint32 sigfigs;        /* accuracy of timestamps */ | ||||||
|  |         guint32 snaplen;        /* max length of captured packets, in octets */ | ||||||
|  |         guint32 network;        /* data link type */ | ||||||
|  | } pcap_hdr_t; | ||||||
|  | 
 | ||||||
|  | typedef struct __attribute__ ((__packed__)) pcaprec_hdr_s { | ||||||
|  |         guint32 ts_sec;         /* timestamp seconds */ | ||||||
|  |         guint32 ts_usec;        /* timestamp microseconds */ | ||||||
|  |         guint32 incl_len;       /* number of octets of packet saved in file */ | ||||||
|  |         guint32 orig_len;       /* actual length of packet */ | ||||||
|  | } pcaprec_hdr_t; | ||||||
|  | 
 | ||||||
|  | #define PCAP_MAGIC 0xa1b2c3d4 | ||||||
|  | #define PCAP_MAJOR 2 | ||||||
|  | #define PCAP_MINOR 4 | ||||||
|  | #define PCAP_SNAPLEN 65535 | ||||||
|  | #define PCAP_ETHERNET 1 | ||||||
|  | 
 | ||||||
|  | unsigned char fake_frame_header[] = { | ||||||
|  | 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Ethernet frame, dst and src MAC
 | ||||||
|  | 	0x08, 0x00,		// EtherType 0800 = IPv4
 | ||||||
|  | 	0x45,			// IPv4 (0x4_), 20B header (0x_5)
 | ||||||
|  | 	0x00,			// no diffserv
 | ||||||
|  | 	0x00, 0xff,		// length
 | ||||||
|  | 	0xc6, 0xd1,		// some random frag
 | ||||||
|  | 	0x40, 0x00,		// don't frag
 | ||||||
|  | 	0x3f,			// TTL
 | ||||||
|  | 	0x11,			// IP proto = UDP
 | ||||||
|  | 	0x00, 0x00,		// checksum
 | ||||||
|  | 	0x7f, 0x00, 0x00, 0x01,	// src = 127.0.0.1
 | ||||||
|  | 	0x7f, 0x00, 0x00, 0x01, // dst = 127.0.0.1
 | ||||||
|  | 	0xbb, 0x13,		// source port
 | ||||||
|  | 	0x12, 0x79,		// dst port = 4729
 | ||||||
|  | 	0x00, 0xeb,		// length = iplen-20
 | ||||||
|  | 	0x00, 0x00		// checksum
 | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  | @ -35,25 +35,57 @@ | ||||||
| #include "tetra_gsmtap.h" | #include "tetra_gsmtap.h" | ||||||
| 
 | 
 | ||||||
| void *tetra_tall_ctx; | void *tetra_tall_ctx; | ||||||
|  | char *dumpdir; | ||||||
|  | 
 | ||||||
|  | char *pcap_file_path; | ||||||
|  | int arfcn; | ||||||
|  | int ssi; | ||||||
|  | int tsn; | ||||||
| 
 | 
 | ||||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||||
| { | { | ||||||
| 	int fd; | 	int fd; | ||||||
|  | 	int opt; | ||||||
|  | 
 | ||||||
| 	struct tetra_rx_state *trs; | 	struct tetra_rx_state *trs; | ||||||
| 	struct tetra_mac_state *tms; | 	struct tetra_mac_state *tms; | ||||||
| 
 | 
 | ||||||
| 	if (argc < 2) { | 	char no_udp_tap = 0; | ||||||
|  | 
 | ||||||
|  | 	while ((opt = getopt(argc, argv, "a:t:d:n")) != -1) { | ||||||
|  | 		switch (opt) { | ||||||
|  | 		case 'a': | ||||||
|  | 			arfcn = atoi(optarg); | ||||||
|  | 			break; | ||||||
|  | 		case 't': | ||||||
|  | 			//pcap_file_path = malloc(strlen(optarg));
 | ||||||
|  | 			//memcpy(pcap_file_path, optarg, strlen(optarg));
 | ||||||
|  | 			pcap_file_path = optarg; | ||||||
|  | 			break; | ||||||
|  | 		case 'd': | ||||||
|  | 			dumpdir = optarg; | ||||||
|  | 			break; | ||||||
|  | 		case 'n': | ||||||
|  | 			fprintf(stderr, "-n does not work\n"); | ||||||
|  | 			exit(1); | ||||||
|  | 			no_udp_tap = 1; | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			fprintf(stderr, "Unknown option %c\n", opt); | ||||||
|  | 			exit(2); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (argc <= optind) { | ||||||
|  | 		fprintf(stderr, "Usage: %s [-a ARFCN] [-t GSMTAP_PATH] [-d DUMPDIR] [-n] -s [-v] <filestream>\n", argv[0]); | ||||||
|  | 		fprintf(stderr, "Usage: -n .. no UDP GSMTAP messages\n"); | ||||||
| 		fprintf(stderr, "Usage: %s <file_with_1_byte_per_bit>\n", argv[0]); | 		fprintf(stderr, "Usage: %s <file_with_1_byte_per_bit>\n", argv[0]); | ||||||
| 		exit(1); | 		exit(1); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fd = open(argv[1], O_RDONLY); | 	if (no_udp_tap == 0) { | ||||||
| 	if (fd < 0) { |  | ||||||
| 		perror("open"); |  | ||||||
| 		exit(2); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 		tetra_gsmtap_init("localhost", 0); | 		tetra_gsmtap_init("localhost", 0); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	tms = talloc_zero(tetra_tall_ctx, struct tetra_mac_state); | 	tms = talloc_zero(tetra_tall_ctx, struct tetra_mac_state); | ||||||
| 	tetra_mac_state_init(tms); | 	tetra_mac_state_init(tms); | ||||||
|  | @ -61,6 +93,12 @@ int main(int argc, char **argv) | ||||||
| 	trs = talloc_zero(tetra_tall_ctx, struct tetra_rx_state); | 	trs = talloc_zero(tetra_tall_ctx, struct tetra_rx_state); | ||||||
| 	trs->burst_cb_priv = tms; | 	trs->burst_cb_priv = tms; | ||||||
| 
 | 
 | ||||||
|  | 	fd = open(argv[optind], O_RDONLY); | ||||||
|  | 	if (fd < 0) { | ||||||
|  | 		perror("open"); | ||||||
|  | 		exit(2); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	while (1) { | 	while (1) { | ||||||
| 		uint8_t buf[64]; | 		uint8_t buf[64]; | ||||||
| 		int len; | 		int len; | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
|  | #include <time.h> | ||||||
| 
 | 
 | ||||||
| #include <osmocom/core/msgb.h> | #include <osmocom/core/msgb.h> | ||||||
| #include <osmocom/core/gsmtap.h> | #include <osmocom/core/gsmtap.h> | ||||||
|  | @ -14,7 +15,13 @@ | ||||||
| #include "tetra_common.h" | #include "tetra_common.h" | ||||||
| #include "tetra_tdma.h" | #include "tetra_tdma.h" | ||||||
| 
 | 
 | ||||||
|  | #include "pcap.h" | ||||||
|  | 
 | ||||||
| static struct gsmtap_inst *g_gti = NULL; | static struct gsmtap_inst *g_gti = NULL; | ||||||
|  | FILE *pcap_file; | ||||||
|  | extern char *pcap_file_path; | ||||||
|  | extern int arfcn; | ||||||
|  | extern int tsn; | ||||||
| 
 | 
 | ||||||
| static const uint8_t lchan2gsmtap[] = { | static const uint8_t lchan2gsmtap[] = { | ||||||
| 	[TETRA_LC_SCH_F]	= GSMTAP_TETRA_SCH_F, | 	[TETRA_LC_SCH_F]	= GSMTAP_TETRA_SCH_F, | ||||||
|  | @ -27,7 +34,6 @@ static const uint8_t lchan2gsmtap[] = { | ||||||
| 	[TETRA_LC_BNCH]		= GSMTAP_TETRA_BNCH, | 	[TETRA_LC_BNCH]		= GSMTAP_TETRA_BNCH, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| struct msgb *tetra_gsmtap_makemsg(struct tetra_tdma_time *tm, enum tetra_log_chan lchan, | struct msgb *tetra_gsmtap_makemsg(struct tetra_tdma_time *tm, enum tetra_log_chan lchan, | ||||||
| 				  uint8_t ts, uint8_t ss, int8_t signal_dbm, | 				  uint8_t ts, uint8_t ss, int8_t signal_dbm, | ||||||
| 				  uint8_t snr, const ubit_t *bitdata, unsigned int bitlen) | 				  uint8_t snr, const ubit_t *bitdata, unsigned int bitlen) | ||||||
|  | @ -47,8 +53,10 @@ struct msgb *tetra_gsmtap_makemsg(struct tetra_tdma_time *tm, enum tetra_log_cha | ||||||
| 	gh->hdr_len = sizeof(*gh)/4; | 	gh->hdr_len = sizeof(*gh)/4; | ||||||
| 	gh->type = GSMTAP_TYPE_TETRA_I1; | 	gh->type = GSMTAP_TYPE_TETRA_I1; | ||||||
| 	gh->timeslot = ts; | 	gh->timeslot = ts; | ||||||
|  |   tsn = ts; | ||||||
| 	gh->sub_slot = ss; | 	gh->sub_slot = ss; | ||||||
| 	gh->snr_db = snr; | 	gh->snr_db = snr; | ||||||
|  | 	gh->arfcn = htons(arfcn); | ||||||
| 	gh->signal_dbm = signal_dbm; | 	gh->signal_dbm = signal_dbm; | ||||||
| 	gh->frame_number = htonl(fn); | 	gh->frame_number = htonl(fn); | ||||||
| 	gh->sub_type = lchan2gsmtap[lchan]; | 	gh->sub_type = lchan2gsmtap[lchan]; | ||||||
|  | @ -61,8 +69,31 @@ struct msgb *tetra_gsmtap_makemsg(struct tetra_tdma_time *tm, enum tetra_log_cha | ||||||
| 	return msg; | 	return msg; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void pcap_pipe(char * buf, size_t n) | ||||||
|  | { | ||||||
|  | 	if (pcap_file) { | ||||||
|  | 		fwrite(buf, n, 1, pcap_file); | ||||||
|  | 		fflush(pcap_file); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int tetra_gsmtap_sendmsg(struct msgb *msg) | int tetra_gsmtap_sendmsg(struct msgb *msg) | ||||||
| { | { | ||||||
|  | 	pcaprec_hdr_t hdr; | ||||||
|  | 	bzero(&hdr, sizeof(hdr)); | ||||||
|  | 
 | ||||||
|  | 	struct timespec now; | ||||||
|  | 	clock_gettime(CLOCK_REALTIME, &now); | ||||||
|  | 
 | ||||||
|  | 	hdr.ts_sec = now.tv_sec; | ||||||
|  | 	hdr.ts_usec = now.tv_nsec/1000; | ||||||
|  | 	hdr.incl_len = msg->len + sizeof(fake_frame_header); | ||||||
|  | 	hdr.orig_len = hdr.incl_len; | ||||||
|  | 
 | ||||||
|  | 	pcap_pipe((char*)&hdr, sizeof(pcaprec_hdr_t)); | ||||||
|  | 	pcap_pipe((char*)&fake_frame_header, sizeof(fake_frame_header)); | ||||||
|  | 	pcap_pipe((char*)msg->data, msg->len); | ||||||
|  | 
 | ||||||
| 	if (g_gti) | 	if (g_gti) | ||||||
| 		return gsmtap_sendmsg(g_gti, msg); | 		return gsmtap_sendmsg(g_gti, msg); | ||||||
| 	else | 	else | ||||||
|  | @ -76,5 +107,20 @@ int tetra_gsmtap_init(const char *host, uint16_t port) | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 	gsmtap_source_add_sink(g_gti); | 	gsmtap_source_add_sink(g_gti); | ||||||
| 
 | 
 | ||||||
|  | 	if (pcap_file_path) { | ||||||
|  | 		pcap_hdr_t hdr; | ||||||
|  | 
 | ||||||
|  | 		bzero(&hdr, sizeof(hdr)); | ||||||
|  | 
 | ||||||
|  | 		hdr.magic_number = PCAP_MAGIC; | ||||||
|  | 		hdr.version_major = PCAP_MAJOR; | ||||||
|  | 		hdr.version_minor = PCAP_MINOR; | ||||||
|  | 		hdr.snaplen = PCAP_SNAPLEN; | ||||||
|  | 		hdr.network = PCAP_ETHERNET; | ||||||
|  | 
 | ||||||
|  | 		pcap_file = fopen(pcap_file_path, "wb"); | ||||||
|  | 		//pcap_pipe((char*)&hdr, sizeof(pcap_hdr_t));
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,6 +38,8 @@ | ||||||
| #include "tetra_mle_pdu.h" | #include "tetra_mle_pdu.h" | ||||||
| #include "tetra_gsmtap.h" | #include "tetra_gsmtap.h" | ||||||
| 
 | 
 | ||||||
|  | extern int ssi; | ||||||
|  | 
 | ||||||
| static int rx_tm_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len); | static int rx_tm_sdu(struct tetra_mac_state *tms, struct msgb *msg, unsigned int len); | ||||||
| 
 | 
 | ||||||
| static void rx_bcast(struct tetra_tmvsap_prim *tmvp, struct tetra_mac_state *tms) | static void rx_bcast(struct tetra_tmvsap_prim *tmvp, struct tetra_mac_state *tms) | ||||||
|  | @ -181,6 +183,8 @@ static void rx_resrc(struct tetra_tmvsap_prim *tmvp, struct tetra_mac_state *tms | ||||||
| 		rx_tm_sdu(tms, msg, len_bits); | 		rx_tm_sdu(tms, msg, len_bits); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |   ssi = rsd.addr.ssi; | ||||||
|  | 
 | ||||||
| out: | out: | ||||||
| 	printf("\n"); | 	printf("\n"); | ||||||
| } | } | ||||||
|  | @ -240,11 +244,12 @@ static void rx_aach(struct tetra_tmvsap_prim *tmvp, struct tetra_mac_state *tms) | ||||||
| 		printf("UL_USAGE: %s ", tetra_get_ul_usage_name(aad.ul_usage)); | 		printf("UL_USAGE: %s ", tetra_get_ul_usage_name(aad.ul_usage)); | ||||||
| 
 | 
 | ||||||
| 	/* save the state whether the current burst is traffic or not */ | 	/* save the state whether the current burst is traffic or not */ | ||||||
| 	if (aad.dl_usage > 3) | 	if (aad.dl_usage > 3) { | ||||||
| 		tms->cur_burst.is_traffic = 1; | 		tms->cur_burst.is_traffic = 1; | ||||||
| 	else | 		tms->cur_burst.is_traffic = aad.dl_usage; | ||||||
|  | 	} else { | ||||||
| 		tms->cur_burst.is_traffic = 0; | 		tms->cur_burst.is_traffic = 0; | ||||||
| 
 | 	} | ||||||
| 	printf("\n"); | 	printf("\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jenda
						Jenda