Commit 6cc2d6fb authored by Swetank Srivastava's avatar Swetank Srivastava

changes for debugging gNB setup

parent d7d51b4f
...@@ -38,7 +38,6 @@ void nfapi_trace(nfapi_trace_level_t, char const *caller, const char *format, .. ...@@ -38,7 +38,6 @@ void nfapi_trace(nfapi_trace_level_t, char const *caller, const char *format, ..
nfapi_trace_level_t nfapi_trace_level(void); nfapi_trace_level_t nfapi_trace_level(void);
#define NFAPI_TRACE(LEVEL, FORMAT, ...) do { \ #define NFAPI_TRACE(LEVEL, FORMAT, ...) do { \
if (nfapi_trace_level() >= (LEVEL)) \ nfapi_trace(LEVEL, __func__, FORMAT, ##__VA_ARGS__); \
nfapi_trace(LEVEL, __func__, FORMAT, ##__VA_ARGS__); \
} while (0) } while (0)
...@@ -1596,74 +1596,75 @@ uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy) ...@@ -1596,74 +1596,75 @@ uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy)
// P7 messages // P7 messages
void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
{ {
//NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req Received\n"); //NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req Received\n");
nfapi_nr_dl_tti_request_t* req = allocate_nfapi_dl_tti_request(pnf_p7); nfapi_nr_dl_tti_request_t* req = allocate_nfapi_dl_tti_request(pnf_p7);
if(req == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_dl_tti_request structure\n");
return;
}
int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_dl_tti_request_t), &(pnf_p7->_public.codec_config));
if(unpack_result == 0) if(req == NULL)
{ {
if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_dl_tti_request structure\n");
{ return;
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); }
return; int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_dl_tti_request_t), &(pnf_p7->_public.codec_config));
}
if(is_nr_p7_request_in_window(req->SFN,req->Slot, "dl_tti_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % 20;
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_TTI_REQ current tx sfn/slot:%d.%d p7 msg sfn/slot: %d.%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, pnf_p7->sfn,pnf_p7->slot, req->SFN, req->Slot, buffer_index);
// if there is already an dl_tti_req make sure we free it. if(unpack_result == 0)
if(pnf_p7->slot_buffer[buffer_index].dl_tti_req != 0) {
{ if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_nr_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_slot:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(req->SFN,req->Slot), buffer_index); {
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing dl_config_req at index %d (%d/%d)", NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
// pMyPhyInfo->sfnSf, bufferIdx, return;
// SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); }
deallocate_nfapi_dl_tti_request(pnf_p7->slot_buffer[buffer_index].dl_tti_req, pnf_p7);
}
// filling dl_tti_request in slot buffer if(is_nr_p7_request_in_window(req->SFN,req->Slot, "dl_tti_request", pnf_p7))
pnf_p7->slot_buffer[buffer_index].sfn = req->SFN; {
pnf_p7->slot_buffer[buffer_index].slot = req->Slot; uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
pnf_p7->slot_buffer[buffer_index].dl_tti_req = req; uint8_t buffer_index = sfn_slot_dec % 20;
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
NFAPI_TRACE(NFAPI_TRACE_INFO, "swetank: fxn:%s sfn:%d slot:%d\n", __FUNCTION__, req->SFN, req->Slot);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_TTI_REQ current tx sfn/slot:%d.%d p7 msg sfn/slot: %d.%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, pnf_p7->sfn,pnf_p7->slot, req->SFN, req->Slot, buffer_index);
// if there is already an dl_tti_req make sure we free it.
if(pnf_p7->slot_buffer[buffer_index].dl_tti_req != 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_nr_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_slot:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(req->SFN,req->Slot), buffer_index);
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing dl_config_req at index %d (%d/%d)",
// pMyPhyInfo->sfnSf, bufferIdx,
// SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf));
deallocate_nfapi_dl_tti_request(pnf_p7->slot_buffer[buffer_index].dl_tti_req, pnf_p7);
}
// filling dl_tti_request in slot buffer
pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
pnf_p7->slot_buffer[buffer_index].dl_tti_req = req;
pnf_p7->stats.dl_tti_ontime++;
}
else
{
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "NOT storing dl_config_req SFN/SF %d\n", req->sfn_sf);
deallocate_nfapi_dl_tti_request(req, pnf_p7);
pnf_p7->stats.dl_tti_ontime++; if(pnf_p7->_public.timing_info_mode_aperiodic)
} {
else pnf_p7->timing_info_aperiodic_send = 1;
{ }
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "NOT storing dl_config_req SFN/SF %d\n", req->sfn_sf);
deallocate_nfapi_dl_tti_request(req, pnf_p7);
if(pnf_p7->_public.timing_info_mode_aperiodic) pnf_p7->stats.dl_tti_late++;
{ }
pnf_p7->timing_info_aperiodic_send = 1; if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
} {
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
pnf_p7->stats.dl_tti_late++; return;
} }
if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) }
{ else
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); {
return; NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack dl_tti_req");
} deallocate_nfapi_dl_tti_request(req, pnf_p7);
} }
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack dl_tti_req");
deallocate_nfapi_dl_tti_request(req, pnf_p7);
}
} }
...@@ -1781,32 +1782,33 @@ void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) ...@@ -1781,32 +1782,33 @@ void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
} }
if(is_nr_p7_request_in_window(req->SFN,req->Slot, "ul_tti_request", pnf_p7)) if(is_nr_p7_request_in_window(req->SFN,req->Slot, "ul_tti_request", pnf_p7))
{ {
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot); NFAPI_TRACE(NFAPI_TRACE_INFO, "swetank: fxn:%s sfn:%d slot:%d\n", __FUNCTION__, req->SFN, req->Slot);
uint8_t buffer_index = (sfn_slot_dec % 20); uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = (sfn_slot_dec % 20);
struct timespec t; struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t); clock_gettime(CLOCK_MONOTONIC, &t);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_TTI_REQ current tx sfn/slot:%d.%d p7 msg sfn/slot: %d.%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, pnf_p7->sfn,pnf_p7->slot, req->SFN, req->Slot, buffer_index); NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_TTI_REQ current tx sfn/slot:%d.%d p7 msg sfn/slot: %d.%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, pnf_p7->sfn,pnf_p7->slot, req->SFN, req->Slot, buffer_index);
if(pnf_p7->slot_buffer[buffer_index].ul_tti_req != 0) if(pnf_p7->slot_buffer[buffer_index].ul_tti_req != 0)
{ {
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing ul_config_req at index %d (%d/%d)", //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing ul_config_req at index %d (%d/%d)",
// pMyPhyInfo->sfnSf, bufferIdx, // pMyPhyInfo->sfnSf, bufferIdx,
// SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf));
deallocate_nfapi_ul_tti_request(pnf_p7->slot_buffer[buffer_index].ul_tti_req, pnf_p7); deallocate_nfapi_ul_tti_request(pnf_p7->slot_buffer[buffer_index].ul_tti_req, pnf_p7);
} }
//filling slot buffer
pnf_p7->slot_buffer[buffer_index].sfn = req->SFN; //filling slot buffer
pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
pnf_p7->slot_buffer[buffer_index].ul_tti_req = req; pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
pnf_p7->stats.ul_tti_ontime++; pnf_p7->slot_buffer[buffer_index].ul_tti_req = req;
}
pnf_p7->stats.ul_tti_ontime++;
}
else else
{ {
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing ul_tti_req OUTSIDE OF TRANSMIT BUFFER WINDOW SFN/SLOT %d\n", NFAPI_SFNSLOT2DEC(pnf_p7->sfn,pnf_p7->slot), NFAPI_SFNSLOT2DEC(req->SFN,req->Slot)); NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing ul_tti_req OUTSIDE OF TRANSMIT BUFFER WINDOW SFN/SLOT %d\n", NFAPI_SFNSLOT2DEC(pnf_p7->sfn,pnf_p7->slot), NFAPI_SFNSLOT2DEC(req->SFN,req->Slot));
...@@ -1930,6 +1932,7 @@ void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) ...@@ -1930,6 +1932,7 @@ void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
if(is_nr_p7_request_in_window(req->SFN,req->Slot,"ul_dci_request", pnf_p7)) if(is_nr_p7_request_in_window(req->SFN,req->Slot,"ul_dci_request", pnf_p7))
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "swetank: fxn:%s sfn:%d slot:%d\n", __FUNCTION__, req->SFN, req->Slot);
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot); uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % 20; uint8_t buffer_index = sfn_slot_dec % 20;
...@@ -2069,6 +2072,7 @@ void pnf_handle_tx_data_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7 ...@@ -2069,6 +2072,7 @@ void pnf_handle_tx_data_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
if(is_nr_p7_request_in_window(req->SFN, req->Slot,"tx_request", pnf_p7)) if(is_nr_p7_request_in_window(req->SFN, req->Slot,"tx_request", pnf_p7))
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "swetank: fxn:%s sfn:%d slot:%d\n", __FUNCTION__, req->SFN, req->Slot);
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot); uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % 20; uint8_t buffer_index = sfn_slot_dec % 20;
...@@ -2505,6 +2509,7 @@ void pnf_nr_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7 ...@@ -2505,6 +2509,7 @@ void pnf_nr_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
return; return;
} }
if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
......
...@@ -1511,7 +1511,7 @@ void vnf_handle_nr_slot_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf ...@@ -1511,7 +1511,7 @@ void vnf_handle_nr_slot_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf
} }
else else
{ {
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s: Handling NR SLOT Indication\n", __FUNCTION__); NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s: Handling NR SLOT Indication sfn:%d slot:%d\n", __FUNCTION__, ind.sfn, ind.slot);
if(vnf_p7->_public.nr_slot_indication) if(vnf_p7->_public.nr_slot_indication)
{ {
(vnf_p7->_public.nr_slot_indication)(&ind); (vnf_p7->_public.nr_slot_indication)(&ind);
...@@ -1537,7 +1537,7 @@ void vnf_handle_nr_rx_data_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* ...@@ -1537,7 +1537,7 @@ void vnf_handle_nr_rx_data_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t*
} }
else else
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RX Indication\n", __FUNCTION__); NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RX Indication sfn:%d slot:%d\n", __FUNCTION__, ind.sfn, ind.slot);
if(vnf_p7->_public.nr_rx_data_indication) if(vnf_p7->_public.nr_rx_data_indication)
{ {
(vnf_p7->_public.nr_rx_data_indication)(&ind); (vnf_p7->_public.nr_rx_data_indication)(&ind);
...@@ -1563,7 +1563,7 @@ void vnf_handle_nr_crc_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_ ...@@ -1563,7 +1563,7 @@ void vnf_handle_nr_crc_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
} }
else else
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling CRC Indication\n", __FUNCTION__); NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling CRC Indication sfn:%d slot:%d\n", __FUNCTION__, ind.sfn, ind.slot);
if(vnf_p7->_public.nr_crc_indication) if(vnf_p7->_public.nr_crc_indication)
{ {
(vnf_p7->_public.nr_crc_indication)(&ind); (vnf_p7->_public.nr_crc_indication)(&ind);
...@@ -1589,6 +1589,7 @@ void vnf_handle_nr_srs_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_ ...@@ -1589,6 +1589,7 @@ void vnf_handle_nr_srs_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
} }
else else
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling SRS Indication sfn:%d slot:%d\n", __FUNCTION__, ind.sfn, ind.slot);
if(vnf_p7->_public.nr_srs_indication) if(vnf_p7->_public.nr_srs_indication)
{ {
(vnf_p7->_public.nr_srs_indication)(&ind); (vnf_p7->_public.nr_srs_indication)(&ind);
...@@ -1614,7 +1615,7 @@ void vnf_handle_nr_uci_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_ ...@@ -1614,7 +1615,7 @@ void vnf_handle_nr_uci_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
} }
else else
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling UCI Indication\n", __FUNCTION__); NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling UCI Indication sfn:%d slot:%d\n", __FUNCTION__, ind.sfn, ind.slot);
if(vnf_p7->_public.nr_uci_indication) if(vnf_p7->_public.nr_uci_indication)
{ {
(vnf_p7->_public.nr_uci_indication)(&ind); (vnf_p7->_public.nr_uci_indication)(&ind);
...@@ -1640,7 +1641,7 @@ void vnf_handle_nr_rach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf ...@@ -1640,7 +1641,7 @@ void vnf_handle_nr_rach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf
} }
else else
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RACH Indication\n", __FUNCTION__); NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RACH Indication sfn:%d slot:%d\n", __FUNCTION__, ind.sfn, ind.slot);
if(vnf_p7->_public.nr_rach_indication) if(vnf_p7->_public.nr_rach_indication)
{ {
(vnf_p7->_public.nr_rach_indication)(&ind); (vnf_p7->_public.nr_rach_indication)(&ind);
......
...@@ -168,6 +168,14 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac, ...@@ -168,6 +168,14 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac,
NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index]; NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index];
if (!curr_pucch->active) if (!curr_pucch->active)
continue; continue;
LOG_A(NR_MAC,"swetank: fxn:%s frameP:%d curr_pucch->frame:%d slotP:%d curr_pucch->ul_slot:%d \n",
__FUNCTION__,
frameP,
curr_pucch->frame,
slotP,
curr_pucch->ul_slot);
DevAssert(frameP == curr_pucch->frame && slotP == curr_pucch->ul_slot); DevAssert(frameP == curr_pucch->frame && slotP == curr_pucch->ul_slot);
const uint16_t O_ack = curr_pucch->dai_c; const uint16_t O_ack = curr_pucch->dai_c;
...@@ -1245,6 +1253,14 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) ...@@ -1245,6 +1253,14 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
else if (curr_pucch->active) { else if (curr_pucch->active) {
AssertFatal(1==0, "This shouldn't happen! curr_pucch frame.slot %d.%d not matching with SR function frame.slot %d.%d\n", AssertFatal(1==0, "This shouldn't happen! curr_pucch frame.slot %d.%d not matching with SR function frame.slot %d.%d\n",
curr_pucch->frame, curr_pucch->ul_slot, SFN, slot); curr_pucch->frame, curr_pucch->ul_slot, SFN, slot);
LOG_A(NR_MAC,"swetank: fxn:%d frameP:%d curr_pucch->frame:%d slotP:%d curr_pucch->ul_slot:%d \n",
__FUNCTION__,
SFN,
curr_pucch->frame,
slot,
curr_pucch->ul_slot);
continue; continue;
} }
else { else {
......
...@@ -1366,7 +1366,7 @@ static bool pdcp_data_req_srb(protocol_ctxt_t *ctxt_pP, ...@@ -1366,7 +1366,7 @@ static bool pdcp_data_req_srb(protocol_ctxt_t *ctxt_pP,
nr_pdcp_pkt_info_t pdcp_pkt; nr_pdcp_pkt_info_t pdcp_pkt;
memset(&pdcp_pkt, 0, sizeof(pdcp_pkt)); memset(&pdcp_pkt, 0, sizeof(pdcp_pkt));
pdcp_pkt.direction = 1; //PDCP_NR_DIRECTION_DOWNLINK pdcp_pkt.direction = 1; //PDCP_NR_DIRECTION_DOWNLINK
pdcp_pkt.ueid = ue->rntiMaybeUEid; // pdcp_pkt.ueid = ue->rntiMaybeUEid;
pdcp_pkt.bearerType = 8; //TODO pdcp_pkt.bearerType = 8; //TODO
pdcp_pkt.bearerId = rb_id - 1; pdcp_pkt.bearerId = rb_id - 1;
pdcp_pkt.plane = (rb_id == 1)?4:1; pdcp_pkt.plane = (rb_id == 1)?4:1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment