92 lines
2.4 KiB
C++
92 lines
2.4 KiB
C++
|
/* 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);
|
||
|
}
|