diff options
Diffstat (limited to 'pcu_l1_if.cpp')
-rw-r--r-- | pcu_l1_if.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/pcu_l1_if.cpp b/pcu_l1_if.cpp new file mode 100644 index 00000000..54c5b368 --- /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); +} |