|
|
|
@ -28,6 +28,18 @@ |
|
|
|
|
// TODO: We should take ports and IP from config.
|
|
|
|
|
UDPSocket pcu_gsmtap_socket(5077, "127.0.0.1", 4729); |
|
|
|
|
|
|
|
|
|
// Variable for storage current FN.
|
|
|
|
|
int frame_number; |
|
|
|
|
|
|
|
|
|
int get_current_fn() |
|
|
|
|
{ |
|
|
|
|
return frame_number; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void set_current_fn(int fn) |
|
|
|
|
{ |
|
|
|
|
frame_number = fn; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct msgb *l1p_msgb_alloc(void) |
|
|
|
|
{ |
|
|
|
@ -39,11 +51,27 @@ struct msgb *l1p_msgb_alloc(void) |
|
|
|
|
return msg; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct msgb *gen_dummy_msg(void) |
|
|
|
|
{ |
|
|
|
|
int ofs = 0; |
|
|
|
|
struct msgb *msg = l1p_msgb_alloc(); |
|
|
|
|
GsmL1_Prim_t *prim = msgb_l1prim(msg); |
|
|
|
|
// RLC/MAC filler with USF=1
|
|
|
|
|
BitVector filler("0100000110010100001010110010101100101011001010110010101100101011001010110010101100101011001010110010101100101011001010110010101100101011001010110010101100101011001010110010101100101011"); |
|
|
|
|
prim->id = GsmL1_PrimId_PhDataReq; |
|
|
|
|
filler.pack((unsigned char*)&(prim->u.phDataReq.msgUnitParam.u8Buffer[ofs])); |
|
|
|
|
ofs += filler.size() >> 3; |
|
|
|
|
prim->u.phDataReq.msgUnitParam.u8Size = ofs; |
|
|
|
|
return msg; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Send RLC/MAC block to OpenBTS.
|
|
|
|
|
void pcu_l1if_tx(BitVector * block) |
|
|
|
|
{ |
|
|
|
|
int ofs = 0; |
|
|
|
|
struct msgb *msg = l1p_msgb_alloc(); |
|
|
|
|
struct osmo_wqueue * queue; |
|
|
|
|
queue = &((l1fh->fl1h)->write_q); |
|
|
|
|
GsmL1_Prim_t *prim = msgb_l1prim(msg); |
|
|
|
|
|
|
|
|
|
prim->id = GsmL1_PrimId_PhDataReq; |
|
|
|
@ -51,21 +79,37 @@ void pcu_l1if_tx(BitVector * block) |
|
|
|
|
ofs += block->size() >> 3; |
|
|
|
|
prim->u.phDataReq.msgUnitParam.u8Size = ofs; |
|
|
|
|
|
|
|
|
|
COUT("Send to OpenBTS: " << *block); |
|
|
|
|
osmo_wqueue_enqueue(&l1fh->udp_wq, msg); |
|
|
|
|
COUT("Add Block to WRITE QUEUE: " << *block); |
|
|
|
|
osmo_wqueue_enqueue(queue, msg); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int pcu_l1if_rx_pdch(GsmL1_PhDataInd_t *data_ind) |
|
|
|
|
{ |
|
|
|
|
BitVector *block = new BitVector(23*8); |
|
|
|
|
block->unpack((const unsigned char*)data_ind->msgUnitParam.u8Buffer); |
|
|
|
|
COUT("Recieve from OpenBTS (MS): " << *block); |
|
|
|
|
COUT("RX: " << *block); |
|
|
|
|
|
|
|
|
|
gprs_rlcmac_rcv_block(block); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_ind, |
|
|
|
|
struct msgb *l1p_msg) |
|
|
|
|
static int handle_ph_readytosend_ind(struct femtol1_hdl *fl1, GsmL1_PhReadyToSendInd_t *readytosend_ind) |
|
|
|
|
{ |
|
|
|
|
struct msgb *resp_msg; |
|
|
|
|
struct osmo_wqueue * queue; |
|
|
|
|
queue = &((l1fh->fl1h)->write_q); |
|
|
|
|
|
|
|
|
|
set_current_fn(readytosend_ind->u32Fn); |
|
|
|
|
resp_msg = msgb_dequeue(&queue->msg_queue); |
|
|
|
|
if (!resp_msg) { |
|
|
|
|
resp_msg = gen_dummy_msg(); |
|
|
|
|
if (!resp_msg) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
osmo_wqueue_enqueue(&l1fh->udp_wq, resp_msg); |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_ind) |
|
|
|
|
{ |
|
|
|
|
int rc = 0; |
|
|
|
|
switch (data_ind->sapi) { |
|
|
|
@ -97,16 +141,14 @@ int pcu_l1if_handle_l1prim(struct femtol1_hdl *fl1, struct msgb *msg) |
|
|
|
|
int rc = 0; |
|
|
|
|
|
|
|
|
|
switch (l1p->id) { |
|
|
|
|
case GsmL1_PrimId_MphTimeInd: |
|
|
|
|
break; |
|
|
|
|
case GsmL1_PrimId_MphSyncInd: |
|
|
|
|
break; |
|
|
|
|
case GsmL1_PrimId_PhConnectInd: |
|
|
|
|
break; |
|
|
|
|
case GsmL1_PrimId_PhReadyToSendInd: |
|
|
|
|
rc = handle_ph_readytosend_ind(fl1, &l1p->u.phReadyToSendInd); |
|
|
|
|
break; |
|
|
|
|
case GsmL1_PrimId_PhDataInd: |
|
|
|
|
rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd, msg); |
|
|
|
|
COUT("RX GsmL1_PrimId_PhDataInd "); |
|
|
|
|
rc = handle_ph_data_ind(fl1, &l1p->u.phDataInd); |
|
|
|
|
break; |
|
|
|
|
case GsmL1_PrimId_PhRaInd: |
|
|
|
|
break; |
|
|
|
|