|
|
@ -78,8 +78,6 @@ void rrc::init(const rrc_cfg_t& cfg_,
|
|
|
|
config_mac();
|
|
|
|
config_mac();
|
|
|
|
enb_mobility_cfg.reset(new mobility_cfg(&cfg));
|
|
|
|
enb_mobility_cfg.reset(new mobility_cfg(&cfg));
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_init(&paging_mutex, nullptr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bzero(&sr_sched, sizeof(sr_sched_t));
|
|
|
|
bzero(&sr_sched, sizeof(sr_sched_t));
|
|
|
|
|
|
|
|
|
|
|
|
running = true;
|
|
|
|
running = true;
|
|
|
@ -93,7 +91,6 @@ void rrc::stop()
|
|
|
|
rx_pdu_queue.push(std::move(p));
|
|
|
|
rx_pdu_queue.push(std::move(p));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
users.clear();
|
|
|
|
users.clear();
|
|
|
|
pthread_mutex_destroy(&paging_mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
/*******************************************************************************
|
|
|
@ -441,15 +438,31 @@ bool rrc::release_erabs(uint32_t rnti)
|
|
|
|
than user map
|
|
|
|
than user map
|
|
|
|
*******************************************************************************/
|
|
|
|
*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
void rrc::add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& UEPagingID)
|
|
|
|
void rrc::add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_paging_id)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&paging_mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(paging_mutex);
|
|
|
|
if (pending_paging.count(ueid) == 0) {
|
|
|
|
if (pending_paging.count(ueid) > 0) {
|
|
|
|
pending_paging[ueid] = UEPagingID;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
rrc_log->warning("Received Paging for UEID=%d but not yet transmitted\n", ueid);
|
|
|
|
rrc_log->warning("Received Paging for UEID=%d but not yet transmitted\n", ueid);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&paging_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
paging_record_s& paging_elem = pending_paging[ueid];
|
|
|
|
|
|
|
|
if (ue_paging_id.type().value == asn1::s1ap::ue_paging_id_c::types_opts::imsi) {
|
|
|
|
|
|
|
|
paging_elem.ue_id.set_imsi();
|
|
|
|
|
|
|
|
paging_elem.ue_id.imsi().resize(ue_paging_id.imsi().size());
|
|
|
|
|
|
|
|
memcpy(paging_elem.ue_id.imsi().data(), ue_paging_id.imsi().data(), ue_paging_id.imsi().size());
|
|
|
|
|
|
|
|
rrc_log->console("Warning IMSI paging not tested\n");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
paging_elem.ue_id.set_s_tmsi();
|
|
|
|
|
|
|
|
paging_elem.ue_id.s_tmsi().mmec.from_number(ue_paging_id.s_tmsi().mmec[0]);
|
|
|
|
|
|
|
|
uint32_t m_tmsi = 0;
|
|
|
|
|
|
|
|
uint32_t nof_octets = ue_paging_id.s_tmsi().m_tmsi.size();
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < nof_octets; i++) {
|
|
|
|
|
|
|
|
m_tmsi |= ue_paging_id.s_tmsi().m_tmsi[i] << (8u * (nof_octets - i - 1u));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
paging_elem.ue_id.s_tmsi().m_tmsi.from_number(m_tmsi);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
paging_elem.cn_domain = paging_record_s::cn_domain_e_::ps;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Described in Section 7 of 36.304
|
|
|
|
// Described in Section 7 of 36.304
|
|
|
@ -461,8 +474,6 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&paging_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
asn1::rrc::pcch_msg_s pcch_msg;
|
|
|
|
asn1::rrc::pcch_msg_s pcch_msg;
|
|
|
|
pcch_msg.msg.set_c1();
|
|
|
|
pcch_msg.msg.set_c1();
|
|
|
|
paging_s* paging_rec = &pcch_msg.msg.c1().paging();
|
|
|
|
paging_s* paging_rec = &pcch_msg.msg.c1().paging();
|
|
|
@ -477,12 +488,15 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len)
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<uint32_t> ue_to_remove;
|
|
|
|
std::vector<uint32_t> ue_to_remove;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::lock_guard<std::mutex> lock(paging_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
int n = 0;
|
|
|
|
int n = 0;
|
|
|
|
for (auto& item : pending_paging) {
|
|
|
|
for (auto& item : pending_paging) {
|
|
|
|
if (n >= ASN1_RRC_MAX_PAGE_REC) {
|
|
|
|
if (n >= ASN1_RRC_MAX_PAGE_REC) {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
asn1::s1ap::ue_paging_id_c& u = item.second;
|
|
|
|
const asn1::rrc::paging_record_s& u = item.second;
|
|
|
|
uint32_t ueid = ((uint32_t)item.first) % 1024;
|
|
|
|
uint32_t ueid = ((uint32_t)item.first) % 1024;
|
|
|
|
uint32_t i_s = (ueid / N) % Ns;
|
|
|
|
uint32_t i_s = (ueid / N) % Ns;
|
|
|
|
|
|
|
|
|
|
|
@ -498,24 +512,7 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len)
|
|
|
|
|
|
|
|
|
|
|
|
if ((uint32_t)sf_idx == (tti % 10)) {
|
|
|
|
if ((uint32_t)sf_idx == (tti % 10)) {
|
|
|
|
paging_rec->paging_record_list_present = true;
|
|
|
|
paging_rec->paging_record_list_present = true;
|
|
|
|
paging_record_s paging_elem;
|
|
|
|
paging_rec->paging_record_list.push_back(u);
|
|
|
|
if (u.type().value == asn1::s1ap::ue_paging_id_c::types_opts::imsi) {
|
|
|
|
|
|
|
|
paging_elem.ue_id.set_imsi();
|
|
|
|
|
|
|
|
paging_elem.ue_id.imsi().resize(u.imsi().size());
|
|
|
|
|
|
|
|
memcpy(paging_elem.ue_id.imsi().data(), u.imsi().data(), u.imsi().size());
|
|
|
|
|
|
|
|
rrc_log->console("Warning IMSI paging not tested\n");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
paging_elem.ue_id.set_s_tmsi();
|
|
|
|
|
|
|
|
paging_elem.ue_id.s_tmsi().mmec.from_number(u.s_tmsi().mmec[0]);
|
|
|
|
|
|
|
|
uint32_t m_tmsi = 0;
|
|
|
|
|
|
|
|
uint32_t nof_octets = u.s_tmsi().m_tmsi.size();
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < nof_octets; i++) {
|
|
|
|
|
|
|
|
m_tmsi |= u.s_tmsi().m_tmsi[i] << (8u * (nof_octets - i - 1u));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
paging_elem.ue_id.s_tmsi().m_tmsi.from_number(m_tmsi);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
paging_elem.cn_domain = paging_record_s::cn_domain_e_::ps;
|
|
|
|
|
|
|
|
paging_rec->paging_record_list.push_back(paging_elem);
|
|
|
|
|
|
|
|
ue_to_remove.push_back(ueid);
|
|
|
|
ue_to_remove.push_back(ueid);
|
|
|
|
n++;
|
|
|
|
n++;
|
|
|
|
rrc_log->info("Assembled paging for ue_id=%d, tti=%d\n", ueid, tti);
|
|
|
|
rrc_log->info("Assembled paging for ue_id=%d, tti=%d\n", ueid, tti);
|
|
|
@ -525,8 +522,7 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len)
|
|
|
|
for (unsigned int i : ue_to_remove) {
|
|
|
|
for (unsigned int i : ue_to_remove) {
|
|
|
|
pending_paging.erase(i);
|
|
|
|
pending_paging.erase(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&paging_mutex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (paging_rec->paging_record_list.size() > 0) {
|
|
|
|
if (paging_rec->paging_record_list.size() > 0) {
|
|
|
|
byte_buf_paging.clear();
|
|
|
|
byte_buf_paging.clear();
|
|
|
@ -555,11 +551,10 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len)
|
|
|
|
|
|
|
|
|
|
|
|
void rrc::read_pdu_pcch(uint8_t* payload, uint32_t buffer_size)
|
|
|
|
void rrc::read_pdu_pcch(uint8_t* payload, uint32_t buffer_size)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&paging_mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(paging_mutex);
|
|
|
|
if (byte_buf_paging.N_bytes <= buffer_size) {
|
|
|
|
if (byte_buf_paging.N_bytes <= buffer_size) {
|
|
|
|
memcpy(payload, byte_buf_paging.msg, byte_buf_paging.N_bytes);
|
|
|
|
memcpy(payload, byte_buf_paging.msg, byte_buf_paging.N_bytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&paging_mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
/*******************************************************************************
|
|
|
|