aboutsummaryrefslogtreecommitdiffstats
path: root/pcu_l1_if.cpp
blob: 54c5b368ece2c9c235288192487b69bb63c40a7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* pcu_l1_if.cpp
 *
 * Copyright (C) 2012 Ivan Klyuchnikov
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <Sockets.h>
#include <gsmtap.h>
#include <gprs_rlcmac.h>
#include <Threads.h>
#include <pcu_l1_if.h>

#define MAX_UDP_LENGTH 1500

// TODO: We should take ports and IP from config.
UDPSocket pcu_l1if_socket(5070, "127.0.0.1", 5934);
UDPSocket pcu_gsmtap_socket(5077, "127.0.0.1", 4729);

// Send RLC/MAC block to OpenBTS.
void pcu_l1if_tx(BitVector * block)
{
	char buffer[MAX_UDP_LENGTH];
	int ofs = 0;
	block->pack((unsigned char*)&buffer[ofs]);
	ofs += block->size() >> 3;
	COUT("Send to OpenBTS: " << *block);
	pcu_l1if_socket.write(buffer, ofs);
}

// Recieve RLC/MAC block from OpenBTS.
void *pcu_l1if_rx(void *)
{
	BitVector *block = new BitVector(23*8);
	pcu_l1if_socket.nonblocking();
	while (1) {
		char buf[MAX_UDP_LENGTH];
		int count = pcu_l1if_socket.read(buf, 3000);
		if (count>0) {
			block->unpack((const unsigned char*)buf);
			COUT("Recieve from OpenBTS (MS): " << *block);
			gprs_rlcmac_rcv_block(block);
		}
	}
}

void gsmtap_send_llc(uint8_t * data, unsigned len)
{
	char buffer[MAX_UDP_LENGTH];
	int ofs = 0;

	// Build header
	struct gsmtap_hdr *header = (struct gsmtap_hdr *)buffer;
	header->version			= 2;
	header->hdr_len			= sizeof(struct gsmtap_hdr) >> 2;
	header->type			= 0x08;
	header->timeslot		= 5;
	header->arfcn			= 0;
	header->signal_dbm		= 0;
	header->snr_db			= 0;
	header->frame_number	= 0;
	header->sub_type		= 0;
	header->antenna_nr		= 0;
	header->sub_slot		= 0;
	header->res				= 0;

	ofs += sizeof(*header);

	// Add frame data
	unsigned j = 0;
	for (unsigned i = ofs; i < len+ofs; i++)
	{
		buffer[i] = (char)data[j];
		j++;
	}
	ofs += len;
	// Write the GSMTAP packet
	pcu_gsmtap_socket.write(buffer, ofs);
}