Separation of GPRS PCU application from main OpenBTS code and changing PCU architecture (First step).
1. pcu - main program for  GPRS PCU.
2. gprs_rlcmac - RLC/MAC layer implementation for PCU. Added list for TBF, TBF allocation, establishment, release.
3. gprs_bssgp_pcu - BSSGP protocol implementation for PCU.
4. pcu_l1_if - interface for communication PCU application with OpenBTS.
diff --git a/pcu_l1_if.cpp b/pcu_l1_if.cpp
new file mode 100644
index 0000000..54c5b36
--- /dev/null
+++ b/pcu_l1_if.cpp
@@ -0,0 +1,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);
+}